summaryrefslogtreecommitdiffstats
path: root/qt-ui/profilegraphics.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'qt-ui/profilegraphics.cpp')
-rw-r--r--qt-ui/profilegraphics.cpp268
1 files changed, 164 insertions, 104 deletions
diff --git a/qt-ui/profilegraphics.cpp b/qt-ui/profilegraphics.cpp
index cfd155132..126690750 100644
--- a/qt-ui/profilegraphics.cpp
+++ b/qt-ui/profilegraphics.cpp
@@ -1,4 +1,6 @@
#include "profilegraphics.h"
+#include "mainwindow.h"
+#include "divelistview.h"
#include <QGraphicsScene>
#include <QResizeEvent>
@@ -12,11 +14,13 @@
#include <QPropertyAnimation>
#include <QGraphicsSceneHoverEvent>
#include <QMouseEvent>
+#include <qtextdocument.h>
#include "../color.h"
#include "../display.h"
#include "../dive.h"
#include "../profile.h"
+#include "../device.h"
#include <libdivecomputer/parser.h>
#include <libdivecomputer/version.h>
@@ -145,6 +149,7 @@ void ProfileGraphicsView::wheelEvent(QWheelEvent* event)
// Scale the view / do the zoom
QPoint toolTipPos = mapFromScene(toolTip->pos());
+
double scaleFactor = 1.15;
if (event->delta() > 0 && zoomLevel <= 10) {
scale(scaleFactor, scaleFactor);
@@ -171,14 +176,20 @@ void ProfileGraphicsView::mouseMoveEvent(QMouseEvent* event)
ensureVisible(event->pos().x() + dx, event->pos().y() + dy, 1, 1);
- toolTip->setPos(mapToScene(toolTipPos).x(), mapToScene(toolTipPos).y());
-
if (zoomLevel == 0)
QGraphicsView::mouseMoveEvent(event);
+ else
+ toolTip->setPos(mapToScene(toolTipPos).x(), mapToScene(toolTipPos).y());
}
bool ProfileGraphicsView::eventFilter(QObject* obj, QEvent* event)
{
+ if (event->type() == QEvent::Leave) {
+ if (toolTip && toolTip->isExpanded())
+ toolTip->collapse();
+ return true;
+ }
+
// This will "Eat" the default tooltip behavior.
if (event->type() == QEvent::GraphicsSceneHelp) {
event->ignore();
@@ -206,7 +217,7 @@ void ProfileGraphicsView::showEvent(QShowEvent* event)
// but the dive was not ploted.
// force a replot by modifying the dive
// hold by the view, and issuing a plot.
- if (dive) {
+ if (dive && !scene()->items().count()) {
dive = 0;
plot(get_dive(selected_dive));
}
@@ -214,10 +225,14 @@ void ProfileGraphicsView::showEvent(QShowEvent* event)
void ProfileGraphicsView::clear()
{
- scene()->clear();
resetTransform();
zoomLevel = 0;
- toolTip = 0;
+ if(toolTip){
+ scene()->removeItem(toolTip);
+ toolTip->deleteLater();
+ toolTip = 0;
+ }
+ scene()->clear();
}
void ProfileGraphicsView::refresh()
@@ -243,42 +258,32 @@ void ProfileGraphicsView::plot(struct dive *d, bool forceRedraw)
return;
}
+ // best place to put the focus stealer code.
+ setFocusProxy(mainWindow()->dive_list());
scene()->setSceneRect(0,0, viewport()->width()-50, viewport()->height()-50);
- QSettings s;
- s.beginGroup("ProfileMap");
- QPointF toolTipPos = s.value("tooltip_position", QPointF(0,0)).toPointF();
- s.endGroup();
-
toolTip = new ToolTipItem();
- toolTip->setPos(toolTipPos);
-
+ installEventFilter(toolTip);
scene()->addItem(toolTip);
// Fix this for printing / screen later.
// plot_set_scale(scale_mode_t);
if (!dc->samples) {
- static struct sample fake[4];
- static struct divecomputer fakedc;
- fakedc = dive->dc;
- fakedc.sample = fake;
- fakedc.samples = 4;
-
- /* The dive has no samples, so create a few fake ones. This assumes an
- ascent/descent rate of 9 m/min, which is just below the limit for FAST. */
- int duration = dive->dc.duration.seconds;
- int maxdepth = dive->dc.maxdepth.mm;
- int asc_desc_time = dive->dc.maxdepth.mm*60/9000;
- if (asc_desc_time * 2 >= duration)
- asc_desc_time = duration / 2;
- fake[1].time.seconds = asc_desc_time;
- fake[1].depth.mm = maxdepth;
- fake[2].time.seconds = duration - asc_desc_time;
- fake[2].depth.mm = maxdepth;
- fake[3].time.seconds = duration * 1.00;
- fakedc.events = dc->events;
- dc = &fakedc;
+ dc = fake_dc(dc);
+ }
+
+ QString nick(get_dc_nickname(dc->model, dc->deviceid));
+ if (nick.isEmpty())
+ nick = QString(dc->model);
+
+ if (nick.isEmpty())
+ nick = tr("unknown divecomputer");
+
+ if ( tr("unknown divecomputer") == nick){
+ mode = PLAN;
+ }else{
+ mode = DIVE;
}
/*
@@ -291,7 +296,7 @@ void ProfileGraphicsView::plot(struct dive *d, bool forceRedraw)
gc.maxx = (profile_grid_area.width() - 2 * profile_grid_area.x());
gc.maxy = (profile_grid_area.height() - 2 * profile_grid_area.y());
- /* This is per-dive-computer. Right now we just do the first one */
+ /* This is per-dive-computer */
gc.pi = *create_plot_info(dive, dc, &gc);
/* Depth profile */
@@ -303,7 +308,7 @@ void ProfileGraphicsView::plot(struct dive *d, bool forceRedraw)
plot_temperature_profile();
/* Cylinder pressure plot */
- plot_cylinder_pressure(dive, dc);
+ plot_cylinder_pressure(dc);
/* Text on top of all graphs.. */
plot_temperature_text();
@@ -322,13 +327,6 @@ void ProfileGraphicsView::plot(struct dive *d, bool forceRedraw)
scene()->addItem(rect);
/* Put the dive computer name in the lower left corner */
- QString nick(get_dc_nickname(dc->model, dc->deviceid));
- if (nick.isEmpty())
- nick = QString(dc->model);
-
- if (nick.isEmpty())
- nick = tr("unknown divecomputer");
-
gc.leftx = 0; gc.rightx = 1.0;
gc.topy = 0; gc.bottomy = 1.0;
@@ -342,7 +340,6 @@ void ProfileGraphicsView::plot(struct dive *d, bool forceRedraw)
plot_pp_text();
}
-
/* now shift the translation back by half the margin;
* this way we can draw the vertical scales on both sides */
//cairo_translate(gc->cr, -drawing_area->x / 2.0, 0);
@@ -366,6 +363,16 @@ void ProfileGraphicsView::plot(struct dive *d, bool forceRedraw)
if (zoomLevel == 0) {
fitInView(sceneRect());
}
+ toolTip->readPos();
+
+ if(mode == PLAN){
+ timeEditor = new GraphicsTextEditor();
+ timeEditor->setPlainText( dive->duration.seconds ? QString::number(dive->duration.seconds/60) : tr("Set Duration: 10 minutes"));
+ timeEditor->setPos(profile_grid_area.width() - timeEditor->boundingRect().width(), timeMarkers->y());
+ timeEditor->document();
+ connect(timeEditor, SIGNAL(editingFinished(QString)), this, SLOT(edit_dive_time(QString)));
+ scene()->addItem(timeEditor);
+ }
}
void ProfileGraphicsView::plot_depth_scale()
@@ -420,6 +427,17 @@ void ProfileGraphicsView::plot_pp_text()
}
}
+void ProfileGraphicsView::plot_add_line(int sec, double val, QColor c, QPointF &from)
+{
+ QPointF to = QPointF(SCALEGC(sec, val));
+ QGraphicsLineItem *item = new QGraphicsLineItem(from.x(), from.y(), to.x(), to.y());
+ QPen pen(defaultPen);
+ pen.setColor(c);
+ item->setPen(pen);
+ scene()->addItem(item);
+ from = to;
+}
+
void ProfileGraphicsView::plot_pp_gas_profile()
{
int i;
@@ -435,17 +453,10 @@ void ProfileGraphicsView::plot_pp_gas_profile()
from = QPointF(SCALEGC(entry->sec, entry->pn2));
for (i = 1; i < pi->nr; i++) {
entry++;
- if (entry->pn2 < prefs.pp_graphs.pn2_threshold) {
- to = QPointF(SCALEGC(entry->sec, entry->pn2));
- QGraphicsLineItem *item = new QGraphicsLineItem(from.x(), from.y(), to.x(), to.y());
- QPen pen(defaultPen);
- pen.setColor(c);
- item->setPen(pen);
- scene()->addItem(item);
- from = to;
- } else {
+ if (entry->pn2 < prefs.pp_graphs.pn2_threshold)
+ plot_add_line(entry->sec, entry->pn2, c, from);
+ else
from = QPointF(SCALEGC(entry->sec, entry->pn2));
- }
}
c = profile_color[PN2_ALERT].first();
@@ -453,17 +464,10 @@ void ProfileGraphicsView::plot_pp_gas_profile()
from = QPointF(SCALEGC(entry->sec, entry->pn2));
for (i = 1; i < pi->nr; i++) {
entry++;
- if (entry->pn2 >= prefs.pp_graphs.pn2_threshold) {
- to = QPointF(SCALEGC(entry->sec, entry->pn2));
- QGraphicsLineItem *item = new QGraphicsLineItem(from.x(), from.y(), to.x(), to.y());
- QPen pen(defaultPen);
- pen.setColor(c);
- item->setPen(pen);
- scene()->addItem(item);
- from = to;
- } else {
+ if (entry->pn2 >= prefs.pp_graphs.pn2_threshold)
+ plot_add_line(entry->sec, entry->pn2, c, from);
+ else
from = QPointF(SCALEGC(entry->sec, entry->pn2));
- }
}
}
@@ -474,17 +478,10 @@ void ProfileGraphicsView::plot_pp_gas_profile()
from = QPointF(SCALEGC(entry->sec, entry->phe));
for (i = 1; i < pi->nr; i++) {
entry++;
- if (entry->phe < prefs.pp_graphs.phe_threshold) {
- to = QPointF(SCALEGC(entry->sec, entry->phe));
- QGraphicsLineItem *item = new QGraphicsLineItem(from.x(), from.y(), to.x(), to.y());
- QPen pen(defaultPen);
- pen.setColor(c);
- item->setPen(pen);
- scene()->addItem(item);
- from = to;
- } else {
+ if (entry->phe < prefs.pp_graphs.phe_threshold)
+ plot_add_line(entry->sec, entry->phe, c, from);
+ else
from = QPointF(SCALEGC(entry->sec, entry->phe));
- }
}
c = profile_color[PHE_ALERT].first();
@@ -492,17 +489,10 @@ void ProfileGraphicsView::plot_pp_gas_profile()
from = QPointF(SCALEGC(entry->sec, entry->phe));
for (i = 1; i < pi->nr; i++) {
entry++;
- if (entry->phe >= prefs.pp_graphs.phe_threshold) {
- to = QPointF(SCALEGC(entry->sec, entry->phe));
- QGraphicsLineItem *item = new QGraphicsLineItem(from.x(), from.y(), to.x(), to.y());
- QPen pen(defaultPen);
- pen.setColor(c);
- item->setPen(pen);
- scene()->addItem(item);
- from = to;
- } else {
+ if (entry->phe >= prefs.pp_graphs.phe_threshold)
+ plot_add_line(entry->sec, entry->phe, c, from);
+ else
from = QPointF(SCALEGC(entry->sec, entry->phe));
- }
}
}
if (prefs.pp_graphs.po2) {
@@ -511,17 +501,10 @@ void ProfileGraphicsView::plot_pp_gas_profile()
from = QPointF(SCALEGC(entry->sec, entry->po2));
for (i = 1; i < pi->nr; i++) {
entry++;
- if (entry->po2 < prefs.pp_graphs.po2_threshold) {
- to = QPointF(SCALEGC(entry->sec, entry->po2));
- QGraphicsLineItem *item = new QGraphicsLineItem(from.x(), from.y(), to.x(), to.y());
- QPen pen(defaultPen);
- pen.setColor(c);
- item->setPen(pen);
- scene()->addItem(item);
- from = to;
- } else {
+ if (entry->po2 < prefs.pp_graphs.po2_threshold)
+ plot_add_line(entry->sec, entry->po2, c, from);
+ else
from = QPointF(SCALEGC(entry->sec, entry->po2));
- }
}
c = profile_color[PO2_ALERT].first();
@@ -529,15 +512,10 @@ void ProfileGraphicsView::plot_pp_gas_profile()
from = QPointF(SCALEGC(entry->sec, entry->po2));
for (i = 1; i < pi->nr; i++) {
entry++;
- if (entry->po2 >= prefs.pp_graphs.po2_threshold) {
- to = QPointF(SCALEGC(entry->sec, entry->po2));
- QGraphicsLineItem *item = new QGraphicsLineItem(from.x(), from.y(), to.x(), to.y());
- item->setPen(QPen(c));
- scene()->addItem(item);
- from = to;
- } else {
+ if (entry->po2 >= prefs.pp_graphs.po2_threshold)
+ plot_add_line(entry->sec, entry->po2, c, from);
+ else
from = QPointF(SCALEGC(entry->sec, entry->po2));
- }
}
}
}
@@ -720,7 +698,7 @@ void ProfileGraphicsView::plot_single_temp_text(int sec, int mkelvin)
plot_text(&tro, QPointF(sec, mkelvin), QString("%1%2").arg(deg, 0, 'f', 1).arg(unit)); //"%.2g%s"
}
-void ProfileGraphicsView::plot_cylinder_pressure(struct dive *dive, struct divecomputer *dc)
+void ProfileGraphicsView::plot_cylinder_pressure(struct divecomputer *dc)
{
int i;
int last = -1, last_index = -1;
@@ -1213,6 +1191,12 @@ void ProfileGraphicsView::plot_temperature_profile()
}
}
+void ProfileGraphicsView::edit_dive_time(const QString& time)
+{
+ // this should set the full time of the dive.
+ refresh();
+}
+
void ToolTipItem::addToolTip(const QString& toolTip, const QIcon& icon)
{
QGraphicsPixmapItem *iconItem = 0;
@@ -1324,6 +1308,9 @@ void ToolTipItem::collapse()
animation->setStartValue(boundingRect());
animation->setEndValue(QRect(0, 0, ICON_SMALL, ICON_SMALL));
animation->start(QAbstractAnimation::DeleteWhenStopped);
+ clear();
+
+ status = COLLAPSED;
}
void ToolTipItem::expand()
@@ -1358,20 +1345,26 @@ void ToolTipItem::expand()
animation->setEndValue(nextRectangle);
animation->start(QAbstractAnimation::DeleteWhenStopped);
+ status = EXPANDED;
}
ToolTipItem::ToolTipItem(QGraphicsItem* parent): QGraphicsPathItem(parent), background(0)
{
title = new QGraphicsSimpleTextItem(tr("Information"), this);
separator = new QGraphicsLineItem(this);
-
+ dragging = false;
setFlag(ItemIgnoresTransformations);
- setFlag(ItemIsMovable);
-
+ status = COLLAPSED;
updateTitlePosition();
setZValue(99);
}
+ToolTipItem::~ToolTipItem()
+{
+ clear();
+}
+
+
void ToolTipItem::updateTitlePosition()
{
if (rectangle.width() < title->boundingRect().width() + SPACING*4) {
@@ -1401,6 +1394,51 @@ void ToolTipItem::updateTitlePosition()
}
}
+bool ToolTipItem::isExpanded() {
+ return status == EXPANDED;
+}
+
+void ToolTipItem::mouseReleaseEvent(QGraphicsSceneMouseEvent* event)
+{
+ persistPos();
+ dragging = false;
+}
+
+void ToolTipItem::mousePressEvent(QGraphicsSceneMouseEvent* event)
+{
+ dragging = true;
+}
+
+void ToolTipItem::persistPos()
+{
+ QPoint currentPos = scene()->views().at(0)->mapFromScene(pos());
+ QSettings s;
+ s.beginGroup("ProfileMap");
+ s.setValue("tooltip_position", currentPos);
+ s.endGroup();
+ s.sync();
+}
+
+void ToolTipItem::readPos()
+{
+ QSettings s;
+ s.beginGroup("ProfileMap");
+ QPointF value = scene()->views().at(0)->mapToScene(
+ s.value("tooltip_position").toPoint()
+ );
+ setPos(value);
+}
+
+bool ToolTipItem::eventFilter(QObject* view, QEvent* event)
+{
+ if (event->type() == QEvent::HoverMove && dragging){
+ QHoverEvent *e = static_cast<QHoverEvent*>(event);
+ QGraphicsView *v = scene()->views().at(0);
+ setPos( v->mapToScene(e->pos()));
+ }
+ return false;
+}
+
EventItem::EventItem(QGraphicsItem* parent): QGraphicsPolygonItem(parent)
{
setFlag(ItemIgnoresTransformations);
@@ -1431,5 +1469,27 @@ EventItem::EventItem(QGraphicsItem* parent): QGraphicsPolygonItem(parent)
QGraphicsEllipseItem *ball = new QGraphicsEllipseItem(-1, 12, 2,2, this);
ball->setBrush(QBrush(Qt::black));
+}
+GraphicsTextEditor::GraphicsTextEditor(QGraphicsItem* parent): QGraphicsTextItem(parent)
+{
+}
+
+void GraphicsTextEditor::mouseDoubleClickEvent(QGraphicsSceneMouseEvent* event)
+{
+ // Remove the proxy filter so we can focus here.
+ mainWindow()->graphics()->setFocusProxy(0);
+ setTextInteractionFlags(Qt::TextEditorInteraction | Qt::TextEditable);
+}
+
+void GraphicsTextEditor::keyReleaseEvent(QKeyEvent* event)
+{
+ if (event->key() == Qt::Key_Enter || event->key() == Qt::Key_Return){
+ setTextInteractionFlags(Qt::NoTextInteraction);
+ emit editingFinished( toPlainText() );
+ mainWindow()->graphics()->setFocusProxy(mainWindow()->dive_list());
+ return;
+ }
+ emit textChanged( toPlainText() );
+ QGraphicsTextItem::keyReleaseEvent(event);
}