summaryrefslogtreecommitdiffstats
path: root/desktop-widgets
diff options
context:
space:
mode:
authorGravatar Tomaz Canabrava <tomaz.canabrava@intel.com>2015-09-03 15:56:37 -0300
committerGravatar Dirk Hohndel <dirk@hohndel.org>2015-10-30 10:36:49 -0700
commit1d6683f3e07d9a73af5fab702bc3a551ec7dabc9 (patch)
tree80a64ced06489bf0dca866b2097ca7048b1f0ab8 /desktop-widgets
parent50ec7200e66637abefe685e1875f3d4de2101158 (diff)
downloadsubsurface-1d6683f3e07d9a73af5fab702bc3a551ec7dabc9.tar.gz
Move Profile widget out of desktop-widgets
The reason for that is, even if profile widget is made with qpainter and for that reason it should be a desktop widget, it's being used on the mobile version because of a lack of QML plotting library that is fast and reliable. We discovered that it was faster just to encapsulate our Profile in a QML class and call it directly. Signed-off-by: Tomaz Canabrava <tomaz.canabrava@intel.com> Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
Diffstat (limited to 'desktop-widgets')
-rw-r--r--desktop-widgets/CMakeLists.txt19
-rw-r--r--desktop-widgets/diveplanner.cpp6
-rw-r--r--desktop-widgets/maintab.cpp2
-rw-r--r--desktop-widgets/mainwindow.cpp2
-rw-r--r--desktop-widgets/modeldelegates.cpp2
-rw-r--r--desktop-widgets/printer.cpp1
-rw-r--r--desktop-widgets/printer.h1
-rw-r--r--desktop-widgets/profile/animationfunctions.cpp75
-rw-r--r--desktop-widgets/profile/animationfunctions.h18
-rw-r--r--desktop-widgets/profile/divecartesianaxis.cpp459
-rw-r--r--desktop-widgets/profile/divecartesianaxis.h122
-rw-r--r--desktop-widgets/profile/diveeventitem.cpp172
-rw-r--r--desktop-widgets/profile/diveeventitem.h34
-rw-r--r--desktop-widgets/profile/divelineitem.cpp5
-rw-r--r--desktop-widgets/profile/divelineitem.h15
-rw-r--r--desktop-widgets/profile/divepixmapitem.cpp130
-rw-r--r--desktop-widgets/profile/divepixmapitem.h57
-rw-r--r--desktop-widgets/profile/diveprofileitem.cpp979
-rw-r--r--desktop-widgets/profile/diveprofileitem.h225
-rw-r--r--desktop-widgets/profile/diverectitem.cpp5
-rw-r--r--desktop-widgets/profile/diverectitem.h17
-rw-r--r--desktop-widgets/profile/divetextitem.cpp113
-rw-r--r--desktop-widgets/profile/divetextitem.h38
-rw-r--r--desktop-widgets/profile/divetooltipitem.cpp285
-rw-r--r--desktop-widgets/profile/divetooltipitem.h67
-rw-r--r--desktop-widgets/profile/profilewidget2.cpp1836
-rw-r--r--desktop-widgets/profile/profilewidget2.h211
-rw-r--r--desktop-widgets/profile/ruleritem.cpp179
-rw-r--r--desktop-widgets/profile/ruleritem.h59
-rw-r--r--desktop-widgets/profile/tankitem.cpp120
-rw-r--r--desktop-widgets/profile/tankitem.h39
-rw-r--r--desktop-widgets/simplewidgets.cpp2
-rw-r--r--desktop-widgets/socialnetworks.cpp2
33 files changed, 9 insertions, 5288 deletions
diff --git a/desktop-widgets/CMakeLists.txt b/desktop-widgets/CMakeLists.txt
index 2c373b83f..635a8b68e 100644
--- a/desktop-widgets/CMakeLists.txt
+++ b/desktop-widgets/CMakeLists.txt
@@ -75,23 +75,6 @@ endif()
source_group("Subsurface Interface" FILES ${SUBSURFACE_INTERFACE})
-# the profile widget
-set(SUBSURFACE_PROFILE_LIB_SRCS
- profile/profilewidget2.cpp
- profile/diverectitem.cpp
- profile/divepixmapitem.cpp
- profile/divelineitem.cpp
- profile/divetextitem.cpp
- profile/animationfunctions.cpp
- profile/divecartesianaxis.cpp
- profile/diveprofileitem.cpp
- profile/diveeventitem.cpp
- profile/divetooltipitem.cpp
- profile/ruleritem.cpp
- profile/tankitem.cpp
-)
-source_group("Subsurface Profile" FILES ${SUBSURFACE_PROFILE_LIB_SRCS})
-
# the yearly statistics widget.
set(SUBSURFACE_STATISTICS_LIB_SRCS
statistics/statisticswidget.cpp
@@ -101,8 +84,6 @@ set(SUBSURFACE_STATISTICS_LIB_SRCS
)
source_group("Subsurface Statistics" FILES ${SUBSURFACE_STATISTICS_LIB_SRCS})
-add_library(subsurface_profile STATIC ${SUBSURFACE_PROFILE_LIB_SRCS})
-target_link_libraries(subsurface_profile ${QT_LIBRARIES})
add_library(subsurface_statistics STATIC ${SUBSURFACE_STATISTICS_LIB_SRCS})
target_link_libraries(subsurface_statistics ${QT_LIBRARIES})
add_library(subsurface_generated_ui STATIC ${SUBSURFACE_UI_HDRS})
diff --git a/desktop-widgets/diveplanner.cpp b/desktop-widgets/diveplanner.cpp
index b4413d11a..86f03b1d2 100644
--- a/desktop-widgets/diveplanner.cpp
+++ b/desktop-widgets/diveplanner.cpp
@@ -5,7 +5,7 @@
#include "helpers.h"
#include "cylindermodel.h"
#include "models.h"
-#include "profile/profilewidget2.h"
+#include "profile-widget/profilewidget2.h"
#include "diveplannermodel.h"
#include <QGraphicsSceneMouseEvent>
@@ -328,11 +328,11 @@ PlannerSettingsWidget::PlannerSettingsWidget(QWidget *parent, Qt::WindowFlags f)
modeMapper->setMapping(ui.recreational_deco, int(RECREATIONAL));
modeMapper->setMapping(ui.buehlmann_deco, int(BUEHLMANN));
modeMapper->setMapping(ui.vpmb_deco, int(VPMB));
-
+
connect(ui.recreational_deco, SIGNAL(clicked()), modeMapper, SLOT(map()));
connect(ui.buehlmann_deco, SIGNAL(clicked()), modeMapper, SLOT(map()));
connect(ui.vpmb_deco, SIGNAL(clicked()), modeMapper, SLOT(map()));
-
+
connect(ui.lastStop, SIGNAL(toggled(bool)), plannerModel, SLOT(setLastStop6m(bool)));
connect(ui.verbatim_plan, SIGNAL(toggled(bool)), plannerModel, SLOT(setVerbatim(bool)));
connect(ui.display_duration, SIGNAL(toggled(bool)), plannerModel, SLOT(setDisplayDuration(bool)));
diff --git a/desktop-widgets/maintab.cpp b/desktop-widgets/maintab.cpp
index 0afb7b4c0..4d4cd3a5e 100644
--- a/desktop-widgets/maintab.cpp
+++ b/desktop-widgets/maintab.cpp
@@ -13,7 +13,7 @@
#include "diveplannermodel.h"
#include "divelistview.h"
#include "display.h"
-#include "profile/profilewidget2.h"
+#include "profile-widget/profilewidget2.h"
#include "diveplanner.h"
#include "divesitehelpers.h"
#include "cylindermodel.h"
diff --git a/desktop-widgets/mainwindow.cpp b/desktop-widgets/mainwindow.cpp
index e1e0d81a2..43b433d62 100644
--- a/desktop-widgets/mainwindow.cpp
+++ b/desktop-widgets/mainwindow.cpp
@@ -21,7 +21,7 @@
#include "updatemanager.h"
#include "planner.h"
#include "filtermodels.h"
-#include "profile/profilewidget2.h"
+#include "profile-widget/profilewidget2.h"
#include "globe.h"
#include "divecomputer.h"
#include "maintab.h"
diff --git a/desktop-widgets/modeldelegates.cpp b/desktop-widgets/modeldelegates.cpp
index 881037a83..1b1a31c0b 100644
--- a/desktop-widgets/modeldelegates.cpp
+++ b/desktop-widgets/modeldelegates.cpp
@@ -5,7 +5,7 @@
#include "cylindermodel.h"
#include "models.h"
#include "starwidget.h"
-#include "profile/profilewidget2.h"
+#include "profile-widget/profilewidget2.h"
#include "tankinfomodel.h"
#include "weigthsysteminfomodel.h"
#include "weightmodel.h"
diff --git a/desktop-widgets/printer.cpp b/desktop-widgets/printer.cpp
index f0197d446..33ee71b55 100644
--- a/desktop-widgets/printer.cpp
+++ b/desktop-widgets/printer.cpp
@@ -8,6 +8,7 @@
#include <QPainter>
#include <QWebElementCollection>
#include <QWebElement>
+#include "profile-widget/profilewidget2.h"
Printer::Printer(QPaintDevice *paintDevice, print_options *printOptions, template_options *templateOptions, PrintMode printMode)
{
diff --git a/desktop-widgets/printer.h b/desktop-widgets/printer.h
index 979cacd6a..e5f16d77d 100644
--- a/desktop-widgets/printer.h
+++ b/desktop-widgets/printer.h
@@ -6,7 +6,6 @@
#include <QRect>
#include <QPainter>
-#include "profile/profilewidget2.h"
#include "printoptions.h"
#include "templateedit.h"
diff --git a/desktop-widgets/profile/animationfunctions.cpp b/desktop-widgets/profile/animationfunctions.cpp
deleted file mode 100644
index a19d50c9d..000000000
--- a/desktop-widgets/profile/animationfunctions.cpp
+++ /dev/null
@@ -1,75 +0,0 @@
-#include "animationfunctions.h"
-#include "pref.h"
-#include <QPropertyAnimation>
-
-namespace Animations {
-
- void hide(QObject *obj)
- {
- if (prefs.animation_speed != 0) {
- QPropertyAnimation *animation = new QPropertyAnimation(obj, "opacity");
- animation->setStartValue(1);
- animation->setEndValue(0);
- animation->start(QAbstractAnimation::DeleteWhenStopped);
- } else {
- obj->setProperty("opacity", 0);
- }
- }
-
- void show(QObject *obj)
- {
- if (prefs.animation_speed != 0) {
- QPropertyAnimation *animation = new QPropertyAnimation(obj, "opacity");
- animation->setStartValue(0);
- animation->setEndValue(1);
- animation->start(QAbstractAnimation::DeleteWhenStopped);
- } else {
- obj->setProperty("opacity", 1);
- }
- }
-
- void animDelete(QObject *obj)
- {
- if (prefs.animation_speed != 0) {
- QPropertyAnimation *animation = new QPropertyAnimation(obj, "opacity");
- obj->connect(animation, SIGNAL(finished()), SLOT(deleteLater()));
- animation->setStartValue(1);
- animation->setEndValue(0);
- animation->start(QAbstractAnimation::DeleteWhenStopped);
- } else {
- obj->setProperty("opacity", 0);
- }
- }
-
- void moveTo(QObject *obj, qreal x, qreal y)
- {
- if (prefs.animation_speed != 0) {
- QPropertyAnimation *animation = new QPropertyAnimation(obj, "pos");
- animation->setDuration(prefs.animation_speed);
- animation->setStartValue(obj->property("pos").toPointF());
- animation->setEndValue(QPointF(x, y));
- animation->start(QAbstractAnimation::DeleteWhenStopped);
- } else {
- obj->setProperty("pos", QPointF(x, y));
- }
- }
-
- void scaleTo(QObject *obj, qreal scale)
- {
- if (prefs.animation_speed != 0) {
- QPropertyAnimation *animation = new QPropertyAnimation(obj, "scale");
- animation->setDuration(prefs.animation_speed);
- animation->setStartValue(obj->property("scale").toReal());
- animation->setEndValue(QVariant::fromValue(scale));
- animation->setEasingCurve(QEasingCurve::InCubic);
- animation->start(QAbstractAnimation::DeleteWhenStopped);
- } else {
- obj->setProperty("scale", QVariant::fromValue(scale));
- }
- }
-
- void moveTo(QObject *obj, const QPointF &pos)
- {
- moveTo(obj, pos.x(), pos.y());
- }
-}
diff --git a/desktop-widgets/profile/animationfunctions.h b/desktop-widgets/profile/animationfunctions.h
deleted file mode 100644
index 3cfcff563..000000000
--- a/desktop-widgets/profile/animationfunctions.h
+++ /dev/null
@@ -1,18 +0,0 @@
-#ifndef ANIMATIONFUNCTIONS_H
-#define ANIMATIONFUNCTIONS_H
-
-#include <QtGlobal>
-#include <QPointF>
-
-class QObject;
-
-namespace Animations {
- void hide(QObject *obj);
- void show(QObject *obj);
- void moveTo(QObject *obj, qreal x, qreal y);
- void moveTo(QObject *obj, const QPointF &pos);
- void animDelete(QObject *obj);
- void scaleTo(QObject *obj, qreal scale);
-}
-
-#endif // ANIMATIONFUNCTIONS_H
diff --git a/desktop-widgets/profile/divecartesianaxis.cpp b/desktop-widgets/profile/divecartesianaxis.cpp
deleted file mode 100644
index bf5a5380c..000000000
--- a/desktop-widgets/profile/divecartesianaxis.cpp
+++ /dev/null
@@ -1,459 +0,0 @@
-#include "divecartesianaxis.h"
-#include "divetextitem.h"
-#include "helpers.h"
-#include "preferences.h"
-#include "diveplotdatamodel.h"
-#include "animationfunctions.h"
-#include "mainwindow.h"
-#include "divelineitem.h"
-#include "profilewidget2.h"
-
-QPen DiveCartesianAxis::gridPen()
-{
- QPen pen;
- pen.setColor(getColor(TIME_GRID));
- /* cosmetic width() == 0 for lines in printMode
- * having setCosmetic(true) and width() > 0 does not work when
- * printing on OSX and Linux */
- pen.setWidth(DiveCartesianAxis::printMode ? 0 : 2);
- pen.setCosmetic(true);
- return pen;
-}
-
-double DiveCartesianAxis::tickInterval() const
-{
- return interval;
-}
-
-double DiveCartesianAxis::tickSize() const
-{
- return tick_size;
-}
-
-void DiveCartesianAxis::setFontLabelScale(qreal scale)
-{
- labelScale = scale;
- changed = true;
-}
-
-void DiveCartesianAxis::setPrintMode(bool mode)
-{
- printMode = mode;
- // update the QPen of all lines depending on printMode
- QPen newPen = gridPen();
- QColor oldColor = pen().brush().color();
- newPen.setBrush(oldColor);
- setPen(newPen);
- Q_FOREACH (DiveLineItem *item, lines)
- item->setPen(pen());
-}
-
-void DiveCartesianAxis::setMaximum(double maximum)
-{
- if (IS_FP_SAME(max, maximum))
- return;
- max = maximum;
- changed = true;
- emit maxChanged();
-}
-
-void DiveCartesianAxis::setMinimum(double minimum)
-{
- if (IS_FP_SAME(min, minimum))
- return;
- min = minimum;
- changed = true;
-}
-
-void DiveCartesianAxis::setTextColor(const QColor &color)
-{
- textColor = color;
-}
-
-DiveCartesianAxis::DiveCartesianAxis() : QObject(),
- QGraphicsLineItem(),
- printMode(false),
- unitSystem(0),
- orientation(LeftToRight),
- min(0),
- max(0),
- interval(1),
- tick_size(0),
- textVisibility(true),
- lineVisibility(true),
- labelScale(1.0),
- line_size(1),
- changed(true)
-{
- setPen(gridPen());
-}
-
-DiveCartesianAxis::~DiveCartesianAxis()
-{
-}
-
-void DiveCartesianAxis::setLineSize(qreal lineSize)
-{
- line_size = lineSize;
- changed = true;
-}
-
-void DiveCartesianAxis::setOrientation(Orientation o)
-{
- orientation = o;
- changed = true;
-}
-
-QColor DiveCartesianAxis::colorForValue(double value)
-{
- return QColor(Qt::black);
-}
-
-void DiveCartesianAxis::setTextVisible(bool arg1)
-{
- if (textVisibility == arg1) {
- return;
- }
- textVisibility = arg1;
- Q_FOREACH (DiveTextItem *item, labels) {
- item->setVisible(textVisibility);
- }
-}
-
-void DiveCartesianAxis::setLinesVisible(bool arg1)
-{
- if (lineVisibility == arg1) {
- return;
- }
- lineVisibility = arg1;
- Q_FOREACH (DiveLineItem *item, lines) {
- item->setVisible(lineVisibility);
- }
-}
-
-template <typename T>
-void emptyList(QList<T *> &list, double steps)
-{
- if (!list.isEmpty() && list.size() > steps) {
- while (list.size() > steps) {
- T *removedItem = list.takeLast();
- Animations::animDelete(removedItem);
- }
- }
-}
-
-void DiveCartesianAxis::updateTicks(color_indice_t color)
-{
- if (!scene() || (!changed && !MainWindow::instance()->graphics()->getPrintMode()))
- return;
- QLineF m = line();
- // unused so far:
- // QGraphicsView *view = scene()->views().first();
- double steps = (max - min) / interval;
- double currValueText = min;
- double currValueLine = min;
-
- if (steps < 1)
- return;
-
- emptyList(labels, steps);
- emptyList(lines, steps);
-
- // Move the remaining Ticks / Text to it's corerct position
- // Regartind the possibly new values for the Axis
- qreal begin, stepSize;
- if (orientation == TopToBottom) {
- begin = m.y1();
- stepSize = (m.y2() - m.y1());
- } else if (orientation == BottomToTop) {
- begin = m.y2();
- stepSize = (m.y2() - m.y1());
- } else if (orientation == LeftToRight) {
- begin = m.x1();
- stepSize = (m.x2() - m.x1());
- } else /* if (orientation == RightToLeft) */ {
- begin = m.x2();
- stepSize = (m.x2() - m.x1());
- }
- stepSize = stepSize / steps;
-
- for (int i = 0, count = labels.size(); i < count; i++, currValueText += interval) {
- qreal childPos = (orientation == TopToBottom || orientation == LeftToRight) ?
- begin + i * stepSize :
- begin - i * stepSize;
-
- labels[i]->setText(textForValue(currValueText));
- if (orientation == LeftToRight || orientation == RightToLeft) {
- Animations::moveTo(labels[i],childPos, m.y1() + tick_size);
- } else {
- Animations::moveTo(labels[i],m.x1() - tick_size, childPos);
- }
- }
-
- for (int i = 0, count = lines.size(); i < count; i++, currValueLine += interval) {
- qreal childPos = (orientation == TopToBottom || orientation == LeftToRight) ?
- begin + i * stepSize :
- begin - i * stepSize;
-
- if (orientation == LeftToRight || orientation == RightToLeft) {
- Animations::moveTo(lines[i],childPos, m.y1());
- } else {
- Animations::moveTo(lines[i],m.x1(), childPos);
- }
- }
-
- // Add's the rest of the needed Ticks / Text.
- for (int i = labels.size(); i < steps; i++, currValueText += interval) {
- qreal childPos;
- if (orientation == TopToBottom || orientation == LeftToRight) {
- childPos = begin + i * stepSize;
- } else {
- childPos = begin - i * stepSize;
- }
- DiveTextItem *label = new DiveTextItem(this);
- label->setText(textForValue(currValueText));
- label->setBrush(colorForValue(currValueText));
- label->setScale(fontLabelScale());
- label->setZValue(1);
- labels.push_back(label);
- if (orientation == RightToLeft || orientation == LeftToRight) {
- label->setAlignment(Qt::AlignBottom | Qt::AlignHCenter);
- label->setPos(scene()->sceneRect().width() + 10, m.y1() + tick_size); // position it outside of the scene);
- Animations::moveTo(label,childPos, m.y1() + tick_size);
- } else {
- label->setAlignment(Qt::AlignVCenter | Qt::AlignLeft);
- label->setPos(m.x1() - tick_size, scene()->sceneRect().height() + 10);
- Animations::moveTo(label,m.x1() - tick_size, childPos);
- }
- }
-
- // Add's the rest of the needed Ticks / Text.
- for (int i = lines.size(); i < steps; i++, currValueText += interval) {
- qreal childPos;
- if (orientation == TopToBottom || orientation == LeftToRight) {
- childPos = begin + i * stepSize;
- } else {
- childPos = begin - i * stepSize;
- }
- DiveLineItem *line = new DiveLineItem(this);
- QPen pen = gridPen();
- pen.setBrush(getColor(color));
- line->setPen(pen);
- line->setZValue(0);
- lines.push_back(line);
- if (orientation == RightToLeft || orientation == LeftToRight) {
- line->setLine(0, -line_size, 0, 0);
- line->setPos(scene()->sceneRect().width() + 10, m.y1()); // position it outside of the scene);
- Animations::moveTo(line,childPos, m.y1());
- } else {
- QPointF p1 = mapFromScene(3, 0);
- QPointF p2 = mapFromScene(line_size, 0);
- line->setLine(p1.x(), 0, p2.x(), 0);
- line->setPos(m.x1(), scene()->sceneRect().height() + 10);
- Animations::moveTo(line,m.x1(), childPos);
- }
- }
-
- Q_FOREACH (DiveTextItem *item, labels)
- item->setVisible(textVisibility);
- Q_FOREACH (DiveLineItem *item, lines)
- item->setVisible(lineVisibility);
- changed = false;
-}
-
-void DiveCartesianAxis::setLine(const QLineF &line)
-{
- QGraphicsLineItem::setLine(line);
- changed = true;
-}
-
-void DiveCartesianAxis::animateChangeLine(const QLineF &newLine)
-{
- setLine(newLine);
- updateTicks();
- sizeChanged();
-}
-
-QString DiveCartesianAxis::textForValue(double value)
-{
- return QString::number(value);
-}
-
-void DiveCartesianAxis::setTickSize(qreal size)
-{
- tick_size = size;
-}
-
-void DiveCartesianAxis::setTickInterval(double i)
-{
- interval = i;
-}
-
-qreal DiveCartesianAxis::valueAt(const QPointF &p) const
-{
- QLineF m = line();
- QPointF relativePosition = p;
- relativePosition -= pos(); // normalize p based on the axis' offset on screen
-
- double retValue = (orientation == LeftToRight || orientation == RightToLeft) ?
- max * (relativePosition.x() - m.x1()) / (m.x2() - m.x1()) :
- max * (relativePosition.y() - m.y1()) / (m.y2() - m.y1());
- return retValue;
-}
-
-qreal DiveCartesianAxis::posAtValue(qreal value)
-{
- QLineF m = line();
- QPointF p = pos();
-
- double size = max - min;
- // unused for now:
- // double distanceFromOrigin = value - min;
- double percent = IS_FP_SAME(min, max) ? 0.0 : (value - min) / size;
-
-
- double realSize = orientation == LeftToRight || orientation == RightToLeft ?
- m.x2() - m.x1() :
- m.y2() - m.y1();
-
- // Inverted axis, just invert the percentage.
- if (orientation == RightToLeft || orientation == BottomToTop)
- percent = 1 - percent;
-
- double retValue = realSize * percent;
- double adjusted =
- orientation == LeftToRight ? retValue + m.x1() + p.x() :
- orientation == RightToLeft ? retValue + m.x1() + p.x() :
- orientation == TopToBottom ? retValue + m.y1() + p.y() :
- /* entation == BottomToTop */ retValue + m.y1() + p.y();
- return adjusted;
-}
-
-qreal DiveCartesianAxis::percentAt(const QPointF &p)
-{
- qreal value = valueAt(p);
- double size = max - min;
- double percent = value / size;
- return percent;
-}
-
-double DiveCartesianAxis::maximum() const
-{
- return max;
-}
-
-double DiveCartesianAxis::minimum() const
-{
- return min;
-}
-
-double DiveCartesianAxis::fontLabelScale() const
-{
- return labelScale;
-}
-
-void DiveCartesianAxis::setColor(const QColor &color)
-{
- QPen defaultPen = gridPen();
- defaultPen.setColor(color);
- defaultPen.setJoinStyle(Qt::RoundJoin);
- defaultPen.setCapStyle(Qt::RoundCap);
- setPen(defaultPen);
-}
-
-QString DepthAxis::textForValue(double value)
-{
- if (value == 0)
- return QString();
- return get_depth_string(value, false, false);
-}
-
-QColor DepthAxis::colorForValue(double value)
-{
- Q_UNUSED(value);
- return QColor(Qt::red);
-}
-
-DepthAxis::DepthAxis()
-{
- connect(PreferencesDialog::instance(), SIGNAL(settingsChanged()), this, SLOT(settingsChanged()));
- changed = true;
- settingsChanged();
-}
-
-void DepthAxis::settingsChanged()
-{
- static int unitSystem = prefs.units.length;
- if ( unitSystem == prefs.units.length )
- return;
- changed = true;
- updateTicks();
- unitSystem = prefs.units.length;
-}
-
-QColor TimeAxis::colorForValue(double value)
-{
- Q_UNUSED(value);
- return QColor(Qt::blue);
-}
-
-QString TimeAxis::textForValue(double value)
-{
- int nr = value / 60;
- if (maximum() < 600)
- return QString("%1:%2").arg(nr).arg((int)value % 60, 2, 10, QChar('0'));
- return QString::number(nr);
-}
-
-void TimeAxis::updateTicks()
-{
- DiveCartesianAxis::updateTicks();
- if (maximum() > 600) {
- for (int i = 0; i < labels.count(); i++) {
- labels[i]->setVisible(i % 2);
- }
- }
-}
-
-QString TemperatureAxis::textForValue(double value)
-{
- return QString::number(mkelvin_to_C((int)value));
-}
-
-PartialGasPressureAxis::PartialGasPressureAxis() :
- DiveCartesianAxis(),
- model(NULL)
-{
- connect(PreferencesDialog::instance(), SIGNAL(settingsChanged()), this, SLOT(settingsChanged()));
-}
-
-void PartialGasPressureAxis::setModel(DivePlotDataModel *m)
-{
- model = m;
- connect(model, SIGNAL(dataChanged(QModelIndex, QModelIndex)), this, SLOT(settingsChanged()));
- settingsChanged();
-}
-
-void PartialGasPressureAxis::settingsChanged()
-{
- bool showPhe = prefs.pp_graphs.phe;
- bool showPn2 = prefs.pp_graphs.pn2;
- bool showPo2 = prefs.pp_graphs.po2;
- setVisible(showPhe || showPn2 || showPo2);
- if (!model->rowCount())
- return;
-
- double max = showPhe ? model->pheMax() : -1;
- if (showPn2 && model->pn2Max() > max)
- max = model->pn2Max();
- if (showPo2 && model->po2Max() > max)
- max = model->po2Max();
-
- qreal pp = floor(max * 10.0) / 10.0 + 0.2;
- if (IS_FP_SAME(maximum(), pp))
- return;
-
- setMaximum(pp);
- setTickInterval(pp > 4 ? 0.5 : 0.25);
- updateTicks();
-}
diff --git a/desktop-widgets/profile/divecartesianaxis.h b/desktop-widgets/profile/divecartesianaxis.h
deleted file mode 100644
index cc7d0bcf7..000000000
--- a/desktop-widgets/profile/divecartesianaxis.h
+++ /dev/null
@@ -1,122 +0,0 @@
-#ifndef DIVECARTESIANAXIS_H
-#define DIVECARTESIANAXIS_H
-
-#include <QObject>
-#include <QGraphicsLineItem>
-#include "subsurface-core/color.h"
-
-class QPropertyAnimation;
-class DiveTextItem;
-class DiveLineItem;
-class DivePlotDataModel;
-
-class DiveCartesianAxis : public QObject, public QGraphicsLineItem {
- Q_OBJECT
- Q_PROPERTY(QLineF line WRITE setLine READ line)
- Q_PROPERTY(QPointF pos WRITE setPos READ pos)
- Q_PROPERTY(qreal x WRITE setX READ x)
- Q_PROPERTY(qreal y WRITE setY READ y)
-private:
- bool printMode;
- QPen gridPen();
-public:
- enum Orientation {
- TopToBottom,
- BottomToTop,
- LeftToRight,
- RightToLeft
- };
- DiveCartesianAxis();
- virtual ~DiveCartesianAxis();
- void setPrintMode(bool mode);
- void setMinimum(double minimum);
- void setMaximum(double maximum);
- void setTickInterval(double interval);
- void setOrientation(Orientation orientation);
- void setTickSize(qreal size);
- void setFontLabelScale(qreal scale);
- double minimum() const;
- double maximum() const;
- double tickInterval() const;
- double tickSize() const;
- double fontLabelScale() const;
- qreal valueAt(const QPointF &p) const;
- qreal percentAt(const QPointF &p);
- qreal posAtValue(qreal value);
- void setColor(const QColor &color);
- void setTextColor(const QColor &color);
- void animateChangeLine(const QLineF &newLine);
- void setTextVisible(bool arg1);
- void setLinesVisible(bool arg1);
- void setLineSize(qreal lineSize);
- void setLine(const QLineF& line);
- int unitSystem;
-public
-slots:
- virtual void updateTicks(color_indice_t color = TIME_GRID);
-
-signals:
- void sizeChanged();
- void maxChanged();
-
-protected:
- virtual QString textForValue(double value);
- virtual QColor colorForValue(double value);
- Orientation orientation;
- QList<DiveTextItem *> labels;
- QList<DiveLineItem *> lines;
- double min;
- double max;
- double interval;
- double tick_size;
- QColor textColor;
- bool textVisibility;
- bool lineVisibility;
- double labelScale;
- qreal line_size;
- bool changed;
-};
-
-class DepthAxis : public DiveCartesianAxis {
- Q_OBJECT
-public:
- DepthAxis();
-
-protected:
- QString textForValue(double value);
- QColor colorForValue(double value);
-private
-slots:
- void settingsChanged();
-};
-
-class TimeAxis : public DiveCartesianAxis {
- Q_OBJECT
-public:
- virtual void updateTicks();
-
-protected:
- QString textForValue(double value);
- QColor colorForValue(double value);
-};
-
-class TemperatureAxis : public DiveCartesianAxis {
- Q_OBJECT
-protected:
- QString textForValue(double value);
-};
-
-class PartialGasPressureAxis : public DiveCartesianAxis {
- Q_OBJECT
-public:
- PartialGasPressureAxis();
- void setModel(DivePlotDataModel *model);
-public
-slots:
- void settingsChanged();
-
-private:
- DivePlotDataModel *model;
-};
-
-#endif // DIVECARTESIANAXIS_H
diff --git a/desktop-widgets/profile/diveeventitem.cpp b/desktop-widgets/profile/diveeventitem.cpp
deleted file mode 100644
index 0bbc84267..000000000
--- a/desktop-widgets/profile/diveeventitem.cpp
+++ /dev/null
@@ -1,172 +0,0 @@
-#include "diveeventitem.h"
-#include "diveplotdatamodel.h"
-#include "divecartesianaxis.h"
-#include "animationfunctions.h"
-#include "libdivecomputer.h"
-#include "profile.h"
-#include "gettextfromc.h"
-#include "metrics.h"
-
-extern struct ev_select *ev_namelist;
-extern int evn_used;
-
-DiveEventItem::DiveEventItem(QObject *parent) : DivePixmapItem(parent),
- vAxis(NULL),
- hAxis(NULL),
- dataModel(NULL),
- internalEvent(NULL)
-{
- setFlag(ItemIgnoresTransformations);
-}
-
-
-void DiveEventItem::setHorizontalAxis(DiveCartesianAxis *axis)
-{
- hAxis = axis;
- recalculatePos(true);
-}
-
-void DiveEventItem::setModel(DivePlotDataModel *model)
-{
- dataModel = model;
- recalculatePos(true);
-}
-
-void DiveEventItem::setVerticalAxis(DiveCartesianAxis *axis)
-{
- vAxis = axis;
- recalculatePos(true);
- connect(vAxis, SIGNAL(sizeChanged()), this, SLOT(recalculatePos()));
-}
-
-struct event *DiveEventItem::getEvent()
-{
- return internalEvent;
-}
-
-void DiveEventItem::setEvent(struct event *ev)
-{
- if (!ev)
- return;
- internalEvent = ev;
- setupPixmap();
- setupToolTipString();
- recalculatePos(true);
-}
-
-void DiveEventItem::setupPixmap()
-{
- const IconMetrics& metrics = defaultIconMetrics();
- int sz_bigger = metrics.sz_med + metrics.sz_small; // ex 40px
- int sz_pix = sz_bigger/2; // ex 20px
-
-#define EVENT_PIXMAP(PIX) QPixmap(QString(PIX)).scaled(sz_pix, sz_pix, Qt::KeepAspectRatio, Qt::SmoothTransformation)
-#define EVENT_PIXMAP_BIGGER(PIX) QPixmap(QString(PIX)).scaled(sz_bigger, sz_bigger, Qt::KeepAspectRatio, Qt::SmoothTransformation)
- if (same_string(internalEvent->name, "")) {
- setPixmap(EVENT_PIXMAP(":warning"));
- } else if (internalEvent->type == SAMPLE_EVENT_BOOKMARK) {
- setPixmap(EVENT_PIXMAP(":flag"));
- } else if (strcmp(internalEvent->name, "heading") == 0 ||
- (same_string(internalEvent->name, "SP change") && internalEvent->time.seconds == 0)) {
- // 2 cases:
- // a) some dive computers have heading in every sample
- // b) at t=0 we might have an "SP change" to indicate dive type
- // in both cases we want to get the right data into the tooltip but don't want the visual clutter
- // so set an "almost invisible" pixmap (a narrow but somewhat tall, basically transparent pixmap)
- // that allows tooltips to work when we don't want to show a specific
- // pixmap for an event, but want to show the event value in the tooltip
- QPixmap transparentPixmap(4, 20);
- transparentPixmap.fill(QColor::fromRgbF(1.0, 1.0, 1.0, 0.01));
- setPixmap(transparentPixmap);
- } else if (event_is_gaschange(internalEvent)) {
- if (internalEvent->gas.mix.he.permille)
- setPixmap(EVENT_PIXMAP_BIGGER(":gaschangeTrimix"));
- else if (gasmix_is_air(&internalEvent->gas.mix))
- setPixmap(EVENT_PIXMAP_BIGGER(":gaschangeAir"));
- else
- setPixmap(EVENT_PIXMAP_BIGGER(":gaschangeNitrox"));
- } else {
- setPixmap(EVENT_PIXMAP(":warning"));
- }
-#undef EVENT_PIXMAP
-}
-
-void DiveEventItem::setupToolTipString()
-{
- // we display the event on screen - so translate
- QString name = gettextFromC::instance()->tr(internalEvent->name);
- int value = internalEvent->value;
- int type = internalEvent->type;
- if (value) {
- if (event_is_gaschange(internalEvent)) {
- name += ": ";
- name += gasname(&internalEvent->gas.mix);
-
- /* Do we have an explicit cylinder index? Show it. */
- if (internalEvent->gas.index >= 0)
- name += QString(" (cyl %1)").arg(internalEvent->gas.index+1);
- } else if (type == SAMPLE_EVENT_PO2 && name == "SP change") {
- name += QString(":%1").arg((double)value / 1000);
- } else {
- name += QString(":%1").arg(value);
- }
- } else if (type == SAMPLE_EVENT_PO2 && name == "SP change") {
- // this is a bad idea - we are abusing an existing event type that is supposed to
- // warn of high or low pOâ‚‚ and are turning it into a set point change event
- name += "\n" + tr("Manual switch to OC");
- } else {
- name += internalEvent->flags == SAMPLE_FLAGS_BEGIN ? tr(" begin", "Starts with space!") :
- internalEvent->flags == SAMPLE_FLAGS_END ? tr(" end", "Starts with space!") : "";
- }
- // qDebug() << name;
- setToolTip(name);
-}
-
-void DiveEventItem::eventVisibilityChanged(const QString &eventName, bool visible)
-{
-}
-
-bool DiveEventItem::shouldBeHidden()
-{
- struct event *event = internalEvent;
-
- /*
- * Some gas change events are special. Some dive computers just tell us the initial gas this way.
- * Don't bother showing those
- */
- struct sample *first_sample = &get_dive_dc(&displayed_dive, dc_number)->sample[0];
- if (!strcmp(event->name, "gaschange") &&
- (event->time.seconds == 0 ||
- (first_sample && event->time.seconds == first_sample->time.seconds)))
- return true;
-
- for (int i = 0; i < evn_used; i++) {
- if (!strcmp(event->name, ev_namelist[i].ev_name) && ev_namelist[i].plot_ev == false)
- return true;
- }
- return false;
-}
-
-void DiveEventItem::recalculatePos(bool instant)
-{
- if (!vAxis || !hAxis || !internalEvent || !dataModel)
- return;
-
- QModelIndexList result = dataModel->match(dataModel->index(0, DivePlotDataModel::TIME), Qt::DisplayRole, internalEvent->time.seconds);
- if (result.isEmpty()) {
- Q_ASSERT("can't find a spot in the dataModel");
- hide();
- return;
- }
- if (!isVisible() && !shouldBeHidden())
- show();
- int depth = dataModel->data(dataModel->index(result.first().row(), DivePlotDataModel::DEPTH)).toInt();
- qreal x = hAxis->posAtValue(internalEvent->time.seconds);
- qreal y = vAxis->posAtValue(depth);
- if (!instant)
- Animations::moveTo(this, x, y);
- else
- setPos(x, y);
- if (isVisible() && shouldBeHidden())
- hide();
-}
diff --git a/desktop-widgets/profile/diveeventitem.h b/desktop-widgets/profile/diveeventitem.h
deleted file mode 100644
index f358fee6d..000000000
--- a/desktop-widgets/profile/diveeventitem.h
+++ /dev/null
@@ -1,34 +0,0 @@
-#ifndef DIVEEVENTITEM_H
-#define DIVEEVENTITEM_H
-
-#include "divepixmapitem.h"
-
-class DiveCartesianAxis;
-class DivePlotDataModel;
-struct event;
-
-class DiveEventItem : public DivePixmapItem {
- Q_OBJECT
-public:
- DiveEventItem(QObject *parent = 0);
- void setEvent(struct event *ev);
- struct event *getEvent();
- void eventVisibilityChanged(const QString &eventName, bool visible);
- void setVerticalAxis(DiveCartesianAxis *axis);
- void setHorizontalAxis(DiveCartesianAxis *axis);
- void setModel(DivePlotDataModel *model);
- bool shouldBeHidden();
-public
-slots:
- void recalculatePos(bool instant = false);
-
-private:
- void setupToolTipString();
- void setupPixmap();
- DiveCartesianAxis *vAxis;
- DiveCartesianAxis *hAxis;
- DivePlotDataModel *dataModel;
- struct event *internalEvent;
-};
-
-#endif // DIVEEVENTITEM_H
diff --git a/desktop-widgets/profile/divelineitem.cpp b/desktop-widgets/profile/divelineitem.cpp
deleted file mode 100644
index f9e288a44..000000000
--- a/desktop-widgets/profile/divelineitem.cpp
+++ /dev/null
@@ -1,5 +0,0 @@
-#include "divelineitem.h"
-
-DiveLineItem::DiveLineItem(QGraphicsItem *parent) : QGraphicsLineItem(parent)
-{
-}
diff --git a/desktop-widgets/profile/divelineitem.h b/desktop-widgets/profile/divelineitem.h
deleted file mode 100644
index ec88e9da5..000000000
--- a/desktop-widgets/profile/divelineitem.h
+++ /dev/null
@@ -1,15 +0,0 @@
-#ifndef DIVELINEITEM_H
-#define DIVELINEITEM_H
-
-#include <QObject>
-#include <QGraphicsLineItem>
-
-class DiveLineItem : public QObject, public QGraphicsLineItem {
- Q_OBJECT
- Q_PROPERTY(QPointF pos READ pos WRITE setPos)
- Q_PROPERTY(qreal opacity READ opacity WRITE setOpacity)
-public:
- DiveLineItem(QGraphicsItem *parent = 0);
-};
-
-#endif // DIVELINEITEM_H
diff --git a/desktop-widgets/profile/divepixmapitem.cpp b/desktop-widgets/profile/divepixmapitem.cpp
deleted file mode 100644
index 581f6f9b4..000000000
--- a/desktop-widgets/profile/divepixmapitem.cpp
+++ /dev/null
@@ -1,130 +0,0 @@
-#include "divepixmapitem.h"
-#include "animationfunctions.h"
-#include "divepicturemodel.h"
-#include <preferences.h>
-
-#include <QDesktopServices>
-#include <QGraphicsView>
-#include <QUrl>
-
-DivePixmapItem::DivePixmapItem(QObject *parent) : QObject(parent), QGraphicsPixmapItem()
-{
-}
-
-DiveButtonItem::DiveButtonItem(QObject *parent): DivePixmapItem(parent)
-{
-}
-
-void DiveButtonItem::mousePressEvent(QGraphicsSceneMouseEvent *event)
-{
- QGraphicsItem::mousePressEvent(event);
- emit clicked();
-}
-
-// If we have many many pictures on screen, maybe a shared-pixmap would be better to
-// paint on screen, but for now, this.
-CloseButtonItem::CloseButtonItem(QObject *parent): DiveButtonItem(parent)
-{
- static QPixmap p = QPixmap(":trash");
- setPixmap(p);
- setFlag(ItemIgnoresTransformations);
-}
-
-void CloseButtonItem::hide()
-{
- DiveButtonItem::hide();
-}
-
-void CloseButtonItem::show()
-{
- DiveButtonItem::show();
-}
-
-DivePictureItem::DivePictureItem(QObject *parent): DivePixmapItem(parent),
- canvas(new QGraphicsRectItem(this)),
- shadow(new QGraphicsRectItem(this))
-{
- setFlag(ItemIgnoresTransformations);
- setAcceptHoverEvents(true);
- setScale(0.2);
- connect(PreferencesDialog::instance(), SIGNAL(settingsChanged()), this, SLOT(settingsChanged()));
- setVisible(prefs.show_pictures_in_profile);
-
- canvas->setPen(Qt::NoPen);
- canvas->setBrush(QColor(Qt::white));
- canvas->setFlag(ItemStacksBehindParent);
- canvas->setZValue(-1);
-
- shadow->setPos(5,5);
- shadow->setPen(Qt::NoPen);
- shadow->setBrush(QColor(Qt::lightGray));
- shadow->setFlag(ItemStacksBehindParent);
- shadow->setZValue(-2);
-}
-
-void DivePictureItem::settingsChanged()
-{
- setVisible(prefs.show_pictures_in_profile);
-}
-
-void DivePictureItem::setPixmap(const QPixmap &pix)
-{
- DivePixmapItem::setPixmap(pix);
- QRectF r = boundingRect();
- canvas->setRect(0 - 10, 0 -10, r.width() + 20, r.height() + 20);
- shadow->setRect(canvas->rect());
-}
-
-CloseButtonItem *button = NULL;
-void DivePictureItem::hoverEnterEvent(QGraphicsSceneHoverEvent *event)
-{
- Animations::scaleTo(this, 1.0);
- setZValue(5);
-
- if(!button) {
- button = new CloseButtonItem();
- button->setScale(0.2);
- button->setZValue(7);
- scene()->addItem(button);
- }
- button->setParentItem(this);
- button->setPos(boundingRect().width() - button->boundingRect().width() * 0.2,
- boundingRect().height() - button->boundingRect().height() * 0.2);
- button->setOpacity(0);
- button->show();
- Animations::show(button);
- button->disconnect();
- connect(button, SIGNAL(clicked()), this, SLOT(removePicture()));
-}
-
-void DivePictureItem::setFileUrl(const QString &s)
-{
- fileUrl = s;
-}
-
-void DivePictureItem::hoverLeaveEvent(QGraphicsSceneHoverEvent *event)
-{
- Animations::scaleTo(this, 0.2);
- setZValue(0);
- if(button){
- button->setParentItem(NULL);
- Animations::hide(button);
- }
-}
-
-DivePictureItem::~DivePictureItem(){
- if(button){
- button->setParentItem(NULL);
- Animations::hide(button);
- }
-}
-
-void DivePictureItem::mousePressEvent(QGraphicsSceneMouseEvent *event)
-{
- QDesktopServices::openUrl(QUrl::fromLocalFile(fileUrl));
-}
-
-void DivePictureItem::removePicture()
-{
- DivePictureModel::instance()->removePicture(fileUrl);
-}
diff --git a/desktop-widgets/profile/divepixmapitem.h b/desktop-widgets/profile/divepixmapitem.h
deleted file mode 100644
index 02c1523f7..000000000
--- a/desktop-widgets/profile/divepixmapitem.h
+++ /dev/null
@@ -1,57 +0,0 @@
-#ifndef DIVEPIXMAPITEM_H
-#define DIVEPIXMAPITEM_H
-
-#include <QObject>
-#include <QGraphicsPixmapItem>
-
-class DivePixmapItem : public QObject, public QGraphicsPixmapItem {
- Q_OBJECT
- Q_PROPERTY(qreal opacity WRITE setOpacity READ opacity)
- Q_PROPERTY(QPointF pos WRITE setPos READ pos)
- Q_PROPERTY(qreal x WRITE setX READ x)
- Q_PROPERTY(qreal y WRITE setY READ y)
-public:
- DivePixmapItem(QObject *parent = 0);
-};
-
-class DivePictureItem : public DivePixmapItem {
- Q_OBJECT
- Q_PROPERTY(qreal scale WRITE setScale READ scale)
-public:
- DivePictureItem(QObject *parent = 0);
- virtual ~DivePictureItem();
- void setPixmap(const QPixmap& pix);
-public slots:
- void settingsChanged();
- void removePicture();
- void setFileUrl(const QString& s);
-protected:
- void hoverEnterEvent(QGraphicsSceneHoverEvent *event);
- void hoverLeaveEvent(QGraphicsSceneHoverEvent *event);
- void mousePressEvent(QGraphicsSceneMouseEvent *event);
-private:
- QString fileUrl;
- QGraphicsRectItem *canvas;
- QGraphicsRectItem *shadow;
-};
-
-class DiveButtonItem : public DivePixmapItem {
- Q_OBJECT
-public:
- DiveButtonItem(QObject *parent = 0);
-protected:
- virtual void mousePressEvent(QGraphicsSceneMouseEvent *event);
-signals:
- void clicked();
-};
-
-class CloseButtonItem : public DiveButtonItem {
- Q_OBJECT
-public:
- CloseButtonItem(QObject *parent = 0);
-public slots:
- void hide();
- void show();
-};
-
-#endif // DIVEPIXMAPITEM_H
diff --git a/desktop-widgets/profile/diveprofileitem.cpp b/desktop-widgets/profile/diveprofileitem.cpp
deleted file mode 100644
index 2c814678a..000000000
--- a/desktop-widgets/profile/diveprofileitem.cpp
+++ /dev/null
@@ -1,979 +0,0 @@
-#include "diveprofileitem.h"
-#include "diveplotdatamodel.h"
-#include "divecartesianaxis.h"
-#include "divetextitem.h"
-#include "animationfunctions.h"
-#include "dive.h"
-#include "profile.h"
-#include "preferences.h"
-#include "diveplannermodel.h"
-#include "helpers.h"
-#include "libdivecomputer/parser.h"
-#include "mainwindow.h"
-#include "maintab.h"
-#include "profile/profilewidget2.h"
-#include "diveplanner.h"
-
-#include <QSettings>
-
-AbstractProfilePolygonItem::AbstractProfilePolygonItem() : QObject(), QGraphicsPolygonItem(), hAxis(NULL), vAxis(NULL), dataModel(NULL), hDataColumn(-1), vDataColumn(-1)
-{
- setCacheMode(DeviceCoordinateCache);
- connect(PreferencesDialog::instance(), SIGNAL(settingsChanged()), this, SLOT(settingsChanged()));
-}
-
-void AbstractProfilePolygonItem::settingsChanged()
-{
-}
-
-void AbstractProfilePolygonItem::setHorizontalAxis(DiveCartesianAxis *horizontal)
-{
- hAxis = horizontal;
- connect(hAxis, SIGNAL(sizeChanged()), this, SLOT(modelDataChanged()));
- modelDataChanged();
-}
-
-void AbstractProfilePolygonItem::setHorizontalDataColumn(int column)
-{
- hDataColumn = column;
- modelDataChanged();
-}
-
-void AbstractProfilePolygonItem::setModel(DivePlotDataModel *model)
-{
- dataModel = model;
- connect(dataModel, SIGNAL(dataChanged(QModelIndex, QModelIndex)), this, SLOT(modelDataChanged(QModelIndex, QModelIndex)));
- connect(dataModel, SIGNAL(rowsAboutToBeRemoved(QModelIndex, int, int)), this, SLOT(modelDataRemoved(QModelIndex, int, int)));
- modelDataChanged();
-}
-
-void AbstractProfilePolygonItem::modelDataRemoved(const QModelIndex &parent, int from, int to)
-{
- setPolygon(QPolygonF());
- qDeleteAll(texts);
- texts.clear();
-}
-
-void AbstractProfilePolygonItem::setVerticalAxis(DiveCartesianAxis *vertical)
-{
- vAxis = vertical;
- connect(vAxis, SIGNAL(sizeChanged()), this, SLOT(modelDataChanged()));
- connect(vAxis, SIGNAL(maxChanged()), this, SLOT(modelDataChanged()));
- modelDataChanged();
-}
-
-void AbstractProfilePolygonItem::setVerticalDataColumn(int column)
-{
- vDataColumn = column;
- modelDataChanged();
-}
-
-bool AbstractProfilePolygonItem::shouldCalculateStuff(const QModelIndex &topLeft, const QModelIndex &bottomRight)
-{
- if (!hAxis || !vAxis)
- return false;
- if (!dataModel || dataModel->rowCount() == 0)
- return false;
- if (hDataColumn == -1 || vDataColumn == -1)
- return false;
- if (topLeft.isValid() && bottomRight.isValid()) {
- if ((topLeft.column() >= vDataColumn || topLeft.column() >= hDataColumn) &&
- (bottomRight.column() <= vDataColumn || topLeft.column() <= hDataColumn)) {
- return true;
- }
- }
- return true;
-}
-
-void AbstractProfilePolygonItem::modelDataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight)
-{
- // We don't have enougth data to calculate things, quit.
-
- // Calculate the polygon. This is the polygon that will be painted on screen
- // on the ::paint method. Here we calculate the correct position of the points
- // regarting our cartesian plane ( made by the hAxis and vAxis ), the QPolygonF
- // is an array of QPointF's, so we basically get the point from the model, convert
- // to our coordinates, store. no painting is done here.
- QPolygonF poly;
- for (int i = 0, modelDataCount = dataModel->rowCount(); i < modelDataCount; i++) {
- qreal horizontalValue = dataModel->index(i, hDataColumn).data().toReal();
- qreal verticalValue = dataModel->index(i, vDataColumn).data().toReal();
- QPointF point(hAxis->posAtValue(horizontalValue), vAxis->posAtValue(verticalValue));
- poly.append(point);
- }
- setPolygon(poly);
-
- qDeleteAll(texts);
- texts.clear();
-}
-
-DiveProfileItem::DiveProfileItem() : show_reported_ceiling(0), reported_ceiling_in_red(0)
-{
-}
-
-void DiveProfileItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
-{
- Q_UNUSED(widget);
- if (polygon().isEmpty())
- return;
-
- painter->save();
- // This paints the Polygon + Background. I'm setting the pen to QPen() so we don't get a black line here,
- // after all we need to plot the correct velocities colors later.
- setPen(Qt::NoPen);
- QGraphicsPolygonItem::paint(painter, option, widget);
-
- // Here we actually paint the boundaries of the Polygon using the colors that the model provides.
- // Those are the speed colors of the dives.
- QPen pen;
- pen.setCosmetic(true);
- pen.setWidth(2);
- QPolygonF poly = polygon();
- // This paints the colors of the velocities.
- for (int i = 1, count = dataModel->rowCount(); i < count; i++) {
- QModelIndex colorIndex = dataModel->index(i, DivePlotDataModel::COLOR);
- pen.setBrush(QBrush(colorIndex.data(Qt::BackgroundRole).value<QColor>()));
- painter->setPen(pen);
- painter->drawLine(poly[i - 1], poly[i]);
- }
- painter->restore();
-}
-
-int DiveProfileItem::maxCeiling(int row)
-{
- int max = -1;
- plot_data *entry = dataModel->data().entry + row;
- for (int tissue = 0; tissue < 16; tissue++) {
- if (max < entry->ceilings[tissue])
- max = entry->ceilings[tissue];
- }
- return max;
-}
-
-void DiveProfileItem::modelDataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight)
-{
- bool eventAdded = false;
- if (!shouldCalculateStuff(topLeft, bottomRight))
- return;
-
- AbstractProfilePolygonItem::modelDataChanged(topLeft, bottomRight);
- if (polygon().isEmpty())
- return;
-
- show_reported_ceiling = prefs.dcceiling;
- reported_ceiling_in_red = prefs.redceiling;
- profileColor = getColor(DEPTH_BOTTOM);
-
- int currState = qobject_cast<ProfileWidget2 *>(scene()->views().first())->currentState;
- if (currState == ProfileWidget2::PLAN) {
- plot_data *entry = dataModel->data().entry;
- for (int i = 0; i < dataModel->rowCount(); i++, entry++) {
- int max = maxCeiling(i);
- // Don't scream if we violate the ceiling by a few cm
- if (entry->depth < max - 100 && entry->sec > 0) {
- profileColor = QColor(Qt::red);
- if (!eventAdded) {
- add_event(&displayed_dive.dc, entry->sec, SAMPLE_EVENT_CEILING, -1, max / 1000, "planned waypoint above ceiling");
- eventAdded = true;
- }
- }
- }
- }
-
- /* Show any ceiling we may have encountered */
- if (prefs.dcceiling && !prefs.redceiling) {
- QPolygonF p = polygon();
- plot_data *entry = dataModel->data().entry + dataModel->rowCount() - 1;
- for (int i = dataModel->rowCount() - 1; i >= 0; i--, entry--) {
- if (!entry->in_deco) {
- /* not in deco implies this is a safety stop, no ceiling */
- p.append(QPointF(hAxis->posAtValue(entry->sec), vAxis->posAtValue(0)));
- } else {
- p.append(QPointF(hAxis->posAtValue(entry->sec), vAxis->posAtValue(qMin(entry->stopdepth, entry->depth))));
- }
- }
- setPolygon(p);
- }
-
- // This is the blueish gradient that the Depth Profile should have.
- // It's a simple QLinearGradient with 2 stops, starting from top to bottom.
- QLinearGradient pat(0, polygon().boundingRect().top(), 0, polygon().boundingRect().bottom());
- pat.setColorAt(1, profileColor);
- pat.setColorAt(0, getColor(DEPTH_TOP));
- setBrush(QBrush(pat));
-
- int last = -1;
- for (int i = 0, count = dataModel->rowCount(); i < count; i++) {
-
- struct plot_data *entry = dataModel->data().entry + i;
- if (entry->depth < 2000)
- continue;
-
- if ((entry == entry->max[2]) && entry->depth / 100 != last) {
- plot_depth_sample(entry, Qt::AlignHCenter | Qt::AlignBottom, getColor(SAMPLE_DEEP));
- last = entry->depth / 100;
- }
-
- if ((entry == entry->min[2]) && entry->depth / 100 != last) {
- plot_depth_sample(entry, Qt::AlignHCenter | Qt::AlignTop, getColor(SAMPLE_SHALLOW));
- last = entry->depth / 100;
- }
-
- if (entry->depth != last)
- last = -1;
- }
-}
-
-void DiveProfileItem::settingsChanged()
-{
- //TODO: Only modelDataChanged() here if we need to rebuild the graph ( for instance,
- // if the prefs.dcceiling are enabled, but prefs.redceiling is disabled
- // and only if it changed something. let's not waste cpu cycles repoloting something we don't need to.
- modelDataChanged();
-}
-
-void DiveProfileItem::plot_depth_sample(struct plot_data *entry, QFlags<Qt::AlignmentFlag> flags, const QColor &color)
-{
- int decimals;
- double d = get_depth_units(entry->depth, &decimals, NULL);
- DiveTextItem *item = new DiveTextItem(this);
- item->setPos(hAxis->posAtValue(entry->sec), vAxis->posAtValue(entry->depth));
- item->setText(QString("%1").arg(d, 0, 'f', 1));
- item->setAlignment(flags);
- item->setBrush(color);
- texts.append(item);
-}
-
-DiveHeartrateItem::DiveHeartrateItem()
-{
- QPen pen;
- pen.setBrush(QBrush(getColor(::HR_PLOT)));
- pen.setCosmetic(true);
- pen.setWidth(1);
- setPen(pen);
- settingsChanged();
-}
-
-void DiveHeartrateItem::modelDataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight)
-{
- int last = -300, last_printed_hr = 0, sec = 0;
- struct {
- int sec;
- int hr;
- } hist[3] = {};
-
- // We don't have enougth data to calculate things, quit.
- if (!shouldCalculateStuff(topLeft, bottomRight))
- return;
-
- qDeleteAll(texts);
- texts.clear();
- // Ignore empty values. a heartrate of 0 would be a bad sign.
- QPolygonF poly;
- for (int i = 0, modelDataCount = dataModel->rowCount(); i < modelDataCount; i++) {
- int hr = dataModel->index(i, vDataColumn).data().toInt();
- if (!hr)
- continue;
- sec = dataModel->index(i, hDataColumn).data().toInt();
- QPointF point(hAxis->posAtValue(sec), vAxis->posAtValue(hr));
- poly.append(point);
- if (hr == hist[2].hr)
- // same as last one, no point in looking at printing
- continue;
- hist[0] = hist[1];
- hist[1] = hist[2];
- hist[2].sec = sec;
- hist[2].hr = hr;
- // don't print a HR
- // if it's not a local min / max
- // if it's been less than 5min and less than a 20 beats change OR
- // if it's been less than 2min OR if the change from the
- // last print is less than 10 beats
- // to test min / max requires three points, so we now look at the
- // previous one
- sec = hist[1].sec;
- hr = hist[1].hr;
- if ((hist[0].hr < hr && hr < hist[2].hr) ||
- (hist[0].hr > hr && hr > hist[2].hr) ||
- ((sec < last + 300) && (abs(hr - last_printed_hr) < 20)) ||
- (sec < last + 120) ||
- (abs(hr - last_printed_hr) < 10))
- continue;
- last = sec;
- createTextItem(sec, hr);
- last_printed_hr = hr;
- }
- setPolygon(poly);
-
- if (texts.count())
- texts.last()->setAlignment(Qt::AlignLeft | Qt::AlignBottom);
-}
-
-void DiveHeartrateItem::createTextItem(int sec, int hr)
-{
- DiveTextItem *text = new DiveTextItem(this);
- text->setAlignment(Qt::AlignRight | Qt::AlignBottom);
- text->setBrush(getColor(HR_TEXT));
- text->setPos(QPointF(hAxis->posAtValue(sec), vAxis->posAtValue(hr)));
- text->setScale(0.7); // need to call this BEFORE setText()
- text->setText(QString("%1").arg(hr));
- texts.append(text);
-}
-
-void DiveHeartrateItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
-{
- if (polygon().isEmpty())
- return;
- painter->save();
- painter->setPen(pen());
- painter->drawPolyline(polygon());
- painter->restore();
-}
-
-void DiveHeartrateItem::settingsChanged()
-{
- setVisible(prefs.hrgraph);
-}
-
-DivePercentageItem::DivePercentageItem(int i)
-{
- QPen pen;
- QColor color;
- color.setHsl(100 + 10 * i, 200, 100);
- pen.setBrush(QBrush(color));
- pen.setCosmetic(true);
- pen.setWidth(1);
- setPen(pen);
- settingsChanged();
-}
-
-void DivePercentageItem::modelDataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight)
-{
- int sec = 0;
-
- // We don't have enougth data to calculate things, quit.
- if (!shouldCalculateStuff(topLeft, bottomRight))
- return;
-
- // Ignore empty values. a heartrate of 0 would be a bad sign.
- QPolygonF poly;
- for (int i = 0, modelDataCount = dataModel->rowCount(); i < modelDataCount; i++) {
- int hr = dataModel->index(i, vDataColumn).data().toInt();
- if (!hr)
- continue;
- sec = dataModel->index(i, hDataColumn).data().toInt();
- QPointF point(hAxis->posAtValue(sec), vAxis->posAtValue(hr));
- poly.append(point);
- }
- setPolygon(poly);
-
- if (texts.count())
- texts.last()->setAlignment(Qt::AlignLeft | Qt::AlignBottom);
-}
-
-void DivePercentageItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
-{
- if (polygon().isEmpty())
- return;
- painter->save();
- painter->setPen(pen());
- painter->drawPolyline(polygon());
- painter->restore();
-}
-
-void DivePercentageItem::settingsChanged()
-{
- setVisible(prefs.percentagegraph);
-}
-
-DiveAmbPressureItem::DiveAmbPressureItem()
-{
- QPen pen;
- pen.setBrush(QBrush(getColor(::AMB_PRESSURE_LINE)));
- pen.setCosmetic(true);
- pen.setWidth(2);
- setPen(pen);
- settingsChanged();
-}
-
-void DiveAmbPressureItem::modelDataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight)
-{
- int sec = 0;
-
- // We don't have enougth data to calculate things, quit.
- if (!shouldCalculateStuff(topLeft, bottomRight))
- return;
-
- // Ignore empty values. a heartrate of 0 would be a bad sign.
- QPolygonF poly;
- for (int i = 0, modelDataCount = dataModel->rowCount(); i < modelDataCount; i++) {
- int hr = dataModel->index(i, vDataColumn).data().toInt();
- if (!hr)
- continue;
- sec = dataModel->index(i, hDataColumn).data().toInt();
- QPointF point(hAxis->posAtValue(sec), vAxis->posAtValue(hr));
- poly.append(point);
- }
- setPolygon(poly);
-
- if (texts.count())
- texts.last()->setAlignment(Qt::AlignLeft | Qt::AlignBottom);
-}
-
-void DiveAmbPressureItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
-{
- if (polygon().isEmpty())
- return;
- painter->save();
- painter->setPen(pen());
- painter->drawPolyline(polygon());
- painter->restore();
-}
-
-void DiveAmbPressureItem::settingsChanged()
-{
- setVisible(prefs.percentagegraph);
-}
-
-DiveGFLineItem::DiveGFLineItem()
-{
- QPen pen;
- pen.setBrush(QBrush(getColor(::GF_LINE)));
- pen.setCosmetic(true);
- pen.setWidth(2);
- setPen(pen);
- settingsChanged();
-}
-
-void DiveGFLineItem::modelDataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight)
-{
- int sec = 0;
-
- // We don't have enougth data to calculate things, quit.
- if (!shouldCalculateStuff(topLeft, bottomRight))
- return;
-
- // Ignore empty values. a heartrate of 0 would be a bad sign.
- QPolygonF poly;
- for (int i = 0, modelDataCount = dataModel->rowCount(); i < modelDataCount; i++) {
- int hr = dataModel->index(i, vDataColumn).data().toInt();
- if (!hr)
- continue;
- sec = dataModel->index(i, hDataColumn).data().toInt();
- QPointF point(hAxis->posAtValue(sec), vAxis->posAtValue(hr));
- poly.append(point);
- }
- setPolygon(poly);
-
- if (texts.count())
- texts.last()->setAlignment(Qt::AlignLeft | Qt::AlignBottom);
-}
-
-void DiveGFLineItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
-{
- if (polygon().isEmpty())
- return;
- painter->save();
- painter->setPen(pen());
- painter->drawPolyline(polygon());
- painter->restore();
-}
-
-void DiveGFLineItem::settingsChanged()
-{
- setVisible(prefs.percentagegraph);
-}
-
-DiveTemperatureItem::DiveTemperatureItem()
-{
- QPen pen;
- pen.setBrush(QBrush(getColor(::TEMP_PLOT)));
- pen.setCosmetic(true);
- pen.setWidth(2);
- setPen(pen);
-}
-
-void DiveTemperatureItem::modelDataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight)
-{
- int last = -300, last_printed_temp = 0, sec = 0, last_valid_temp = 0;
- // We don't have enougth data to calculate things, quit.
- if (!shouldCalculateStuff(topLeft, bottomRight))
- return;
-
- qDeleteAll(texts);
- texts.clear();
- // Ignore empty values. things do not look good with '0' as temperature in kelvin...
- QPolygonF poly;
- for (int i = 0, modelDataCount = dataModel->rowCount(); i < modelDataCount; i++) {
- int mkelvin = dataModel->index(i, vDataColumn).data().toInt();
- if (!mkelvin)
- continue;
- last_valid_temp = mkelvin;
- sec = dataModel->index(i, hDataColumn).data().toInt();
- QPointF point(hAxis->posAtValue(sec), vAxis->posAtValue(mkelvin));
- poly.append(point);
-
- /* don't print a temperature
- * if it's been less than 5min and less than a 2K change OR
- * if it's been less than 2min OR if the change from the
- * last print is less than .4K (and therefore less than 1F) */
- if (((sec < last + 300) && (abs(mkelvin - last_printed_temp) < 2000)) ||
- (sec < last + 120) ||
- (abs(mkelvin - last_printed_temp) < 400))
- continue;
- last = sec;
- if (mkelvin > 200000)
- createTextItem(sec, mkelvin);
- last_printed_temp = mkelvin;
- }
- setPolygon(poly);
-
- /* it would be nice to print the end temperature, if it's
- * different or if the last temperature print has been more
- * than a quarter of the dive back */
- if (last_valid_temp > 200000 &&
- ((abs(last_valid_temp - last_printed_temp) > 500) || ((double)last / (double)sec < 0.75))) {
- createTextItem(sec, last_valid_temp);
- }
- if (texts.count())
- texts.last()->setAlignment(Qt::AlignLeft | Qt::AlignBottom);
-}
-
-void DiveTemperatureItem::createTextItem(int sec, int mkelvin)
-{
- double deg;
- const char *unit;
- deg = get_temp_units(mkelvin, &unit);
-
- DiveTextItem *text = new DiveTextItem(this);
- text->setAlignment(Qt::AlignRight | Qt::AlignBottom);
- text->setBrush(getColor(TEMP_TEXT));
- text->setPos(QPointF(hAxis->posAtValue(sec), vAxis->posAtValue(mkelvin)));
- text->setScale(0.8); // need to call this BEFORE setText()
- text->setText(QString("%1%2").arg(deg, 0, 'f', 1).arg(unit));
- texts.append(text);
-}
-
-void DiveTemperatureItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
-{
- if (polygon().isEmpty())
- return;
- painter->save();
- painter->setPen(pen());
- painter->drawPolyline(polygon());
- painter->restore();
-}
-
-DiveMeanDepthItem::DiveMeanDepthItem()
-{
- QPen pen;
- pen.setBrush(QBrush(getColor(::HR_AXIS)));
- pen.setCosmetic(true);
- pen.setWidth(2);
- setPen(pen);
- settingsChanged();
-}
-
-void DiveMeanDepthItem::modelDataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight)
-{
- double meandepthvalue = 0.0;
- // We don't have enougth data to calculate things, quit.
- if (!shouldCalculateStuff(topLeft, bottomRight))
- return;
-
- QPolygonF poly;
- plot_data *entry = dataModel->data().entry;
- for (int i = 0, modelDataCount = dataModel->rowCount(); i < modelDataCount; i++, entry++) {
- // Ignore empty values
- if (entry->running_sum == 0 || entry->sec == 0)
- continue;
-
- meandepthvalue = entry->running_sum / entry->sec;
- QPointF point(hAxis->posAtValue(entry->sec), vAxis->posAtValue(meandepthvalue));
- poly.append(point);
- }
- lastRunningSum = meandepthvalue;
- setPolygon(poly);
- createTextItem();
-}
-
-
-void DiveMeanDepthItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
-{
- if (polygon().isEmpty())
- return;
- painter->save();
- painter->setPen(pen());
- painter->drawPolyline(polygon());
- painter->restore();
-}
-
-void DiveMeanDepthItem::settingsChanged()
-{
- setVisible(prefs.show_average_depth);
-}
-
-void DiveMeanDepthItem::createTextItem() {
- plot_data *entry = dataModel->data().entry;
- int sec = entry[dataModel->rowCount()-1].sec;
- qDeleteAll(texts);
- texts.clear();
- int decimals;
- const char *unitText;
- double d = get_depth_units(lastRunningSum, &decimals, &unitText);
- DiveTextItem *text = new DiveTextItem(this);
- text->setAlignment(Qt::AlignRight | Qt::AlignTop);
- text->setBrush(getColor(TEMP_TEXT));
- text->setPos(QPointF(hAxis->posAtValue(sec) + 1, vAxis->posAtValue(lastRunningSum)));
- text->setScale(0.8); // need to call this BEFORE setText()
- text->setText(QString("%1%2").arg(d, 0, 'f', 1).arg(unitText));
- texts.append(text);
-}
-
-void DiveGasPressureItem::modelDataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight)
-{
- // We don't have enougth data to calculate things, quit.
- if (!shouldCalculateStuff(topLeft, bottomRight))
- return;
- int last_index = -1;
- int o2mbar;
- QPolygonF boundingPoly, o2Poly; // This is the "Whole Item", but a pressure can be divided in N Polygons.
- polygons.clear();
- if (displayed_dive.dc.divemode == CCR)
- polygons.append(o2Poly);
-
- for (int i = 0, count = dataModel->rowCount(); i < count; i++) {
- o2mbar = 0;
- plot_data *entry = dataModel->data().entry + i;
- int mbar = GET_PRESSURE(entry);
- if (displayed_dive.dc.divemode == CCR)
- o2mbar = GET_O2CYLINDER_PRESSURE(entry);
-
- if (entry->cylinderindex != last_index) {
- polygons.append(QPolygonF()); // this is the polygon that will be actually drawn on screen.
- last_index = entry->cylinderindex;
- }
- if (!mbar) {
- continue;
- }
- if (o2mbar) {
- QPointF o2point(hAxis->posAtValue(entry->sec), vAxis->posAtValue(o2mbar));
- boundingPoly.push_back(o2point);
- polygons.first().push_back(o2point);
- }
-
- QPointF point(hAxis->posAtValue(entry->sec), vAxis->posAtValue(mbar));
- boundingPoly.push_back(point); // The BoundingRect
- polygons.last().push_back(point); // The polygon thta will be plotted.
- }
- setPolygon(boundingPoly);
- qDeleteAll(texts);
- texts.clear();
- int mbar, cyl;
- int seen_cyl[MAX_CYLINDERS] = { false, };
- int last_pressure[MAX_CYLINDERS] = { 0, };
- int last_time[MAX_CYLINDERS] = { 0, };
- struct plot_data *entry;
-
- cyl = -1;
- o2mbar = 0;
-
- double print_y_offset[8][2] = { { 0, -0.5 }, { 0, -0.5 }, { 0, -0.5 }, { 0, -0.5 }, { 0, -0.5 } ,{ 0, -0.5 }, { 0, -0.5 }, { 0, -0.5 } };
- // CCR dives: These are offset values used to print the gas lables and pressures on a CCR dive profile at
- // appropriate Y-coordinates: One doublet of values for each of 8 cylinders.
- // Order of offsets within a doublet: gas lable offset; gas pressure offset.
- // The array is initialised with default values that apply to non-CCR dives.
-
- bool offsets_initialised = false;
- int o2cyl = -1, dilcyl = -1;
- QFlags<Qt::AlignmentFlag> alignVar= Qt::AlignTop, align_dil = Qt::AlignBottom, align_o2 = Qt::AlignTop;
- double axisRange = (vAxis->maximum() - vAxis->minimum())/1000; // Convert axis pressure range to bar
- double axisLog = log10(log10(axisRange));
- for (int i = 0, count = dataModel->rowCount(); i < count; i++) {
- entry = dataModel->data().entry + i;
- mbar = GET_PRESSURE(entry);
- if (displayed_dive.dc.divemode == CCR && displayed_dive.oxygen_cylinder_index >= 0)
- o2mbar = GET_O2CYLINDER_PRESSURE(entry);
-
- if (o2mbar) { // If there is an o2mbar value then this is a CCR dive. Then do:
- // The first time an o2 value is detected, see if the oxygen cyl pressure graph starts above or below the dil graph
- if (!offsets_initialised) { // Initialise the parameters for placing the text correctly near the graph line:
- o2cyl = displayed_dive.oxygen_cylinder_index;
- dilcyl = displayed_dive.diluent_cylinder_index;
- if ((o2mbar > mbar)) { // If above, write o2 start cyl pressure above graph and diluent pressure below graph:
- print_y_offset[o2cyl][0] = -7 * axisLog; // y offset for oxygen gas lable (above); pressure offsets=-0.5, already initialised
- print_y_offset[dilcyl][0] = 5 * axisLog; // y offset for diluent gas lable (below)
- } else { // ... else write o2 start cyl pressure below graph:
- print_y_offset[o2cyl][0] = 5 * axisLog; // o2 lable & pressure below graph; pressure offsets=-0.5, already initialised
- print_y_offset[dilcyl][0] = -7.8 * axisLog; // and diluent lable above graph.
- align_dil = Qt::AlignTop;
- align_o2 = Qt::AlignBottom;
- }
- offsets_initialised = true;
- }
-
- if (!seen_cyl[displayed_dive.oxygen_cylinder_index]) { //For o2, on the left of profile, write lable and pressure
- plotPressureValue(o2mbar, entry->sec, align_o2, print_y_offset[o2cyl][1]);
- plotGasValue(o2mbar, entry->sec, displayed_dive.cylinder[displayed_dive.oxygen_cylinder_index].gasmix, align_o2, print_y_offset[o2cyl][0]);
- seen_cyl[displayed_dive.oxygen_cylinder_index] = true;
- }
- last_pressure[displayed_dive.oxygen_cylinder_index] = o2mbar;
- last_time[displayed_dive.oxygen_cylinder_index] = entry->sec;
- alignVar = align_dil;
- }
-
- if (!mbar)
- continue;
-
- if (cyl != entry->cylinderindex) { // Pressure value near the left hand edge of the profile - other cylinders:
- cyl = entry->cylinderindex; // For each other cylinder, write the gas lable and pressure
- if (!seen_cyl[cyl]) {
- plotPressureValue(mbar, entry->sec, alignVar, print_y_offset[cyl][1]);
- plotGasValue(mbar, entry->sec, displayed_dive.cylinder[cyl].gasmix, align_dil, print_y_offset[cyl][0]);
- seen_cyl[cyl] = true;
- }
- }
- last_pressure[cyl] = mbar;
- last_time[cyl] = entry->sec;
- }
-
- for (cyl = 0; cyl < MAX_CYLINDERS; cyl++) { // For each cylinder, on right hand side of profile, write cylinder pressure
- alignVar = ((o2cyl >= 0) && (cyl == displayed_dive.oxygen_cylinder_index)) ? align_o2 : align_dil;
- if (last_time[cyl]) {
- plotPressureValue(last_pressure[cyl], last_time[cyl], (alignVar | Qt::AlignLeft), print_y_offset[cyl][1]);
- }
- }
-}
-
-void DiveGasPressureItem::plotPressureValue(int mbar, int sec, QFlags<Qt::AlignmentFlag> align, double pressure_offset)
-{
- const char *unit;
- int pressure = get_pressure_units(mbar, &unit);
- DiveTextItem *text = new DiveTextItem(this);
- text->setPos(hAxis->posAtValue(sec), vAxis->posAtValue(mbar) + pressure_offset );
- text->setText(QString("%1 %2").arg(pressure).arg(unit));
- text->setAlignment(align);
- text->setBrush(getColor(PRESSURE_TEXT));
- texts.push_back(text);
-}
-
-void DiveGasPressureItem::plotGasValue(int mbar, int sec, struct gasmix gasmix, QFlags<Qt::AlignmentFlag> align, double gasname_offset)
-{
- QString gas = get_gas_string(gasmix);
- DiveTextItem *text = new DiveTextItem(this);
- text->setPos(hAxis->posAtValue(sec), vAxis->posAtValue(mbar) + gasname_offset );
- text->setText(gas);
- text->setAlignment(align);
- text->setBrush(getColor(PRESSURE_TEXT));
- texts.push_back(text);
-}
-
-void DiveGasPressureItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
-{
- if (polygon().isEmpty())
- return;
- QPen pen;
- pen.setCosmetic(true);
- pen.setWidth(2);
- painter->save();
- struct plot_data *entry;
- Q_FOREACH (const QPolygonF &poly, polygons) {
- entry = dataModel->data().entry;
- for (int i = 1, count = poly.count(); i < count; i++, entry++) {
- if (entry->sac)
- pen.setBrush(getSacColor(entry->sac, displayed_dive.sac));
- else
- pen.setBrush(MED_GRAY_HIGH_TRANS);
- painter->setPen(pen);
- painter->drawLine(poly[i - 1], poly[i]);
- }
- }
- painter->restore();
-}
-
-DiveCalculatedCeiling::DiveCalculatedCeiling() : is3mIncrement(false)
-{
- settingsChanged();
-}
-
-void DiveCalculatedCeiling::modelDataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight)
-{
- if (MainWindow::instance()->information())
- connect(MainWindow::instance()->information(), SIGNAL(dateTimeChanged()), this, SLOT(recalc()), Qt::UniqueConnection);
-
- // We don't have enougth data to calculate things, quit.
- if (!shouldCalculateStuff(topLeft, bottomRight))
- return;
- AbstractProfilePolygonItem::modelDataChanged(topLeft, bottomRight);
- // Add 2 points to close the polygon.
- QPolygonF poly = polygon();
- if (poly.isEmpty())
- return;
- QPointF p1 = poly.first();
- QPointF p2 = poly.last();
-
- poly.prepend(QPointF(p1.x(), vAxis->posAtValue(0)));
- poly.append(QPointF(p2.x(), vAxis->posAtValue(0)));
- setPolygon(poly);
-
- QLinearGradient pat(0, polygon().boundingRect().top(), 0, polygon().boundingRect().bottom());
- pat.setColorAt(0, getColor(CALC_CEILING_SHALLOW));
- pat.setColorAt(1, getColor(CALC_CEILING_DEEP));
- setPen(QPen(QBrush(Qt::NoBrush), 0));
- setBrush(pat);
-}
-
-void DiveCalculatedCeiling::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
-{
- if (polygon().isEmpty())
- return;
- QGraphicsPolygonItem::paint(painter, option, widget);
-}
-
-DiveCalculatedTissue::DiveCalculatedTissue()
-{
- settingsChanged();
-}
-
-void DiveCalculatedTissue::settingsChanged()
-{
- setVisible(prefs.calcalltissues && prefs.calcceiling);
-}
-
-void DiveReportedCeiling::modelDataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight)
-{
- if (!shouldCalculateStuff(topLeft, bottomRight))
- return;
-
- QPolygonF p;
- p.append(QPointF(hAxis->posAtValue(0), vAxis->posAtValue(0)));
- plot_data *entry = dataModel->data().entry;
- for (int i = 0, count = dataModel->rowCount(); i < count; i++, entry++) {
- if (entry->in_deco && entry->stopdepth) {
- p.append(QPointF(hAxis->posAtValue(entry->sec), vAxis->posAtValue(qMin(entry->stopdepth, entry->depth))));
- } else {
- p.append(QPointF(hAxis->posAtValue(entry->sec), vAxis->posAtValue(0)));
- }
- }
- setPolygon(p);
- QLinearGradient pat(0, p.boundingRect().top(), 0, p.boundingRect().bottom());
- // does the user want the ceiling in "surface color" or in red?
- if (prefs.redceiling) {
- pat.setColorAt(0, getColor(CEILING_SHALLOW));
- pat.setColorAt(1, getColor(CEILING_DEEP));
- } else {
- pat.setColorAt(0, getColor(BACKGROUND_TRANS));
- pat.setColorAt(1, getColor(BACKGROUND_TRANS));
- }
- setPen(QPen(QBrush(Qt::NoBrush), 0));
- setBrush(pat);
-}
-
-void DiveCalculatedCeiling::recalc()
-{
- dataModel->calculateDecompression();
-}
-
-void DiveCalculatedCeiling::settingsChanged()
-{
- if (dataModel && is3mIncrement != prefs.calcceiling3m) {
- // recalculate that part.
- recalc();
- }
- is3mIncrement = prefs.calcceiling3m;
- setVisible(prefs.calcceiling);
-}
-
-void DiveReportedCeiling::settingsChanged()
-{
- setVisible(prefs.dcceiling);
-}
-
-void DiveReportedCeiling::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
-{
- if (polygon().isEmpty())
- return;
- QGraphicsPolygonItem::paint(painter, option, widget);
-}
-
-void PartialPressureGasItem::modelDataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight)
-{
- //AbstractProfilePolygonItem::modelDataChanged();
- if (!shouldCalculateStuff(topLeft, bottomRight))
- return;
-
- plot_data *entry = dataModel->data().entry;
- QPolygonF poly;
- QPolygonF alertpoly;
- alertPolygons.clear();
- QSettings s;
- s.beginGroup("TecDetails");
- double threshold = 0.0;
- if (thresholdPtr)
- threshold = *thresholdPtr;
- bool inAlertFragment = false;
- for (int i = 0; i < dataModel->rowCount(); i++, entry++) {
- double value = dataModel->index(i, vDataColumn).data().toDouble();
- int time = dataModel->index(i, hDataColumn).data().toInt();
- QPointF point(hAxis->posAtValue(time), vAxis->posAtValue(value));
- poly.push_back(point);
- if (value >= threshold) {
- if (inAlertFragment) {
- alertPolygons.back().push_back(point);
- } else {
- alertpoly.clear();
- alertpoly.push_back(point);
- alertPolygons.append(alertpoly);
- inAlertFragment = true;
- }
- } else {
- inAlertFragment = false;
- }
- }
- setPolygon(poly);
- /*
- createPPLegend(trUtf8("pN" UTF8_SUBSCRIPT_2),getColor(PN2), legendPos);
- */
-}
-
-void PartialPressureGasItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
-{
- const qreal pWidth = 0.0;
- painter->save();
- painter->setPen(QPen(normalColor, pWidth));
- painter->drawPolyline(polygon());
-
- QPolygonF poly;
- painter->setPen(QPen(alertColor, pWidth));
- Q_FOREACH (const QPolygonF &poly, alertPolygons)
- painter->drawPolyline(poly);
- painter->restore();
-}
-
-void PartialPressureGasItem::setThreshouldSettingsKey(double *prefPointer)
-{
- thresholdPtr = prefPointer;
-}
-
-PartialPressureGasItem::PartialPressureGasItem() :
- thresholdPtr(NULL)
-{
-}
-
-void PartialPressureGasItem::settingsChanged()
-{
- QSettings s;
- s.beginGroup("TecDetails");
- setVisible(s.value(visibilityKey).toBool());
-}
-
-void PartialPressureGasItem::setVisibilitySettingsKey(const QString &key)
-{
- visibilityKey = key;
-}
-
-void PartialPressureGasItem::setColors(const QColor &normal, const QColor &alert)
-{
- normalColor = normal;
- alertColor = alert;
-}
diff --git a/desktop-widgets/profile/diveprofileitem.h b/desktop-widgets/profile/diveprofileitem.h
deleted file mode 100644
index 0bba7f7a3..000000000
--- a/desktop-widgets/profile/diveprofileitem.h
+++ /dev/null
@@ -1,225 +0,0 @@
-#ifndef DIVEPROFILEITEM_H
-#define DIVEPROFILEITEM_H
-
-#include <QObject>
-#include <QGraphicsPolygonItem>
-#include <QModelIndex>
-
-#include "divelineitem.h"
-
-/* This is the Profile Item, it should be used for quite a lot of things
- on the profile view. The usage should be pretty simple:
-
- DiveProfileItem *profile = new DiveProfileItem();
- profile->setVerticalAxis( profileYAxis );
- profile->setHorizontalAxis( timeAxis );
- profile->setModel( DiveDataModel );
- profile->setHorizontalDataColumn( DiveDataModel::TIME );
- profile->setVerticalDataColumn( DiveDataModel::DEPTH );
- scene()->addItem(profile);
-
- This is a generically item and should be used as a base for others, I think...
-*/
-
-class DivePlotDataModel;
-class DiveTextItem;
-class DiveCartesianAxis;
-class QAbstractTableModel;
-struct plot_data;
-
-class AbstractProfilePolygonItem : public QObject, public QGraphicsPolygonItem {
- Q_OBJECT
- Q_PROPERTY(QPointF pos WRITE setPos READ pos)
- Q_PROPERTY(qreal x WRITE setX READ x)
- Q_PROPERTY(qreal y WRITE setY READ y)
-public:
- AbstractProfilePolygonItem();
- void setVerticalAxis(DiveCartesianAxis *vertical);
- void setHorizontalAxis(DiveCartesianAxis *horizontal);
- void setModel(DivePlotDataModel *model);
- void setHorizontalDataColumn(int column);
- void setVerticalDataColumn(int column);
- virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0) = 0;
- virtual void clear()
- {
- }
-public
-slots:
- virtual void settingsChanged();
- virtual void modelDataChanged(const QModelIndex &topLeft = QModelIndex(), const QModelIndex &bottomRight = QModelIndex());
- virtual void modelDataRemoved(const QModelIndex &parent, int from, int to);
-
-protected:
- /* when the model emits a 'datachanged' signal, this method below should be used to check if the
- * modified data affects this particular item ( for example, when setting the '3m increment'
- * the data for Ceiling and tissues will be changed, and only those. so, the topLeft will be the CEILING
- * column and the bottomRight will have the TISSUE_16 column. this method takes the vDataColumn and hDataColumn
- * into consideration when returning 'true' for "yes, continue the calculation', and 'false' for
- * 'do not recalculate, we already have the right data.
- */
- bool shouldCalculateStuff(const QModelIndex &topLeft, const QModelIndex &bottomRight);
-
- DiveCartesianAxis *hAxis;
- DiveCartesianAxis *vAxis;
- DivePlotDataModel *dataModel;
- int hDataColumn;
- int vDataColumn;
- QList<DiveTextItem *> texts;
-};
-
-class DiveProfileItem : public AbstractProfilePolygonItem {
- Q_OBJECT
-
-public:
- DiveProfileItem();
- virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0);
- virtual void modelDataChanged(const QModelIndex &topLeft = QModelIndex(), const QModelIndex &bottomRight = QModelIndex());
- virtual void settingsChanged();
- void plot_depth_sample(struct plot_data *entry, QFlags<Qt::AlignmentFlag> flags, const QColor &color);
- int maxCeiling(int row);
-
-private:
- unsigned int show_reported_ceiling;
- unsigned int reported_ceiling_in_red;
- QColor profileColor;
-};
-
-class DiveMeanDepthItem : public AbstractProfilePolygonItem {
- Q_OBJECT
-public:
- DiveMeanDepthItem();
- virtual void modelDataChanged(const QModelIndex &topLeft = QModelIndex(), const QModelIndex &bottomRight = QModelIndex());
- virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0);
- virtual void settingsChanged();
-
-private:
- void createTextItem();
- double lastRunningSum;
- QString visibilityKey;
-};
-
-class DiveTemperatureItem : public AbstractProfilePolygonItem {
- Q_OBJECT
-public:
- DiveTemperatureItem();
- virtual void modelDataChanged(const QModelIndex &topLeft = QModelIndex(), const QModelIndex &bottomRight = QModelIndex());
- virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0);
-
-private:
- void createTextItem(int seconds, int mkelvin);
-};
-
-class DiveHeartrateItem : public AbstractProfilePolygonItem {
- Q_OBJECT
-public:
- DiveHeartrateItem();
- virtual void modelDataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight);
- virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
- virtual void settingsChanged();
-
-private:
- void createTextItem(int seconds, int hr);
- QString visibilityKey;
-};
-
-class DivePercentageItem : public AbstractProfilePolygonItem {
- Q_OBJECT
-public:
- DivePercentageItem(int i);
- virtual void modelDataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight);
- virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
- virtual void settingsChanged();
-
-private:
- QString visibilityKey;
-};
-
-class DiveAmbPressureItem : public AbstractProfilePolygonItem {
- Q_OBJECT
-public:
- DiveAmbPressureItem();
- virtual void modelDataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight);
- virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
- virtual void settingsChanged();
-
-private:
- QString visibilityKey;
-};
-
-class DiveGFLineItem : public AbstractProfilePolygonItem {
- Q_OBJECT
-public:
- DiveGFLineItem();
- virtual void modelDataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight);
- virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
- virtual void settingsChanged();
-
-private:
- QString visibilityKey;
-};
-
-class DiveGasPressureItem : public AbstractProfilePolygonItem {
- Q_OBJECT
-
-public:
- virtual void modelDataChanged(const QModelIndex &topLeft = QModelIndex(), const QModelIndex &bottomRight = QModelIndex());
- virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0);
-
-private:
- void plotPressureValue(int mbar, int sec, QFlags<Qt::AlignmentFlag> align, double offset);
- void plotGasValue(int mbar, int sec, struct gasmix gasmix, QFlags<Qt::AlignmentFlag> align, double offset);
- QVector<QPolygonF> polygons;
-};
-
-class DiveCalculatedCeiling : public AbstractProfilePolygonItem {
- Q_OBJECT
-
-public:
- DiveCalculatedCeiling();
- virtual void modelDataChanged(const QModelIndex &topLeft = QModelIndex(), const QModelIndex &bottomRight = QModelIndex());
- virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0);
- virtual void settingsChanged();
-
-public
-slots:
- void recalc();
-
-private:
- bool is3mIncrement;
-};
-
-class DiveReportedCeiling : public AbstractProfilePolygonItem {
- Q_OBJECT
-
-public:
- virtual void modelDataChanged(const QModelIndex &topLeft = QModelIndex(), const QModelIndex &bottomRight = QModelIndex());
- virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0);
- virtual void settingsChanged();
-};
-
-class DiveCalculatedTissue : public DiveCalculatedCeiling {
- Q_OBJECT
-public:
- DiveCalculatedTissue();
- virtual void settingsChanged();
-};
-
-class PartialPressureGasItem : public AbstractProfilePolygonItem {
- Q_OBJECT
-public:
- PartialPressureGasItem();
- virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0);
- virtual void modelDataChanged(const QModelIndex &topLeft = QModelIndex(), const QModelIndex &bottomRight = QModelIndex());
- virtual void settingsChanged();
- void setThreshouldSettingsKey(double *prefPointer);
- void setVisibilitySettingsKey(const QString &setVisibilitySettingsKey);
- void setColors(const QColor &normalColor, const QColor &alertColor);
-
-private:
- QVector<QPolygonF> alertPolygons;
- double *thresholdPtr;
- QString visibilityKey;
- QColor normalColor;
- QColor alertColor;
-};
-#endif // DIVEPROFILEITEM_H
diff --git a/desktop-widgets/profile/diverectitem.cpp b/desktop-widgets/profile/diverectitem.cpp
deleted file mode 100644
index 8cb60c3f5..000000000
--- a/desktop-widgets/profile/diverectitem.cpp
+++ /dev/null
@@ -1,5 +0,0 @@
-#include "diverectitem.h"
-
-DiveRectItem::DiveRectItem(QObject *parent, QGraphicsItem *parentItem) : QObject(parent), QGraphicsRectItem(parentItem)
-{
-}
diff --git a/desktop-widgets/profile/diverectitem.h b/desktop-widgets/profile/diverectitem.h
deleted file mode 100644
index e616cf591..000000000
--- a/desktop-widgets/profile/diverectitem.h
+++ /dev/null
@@ -1,17 +0,0 @@
-#ifndef DIVERECTITEM_H
-#define DIVERECTITEM_H
-
-#include <QObject>
-#include <QGraphicsRectItem>
-
-class DiveRectItem : public QObject, public QGraphicsRectItem {
- Q_OBJECT
- Q_PROPERTY(QRectF rect WRITE setRect READ rect)
- Q_PROPERTY(QPointF pos WRITE setPos READ pos)
- Q_PROPERTY(qreal x WRITE setX READ x)
- Q_PROPERTY(qreal y WRITE setY READ y)
-public:
- DiveRectItem(QObject *parent = 0, QGraphicsItem *parentItem = 0);
-};
-
-#endif // DIVERECTITEM_H
diff --git a/desktop-widgets/profile/divetextitem.cpp b/desktop-widgets/profile/divetextitem.cpp
deleted file mode 100644
index 3bf00d68f..000000000
--- a/desktop-widgets/profile/divetextitem.cpp
+++ /dev/null
@@ -1,113 +0,0 @@
-#include "divetextitem.h"
-#include "mainwindow.h"
-#include "profilewidget2.h"
-#include "subsurface-core/color.h"
-
-#include <QBrush>
-
-DiveTextItem::DiveTextItem(QGraphicsItem *parent) : QGraphicsItemGroup(parent),
- internalAlignFlags(Qt::AlignHCenter | Qt::AlignVCenter),
- textBackgroundItem(new QGraphicsPathItem(this)),
- textItem(new QGraphicsPathItem(this)),
- printScale(1.0),
- scale(1.0),
- connected(false)
-{
- setFlag(ItemIgnoresTransformations);
- textBackgroundItem->setBrush(QBrush(getColor(TEXT_BACKGROUND)));
- textBackgroundItem->setPen(Qt::NoPen);
- textItem->setPen(Qt::NoPen);
-}
-
-void DiveTextItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
-{
- updateText();
- QGraphicsItemGroup::paint(painter, option, widget);
-}
-
-void DiveTextItem::fontPrintScaleUpdate(double scale)
-{
- printScale = scale;
-}
-
-void DiveTextItem::setAlignment(int alignFlags)
-{
- if (alignFlags != internalAlignFlags) {
- internalAlignFlags = alignFlags;
- }
-}
-
-void DiveTextItem::setBrush(const QBrush &b)
-{
- textItem->setBrush(b);
-}
-
-void DiveTextItem::setScale(double newscale)
-{
- if (scale != newscale) {
- scale = newscale;
- }
-}
-
-void DiveTextItem::setText(const QString &t)
-{
- if (internalText != t) {
- if (!connected) {
- if (scene()) {
- // by now we should be on a scene. grab the profile widget from it and setup our printScale
- // and connect to the signal that makes sure we keep track if that changes
- ProfileWidget2 *profile = qobject_cast<ProfileWidget2 *>(scene()->views().first());
- connect(profile, SIGNAL(fontPrintScaleChanged(double)), this, SLOT(fontPrintScaleUpdate(double)), Qt::UniqueConnection);
- fontPrintScaleUpdate(profile->getFontPrintScale());
- connected = true;
- } else {
- qDebug() << "called before scene was set up" << t;
- }
- }
- internalText = t;
- updateText();
- }
-}
-
-const QString &DiveTextItem::text()
-{
- return internalText;
-}
-
-void DiveTextItem::updateText()
-{
- double size;
- if (internalText.isEmpty()) {
- return;
- }
-
- QFont fnt(qApp->font());
- if ((size = fnt.pixelSize()) > 0) {
- // set in pixels - so the scale factor may not make a difference if it's too close to 1
- size *= scale * printScale;
- fnt.setPixelSize(size);
- } else {
- size = fnt.pointSizeF();
- size *= scale * printScale;
- fnt.setPointSizeF(size);
- }
- QFontMetrics fm(fnt);
-
- QPainterPath textPath;
- qreal xPos = 0, yPos = 0;
-
- QRectF rect = fm.boundingRect(internalText);
- yPos = (internalAlignFlags & Qt::AlignTop) ? 0 :
- (internalAlignFlags & Qt::AlignBottom) ? +rect.height() :
- /*(internalAlignFlags & Qt::AlignVCenter ? */ +rect.height() / 4;
-
- xPos = (internalAlignFlags & Qt::AlignLeft) ? -rect.width() :
- (internalAlignFlags & Qt::AlignHCenter) ? -rect.width() / 2 :
- /* (internalAlignFlags & Qt::AlignRight) */ 0;
-
- textPath.addText(xPos, yPos, fnt, internalText);
- QPainterPathStroker stroker;
- stroker.setWidth(3);
- textBackgroundItem->setPath(stroker.createStroke(textPath));
- textItem->setPath(textPath);
-}
diff --git a/desktop-widgets/profile/divetextitem.h b/desktop-widgets/profile/divetextitem.h
deleted file mode 100644
index be0adf292..000000000
--- a/desktop-widgets/profile/divetextitem.h
+++ /dev/null
@@ -1,38 +0,0 @@
-#ifndef DIVETEXTITEM_H
-#define DIVETEXTITEM_H
-
-#include <QObject>
-#include <QGraphicsItemGroup>
-
-class QBrush;
-
-/* A Line Item that has animated-properties. */
-class DiveTextItem : public QObject, public QGraphicsItemGroup {
- Q_OBJECT
- Q_PROPERTY(QPointF pos READ pos WRITE setPos)
- Q_PROPERTY(qreal opacity READ opacity WRITE setOpacity)
-public:
- DiveTextItem(QGraphicsItem *parent = 0);
- void setText(const QString &text);
- void setAlignment(int alignFlags);
- void setScale(double newscale);
- void setBrush(const QBrush &brush);
- const QString &text();
- void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
-
-private
-slots:
- void fontPrintScaleUpdate(double scale);
-
-private:
- void updateText();
- int internalAlignFlags;
- QGraphicsPathItem *textBackgroundItem;
- QGraphicsPathItem *textItem;
- QString internalText;
- double printScale;
- double scale;
- bool connected;
-};
-
-#endif // DIVETEXTITEM_H
diff --git a/desktop-widgets/profile/divetooltipitem.cpp b/desktop-widgets/profile/divetooltipitem.cpp
deleted file mode 100644
index d4818422b..000000000
--- a/desktop-widgets/profile/divetooltipitem.cpp
+++ /dev/null
@@ -1,285 +0,0 @@
-#include "divetooltipitem.h"
-#include "divecartesianaxis.h"
-#include "dive.h"
-#include "profile.h"
-#include "membuffer.h"
-#include "metrics.h"
-#include <QPropertyAnimation>
-#include <QSettings>
-#include <QGraphicsView>
-#include <QStyleOptionGraphicsItem>
-
-#define PORT_IN_PROGRESS 1
-#ifdef PORT_IN_PROGRESS
-#include "display.h"
-#endif
-
-void ToolTipItem::addToolTip(const QString &toolTip, const QIcon &icon, const QPixmap& pixmap)
-{
- const IconMetrics& iconMetrics = defaultIconMetrics();
-
- QGraphicsPixmapItem *iconItem = 0;
- double yValue = title->boundingRect().height() + iconMetrics.spacing;
- Q_FOREACH (ToolTip t, toolTips) {
- yValue += t.second->boundingRect().height();
- }
- if (entryToolTip.second) {
- yValue += entryToolTip.second->boundingRect().height();
- }
- iconItem = new QGraphicsPixmapItem(this);
- if (!icon.isNull()) {
- iconItem->setPixmap(icon.pixmap(iconMetrics.sz_small, iconMetrics.sz_small));
- } else if (!pixmap.isNull()) {
- iconItem->setPixmap(pixmap);
- }
- iconItem->setPos(iconMetrics.spacing, yValue);
-
- QGraphicsSimpleTextItem *textItem = new QGraphicsSimpleTextItem(toolTip, this);
- textItem->setPos(iconMetrics.spacing + iconMetrics.sz_small + iconMetrics.spacing, yValue);
- textItem->setBrush(QBrush(Qt::white));
- textItem->setFlag(ItemIgnoresTransformations);
- toolTips.push_back(qMakePair(iconItem, textItem));
-}
-
-void ToolTipItem::clear()
-{
- Q_FOREACH (ToolTip t, toolTips) {
- delete t.first;
- delete t.second;
- }
- toolTips.clear();
-}
-
-void ToolTipItem::setRect(const QRectF &r)
-{
- if( r == rect() ) {
- return;
- }
-
- QGraphicsRectItem::setRect(r);
- updateTitlePosition();
-}
-
-void ToolTipItem::collapse()
-{
- int dim = defaultIconMetrics().sz_small;
-
- if (prefs.animation_speed) {
- QPropertyAnimation *animation = new QPropertyAnimation(this, "rect");
- animation->setDuration(100);
- animation->setStartValue(nextRectangle);
- animation->setEndValue(QRect(0, 0, dim, dim));
- animation->start(QAbstractAnimation::DeleteWhenStopped);
- } else {
- setRect(nextRectangle);
- }
- clear();
-
- status = COLLAPSED;
-}
-
-void ToolTipItem::expand()
-{
- if (!title)
- return;
-
- const IconMetrics& iconMetrics = defaultIconMetrics();
-
- double width = 0, height = title->boundingRect().height() + iconMetrics.spacing;
- Q_FOREACH (const ToolTip& t, toolTips) {
- QRectF sRect = t.second->boundingRect();
- if (sRect.width() > width)
- width = sRect.width();
- height += sRect.height();
- }
-
- if (entryToolTip.first) {
- QRectF sRect = entryToolTip.second->boundingRect();
- if (sRect.width() > width)
- width = sRect.width();
- height += sRect.height();
- }
-
- /* Left padding, Icon Size, space, right padding */
- width += iconMetrics.spacing + iconMetrics.sz_small + iconMetrics.spacing + iconMetrics.spacing;
-
- if (width < title->boundingRect().width() + iconMetrics.spacing * 2)
- width = title->boundingRect().width() + iconMetrics.spacing * 2;
-
- if (height < iconMetrics.sz_small)
- height = iconMetrics.sz_small;
-
- nextRectangle.setWidth(width);
- nextRectangle.setHeight(height);
-
- if (nextRectangle != rect()) {
- if (prefs.animation_speed) {
- QPropertyAnimation *animation = new QPropertyAnimation(this, "rect", this);
- animation->setDuration(prefs.animation_speed);
- animation->setStartValue(rect());
- animation->setEndValue(nextRectangle);
- animation->start(QAbstractAnimation::DeleteWhenStopped);
- } else {
- setRect(nextRectangle);
- }
- }
-
- status = EXPANDED;
-}
-
-ToolTipItem::ToolTipItem(QGraphicsItem *parent) : QGraphicsRectItem(parent),
- title(new QGraphicsSimpleTextItem(tr("Information"), this)),
- status(COLLAPSED),
- timeAxis(0),
- lastTime(-1)
-{
- memset(&pInfo, 0, sizeof(pInfo));
- entryToolTip.first = NULL;
- entryToolTip.second = NULL;
- setFlags(ItemIgnoresTransformations | ItemIsMovable | ItemClipsChildrenToShape);
-
- QColor c = QColor(Qt::black);
- c.setAlpha(155);
- setBrush(c);
-
- setZValue(99);
-
- addToolTip(QString(), QIcon(), QPixmap(16,60));
- entryToolTip = toolTips.first();
- toolTips.clear();
-
- title->setFlag(ItemIgnoresTransformations);
- title->setPen(QPen(Qt::white, 1));
- title->setBrush(Qt::white);
-
- setPen(QPen(Qt::white, 2));
- refreshTime.start();
-}
-
-ToolTipItem::~ToolTipItem()
-{
- clear();
-}
-
-void ToolTipItem::updateTitlePosition()
-{
- const IconMetrics& iconMetrics = defaultIconMetrics();
- if (rect().width() < title->boundingRect().width() + iconMetrics.spacing * 4) {
- QRectF newRect = rect();
- newRect.setWidth(title->boundingRect().width() + iconMetrics.spacing * 4);
- newRect.setHeight((newRect.height() && isExpanded()) ? newRect.height() : iconMetrics.sz_small);
- setRect(newRect);
- }
-
- title->setPos(rect().width() / 2 - title->boundingRect().width() / 2 - 1, 0);
-}
-
-bool ToolTipItem::isExpanded() const
-{
- return status == EXPANDED;
-}
-
-void ToolTipItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
-{
- persistPos();
- QGraphicsRectItem::mouseReleaseEvent(event);
- Q_FOREACH (QGraphicsItem *item, oldSelection) {
- item->setSelected(true);
- }
-}
-
-void ToolTipItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
-{
- Q_UNUSED(widget);
- painter->save();
- painter->setClipRect(option->rect);
- painter->setPen(pen());
- painter->setBrush(brush());
- painter->drawRoundedRect(rect(), 10, 10, Qt::AbsoluteSize);
- painter->restore();
-}
-
-void ToolTipItem::persistPos()
-{
- QSettings s;
- s.beginGroup("ProfileMap");
- s.setValue("tooltip_position", pos());
- s.endGroup();
-}
-
-void ToolTipItem::readPos()
-{
- QSettings s;
- s.beginGroup("ProfileMap");
- QPointF value = s.value("tooltip_position").toPoint();
- if (!scene()->sceneRect().contains(value)) {
- value = QPointF(0, 0);
- }
- setPos(value);
-}
-
-void ToolTipItem::setPlotInfo(const plot_info &plot)
-{
- pInfo = plot;
-}
-
-void ToolTipItem::setTimeAxis(DiveCartesianAxis *axis)
-{
- timeAxis = axis;
-}
-
-void ToolTipItem::refresh(const QPointF &pos)
-{
- struct plot_data *entry;
- static QPixmap tissues(16,60);
- static QPainter painter(&tissues);
- static struct membuffer mb = { 0 };
-
- if(refreshTime.elapsed() < 40)
- return;
- refreshTime.start();
-
- int time = timeAxis->valueAt(pos);
- if (time == lastTime)
- return;
-
- lastTime = time;
- clear();
-
- mb.len = 0;
- entry = get_plot_details_new(&pInfo, time, &mb);
- if (entry) {
- tissues.fill();
- painter.setPen(QColor(0, 0, 0, 0));
- painter.setBrush(QColor(LIMENADE1));
- painter.drawRect(0, 10 + (100 - AMB_PERCENTAGE) / 2, 16, AMB_PERCENTAGE / 2);
- painter.setBrush(QColor(SPRINGWOOD1));
- painter.drawRect(0, 10, 16, (100 - AMB_PERCENTAGE) / 2);
- painter.setBrush(QColor(Qt::red));
- painter.drawRect(0,0,16,10);
- painter.setPen(QColor(0, 0, 0, 255));
- painter.drawLine(0, 60 - entry->gfline / 2, 16, 60 - entry->gfline / 2);
- painter.drawLine(0, 60 - AMB_PERCENTAGE * (entry->pressures.n2 + entry->pressures.he) / entry->ambpressure / 2,
- 16, 60 - AMB_PERCENTAGE * (entry->pressures.n2 + entry->pressures.he) / entry->ambpressure /2);
- painter.setPen(QColor(0, 0, 0, 127));
- for (int i=0; i<16; i++) {
- painter.drawLine(i, 60, i, 60 - entry->percentages[i] / 2);
- }
- entryToolTip.first->setPixmap(tissues);
- entryToolTip.second->setText(QString::fromUtf8(mb.buffer, mb.len));
- }
-
- Q_FOREACH (QGraphicsItem *item, scene()->items(pos, Qt::IntersectsItemBoundingRect
- ,Qt::DescendingOrder, scene()->views().first()->transform())) {
- if (!item->toolTip().isEmpty())
- addToolTip(item->toolTip());
- }
- expand();
-}
-
-void ToolTipItem::mousePressEvent(QGraphicsSceneMouseEvent *event)
-{
- oldSelection = scene()->selectedItems();
- scene()->clearSelection();
- QGraphicsItem::mousePressEvent(event);
-}
diff --git a/desktop-widgets/profile/divetooltipitem.h b/desktop-widgets/profile/divetooltipitem.h
deleted file mode 100644
index 4fa7ec2d7..000000000
--- a/desktop-widgets/profile/divetooltipitem.h
+++ /dev/null
@@ -1,67 +0,0 @@
-#ifndef DIVETOOLTIPITEM_H
-#define DIVETOOLTIPITEM_H
-
-#include <QGraphicsRectItem>
-#include <QVector>
-#include <QPair>
-#include <QRectF>
-#include <QIcon>
-#include <QTime>
-#include "display.h"
-
-class DiveCartesianAxis;
-class QGraphicsLineItem;
-class QGraphicsSimpleTextItem;
-class QGraphicsPixmapItem;
-struct graphics_context;
-
-/* To use a tooltip, simply ->setToolTip on the QGraphicsItem that you want
- * or, if it's a "global" tooltip, set it on the mouseMoveEvent of the ProfileGraphicsView.
- */
-class ToolTipItem : public QObject, public QGraphicsRectItem {
- Q_OBJECT
- void updateTitlePosition();
- Q_PROPERTY(QRectF rect READ rect WRITE setRect)
-
-public:
- enum Status {
- COLLAPSED,
- EXPANDED
- };
-
- explicit ToolTipItem(QGraphicsItem *parent = 0);
- virtual ~ToolTipItem();
-
- void collapse();
- void expand();
- void clear();
- void addToolTip(const QString &toolTip, const QIcon &icon = QIcon(), const QPixmap &pixmap = QPixmap());
- void refresh(const QPointF &pos);
- bool isExpanded() const;
- void persistPos();
- void readPos();
- void mousePressEvent(QGraphicsSceneMouseEvent *event);
- void mouseReleaseEvent(QGraphicsSceneMouseEvent *event);
- void setTimeAxis(DiveCartesianAxis *axis);
- void setPlotInfo(const plot_info &plot);
- void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
-public
-slots:
- void setRect(const QRectF &rect);
-
-private:
- typedef QPair<QGraphicsPixmapItem *, QGraphicsSimpleTextItem *> ToolTip;
- QVector<ToolTip> toolTips;
- ToolTip entryToolTip;
- QGraphicsSimpleTextItem *title;
- Status status;
- QRectF rectangle;
- QRectF nextRectangle;
- DiveCartesianAxis *timeAxis;
- plot_info pInfo;
- int lastTime;
- QTime refreshTime;
- QList<QGraphicsItem*> oldSelection;
-};
-
-#endif // DIVETOOLTIPITEM_H
diff --git a/desktop-widgets/profile/profilewidget2.cpp b/desktop-widgets/profile/profilewidget2.cpp
deleted file mode 100644
index 3ccd1bb6d..000000000
--- a/desktop-widgets/profile/profilewidget2.cpp
+++ /dev/null
@@ -1,1836 +0,0 @@
-#include "profilewidget2.h"
-#include "diveplotdatamodel.h"
-#include "helpers.h"
-#include "profile.h"
-#include "diveeventitem.h"
-#include "divetextitem.h"
-#include "divetooltipitem.h"
-#include "planner.h"
-#include "device.h"
-#include "ruleritem.h"
-#include "tankitem.h"
-#include "pref.h"
-#include "divepicturewidget.h"
-#include "diveplannermodel.h"
-#include "models.h"
-#include "divepicturemodel.h"
-#include "maintab.h"
-#include "diveplanner.h"
-
-#include <libdivecomputer/parser.h>
-#include <QScrollBar>
-#include <QtCore/qmath.h>
-#include <QMessageBox>
-#include <QInputDialog>
-#include <QDebug>
-#include <QWheelEvent>
-
-#ifndef QT_NO_DEBUG
-#include <QTableView>
-#endif
-#include "mainwindow.h"
-#include <preferences.h>
-
-/* This is the global 'Item position' variable.
- * it should tell you where to position things up
- * on the canvas.
- *
- * please, please, please, use this instead of
- * hard coding the item on the scene with a random
- * value.
- */
-static struct _ItemPos {
- struct _Pos {
- QPointF on;
- QPointF off;
- };
- struct _Axis {
- _Pos pos;
- QLineF shrinked;
- QLineF expanded;
- QLineF intermediate;
- };
- _Pos background;
- _Pos dcLabel;
- _Pos tankBar;
- _Axis depth;
- _Axis partialPressure;
- _Axis partialPressureTissue;
- _Axis partialPressureWithTankBar;
- _Axis percentage;
- _Axis percentageWithTankBar;
- _Axis time;
- _Axis cylinder;
- _Axis temperature;
- _Axis temperatureAll;
- _Axis heartBeat;
- _Axis heartBeatWithTankBar;
-} itemPos;
-
-ProfileWidget2::ProfileWidget2(QWidget *parent) : QGraphicsView(parent),
- currentState(INVALID),
- dataModel(new DivePlotDataModel(this)),
- zoomLevel(0),
- zoomFactor(1.15),
- background(new DivePixmapItem()),
- backgroundFile(":poster"),
- toolTipItem(new ToolTipItem()),
- isPlotZoomed(prefs.zoomed_plot),// no! bad use of prefs. 'PreferencesDialog::loadSettings' NOT CALLED yet.
- profileYAxis(new DepthAxis()),
- gasYAxis(new PartialGasPressureAxis()),
- temperatureAxis(new TemperatureAxis()),
- timeAxis(new TimeAxis()),
- diveProfileItem(new DiveProfileItem()),
- temperatureItem(new DiveTemperatureItem()),
- meanDepthItem(new DiveMeanDepthItem()),
- cylinderPressureAxis(new DiveCartesianAxis()),
- gasPressureItem(new DiveGasPressureItem()),
- diveComputerText(new DiveTextItem()),
- diveCeiling(new DiveCalculatedCeiling()),
- gradientFactor(new DiveTextItem()),
- reportedCeiling(new DiveReportedCeiling()),
- pn2GasItem(new PartialPressureGasItem()),
- pheGasItem(new PartialPressureGasItem()),
- po2GasItem(new PartialPressureGasItem()),
- o2SetpointGasItem(new PartialPressureGasItem()),
- ccrsensor1GasItem(new PartialPressureGasItem()),
- ccrsensor2GasItem(new PartialPressureGasItem()),
- ccrsensor3GasItem(new PartialPressureGasItem()),
- heartBeatAxis(new DiveCartesianAxis()),
- heartBeatItem(new DiveHeartrateItem()),
- percentageAxis(new DiveCartesianAxis()),
- ambPressureItem(new DiveAmbPressureItem()),
- gflineItem(new DiveGFLineItem()),
- mouseFollowerVertical(new DiveLineItem()),
- mouseFollowerHorizontal(new DiveLineItem()),
- rulerItem(new RulerItem2()),
- tankItem(new TankItem()),
- isGrayscale(false),
- printMode(false),
- shouldCalculateMaxTime(true),
- shouldCalculateMaxDepth(true),
- fontPrintScale(1.0)
-{
- // would like to be able to ASSERT here that PreferencesDialog::loadSettings has been called.
- isPlotZoomed = prefs.zoomed_plot; // now it seems that 'prefs' has loaded our preferences
-
- memset(&plotInfo, 0, sizeof(plotInfo));
-
- setupSceneAndFlags();
- setupItemSizes();
- setupItemOnScene();
- addItemsToScene();
- scene()->installEventFilter(this);
- connect(PreferencesDialog::instance(), SIGNAL(settingsChanged()), this, SLOT(settingsChanged()));
- QAction *action = NULL;
-#define ADD_ACTION(SHORTCUT, Slot) \
- action = new QAction(this); \
- action->setShortcut(SHORTCUT); \
- action->setShortcutContext(Qt::WindowShortcut); \
- addAction(action); \
- connect(action, SIGNAL(triggered(bool)), this, SLOT(Slot)); \
- actionsForKeys[SHORTCUT] = action;
-
- ADD_ACTION(Qt::Key_Escape, keyEscAction());
- ADD_ACTION(Qt::Key_Delete, keyDeleteAction());
- ADD_ACTION(Qt::Key_Up, keyUpAction());
- ADD_ACTION(Qt::Key_Down, keyDownAction());
- ADD_ACTION(Qt::Key_Left, keyLeftAction());
- ADD_ACTION(Qt::Key_Right, keyRightAction());
-#undef ADD_ACTION
-
-#if !defined(QT_NO_DEBUG) && defined(SHOW_PLOT_INFO_TABLE)
- QTableView *diveDepthTableView = new QTableView();
- diveDepthTableView->setModel(dataModel);
- diveDepthTableView->show();
-#endif
-}
-
-
-ProfileWidget2::~ProfileWidget2()
-{
- delete background;
- delete toolTipItem;
- delete profileYAxis;
- delete gasYAxis;
- delete temperatureAxis;
- delete timeAxis;
- delete diveProfileItem;
- delete temperatureItem;
- delete meanDepthItem;
- delete cylinderPressureAxis;
- delete gasPressureItem;
- delete diveComputerText;
- delete diveCeiling;
- delete reportedCeiling;
- delete pn2GasItem;
- delete pheGasItem;
- delete po2GasItem;
- delete o2SetpointGasItem;
- delete ccrsensor1GasItem;
- delete ccrsensor2GasItem;
- delete ccrsensor3GasItem;
- delete heartBeatAxis;
- delete heartBeatItem;
- delete percentageAxis;
- delete ambPressureItem;
- delete gflineItem;
- delete mouseFollowerVertical;
- delete mouseFollowerHorizontal;
- delete rulerItem;
- delete tankItem;
-}
-
-#define SUBSURFACE_OBJ_DATA 1
-#define SUBSURFACE_OBJ_DC_TEXT 0x42
-
-void ProfileWidget2::addItemsToScene()
-{
- scene()->addItem(background);
- scene()->addItem(toolTipItem);
- scene()->addItem(profileYAxis);
- scene()->addItem(gasYAxis);
- scene()->addItem(temperatureAxis);
- scene()->addItem(timeAxis);
- scene()->addItem(diveProfileItem);
- scene()->addItem(cylinderPressureAxis);
- scene()->addItem(temperatureItem);
- scene()->addItem(meanDepthItem);
- scene()->addItem(gasPressureItem);
- // I cannot seem to figure out if an object that I find with itemAt() on the scene
- // is the object I am looking for - my guess is there's a simple way in Qt to do that
- // but nothing I tried worked.
- // so instead this adds a special magic key/value pair to the object to mark it
- diveComputerText->setData(SUBSURFACE_OBJ_DATA, SUBSURFACE_OBJ_DC_TEXT);
- scene()->addItem(diveComputerText);
- scene()->addItem(diveCeiling);
- scene()->addItem(gradientFactor);
- scene()->addItem(reportedCeiling);
- scene()->addItem(pn2GasItem);
- scene()->addItem(pheGasItem);
- scene()->addItem(po2GasItem);
- scene()->addItem(o2SetpointGasItem);
- scene()->addItem(ccrsensor1GasItem);
- scene()->addItem(ccrsensor2GasItem);
- scene()->addItem(ccrsensor3GasItem);
- scene()->addItem(percentageAxis);
- scene()->addItem(heartBeatAxis);
- scene()->addItem(heartBeatItem);
- scene()->addItem(rulerItem);
- scene()->addItem(rulerItem->sourceNode());
- scene()->addItem(rulerItem->destNode());
- scene()->addItem(tankItem);
- scene()->addItem(mouseFollowerHorizontal);
- scene()->addItem(mouseFollowerVertical);
- QPen pen(QColor(Qt::red).lighter());
- pen.setWidth(0);
- mouseFollowerHorizontal->setPen(pen);
- mouseFollowerVertical->setPen(pen);
- Q_FOREACH (DiveCalculatedTissue *tissue, allTissues) {
- scene()->addItem(tissue);
- }
- Q_FOREACH (DivePercentageItem *percentage, allPercentages) {
- scene()->addItem(percentage);
- }
- scene()->addItem(ambPressureItem);
- scene()->addItem(gflineItem);
-}
-
-void ProfileWidget2::setupItemOnScene()
-{
- background->setZValue(9999);
- toolTipItem->setZValue(9998);
- toolTipItem->setTimeAxis(timeAxis);
- rulerItem->setZValue(9997);
- tankItem->setZValue(100);
-
- profileYAxis->setOrientation(DiveCartesianAxis::TopToBottom);
- profileYAxis->setMinimum(0);
- profileYAxis->setTickInterval(M_OR_FT(10, 30));
- profileYAxis->setTickSize(0.5);
- profileYAxis->setLineSize(96);
-
- timeAxis->setLineSize(92);
- timeAxis->setTickSize(-0.5);
-
- gasYAxis->setOrientation(DiveCartesianAxis::BottomToTop);
- gasYAxis->setTickInterval(1);
- gasYAxis->setTickSize(1);
- gasYAxis->setMinimum(0);
- gasYAxis->setModel(dataModel);
- gasYAxis->setFontLabelScale(0.7);
- gasYAxis->setLineSize(96);
-
- heartBeatAxis->setOrientation(DiveCartesianAxis::BottomToTop);
- heartBeatAxis->setTickSize(0.2);
- heartBeatAxis->setTickInterval(10);
- heartBeatAxis->setFontLabelScale(0.7);
- heartBeatAxis->setLineSize(96);
-
- percentageAxis->setOrientation(DiveCartesianAxis::BottomToTop);
- percentageAxis->setTickSize(0.2);
- percentageAxis->setTickInterval(10);
- percentageAxis->setFontLabelScale(0.7);
- percentageAxis->setLineSize(96);
-
- temperatureAxis->setOrientation(DiveCartesianAxis::BottomToTop);
- temperatureAxis->setTickSize(2);
- temperatureAxis->setTickInterval(300);
-
- cylinderPressureAxis->setOrientation(DiveCartesianAxis::BottomToTop);
- cylinderPressureAxis->setTickSize(2);
- cylinderPressureAxis->setTickInterval(30000);
-
-
- diveComputerText->setAlignment(Qt::AlignRight | Qt::AlignTop);
- diveComputerText->setBrush(getColor(TIME_TEXT, isGrayscale));
-
- rulerItem->setAxis(timeAxis, profileYAxis);
- tankItem->setHorizontalAxis(timeAxis);
-
- // show the gradient factor at the top in the center
- gradientFactor->setY(0);
- gradientFactor->setX(50);
- gradientFactor->setBrush(getColor(PRESSURE_TEXT));
- gradientFactor->setAlignment(Qt::AlignHCenter | Qt::AlignBottom);
-
- setupItem(reportedCeiling, timeAxis, profileYAxis, dataModel, DivePlotDataModel::CEILING, DivePlotDataModel::TIME, 1);
- setupItem(diveCeiling, timeAxis, profileYAxis, dataModel, DivePlotDataModel::CEILING, DivePlotDataModel::TIME, 1);
- for (int i = 0; i < 16; i++) {
- DiveCalculatedTissue *tissueItem = new DiveCalculatedTissue();
- setupItem(tissueItem, timeAxis, profileYAxis, dataModel, DivePlotDataModel::TISSUE_1 + i, DivePlotDataModel::TIME, 1 + i);
- allTissues.append(tissueItem);
- DivePercentageItem *percentageItem = new DivePercentageItem(i);
- setupItem(percentageItem, timeAxis, percentageAxis, dataModel, DivePlotDataModel::PERCENTAGE_1 + i, DivePlotDataModel::TIME, 1 + i);
- allPercentages.append(percentageItem);
- }
- setupItem(gasPressureItem, timeAxis, cylinderPressureAxis, dataModel, DivePlotDataModel::TEMPERATURE, DivePlotDataModel::TIME, 1);
- setupItem(temperatureItem, timeAxis, temperatureAxis, dataModel, DivePlotDataModel::TEMPERATURE, DivePlotDataModel::TIME, 1);
- setupItem(heartBeatItem, timeAxis, heartBeatAxis, dataModel, DivePlotDataModel::HEARTBEAT, DivePlotDataModel::TIME, 1);
- setupItem(ambPressureItem, timeAxis, percentageAxis, dataModel, DivePlotDataModel::AMBPRESSURE, DivePlotDataModel::TIME, 1);
- setupItem(gflineItem, timeAxis, percentageAxis, dataModel, DivePlotDataModel::GFLINE, DivePlotDataModel::TIME, 1);
- setupItem(diveProfileItem, timeAxis, profileYAxis, dataModel, DivePlotDataModel::DEPTH, DivePlotDataModel::TIME, 0);
- setupItem(meanDepthItem, timeAxis, profileYAxis, dataModel, DivePlotDataModel::INSTANT_MEANDEPTH, DivePlotDataModel::TIME, 1);
-
-
-#define CREATE_PP_GAS(ITEM, VERTICAL_COLUMN, COLOR, COLOR_ALERT, THRESHOULD_SETTINGS, VISIBILITY_SETTINGS) \
- setupItem(ITEM, timeAxis, gasYAxis, dataModel, DivePlotDataModel::VERTICAL_COLUMN, DivePlotDataModel::TIME, 0); \
- ITEM->setThreshouldSettingsKey(THRESHOULD_SETTINGS); \
- ITEM->setVisibilitySettingsKey(VISIBILITY_SETTINGS); \
- ITEM->setColors(getColor(COLOR, isGrayscale), getColor(COLOR_ALERT, isGrayscale)); \
- ITEM->settingsChanged(); \
- ITEM->setZValue(99);
-
- CREATE_PP_GAS(pn2GasItem, PN2, PN2, PN2_ALERT, &prefs.pp_graphs.pn2_threshold, "pn2graph");
- CREATE_PP_GAS(pheGasItem, PHE, PHE, PHE_ALERT, &prefs.pp_graphs.phe_threshold, "phegraph");
- CREATE_PP_GAS(po2GasItem, PO2, PO2, PO2_ALERT, &prefs.pp_graphs.po2_threshold, "po2graph");
- CREATE_PP_GAS(o2SetpointGasItem, O2SETPOINT, PO2_ALERT, PO2_ALERT, &prefs.pp_graphs.po2_threshold, "po2graph");
- CREATE_PP_GAS(ccrsensor1GasItem, CCRSENSOR1, CCRSENSOR1, PO2_ALERT, &prefs.pp_graphs.po2_threshold, "ccrsensorgraph");
- CREATE_PP_GAS(ccrsensor2GasItem, CCRSENSOR2, CCRSENSOR2, PO2_ALERT, &prefs.pp_graphs.po2_threshold, "ccrsensorgraph");
- CREATE_PP_GAS(ccrsensor3GasItem, CCRSENSOR3, CCRSENSOR3, PO2_ALERT, &prefs.pp_graphs.po2_threshold, "ccrsensorgraph");
-#undef CREATE_PP_GAS
-
- temperatureAxis->setTextVisible(false);
- temperatureAxis->setLinesVisible(false);
- cylinderPressureAxis->setTextVisible(false);
- cylinderPressureAxis->setLinesVisible(false);
- timeAxis->setLinesVisible(true);
- profileYAxis->setLinesVisible(true);
- gasYAxis->setZValue(timeAxis->zValue() + 1);
- heartBeatAxis->setTextVisible(true);
- heartBeatAxis->setLinesVisible(true);
- percentageAxis->setTextVisible(true);
- percentageAxis->setLinesVisible(true);
-
- replotEnabled = true;
-}
-
-void ProfileWidget2::replot(struct dive *d)
-{
- if (!replotEnabled)
- return;
- dataModel->clear();
- plotDive(d, true);
-}
-
-void ProfileWidget2::setupItemSizes()
-{
- // Scene is *always* (double) 100 / 100.
- // Background Config
- /* Much probably a better math is needed here.
- * good thing is that we only need to change the
- * Axis and everything else is auto-adjusted.*
- */
-
- itemPos.background.on.setX(0);
- itemPos.background.on.setY(0);
- itemPos.background.off.setX(0);
- itemPos.background.off.setY(110);
-
- //Depth Axis Config
- itemPos.depth.pos.on.setX(3);
- itemPos.depth.pos.on.setY(3);
- itemPos.depth.pos.off.setX(-2);
- itemPos.depth.pos.off.setY(3);
- itemPos.depth.expanded.setP1(QPointF(0, 0));
- itemPos.depth.expanded.setP2(QPointF(0, 85));
- itemPos.depth.shrinked.setP1(QPointF(0, 0));
- itemPos.depth.shrinked.setP2(QPointF(0, 55));
- itemPos.depth.intermediate.setP1(QPointF(0, 0));
- itemPos.depth.intermediate.setP2(QPointF(0, 65));
-
- // Time Axis Config
- itemPos.time.pos.on.setX(3);
- itemPos.time.pos.on.setY(95);
- itemPos.time.pos.off.setX(3);
- itemPos.time.pos.off.setY(110);
- itemPos.time.expanded.setP1(QPointF(0, 0));
- itemPos.time.expanded.setP2(QPointF(94, 0));
-
- // Partial Gas Axis Config
- itemPos.partialPressure.pos.on.setX(97);
- itemPos.partialPressure.pos.on.setY(75);
- itemPos.partialPressure.pos.off.setX(110);
- itemPos.partialPressure.pos.off.setY(63);
- itemPos.partialPressure.expanded.setP1(QPointF(0, 0));
- itemPos.partialPressure.expanded.setP2(QPointF(0, 19));
- itemPos.partialPressureWithTankBar = itemPos.partialPressure;
- itemPos.partialPressureWithTankBar.expanded.setP2(QPointF(0, 17));
- itemPos.partialPressureTissue = itemPos.partialPressure;
- itemPos.partialPressureTissue.pos.on.setX(97);
- itemPos.partialPressureTissue.pos.on.setY(65);
- itemPos.partialPressureTissue.expanded.setP2(QPointF(0, 16));
-
- // cylinder axis config
- itemPos.cylinder.pos.on.setX(3);
- itemPos.cylinder.pos.on.setY(20);
- itemPos.cylinder.pos.off.setX(-10);
- itemPos.cylinder.pos.off.setY(20);
- itemPos.cylinder.expanded.setP1(QPointF(0, 15));
- itemPos.cylinder.expanded.setP2(QPointF(0, 50));
- itemPos.cylinder.shrinked.setP1(QPointF(0, 0));
- itemPos.cylinder.shrinked.setP2(QPointF(0, 20));
- itemPos.cylinder.intermediate.setP1(QPointF(0, 0));
- itemPos.cylinder.intermediate.setP2(QPointF(0, 20));
-
- // Temperature axis config
- itemPos.temperature.pos.on.setX(3);
- itemPos.temperature.pos.on.setY(60);
- itemPos.temperatureAll.pos.on.setY(51);
- itemPos.temperature.pos.off.setX(-10);
- itemPos.temperature.pos.off.setY(40);
- itemPos.temperature.expanded.setP1(QPointF(0, 20));
- itemPos.temperature.expanded.setP2(QPointF(0, 33));
- itemPos.temperature.shrinked.setP1(QPointF(0, 2));
- itemPos.temperature.shrinked.setP2(QPointF(0, 12));
- itemPos.temperature.intermediate.setP1(QPointF(0, 2));
- itemPos.temperature.intermediate.setP2(QPointF(0, 12));
-
- // Heartbeat axis config
- itemPos.heartBeat.pos.on.setX(3);
- itemPos.heartBeat.pos.on.setY(82);
- itemPos.heartBeat.expanded.setP1(QPointF(0, 0));
- itemPos.heartBeat.expanded.setP2(QPointF(0, 10));
- itemPos.heartBeatWithTankBar = itemPos.heartBeat;
- itemPos.heartBeatWithTankBar.expanded.setP2(QPointF(0, 7));
-
- // Percentage axis config
- itemPos.percentage.pos.on.setX(3);
- itemPos.percentage.pos.on.setY(80);
- itemPos.percentage.expanded.setP1(QPointF(0, 0));
- itemPos.percentage.expanded.setP2(QPointF(0, 15));
- itemPos.percentageWithTankBar = itemPos.percentage;
- itemPos.percentageWithTankBar.expanded.setP2(QPointF(0, 12));
-
- itemPos.dcLabel.on.setX(3);
- itemPos.dcLabel.on.setY(100);
- itemPos.dcLabel.off.setX(-10);
- itemPos.dcLabel.off.setY(100);
-
- itemPos.tankBar.on.setX(0);
- itemPos.tankBar.on.setY(91.5);
-}
-
-void ProfileWidget2::setupItem(AbstractProfilePolygonItem *item, DiveCartesianAxis *hAxis,
- DiveCartesianAxis *vAxis, DivePlotDataModel *model,
- int vData, int hData, int zValue)
-{
- item->setHorizontalAxis(hAxis);
- item->setVerticalAxis(vAxis);
- item->setModel(model);
- item->setVerticalDataColumn(vData);
- item->setHorizontalDataColumn(hData);
- item->setZValue(zValue);
-}
-
-void ProfileWidget2::setupSceneAndFlags()
-{
- setScene(new QGraphicsScene(this));
- scene()->setSceneRect(0, 0, 100, 100);
- setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
- setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
- scene()->setItemIndexMethod(QGraphicsScene::NoIndex);
- setOptimizationFlags(QGraphicsView::DontSavePainterState);
- setViewportUpdateMode(QGraphicsView::BoundingRectViewportUpdate);
- setRenderHints(QPainter::Antialiasing | QPainter::TextAntialiasing | QPainter::SmoothPixmapTransform);
- setMouseTracking(true);
- background->setFlag(QGraphicsItem::ItemIgnoresTransformations);
-}
-
-void ProfileWidget2::resetZoom()
-{
- if (!zoomLevel)
- return;
- const qreal defScale = 1.0 / qPow(zoomFactor, (qreal)zoomLevel);
- scale(defScale, defScale);
- zoomLevel = 0;
-}
-
-// Currently just one dive, but the plan is to enable All of the selected dives.
-void ProfileWidget2::plotDive(struct dive *d, bool force)
-{
- static bool firstCall = true;
- QTime measureDuration; // let's measure how long this takes us (maybe we'll turn of TTL calculation later
- measureDuration.start();
-
- if (currentState != ADD && currentState != PLAN) {
- if (!d) {
- if (selected_dive == -1)
- return;
- d = current_dive; // display the current dive
- }
-
- // No need to do this again if we are already showing the same dive
- // computer of the same dive, so we check the unique id of the dive
- // and the selected dive computer number against the ones we are
- // showing (can't compare the dive pointers as those might change).
- if (d->id == displayed_dive.id && dc_number == dataModel->dcShown() && !force)
- return;
-
- // this copies the dive and makes copies of all the relevant additional data
- copy_dive(d, &displayed_dive);
- gradientFactor->setText(QString("GF %1/%2").arg(prefs.gflow).arg(prefs.gfhigh));
- } else {
- DivePlannerPointsModel *plannerModel = DivePlannerPointsModel::instance();
- plannerModel->createTemporaryPlan();
- struct diveplan &diveplan = plannerModel->getDiveplan();
- if (!diveplan.dp) {
- plannerModel->deleteTemporaryPlan();
- return;
- }
- gradientFactor->setText(QString("GF %1/%2").arg(diveplan.gflow).arg(diveplan.gfhigh));
- }
-
- // special handling for the first time we display things
- int animSpeedBackup = 0;
- if (firstCall && MainWindow::instance()->filesFromCommandLine()) {
- animSpeedBackup = prefs.animation_speed;
- prefs.animation_speed = 0;
- firstCall = false;
- }
-
- // restore default zoom level
- resetZoom();
-
- // reset some item visibility on printMode changes
- toolTipItem->setVisible(!printMode);
- rulerItem->setVisible(prefs.rulergraph && !printMode && currentState != PLAN && currentState != ADD);
-
- if (currentState == EMPTY)
- setProfileState();
-
- // next get the dive computer structure - if there are no samples
- // let's create a fake profile that's somewhat reasonable for the
- // data that we have
- struct divecomputer *currentdc = select_dc(&displayed_dive);
- Q_ASSERT(currentdc);
- if (!currentdc || !currentdc->samples) {
- currentdc = fake_dc(currentdc);
- }
-
- bool setpointflag = (currentdc->divemode == CCR) && prefs.pp_graphs.po2 && current_dive;
- bool sensorflag = setpointflag && prefs.show_ccr_sensors;
- o2SetpointGasItem->setVisible(setpointflag && prefs.show_ccr_setpoint);
- ccrsensor1GasItem->setVisible(sensorflag);
- ccrsensor2GasItem->setVisible(sensorflag && (currentdc->no_o2sensors > 1));
- ccrsensor3GasItem->setVisible(sensorflag && (currentdc->no_o2sensors > 2));
-
- /* This struct holds all the data that's about to be plotted.
- * I'm not sure this is the best approach ( but since we are
- * interpolating some points of the Dive, maybe it is... )
- * The Calculation of the points should be done per graph,
- * so I'll *not* calculate everything if something is not being
- * shown.
- */
- plotInfo = calculate_max_limits_new(&displayed_dive, currentdc);
- create_plot_info_new(&displayed_dive, currentdc, &plotInfo, !shouldCalculateMaxDepth);
- if (shouldCalculateMaxTime)
- maxtime = get_maxtime(&plotInfo);
-
- /* Only update the max depth if it's bigger than the current ones
- * when we are dragging the handler to plan / add dive.
- * otherwhise, update normally.
- */
- int newMaxDepth = get_maxdepth(&plotInfo);
- if (!shouldCalculateMaxDepth) {
- if (maxdepth < newMaxDepth) {
- maxdepth = newMaxDepth;
- }
- } else {
- maxdepth = newMaxDepth;
- }
-
- dataModel->setDive(&displayed_dive, plotInfo);
- toolTipItem->setPlotInfo(plotInfo);
-
- // It seems that I'll have a lot of boilerplate setting the model / axis for
- // each item, I'll mostly like to fix this in the future, but I'll keep at this for now.
- profileYAxis->setMaximum(maxdepth);
- profileYAxis->updateTicks();
-
- temperatureAxis->setMinimum(plotInfo.mintemp);
- temperatureAxis->setMaximum(plotInfo.maxtemp - plotInfo.mintemp > 2000 ? plotInfo.maxtemp : plotInfo.mintemp + 2000);
-
- if (plotInfo.maxhr) {
- heartBeatAxis->setMinimum(plotInfo.minhr);
- heartBeatAxis->setMaximum(plotInfo.maxhr);
- heartBeatAxis->updateTicks(HR_AXIS); // this shows the ticks
- }
- heartBeatAxis->setVisible(prefs.hrgraph && plotInfo.maxhr);
-
- percentageAxis->setMinimum(0);
- percentageAxis->setMaximum(100);
- percentageAxis->setVisible(false);
- percentageAxis->updateTicks(HR_AXIS);
-
- timeAxis->setMaximum(maxtime);
- int i, incr;
- static int increments[8] = { 10, 20, 30, 60, 5 * 60, 10 * 60, 15 * 60, 30 * 60 };
- /* Time markers: at most every 10 seconds, but no more than 12 markers.
- * We start out with 10 seconds and increment up to 30 minutes,
- * depending on the dive time.
- * This allows for 6h dives - enough (I hope) for even the craziest
- * divers - but just in case, for those 8h depth-record-breaking dives,
- * we double the interval if this still doesn't get us to 12 or fewer
- * time markers */
- i = 0;
- while (i < 7 && maxtime / increments[i] > 12)
- i++;
- incr = increments[i];
- while (maxtime / incr > 12)
- incr *= 2;
- timeAxis->setTickInterval(incr);
- timeAxis->updateTicks();
- cylinderPressureAxis->setMinimum(plotInfo.minpressure);
- cylinderPressureAxis->setMaximum(plotInfo.maxpressure);
-
- rulerItem->setPlotInfo(plotInfo);
- tankItem->setData(dataModel, &plotInfo, &displayed_dive);
-
- dataModel->emitDataChanged();
- // The event items are a bit special since we don't know how many events are going to
- // exist on a dive, so I cant create cache items for that. that's why they are here
- // while all other items are up there on the constructor.
- qDeleteAll(eventItems);
- eventItems.clear();
- struct event *event = currentdc->events;
- while (event) {
- // if print mode is selected only draw headings, SP change, gas events or bookmark event
- if (printMode) {
- if (same_string(event->name, "") ||
- !(strcmp(event->name, "heading") == 0 ||
- (same_string(event->name, "SP change") && event->time.seconds == 0) ||
- event_is_gaschange(event) ||
- event->type == SAMPLE_EVENT_BOOKMARK)) {
- event = event->next;
- continue;
- }
- }
- DiveEventItem *item = new DiveEventItem();
- item->setHorizontalAxis(timeAxis);
- item->setVerticalAxis(profileYAxis);
- item->setModel(dataModel);
- item->setEvent(event);
- item->setZValue(2);
- scene()->addItem(item);
- eventItems.push_back(item);
- event = event->next;
- }
- // Only set visible the events that should be visible
- Q_FOREACH (DiveEventItem *event, eventItems) {
- event->setVisible(!event->shouldBeHidden());
- }
- QString dcText = get_dc_nickname(currentdc->model, currentdc->deviceid);
- int nr;
- if ((nr = number_of_computers(&displayed_dive)) > 1)
- dcText += tr(" (#%1 of %2)").arg(dc_number + 1).arg(nr);
- if (dcText.isEmpty())
- dcText = tr("Unknown dive computer");
- diveComputerText->setText(dcText);
- if (MainWindow::instance()->filesFromCommandLine() && animSpeedBackup != 0) {
- prefs.animation_speed = animSpeedBackup;
- }
-
- if (currentState == ADD || currentState == PLAN) { // TODO: figure a way to move this from here.
- repositionDiveHandlers();
- DivePlannerPointsModel *model = DivePlannerPointsModel::instance();
- model->deleteTemporaryPlan();
- }
- plotPictures();
-
- // OK, how long did this take us? Anything above the second is way too long,
- // so if we are calculation TTS / NDL then let's force that off.
- if (measureDuration.elapsed() > 1000 && prefs.calcndltts) {
- MainWindow::instance()->turnOffNdlTts();
- MainWindow::instance()->getNotificationWidget()->showNotification(tr("Show NDL / TTS was disabled because of excessive processing time"), KMessageWidget::Error);
- }
- MainWindow::instance()->getNotificationWidget()->showNotification(get_error_string(), KMessageWidget::Error);
-
-}
-
-void ProfileWidget2::recalcCeiling()
-{
- diveCeiling->recalc();
-}
-
-void ProfileWidget2::settingsChanged()
-{
- // if we are showing calculated ceilings then we have to replot()
- // because the GF could have changed; otherwise we try to avoid replot()
- bool needReplot = prefs.calcceiling;
- if ((prefs.percentagegraph||prefs.hrgraph) && PP_GRAPHS_ENABLED) {
- profileYAxis->animateChangeLine(itemPos.depth.shrinked);
- temperatureAxis->setPos(itemPos.temperatureAll.pos.on);
- temperatureAxis->animateChangeLine(itemPos.temperature.shrinked);
- cylinderPressureAxis->animateChangeLine(itemPos.cylinder.shrinked);
-
- if (prefs.tankbar) {
- percentageAxis->setPos(itemPos.percentageWithTankBar.pos.on);
- percentageAxis->animateChangeLine(itemPos.percentageWithTankBar.expanded);
- heartBeatAxis->setPos(itemPos.heartBeatWithTankBar.pos.on);
- heartBeatAxis->animateChangeLine(itemPos.heartBeatWithTankBar.expanded);
- }else {
- percentageAxis->setPos(itemPos.percentage.pos.on);
- percentageAxis->animateChangeLine(itemPos.percentage.expanded);
- heartBeatAxis->setPos(itemPos.heartBeat.pos.on);
- heartBeatAxis->animateChangeLine(itemPos.heartBeat.expanded);
- }
- gasYAxis->setPos(itemPos.partialPressureTissue.pos.on);
- gasYAxis->animateChangeLine(itemPos.partialPressureTissue.expanded);
-
- } else if (PP_GRAPHS_ENABLED || prefs.hrgraph || prefs.percentagegraph) {
- profileYAxis->animateChangeLine(itemPos.depth.intermediate);
- temperatureAxis->setPos(itemPos.temperature.pos.on);
- temperatureAxis->animateChangeLine(itemPos.temperature.intermediate);
- cylinderPressureAxis->animateChangeLine(itemPos.cylinder.intermediate);
- if (prefs.tankbar) {
- percentageAxis->setPos(itemPos.percentageWithTankBar.pos.on);
- percentageAxis->animateChangeLine(itemPos.percentageWithTankBar.expanded);
- gasYAxis->setPos(itemPos.partialPressureWithTankBar.pos.on);
- gasYAxis->setLine(itemPos.partialPressureWithTankBar.expanded);
- heartBeatAxis->setPos(itemPos.heartBeatWithTankBar.pos.on);
- heartBeatAxis->animateChangeLine(itemPos.heartBeatWithTankBar.expanded);
- } else {
- gasYAxis->setPos(itemPos.partialPressure.pos.on);
- gasYAxis->animateChangeLine(itemPos.partialPressure.expanded);
- percentageAxis->setPos(itemPos.percentage.pos.on);
- percentageAxis->setLine(itemPos.percentage.expanded);
- heartBeatAxis->setPos(itemPos.heartBeat.pos.on);
- heartBeatAxis->animateChangeLine(itemPos.heartBeat.expanded);
- }
- } else {
- profileYAxis->animateChangeLine(itemPos.depth.expanded);
- if (prefs.tankbar) {
- temperatureAxis->setPos(itemPos.temperatureAll.pos.on);
- } else {
- temperatureAxis->setPos(itemPos.temperature.pos.on);
- }
- temperatureAxis->animateChangeLine(itemPos.temperature.expanded);
- cylinderPressureAxis->animateChangeLine(itemPos.cylinder.expanded);
- }
-
- tankItem->setVisible(prefs.tankbar);
- if (prefs.zoomed_plot != isPlotZoomed) {
- isPlotZoomed = prefs.zoomed_plot;
- needReplot = true;
- }
- if (needReplot)
- replot();
-}
-
-void ProfileWidget2::resizeEvent(QResizeEvent *event)
-{
- QGraphicsView::resizeEvent(event);
- fitInView(sceneRect(), Qt::IgnoreAspectRatio);
- fixBackgroundPos();
-}
-
-void ProfileWidget2::mousePressEvent(QMouseEvent *event)
-{
- if (zoomLevel)
- return;
- QGraphicsView::mousePressEvent(event);
- if (currentState == PLAN)
- shouldCalculateMaxTime = false;
-}
-
-void ProfileWidget2::divePlannerHandlerClicked()
-{
- if (zoomLevel)
- return;
- shouldCalculateMaxDepth = false;
- replot();
-}
-
-void ProfileWidget2::divePlannerHandlerReleased()
-{
- if (zoomLevel)
- return;
- shouldCalculateMaxDepth = true;
- replot();
-}
-
-void ProfileWidget2::mouseReleaseEvent(QMouseEvent *event)
-{
- if (zoomLevel)
- return;
- QGraphicsView::mouseReleaseEvent(event);
- if (currentState == PLAN) {
- shouldCalculateMaxTime = true;
- replot();
- }
-}
-
-void ProfileWidget2::fixBackgroundPos()
-{
- static QPixmap toBeScaled(backgroundFile);
- if (currentState != EMPTY)
- return;
- QPixmap p = toBeScaled.scaledToHeight(viewport()->height() - 40, Qt::SmoothTransformation);
- int x = viewport()->width() / 2 - p.width() / 2;
- int y = viewport()->height() / 2 - p.height() / 2;
- background->setPixmap(p);
- background->setX(mapToScene(x, 0).x());
- background->setY(mapToScene(y, 20).y());
-}
-
-void ProfileWidget2::wheelEvent(QWheelEvent *event)
-{
- if (currentState == EMPTY)
- return;
- QPoint toolTipPos = mapFromScene(toolTipItem->pos());
- if (event->buttons() == Qt::LeftButton)
- return;
- if (event->delta() > 0 && zoomLevel < 20) {
- scale(zoomFactor, zoomFactor);
- zoomLevel++;
- } else if (event->delta() < 0 && zoomLevel > 0) {
- // Zooming out
- scale(1.0 / zoomFactor, 1.0 / zoomFactor);
- zoomLevel--;
- }
- scrollViewTo(event->pos());
- toolTipItem->setPos(mapToScene(toolTipPos));
-}
-
-void ProfileWidget2::mouseDoubleClickEvent(QMouseEvent *event)
-{
- if (currentState == PLAN || currentState == ADD) {
- DivePlannerPointsModel *plannerModel = DivePlannerPointsModel::instance();
- QPointF mappedPos = mapToScene(event->pos());
- if (isPointOutOfBoundaries(mappedPos))
- return;
-
- int minutes = rint(timeAxis->valueAt(mappedPos) / 60);
- int milimeters = rint(profileYAxis->valueAt(mappedPos) / M_OR_FT(1, 1)) * M_OR_FT(1, 1);
- plannerModel->addStop(milimeters, minutes * 60, 0, 0, true);
- }
-}
-
-bool ProfileWidget2::isPointOutOfBoundaries(const QPointF &point) const
-{
- double xpos = timeAxis->valueAt(point);
- double ypos = profileYAxis->valueAt(point);
- return (xpos > timeAxis->maximum() ||
- xpos < timeAxis->minimum() ||
- ypos > profileYAxis->maximum() ||
- ypos < profileYAxis->minimum());
-}
-
-void ProfileWidget2::scrollViewTo(const QPoint &pos)
-{
- /* since we cannot use translate() directly on the scene we hack on
- * the scroll bars (hidden) functionality */
- if (!zoomLevel || currentState == EMPTY)
- return;
- QScrollBar *vs = verticalScrollBar();
- QScrollBar *hs = horizontalScrollBar();
- const qreal yRat = (qreal)pos.y() / viewport()->height();
- const qreal xRat = (qreal)pos.x() / viewport()->width();
- vs->setValue(yRat * vs->maximum());
- hs->setValue(xRat * hs->maximum());
-}
-
-void ProfileWidget2::mouseMoveEvent(QMouseEvent *event)
-{
- QPointF pos = mapToScene(event->pos());
- toolTipItem->refresh(pos);
- if (zoomLevel == 0) {
- QGraphicsView::mouseMoveEvent(event);
- } else {
- QPoint toolTipPos = mapFromScene(toolTipItem->pos());
- scrollViewTo(event->pos());
- toolTipItem->setPos(mapToScene(toolTipPos));
- }
-
- qreal vValue = profileYAxis->valueAt(pos);
- qreal hValue = timeAxis->valueAt(pos);
- if (profileYAxis->maximum() >= vValue && profileYAxis->minimum() <= vValue) {
- mouseFollowerHorizontal->setPos(timeAxis->pos().x(), pos.y());
- }
- if (timeAxis->maximum() >= hValue && timeAxis->minimum() <= hValue) {
- mouseFollowerVertical->setPos(pos.x(), profileYAxis->line().y1());
- }
-}
-
-bool ProfileWidget2::eventFilter(QObject *object, QEvent *event)
-{
- QGraphicsScene *s = qobject_cast<QGraphicsScene *>(object);
- if (s && event->type() == QEvent::GraphicsSceneHelp) {
- event->ignore();
- return true;
- }
- return QGraphicsView::eventFilter(object, event);
-}
-
-void ProfileWidget2::setEmptyState()
-{
- // Then starting Empty State, move the background up.
- if (currentState == EMPTY)
- return;
-
- disconnectTemporaryConnections();
- setBackgroundBrush(getColor(::BACKGROUND, isGrayscale));
- dataModel->clear();
- currentState = EMPTY;
- MainWindow::instance()->setEnabledToolbar(false);
-
- fixBackgroundPos();
- background->setVisible(true);
-
- profileYAxis->setVisible(false);
- gasYAxis->setVisible(false);
- timeAxis->setVisible(false);
- temperatureAxis->setVisible(false);
- cylinderPressureAxis->setVisible(false);
- toolTipItem->setVisible(false);
- diveComputerText->setVisible(false);
- diveCeiling->setVisible(false);
- gradientFactor->setVisible(false);
- reportedCeiling->setVisible(false);
- rulerItem->setVisible(false);
- tankItem->setVisible(false);
- pn2GasItem->setVisible(false);
- po2GasItem->setVisible(false);
- o2SetpointGasItem->setVisible(false);
- ccrsensor1GasItem->setVisible(false);
- ccrsensor2GasItem->setVisible(false);
- ccrsensor3GasItem->setVisible(false);
- pheGasItem->setVisible(false);
- ambPressureItem->setVisible(false);
- gflineItem->setVisible(false);
- mouseFollowerHorizontal->setVisible(false);
- mouseFollowerVertical->setVisible(false);
-
-#define HIDE_ALL(TYPE, CONTAINER) \
- Q_FOREACH (TYPE *item, CONTAINER) item->setVisible(false);
- HIDE_ALL(DiveCalculatedTissue, allTissues);
- HIDE_ALL(DivePercentageItem, allPercentages);
- HIDE_ALL(DiveEventItem, eventItems);
- HIDE_ALL(DiveHandler, handles);
- HIDE_ALL(QGraphicsSimpleTextItem, gases);
-#undef HIDE_ALL
-}
-
-void ProfileWidget2::setProfileState()
-{
- // Then starting Empty State, move the background up.
- if (currentState == PROFILE)
- return;
-
- disconnectTemporaryConnections();
- connect(DivePictureModel::instance(), SIGNAL(dataChanged(QModelIndex, QModelIndex)), this, SLOT(plotPictures()));
- connect(DivePictureModel::instance(), SIGNAL(rowsInserted(const QModelIndex &, int, int)), this, SLOT(plotPictures()));
- connect(DivePictureModel::instance(), SIGNAL(rowsRemoved(const QModelIndex &, int, int)), this, SLOT(plotPictures()));
- /* show the same stuff that the profile shows. */
-
- //TODO: Move the DC handling to another method.
- MainWindow::instance()->enableShortcuts();
-
- currentState = PROFILE;
- MainWindow::instance()->setEnabledToolbar(true);
- toolTipItem->readPos();
- setBackgroundBrush(getColor(::BACKGROUND, isGrayscale));
-
- background->setVisible(false);
- toolTipItem->setVisible(true);
- profileYAxis->setVisible(true);
- gasYAxis->setVisible(true);
- timeAxis->setVisible(true);
- temperatureAxis->setVisible(true);
- cylinderPressureAxis->setVisible(true);
-
- profileYAxis->setPos(itemPos.depth.pos.on);
- if ((prefs.percentagegraph||prefs.hrgraph) && PP_GRAPHS_ENABLED) {
- profileYAxis->animateChangeLine(itemPos.depth.shrinked);
- temperatureAxis->setPos(itemPos.temperatureAll.pos.on);
- temperatureAxis->animateChangeLine(itemPos.temperature.shrinked);
- cylinderPressureAxis->animateChangeLine(itemPos.cylinder.shrinked);
-
- if (prefs.tankbar) {
- percentageAxis->setPos(itemPos.percentageWithTankBar.pos.on);
- percentageAxis->animateChangeLine(itemPos.percentageWithTankBar.expanded);
- heartBeatAxis->setPos(itemPos.heartBeatWithTankBar.pos.on);
- heartBeatAxis->animateChangeLine(itemPos.heartBeatWithTankBar.expanded);
- }else {
- percentageAxis->setPos(itemPos.percentage.pos.on);
- percentageAxis->animateChangeLine(itemPos.percentage.expanded);
- heartBeatAxis->setPos(itemPos.heartBeat.pos.on);
- heartBeatAxis->animateChangeLine(itemPos.heartBeat.expanded);
- }
- gasYAxis->setPos(itemPos.partialPressureTissue.pos.on);
- gasYAxis->animateChangeLine(itemPos.partialPressureTissue.expanded);
-
- } else if (PP_GRAPHS_ENABLED || prefs.hrgraph || prefs.percentagegraph) {
- profileYAxis->animateChangeLine(itemPos.depth.intermediate);
- temperatureAxis->setPos(itemPos.temperature.pos.on);
- temperatureAxis->animateChangeLine(itemPos.temperature.intermediate);
- cylinderPressureAxis->animateChangeLine(itemPos.cylinder.intermediate);
- if (prefs.tankbar) {
- percentageAxis->setPos(itemPos.percentageWithTankBar.pos.on);
- percentageAxis->animateChangeLine(itemPos.percentageWithTankBar.expanded);
- gasYAxis->setPos(itemPos.partialPressureWithTankBar.pos.on);
- gasYAxis->setLine(itemPos.partialPressureWithTankBar.expanded);
- heartBeatAxis->setPos(itemPos.heartBeatWithTankBar.pos.on);
- heartBeatAxis->animateChangeLine(itemPos.heartBeatWithTankBar.expanded);
- } else {
- gasYAxis->setPos(itemPos.partialPressure.pos.on);
- gasYAxis->animateChangeLine(itemPos.partialPressure.expanded);
- percentageAxis->setPos(itemPos.percentage.pos.on);
- percentageAxis->setLine(itemPos.percentage.expanded);
- heartBeatAxis->setPos(itemPos.heartBeat.pos.on);
- heartBeatAxis->animateChangeLine(itemPos.heartBeat.expanded);
- }
- } else {
- profileYAxis->animateChangeLine(itemPos.depth.expanded);
- if (prefs.tankbar) {
- temperatureAxis->setPos(itemPos.temperatureAll.pos.on);
- } else {
- temperatureAxis->setPos(itemPos.temperature.pos.on);
- }
- temperatureAxis->animateChangeLine(itemPos.temperature.expanded);
- cylinderPressureAxis->animateChangeLine(itemPos.cylinder.expanded);
- }
- pn2GasItem->setVisible(prefs.pp_graphs.pn2);
- po2GasItem->setVisible(prefs.pp_graphs.po2);
- pheGasItem->setVisible(prefs.pp_graphs.phe);
-
- bool setpointflag = current_dive && (current_dc->divemode == CCR) && prefs.pp_graphs.po2;
- bool sensorflag = setpointflag && prefs.show_ccr_sensors;
- o2SetpointGasItem->setVisible(setpointflag && prefs.show_ccr_setpoint);
- ccrsensor1GasItem->setVisible(sensorflag);
- ccrsensor2GasItem->setVisible(sensorflag && (current_dc->no_o2sensors > 1));
- ccrsensor3GasItem->setVisible(sensorflag && (current_dc->no_o2sensors > 2));
-
- timeAxis->setPos(itemPos.time.pos.on);
- timeAxis->setLine(itemPos.time.expanded);
-
- cylinderPressureAxis->setPos(itemPos.cylinder.pos.on);
- heartBeatItem->setVisible(prefs.hrgraph);
- meanDepthItem->setVisible(prefs.show_average_depth);
-
- diveComputerText->setVisible(true);
- diveComputerText->setPos(itemPos.dcLabel.on);
-
- diveCeiling->setVisible(prefs.calcceiling);
- gradientFactor->setVisible(prefs.calcceiling);
- reportedCeiling->setVisible(prefs.dcceiling);
-
- if (prefs.calcalltissues) {
- Q_FOREACH (DiveCalculatedTissue *tissue, allTissues) {
- tissue->setVisible(true);
- }
- }
-
- if (prefs.percentagegraph) {
- Q_FOREACH (DivePercentageItem *percentage, allPercentages) {
- percentage->setVisible(true);
- }
-
- ambPressureItem->setVisible(true);
- gflineItem->setVisible(true);
- }
-
- rulerItem->setVisible(prefs.rulergraph);
- tankItem->setVisible(prefs.tankbar);
- tankItem->setPos(itemPos.tankBar.on);
-
-#define HIDE_ALL(TYPE, CONTAINER) \
- Q_FOREACH (TYPE *item, CONTAINER) item->setVisible(false);
- HIDE_ALL(DiveHandler, handles);
- HIDE_ALL(QGraphicsSimpleTextItem, gases);
-#undef HIDE_ALL
- mouseFollowerHorizontal->setVisible(false);
- mouseFollowerVertical->setVisible(false);
-}
-
-void ProfileWidget2::clearHandlers()
-{
- if (handles.count()) {
- foreach (DiveHandler *handle, handles) {
- scene()->removeItem(handle);
- delete handle;
- }
- handles.clear();
- }
-}
-
-void ProfileWidget2::setToolTipVisibile(bool visible)
-{
- toolTipItem->setVisible(visible);
-}
-
-void ProfileWidget2::setAddState()
-{
- if (currentState == ADD)
- return;
-
- clearHandlers();
- setProfileState();
- mouseFollowerHorizontal->setVisible(true);
- mouseFollowerVertical->setVisible(true);
- mouseFollowerHorizontal->setLine(timeAxis->line());
- mouseFollowerVertical->setLine(QLineF(0, profileYAxis->pos().y(), 0, timeAxis->pos().y()));
- disconnectTemporaryConnections();
- //TODO: Move this method to another place, shouldn't be on mainwindow.
- MainWindow::instance()->disableShortcuts(false);
- actionsForKeys[Qt::Key_Left]->setShortcut(Qt::Key_Left);
- actionsForKeys[Qt::Key_Right]->setShortcut(Qt::Key_Right);
- actionsForKeys[Qt::Key_Up]->setShortcut(Qt::Key_Up);
- actionsForKeys[Qt::Key_Down]->setShortcut(Qt::Key_Down);
- actionsForKeys[Qt::Key_Escape]->setShortcut(Qt::Key_Escape);
- actionsForKeys[Qt::Key_Delete]->setShortcut(Qt::Key_Delete);
-
- DivePlannerPointsModel *plannerModel = DivePlannerPointsModel::instance();
- connect(plannerModel, SIGNAL(dataChanged(QModelIndex, QModelIndex)), this, SLOT(replot()));
- connect(plannerModel, SIGNAL(cylinderModelEdited()), this, SLOT(replot()));
- connect(plannerModel, SIGNAL(rowsInserted(const QModelIndex &, int, int)),
- this, SLOT(pointInserted(const QModelIndex &, int, int)));
- connect(plannerModel, SIGNAL(rowsRemoved(const QModelIndex &, int, int)),
- this, SLOT(pointsRemoved(const QModelIndex &, int, int)));
- /* show the same stuff that the profile shows. */
- currentState = ADD; /* enable the add state. */
- diveCeiling->setVisible(true);
- gradientFactor->setVisible(true);
- setBackgroundBrush(QColor("#A7DCFF"));
-}
-
-void ProfileWidget2::setPlanState()
-{
- if (currentState == PLAN)
- return;
-
- setProfileState();
- mouseFollowerHorizontal->setVisible(true);
- mouseFollowerVertical->setVisible(true);
- mouseFollowerHorizontal->setLine(timeAxis->line());
- mouseFollowerVertical->setLine(QLineF(0, profileYAxis->pos().y(), 0, timeAxis->pos().y()));
- disconnectTemporaryConnections();
- //TODO: Move this method to another place, shouldn't be on mainwindow.
- MainWindow::instance()->disableShortcuts();
- actionsForKeys[Qt::Key_Left]->setShortcut(Qt::Key_Left);
- actionsForKeys[Qt::Key_Right]->setShortcut(Qt::Key_Right);
- actionsForKeys[Qt::Key_Up]->setShortcut(Qt::Key_Up);
- actionsForKeys[Qt::Key_Down]->setShortcut(Qt::Key_Down);
- actionsForKeys[Qt::Key_Escape]->setShortcut(Qt::Key_Escape);
- actionsForKeys[Qt::Key_Delete]->setShortcut(Qt::Key_Delete);
-
- DivePlannerPointsModel *plannerModel = DivePlannerPointsModel::instance();
- connect(plannerModel, SIGNAL(dataChanged(QModelIndex, QModelIndex)), this, SLOT(replot()));
- connect(plannerModel, SIGNAL(cylinderModelEdited()), this, SLOT(replot()));
- connect(plannerModel, SIGNAL(rowsInserted(const QModelIndex &, int, int)),
- this, SLOT(pointInserted(const QModelIndex &, int, int)));
- connect(plannerModel, SIGNAL(rowsRemoved(const QModelIndex &, int, int)),
- this, SLOT(pointsRemoved(const QModelIndex &, int, int)));
- /* show the same stuff that the profile shows. */
- currentState = PLAN; /* enable the add state. */
- diveCeiling->setVisible(true);
- gradientFactor->setVisible(true);
- setBackgroundBrush(QColor("#D7E3EF"));
-}
-
-extern struct ev_select *ev_namelist;
-extern int evn_allocated;
-extern int evn_used;
-
-bool ProfileWidget2::isPlanner()
-{
- return currentState == PLAN;
-}
-
-bool ProfileWidget2::isAddOrPlanner()
-{
- return currentState == PLAN || currentState == ADD;
-}
-
-struct plot_data *ProfileWidget2::getEntryFromPos(QPointF pos)
-{
- // find the time stamp corresponding to the mouse position
- int seconds = timeAxis->valueAt(pos);
- struct plot_data *entry = NULL;
-
- for (int i = 0; i < plotInfo.nr; i++) {
- entry = plotInfo.entry + i;
- if (entry->sec >= seconds)
- break;
- }
- return entry;
-}
-
-void ProfileWidget2::setReplot(bool state)
-{
- replotEnabled = state;
-}
-
-void ProfileWidget2::contextMenuEvent(QContextMenuEvent *event)
-{
- if (currentState == ADD || currentState == PLAN) {
- QGraphicsView::contextMenuEvent(event);
- return;
- }
- QMenu m;
- bool isDCName = false;
- if (selected_dive == -1)
- return;
- // figure out if we are ontop of the dive computer name in the profile
- QGraphicsItem *sceneItem = itemAt(mapFromGlobal(event->globalPos()));
- if (sceneItem) {
- QGraphicsItem *parentItem = sceneItem;
- while (parentItem) {
- if (parentItem->data(SUBSURFACE_OBJ_DATA) == SUBSURFACE_OBJ_DC_TEXT) {
- isDCName = true;
- break;
- }
- parentItem = parentItem->parentItem();
- }
- if (isDCName) {
- if (dc_number == 0 && count_divecomputers() == 1)
- // nothing to do, can't delete or reorder
- return;
- // create menu to show when right clicking on dive computer name
- if (dc_number > 0)
- m.addAction(tr("Make first divecomputer"), this, SLOT(makeFirstDC()));
- if (count_divecomputers() > 1)
- m.addAction(tr("Delete this divecomputer"), this, SLOT(deleteCurrentDC()));
- m.exec(event->globalPos());
- // don't show the regular profile context menu
- return;
- }
- }
- // create the profile context menu
- QPointF scenePos = mapToScene(event->pos());
- struct plot_data *entry = getEntryFromPos(scenePos);
- GasSelectionModel *model = GasSelectionModel::instance();
- model->repopulate();
- int rowCount = model->rowCount();
- if (rowCount > 1) {
- // if we have more than one gas, offer to switch to another one
- QMenu *gasChange = m.addMenu(tr("Add gas change"));
- for (int i = 0; i < rowCount; i++) {
- QAction *action = new QAction(&m);
- action->setText(model->data(model->index(i, 0), Qt::DisplayRole).toString() + QString(tr(" (Tank %1)")).arg(i + 1));
- connect(action, SIGNAL(triggered(bool)), this, SLOT(changeGas()));
- action->setData(event->globalPos());
- if (i == entry->cylinderindex)
- action->setDisabled(true);
- gasChange->addAction(action);
- }
- }
- QAction *setpointAction = m.addAction(tr("Add set-point change"), this, SLOT(addSetpointChange()));
- setpointAction->setData(event->globalPos());
- QAction *action = m.addAction(tr("Add bookmark"), this, SLOT(addBookmark()));
- action->setData(event->globalPos());
-
- if (same_string(current_dc->model, "manually added dive"))
- QAction *editProfileAction = m.addAction(tr("Edit the profile"), MainWindow::instance(), SLOT(editCurrentDive()));
-
- if (DiveEventItem *item = dynamic_cast<DiveEventItem *>(sceneItem)) {
- action = new QAction(&m);
- action->setText(tr("Remove event"));
- action->setData(QVariant::fromValue<void *>(item)); // so we know what to remove.
- connect(action, SIGNAL(triggered(bool)), this, SLOT(removeEvent()));
- m.addAction(action);
- action = new QAction(&m);
- action->setText(tr("Hide similar events"));
- action->setData(QVariant::fromValue<void *>(item));
- connect(action, SIGNAL(triggered(bool)), this, SLOT(hideEvents()));
- m.addAction(action);
- struct event *dcEvent = item->getEvent();
- if (dcEvent->type == SAMPLE_EVENT_BOOKMARK) {
- action = new QAction(&m);
- action->setText(tr("Edit name"));
- action->setData(QVariant::fromValue<void *>(item));
- connect(action, SIGNAL(triggered(bool)), this, SLOT(editName()));
- m.addAction(action);
- }
-#if 0 // FIXME::: FINISH OR DISABLE
- // this shows how to figure out if we should ask the user if they want adjust interpolated pressures
- // at either side of a gas change
- if (dcEvent->type == SAMPLE_EVENT_GASCHANGE || dcEvent->type == SAMPLE_EVENT_GASCHANGE2) {
- qDebug() << "figure out if there are interpolated pressures";
- struct plot_data *gasChangeEntry = entry;
- struct plot_data *newGasEntry;
- while (gasChangeEntry > plotInfo.entry) {
- --gasChangeEntry;
- if (gasChangeEntry->sec <= dcEvent->time.seconds)
- break;
- }
- qDebug() << "at gas change at" << gasChangeEntry->sec << ": sensor pressure" << gasChangeEntry->pressure[0] << "interpolated" << gasChangeEntry->pressure[1];
- // now gasChangeEntry points at the gas change, that entry has the final pressure of
- // the old tank, the next entry has the starting pressure of the next tank
- if (gasChangeEntry + 1 <= plotInfo.entry + plotInfo.nr) {
- newGasEntry = gasChangeEntry + 1;
- qDebug() << "after gas change at " << newGasEntry->sec << ": sensor pressure" << newGasEntry->pressure[0] << "interpolated" << newGasEntry->pressure[1];
- if (SENSOR_PRESSURE(gasChangeEntry) == 0 || displayed_dive.cylinder[gasChangeEntry->cylinderindex].sample_start.mbar == 0) {
- // if we have no sensorpressure or if we have no pressure from samples we can assume that
- // we only have interpolated pressure (the pressure in the entry may be stored in the sensor
- // pressure field if this is the first or last entry for this tank... see details in gaspressures.c
- pressure_t pressure;
- pressure.mbar = INTERPOLATED_PRESSURE(gasChangeEntry) ? : SENSOR_PRESSURE(gasChangeEntry);
- QAction *adjustOldPressure = m.addAction(tr("Adjust pressure of tank %1 (currently interpolated as %2)")
- .arg(gasChangeEntry->cylinderindex + 1).arg(get_pressure_string(pressure)));
- }
- if (SENSOR_PRESSURE(newGasEntry) == 0 || displayed_dive.cylinder[newGasEntry->cylinderindex].sample_start.mbar == 0) {
- // we only have interpolated press -- see commend above
- pressure_t pressure;
- pressure.mbar = INTERPOLATED_PRESSURE(newGasEntry) ? : SENSOR_PRESSURE(newGasEntry);
- QAction *adjustOldPressure = m.addAction(tr("Adjust pressure of tank %1 (currently interpolated as %2)")
- .arg(newGasEntry->cylinderindex + 1).arg(get_pressure_string(pressure)));
- }
- }
- }
-#endif
- }
- bool some_hidden = false;
- for (int i = 0; i < evn_used; i++) {
- if (ev_namelist[i].plot_ev == false) {
- some_hidden = true;
- break;
- }
- }
- if (some_hidden) {
- action = m.addAction(tr("Unhide all events"), this, SLOT(unhideEvents()));
- action->setData(event->globalPos());
- }
- m.exec(event->globalPos());
-}
-
-void ProfileWidget2::deleteCurrentDC()
-{
- delete_current_divecomputer();
- mark_divelist_changed(true);
- // we need to force it since it's likely the same dive and same dc_number - but that's a different dive computer now
- MainWindow::instance()->graphics()->plotDive(0, true);
- MainWindow::instance()->refreshDisplay();
-}
-
-void ProfileWidget2::makeFirstDC()
-{
- make_first_dc();
- mark_divelist_changed(true);
- // this is now the first DC, so we need to redraw the profile and refresh the dive list
- // (and no, it's not just enough to rewrite the text - the first DC is special so values in the
- // dive list may change).
- // As a side benefit, this returns focus to the dive list.
- dc_number = 0;
- MainWindow::instance()->refreshDisplay();
-}
-
-void ProfileWidget2::hideEvents()
-{
- QAction *action = qobject_cast<QAction *>(sender());
- DiveEventItem *item = static_cast<DiveEventItem *>(action->data().value<void *>());
- struct event *event = item->getEvent();
-
- if (QMessageBox::question(MainWindow::instance(),
- TITLE_OR_TEXT(tr("Hide events"), tr("Hide all %1 events?").arg(event->name)),
- QMessageBox::Ok | QMessageBox::Cancel) == QMessageBox::Ok) {
- if (!same_string(event->name, "")) {
- for (int i = 0; i < evn_used; i++) {
- if (same_string(event->name, ev_namelist[i].ev_name)) {
- ev_namelist[i].plot_ev = false;
- break;
- }
- }
- Q_FOREACH (DiveEventItem *evItem, eventItems) {
- if (same_string(evItem->getEvent()->name, event->name))
- evItem->hide();
- }
- } else {
- item->hide();
- }
- }
-}
-
-void ProfileWidget2::unhideEvents()
-{
- for (int i = 0; i < evn_used; i++) {
- ev_namelist[i].plot_ev = true;
- }
- Q_FOREACH (DiveEventItem *item, eventItems)
- item->show();
-}
-
-void ProfileWidget2::removeEvent()
-{
- QAction *action = qobject_cast<QAction *>(sender());
- DiveEventItem *item = static_cast<DiveEventItem *>(action->data().value<void *>());
- struct event *event = item->getEvent();
-
- if (QMessageBox::question(MainWindow::instance(), TITLE_OR_TEXT(
- tr("Remove the selected event?"),
- tr("%1 @ %2:%3").arg(event->name).arg(event->time.seconds / 60).arg(event->time.seconds % 60, 2, 10, QChar('0'))),
- QMessageBox::Ok | QMessageBox::Cancel) == QMessageBox::Ok) {
- remove_event(event);
- mark_divelist_changed(true);
- replot();
- }
-}
-
-void ProfileWidget2::addBookmark()
-{
- QAction *action = qobject_cast<QAction *>(sender());
- QPointF scenePos = mapToScene(mapFromGlobal(action->data().toPoint()));
- add_event(current_dc, timeAxis->valueAt(scenePos), SAMPLE_EVENT_BOOKMARK, 0, 0, "bookmark");
- mark_divelist_changed(true);
- replot();
-}
-
-void ProfileWidget2::addSetpointChange()
-{
- QAction *action = qobject_cast<QAction *>(sender());
- QPointF scenePos = mapToScene(mapFromGlobal(action->data().toPoint()));
- SetpointDialog::instance()->setpointData(current_dc, timeAxis->valueAt(scenePos));
- SetpointDialog::instance()->show();
-}
-
-void ProfileWidget2::changeGas()
-{
- QAction *action = qobject_cast<QAction *>(sender());
- QPointF scenePos = mapToScene(mapFromGlobal(action->data().toPoint()));
- QString gas = action->text();
- gas.remove(QRegExp(" \\(.*\\)"));
-
- // backup the things on the dataModel, since we will clear that out.
- struct gasmix gasmix;
- qreal sec_val = timeAxis->valueAt(scenePos);
-
- // no gas changes before the dive starts
- unsigned int seconds = (sec_val < 0.0) ? 0 : (unsigned int)sec_val;
-
- // if there is a gas change at this time stamp, remove it before adding the new one
- struct event *gasChangeEvent = current_dc->events;
- while ((gasChangeEvent = get_next_event(gasChangeEvent, "gaschange")) != NULL) {
- if (gasChangeEvent->time.seconds == seconds) {
- remove_event(gasChangeEvent);
- gasChangeEvent = current_dc->events;
- } else {
- gasChangeEvent = gasChangeEvent->next;
- }
- }
- validate_gas(gas.toUtf8().constData(), &gasmix);
- QRegExp rx("\\(\\D*(\\d+)");
- int tank;
- if (rx.indexIn(action->text()) > -1) {
- tank = rx.cap(1).toInt() - 1; // we display the tank 1 based
- } else {
- qDebug() << "failed to parse tank number";
- tank = get_gasidx(&displayed_dive, &gasmix);
- }
- // add this both to the displayed dive and the current dive
- add_gas_switch_event(current_dive, current_dc, seconds, tank);
- add_gas_switch_event(&displayed_dive, get_dive_dc(&displayed_dive, dc_number), seconds, tank);
- // this means we potentially have a new tank that is being used and needs to be shown
- fixup_dive(&displayed_dive);
-
- // FIXME - this no longer gets written to the dive list - so we need to enableEdition() here
-
- MainWindow::instance()->information()->updateDiveInfo();
- mark_divelist_changed(true);
- replot();
-}
-
-bool ProfileWidget2::getPrintMode()
-{
- return printMode;
-}
-
-void ProfileWidget2::setPrintMode(bool mode, bool grayscale)
-{
- printMode = mode;
- resetZoom();
-
- // set printMode for axes
- profileYAxis->setPrintMode(mode);
- gasYAxis->setPrintMode(mode);
- temperatureAxis->setPrintMode(mode);
- timeAxis->setPrintMode(mode);
- cylinderPressureAxis->setPrintMode(mode);
- heartBeatAxis->setPrintMode(mode);
- percentageAxis->setPrintMode(mode);
-
- isGrayscale = mode ? grayscale : false;
- mouseFollowerHorizontal->setVisible(!mode);
- mouseFollowerVertical->setVisible(!mode);
-}
-
-void ProfileWidget2::setFontPrintScale(double scale)
-{
- fontPrintScale = scale;
- emit fontPrintScaleChanged(scale);
-}
-
-double ProfileWidget2::getFontPrintScale()
-{
- if (printMode)
- return fontPrintScale;
- else
- return 1.0;
-}
-
-void ProfileWidget2::editName()
-{
- QAction *action = qobject_cast<QAction *>(sender());
- DiveEventItem *item = static_cast<DiveEventItem *>(action->data().value<void *>());
- struct event *event = item->getEvent();
- bool ok;
- QString newName = QInputDialog::getText(MainWindow::instance(), tr("Edit name of bookmark"),
- tr("Custom name:"), QLineEdit::Normal,
- event->name, &ok);
- if (ok && !newName.isEmpty()) {
- if (newName.length() > 22) { //longer names will display as garbage.
- QMessageBox lengthWarning;
- lengthWarning.setText(tr("Name is too long!"));
- lengthWarning.exec();
- return;
- }
- // order is important! first update the current dive (by matching the unchanged event),
- // then update the displayed dive (as event is part of the events on displayed dive
- // and will be freed as part of changing the name!
- update_event_name(current_dive, event, newName.toUtf8().data());
- update_event_name(&displayed_dive, event, newName.toUtf8().data());
- mark_divelist_changed(true);
- replot();
- }
-}
-
-void ProfileWidget2::disconnectTemporaryConnections()
-{
- DivePlannerPointsModel *plannerModel = DivePlannerPointsModel::instance();
- disconnect(plannerModel, SIGNAL(dataChanged(QModelIndex, QModelIndex)), this, SLOT(replot()));
- disconnect(plannerModel, SIGNAL(cylinderModelEdited()), this, SLOT(replot()));
-
- disconnect(plannerModel, SIGNAL(rowsInserted(const QModelIndex &, int, int)),
- this, SLOT(pointInserted(const QModelIndex &, int, int)));
- disconnect(plannerModel, SIGNAL(rowsRemoved(const QModelIndex &, int, int)),
- this, SLOT(pointsRemoved(const QModelIndex &, int, int)));
-
- Q_FOREACH (QAction *action, actionsForKeys.values()) {
- action->setShortcut(QKeySequence());
- action->setShortcutContext(Qt::WidgetShortcut);
- }
-}
-
-void ProfileWidget2::pointInserted(const QModelIndex &parent, int start, int end)
-{
- DiveHandler *item = new DiveHandler();
- scene()->addItem(item);
- handles << item;
-
- connect(item, SIGNAL(moved()), this, SLOT(recreatePlannedDive()));
- connect(item, SIGNAL(clicked()), this, SLOT(divePlannerHandlerClicked()));
- connect(item, SIGNAL(released()), this, SLOT(divePlannerHandlerReleased()));
- QGraphicsSimpleTextItem *gasChooseBtn = new QGraphicsSimpleTextItem();
- scene()->addItem(gasChooseBtn);
- gasChooseBtn->setZValue(10);
- gasChooseBtn->setFlag(QGraphicsItem::ItemIgnoresTransformations);
- gases << gasChooseBtn;
- DivePlannerPointsModel *plannerModel = DivePlannerPointsModel::instance();
- if (plannerModel->recalcQ())
- replot();
-}
-
-void ProfileWidget2::pointsRemoved(const QModelIndex &, int start, int end)
-{ // start and end are inclusive.
- int num = (end - start) + 1;
- for (int i = num; i != 0; i--) {
- delete handles.back();
- handles.pop_back();
- delete gases.back();
- gases.pop_back();
- }
- scene()->clearSelection();
- replot();
-}
-
-void ProfileWidget2::repositionDiveHandlers()
-{
- DivePlannerPointsModel *plannerModel = DivePlannerPointsModel::instance();
- // Re-position the user generated dive handlers
- struct gasmix mix, lastmix;
- for (int i = 0; i < plannerModel->rowCount(); i++) {
- struct divedatapoint datapoint = plannerModel->at(i);
- if (datapoint.time == 0) // those are the magic entries for tanks
- continue;
- DiveHandler *h = handles.at(i);
- h->setVisible(datapoint.entered);
- h->setPos(timeAxis->posAtValue(datapoint.time), profileYAxis->posAtValue(datapoint.depth));
- QPointF p1;
- if (i == 0) {
- if (prefs.drop_stone_mode)
- // place the text on the straight line from the drop to stone position
- p1 = QPointF(timeAxis->posAtValue(datapoint.depth / prefs.descrate),
- profileYAxis->posAtValue(datapoint.depth));
- else
- // place the text on the straight line from the origin to the first position
- p1 = QPointF(timeAxis->posAtValue(0), profileYAxis->posAtValue(0));
- } else {
- // place the text on the line from the last position
- p1 = handles[i - 1]->pos();
- }
- QPointF p2 = handles[i]->pos();
- QLineF line(p1, p2);
- QPointF pos = line.pointAt(0.5);
- gases[i]->setPos(pos);
- gases[i]->setText(get_divepoint_gas_string(datapoint));
- gases[i]->setVisible(datapoint.entered &&
- (i == 0 || gases[i]->text() != gases[i-1]->text()));
- }
-}
-
-int ProfileWidget2::fixHandlerIndex(DiveHandler *activeHandler)
-{
- int index = handles.indexOf(activeHandler);
- if (index > 0 && index < handles.count() - 1) {
- DiveHandler *before = handles[index - 1];
- if (before->pos().x() > activeHandler->pos().x()) {
- handles.swap(index, index - 1);
- return index - 1;
- }
- DiveHandler *after = handles[index + 1];
- if (after->pos().x() < activeHandler->pos().x()) {
- handles.swap(index, index + 1);
- return index + 1;
- }
- }
- return index;
-}
-
-void ProfileWidget2::recreatePlannedDive()
-{
- DiveHandler *activeHandler = qobject_cast<DiveHandler *>(sender());
- DivePlannerPointsModel *plannerModel = DivePlannerPointsModel::instance();
- int index = fixHandlerIndex(activeHandler);
- int mintime = 0, maxtime = (timeAxis->maximum() + 10) * 60;
- if (index > 0)
- mintime = plannerModel->at(index - 1).time;
- if (index < plannerModel->size() - 1)
- maxtime = plannerModel->at(index + 1).time;
-
- int minutes = rint(timeAxis->valueAt(activeHandler->pos()) / 60);
- if (minutes * 60 <= mintime || minutes * 60 >= maxtime)
- return;
-
- divedatapoint data = plannerModel->at(index);
- data.depth = rint(profileYAxis->valueAt(activeHandler->pos()) / M_OR_FT(1, 1)) * M_OR_FT(1, 1);
- data.time = rint(timeAxis->valueAt(activeHandler->pos()));
-
- plannerModel->editStop(index, data);
-}
-
-void ProfileWidget2::keyDownAction()
-{
- if (currentState != ADD && currentState != PLAN)
- return;
-
- DivePlannerPointsModel *plannerModel = DivePlannerPointsModel::instance();
- Q_FOREACH (QGraphicsItem *i, scene()->selectedItems()) {
- if (DiveHandler *handler = qgraphicsitem_cast<DiveHandler *>(i)) {
- int row = handles.indexOf(handler);
- divedatapoint dp = plannerModel->at(row);
- if (dp.depth >= profileYAxis->maximum())
- continue;
-
- dp.depth += M_OR_FT(1, 5);
- plannerModel->editStop(row, dp);
- }
- }
-}
-
-void ProfileWidget2::keyUpAction()
-{
- if (currentState != ADD && currentState != PLAN)
- return;
-
- DivePlannerPointsModel *plannerModel = DivePlannerPointsModel::instance();
- Q_FOREACH (QGraphicsItem *i, scene()->selectedItems()) {
- if (DiveHandler *handler = qgraphicsitem_cast<DiveHandler *>(i)) {
- int row = handles.indexOf(handler);
- divedatapoint dp = plannerModel->at(row);
-
- if (dp.depth <= 0)
- continue;
-
- dp.depth -= M_OR_FT(1, 5);
- plannerModel->editStop(row, dp);
- }
- }
-}
-
-void ProfileWidget2::keyLeftAction()
-{
- if (currentState != ADD && currentState != PLAN)
- return;
-
- DivePlannerPointsModel *plannerModel = DivePlannerPointsModel::instance();
- Q_FOREACH (QGraphicsItem *i, scene()->selectedItems()) {
- if (DiveHandler *handler = qgraphicsitem_cast<DiveHandler *>(i)) {
- int row = handles.indexOf(handler);
- divedatapoint dp = plannerModel->at(row);
-
- if (dp.time / 60 <= 0)
- continue;
-
- // don't overlap positions.
- // maybe this is a good place for a 'goto'?
- double xpos = timeAxis->posAtValue((dp.time - 60) / 60);
- bool nextStep = false;
- Q_FOREACH (DiveHandler *h, handles) {
- if (IS_FP_SAME(h->pos().x(), xpos)) {
- nextStep = true;
- break;
- }
- }
- if (nextStep)
- continue;
-
- dp.time -= 60;
- plannerModel->editStop(row, dp);
- }
- }
-}
-
-void ProfileWidget2::keyRightAction()
-{
- if (currentState != ADD && currentState != PLAN)
- return;
-
- DivePlannerPointsModel *plannerModel = DivePlannerPointsModel::instance();
- Q_FOREACH (QGraphicsItem *i, scene()->selectedItems()) {
- if (DiveHandler *handler = qgraphicsitem_cast<DiveHandler *>(i)) {
- int row = handles.indexOf(handler);
- divedatapoint dp = plannerModel->at(row);
- if (dp.time / 60.0 >= timeAxis->maximum())
- continue;
-
- // don't overlap positions.
- // maybe this is a good place for a 'goto'?
- double xpos = timeAxis->posAtValue((dp.time + 60) / 60);
- bool nextStep = false;
- Q_FOREACH (DiveHandler *h, handles) {
- if (IS_FP_SAME(h->pos().x(), xpos)) {
- nextStep = true;
- break;
- }
- }
- if (nextStep)
- continue;
-
- dp.time += 60;
- plannerModel->editStop(row, dp);
- }
- }
-}
-
-void ProfileWidget2::keyDeleteAction()
-{
- if (currentState != ADD && currentState != PLAN)
- return;
-
- DivePlannerPointsModel *plannerModel = DivePlannerPointsModel::instance();
- int selCount = scene()->selectedItems().count();
- if (selCount) {
- QVector<int> selectedIndexes;
- Q_FOREACH (QGraphicsItem *i, scene()->selectedItems()) {
- if (DiveHandler *handler = qgraphicsitem_cast<DiveHandler *>(i)) {
- selectedIndexes.push_back(handles.indexOf(handler));
- handler->hide();
- }
- }
- plannerModel->removeSelectedPoints(selectedIndexes);
- }
-}
-
-void ProfileWidget2::keyEscAction()
-{
- if (currentState != ADD && currentState != PLAN)
- return;
-
- if (scene()->selectedItems().count()) {
- scene()->clearSelection();
- return;
- }
-
- DivePlannerPointsModel *plannerModel = DivePlannerPointsModel::instance();
- if (plannerModel->isPlanner())
- plannerModel->cancelPlan();
-}
-
-void ProfileWidget2::plotPictures()
-{
- Q_FOREACH (DivePictureItem *item, pictures) {
- item->hide();
- item->deleteLater();
- }
- pictures.clear();
-
- if (printMode)
- return;
-
- double x, y, lastX = -1.0, lastY = -1.0;
- DivePictureModel *m = DivePictureModel::instance();
- for (int i = 0; i < m->rowCount(); i++) {
- int offsetSeconds = m->index(i, 1).data(Qt::UserRole).value<int>();
- // it's a correct picture, but doesn't have a timestamp: only show on the widget near the
- // information area.
- if (!offsetSeconds)
- continue;
- DivePictureItem *item = new DivePictureItem();
- item->setPixmap(m->index(i, 0).data(Qt::DecorationRole).value<QPixmap>());
- item->setFileUrl(m->index(i, 1).data().toString());
- // let's put the picture at the correct time, but at a fixed "depth" on the profile
- // not sure this is ideal, but it seems to look right.
- x = timeAxis->posAtValue(offsetSeconds);
- if (i == 0)
- y = 10;
- else if (fabs(x - lastX) < 4)
- y = lastY + 3;
- else
- y = 10;
- lastX = x;
- lastY = y;
- item->setPos(x, y);
- scene()->addItem(item);
- pictures.push_back(item);
- }
-}
diff --git a/desktop-widgets/profile/profilewidget2.h b/desktop-widgets/profile/profilewidget2.h
deleted file mode 100644
index f11ec5be1..000000000
--- a/desktop-widgets/profile/profilewidget2.h
+++ /dev/null
@@ -1,211 +0,0 @@
-#ifndef PROFILEWIDGET2_H
-#define PROFILEWIDGET2_H
-
-#include <QGraphicsView>
-
-// /* The idea of this widget is to display and edit the profile.
-// * It has:
-// * 1 - ToolTip / Legend item, displays every information of the current mouse position on it, plus the legends of the maps.
-// * 2 - ToolBox, displays the QActions that are used to do special stuff on the profile ( like activating the plugins. )
-// * 3 - Cartesian Axis for depth ( y )
-// * 4 - Cartesian Axis for Gases ( y )
-// * 5 - Cartesian Axis for Time ( x )
-// *
-// * It needs to be dynamic, things should *flow* on it, not just appear / disappear.
-// */
-#include "divelineitem.h"
-#include "diveprofileitem.h"
-#include "display.h"
-
-class RulerItem2;
-struct dive;
-struct plot_info;
-class ToolTipItem;
-class DiveMeanDepth;
-class DiveReportedCeiling;
-class DiveTextItem;
-class TemperatureAxis;
-class DiveEventItem;
-class DivePlotDataModel;
-class DivePixmapItem;
-class DiveRectItem;
-class DepthAxis;
-class DiveCartesianAxis;
-class DiveProfileItem;
-class TimeAxis;
-class DiveTemperatureItem;
-class DiveHeartrateItem;
-class PercentageItem;
-class DiveGasPressureItem;
-class DiveCalculatedCeiling;
-class DiveCalculatedTissue;
-class PartialPressureGasItem;
-class PartialGasPressureAxis;
-class AbstractProfilePolygonItem;
-class TankItem;
-class DiveHandler;
-class QGraphicsSimpleTextItem;
-class QModelIndex;
-class DivePictureItem;
-
-class ProfileWidget2 : public QGraphicsView {
- Q_OBJECT
-public:
- enum State {
- EMPTY,
- PROFILE,
- EDIT,
- ADD,
- PLAN,
- INVALID
- };
- enum Items {
- BACKGROUND,
- PROFILE_Y_AXIS,
- GAS_Y_AXIS,
- TIME_AXIS,
- DEPTH_CONTROLLER,
- TIME_CONTROLLER,
- COLUMNS
- };
-
- ProfileWidget2(QWidget *parent = 0);
- void resetZoom();
- void plotDive(struct dive *d = 0, bool force = false);
- virtual bool eventFilter(QObject *, QEvent *);
- void setupItem(AbstractProfilePolygonItem *item, DiveCartesianAxis *hAxis, DiveCartesianAxis *vAxis, DivePlotDataModel *model, int vData, int hData, int zValue);
- void setPrintMode(bool mode, bool grayscale = false);
- bool getPrintMode();
- bool isPointOutOfBoundaries(const QPointF &point) const;
- bool isPlanner();
- bool isAddOrPlanner();
- double getFontPrintScale();
- void setFontPrintScale(double scale);
- void clearHandlers();
- void recalcCeiling();
- void setToolTipVisibile(bool visible);
- State currentState;
-
-signals:
- void fontPrintScaleChanged(double scale);
-
-public
-slots: // Necessary to call from QAction's signals.
- void settingsChanged();
- void setEmptyState();
- void setProfileState();
- void setPlanState();
- void setAddState();
- void changeGas();
- void addSetpointChange();
- void addBookmark();
- void hideEvents();
- void unhideEvents();
- void removeEvent();
- void editName();
- void makeFirstDC();
- void deleteCurrentDC();
- void pointInserted(const QModelIndex &parent, int start, int end);
- void pointsRemoved(const QModelIndex &, int start, int end);
- void plotPictures();
- void setReplot(bool state);
- void replot(dive *d = 0);
-
- /* this is called for every move on the handlers. maybe we can speed up this a bit? */
- void recreatePlannedDive();
-
- /* key press handlers */
- void keyEscAction();
- void keyDeleteAction();
- void keyUpAction();
- void keyDownAction();
- void keyLeftAction();
- void keyRightAction();
-
- void divePlannerHandlerClicked();
- void divePlannerHandlerReleased();
-
-protected:
- virtual ~ProfileWidget2();
- virtual void resizeEvent(QResizeEvent *event);
- virtual void wheelEvent(QWheelEvent *event);
- virtual void mouseMoveEvent(QMouseEvent *event);
- virtual void contextMenuEvent(QContextMenuEvent *event);
- virtual void mouseDoubleClickEvent(QMouseEvent *event);
- virtual void mousePressEvent(QMouseEvent *event);
- virtual void mouseReleaseEvent(QMouseEvent *event);
-
-private: /*methods*/
- void fixBackgroundPos();
- void scrollViewTo(const QPoint &pos);
- void setupSceneAndFlags();
- void setupItemSizes();
- void addItemsToScene();
- void setupItemOnScene();
- void disconnectTemporaryConnections();
- struct plot_data *getEntryFromPos(QPointF pos);
-
-private:
- DivePlotDataModel *dataModel;
- int zoomLevel;
- qreal zoomFactor;
- DivePixmapItem *background;
- QString backgroundFile;
- ToolTipItem *toolTipItem;
- bool isPlotZoomed;
- bool replotEnabled;
- // All those here should probably be merged into one structure,
- // So it's esyer to replicate for more dives later.
- // In the meantime, keep it here.
- struct plot_info plotInfo;
- DepthAxis *profileYAxis;
- PartialGasPressureAxis *gasYAxis;
- TemperatureAxis *temperatureAxis;
- TimeAxis *timeAxis;
- DiveProfileItem *diveProfileItem;
- DiveTemperatureItem *temperatureItem;
- DiveMeanDepthItem *meanDepthItem;
- DiveCartesianAxis *cylinderPressureAxis;
- DiveGasPressureItem *gasPressureItem;
- QList<DiveEventItem *> eventItems;
- DiveTextItem *diveComputerText;
- DiveCalculatedCeiling *diveCeiling;
- DiveTextItem *gradientFactor;
- QList<DiveCalculatedTissue *> allTissues;
- DiveReportedCeiling *reportedCeiling;
- PartialPressureGasItem *pn2GasItem;
- PartialPressureGasItem *pheGasItem;
- PartialPressureGasItem *po2GasItem;
- PartialPressureGasItem *o2SetpointGasItem;
- PartialPressureGasItem *ccrsensor1GasItem;
- PartialPressureGasItem *ccrsensor2GasItem;
- PartialPressureGasItem *ccrsensor3GasItem;
- DiveCartesianAxis *heartBeatAxis;
- DiveHeartrateItem *heartBeatItem;
- DiveCartesianAxis *percentageAxis;
- QList<DivePercentageItem *> allPercentages;
- DiveAmbPressureItem *ambPressureItem;
- DiveGFLineItem *gflineItem;
- DiveLineItem *mouseFollowerVertical;
- DiveLineItem *mouseFollowerHorizontal;
- RulerItem2 *rulerItem;
- TankItem *tankItem;
- bool isGrayscale;
- bool printMode;
-
- //specifics for ADD and PLAN
- QList<DiveHandler *> handles;
- QList<QGraphicsSimpleTextItem *> gases;
- QList<DivePictureItem *> pictures;
- void repositionDiveHandlers();
- int fixHandlerIndex(DiveHandler *activeHandler);
- friend class DiveHandler;
- QHash<Qt::Key, QAction *> actionsForKeys;
- bool shouldCalculateMaxTime;
- bool shouldCalculateMaxDepth;
- int maxtime;
- int maxdepth;
- double fontPrintScale;
-};
-
-#endif // PROFILEWIDGET2_H
diff --git a/desktop-widgets/profile/ruleritem.cpp b/desktop-widgets/profile/ruleritem.cpp
deleted file mode 100644
index 830985552..000000000
--- a/desktop-widgets/profile/ruleritem.cpp
+++ /dev/null
@@ -1,179 +0,0 @@
-#include "ruleritem.h"
-#include "preferences.h"
-#include "mainwindow.h"
-#include "profilewidget2.h"
-#include "display.h"
-
-#include <qgraphicssceneevent.h>
-
-#include "profile.h"
-
-RulerNodeItem2::RulerNodeItem2() :
- entry(NULL),
- ruler(NULL),
- timeAxis(NULL),
- depthAxis(NULL)
-{
- memset(&pInfo, 0, sizeof(pInfo));
- setRect(-8, -8, 16, 16);
- setBrush(QColor(0xff, 0, 0, 127));
- setPen(QColor(Qt::red));
- setFlag(ItemIsMovable);
- setFlag(ItemSendsGeometryChanges);
- setFlag(ItemIgnoresTransformations);
-}
-
-void RulerNodeItem2::setPlotInfo(plot_info &info)
-{
- pInfo = info;
- entry = pInfo.entry;
-}
-
-void RulerNodeItem2::setRuler(RulerItem2 *r)
-{
- ruler = r;
-}
-
-void RulerNodeItem2::recalculate()
-{
- struct plot_data *data = pInfo.entry + (pInfo.nr - 1);
- uint16_t count = 0;
- if (x() < 0) {
- setPos(0, y());
- } else if (x() > timeAxis->posAtValue(data->sec)) {
- setPos(timeAxis->posAtValue(data->sec), depthAxis->posAtValue(data->depth));
- } else {
- data = pInfo.entry;
- count = 0;
- while (timeAxis->posAtValue(data->sec) < x() && count < pInfo.nr) {
- data = pInfo.entry + count;
- count++;
- }
- setPos(timeAxis->posAtValue(data->sec), depthAxis->posAtValue(data->depth));
- entry = data;
- }
-}
-
-void RulerNodeItem2::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
-{
- qreal x = event->scenePos().x();
- if (x < 0.0)
- x = 0.0;
- setPos(x, event->scenePos().y());
- recalculate();
- ruler->recalculate();
-}
-
-RulerItem2::RulerItem2() : source(new RulerNodeItem2()),
- dest(new RulerNodeItem2()),
- timeAxis(NULL),
- depthAxis(NULL),
- textItemBack(new QGraphicsRectItem(this)),
- textItem(new QGraphicsSimpleTextItem(this))
-{
- memset(&pInfo, 0, sizeof(pInfo));
- source->setRuler(this);
- dest->setRuler(this);
- textItem->setFlag(QGraphicsItem::ItemIgnoresTransformations);
- textItemBack->setBrush(QColor(0xff, 0xff, 0xff, 190));
- textItemBack->setPen(QColor(Qt::white));
- textItemBack->setFlag(QGraphicsItem::ItemIgnoresTransformations);
- setPen(QPen(QColor(Qt::black), 0.0));
- connect(PreferencesDialog::instance(), SIGNAL(settingsChanged()), this, SLOT(settingsChanged()));
-}
-
-void RulerItem2::settingsChanged()
-{
- ProfileWidget2 *profWidget = NULL;
- if (scene() && scene()->views().count())
- profWidget = qobject_cast<ProfileWidget2 *>(scene()->views().first());
-
- if (profWidget && profWidget->currentState == ProfileWidget2::PROFILE)
- setVisible(prefs.rulergraph);
- else
- setVisible(false);
-}
-
-void RulerItem2::recalculate()
-{
- char buffer[500];
- QPointF tmp;
- QFont font;
- QFontMetrics fm(font);
-
- if (timeAxis == NULL || depthAxis == NULL || pInfo.nr == 0)
- return;
-
- prepareGeometryChange();
- startPoint = mapFromItem(source, 0, 0);
- endPoint = mapFromItem(dest, 0, 0);
-
- if (startPoint.x() > endPoint.x()) {
- tmp = endPoint;
- endPoint = startPoint;
- startPoint = tmp;
- }
- QLineF line(startPoint, endPoint);
- setLine(line);
- compare_samples(source->entry, dest->entry, buffer, 500, 1);
- text = QString(buffer);
-
- // draw text
- QGraphicsView *view = scene()->views().first();
- QPoint begin = view->mapFromScene(mapToScene(startPoint));
- textItem->setText(text);
- qreal tgtX = startPoint.x();
- const qreal diff = begin.x() + textItem->boundingRect().width();
- // clamp so that the text doesn't go out of the screen to the right
- if (diff > view->width()) {
- begin.setX(begin.x() - (diff - view->width()));
- tgtX = mapFromScene(view->mapToScene(begin)).x();
- }
- // always show the text bellow the lowest of the start and end points
- qreal tgtY = (startPoint.y() >= endPoint.y()) ? startPoint.y() : endPoint.y();
- // this isn't exactly optimal, since we want to scale the 1.0, 4.0 distances as well
- textItem->setPos(tgtX - 1.0, tgtY + 4.0);
-
- // setup the text background
- textItemBack->setVisible(startPoint.x() != endPoint.x());
- textItemBack->setPos(textItem->x(), textItem->y());
- textItemBack->setRect(0, 0, textItem->boundingRect().width(), textItem->boundingRect().height());
-}
-
-RulerNodeItem2 *RulerItem2::sourceNode() const
-{
- return source;
-}
-
-RulerNodeItem2 *RulerItem2::destNode() const
-{
- return dest;
-}
-
-void RulerItem2::setPlotInfo(plot_info info)
-{
- pInfo = info;
- dest->setPlotInfo(info);
- source->setPlotInfo(info);
- dest->recalculate();
- source->recalculate();
- recalculate();
-}
-
-void RulerItem2::setAxis(DiveCartesianAxis *time, DiveCartesianAxis *depth)
-{
- timeAxis = time;
- depthAxis = depth;
- dest->depthAxis = depth;
- dest->timeAxis = time;
- source->depthAxis = depth;
- source->timeAxis = time;
- recalculate();
-}
-
-void RulerItem2::setVisible(bool visible)
-{
- QGraphicsLineItem::setVisible(visible);
- source->setVisible(visible);
- dest->setVisible(visible);
-}
diff --git a/desktop-widgets/profile/ruleritem.h b/desktop-widgets/profile/ruleritem.h
deleted file mode 100644
index 4fad0451c..000000000
--- a/desktop-widgets/profile/ruleritem.h
+++ /dev/null
@@ -1,59 +0,0 @@
-#ifndef RULERITEM_H
-#define RULERITEM_H
-
-#include <QObject>
-#include <QGraphicsEllipseItem>
-#include <QGraphicsObject>
-#include "divecartesianaxis.h"
-#include "display.h"
-
-struct plot_data;
-class RulerItem2;
-
-class RulerNodeItem2 : public QObject, public QGraphicsEllipseItem {
- Q_OBJECT
- friend class RulerItem2;
-
-public:
- explicit RulerNodeItem2();
- void setRuler(RulerItem2 *r);
- void setPlotInfo(struct plot_info &info);
- void recalculate();
-
-protected:
- virtual void mouseMoveEvent(QGraphicsSceneMouseEvent *event);
-private:
- struct plot_info pInfo;
- struct plot_data *entry;
- RulerItem2 *ruler;
- DiveCartesianAxis *timeAxis;
- DiveCartesianAxis *depthAxis;
-};
-
-class RulerItem2 : public QObject, public QGraphicsLineItem {
- Q_OBJECT
-public:
- explicit RulerItem2();
- void recalculate();
-
- void setPlotInfo(struct plot_info pInfo);
- RulerNodeItem2 *sourceNode() const;
- RulerNodeItem2 *destNode() const;
- void setAxis(DiveCartesianAxis *time, DiveCartesianAxis *depth);
- void setVisible(bool visible);
-
-public
-slots:
- void settingsChanged();
-
-private:
- struct plot_info pInfo;
- QPointF startPoint, endPoint;
- RulerNodeItem2 *source, *dest;
- QString text;
- DiveCartesianAxis *timeAxis;
- DiveCartesianAxis *depthAxis;
- QGraphicsRectItem *textItemBack;
- QGraphicsSimpleTextItem *textItem;
-};
-#endif
diff --git a/desktop-widgets/profile/tankitem.cpp b/desktop-widgets/profile/tankitem.cpp
deleted file mode 100644
index c0e75a371..000000000
--- a/desktop-widgets/profile/tankitem.cpp
+++ /dev/null
@@ -1,120 +0,0 @@
-#include "tankitem.h"
-#include "diveplotdatamodel.h"
-#include "divetextitem.h"
-#include "profile.h"
-#include <QPen>
-
-TankItem::TankItem(QObject *parent) :
- QGraphicsRectItem(),
- dataModel(0),
- pInfoEntry(0),
- pInfoNr(0)
-{
- height = 3;
- QColor red(PERSIANRED1);
- QColor blue(AIR_BLUE);
- QColor yellow(NITROX_YELLOW);
- QColor green(NITROX_GREEN);
- QLinearGradient nitroxGradient(QPointF(0, 0), QPointF(0, height));
- nitroxGradient.setColorAt(0.0, green);
- nitroxGradient.setColorAt(0.49, green);
- nitroxGradient.setColorAt(0.5, yellow);
- nitroxGradient.setColorAt(1.0, yellow);
- nitrox = nitroxGradient;
- oxygen = green;
- QLinearGradient trimixGradient(QPointF(0, 0), QPointF(0, height));
- trimixGradient.setColorAt(0.0, green);
- trimixGradient.setColorAt(0.49, green);
- trimixGradient.setColorAt(0.5, red);
- trimixGradient.setColorAt(1.0, red);
- trimix = trimixGradient;
- air = blue;
- memset(&diveCylinderStore, 0, sizeof(diveCylinderStore));
-}
-
-TankItem::~TankItem()
-{
- // Should this be clear_dive(diveCylinderStore)?
- for (int i = 0; i < MAX_CYLINDERS; i++)
- free((void *)diveCylinderStore.cylinder[i].type.description);
-}
-
-void TankItem::setData(DivePlotDataModel *model, struct plot_info *plotInfo, struct dive *d)
-{
- free(pInfoEntry);
- // the plotInfo and dive structures passed in could become invalid before we stop using them,
- // so copy the data that we need
- int size = plotInfo->nr * sizeof(plotInfo->entry[0]);
- pInfoEntry = (struct plot_data *)malloc(size);
- pInfoNr = plotInfo->nr;
- memcpy(pInfoEntry, plotInfo->entry, size);
- copy_cylinders(d, &diveCylinderStore, false);
- dataModel = model;
- connect(dataModel, SIGNAL(dataChanged(QModelIndex, QModelIndex)), this, SLOT(modelDataChanged(QModelIndex, QModelIndex)), Qt::UniqueConnection);
- modelDataChanged();
-}
-
-void TankItem::createBar(qreal x, qreal w, struct gasmix *gas)
-{
- // pick the right gradient, size, position and text
- QGraphicsRectItem *rect = new QGraphicsRectItem(x, 0, w, height, this);
- if (gasmix_is_air(gas))
- rect->setBrush(air);
- else if (gas->he.permille)
- rect->setBrush(trimix);
- else if (gas->o2.permille == 1000)
- rect->setBrush(oxygen);
- else
- rect->setBrush(nitrox);
- rect->setPen(QPen(QBrush(), 0.0)); // get rid of the thick line around the rectangle
- rects.push_back(rect);
- DiveTextItem *label = new DiveTextItem(rect);
- label->setText(gasname(gas));
- label->setBrush(Qt::black);
- label->setPos(x + 1, 0);
- label->setAlignment(Qt::AlignBottom | Qt::AlignRight);
- label->setZValue(101);
-}
-
-void TankItem::modelDataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight)
-{
- // We don't have enougth data to calculate things, quit.
-
- if (!dataModel || !pInfoEntry || !pInfoNr)
- return;
-
- // remove the old rectangles
- foreach (QGraphicsRectItem *r, rects) {
- delete(r);
- }
- rects.clear();
-
- // walk the list and figure out which tanks go where
- struct plot_data *entry = pInfoEntry;
- int cylIdx = entry->cylinderindex;
- int i = -1;
- int startTime = 0;
- struct gasmix *gas = &diveCylinderStore.cylinder[cylIdx].gasmix;
- qreal width, left;
- while (++i < pInfoNr) {
- entry = &pInfoEntry[i];
- if (entry->cylinderindex == cylIdx)
- continue;
- width = hAxis->posAtValue(entry->sec) - hAxis->posAtValue(startTime);
- left = hAxis->posAtValue(startTime);
- createBar(left, width, gas);
- cylIdx = entry->cylinderindex;
- gas = &diveCylinderStore.cylinder[cylIdx].gasmix;
- startTime = entry->sec;
- }
- width = hAxis->posAtValue(entry->sec) - hAxis->posAtValue(startTime);
- left = hAxis->posAtValue(startTime);
- createBar(left, width, gas);
-}
-
-void TankItem::setHorizontalAxis(DiveCartesianAxis *horizontal)
-{
- hAxis = horizontal;
- connect(hAxis, SIGNAL(sizeChanged()), this, SLOT(modelDataChanged()));
- modelDataChanged();
-}
diff --git a/desktop-widgets/profile/tankitem.h b/desktop-widgets/profile/tankitem.h
deleted file mode 100644
index fd685fc82..000000000
--- a/desktop-widgets/profile/tankitem.h
+++ /dev/null
@@ -1,39 +0,0 @@
-#ifndef TANKITEM_H
-#define TANKITEM_H
-
-#include <QGraphicsItem>
-#include <QModelIndex>
-#include <QBrush>
-#include "divelineitem.h"
-#include "divecartesianaxis.h"
-#include "dive.h"
-
-class TankItem : public QObject, public QGraphicsRectItem
-{
- Q_OBJECT
-
-public:
- explicit TankItem(QObject *parent = 0);
- ~TankItem();
- void setHorizontalAxis(DiveCartesianAxis *horizontal);
- void setData(DivePlotDataModel *model, struct plot_info *plotInfo, struct dive *d);
-
-signals:
-
-public slots:
- virtual void modelDataChanged(const QModelIndex &topLeft = QModelIndex(), const QModelIndex &bottomRight = QModelIndex());
-
-private:
- void createBar(qreal x, qreal w, struct gasmix *gas);
- DivePlotDataModel *dataModel;
- DiveCartesianAxis *hAxis;
- int hDataColumn;
- struct dive diveCylinderStore;
- struct plot_data *pInfoEntry;
- int pInfoNr;
- qreal height;
- QBrush air, nitrox, oxygen, trimix;
- QList<QGraphicsRectItem *> rects;
-};
-
-#endif // TANKITEM_H
diff --git a/desktop-widgets/simplewidgets.cpp b/desktop-widgets/simplewidgets.cpp
index 62a9cc646..43ad1ddc0 100644
--- a/desktop-widgets/simplewidgets.cpp
+++ b/desktop-widgets/simplewidgets.cpp
@@ -14,7 +14,7 @@
#include "libdivecomputer/parser.h"
#include "divelistview.h"
#include "display.h"
-#include "profile/profilewidget2.h"
+#include "profile-widget/profilewidget2.h"
#include "undocommands.h"
class MinMaxAvgWidgetPrivate {
diff --git a/desktop-widgets/socialnetworks.cpp b/desktop-widgets/socialnetworks.cpp
index 6e191267a..0794c764e 100644
--- a/desktop-widgets/socialnetworks.cpp
+++ b/desktop-widgets/socialnetworks.cpp
@@ -16,7 +16,7 @@
#include <QMessageBox>
#include <QInputDialog>
#include "mainwindow.h"
-#include "profile/profilewidget2.h"
+#include "profile-widget/profilewidget2.h"
#include "pref.h"
#include "helpers.h"
#include "ui_socialnetworksdialog.h"