mirror of
https://github.com/subsurface/subsurface.git
synced 2024-12-03 15:43:09 +00:00
fe61f6b69e
Most tabs in the dive-information widget have there own translation units and ui-files. Only the equipment tab was married with the main tab. Move it out to get more reasonably sized translation units and some isolation. Currently, this needs ugly hacks when entering / checking for edit mode: Access to MainTab is via the MainWindow. And vice/versa, when accessing the DiveEquipmentTab from the MainTab, the former is hardcoded as the first item of an array. These hacks will soon be removed though, when making equipment editing undoable. The tabs will then be independent. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
260 lines
8.8 KiB
C++
260 lines
8.8 KiB
C++
// SPDX-License-Identifier: GPL-2.0
|
|
#include "TabDiveEquipment.h"
|
|
#include "maintab.h"
|
|
#include "desktop-widgets/mainwindow.h" // TODO: Only used temporarilly for edit mode changes
|
|
#include "desktop-widgets/simplewidgets.h" // For isGnome3Session()
|
|
#include "desktop-widgets/modeldelegates.h"
|
|
|
|
#include "profile-widget/profilewidget2.h"
|
|
|
|
#include "qt-models/cylindermodel.h"
|
|
#include "qt-models/weightmodel.h"
|
|
|
|
#include "core/divelist.h"
|
|
#include "core/subsurface-string.h"
|
|
|
|
#include <QSettings>
|
|
TabDiveEquipment::TabDiveEquipment(QWidget *parent) : TabBase(parent),
|
|
cylindersModel(new CylindersModel(this)),
|
|
weightModel(new WeightModel(this))
|
|
{
|
|
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(ui.cylinders->view(), &QTableView::clicked, this, &TabDiveEquipment::editCylinderWidget);
|
|
connect(ui.weights->view(), &QTableView::clicked, this, &TabDiveEquipment::editWeightWidget);
|
|
|
|
// Current display of things on Gnome3 looks like shit, so
|
|
// let's fix that.
|
|
if (isGnome3Session()) {
|
|
QPalette p;
|
|
p.setColor(QPalette::Window, QColor(Qt::white));
|
|
ui.scrollArea->viewport()->setPalette(p);
|
|
}
|
|
|
|
ui.cylinders->view()->setItemDelegateForColumn(CylindersModel::TYPE, new TankInfoDelegate(this));
|
|
ui.cylinders->view()->setItemDelegateForColumn(CylindersModel::USE, new TankUseDelegate(this));
|
|
ui.weights->view()->setItemDelegateForColumn(WeightModel::TYPE, new WSInfoDelegate(this));
|
|
ui.cylinders->view()->setColumnHidden(CylindersModel::DEPTH, 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);
|
|
|
|
QSettings s;
|
|
s.beginGroup("cylinders_dialog");
|
|
for (int i = 0; i < CylindersModel::COLUMNS; i++) {
|
|
if ((i == CylindersModel::REMOVE) || (i == CylindersModel::TYPE))
|
|
continue;
|
|
bool checked = s.value(QString("column%1_hidden").arg(i)).toBool();
|
|
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);
|
|
}
|
|
|
|
TabDiveEquipment::~TabDiveEquipment()
|
|
{
|
|
QSettings s;
|
|
s.beginGroup("cylinders_dialog");
|
|
for (int i = 0; i < CylindersModel::COLUMNS; i++) {
|
|
if ((i == CylindersModel::REMOVE) || (i == CylindersModel::TYPE))
|
|
continue;
|
|
s.setValue(QString("column%1_hidden").arg(i), ui.cylinders->view()->isColumnHidden(i));
|
|
}
|
|
}
|
|
|
|
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()
|
|
{
|
|
cylindersModel->updateDive();
|
|
weightModel->updateDive();
|
|
|
|
ui.cylinders->view()->hideColumn(CylindersModel::DEPTH);
|
|
if (get_dive_dc(&displayed_dive, dc_number)->divemode == CCR)
|
|
ui.cylinders->view()->showColumn(CylindersModel::USE);
|
|
else
|
|
ui.cylinders->view()->hideColumn(CylindersModel::USE);
|
|
}
|
|
|
|
void TabDiveEquipment::clear()
|
|
{
|
|
cylindersModel->clear();
|
|
weightModel->clear();
|
|
}
|
|
|
|
void TabDiveEquipment::addCylinder_clicked()
|
|
{
|
|
MainWindow::instance()->mainTab->enableEdition();
|
|
cylindersModel->add();
|
|
}
|
|
|
|
void TabDiveEquipment::addWeight_clicked()
|
|
{
|
|
MainWindow::instance()->mainTab->enableEdition();
|
|
weightModel->add();
|
|
}
|
|
|
|
void TabDiveEquipment::editCylinderWidget(const QModelIndex &index)
|
|
{
|
|
if (cylindersModel->changed && !MainWindow::instance()->mainTab->isEditing()) {
|
|
MainWindow::instance()->mainTab->enableEdition();
|
|
return;
|
|
}
|
|
if (index.isValid() && index.column() != CylindersModel::REMOVE) {
|
|
MainWindow::instance()->mainTab->enableEdition();
|
|
ui.cylinders->edit(index);
|
|
}
|
|
}
|
|
|
|
void TabDiveEquipment::editWeightWidget(const QModelIndex &index)
|
|
{
|
|
MainWindow::instance()->mainTab->enableEdition();
|
|
|
|
if (index.isValid() && index.column() != WeightModel::REMOVE)
|
|
ui.weights->edit(index);
|
|
}
|
|
|
|
// tricky little macro to edit all the selected dives
|
|
// loop ove all DIVES and do WHAT.
|
|
#define MODIFY_DIVES(DIVES, WHAT) \
|
|
do { \
|
|
for (dive *mydive: DIVES) { \
|
|
WHAT; \
|
|
} \
|
|
mark_divelist_changed(true); \
|
|
} while (0)
|
|
|
|
// Get the list of selected dives, but put the current dive at the last position of the vector
|
|
static QVector<dive *> getSelectedDivesCurrentLast()
|
|
{
|
|
QVector<dive *> res;
|
|
struct dive *d;
|
|
int i;
|
|
for_each_dive (i, d) {
|
|
if (d->selected && d != current_dive)
|
|
res.append(d);
|
|
}
|
|
res.append(current_dive);
|
|
return res;
|
|
}
|
|
|
|
void TabDiveEquipment::acceptChanges()
|
|
{
|
|
bool do_replot = false;
|
|
|
|
// now check if something has changed and if yes, edit the selected dives that
|
|
// were identical with the master dive shown (and mark the divelist as changed)
|
|
struct dive *cd = current_dive;
|
|
|
|
// Get list of selected dives, but put the current dive last;
|
|
// this is required in case the invocation wants to compare things
|
|
// to the original value in current_dive like it should
|
|
QVector<dive *> selectedDives = getSelectedDivesCurrentLast();
|
|
|
|
if (cylindersModel->changed) {
|
|
mark_divelist_changed(true);
|
|
MODIFY_DIVES(selectedDives,
|
|
for (int i = 0; i < MAX_CYLINDERS; i++) {
|
|
if (mydive != cd) {
|
|
if (same_string(mydive->cylinder[i].type.description, cd->cylinder[i].type.description)) {
|
|
// if we started out with the same cylinder description (for multi-edit) or if we do copt & paste
|
|
// make sure that we have the same cylinder type and copy the gasmix, but DON'T copy the start
|
|
// and end pressures (those are per dive after all)
|
|
if (!same_string(mydive->cylinder[i].type.description, displayed_dive.cylinder[i].type.description)) {
|
|
free((void*)mydive->cylinder[i].type.description);
|
|
mydive->cylinder[i].type.description = copy_string(displayed_dive.cylinder[i].type.description);
|
|
}
|
|
mydive->cylinder[i].type.size = displayed_dive.cylinder[i].type.size;
|
|
mydive->cylinder[i].type.workingpressure = displayed_dive.cylinder[i].type.workingpressure;
|
|
mydive->cylinder[i].gasmix = displayed_dive.cylinder[i].gasmix;
|
|
mydive->cylinder[i].cylinder_use = displayed_dive.cylinder[i].cylinder_use;
|
|
mydive->cylinder[i].depth = displayed_dive.cylinder[i].depth;
|
|
}
|
|
}
|
|
}
|
|
);
|
|
for (int i = 0; i < MAX_CYLINDERS; i++) {
|
|
// copy the cylinder but make sure we have our own copy of the strings
|
|
free((void*)cd->cylinder[i].type.description);
|
|
cd->cylinder[i] = displayed_dive.cylinder[i];
|
|
cd->cylinder[i].type.description = copy_string(displayed_dive.cylinder[i].type.description);
|
|
}
|
|
/* if cylinders changed we may have changed gas change events
|
|
* and sensor idx in samples as well
|
|
* - so far this is ONLY supported for a single selected dive */
|
|
struct divecomputer *tdc = ¤t_dive->dc;
|
|
struct divecomputer *sdc = &displayed_dive.dc;
|
|
while(tdc && sdc) {
|
|
free_events(tdc->events);
|
|
copy_events(sdc, tdc);
|
|
free(tdc->sample);
|
|
copy_samples(sdc, tdc);
|
|
tdc = tdc->next;
|
|
sdc = sdc->next;
|
|
}
|
|
do_replot = true;
|
|
}
|
|
|
|
if (weightModel->changed) {
|
|
mark_divelist_changed(true);
|
|
MODIFY_DIVES(selectedDives,
|
|
for (int i = 0; i < MAX_WEIGHTSYSTEMS; i++) {
|
|
if (mydive != cd && (same_string(mydive->weightsystem[i].description, cd->weightsystem[i].description))) {
|
|
mydive->weightsystem[i] = displayed_dive.weightsystem[i];
|
|
mydive->weightsystem[i].description = copy_string(displayed_dive.weightsystem[i].description);
|
|
}
|
|
}
|
|
);
|
|
for (int i = 0; i < MAX_WEIGHTSYSTEMS; i++) {
|
|
cd->weightsystem[i] = displayed_dive.weightsystem[i];
|
|
cd->weightsystem[i].description = copy_string(displayed_dive.weightsystem[i].description);
|
|
}
|
|
}
|
|
|
|
if (do_replot)
|
|
MainWindow::instance()->graphics->replot();
|
|
|
|
cylindersModel->changed = false;
|
|
weightModel->changed = false;
|
|
}
|
|
|
|
void TabDiveEquipment::rejectChanges()
|
|
{
|
|
cylindersModel->changed = false;
|
|
weightModel->changed = false;
|
|
cylindersModel->updateDive();
|
|
weightModel->updateDive();
|
|
}
|