diff options
Diffstat (limited to 'qt-ui/diveplanner.cpp')
-rw-r--r-- | qt-ui/diveplanner.cpp | 505 |
1 files changed, 394 insertions, 111 deletions
diff --git a/qt-ui/diveplanner.cpp b/qt-ui/diveplanner.cpp index 39d3b20a8..e7c1b1962 100644 --- a/qt-ui/diveplanner.cpp +++ b/qt-ui/diveplanner.cpp @@ -1,34 +1,45 @@ #include "diveplanner.h" #include "graphicsview-common.h" +#include "models.h" +#include "modeldelegates.h" +#include "ui_diveplanner.h" +#include "mainwindow.h" #include "../dive.h" #include "../divelist.h" -#include <cmath> +#include "../planner.h" + #include <QMouseEvent> #include <QDebug> -#include <QGraphicsWidget> -#include <QGraphicsProxyWidget> -#include <QPushButton> #include <QGraphicsSceneMouseEvent> #include <QMessageBox> #include <QStringListModel> -#include <QGraphicsProxyWidget> #include <QListView> -#include <QDesktopWidget> #include <QModelIndex> - -#include "ui_diveplanner.h" -#include "mainwindow.h" +#include <QSettings> #define TIME_INITIAL_MAX 30 #define MAX_DEEPNESS 150 #define MIN_DEEPNESS 40 -bool handlerLessThenMinutes(DiveHandler *d1, DiveHandler *d2){ - return d1->sec < d2->sec; +QStringListModel *airTypes(){ + static QStringListModel *self = new QStringListModel(QStringList() + << QObject::tr("AIR") + << QObject::tr("EAN32") + << QObject::tr("EAN36")); + return self; } +QString strForAir(const divedatapoint& p){ + return p.o2 == 209 ? QObject::tr("AIR") + : p.o2 == 320 ? QObject::tr("EAN32") + : p.o2 == 360 ? QObject::tr("EAN36") + : QObject::tr("Choose Gas"); +} + +static DivePlannerPointsModel *plannerModel = DivePlannerPointsModel::instance(); + DivePlannerGraphics::DivePlannerGraphics(QWidget* parent): QGraphicsView(parent), activeDraggedHandler(0) { fill_profile_color(); @@ -111,16 +122,10 @@ DivePlannerGraphics::DivePlannerGraphics(QWidget* parent): QGraphicsView(parent) connect(obj, SIGNAL(clicked()), this, SLOT(slot)); ADDBTN(plusDepth, ":plus", "" , 5, 5, tr("Increase maximum depth by 10m"), increaseDepth()); - ADDBTN(plusTime, ":plus", "" , 95, 5, tr("Increase minimum time by 10m"), increaseTime()); + ADDBTN(plusTime, ":plus", "" , 95, 95, tr("Increase minimum time by 10m"), increaseTime()); ADDBTN(lessDepth, ":minimum","" , 2, 5, tr("Decreases maximum depth by 10m"), decreaseDepth()); ADDBTN(lessTime, ":minimum","" , 92, 95, tr("Decreases minimum time by 10m"), decreaseTime()); - ADDBTN(okBtn, "", tr("Ok"), 1, 95, "", okClicked()); - ADDBTN(cancelBtn, "", tr("Cancel"), 0,0, "", cancelClicked()); #undef ADDBTN - - cancelBtn->setPos(okBtn->pos().x() + okBtn->boundingRect().width() - + fromPercent(2, Qt::Horizontal), fromPercent(95, Qt::Vertical)); - minMinutes = TIME_INITIAL_MAX; QAction *action = NULL; @@ -141,31 +146,50 @@ DivePlannerGraphics::DivePlannerGraphics(QWidget* parent): QGraphicsView(parent) #undef ADD_ACTION // Prepare the stuff for the gas-choices. - gasChoices = new QStringListModel(QStringList() << tr("AIR") << tr("EAN32") << tr("EAN36")); - gasListView = new QListView(this); - gasListView->setWindowFlags(Qt::FramelessWindowHint | Qt::Popup); - gasListView->setModel(gasChoices); - gasListView->setWindowModality(Qt::WindowModal); + gasListView = new QListView(); + gasListView->setWindowFlags(Qt::Popup); + gasListView->setModel(airTypes()); gasListView->hide(); connect(gasListView, SIGNAL(activated(QModelIndex)), this, SLOT(selectGas(QModelIndex))); + connect(plannerModel, SIGNAL(dataChanged(QModelIndex,QModelIndex)), this, SLOT(createDecoStops())); + + 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))); setRenderHint(QPainter::Antialiasing); } +void DivePlannerGraphics::pointInserted(const QModelIndex& parent, int start , int end) +{ + DiveHandler *item = new DiveHandler (); + scene()->addItem(item); + handles << item; + + Button *gasChooseBtn = new Button(); + scene()->addItem(gasChooseBtn); + gasChooseBtn->setZValue(10); + connect(gasChooseBtn, SIGNAL(clicked()), this, SLOT(prepareSelectGas())); + + gases << gasChooseBtn; + createDecoStops(); +} + void DivePlannerGraphics::keyDownAction() { if(scene()->selectedItems().count()){ Q_FOREACH(QGraphicsItem *i, scene()->selectedItems()){ if (DiveHandler *handler = qgraphicsitem_cast<DiveHandler*>(i)){ - if (handler->mm / 1000 >= depthLine->maximum()) + int row = handles.indexOf(handler); + divedatapoint dp = plannerModel->at(row); + if (dp.depth / 1000 >= depthLine->maximum()) continue; - handler->mm += 1000; - double ypos = depthLine->posAtValue(handler->mm / 1000); - handler->setPos(handler->pos().x(), ypos); + dp.depth += 1000; + plannerModel->editStop(row, dp); } } - createDecoStops(); } } @@ -173,12 +197,14 @@ void DivePlannerGraphics::keyUpAction() { Q_FOREACH(QGraphicsItem *i, scene()->selectedItems()){ if (DiveHandler *handler = qgraphicsitem_cast<DiveHandler*>(i)){ - if (handler->mm / 1000 <= 0) + int row = handles.indexOf(handler); + divedatapoint dp = plannerModel->at(row); + + if (dp.depth / 1000 <= 0) continue; - handler->mm -= 1000; - double ypos = depthLine->posAtValue(handler->mm / 1000); - handler->setPos(handler->pos().x(), ypos); + dp.depth -= 1000; + plannerModel->editStop(row, dp); } } createDecoStops(); @@ -188,12 +214,15 @@ void DivePlannerGraphics::keyLeftAction() { Q_FOREACH(QGraphicsItem *i, scene()->selectedItems()){ if (DiveHandler *handler = qgraphicsitem_cast<DiveHandler*>(i)){ - if (handler->sec / 60 <= 0) + 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 = timeLine->posAtValue((handler->sec - 60) / 60); + double xpos = timeLine->posAtValue((dp.time - 60) / 60); bool nextStep = false; Q_FOREACH(DiveHandler *h, handles){ if (h->pos().x() == xpos){ @@ -204,23 +233,24 @@ void DivePlannerGraphics::keyLeftAction() if(nextStep) continue; - handler->sec -= 60; - handler->setPos(xpos, handler->pos().y()); + dp.time -= 60; + plannerModel->editStop(row, dp); } } - createDecoStops(); } void DivePlannerGraphics::keyRightAction() { Q_FOREACH(QGraphicsItem *i, scene()->selectedItems()){ if (DiveHandler *handler = qgraphicsitem_cast<DiveHandler*>(i)){ - if (handler->sec / 60 >= timeLine->maximum()) + int row = handles.indexOf(handler); + divedatapoint dp = plannerModel->at(row); + if (dp.time / 60 >= timeLine->maximum()) continue; // don't overlap positions. // maybe this is a good place for a 'goto'? - double xpos = timeLine->posAtValue((handler->sec + 60) / 60); + double xpos = timeLine->posAtValue((dp.time + 60) / 60); bool nextStep = false; Q_FOREACH(DiveHandler *h, handles){ if (h->pos().x() == xpos){ @@ -231,32 +261,52 @@ void DivePlannerGraphics::keyRightAction() if(nextStep) continue; - handler->sec += 60; - handler->setPos(xpos, handler->pos().y()); + dp.time += 60; + plannerModel->editStop(row, dp); } - } createDecoStops(); + } } void DivePlannerGraphics::keyDeleteAction() { int selCount = scene()->selectedItems().count(); if(selCount){ - - while(selCount--){ - Button *btn = gases.takeLast(); - delete btn; - } - + QVector<int> selectedIndexes; Q_FOREACH(QGraphicsItem *i, scene()->selectedItems()){ if (DiveHandler *handler = qgraphicsitem_cast<DiveHandler*>(i)){ - handles.removeAll(handler); - scene()->removeItem(handler); - delete i; + selectedIndexes.push_back(handles.indexOf(handler)); } } + plannerModel->removeSelectedPoints(selectedIndexes); + } +} - createDecoStops(); +void DivePlannerGraphics::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(); + createDecoStops(); +} + +bool intLessThan(int a, int b){ + return a <= b; +} +void DivePlannerPointsModel::removeSelectedPoints(const QVector< int >& rows) +{ + int firstRow = rowCount() - rows.count(); + QVector<int> v2 = rows; + std::sort(v2.begin(), v2.end(), intLessThan); + beginRemoveRows(QModelIndex(), firstRow, rowCount()-1); + for(int i = v2.count()-1; i >= 0; i--){ + divepoints.remove(v2[i]); + } + endRemoveRows(); } void DivePlannerGraphics::keyEscAction() @@ -265,8 +315,7 @@ void DivePlannerGraphics::keyEscAction() scene()->clearSelection(); return; } - - cancelClicked(); + cancelPlan(); } qreal DivePlannerGraphics::fromPercent(qreal percent, Qt::Orientation orientation) @@ -276,7 +325,7 @@ qreal DivePlannerGraphics::fromPercent(qreal percent, Qt::Orientation orientatio return result; } -void DivePlannerGraphics::cancelClicked() +void DivePlannerGraphics::cancelPlan() { if (handles.size()){ if (QMessageBox::warning(mainWindow(), tr("Save the Plan?"), @@ -288,11 +337,6 @@ void DivePlannerGraphics::cancelClicked() mainWindow()->showProfile(); } -void DivePlannerGraphics::okClicked() -{ - // todo. -} - void DivePlannerGraphics::increaseDepth() { if (depthLine->maximum() + 10 > MAX_DEEPNESS) @@ -324,7 +368,6 @@ void DivePlannerGraphics::decreaseDepth() return; } } - depthLine->setMaximum(depthLine->maximum() - 10); depthLine->updateTicks(); createDecoStops(); @@ -353,31 +396,7 @@ void DivePlannerGraphics::mouseDoubleClickEvent(QMouseEvent* event) int minutes = rint(timeLine->valueAt(mappedPos)); int meters = rint(depthLine->valueAt(mappedPos)); - double xpos = timeLine->posAtValue(minutes); - double ypos = depthLine->posAtValue(meters); - Q_FOREACH(DiveHandler* handler, handles){ - if (xpos == handler->pos().x()){ - qDebug() << "There's already an point at that place."; - //TODO: Move this later to a KMessageWidget. - return; - } - } - - DiveHandler *item = new DiveHandler (); - item->sec = minutes * 60; - item->mm = meters * 1000; - item->setPos(QPointF(xpos, ypos)); - scene()->addItem(item); - handles << item; - - Button *gasChooseBtn = new Button(); - gasChooseBtn ->setText(tr("Air")); - scene()->addItem(gasChooseBtn); - gasChooseBtn->setZValue(10); - connect(gasChooseBtn, SIGNAL(clicked()), this, SLOT(prepareSelectGas())); - - gases << gasChooseBtn; - createDecoStops(); + plannerModel->addStop(meters * 1000, minutes * 60, tr("Air"), 0); } void DivePlannerGraphics::prepareSelectGas() @@ -391,16 +410,15 @@ void DivePlannerGraphics::prepareSelectGas() void DivePlannerGraphics::selectGas(const QModelIndex& index) { QString gasSelected = gasListView->model()->data(index, Qt::DisplayRole).toString(); - currentGasChoice->setText(gasSelected); + int idx = gases.indexOf(currentGasChoice); + plannerModel->setData(plannerModel->index(idx, DivePlannerPointsModel::GAS), gasSelected); gasListView->hide(); } - void DivePlannerGraphics::createDecoStops() { qDeleteAll(lines); lines.clear(); - qSort(handles.begin(), handles.end(), handlerLessThenMinutes); // This needs to be done in the following steps: // Get the user-input and calculate the dive info @@ -413,18 +431,16 @@ void DivePlannerGraphics::createDecoStops() diveplan.gflow = 30; diveplan.gfhigh = 70; diveplan.surface_pressure = 1013; - DiveHandler *lastH = NULL; - Q_FOREACH(DiveHandler *h, handles) { - // these values need to come from the planner UI, eventually - int o2 = 209; - int he = 0; - int po2 = 0; - int deltaT = lastH ? h->sec - lastH->sec : h->sec; - lastH = h; - dp = plan_add_segment(&diveplan, deltaT, h->mm, o2, he, po2); - dp->entered = TRUE; - qDebug("time %d, depth %d", h->sec, h->mm); + + int rowCount = plannerModel->rowCount(); + int lastIndex = -1; + for(int i = 0; i < rowCount; i++){ + divedatapoint p = plannerModel->at(i); + int deltaT = lastIndex != -1 ? p.time - plannerModel->at(lastIndex).time : p.time; + lastIndex = i; + dp = plan_add_segment(&diveplan, deltaT, p.depth, p.o2, p.he, p.po2); } + #if DEBUG_PLAN dump_plan(&diveplan); #endif @@ -449,19 +465,16 @@ void DivePlannerGraphics::createDecoStops() } // Re-position the user generated dive handlers - Q_FOREACH(DiveHandler *h, handles){ - h->setPos(timeLine->posAtValue(h->sec / 60), depthLine->posAtValue(h->mm / 1000)); - } - - int gasCount = gases.count(); - for(int i = 0; i < gasCount; i++){ + for(int i = 0; i < plannerModel->rowCount(); i++){ + divedatapoint dp = plannerModel->at(i); + DiveHandler *h = handles.at(i); + h->setPos(timeLine->posAtValue(dp.time / 60), depthLine->posAtValue(dp.depth / 1000)); QPointF p1 = (i == 0) ? QPointF(timeLine->posAtValue(0), depthLine->posAtValue(0)) : handles[i-1]->pos(); QPointF p2 = handles[i]->pos(); - QLineF line(p1, p2); QPointF pos = line.pointAt(0.5); gases[i]->setPos(pos); - qDebug() << "Adding a gas at" << pos; + gases[i]->setText( strForAir(dp)); } // (re-) create the profile with different colors for segments that were @@ -620,8 +633,14 @@ void DivePlannerGraphics::mouseReleaseEvent(QMouseEvent* event) } } - activeDraggedHandler->sec = rint(timeLine->valueAt(mappedPos)) * 60; - activeDraggedHandler->mm = rint(depthLine->valueAt(mappedPos)) * 1000; + int pos = handles.indexOf(activeDraggedHandler); + divedatapoint data = plannerModel->at(pos); + + data.depth = rint(depthLine->valueAt(mappedPos)) * 1000; + data.time = rint(timeLine->valueAt(mappedPos)) * 60; + + plannerModel->editStop(pos, data); + activeDraggedHandler->setBrush(QBrush(Qt::white)); activeDraggedHandler->setPos(QPointF(xpos, ypos)); @@ -646,6 +665,10 @@ void DiveHandler::mousePressEvent(QGraphicsSceneMouseEvent* event) } // mousePressEvent 'grabs' the mouse and keyboard, annoying. ungrabMouse(); + + /* hack. Sometimes the keyboard is grabbed, sometime it's not, + so, let's force a grab and release, to get rid of a warning. */ + grabKeyboard(); ungrabKeyboard(); } @@ -763,7 +786,7 @@ void Ruler::setColor(const QColor& color) Button::Button(QObject* parent): QObject(parent), QGraphicsRectItem() { - icon = new QGraphicsPixmapItem(this); + icon = new QGraphicsPixmapItem(this); text = new QGraphicsSimpleTextItem(this); icon->setPos(0,0); text->setPos(0,0); @@ -800,3 +823,263 @@ void Button::mousePressEvent(QGraphicsSceneMouseEvent* event) event->ignore(); emit clicked(); } + +DivePlannerWidget::DivePlannerWidget(QWidget* parent, Qt::WindowFlags f): QWidget(parent, f), ui(new Ui::DivePlanner()) +{ + ui->setupUi(this); + ui->tablePoints->setModel(DivePlannerPointsModel::instance()); + ui->tablePoints->setItemDelegateForColumn(DivePlannerPointsModel::GAS, new AirTypesDelegate(this)); + + connect(ui->tablePoints, SIGNAL(clicked(QModelIndex)), plannerModel, SLOT(removePoint(const QModelIndex))); + connect(ui->startTime, SIGNAL(timeChanged(QTime)), this, SLOT(startTimeChanged(QTime))); + connect(ui->ATMPressure, SIGNAL(textChanged(QString)), this, SLOT(atmPressureChanged(QString))); + connect(ui->bottomSAC, SIGNAL(textChanged(QString)), this, SLOT(bottomSacChanged(QString))); + connect(ui->decoStopSAC, SIGNAL(textChanged(QString)), this, SLOT(decoSacChanged(QString))); + connect(ui->highGF, SIGNAL(textChanged(QString)), this, SLOT(gfhighChanged(QString))); + connect(ui->lowGF, SIGNAL(textChanged(QString)), this, SLOT(gflowChanged(QString))); + connect(ui->highGF, SIGNAL(textChanged(QString)), this, SLOT(gfhighChanged(QString))); + connect(ui->lastStop, SIGNAL(toggled(bool)), this, SLOT(lastStopChanged(bool))); + + QFile cssFile(":table-css"); + cssFile.open(QIODevice::ReadOnly); + QTextStream reader(&cssFile); + QString css = reader.readAll(); + + ui->tablePoints->setStyleSheet(css); + QFontMetrics metrics(defaultModelFont()); + + ui->tablePoints->horizontalHeader()->setResizeMode(DivePlannerPointsModel::REMOVE, QHeaderView::Fixed); + ui->tablePoints->verticalHeader()->setDefaultSectionSize( metrics.height() +8 ); + initialUiSetup(); +} + +void DivePlannerWidget::hideEvent(QHideEvent* event) +{ + QSettings s; + s.beginGroup("DivePlanner"); + s.beginGroup("PointTables"); + for (int i = 0; i < CylindersModel::COLUMNS; i++) { + s.setValue(QString("colwidth%1").arg(i), ui->tablePoints->columnWidth(i)); + } + s.endGroup(); + s.sync(); +} + +void DivePlannerWidget::initialUiSetup() +{ + QSettings s; + s.beginGroup("DivePlanner"); + s.beginGroup("PointTables"); + for (int i = 0; i < CylindersModel::COLUMNS; i++) { + QVariant width = s.value(QString("colwidth%1").arg(i)); + if (width.isValid()) + ui->tablePoints->setColumnWidth(i, width.toInt()); + else + ui->tablePoints->resizeColumnToContents(i); + } + s.endGroup(); +} +void DivePlannerWidget::startTimeChanged(const QTime& time) +{ + plannerModel->setStartTime(time); +} + +void DivePlannerWidget::atmPressureChanged(const QString& pressure) +{ + plannerModel->setSurfacePressure(pressure.toInt()); +} + +void DivePlannerWidget::bottomSacChanged(const QString& bottomSac) +{ + plannerModel->setBottomSac(bottomSac.toInt()); +} + +void DivePlannerWidget::decoSacChanged(const QString& decosac) +{ + plannerModel->setDecoSac(decosac.toInt()); +} + +void DivePlannerWidget::gfhighChanged(const QString& gfhigh) +{ + plannerModel->setGFHigh(gfhigh.toShort()); +} + +void DivePlannerWidget::gflowChanged(const QString& gflow) +{ + plannerModel->setGFLow(gflow.toShort()); +} + +void DivePlannerWidget::lastStopChanged(bool checked) +{ + plannerModel->setLastStop6m(checked); +} + +int DivePlannerPointsModel::columnCount(const QModelIndex& parent) const +{ + return COLUMNS; +} + +QVariant DivePlannerPointsModel::data(const QModelIndex& index, int role) const +{ + if(role == Qt::DisplayRole){ + divedatapoint p = divepoints.at(index.row()); + switch(index.column()){ + case CCSETPOINT: return 0; + case DEPTH: return p.depth / 1000; + case DURATION: return p.time / 60; + case GAS: return strForAir(p); + } + } + if (role == Qt::DecorationRole){ + switch(index.column()){ + case REMOVE : return QIcon(":trash"); + } + } + return QVariant(); +} + +bool DivePlannerPointsModel::setData(const QModelIndex& index, const QVariant& value, int role) +{ + if(role == Qt::EditRole){ + divedatapoint& p = divepoints[index.row()]; + switch(index.column()){ + case DEPTH: p.depth = value.toInt() * 1000; break; + case DURATION: p.time = value.toInt() * 60; break; + case CCSETPOINT: /* what do I do here? */ + case GAS: { + int o2 = 0; + int he = 0; + QByteArray gasv = value.toByteArray(); + if (validate_gas(gasv.data(), &o2, &he)) { + p.o2 = o2; + p.he = he; + }break; + } + } + editStop(index.row(), p); + } + return QAbstractItemModel::setData(index, value, role); +} + +QVariant DivePlannerPointsModel::headerData(int section, Qt::Orientation orientation, int role) const +{ + if (role == Qt::DisplayRole && orientation == Qt::Horizontal){ + switch(section){ + case DEPTH: return tr("Final Depth"); + case DURATION: return tr("Duration"); + case GAS: return tr("Used Gas"); + case CCSETPOINT: return tr("CC Set Point"); + } + } + return QVariant(); +} + +Qt::ItemFlags DivePlannerPointsModel::flags(const QModelIndex& index) const +{ + return QAbstractItemModel::flags(index) | Qt::ItemIsEditable; +} + +int DivePlannerPointsModel::rowCount(const QModelIndex& parent) const +{ + return divepoints.count(); +} + +DivePlannerPointsModel::DivePlannerPointsModel(QObject* parent): QAbstractTableModel(parent) +{ +} + +DivePlannerPointsModel* DivePlannerPointsModel::instance() +{ + static DivePlannerPointsModel* self = new DivePlannerPointsModel(); + return self; +} + +void DivePlannerPointsModel::createPlan() +{ + +} + +void DivePlannerPointsModel::setBottomSac(int sac) +{ + diveplan.bottomsac = sac; +} + +void DivePlannerPointsModel::setDecoSac(int sac) +{ + diveplan.decosac = sac; +} + +void DivePlannerPointsModel::setGFHigh(short int gfhigh) +{ + diveplan.gfhigh = gfhigh; +} + +void DivePlannerPointsModel::setGFLow(short int ghflow) +{ + diveplan.gflow = ghflow; +} + +void DivePlannerPointsModel::setSurfacePressure(int pressure) +{ + diveplan.surface_pressure = pressure; +} + +void DivePlannerPointsModel::setLastStop6m(bool value) +{ +} + +void DivePlannerPointsModel::setStartTime(const QTime& t) +{ + diveplan.when = t.msec(); +} + +bool divePointsLessThan(const divedatapoint& p1, const divedatapoint& p2){ + return p1.time <= p2.time; +} +int DivePlannerPointsModel::addStop(int meters, int minutes, const QString& gas, int ccpoint) +{ + int row = divepoints.count(); + // check if there's already a new stop before this one: + for(int i = 0; i < divepoints.count(); i++){ + const divedatapoint& dp = divepoints.at(i); + if (dp.time > minutes ){ + row = i; + break; + } + } + + // add the new stop + beginInsertRows(QModelIndex(), row, row); + divedatapoint point; + point.depth = meters; + point.time = minutes; + point.o2 = 209; + point.he = 0; + point.po2 = 0; + divepoints.append( point ); + std::sort(divepoints.begin(), divepoints.end(), divePointsLessThan); + endInsertRows(); + return row; +} + +void DivePlannerPointsModel::editStop(int row, divedatapoint newData) +{ + divepoints[row] = newData; + std::sort(divepoints.begin(), divepoints.end(), divePointsLessThan); + emit dataChanged(createIndex(0, 0), createIndex(rowCount()-1, COLUMNS-1)); +} + +divedatapoint DivePlannerPointsModel::at(int row) +{ + return divepoints.at(row); +} + +void DivePlannerPointsModel::removePoint(const QModelIndex& index) +{ + if (index.column() != REMOVE) + return; + + beginRemoveRows(QModelIndex(), index.row(), index.row()); + divepoints.remove(index.row()); + endRemoveRows(); +} |