diff options
Diffstat (limited to 'qt-ui/profilegraphics.cpp')
-rw-r--r-- | qt-ui/profilegraphics.cpp | 268 |
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); } |