2017-04-27 18:26:05 +00:00
|
|
|
|
// SPDX-License-Identifier: GPL-2.0
|
2016-04-05 05:02:03 +00:00
|
|
|
|
#include "desktop-widgets/diveplanner.h"
|
|
|
|
|
#include "desktop-widgets/modeldelegates.h"
|
|
|
|
|
#include "desktop-widgets/mainwindow.h"
|
|
|
|
|
#include "core/planner.h"
|
2018-06-03 20:15:19 +00:00
|
|
|
|
#include "core/qthelper.h"
|
2019-05-15 16:39:29 +00:00
|
|
|
|
#include "core/units.h"
|
2022-04-04 16:57:28 +00:00
|
|
|
|
#include "core/selection.h"
|
2018-08-15 09:56:17 +00:00
|
|
|
|
#include "core/settings/qPrefDivePlanner.h"
|
2020-11-24 11:50:52 +00:00
|
|
|
|
#include "core/subsurface-qt/divelistnotifier.h"
|
2018-06-17 06:48:54 +00:00
|
|
|
|
#include "core/gettextfromc.h"
|
2019-12-14 22:12:26 +00:00
|
|
|
|
#include "backend-shared/plannershared.h"
|
2016-08-26 19:21:42 +00:00
|
|
|
|
|
2016-04-05 05:02:03 +00:00
|
|
|
|
#include "qt-models/cylindermodel.h"
|
|
|
|
|
#include "qt-models/models.h"
|
2021-08-04 05:27:41 +00:00
|
|
|
|
#include "profile-widget/profilescene.h"
|
2016-04-05 05:02:03 +00:00
|
|
|
|
#include "qt-models/diveplannermodel.h"
|
2013-08-30 10:14:30 +00:00
|
|
|
|
|
2014-06-03 22:26:06 +00:00
|
|
|
|
#include <QShortcut>
|
2020-11-25 06:31:19 +00:00
|
|
|
|
#ifndef NO_PRINTING
|
|
|
|
|
#include <QPrintDialog>
|
|
|
|
|
#include <QPrinter>
|
|
|
|
|
#include <QBuffer>
|
|
|
|
|
#endif
|
2013-06-20 15:33:26 +00:00
|
|
|
|
|
2024-04-25 20:16:08 +00:00
|
|
|
|
DivePlannerWidget::DivePlannerWidget(dive &planned_dive, int dcNr, PlannerWidgets *parent)
|
2013-10-03 18:54:25 +00:00
|
|
|
|
{
|
2020-02-03 17:37:56 +00:00
|
|
|
|
DivePlannerPointsModel *plannerModel = DivePlannerPointsModel::instance();
|
2020-02-03 17:59:12 +00:00
|
|
|
|
CylindersModel *cylinders = DivePlannerPointsModel::instance()->cylindersModel();
|
2020-02-03 17:52:17 +00:00
|
|
|
|
|
2013-10-03 18:54:25 +00:00
|
|
|
|
ui.setupUi(this);
|
2014-07-10 23:06:46 +00:00
|
|
|
|
ui.tableWidget->setTitle(tr("Dive planner points"));
|
2015-05-28 19:23:49 +00:00
|
|
|
|
ui.tableWidget->setModel(plannerModel);
|
2019-11-02 21:52:27 +00:00
|
|
|
|
connect(ui.tableWidget, &TableView::itemClicked, plannerModel, &DivePlannerPointsModel::remove);
|
2024-03-30 12:40:00 +00:00
|
|
|
|
ui.tableWidget->view()->setItemDelegateForColumn(DivePlannerPointsModel::GAS, new AirTypesDelegate(planned_dive, this));
|
|
|
|
|
ui.tableWidget->view()->setItemDelegateForColumn(DivePlannerPointsModel::DIVEMODE, new DiveTypesDelegate(this));
|
2014-07-10 23:06:46 +00:00
|
|
|
|
ui.cylinderTableWidget->setTitle(tr("Available gases"));
|
2017-03-11 10:42:50 +00:00
|
|
|
|
ui.cylinderTableWidget->setBtnToolTip(tr("Add cylinder"));
|
2020-02-03 17:52:17 +00:00
|
|
|
|
ui.cylinderTableWidget->setModel(cylinders);
|
2020-02-03 17:59:12 +00:00
|
|
|
|
connect(ui.cylinderTableWidget, &TableView::itemClicked, cylinders, &CylindersModel::remove);
|
2018-02-10 22:28:05 +00:00
|
|
|
|
ui.waterType->setItemData(0, FRESHWATER_SALINITY);
|
|
|
|
|
ui.waterType->setItemData(1, SEAWATER_SALINITY);
|
|
|
|
|
ui.waterType->setItemData(2, EN13319_SALINITY);
|
|
|
|
|
waterTypeUpdateTexts();
|
2019-01-10 20:18:53 +00:00
|
|
|
|
|
2013-11-12 19:57:33 +00:00
|
|
|
|
QTableView *view = ui.cylinderTableWidget->view();
|
|
|
|
|
view->setColumnHidden(CylindersModel::START, true);
|
|
|
|
|
view->setColumnHidden(CylindersModel::END, true);
|
2014-03-22 14:13:58 +00:00
|
|
|
|
view->setColumnHidden(CylindersModel::DEPTH, false);
|
2021-11-20 11:27:02 +00:00
|
|
|
|
view->setColumnHidden(CylindersModel::WORKINGPRESS_INT, true);
|
|
|
|
|
view->setColumnHidden(CylindersModel::SIZE_INT, true);
|
2022-02-19 17:47:25 +00:00
|
|
|
|
view->setColumnHidden(CylindersModel::SENSORS, true);
|
2014-01-15 17:52:42 +00:00
|
|
|
|
view->setItemDelegateForColumn(CylindersModel::TYPE, new TankInfoDelegate(this));
|
2022-09-17 14:55:44 +00:00
|
|
|
|
auto tankUseDelegate = new TankUseDelegate(this);
|
2024-06-30 18:38:12 +00:00
|
|
|
|
tankUseDelegate->setCurrentDC(planned_dive.get_dc(dcNr));
|
2022-09-17 14:55:44 +00:00
|
|
|
|
view->setItemDelegateForColumn(CylindersModel::USE, tankUseDelegate);
|
2020-01-06 10:28:57 +00:00
|
|
|
|
connect(ui.cylinderTableWidget, &TableView::addButtonClicked, plannerModel, &DivePlannerPointsModel::addCylinder_clicked);
|
2021-01-23 10:41:42 +00:00
|
|
|
|
connect(ui.tableWidget, &TableView::addButtonClicked, plannerModel, &DivePlannerPointsModel::addDefaultStop);
|
2020-02-03 17:59:12 +00:00
|
|
|
|
connect(cylinders, &CylindersModel::dataChanged, plannerModel, &DivePlannerPointsModel::emitDataChanged);
|
|
|
|
|
connect(cylinders, &CylindersModel::dataChanged, plannerModel, &DivePlannerPointsModel::cylinderModelEdited);
|
|
|
|
|
connect(cylinders, &CylindersModel::rowsInserted, plannerModel, &DivePlannerPointsModel::cylinderModelEdited);
|
|
|
|
|
connect(cylinders, &CylindersModel::rowsRemoved, plannerModel, &DivePlannerPointsModel::cylinderModelEdited);
|
2015-06-16 12:37:02 +00:00
|
|
|
|
|
2014-07-10 23:06:46 +00:00
|
|
|
|
ui.tableWidget->setBtnToolTip(tr("Add dive data point"));
|
2020-01-06 09:33:59 +00:00
|
|
|
|
connect(ui.startTime, &QDateEdit::timeChanged, plannerModel, &DivePlannerPointsModel::setStartTime);
|
|
|
|
|
connect(ui.dateEdit, &QDateEdit::dateChanged, plannerModel, &DivePlannerPointsModel::setStartDate);
|
2020-01-02 21:02:20 +00:00
|
|
|
|
connect(ui.ATMPressure, QOverload<int>::of(&QSpinBox::valueChanged), this, &DivePlannerWidget::atmPressureChanged);
|
|
|
|
|
connect(ui.atmHeight, QOverload<int>::of(&QSpinBox::valueChanged), this, &DivePlannerWidget::heightChanged);
|
2020-01-06 10:28:57 +00:00
|
|
|
|
connect(ui.waterType, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &DivePlannerWidget::waterTypeChanged);
|
2020-01-06 10:46:43 +00:00
|
|
|
|
connect(ui.customSalinity, QOverload<double>::of(&QDoubleSpinBox::valueChanged), this, &DivePlannerWidget::customSalinityChanged);
|
2013-09-09 10:18:22 +00:00
|
|
|
|
|
2014-05-27 22:27:53 +00:00
|
|
|
|
// Creating (and canceling) the plan
|
2014-11-10 22:41:18 +00:00
|
|
|
|
replanButton = ui.buttonBox->addButton(tr("Save new"), QDialogButtonBox::ActionRole);
|
2020-01-02 20:47:36 +00:00
|
|
|
|
connect(replanButton, &QAbstractButton::clicked, plannerModel, &DivePlannerPointsModel::saveDuplicatePlan);
|
|
|
|
|
connect(ui.buttonBox, &QDialogButtonBox::accepted, plannerModel, &DivePlannerPointsModel::savePlan);
|
|
|
|
|
connect(ui.buttonBox, &QDialogButtonBox::rejected, plannerModel, &DivePlannerPointsModel::cancelPlan);
|
2014-06-03 22:26:06 +00:00
|
|
|
|
QShortcut *closeKey = new QShortcut(QKeySequence(Qt::Key_Escape), this);
|
2020-01-06 09:39:08 +00:00
|
|
|
|
connect(closeKey, &QShortcut::activated, plannerModel, &DivePlannerPointsModel::cancelPlan);
|
2013-09-16 14:38:41 +00:00
|
|
|
|
|
2014-07-11 20:42:43 +00:00
|
|
|
|
// This makes shure the spinbox gets a setMinimum(0) on it so we can't have negative time or depth.
|
2020-10-03 13:13:24 +00:00
|
|
|
|
// Limit segments to a depth of 1000 m/3300 ft and a duration of 100 h. Setting the limit for
|
|
|
|
|
// the depth will be done in settingChanged() since this depends on the chosen units.
|
2014-07-12 12:24:25 +00:00
|
|
|
|
ui.tableWidget->view()->setItemDelegateForColumn(DivePlannerPointsModel::RUNTIME, new SpinBoxDelegate(0, INT_MAX, 1, this));
|
2020-10-03 13:13:24 +00:00
|
|
|
|
ui.tableWidget->view()->setItemDelegateForColumn(DivePlannerPointsModel::DURATION, new SpinBoxDelegate(0, 6000, 1, this));
|
2024-01-01 21:52:29 +00:00
|
|
|
|
ui.tableWidget->view()->setItemDelegateForColumn(DivePlannerPointsModel::CCSETPOINT, new DoubleSpinBoxDelegate(0, 2, 0.01, this));
|
2014-07-11 20:42:43 +00:00
|
|
|
|
|
2020-11-24 11:50:52 +00:00
|
|
|
|
connect(&diveListNotifier, &DiveListNotifier::settingsChanged, this, &DivePlannerWidget::settingsChanged);
|
|
|
|
|
|
2013-09-09 10:18:22 +00:00
|
|
|
|
/* set defaults. */
|
2014-06-26 15:04:39 +00:00
|
|
|
|
ui.ATMPressure->setValue(1013);
|
|
|
|
|
ui.atmHeight->setValue(0);
|
2013-09-26 21:14:09 +00:00
|
|
|
|
|
2020-11-25 06:31:19 +00:00
|
|
|
|
settingsChanged();
|
|
|
|
|
|
2013-09-26 21:14:09 +00:00
|
|
|
|
setMinimumWidth(0);
|
|
|
|
|
setMinimumHeight(0);
|
2013-08-28 10:48:46 +00:00
|
|
|
|
}
|
|
|
|
|
|
2022-11-07 18:50:37 +00:00
|
|
|
|
DivePlannerWidget::~DivePlannerWidget()
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
2014-11-04 11:15:27 +00:00
|
|
|
|
void DivePlannerWidget::setReplanButton(bool replan)
|
|
|
|
|
{
|
|
|
|
|
replanButton->setVisible(replan);
|
|
|
|
|
}
|
|
|
|
|
|
2014-06-28 15:07:28 +00:00
|
|
|
|
void DivePlannerWidget::setupStartTime(QDateTime startTime)
|
|
|
|
|
{
|
|
|
|
|
ui.startTime->setTime(startTime.time());
|
|
|
|
|
ui.dateEdit->setDate(startTime.date());
|
|
|
|
|
}
|
|
|
|
|
|
2016-12-15 22:02:32 +00:00
|
|
|
|
void DivePlannerWidget::setSurfacePressure(int surface_pressure)
|
|
|
|
|
{
|
|
|
|
|
ui.ATMPressure->setValue(surface_pressure);
|
|
|
|
|
}
|
|
|
|
|
|
2017-04-19 06:05:28 +00:00
|
|
|
|
void PlannerSettingsWidget::setDiveMode(int mode)
|
|
|
|
|
{
|
|
|
|
|
ui.rebreathermode->setCurrentIndex(mode);
|
|
|
|
|
}
|
|
|
|
|
|
2016-12-15 22:02:32 +00:00
|
|
|
|
void DivePlannerWidget::setSalinity(int salinity)
|
|
|
|
|
{
|
2018-02-10 22:28:05 +00:00
|
|
|
|
bool mapped = false;
|
|
|
|
|
for (int i = 0; i < ui.waterType->count(); i++) {
|
|
|
|
|
if (salinity == ui.waterType->itemData(i).toInt()) {
|
|
|
|
|
mapped = true;
|
|
|
|
|
ui.waterType->setCurrentIndex(i);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
2020-10-25 21:27:39 +00:00
|
|
|
|
|
2018-02-10 22:28:05 +00:00
|
|
|
|
if (!mapped) {
|
|
|
|
|
/* Assign to last element "custom" in combo box */
|
|
|
|
|
ui.waterType->setItemData(ui.waterType->count()-1, salinity);
|
|
|
|
|
ui.waterType->setCurrentIndex(ui.waterType->count()-1);
|
|
|
|
|
ui.customSalinity->setEnabled(true);
|
|
|
|
|
ui.customSalinity->setValue(salinity / 10000.0);
|
|
|
|
|
}
|
2020-02-03 17:37:56 +00:00
|
|
|
|
DivePlannerPointsModel::instance()->setSalinity(salinity);
|
2016-12-15 22:02:32 +00:00
|
|
|
|
}
|
|
|
|
|
|
2013-12-09 06:43:00 +00:00
|
|
|
|
void DivePlannerWidget::settingsChanged()
|
|
|
|
|
{
|
2014-06-27 09:43:11 +00:00
|
|
|
|
// Adopt units
|
2020-10-03 13:13:24 +00:00
|
|
|
|
int maxDepth;
|
2014-06-27 09:43:11 +00:00
|
|
|
|
if (get_units()->length == units::FEET) {
|
|
|
|
|
ui.atmHeight->setSuffix("ft");
|
2017-02-13 21:16:03 +00:00
|
|
|
|
ui.atmHeight->setMinimum(-300);
|
|
|
|
|
ui.atmHeight->setMaximum(10000);
|
2020-10-03 13:13:24 +00:00
|
|
|
|
maxDepth = 3300;
|
2014-06-27 09:43:11 +00:00
|
|
|
|
} else {
|
|
|
|
|
ui.atmHeight->setSuffix(("m"));
|
2017-02-13 21:16:03 +00:00
|
|
|
|
ui.atmHeight->setMinimum(-100);
|
|
|
|
|
ui.atmHeight->setMaximum(3000);
|
2020-10-03 13:13:24 +00:00
|
|
|
|
maxDepth = 1000;
|
2014-06-27 09:43:11 +00:00
|
|
|
|
}
|
2020-10-03 13:13:24 +00:00
|
|
|
|
ui.tableWidget->view()->setItemDelegateForColumn(DivePlannerPointsModel::DEPTH, new SpinBoxDelegate(0, maxDepth, 1, this));
|
2014-08-03 20:24:56 +00:00
|
|
|
|
ui.atmHeight->blockSignals(true);
|
2024-06-13 20:59:32 +00:00
|
|
|
|
ui.atmHeight->setValue((int) get_depth_units((int) pressure_to_altitude(DivePlannerPointsModel::instance()->getSurfacePressure()), NULL, NULL));
|
2014-08-03 20:24:56 +00:00
|
|
|
|
ui.atmHeight->blockSignals(false);
|
2023-03-23 03:52:50 +00:00
|
|
|
|
|
2024-06-13 20:59:32 +00:00
|
|
|
|
ui.dateEdit->setDisplayFormat(QString::fromStdString(prefs.date_format));
|
|
|
|
|
ui.startTime->setDisplayFormat(QString::fromStdString(prefs.time_format));
|
2013-12-09 06:43:00 +00:00
|
|
|
|
}
|
|
|
|
|
|
2014-06-26 15:04:39 +00:00
|
|
|
|
void DivePlannerWidget::atmPressureChanged(const int pressure)
|
2013-08-26 16:18:21 +00:00
|
|
|
|
{
|
2020-02-03 17:37:56 +00:00
|
|
|
|
DivePlannerPointsModel::instance()->setSurfacePressure(pressure);
|
2014-06-26 15:04:39 +00:00
|
|
|
|
ui.atmHeight->blockSignals(true);
|
2024-06-13 20:59:32 +00:00
|
|
|
|
ui.atmHeight->setValue((int) get_depth_units((int) pressure_to_altitude(pressure), NULL, NULL));
|
2014-06-26 15:04:39 +00:00
|
|
|
|
ui.atmHeight->blockSignals(false);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void DivePlannerWidget::heightChanged(const int height)
|
2019-05-15 16:39:29 +00:00
|
|
|
|
{ // height is in ft or in meters
|
|
|
|
|
int pressure = (int) (altitude_to_pressure(units_to_depth((double) height).mm));
|
2014-06-26 15:04:39 +00:00
|
|
|
|
ui.ATMPressure->blockSignals(true);
|
|
|
|
|
ui.ATMPressure->setValue(pressure);
|
|
|
|
|
ui.ATMPressure->blockSignals(false);
|
2020-02-03 17:37:56 +00:00
|
|
|
|
DivePlannerPointsModel::instance()->setSurfacePressure(pressure);
|
2013-08-26 16:18:21 +00:00
|
|
|
|
}
|
|
|
|
|
|
2018-02-10 22:28:05 +00:00
|
|
|
|
void DivePlannerWidget::waterTypeUpdateTexts()
|
|
|
|
|
{
|
|
|
|
|
/* Do not set text in last/custom element */
|
|
|
|
|
for (int i = 0; i < ui.waterType->count()-1; i++) {
|
|
|
|
|
if (ui.waterType->itemData(i) != QVariant::Invalid) {
|
|
|
|
|
QString densityText = ui.waterType->itemText(i).split("(")[0].trimmed();
|
2024-06-08 20:13:44 +00:00
|
|
|
|
double density = ui.waterType->itemData(i).toInt() / 10000.0;
|
|
|
|
|
densityText.append(QStringLiteral(" (%L1%2)").arg(density, 0, 'f', 3).arg(tr("kg/ℓ")));
|
2018-02-10 22:28:05 +00:00
|
|
|
|
ui.waterType->setItemText(i, densityText);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void DivePlannerWidget::waterTypeChanged(const int index)
|
|
|
|
|
{
|
|
|
|
|
ui.customSalinity->setEnabled(index == ui.waterType->count() - 1);
|
|
|
|
|
ui.customSalinity->setValue(ui.waterType->itemData(index).toInt() / 10000.0);
|
2020-02-03 17:37:56 +00:00
|
|
|
|
DivePlannerPointsModel::instance()->setSalinity(ui.waterType->itemData(index).toInt());
|
2018-02-10 22:28:05 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void DivePlannerWidget::customSalinityChanged(double density)
|
2014-11-12 22:33:40 +00:00
|
|
|
|
{
|
2018-02-10 22:28:05 +00:00
|
|
|
|
if (ui.customSalinity->isEnabled()) {
|
|
|
|
|
int newSalinity = (int)(density * 10000.0);
|
|
|
|
|
ui.waterType->setItemData(ui.waterType->count() - 1, newSalinity);
|
2020-02-03 17:37:56 +00:00
|
|
|
|
DivePlannerPointsModel::instance()->setSalinity(newSalinity);
|
2018-02-10 22:28:05 +00:00
|
|
|
|
}
|
2014-11-12 22:33:40 +00:00
|
|
|
|
}
|
|
|
|
|
|
2022-11-08 07:26:06 +00:00
|
|
|
|
void PlannerSettingsWidget::disableDecoElements(int mode, divemode_t rebreathermode)
|
2015-04-26 19:40:36 +00:00
|
|
|
|
{
|
2015-08-15 13:16:51 +00:00
|
|
|
|
if (mode == RECREATIONAL) {
|
2017-11-02 19:39:58 +00:00
|
|
|
|
ui.label_gflow->setDisabled(false);
|
|
|
|
|
ui.label_gfhigh->setDisabled(false);
|
2015-08-15 13:16:51 +00:00
|
|
|
|
ui.gflow->setDisabled(false);
|
|
|
|
|
ui.gfhigh->setDisabled(false);
|
|
|
|
|
ui.lastStop->setDisabled(true);
|
|
|
|
|
ui.backgasBreaks->setDisabled(true);
|
2017-11-24 20:06:42 +00:00
|
|
|
|
ui.backgasBreaks->blockSignals(true);
|
|
|
|
|
ui.backgasBreaks->setChecked(false);
|
|
|
|
|
ui.backgasBreaks->blockSignals(false);
|
2019-01-10 20:18:53 +00:00
|
|
|
|
ui.bailout->setDisabled(true);
|
|
|
|
|
ui.bailout->blockSignals(true);
|
|
|
|
|
ui.bailout->setChecked(false);
|
|
|
|
|
ui.bailout->blockSignals(false);
|
2017-03-06 19:27:09 +00:00
|
|
|
|
ui.bottompo2->setDisabled(false);
|
2015-08-15 13:16:51 +00:00
|
|
|
|
ui.decopo2->setDisabled(true);
|
2017-11-02 19:39:58 +00:00
|
|
|
|
ui.safetystop->setDisabled(false);
|
|
|
|
|
ui.label_reserve_gas->setDisabled(false);
|
2015-08-15 13:16:51 +00:00
|
|
|
|
ui.reserve_gas->setDisabled(false);
|
2017-11-02 19:39:58 +00:00
|
|
|
|
ui.label_vpmb_conservatism->setDisabled(true);
|
2016-09-24 08:02:08 +00:00
|
|
|
|
ui.vpmb_conservatism->setDisabled(true);
|
2015-08-22 17:40:20 +00:00
|
|
|
|
ui.switch_at_req_stop->setDisabled(true);
|
|
|
|
|
ui.min_switch_duration->setDisabled(true);
|
2019-03-25 21:40:59 +00:00
|
|
|
|
ui.surface_segment->setDisabled(true);
|
2017-11-24 20:06:42 +00:00
|
|
|
|
ui.label_min_switch_duration->setDisabled(true);
|
2017-03-06 20:46:05 +00:00
|
|
|
|
ui.sacfactor->setDisabled(true);
|
|
|
|
|
ui.problemsolvingtime->setDisabled(true);
|
|
|
|
|
ui.sacfactor->blockSignals(true);
|
|
|
|
|
ui.problemsolvingtime->blockSignals(true);
|
|
|
|
|
ui.sacfactor->setValue(2.0);
|
|
|
|
|
ui.problemsolvingtime->setValue(0);
|
|
|
|
|
ui.sacfactor->blockSignals(false);
|
|
|
|
|
ui.problemsolvingtime->blockSignals(false);
|
2017-11-30 22:06:46 +00:00
|
|
|
|
ui.display_variations->setDisabled(true);
|
2022-11-06 16:10:37 +00:00
|
|
|
|
} else if (mode == VPMB) {
|
2017-11-02 19:39:58 +00:00
|
|
|
|
ui.label_gflow->setDisabled(true);
|
|
|
|
|
ui.label_gfhigh->setDisabled(true);
|
2015-08-15 13:16:51 +00:00
|
|
|
|
ui.gflow->setDisabled(true);
|
|
|
|
|
ui.gfhigh->setDisabled(true);
|
|
|
|
|
ui.lastStop->setDisabled(false);
|
2017-11-24 20:06:42 +00:00
|
|
|
|
if (prefs.last_stop) {
|
|
|
|
|
ui.backgasBreaks->setDisabled(false);
|
|
|
|
|
ui.backgasBreaks->blockSignals(true);
|
|
|
|
|
ui.backgasBreaks->setChecked(prefs.doo2breaks);
|
|
|
|
|
ui.backgasBreaks->blockSignals(false);
|
|
|
|
|
} else {
|
|
|
|
|
ui.backgasBreaks->setDisabled(true);
|
|
|
|
|
ui.backgasBreaks->blockSignals(true);
|
|
|
|
|
ui.backgasBreaks->setChecked(false);
|
|
|
|
|
ui.backgasBreaks->blockSignals(false);
|
|
|
|
|
}
|
2022-11-06 16:10:37 +00:00
|
|
|
|
ui.bailout->setDisabled(!(rebreathermode == CCR || rebreathermode == PSCR));
|
2015-08-15 13:16:51 +00:00
|
|
|
|
ui.bottompo2->setDisabled(false);
|
|
|
|
|
ui.decopo2->setDisabled(false);
|
2017-11-02 19:39:58 +00:00
|
|
|
|
ui.safetystop->setDisabled(true);
|
|
|
|
|
ui.label_reserve_gas->setDisabled(true);
|
2015-08-15 13:16:51 +00:00
|
|
|
|
ui.reserve_gas->setDisabled(true);
|
2017-11-02 19:39:58 +00:00
|
|
|
|
ui.label_vpmb_conservatism->setDisabled(false);
|
2016-09-24 08:02:08 +00:00
|
|
|
|
ui.vpmb_conservatism->setDisabled(false);
|
2015-08-22 17:40:20 +00:00
|
|
|
|
ui.switch_at_req_stop->setDisabled(false);
|
|
|
|
|
ui.min_switch_duration->setDisabled(false);
|
2019-03-25 21:40:59 +00:00
|
|
|
|
ui.surface_segment->setDisabled(false);
|
2017-11-24 20:06:42 +00:00
|
|
|
|
ui.label_min_switch_duration->setDisabled(false);
|
2017-03-06 20:46:05 +00:00
|
|
|
|
ui.sacfactor->setDisabled(false);
|
|
|
|
|
ui.problemsolvingtime->setDisabled(false);
|
2020-02-03 18:08:35 +00:00
|
|
|
|
ui.sacfactor->setValue(PlannerShared::sacfactor());
|
2017-03-06 20:46:05 +00:00
|
|
|
|
ui.problemsolvingtime->setValue(prefs.problemsolvingtime);
|
2017-11-30 22:06:46 +00:00
|
|
|
|
ui.display_variations->setDisabled(false);
|
2022-11-06 16:10:37 +00:00
|
|
|
|
} else if (mode == BUEHLMANN) {
|
2017-11-02 19:39:58 +00:00
|
|
|
|
ui.label_gflow->setDisabled(false);
|
|
|
|
|
ui.label_gfhigh->setDisabled(false);
|
2015-08-15 13:16:51 +00:00
|
|
|
|
ui.gflow->setDisabled(false);
|
|
|
|
|
ui.gfhigh->setDisabled(false);
|
|
|
|
|
ui.lastStop->setDisabled(false);
|
2017-11-24 20:06:42 +00:00
|
|
|
|
if (prefs.last_stop) {
|
|
|
|
|
ui.backgasBreaks->setDisabled(false);
|
|
|
|
|
ui.backgasBreaks->blockSignals(true);
|
|
|
|
|
ui.backgasBreaks->setChecked(prefs.doo2breaks);
|
|
|
|
|
ui.backgasBreaks->blockSignals(false);
|
|
|
|
|
} else {
|
|
|
|
|
ui.backgasBreaks->setDisabled(true);
|
|
|
|
|
ui.backgasBreaks->blockSignals(true);
|
|
|
|
|
ui.backgasBreaks->setChecked(false);
|
|
|
|
|
ui.backgasBreaks->blockSignals(false);
|
|
|
|
|
}
|
2022-11-06 16:10:37 +00:00
|
|
|
|
ui.bailout->setDisabled(!(rebreathermode == CCR || rebreathermode == PSCR));
|
2015-08-15 13:16:51 +00:00
|
|
|
|
ui.bottompo2->setDisabled(false);
|
|
|
|
|
ui.decopo2->setDisabled(false);
|
2017-11-02 19:39:58 +00:00
|
|
|
|
ui.safetystop->setDisabled(true);
|
|
|
|
|
ui.label_reserve_gas->setDisabled(true);
|
2015-08-15 13:16:51 +00:00
|
|
|
|
ui.reserve_gas->setDisabled(true);
|
2017-11-02 19:39:58 +00:00
|
|
|
|
ui.label_vpmb_conservatism->setDisabled(true);
|
2016-09-24 08:02:08 +00:00
|
|
|
|
ui.vpmb_conservatism->setDisabled(true);
|
2015-08-22 17:40:20 +00:00
|
|
|
|
ui.switch_at_req_stop->setDisabled(false);
|
|
|
|
|
ui.min_switch_duration->setDisabled(false);
|
2019-03-25 21:40:59 +00:00
|
|
|
|
ui.surface_segment->setDisabled(false);
|
2017-11-24 20:06:42 +00:00
|
|
|
|
ui.label_min_switch_duration->setDisabled(false);
|
2017-03-06 20:46:05 +00:00
|
|
|
|
ui.sacfactor->setDisabled(false);
|
|
|
|
|
ui.problemsolvingtime->setDisabled(false);
|
2020-02-03 18:08:35 +00:00
|
|
|
|
ui.sacfactor->setValue(PlannerShared::sacfactor());
|
2017-03-06 20:46:05 +00:00
|
|
|
|
ui.problemsolvingtime->setValue(prefs.problemsolvingtime);
|
2017-11-30 22:06:46 +00:00
|
|
|
|
ui.display_variations->setDisabled(false);
|
2015-07-07 18:29:37 +00:00
|
|
|
|
}
|
2015-04-26 19:40:36 +00:00
|
|
|
|
}
|
|
|
|
|
|
2017-11-02 20:00:54 +00:00
|
|
|
|
void PlannerSettingsWidget::disableBackgasBreaks(bool enabled)
|
|
|
|
|
{
|
2017-11-24 20:06:42 +00:00
|
|
|
|
if (prefs.planner_deco_mode == RECREATIONAL)
|
|
|
|
|
return;
|
|
|
|
|
|
2017-11-02 20:00:54 +00:00
|
|
|
|
if (enabled) {
|
|
|
|
|
ui.backgasBreaks->setDisabled(false);
|
|
|
|
|
ui.backgasBreaks->blockSignals(true);
|
|
|
|
|
ui.backgasBreaks->setChecked(prefs.doo2breaks);
|
|
|
|
|
ui.backgasBreaks->blockSignals(false);
|
|
|
|
|
} else {
|
|
|
|
|
ui.backgasBreaks->setDisabled(true);
|
|
|
|
|
ui.backgasBreaks->blockSignals(true);
|
|
|
|
|
ui.backgasBreaks->setChecked(false);
|
|
|
|
|
ui.backgasBreaks->blockSignals(false);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2022-11-08 07:26:06 +00:00
|
|
|
|
PlannerSettingsWidget::PlannerSettingsWidget(PlannerWidgets *parent)
|
2014-06-10 15:40:02 +00:00
|
|
|
|
{
|
|
|
|
|
ui.setupUi(this);
|
2016-08-26 19:01:31 +00:00
|
|
|
|
|
2020-02-03 17:37:56 +00:00
|
|
|
|
DivePlannerPointsModel *plannerModel = DivePlannerPointsModel::instance();
|
2014-08-26 18:23:50 +00:00
|
|
|
|
plannerModel->getDiveplan().bottomsac = prefs.bottomsac;
|
|
|
|
|
plannerModel->getDiveplan().decosac = prefs.decosac;
|
2014-07-15 18:39:13 +00:00
|
|
|
|
|
2014-07-17 15:03:52 +00:00
|
|
|
|
updateUnitsUI();
|
2015-03-24 21:57:22 +00:00
|
|
|
|
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);
|
2017-09-18 14:10:47 +00:00
|
|
|
|
ui.display_variations->setChecked(prefs.display_variations);
|
2015-04-02 08:32:14 +00:00
|
|
|
|
ui.safetystop->setChecked(prefs.safetystop);
|
2020-02-03 18:08:35 +00:00
|
|
|
|
ui.sacfactor->setValue(PlannerShared::sacfactor());
|
2017-02-11 19:24:18 +00:00
|
|
|
|
ui.problemsolvingtime->setValue(prefs.problemsolvingtime);
|
2020-02-03 18:08:35 +00:00
|
|
|
|
ui.bottompo2->setValue(PlannerShared::bottompo2());
|
|
|
|
|
ui.decopo2->setValue(PlannerShared::decopo2());
|
2014-07-02 20:07:38 +00:00
|
|
|
|
ui.backgasBreaks->setChecked(prefs.doo2breaks);
|
2020-02-03 18:08:35 +00:00
|
|
|
|
PlannerShared::set_dobailout(false);
|
2019-01-10 20:18:53 +00:00
|
|
|
|
setBailoutVisibility(false);
|
2019-10-29 16:57:34 +00:00
|
|
|
|
ui.o2narcotic->setChecked(prefs.o2narcotic);
|
2014-07-17 03:32:06 +00:00
|
|
|
|
ui.drop_stone_mode->setChecked(prefs.drop_stone_mode);
|
2015-06-22 11:48:42 +00:00
|
|
|
|
ui.switch_at_req_stop->setChecked(prefs.switch_at_req_stop);
|
2020-02-03 18:08:35 +00:00
|
|
|
|
ui.min_switch_duration->setValue(PlannerShared::min_switch_duration());
|
|
|
|
|
ui.surface_segment->setValue(PlannerShared::surface_segment());
|
2017-01-07 02:11:19 +00:00
|
|
|
|
ui.recreational_deco->setChecked(prefs.planner_deco_mode == RECREATIONAL);
|
|
|
|
|
ui.buehlmann_deco->setChecked(prefs.planner_deco_mode == BUEHLMANN);
|
|
|
|
|
ui.vpmb_deco->setChecked(prefs.planner_deco_mode == VPMB);
|
2022-11-08 07:26:06 +00:00
|
|
|
|
disableDecoElements((int) prefs.planner_deco_mode, OC);
|
2015-07-03 21:07:58 +00:00
|
|
|
|
|
2015-01-16 14:05:00 +00:00
|
|
|
|
// should be the same order as in dive_comp_type!
|
2018-07-13 16:45:58 +00:00
|
|
|
|
QStringList rebreather_modes = QStringList();
|
|
|
|
|
for (int i = 0; i < FREEDIVE; i++)
|
2018-06-17 15:55:47 +00:00
|
|
|
|
rebreather_modes.append(gettextFromC::tr(divemode_text_ui[i]));
|
2015-07-24 11:42:12 +00:00
|
|
|
|
ui.rebreathermode->insertItems(0, rebreather_modes);
|
2014-06-24 22:08:36 +00:00
|
|
|
|
|
2020-02-04 13:09:12 +00:00
|
|
|
|
connect(ui.recreational_deco, &QAbstractButton::clicked, [] { PlannerShared::set_planner_deco_mode(RECREATIONAL); });
|
|
|
|
|
connect(ui.buehlmann_deco, &QAbstractButton::clicked, [] { PlannerShared::set_planner_deco_mode(BUEHLMANN); });
|
|
|
|
|
connect(ui.vpmb_deco, &QAbstractButton::clicked, [] { PlannerShared::set_planner_deco_mode(VPMB); });
|
2015-09-03 18:56:37 +00:00
|
|
|
|
|
2020-01-21 11:24:40 +00:00
|
|
|
|
connect(ui.lastStop, &QAbstractButton::toggled, plannerModel, &DivePlannerPointsModel::setLastStop6m);
|
2020-01-02 17:31:41 +00:00
|
|
|
|
connect(ui.lastStop, &QAbstractButton::toggled, this, &PlannerSettingsWidget::disableBackgasBreaks);
|
2020-01-20 19:10:35 +00:00
|
|
|
|
connect(ui.verbatim_plan, &QAbstractButton::toggled, plannerModel, &DivePlannerPointsModel::setVerbatim);
|
|
|
|
|
connect(ui.display_duration, &QAbstractButton::toggled, plannerModel, &DivePlannerPointsModel::setDisplayDuration);
|
|
|
|
|
connect(ui.display_runtime, &QAbstractButton::toggled, plannerModel, &DivePlannerPointsModel::setDisplayRuntime);
|
|
|
|
|
connect(ui.display_transitions, &QAbstractButton::toggled, plannerModel, &DivePlannerPointsModel::setDisplayTransitions);
|
2020-05-04 08:33:11 +00:00
|
|
|
|
connect(ui.display_variations, &QAbstractButton::toggled, plannerModel, &DivePlannerPointsModel::setDisplayVariations);
|
2020-01-21 11:24:40 +00:00
|
|
|
|
connect(ui.safetystop, &QAbstractButton::toggled, plannerModel, &DivePlannerPointsModel::setSafetyStop);
|
2020-02-03 18:08:35 +00:00
|
|
|
|
connect(ui.reserve_gas, QOverload<int>::of(&QSpinBox::valueChanged), &PlannerShared::set_reserve_gas);
|
2020-01-20 09:48:31 +00:00
|
|
|
|
connect(ui.ascRate75, QOverload<int>::of(&QSpinBox::valueChanged), plannerModel, &DivePlannerPointsModel::setAscrate75Display);
|
|
|
|
|
connect(ui.ascRate50, QOverload<int>::of(&QSpinBox::valueChanged), plannerModel, &DivePlannerPointsModel::setAscrate50Display);
|
|
|
|
|
connect(ui.ascRateStops, QOverload<int>::of(&QSpinBox::valueChanged), plannerModel, &DivePlannerPointsModel::setAscratestopsDisplay);
|
|
|
|
|
connect(ui.ascRateLast6m, QOverload<int>::of(&QSpinBox::valueChanged), plannerModel, &DivePlannerPointsModel::setAscratelast6mDisplay);
|
|
|
|
|
connect(ui.descRate, QOverload<int>::of(&QSpinBox::valueChanged), plannerModel, &DivePlannerPointsModel::setDescrateDisplay);
|
2020-01-21 11:24:40 +00:00
|
|
|
|
connect(ui.drop_stone_mode, &QAbstractButton::toggled, plannerModel, &DivePlannerPointsModel::setDropStoneMode);
|
|
|
|
|
connect(ui.gfhigh, QOverload<int>::of(&QSpinBox::valueChanged), plannerModel, &DivePlannerPointsModel::setGFHigh);
|
|
|
|
|
connect(ui.gflow, QOverload<int>::of(&QSpinBox::valueChanged), plannerModel, &DivePlannerPointsModel::setGFLow);
|
|
|
|
|
connect(ui.vpmb_conservatism, QOverload<int>::of(&QSpinBox::valueChanged), plannerModel, &DivePlannerPointsModel::setVpmbConservatism);
|
2020-01-02 17:31:41 +00:00
|
|
|
|
connect(ui.backgasBreaks, &QAbstractButton::toggled, this, &PlannerSettingsWidget::setBackgasBreaks);
|
2020-02-03 18:08:35 +00:00
|
|
|
|
connect(ui.bailout, &QAbstractButton::toggled, &PlannerShared::set_dobailout);
|
|
|
|
|
connect(ui.o2narcotic, &QAbstractButton::toggled, &PlannerShared::set_o2narcotic);
|
2020-01-21 11:24:40 +00:00
|
|
|
|
connect(ui.switch_at_req_stop, &QAbstractButton::toggled, plannerModel, &DivePlannerPointsModel::setSwitchAtReqStop);
|
2020-02-03 18:08:35 +00:00
|
|
|
|
connect(ui.min_switch_duration, QOverload<int>::of(&QSpinBox::valueChanged), &PlannerShared::set_min_switch_duration);
|
|
|
|
|
connect(ui.surface_segment, QOverload<int>::of(&QSpinBox::valueChanged), &PlannerShared::set_surface_segment);
|
2020-01-06 09:21:12 +00:00
|
|
|
|
connect(ui.rebreathermode, QOverload<int>::of(&QComboBox::currentIndexChanged), plannerModel, &DivePlannerPointsModel::setRebreatherMode);
|
|
|
|
|
connect(ui.rebreathermode, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &PlannerSettingsWidget::setBailoutVisibility);
|
2016-08-26 19:04:34 +00:00
|
|
|
|
|
2022-11-08 07:26:06 +00:00
|
|
|
|
connect(ui.recreational_deco, &QAbstractButton::clicked, [this, parent] { disableDecoElements(RECREATIONAL, parent->getRebreatherMode()); });
|
|
|
|
|
connect(ui.buehlmann_deco, &QAbstractButton::clicked, [this, parent] { disableDecoElements(BUEHLMANN, parent->getRebreatherMode()); });
|
|
|
|
|
connect(ui.vpmb_deco, &QAbstractButton::clicked, [this, parent] { disableDecoElements(VPMB, parent->getRebreatherMode()); });
|
2020-01-02 14:05:54 +00:00
|
|
|
|
|
2020-02-03 18:08:35 +00:00
|
|
|
|
connect(ui.sacfactor, QOverload<double>::of(&QDoubleSpinBox::valueChanged), &PlannerShared::set_sacfactor);
|
2020-01-21 11:24:40 +00:00
|
|
|
|
connect(ui.problemsolvingtime, QOverload<int>::of(&QSpinBox::valueChanged), plannerModel, &DivePlannerPointsModel::setProblemSolvingTime);
|
2020-02-03 18:08:35 +00:00
|
|
|
|
connect(ui.bottompo2, QOverload<double>::of(&QDoubleSpinBox::valueChanged), &PlannerShared::set_bottompo2);
|
|
|
|
|
connect(ui.decopo2, QOverload<double>::of(&QDoubleSpinBox::valueChanged), &PlannerShared::set_decopo2);
|
|
|
|
|
connect(ui.bestmixEND, QOverload<int>::of(&QSpinBox::valueChanged), &PlannerShared::set_bestmixend);
|
|
|
|
|
connect(ui.bottomSAC, QOverload<double>::of(&QDoubleSpinBox::valueChanged), &PlannerShared::set_bottomsac);
|
|
|
|
|
connect(ui.decoStopSAC, QOverload<double>::of(&QDoubleSpinBox::valueChanged), &PlannerShared::set_decosac);
|
2020-11-24 11:50:52 +00:00
|
|
|
|
connect(&diveListNotifier, &DiveListNotifier::settingsChanged, this, &PlannerSettingsWidget::settingsChanged);
|
2015-04-26 19:40:36 +00:00
|
|
|
|
|
2014-08-19 16:13:55 +00:00
|
|
|
|
settingsChanged();
|
2014-06-26 15:04:39 +00:00
|
|
|
|
ui.gflow->setValue(prefs.gflow);
|
|
|
|
|
ui.gfhigh->setValue(prefs.gfhigh);
|
2016-09-24 08:02:08 +00:00
|
|
|
|
ui.vpmb_conservatism->setValue(prefs.vpmb_conservatism);
|
2014-06-10 15:40:02 +00:00
|
|
|
|
|
2017-10-07 10:50:10 +00:00
|
|
|
|
ui.ascRate75->setKeyboardTracking(false);
|
|
|
|
|
ui.ascRate50->setKeyboardTracking(false);
|
|
|
|
|
ui.ascRateLast6m->setKeyboardTracking(false);
|
|
|
|
|
ui.ascRateStops->setKeyboardTracking(false);
|
|
|
|
|
ui.descRate->setKeyboardTracking(false);
|
|
|
|
|
ui.gfhigh->setKeyboardTracking(false);
|
|
|
|
|
ui.gflow->setKeyboardTracking(false);
|
|
|
|
|
|
2014-06-10 15:40:02 +00:00
|
|
|
|
setMinimumWidth(0);
|
|
|
|
|
setMinimumHeight(0);
|
|
|
|
|
}
|
|
|
|
|
|
2014-07-17 15:03:52 +00:00
|
|
|
|
void PlannerSettingsWidget::updateUnitsUI()
|
|
|
|
|
{
|
2020-02-03 17:37:56 +00:00
|
|
|
|
DivePlannerPointsModel *plannerModel = DivePlannerPointsModel::instance();
|
2020-01-19 17:01:29 +00:00
|
|
|
|
ui.ascRate75->setValue(plannerModel->ascrate75Display());
|
|
|
|
|
ui.ascRate50->setValue(plannerModel->ascrate50Display());
|
|
|
|
|
ui.ascRateStops->setValue(plannerModel->ascratestopsDisplay());
|
|
|
|
|
ui.ascRateLast6m->setValue(plannerModel->ascratelast6mDisplay());
|
|
|
|
|
ui.descRate->setValue(lrint(plannerModel->descrateDisplay()));
|
2017-03-08 06:41:41 +00:00
|
|
|
|
ui.bestmixEND->setValue(lrint(get_depth_units(prefs.bestmixend.mm, NULL, NULL)));
|
2014-07-17 15:03:52 +00:00
|
|
|
|
}
|
|
|
|
|
|
2014-07-15 18:39:13 +00:00
|
|
|
|
PlannerSettingsWidget::~PlannerSettingsWidget()
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
2014-06-10 15:40:02 +00:00
|
|
|
|
void PlannerSettingsWidget::settingsChanged()
|
|
|
|
|
{
|
2014-07-17 05:43:58 +00:00
|
|
|
|
QString vs;
|
2014-08-19 16:13:55 +00:00
|
|
|
|
// don't recurse into setting the value from the ui when setting the ui from the value
|
|
|
|
|
ui.bottomSAC->blockSignals(true);
|
|
|
|
|
ui.decoStopSAC->blockSignals(true);
|
2014-06-27 09:43:11 +00:00
|
|
|
|
if (get_units()->length == units::FEET) {
|
2014-07-17 05:43:58 +00:00
|
|
|
|
vs.append(tr("ft/min"));
|
2014-06-27 09:43:11 +00:00
|
|
|
|
ui.lastStop->setText(tr("Last stop at 20ft"));
|
2014-07-17 17:45:55 +00:00
|
|
|
|
ui.asc50to6->setText(tr("50% avg. depth to 20ft"));
|
|
|
|
|
ui.asc6toSurf->setText(tr("20ft to surface"));
|
2016-05-21 10:14:23 +00:00
|
|
|
|
ui.bestmixEND->setSuffix(tr("ft"));
|
2014-06-27 09:43:11 +00:00
|
|
|
|
} else {
|
2014-07-17 05:43:58 +00:00
|
|
|
|
vs.append(tr("m/min"));
|
2014-06-27 09:43:11 +00:00
|
|
|
|
ui.lastStop->setText(tr("Last stop at 6m"));
|
2014-07-17 17:45:55 +00:00
|
|
|
|
ui.asc50to6->setText(tr("50% avg. depth to 6m"));
|
|
|
|
|
ui.asc6toSurf->setText(tr("6m to surface"));
|
2016-05-21 10:14:23 +00:00
|
|
|
|
ui.bestmixEND->setSuffix(tr("m"));
|
2014-06-27 09:43:11 +00:00
|
|
|
|
}
|
2020-10-03 13:13:24 +00:00
|
|
|
|
if (get_units()->volume == units::CUFT) {
|
2014-08-06 08:16:12 +00:00
|
|
|
|
ui.bottomSAC->setSuffix(tr("cuft/min"));
|
|
|
|
|
ui.decoStopSAC->setSuffix(tr("cuft/min"));
|
2014-08-19 16:13:55 +00:00
|
|
|
|
ui.bottomSAC->setDecimals(2);
|
|
|
|
|
ui.bottomSAC->setSingleStep(0.1);
|
|
|
|
|
ui.decoStopSAC->setDecimals(2);
|
|
|
|
|
ui.decoStopSAC->setSingleStep(0.1);
|
2020-02-03 18:08:35 +00:00
|
|
|
|
ui.bottomSAC->setValue(PlannerShared::bottomsac());
|
|
|
|
|
ui.decoStopSAC->setValue(PlannerShared::decosac());
|
2014-08-06 08:16:12 +00:00
|
|
|
|
} else {
|
|
|
|
|
ui.bottomSAC->setSuffix(tr("ℓ/min"));
|
|
|
|
|
ui.decoStopSAC->setSuffix(tr("ℓ/min"));
|
2014-08-19 16:13:55 +00:00
|
|
|
|
ui.bottomSAC->setDecimals(0);
|
|
|
|
|
ui.bottomSAC->setSingleStep(1);
|
|
|
|
|
ui.decoStopSAC->setDecimals(0);
|
|
|
|
|
ui.decoStopSAC->setSingleStep(1);
|
2020-02-03 18:08:35 +00:00
|
|
|
|
ui.bottomSAC->setValue(PlannerShared::bottomsac());
|
|
|
|
|
ui.decoStopSAC->setValue(PlannerShared::decosac());
|
2014-08-06 08:16:12 +00:00
|
|
|
|
}
|
2020-10-03 13:13:24 +00:00
|
|
|
|
if (get_units()->pressure == units::BAR) {
|
2016-03-22 22:44:59 +00:00
|
|
|
|
ui.reserve_gas->setSuffix(tr("bar"));
|
|
|
|
|
ui.reserve_gas->setSingleStep(1);
|
|
|
|
|
ui.reserve_gas->setValue(prefs.reserve_gas / 1000);
|
2016-03-23 15:59:18 +00:00
|
|
|
|
ui.reserve_gas->setMaximum(300);
|
2016-03-22 22:44:59 +00:00
|
|
|
|
} else {
|
|
|
|
|
ui.reserve_gas->setSuffix(tr("psi"));
|
|
|
|
|
ui.reserve_gas->setSingleStep(10);
|
2016-03-23 15:59:18 +00:00
|
|
|
|
ui.reserve_gas->setMaximum(5000);
|
core: return floating point from to_PSI() functions
Dive data are stored internally using integral types using
appropriately fine units (mm, mbar, mkelvin, etc.). These
are converted with functions defined in units.h for display
(m, bar, C, etc.). Usually floating points are returned by
these functions, to retain the necessary precision. There
is one exception: the to_PSI() and mbar_to_PSI() functions.
For consistency, make these functions likewise return floats.
This will be needed for the rework of the profile-axes.
The plan is to use the conversion functions to make the
axes aware of the displayed values. This in turn will be
necessary to place the ticks at sensible distances. However,
the conversions need to be precise, which is not the
case for the current to_PSI() functions.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2021-09-24 13:07:11 +00:00
|
|
|
|
ui.reserve_gas->setValue(lrint(mbar_to_PSI(prefs.reserve_gas)));
|
2016-03-22 22:44:59 +00:00
|
|
|
|
}
|
|
|
|
|
|
2014-08-19 16:13:55 +00:00
|
|
|
|
ui.bottomSAC->blockSignals(false);
|
|
|
|
|
ui.decoStopSAC->blockSignals(false);
|
2014-07-17 15:03:52 +00:00
|
|
|
|
updateUnitsUI();
|
2014-07-17 05:43:58 +00:00
|
|
|
|
ui.ascRate75->setSuffix(vs);
|
|
|
|
|
ui.ascRate50->setSuffix(vs);
|
|
|
|
|
ui.ascRateStops->setSuffix(vs);
|
|
|
|
|
ui.ascRateLast6m->setSuffix(vs);
|
|
|
|
|
ui.descRate->setSuffix(vs);
|
2014-06-10 15:40:02 +00:00
|
|
|
|
}
|
|
|
|
|
|
2014-07-02 20:07:38 +00:00
|
|
|
|
void PlannerSettingsWidget::setBackgasBreaks(bool dobreaks)
|
|
|
|
|
{
|
2020-02-03 18:08:35 +00:00
|
|
|
|
PlannerShared::set_doo2breaks(dobreaks);
|
2014-07-02 20:07:38 +00:00
|
|
|
|
}
|
|
|
|
|
|
2019-01-10 20:18:53 +00:00
|
|
|
|
void PlannerSettingsWidget::setBailoutVisibility(int mode)
|
|
|
|
|
{
|
2022-11-05 19:27:49 +00:00
|
|
|
|
ui.bailout->setDisabled(!(mode == CCR || mode == PSCR));
|
|
|
|
|
ui.sacFactor->setDisabled(mode == CCR);
|
2019-01-10 20:18:53 +00:00
|
|
|
|
}
|
|
|
|
|
|
2015-02-09 18:37:26 +00:00
|
|
|
|
PlannerDetails::PlannerDetails(QWidget *parent) : QWidget(parent)
|
|
|
|
|
{
|
|
|
|
|
ui.setupUi(this);
|
2020-11-25 06:31:19 +00:00
|
|
|
|
#ifdef NO_PRINTING
|
|
|
|
|
ui.printPlan->hide();
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void PlannerDetails::setPlanNotes(QString plan)
|
|
|
|
|
{
|
|
|
|
|
ui.divePlanOutput->setHtml(plan);
|
|
|
|
|
}
|
|
|
|
|
|
2022-11-05 19:27:49 +00:00
|
|
|
|
PlannerWidgets::PlannerWidgets() :
|
2024-05-16 18:11:21 +00:00
|
|
|
|
planned_dive(std::make_unique<dive>()),
|
2024-04-25 20:16:08 +00:00
|
|
|
|
dcNr(0),
|
|
|
|
|
plannerWidget(*planned_dive, dcNr, this),
|
2022-11-08 07:26:06 +00:00
|
|
|
|
plannerSettingsWidget(this)
|
2020-11-25 06:31:19 +00:00
|
|
|
|
{
|
|
|
|
|
connect(plannerDetails.printPlan(), &QPushButton::pressed, this, &PlannerWidgets::printDecoPlan);
|
|
|
|
|
connect(DivePlannerPointsModel::instance(), &DivePlannerPointsModel::calculatedPlanNotes,
|
|
|
|
|
&plannerDetails, &PlannerDetails::setPlanNotes);
|
|
|
|
|
}
|
|
|
|
|
|
2022-11-07 18:50:37 +00:00
|
|
|
|
PlannerWidgets::~PlannerWidgets()
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
2022-11-05 19:27:49 +00:00
|
|
|
|
struct dive *PlannerWidgets::getDive() const
|
2020-11-25 06:31:19 +00:00
|
|
|
|
{
|
2022-11-05 19:27:49 +00:00
|
|
|
|
return planned_dive.get();
|
|
|
|
|
}
|
2020-11-25 06:31:19 +00:00
|
|
|
|
|
2024-04-25 20:16:08 +00:00
|
|
|
|
int PlannerWidgets::getDcNr()
|
|
|
|
|
{
|
|
|
|
|
return dcNr;
|
|
|
|
|
}
|
|
|
|
|
|
2022-11-08 07:26:06 +00:00
|
|
|
|
divemode_t PlannerWidgets::getRebreatherMode() const
|
|
|
|
|
{
|
2024-06-30 18:38:12 +00:00
|
|
|
|
return planned_dive->get_dc(dcNr)->divemode;
|
2022-11-08 07:26:06 +00:00
|
|
|
|
}
|
|
|
|
|
|
2024-04-25 20:16:08 +00:00
|
|
|
|
void PlannerWidgets::preparePlanDive(const dive *currentDive, int currentDcNr)
|
2022-11-05 19:27:49 +00:00
|
|
|
|
{
|
2023-09-10 17:24:57 +00:00
|
|
|
|
DivePlannerPointsModel::instance()->setPlanMode(DivePlannerPointsModel::PLAN);
|
2020-11-25 06:31:19 +00:00
|
|
|
|
// create a simple starting dive, using the first gas from the just copied cylinders
|
2022-11-05 19:27:49 +00:00
|
|
|
|
DivePlannerPointsModel::instance()->createSimpleDive(planned_dive.get());
|
2024-04-25 20:16:08 +00:00
|
|
|
|
dcNr = 0;
|
2020-11-25 06:31:19 +00:00
|
|
|
|
|
|
|
|
|
// plan the dive in the same mode as the currently selected one
|
2022-09-17 14:55:44 +00:00
|
|
|
|
if (currentDive) {
|
2024-06-30 18:38:12 +00:00
|
|
|
|
plannerSettingsWidget.setDiveMode(currentDive->get_dc(currentDcNr)->divemode);
|
|
|
|
|
plannerSettingsWidget.setBailoutVisibility(currentDive->get_dc(currentDcNr)->divemode);
|
2022-09-17 14:55:44 +00:00
|
|
|
|
if (currentDive->salinity)
|
|
|
|
|
plannerWidget.setSalinity(currentDive->salinity);
|
2020-11-25 06:31:19 +00:00
|
|
|
|
else // No salinity means salt water
|
|
|
|
|
plannerWidget.setSalinity(SEAWATER_SALINITY);
|
|
|
|
|
}
|
2022-11-05 19:27:49 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void PlannerWidgets::planDive()
|
|
|
|
|
{
|
|
|
|
|
DivePlannerPointsModel::instance()->setPlanMode(DivePlannerPointsModel::PLAN);
|
|
|
|
|
|
2020-11-25 06:31:19 +00:00
|
|
|
|
plannerWidget.setReplanButton(false);
|
2022-11-05 19:27:49 +00:00
|
|
|
|
plannerWidget.setupStartTime(timestampToDateTime(planned_dive->when)); // This will reload the profile!
|
|
|
|
|
}
|
2021-01-20 08:41:21 +00:00
|
|
|
|
|
2024-04-25 20:16:08 +00:00
|
|
|
|
void PlannerWidgets::prepareReplanDive(const dive *currentDive, int currentDcNr)
|
2022-11-05 19:27:49 +00:00
|
|
|
|
{
|
2024-04-25 20:16:08 +00:00
|
|
|
|
copy_dive(currentDive, planned_dive.get());
|
|
|
|
|
dcNr = currentDcNr;
|
2020-11-25 06:31:19 +00:00
|
|
|
|
}
|
|
|
|
|
|
2024-04-25 20:16:08 +00:00
|
|
|
|
void PlannerWidgets::replanDive()
|
2020-11-25 06:31:19 +00:00
|
|
|
|
{
|
|
|
|
|
DivePlannerPointsModel::instance()->setPlanMode(DivePlannerPointsModel::PLAN);
|
2024-04-25 20:16:08 +00:00
|
|
|
|
DivePlannerPointsModel::instance()->loadFromDive(planned_dive.get(), dcNr);
|
2020-11-25 06:31:19 +00:00
|
|
|
|
|
|
|
|
|
plannerWidget.setReplanButton(true);
|
2022-11-05 19:27:49 +00:00
|
|
|
|
plannerWidget.setupStartTime(timestampToDateTime(planned_dive->when));
|
|
|
|
|
if (planned_dive->surface_pressure.mbar)
|
|
|
|
|
plannerWidget.setSurfacePressure(planned_dive->surface_pressure.mbar);
|
|
|
|
|
if (planned_dive->salinity)
|
|
|
|
|
plannerWidget.setSalinity(planned_dive->salinity);
|
|
|
|
|
reset_cylinders(planned_dive.get(), true);
|
2024-04-25 20:16:08 +00:00
|
|
|
|
DivePlannerPointsModel::instance()->cylindersModel()->updateDive(planned_dive.get(), dcNr);
|
2022-11-05 19:27:49 +00:00
|
|
|
|
}
|
|
|
|
|
|
2020-11-25 06:31:19 +00:00
|
|
|
|
void PlannerWidgets::printDecoPlan()
|
|
|
|
|
{
|
|
|
|
|
#ifndef NO_PRINTING
|
2024-03-08 09:44:20 +00:00
|
|
|
|
std::string disclaimer = get_planner_disclaimer_formatted();
|
2020-11-25 06:31:19 +00:00
|
|
|
|
// Prepend a logo and a disclaimer to the plan.
|
|
|
|
|
// Save the old plan so that it can be restored at the end of the function.
|
|
|
|
|
QString origPlan = plannerDetails.divePlanOutput()->toHtml();
|
|
|
|
|
QString diveplan = QStringLiteral("<img height=50 src=\":subsurface-icon\"> ") +
|
2024-03-08 09:44:20 +00:00
|
|
|
|
QString::fromStdString(disclaimer) + origPlan;
|
2020-11-25 06:31:19 +00:00
|
|
|
|
|
|
|
|
|
QPrinter printer;
|
2021-05-06 11:01:02 +00:00
|
|
|
|
QPrintDialog dialog(&printer, MainWindow::instance());
|
|
|
|
|
dialog.setWindowTitle(tr("Print runtime table"));
|
|
|
|
|
if (dialog.exec() != QDialog::Accepted)
|
2020-11-25 06:31:19 +00:00
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
/* render the profile as a pixmap that is inserted as base64 data into a HTML <img> tag
|
|
|
|
|
* make it fit a page width defined by 2 cm margins via QTextDocument->print() (cannot be changed?)
|
|
|
|
|
* the height of the profile is 40% of the page height.
|
|
|
|
|
*/
|
|
|
|
|
QSizeF renderSize = printer.pageRect(QPrinter::Inch).size();
|
|
|
|
|
const qreal marginsInch = 1.57480315; // = (2 x 2cm) / 2.45cm/inch
|
|
|
|
|
renderSize.setWidth((renderSize.width() - marginsInch) * printer.resolution());
|
|
|
|
|
renderSize.setHeight(((renderSize.height() - marginsInch) * printer.resolution()) / 2.5);
|
|
|
|
|
|
|
|
|
|
QPixmap pixmap(renderSize.toSize());
|
|
|
|
|
QPainter painter(&pixmap);
|
|
|
|
|
painter.setRenderHint(QPainter::Antialiasing);
|
|
|
|
|
painter.setRenderHint(QPainter::SmoothPixmapTransform);
|
|
|
|
|
|
2021-08-04 05:27:41 +00:00
|
|
|
|
auto profile = std::make_unique<ProfileScene>(1.0, true, false);
|
2022-11-05 19:27:49 +00:00
|
|
|
|
profile->draw(&painter, QRect(0, 0, pixmap.width(), pixmap.height()), planned_dive.get(), 0, DivePlannerPointsModel::instance(), true);
|
2020-11-25 06:31:19 +00:00
|
|
|
|
|
|
|
|
|
QByteArray byteArray;
|
|
|
|
|
QBuffer buffer(&byteArray);
|
|
|
|
|
pixmap.save(&buffer, "PNG");
|
|
|
|
|
QString profileImage = QString("<img src=\"data:image/png;base64,") + byteArray.toBase64() + "\"/><br><br>";
|
|
|
|
|
diveplan = profileImage + diveplan;
|
|
|
|
|
|
|
|
|
|
plannerDetails.divePlanOutput()->setHtml(diveplan);
|
|
|
|
|
plannerDetails.divePlanOutput()->print(&printer);
|
|
|
|
|
plannerDetails.divePlanOutput()->setHtml(origPlan); // restore original plan
|
|
|
|
|
#endif
|
2015-02-09 18:37:26 +00:00
|
|
|
|
}
|