subsurface/desktop-widgets/tab-widgets/TabDiveEquipment.cpp
Michael Keller 5fae7ce7a0 Equipment: Include Unused Tanks in Merge if Preference is Enabled.
Include unused tanks in merges of multiple logs into a single dive if
the 'Show unused cylinders' preference is enabled.
Also rename the preference (in code) to `include_unused_tanks` to
reflect the fact that it is already used in more places than just the
display (exporting, cloning dives).
Simplified the cylinder model to make forced inclusion of unused tanks
dependent on use of the model in planner.
Leaving the persisted name of the preference as `display_unused_tanks`
to avoid resetting this for all users - is there a good way to migrate
preference names?

Signed-off-by: Michael Keller <github@ike.ch>
2023-07-25 11:19:03 +12:00

223 lines
6.9 KiB
C++

// SPDX-License-Identifier: GPL-2.0
#include "TabDiveEquipment.h"
#include "maintab.h"
#include "desktop-widgets/modeldelegates.h"
#include "core/dive.h"
#include "core/selection.h"
#include "commands/command.h"
#include "qt-models/cylindermodel.h"
#include "qt-models/weightmodel.h"
#include <QMessageBox>
#include <QSettings>
#include <QCompleter>
static bool ignoreHiddenFlag(int i)
{
return i == CylindersModel::REMOVE || i == CylindersModel::TYPE ||
i == CylindersModel::WORKINGPRESS_INT || i == CylindersModel::SIZE_INT;
}
static bool hiddenByDefault(int i)
{
switch (i) {
case CylindersModel::SENSORS:
return true;
}
return false;
}
TabDiveEquipment::TabDiveEquipment(MainTab *parent) : TabBase(parent),
cylindersModel(new CylindersModel(false, this)),
weightModel(new WeightModel(this))
{
QCompleter *suitCompleter;
ui.setupUi(this);
// This makes sure we only delete the models
// after the destructor of the tables,
// this is needed to save the column sizes.
cylindersModel->setParent(ui.cylinders);
weightModel->setParent(ui.weights);
ui.cylinders->setModel(cylindersModel);
ui.weights->setModel(weightModel);
connect(&diveListNotifier, &DiveListNotifier::divesChanged, this, &TabDiveEquipment::divesChanged);
connect(ui.cylinders, &TableView::itemClicked, this, &TabDiveEquipment::editCylinderWidget);
connect(ui.weights, &TableView::itemClicked, this, &TabDiveEquipment::editWeightWidget);
connect(cylindersModel, &CylindersModel::divesEdited, this, &TabDiveEquipment::divesEdited);
connect(weightModel, &WeightModel::divesEdited, this, &TabDiveEquipment::divesEdited);
ui.cylinders->view()->setItemDelegateForColumn(CylindersModel::TYPE, &tankInfoDelegate);
ui.cylinders->view()->setItemDelegateForColumn(CylindersModel::USE, &tankUseDelegate);
ui.cylinders->view()->setItemDelegateForColumn(CylindersModel::SENSORS, &sensorDelegate);
ui.weights->view()->setItemDelegateForColumn(WeightModel::TYPE, &wsInfoDelegate);
ui.cylinders->view()->setColumnHidden(CylindersModel::DEPTH, true);
ui.cylinders->view()->setColumnHidden(CylindersModel::WORKINGPRESS_INT, true);
ui.cylinders->view()->setColumnHidden(CylindersModel::SIZE_INT, true);
ui.cylinders->setTitle(tr("Cylinders"));
ui.cylinders->setBtnToolTip(tr("Add cylinder"));
connect(ui.cylinders, &TableView::addButtonClicked, this, &TabDiveEquipment::addCylinder_clicked);
ui.weights->setTitle(tr("Weights"));
ui.weights->setBtnToolTip(tr("Add weight system"));
connect(ui.weights, &TableView::addButtonClicked, this, &TabDiveEquipment::addWeight_clicked);
QAction *action = new QAction(tr("OK"), this);
connect(action, &QAction::triggered, this, &TabDiveEquipment::closeWarning);
ui.multiDiveWarningMessage->addAction(action);
action = new QAction(tr("Undo"), this);
connect(action, &QAction::triggered, Command::undoAction(this), &QAction::trigger);
connect(action, &QAction::triggered, this, &TabDiveEquipment::closeWarning);
ui.multiDiveWarningMessage->addAction(action);
ui.multiDiveWarningMessage->hide();
QSettings s;
s.beginGroup("cylinders_dialog");
for (int i = 0; i < CylindersModel::COLUMNS; i++) {
if (ignoreHiddenFlag(i))
continue;
auto setting = s.value(QString("column%1_hidden").arg(i));
bool checked = setting.isValid() ? setting.toBool() : hiddenByDefault(i) ;
QAction *action = new QAction(cylindersModel->headerData(i, Qt::Horizontal, Qt::DisplayRole).toString(), ui.cylinders->view());
action->setCheckable(true);
action->setData(i);
action->setChecked(!checked);
connect(action, &QAction::triggered, this, &TabDiveEquipment::toggleTriggeredColumn);
ui.cylinders->view()->setColumnHidden(i, checked);
ui.cylinders->view()->horizontalHeader()->addAction(action);
}
ui.cylinders->view()->horizontalHeader()->setContextMenuPolicy(Qt::ActionsContextMenu);
ui.weights->view()->horizontalHeader()->setContextMenuPolicy(Qt::ActionsContextMenu);
suitCompleter = new QCompleter(&suitModel, ui.suit);
suitCompleter->setCaseSensitivity(Qt::CaseInsensitive);
ui.suit->setCompleter(suitCompleter);
}
TabDiveEquipment::~TabDiveEquipment()
{
QSettings s;
s.beginGroup("cylinders_dialog");
for (int i = 0; i < CylindersModel::COLUMNS; i++) {
if (ignoreHiddenFlag(i))
continue;
s.setValue(QString("column%1_hidden").arg(i), ui.cylinders->view()->isColumnHidden(i));
}
}
// This function gets called if a field gets updated by an undo command.
// Refresh the corresponding UI field.
void TabDiveEquipment::divesChanged(const QVector<dive *> &dives, DiveField field)
{
if (!parent.includesCurrentDive(dives))
return;
if (field.suit)
ui.suit->setText(QString(parent.currentDive->suit));
}
void TabDiveEquipment::toggleTriggeredColumn()
{
QAction *action = qobject_cast<QAction *>(sender());
int col = action->data().toInt();
QTableView *view = ui.cylinders->view();
if (action->isChecked()) {
view->showColumn(col);
if (view->columnWidth(col) <= 15)
view->setColumnWidth(col, 80);
} else {
view->hideColumn(col);
}
}
void TabDiveEquipment::updateData(const std::vector<dive *> &, dive *currentDive, int currentDC)
{
divecomputer *dc = get_dive_dc(currentDive, currentDC);
cylindersModel->updateDive(currentDive, currentDC);
weightModel->updateDive(currentDive);
sensorDelegate.setCurrentDC(dc);
tankUseDelegate.setCurrentDC(dc);
if (currentDive && currentDive->suit)
ui.suit->setText(QString(currentDive->suit));
else
ui.suit->clear();
}
void TabDiveEquipment::clear()
{
cylindersModel->clear();
weightModel->clear();
ui.suit->clear();
}
void TabDiveEquipment::addCylinder_clicked()
{
divesEdited(Command::addCylinder(false));
}
void TabDiveEquipment::addWeight_clicked()
{
divesEdited(Command::addWeight(false));
}
void TabDiveEquipment::editCylinderWidget(const QModelIndex &index)
{
if (!index.isValid())
return;
if (index.column() == CylindersModel::REMOVE) {
for (dive *d: getDiveSelection()) {
if (cylinder_with_sensor_sample(d, index.row())) {
if (QMessageBox::warning(this, tr("Remove cylinder?"),
tr("The deleted cylinder has sensor readings, which will be lost.\n"
"Do you want to continue?"),
QMessageBox::Yes|QMessageBox::No) != QMessageBox::Yes)
return;
}
}
divesEdited(Command::removeCylinder(index.row(), false));
} else {
ui.cylinders->edit(index);
}
}
void TabDiveEquipment::editWeightWidget(const QModelIndex &index)
{
if (!index.isValid())
return;
if (index.column() == WeightModel::REMOVE)
divesEdited(Command::removeWeight(index.row(), false));
else
ui.weights->edit(index);
}
void TabDiveEquipment::divesEdited(int i)
{
// No warning if only one dive was edited
if (i <= 1)
return;
ui.multiDiveWarningMessage->setCloseButtonVisible(false);
ui.multiDiveWarningMessage->setText(tr("Warning: edited %1 dives").arg(i));
ui.multiDiveWarningMessage->show();
}
void TabDiveEquipment::on_suit_editingFinished()
{
if (!parent.currentDive)
return;
divesEdited(Command::editSuit(ui.suit->text(), false));
}
void TabDiveEquipment::closeWarning()
{
ui.multiDiveWarningMessage->hide();
}