diff options
Diffstat (limited to 'qt-ui/diveplanner.cpp')
-rw-r--r-- | qt-ui/diveplanner.cpp | 138 |
1 files changed, 117 insertions, 21 deletions
diff --git a/qt-ui/diveplanner.cpp b/qt-ui/diveplanner.cpp index 7831cc6d9..c82bc0463 100644 --- a/qt-ui/diveplanner.cpp +++ b/qt-ui/diveplanner.cpp @@ -3,6 +3,8 @@ #include "mainwindow.h" #include "planner.h" #include "helpers.h" +#include "models.h" +#include "profile/profilewidget2.h" #include <QGraphicsSceneMouseEvent> #include <QMessageBox> @@ -42,15 +44,6 @@ void DivePlannerPointsModel::removeSelectedPoints(const QVector<int> &rows) QVector<int> v2 = rows; std::sort(v2.begin(), v2.end(), intLessThan); - /* - * If we end up having divepoints that are not within the dive - * profile, we need to just skip the removal to prevent - * crashing due to index out of range. - */ - - if (rowCount() >= divepoints.count()) - return; - beginRemoveRows(QModelIndex(), firstRow, rowCount() - 1); for (int i = v2.count() - 1; i >= 0; i--) { divepoints.remove(v2[i]); @@ -74,7 +67,7 @@ void DivePlannerPointsModel::createSimpleDive() if (!prefs.drop_stone_mode) plannerModel->addStop(M_OR_FT(15, 45), 1 * 60, &gas, 0, true); - plannerModel->addStop(M_OR_FT(15, 45), 40 * 60, &gas, 0, true); + plannerModel->addStop(M_OR_FT(15, 45), 20 * 60, &gas, 0, true); if (!isPlanner()) { plannerModel->addStop(M_OR_FT(5, 15), 42 * 60, &gas, 0, true); plannerModel->addStop(M_OR_FT(5, 15), 45 * 60, &gas, 0, true); @@ -99,10 +92,13 @@ void DivePlannerPointsModel::setupStartTime() void DivePlannerPointsModel::loadFromDive(dive *d) { + int depthsum = 0; + int samplecount = 0; bool oldRec = recalc; recalc = false; CylindersModel::instance()->updateDive(); duration_t lasttime = {}; + duration_t newtime = {}; struct gasmix gas; free_dps(&diveplan); diveplan.when = d->when; @@ -111,13 +107,27 @@ void DivePlannerPointsModel::loadFromDive(dive *d) // if it is we only add the manually entered samples as waypoints to the diveplan // otherwise we have to add all of them bool hasMarkedSamples = d->dc.sample[0].manually_entered; - for (int i = 0; i < d->dc.samples - 1; i++) { - const sample &s = d->dc.sample[i]; - if (s.time.seconds == 0 || (hasMarkedSamples && !s.manually_entered)) - continue; - get_gas_at_time(d, &d->dc, lasttime, &gas); - plannerModel->addStop(s.depth.mm, s.time.seconds, &gas, 0, true); - lasttime = s.time; + // if this dive has more than 100 samples (so it is probably a logged dive), + // average samples so we end up with a total of 100 samples. + int plansamples = d->dc.samples <= 100 ? d->dc.samples : 100; + int j = 0; + for (int i = 0; i < plansamples - 1; i++) { + while (j * plansamples <= i * d->dc.samples) { + const sample &s = d->dc.sample[j]; + if (s.time.seconds != 0 && (!hasMarkedSamples || s.manually_entered)) { + depthsum += s.depth.mm; + ++samplecount; + newtime = s.time; + } + j++; + } + if (samplecount) { + get_gas_at_time(d, &d->dc, lasttime, &gas); + plannerModel->addStop(depthsum / samplecount, newtime.seconds, &gas, 0, true); + lasttime = newtime; + depthsum = 0; + samplecount = 0; + } } recalc = oldRec; emitDataChanged(); @@ -231,7 +241,7 @@ void DiveHandler::changeGas() { QAction *action = qobject_cast<QAction *>(sender()); QModelIndex index = plannerModel->index(parentIndex(), DivePlannerPointsModel::GAS); - plannerModel->setData(index, action->text()); + plannerModel->gaschange(index.sibling(index.row() + 1, index.column()), action->text()); } void DiveHandler::mouseMoveEvent(QGraphicsSceneMouseEvent *event) @@ -383,6 +393,15 @@ void PlannerSettingsWidget::decoSacChanged(const double decosac) plannerModel->setDecoSac(decosac); } +void PlannerSettingsWidget::disableDecoElements(bool value) +{ + ui.lastStop->setDisabled(value); + ui.backgasBreaks->setDisabled(value); + ui.bottompo2->setDisabled(value); + ui.decopo2->setDisabled(value); + ui.reserve_gas->setDisabled(!value); +} + void DivePlannerWidget::printDecoPlan() { MainWindow::instance()->printPlan(); @@ -395,6 +414,14 @@ PlannerSettingsWidget::PlannerSettingsWidget(QWidget *parent, Qt::WindowFlags f) QSettings s; QStringList rebreater_modes; s.beginGroup("Planner"); + prefs.last_stop = s.value("last_stop", prefs.last_stop).toBool(); + prefs.verbatim_plan = s.value("verbatim_plan", prefs.verbatim_plan).toBool(); + prefs.display_duration = s.value("display_duration", prefs.display_duration).toBool(); + prefs.display_runtime = s.value("display_runtime", prefs.display_runtime).toBool(); + prefs.display_transitions = s.value("display_transitions", prefs.display_transitions).toBool(); + prefs.recreational_mode = s.value("recreational_mode", prefs.recreational_mode).toBool(); + prefs.safetystop = s.value("safetystop", prefs.safetystop).toBool(); + prefs.reserve_gas = s.value("reserve_gas", prefs.reserve_gas).toInt(); prefs.ascrate75 = s.value("ascrate75", prefs.ascrate75).toInt(); prefs.ascrate50 = s.value("ascrate50", prefs.ascrate50).toInt(); prefs.ascratestops = s.value("ascratestops", prefs.ascratestops).toInt(); @@ -411,6 +438,14 @@ PlannerSettingsWidget::PlannerSettingsWidget(QWidget *parent, Qt::WindowFlags f) s.endGroup(); updateUnitsUI(); + ui.lastStop->setChecked(prefs.last_stop); + ui.verbatim_plan->setChecked(prefs.verbatim_plan); + ui.display_duration->setChecked(prefs.display_duration); + ui.display_runtime->setChecked(prefs.display_runtime); + ui.display_transitions->setChecked(prefs.display_transitions); + ui.recreational_mode->setChecked(prefs.recreational_mode); + ui.safetystop->setChecked(prefs.safetystop); + ui.reserve_gas->setValue(prefs.reserve_gas / 1000); ui.bottompo2->setValue(prefs.bottompo2 / 1000.0); ui.decopo2->setValue(prefs.decopo2 / 1000.0); ui.backgasBreaks->setChecked(prefs.doo2breaks); @@ -424,6 +459,9 @@ PlannerSettingsWidget::PlannerSettingsWidget(QWidget *parent, Qt::WindowFlags f) connect(ui.display_duration, SIGNAL(toggled(bool)), plannerModel, SLOT(setDisplayDuration(bool))); connect(ui.display_runtime, SIGNAL(toggled(bool)), plannerModel, SLOT(setDisplayRuntime(bool))); connect(ui.display_transitions, SIGNAL(toggled(bool)), plannerModel, SLOT(setDisplayTransitions(bool))); + connect(ui.safetystop, SIGNAL(toggled(bool)), plannerModel, SLOT(setSafetyStop(bool))); + connect(ui.recreational_mode, SIGNAL(toggled(bool)), plannerModel, SLOT(setRecreationalMode(bool))); + connect(ui.reserve_gas, SIGNAL(valueChanged(int)), plannerModel, SLOT(setReserveGas(int))); connect(ui.ascRate75, SIGNAL(valueChanged(int)), this, SLOT(setAscRate75(int))); connect(ui.ascRate75, SIGNAL(valueChanged(int)), plannerModel, SLOT(emitDataChanged())); connect(ui.ascRate50, SIGNAL(valueChanged(int)), this, SLOT(setAscRate50(int))); @@ -445,6 +483,8 @@ PlannerSettingsWidget::PlannerSettingsWidget(QWidget *parent, Qt::WindowFlags f) connect(ui.gflow, SIGNAL(editingFinished()), plannerModel, SLOT(triggerGFLow())); connect(ui.backgasBreaks, SIGNAL(toggled(bool)), this, SLOT(setBackgasBreaks(bool))); connect(ui.rebreathermode, SIGNAL(currentIndexChanged(int)), plannerModel, SLOT(setRebreatherMode(int))); + connect(DivePlannerPointsModel::instance(), SIGNAL(recreationChanged(bool)), this, SLOT(disableDecoElements(bool))); + settingsChanged(); ui.gflow->setValue(prefs.gflow); ui.gfhigh->setValue(prefs.gfhigh); @@ -466,6 +506,14 @@ PlannerSettingsWidget::~PlannerSettingsWidget() { QSettings s; s.beginGroup("Planner"); + s.setValue("last_stop", prefs.last_stop); + s.setValue("verbatim_plan", prefs.verbatim_plan); + s.setValue("display_duration", prefs.display_duration); + s.setValue("display_runtime", prefs.display_runtime); + s.setValue("display_transitions", prefs.display_transitions); + s.setValue("recreational_mode", prefs.recreational_mode); + s.setValue("safetystop", prefs.safetystop); + s.setValue("reserve_gas", prefs.reserve_gas); s.setValue("ascrate75", prefs.ascrate75); s.setValue("ascrate50", prefs.ascrate50); s.setValue("ascratestops", prefs.ascratestops); @@ -693,6 +741,18 @@ bool DivePlannerPointsModel::setData(const QModelIndex &index, const QVariant &v return QAbstractItemModel::setData(index, value, role); } +void DivePlannerPointsModel::gaschange(const QModelIndex &index, QString newgas) +{ + int i = index.row(); + gasmix oldgas = divepoints[i].gasmix; + gasmix gas = { 0 }; + if (!validate_gas(newgas.toUtf8().data(), &gas)) + return; + while (i < plannerModel->rowCount() && gasmix_distance(&oldgas, &divepoints[i].gasmix) == 0) + divepoints[i++].gasmix = gas; + emit dataChanged(createIndex(0, 0), createIndex(rowCount() - 1, COLUMNS - 1)); +} + QVariant DivePlannerPointsModel::headerData(int section, Qt::Orientation orientation, int role) const { if (role == Qt::DisplayRole && orientation == Qt::Horizontal) { @@ -729,6 +789,7 @@ int DivePlannerPointsModel::rowCount(const QModelIndex &parent) const DivePlannerPointsModel::DivePlannerPointsModel(QObject *parent) : QAbstractTableModel(parent), mode(NOTHING), + recalc(false), tempGFHigh(100), tempGFLow(100) { @@ -820,30 +881,54 @@ int DivePlannerPointsModel::getSurfacePressure() void DivePlannerPointsModel::setLastStop6m(bool value) { set_last_stop(value); + prefs.last_stop = value; emit dataChanged(createIndex(0, 0), createIndex(rowCount() - 1, COLUMNS - 1)); } void DivePlannerPointsModel::setVerbatim(bool value) { set_verbatim(value); + prefs.verbatim_plan = value; emit dataChanged(createIndex(0, 0), createIndex(rowCount() - 1, COLUMNS - 1)); } void DivePlannerPointsModel::setDisplayRuntime(bool value) { set_display_runtime(value); + prefs.display_runtime = value; emit dataChanged(createIndex(0, 0), createIndex(rowCount() - 1, COLUMNS - 1)); } void DivePlannerPointsModel::setDisplayDuration(bool value) { set_display_duration(value); + prefs.display_duration = value; emit dataChanged(createIndex(0, 0), createIndex(rowCount() - 1, COLUMNS - 1)); } void DivePlannerPointsModel::setDisplayTransitions(bool value) { set_display_transitions(value); + prefs.display_transitions = value; + emit dataChanged(createIndex(0, 0), createIndex(rowCount() - 1, COLUMNS - 1)); +} + +void DivePlannerPointsModel::setRecreationalMode(bool value) +{ + prefs.recreational_mode = value; + emit recreationChanged(value); + emit dataChanged(createIndex(0, 0), createIndex(rowCount() - 1, COLUMNS -1)); +} + +void DivePlannerPointsModel::setSafetyStop(bool value) +{ + prefs.safetystop = value; + emit dataChanged(createIndex(0, 0), createIndex(rowCount() - 1, COLUMNS -1)); +} + +void DivePlannerPointsModel::setReserveGas(int reserve) +{ + prefs.reserve_gas = reserve * 1000; emit dataChanged(createIndex(0, 0), createIndex(rowCount() - 1, COLUMNS - 1)); } @@ -1110,7 +1195,7 @@ bool DivePlannerPointsModel::tankInUse(struct gasmix gasmix) continue; if (!p.entered) // removing deco gases is ok continue; - if (gasmix_distance(&p.gasmix, &gasmix) < 200) + if (gasmix_distance(&p.gasmix, &gasmix) < 100) return true; } return false; @@ -1137,7 +1222,7 @@ void DivePlannerPointsModel::tanksUpdated() struct gasmix gas; gas.o2.permille = oldGases.at(i).first; gas.he.permille = oldGases.at(i).second; - if (gasmix_distance(&gas, &p.gasmix) < 200) { + if (gasmix_distance(&gas, &p.gasmix) < 100) { p.gasmix.o2.permille = gases.at(i).first; p.gasmix.he.permille = gases.at(i).second; } @@ -1237,7 +1322,7 @@ void DivePlannerPointsModel::createPlan(bool replanCopy) plannerModel->setRecalc(oldRecalc); //TODO: C-based function here? - plan(&diveplan, &cache, isPlanner(), true); + bool did_deco = plan(&diveplan, &cache, isPlanner(), true); if (!current_dive || displayed_dive.id != current_dive->id) { // we were planning a new dive, not re-planning an existing on record_dive(clone_dive(&displayed_dive)); @@ -1255,6 +1340,12 @@ void DivePlannerPointsModel::createPlan(bool replanCopy) if (current_dive->divetrip) add_dive_to_trip(copy, current_dive->divetrip); record_dive(copy); + QString oldnotes(current_dive->notes); + if (oldnotes.indexOf(QString(disclaimer)) >= 0) + oldnotes.truncate(oldnotes.indexOf(QString(disclaimer))); + if (did_deco) + oldnotes.append(displayed_dive.notes); + displayed_dive.notes = strdup(oldnotes.toUtf8().data()); } copy_dive(&displayed_dive, current_dive); } @@ -1266,3 +1357,8 @@ void DivePlannerPointsModel::createPlan(bool replanCopy) setPlanMode(NOTHING); planCreated(); } + +PlannerDetails::PlannerDetails(QWidget *parent) : QWidget(parent) +{ + ui.setupUi(this); +} |