diff options
-rw-r--r-- | backend-shared/plannershared.cpp | 10 | ||||
-rw-r--r-- | desktop-widgets/diveplanner.cpp | 18 | ||||
-rw-r--r-- | desktop-widgets/mainwindow.cpp | 2 | ||||
-rw-r--r-- | desktop-widgets/modeldelegates.cpp | 6 | ||||
-rw-r--r-- | desktop-widgets/tab-widgets/TabDiveEquipment.cpp | 12 | ||||
-rw-r--r-- | desktop-widgets/tab-widgets/TabDiveEquipment.h | 4 | ||||
-rw-r--r-- | qt-models/cylindermodel.cpp | 113 | ||||
-rw-r--r-- | qt-models/cylindermodel.h | 25 | ||||
-rw-r--r-- | qt-models/diveplannermodel.cpp | 28 |
9 files changed, 140 insertions, 78 deletions
diff --git a/backend-shared/plannershared.cpp b/backend-shared/plannershared.cpp index 51f7a3a74..606dbb9d2 100644 --- a/backend-shared/plannershared.cpp +++ b/backend-shared/plannershared.cpp @@ -126,7 +126,7 @@ void PlannerShared::set_o2narcotic(bool value) { qPrefDivePlanner::set_o2narcotic(value); DivePlannerPointsModel::instance()->emitDataChanged(); - CylindersModel::instance()->updateBestMixes(); + CylindersModelFiltered::instance()->model()->updateBestMixes(); } double PlannerShared::bottompo2() @@ -136,7 +136,7 @@ double PlannerShared::bottompo2() void PlannerShared::set_bottompo2(double value) { qPrefDivePlanner::set_bottompo2((int) (value * 1000.0)); - CylindersModel::instance()->updateBestMixes(); + CylindersModelFiltered::instance()->model()->updateBestMixes(); } double PlannerShared::decopo2() @@ -148,8 +148,8 @@ void PlannerShared::set_decopo2(double value) pressure_t olddecopo2; olddecopo2.mbar = prefs.decopo2; qPrefDivePlanner::instance()->set_decopo2((int) (value * 1000.0)); - CylindersModel::instance()->updateDecoDepths(olddecopo2); - CylindersModel::instance()->updateBestMixes(); + CylindersModelFiltered::instance()->model()->updateDecoDepths(olddecopo2); + CylindersModelFiltered::instance()->model()->updateBestMixes(); } int PlannerShared::bestmixend() @@ -159,5 +159,5 @@ int PlannerShared::bestmixend() void PlannerShared::set_bestmixend(int value) { qPrefDivePlanner::set_bestmixend(units_to_depth(value).mm); - CylindersModel::instance()->updateBestMixes(); + CylindersModelFiltered::instance()->model()->updateBestMixes(); } diff --git a/desktop-widgets/diveplanner.cpp b/desktop-widgets/diveplanner.cpp index 8d3cbcbd4..d6fbbeb88 100644 --- a/desktop-widgets/diveplanner.cpp +++ b/desktop-widgets/diveplanner.cpp @@ -120,8 +120,8 @@ DivePlannerWidget::DivePlannerWidget(QWidget *parent, Qt::WindowFlags f) : QWidg ui.tableWidget->view()->setItemDelegateForColumn(DivePlannerPointsModel::DIVEMODE, new DiveTypesDelegate(this)); ui.cylinderTableWidget->setTitle(tr("Available gases")); ui.cylinderTableWidget->setBtnToolTip(tr("Add cylinder")); - ui.cylinderTableWidget->setModel(CylindersModel::instance()); - connect(ui.cylinderTableWidget, &TableView::itemClicked, CylindersModel::instance(), &CylindersModel::remove); + ui.cylinderTableWidget->setModel(CylindersModelFiltered::instance()); + connect(ui.cylinderTableWidget, &TableView::itemClicked, CylindersModelFiltered::instance(), &CylindersModelFiltered::remove); ui.waterType->setItemData(0, FRESHWATER_SALINITY); ui.waterType->setItemData(1, SEAWATER_SALINITY); ui.waterType->setItemData(2, EN13319_SALINITY); @@ -139,13 +139,13 @@ DivePlannerWidget::DivePlannerWidget(QWidget *parent, Qt::WindowFlags f) : QWidg // Continue to use old syntax, to avoid problems. connect(ui.tableWidget, SIGNAL(addButtonClicked()), plannerModel, SLOT(addStop())); - connect(CylindersModel::instance(), &CylindersModel::dataChanged, GasSelectionModel::instance(), &GasSelectionModel::repopulate); - connect(CylindersModel::instance(), &CylindersModel::rowsInserted, GasSelectionModel::instance(), &GasSelectionModel::repopulate); - connect(CylindersModel::instance(), &CylindersModel::rowsRemoved, GasSelectionModel::instance(), &GasSelectionModel::repopulate); - connect(CylindersModel::instance(), &CylindersModel::dataChanged, plannerModel, &DivePlannerPointsModel::emitDataChanged); - connect(CylindersModel::instance(), &CylindersModel::dataChanged, plannerModel, &DivePlannerPointsModel::cylinderModelEdited); - connect(CylindersModel::instance(), &CylindersModel::rowsInserted, plannerModel, &DivePlannerPointsModel::cylinderModelEdited); - connect(CylindersModel::instance(), &CylindersModel::rowsRemoved, plannerModel, &DivePlannerPointsModel::cylinderModelEdited); + connect(CylindersModelFiltered::instance(), &CylindersModelFiltered::dataChanged, GasSelectionModel::instance(), &GasSelectionModel::repopulate); + connect(CylindersModelFiltered::instance(), &CylindersModelFiltered::rowsInserted, GasSelectionModel::instance(), &GasSelectionModel::repopulate); + connect(CylindersModelFiltered::instance(), &CylindersModelFiltered::rowsRemoved, GasSelectionModel::instance(), &GasSelectionModel::repopulate); + connect(CylindersModelFiltered::instance(), &CylindersModelFiltered::dataChanged, plannerModel, &DivePlannerPointsModel::emitDataChanged); + connect(CylindersModelFiltered::instance(), &CylindersModelFiltered::dataChanged, plannerModel, &DivePlannerPointsModel::cylinderModelEdited); + connect(CylindersModelFiltered::instance(), &CylindersModelFiltered::rowsInserted, plannerModel, &DivePlannerPointsModel::cylinderModelEdited); + connect(CylindersModelFiltered::instance(), &CylindersModelFiltered::rowsRemoved, plannerModel, &DivePlannerPointsModel::cylinderModelEdited); connect(plannerModel, &DivePlannerPointsModel::calculatedPlanNotes, MainWindow::instance(), &MainWindow::setPlanNotes); diff --git a/desktop-widgets/mainwindow.cpp b/desktop-widgets/mainwindow.cpp index b4db7028c..68c267e0d 100644 --- a/desktop-widgets/mainwindow.cpp +++ b/desktop-widgets/mainwindow.cpp @@ -918,7 +918,7 @@ void MainWindow::on_actionReplanDive_triggered() divePlannerWidget->setSalinity(current_dive->salinity); DivePlannerPointsModel::instance()->loadFromDive(current_dive); reset_cylinders(&displayed_dive, true); - CylindersModel::instance()->updateDive(); + CylindersModelFiltered::instance()->updateDive(); } void MainWindow::on_actionDivePlanner_triggered() diff --git a/desktop-widgets/modeldelegates.cpp b/desktop-widgets/modeldelegates.cpp index ae8755292..ed4833550 100644 --- a/desktop-widgets/modeldelegates.cpp +++ b/desktop-widgets/modeldelegates.cpp @@ -238,7 +238,7 @@ static struct RevertCylinderData { void TankInfoDelegate::setModelData(QWidget*, QAbstractItemModel*, const QModelIndex&) const { - CylindersModel *mymodel = qobject_cast<CylindersModel *>(currCombo.model); + CylindersModelFiltered *mymodel = qobject_cast<CylindersModelFiltered *>(currCombo.model); TankInfoModel *tanks = TankInfoModel::instance(); QModelIndexList matches = tanks->match(tanks->index(0, 0), Qt::DisplayRole, currCombo.activeText); int row; @@ -277,7 +277,7 @@ void TankInfoDelegate::editorClosed(QWidget*, QAbstractItemDelegate::EndEditHint { if (hint == QAbstractItemDelegate::NoHint || hint == QAbstractItemDelegate::RevertModelCache) { - CylindersModel *mymodel = qobject_cast<CylindersModel *>(currCombo.model); + CylindersModelFiltered *mymodel = qobject_cast<CylindersModelFiltered *>(currCombo.model); mymodel->setData(IDX(CylindersModel::TYPE), currCylinderData.type, Qt::EditRole); mymodel->passInData(IDX(CylindersModel::WORKINGPRESS), currCylinderData.pressure); mymodel->passInData(IDX(CylindersModel::SIZE), currCylinderData.size); @@ -289,7 +289,7 @@ QWidget *TankInfoDelegate::createEditor(QWidget *parent, const QStyleOptionViewI // ncreate editor needs to be called before because it will populate a few // things in the currCombo global var. QWidget *delegate = ComboBoxDelegate::createEditor(parent, option, index); - CylindersModel *mymodel = qobject_cast<CylindersModel *>(currCombo.model); + CylindersModelFiltered *mymodel = qobject_cast<CylindersModelFiltered *>(currCombo.model); cylinder_t *cyl = mymodel->cylinderAt(index); currCylinderData.type = cyl->type.description; currCylinderData.pressure = cyl->type.workingpressure.mbar; diff --git a/desktop-widgets/tab-widgets/TabDiveEquipment.cpp b/desktop-widgets/tab-widgets/TabDiveEquipment.cpp index f731631eb..0a5786e50 100644 --- a/desktop-widgets/tab-widgets/TabDiveEquipment.cpp +++ b/desktop-widgets/tab-widgets/TabDiveEquipment.cpp @@ -17,7 +17,7 @@ #include <QCompleter> TabDiveEquipment::TabDiveEquipment(QWidget *parent) : TabBase(parent), - cylindersModel(new CylindersModel(this)), + cylindersModel(new CylindersModelFiltered(this)), weightModel(new WeightModel(this)) { QCompleter *suitCompleter; @@ -33,7 +33,7 @@ TabDiveEquipment::TabDiveEquipment(QWidget *parent) : TabBase(parent), ui.weights->setModel(weightModel); connect(&diveListNotifier, &DiveListNotifier::divesChanged, this, &TabDiveEquipment::divesChanged); - connect(ui.cylinders, &TableView::itemClicked, cylindersModel, &CylindersModel::remove); + connect(ui.cylinders, &TableView::itemClicked, cylindersModel, &CylindersModelFiltered::remove); connect(ui.cylinders, &TableView::itemClicked, this, &TabDiveEquipment::editCylinderWidget); connect(ui.weights, &TableView::itemClicked, this, &TabDiveEquipment::editWeightWidget); @@ -164,7 +164,7 @@ void TabDiveEquipment::addWeight_clicked() void TabDiveEquipment::editCylinderWidget(const QModelIndex &index) { - if (cylindersModel->changed && !MainWindow::instance()->mainTab->isEditing()) { + if (cylindersModel->model()->changed && !MainWindow::instance()->mainTab->isEditing()) { MainWindow::instance()->mainTab->enableEdition(); return; } @@ -228,7 +228,7 @@ void TabDiveEquipment::acceptChanges() // to the original value in current_dive like it should QVector<dive *> selectedDives = getSelectedDivesCurrentLast(); - if (cylindersModel->changed) { + if (cylindersModel->model()->changed) { mark_divelist_changed(true); MODIFY_DIVES(selectedDives, // if we started out with the same cylinder description (for multi-edit) or if we do copt & paste @@ -257,12 +257,12 @@ void TabDiveEquipment::acceptChanges() if (do_replot) MainWindow::instance()->graphics->replot(); - cylindersModel->changed = false; + cylindersModel->model()->changed = false; } void TabDiveEquipment::rejectChanges() { - cylindersModel->changed = false; + cylindersModel->model()->changed = false; cylindersModel->updateDive(); weightModel->updateDive(current_dive); } diff --git a/desktop-widgets/tab-widgets/TabDiveEquipment.h b/desktop-widgets/tab-widgets/TabDiveEquipment.h index 1edc20cef..28e6235d1 100644 --- a/desktop-widgets/tab-widgets/TabDiveEquipment.h +++ b/desktop-widgets/tab-widgets/TabDiveEquipment.h @@ -12,7 +12,7 @@ namespace Ui { }; class WeightModel; -class CylindersModel; +class CylindersModelFiltered; class TabDiveEquipment : public TabBase { Q_OBJECT @@ -38,7 +38,7 @@ private slots: private: Ui::TabDiveEquipment ui; SuitCompletionModel suitModel; - CylindersModel *cylindersModel; + CylindersModelFiltered *cylindersModel; WeightModel *weightModel; }; diff --git a/qt-models/cylindermodel.cpp b/qt-models/cylindermodel.cpp index b1d744c27..c5a0d2272 100644 --- a/qt-models/cylindermodel.cpp +++ b/qt-models/cylindermodel.cpp @@ -14,9 +14,9 @@ CylindersModel::CylindersModel(QObject *parent) : changed(false), rows(0) { - // enum {REMOVE, TYPE, SIZE, WORKINGPRESS, START, END, O2, HE, DEPTH, MOD, MND, USE}; + // enum {REMOVE, TYPE, SIZE, WORKINGPRESS, START, END, O2, HE, DEPTH, MOD, MND, USE, IS_USED}; setHeaderDataStrings(QStringList() << "" << tr("Type") << tr("Size") << tr("Work press.") << tr("Start press.") << tr("End press.") << tr("O₂%") << tr("He%") - << tr("Deco switch at") <<tr("Bot. MOD") <<tr("MND") << tr("Use")); + << tr("Deco switch at") <<tr("Bot. MOD") <<tr("MND") << tr("Use") << "Is used"); connect(&diveListNotifier, &DiveListNotifier::cylindersReset, this, &CylindersModel::cylindersReset); } @@ -29,12 +29,6 @@ QVariant CylindersModel::headerData(int section, Qt::Orientation orientation, in return CleanerTableModel::headerData(section, orientation, role); } -CylindersModel *CylindersModel::instance() -{ - static CylindersModel self; - return &self; -} - static QString get_cylinder_string(const cylinder_t *cyl) { QString unit; @@ -129,6 +123,28 @@ static QVariant percent_string(fraction_t fraction) return QString("%L1%").arg(permille / 10.0, 0, 'f', 1); } +bool CylindersModel::cylinderUsed(int i) const +{ + const struct dive *dive = &displayed_dive; + if (i < 0 || i >= dive->cylinders.nr) + return false; + if (is_cylinder_used(dive, i)) + return true; + + cylinder_t *cyl = get_cylinder(dive, i); + if (cyl->start.mbar || cyl->sample_start.mbar || + cyl->end.mbar || cyl->sample_end.mbar) + return true; + if (cyl->manually_added) + return true; + + /* + * The cylinder has some data, but none of it is very interesting, + * it has no pressures and no gas switches. Do we want to show it? + */ + return false; +} + QVariant CylindersModel::data(const QModelIndex &index, int role) const { if (!index.isValid() || index.row() >= rows) @@ -447,40 +463,13 @@ void CylindersModel::clear() } } -static bool show_cylinder(struct dive *dive, int i) -{ - if (i < 0 || i >= dive->cylinders.nr) - return false; - if (is_cylinder_used(dive, i)) - return true; - - cylinder_t *cyl = get_cylinder(dive, i); - if (cyl->start.mbar || cyl->sample_start.mbar || - cyl->end.mbar || cyl->sample_end.mbar) - return true; - if (cyl->manually_added) - return true; - - /* - * The cylinder has some data, but none of it is very interesting, - * it has no pressures and no gas switches. Do we want to show it? - */ - return prefs.display_unused_tanks; -} - void CylindersModel::updateDive() { #ifdef DEBUG_CYL dump_cylinders(&displayed_dive, true); #endif beginResetModel(); - // TODO: this is fundamentally broken - it assumes that unused cylinders are at - // the end. Fix by using a QSortFilterProxyModel. - rows = 0; - for (int i = 0; i < displayed_dive.cylinders.nr; ++i) { - if (show_cylinder(&displayed_dive, i)) - ++rows; - } + rows = displayed_dive.cylinders.nr; endResetModel(); } @@ -493,7 +482,6 @@ Qt::ItemFlags CylindersModel::flags(const QModelIndex &index) const void CylindersModel::remove(QModelIndex index) { - if (index.column() == USE) { cylinder_t *cyl = cylinderAt(index); if (cyl->cylinder_use == OC_GAS) @@ -622,3 +610,54 @@ void CylindersModel::cylindersReset(const QVector<dive *> &dives) // And update the model.. updateDive(); } + +CylindersModelFiltered *CylindersModelFiltered::instance() +{ + static CylindersModelFiltered self; + return &self; +} + +CylindersModelFiltered::CylindersModelFiltered(QObject *parent) : QSortFilterProxyModel(parent) +{ + setSourceModel(&source); +} + +void CylindersModelFiltered::updateDive() +{ + source.updateDive(); +} + +void CylindersModelFiltered::clear() +{ + source.clear(); +} + +void CylindersModelFiltered::add() +{ + source.add(); +} + +CylindersModel *CylindersModelFiltered::model() +{ + return &source; +} + +void CylindersModelFiltered::remove(QModelIndex index) +{ + source.remove(mapToSource(index)); +} + +void CylindersModelFiltered::passInData(const QModelIndex &index, const QVariant &value) +{ + source.passInData(mapToSource(index), value); +} + +cylinder_t *CylindersModelFiltered::cylinderAt(const QModelIndex &index) +{ + return source.cylinderAt(mapToSource(index)); +} + +bool CylindersModelFiltered::filterAcceptsRow(int source_row, const QModelIndex &source_parent) const +{ + return prefs.display_unused_tanks || source.cylinderUsed(source_row); +} diff --git a/qt-models/cylindermodel.h b/qt-models/cylindermodel.h index 9f9abc836..66f51acca 100644 --- a/qt-models/cylindermodel.h +++ b/qt-models/cylindermodel.h @@ -2,6 +2,8 @@ #ifndef CYLINDERMODEL_H #define CYLINDERMODEL_H +#include <QSortFilterProxyModel> + #include "cleanertablemodel.h" #include "core/dive.h" @@ -27,7 +29,6 @@ public: }; explicit CylindersModel(QObject *parent = 0); - static CylindersModel *instance(); QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; int rowCount(const QModelIndex &parent = QModelIndex()) const override; Qt::ItemFlags flags(const QModelIndex &index) const override; @@ -44,6 +45,7 @@ public: bool changed; QVariant headerData(int section, Qt::Orientation orientation, int role) const override; bool updateBestMixes(); + bool cylinderUsed(int i) const; public slots: @@ -54,4 +56,25 @@ private: int rows; }; +// Cylinder model that hides unused cylinders if the pref.show_unused_cylinders flag is not set +class CylindersModelFiltered : public QSortFilterProxyModel { + Q_OBJECT +public: + CylindersModelFiltered(QObject *parent = 0); + static CylindersModelFiltered *instance(); + CylindersModel *model(); // Access to unfiltered base model + + void clear(); + void add(); + void updateDive(); + cylinder_t *cylinderAt(const QModelIndex &index); + void passInData(const QModelIndex &index, const QVariant &value); +public +slots: + void remove(QModelIndex index); +private: + CylindersModel source; + bool filterAcceptsRow(int source_row, const QModelIndex &source_parent) const override; +}; + #endif diff --git a/qt-models/diveplannermodel.cpp b/qt-models/diveplannermodel.cpp index 65773e13c..3d3f1d0bc 100644 --- a/qt-models/diveplannermodel.cpp +++ b/qt-models/diveplannermodel.cpp @@ -37,7 +37,7 @@ void DivePlannerPointsModel::removeSelectedPoints(const QVector<int> &rows) divepoints.remove(v2[i]); } endRemoveRows(); - CylindersModel::instance()->updateTrashIcon(); + CylindersModelFiltered::instance()->model()->updateTrashIcon(); } void DivePlannerPointsModel::createSimpleDive() @@ -89,7 +89,7 @@ void DivePlannerPointsModel::loadFromDive(dive *d) const struct event *evd = NULL; enum divemode_t current_divemode = UNDEF_COMP_TYPE; recalc = false; - CylindersModel::instance()->updateDive(); + CylindersModelFiltered::instance()->updateDive(); duration_t lasttime = { 0 }; duration_t lastrecordedtime = {}; duration_t newtime = {}; @@ -162,7 +162,7 @@ void DivePlannerPointsModel::setupCylinders() reset_cylinders(&displayed_dive, true); if (displayed_dive.cylinders.nr > 0) { - CylindersModel::instance()->updateDive(); + CylindersModelFiltered::instance()->updateDive(); return; // We have at least one cylinder } } @@ -180,7 +180,7 @@ void DivePlannerPointsModel::setupCylinders() add_to_cylinder_table(&displayed_dive.cylinders, 0, cyl); } reset_cylinders(&displayed_dive, false); - CylindersModel::instance()->updateDive(); + CylindersModelFiltered::instance()->updateDive(); } // Update the dive's maximum depth. Returns true if max. depth changed @@ -209,7 +209,7 @@ void DivePlannerPointsModel::removeDeco() void DivePlannerPointsModel::addCylinder_clicked() { - CylindersModel::instance()->add(); + CylindersModelFiltered::instance()->add(); } @@ -317,7 +317,7 @@ bool DivePlannerPointsModel::setData(const QModelIndex &index, const QVariant &v if (value.toInt() >= 0) { p.depth = units_to_depth(value.toInt()); if (updateMaxDepth()) - CylindersModel::instance()->updateBestMixes(); + CylindersModelFiltered::instance()->model()->updateBestMixes(); } break; case RUNTIME: @@ -343,8 +343,8 @@ bool DivePlannerPointsModel::setData(const QModelIndex &index, const QVariant &v p.cylinderid = value.toInt(); /* Did we change the start (dp 0) cylinder to another cylinderid than 0? */ if (value.toInt() != 0 && index.row() == 0) - CylindersModel::instance()->moveAtFirst(value.toInt()); - CylindersModel::instance()->updateTrashIcon(); + CylindersModelFiltered::instance()->model()->moveAtFirst(value.toInt()); + CylindersModelFiltered::instance()->model()->updateTrashIcon(); break; case DIVEMODE: if (value.toInt() < FREEDIVE) { @@ -799,9 +799,9 @@ void DivePlannerPointsModel::editStop(int row, divedatapoint newData) divepoints[row] = newData; std::sort(divepoints.begin(), divepoints.end(), divePointsLessThan); if (updateMaxDepth()) - CylindersModel::instance()->updateBestMixes(); + CylindersModelFiltered::instance()->model()->updateBestMixes(); if (divepoints[0].cylinderid != old_first_cylid) - CylindersModel::instance()->moveAtFirst(divepoints[0].cylinderid); + CylindersModelFiltered::instance()->model()->moveAtFirst(divepoints[0].cylinderid); emitDataChanged(); } @@ -850,9 +850,9 @@ void DivePlannerPointsModel::remove(const QModelIndex &index) divepoints.remove(index.row()); } endRemoveRows(); - CylindersModel::instance()->updateTrashIcon(); + CylindersModelFiltered::instance()->model()->updateTrashIcon(); if (divepoints[0].cylinderid != old_first_cylid) - CylindersModel::instance()->moveAtFirst(divepoints[0].cylinderid); + CylindersModelFiltered::instance()->model()->moveAtFirst(divepoints[0].cylinderid); } struct diveplan &DivePlannerPointsModel::getDiveplan() @@ -907,13 +907,13 @@ void DivePlannerPointsModel::clear() { bool oldRecalc = setRecalc(false); - CylindersModel::instance()->updateDive(); + CylindersModelFiltered::instance()->updateDive(); if (rowCount() > 0) { beginRemoveRows(QModelIndex(), 0, rowCount() - 1); divepoints.clear(); endRemoveRows(); } - CylindersModel::instance()->clear(); + CylindersModelFiltered::instance()->clear(); setRecalc(oldRecalc); } |