diff options
Diffstat (limited to 'qt-models')
-rw-r--r-- | qt-models/cylindermodel.cpp | 120 | ||||
-rw-r--r-- | qt-models/cylindermodel.h | 1 | ||||
-rw-r--r-- | qt-models/diveplannermodel.cpp | 45 | ||||
-rw-r--r-- | qt-models/diveplotdatamodel.cpp | 4 | ||||
-rw-r--r-- | qt-models/divetripmodel.cpp | 6 | ||||
-rw-r--r-- | qt-models/models.cpp | 6 |
6 files changed, 85 insertions, 97 deletions
diff --git a/qt-models/cylindermodel.cpp b/qt-models/cylindermodel.cpp index 3a2b6e536..f64cc213a 100644 --- a/qt-models/cylindermodel.cpp +++ b/qt-models/cylindermodel.cpp @@ -131,10 +131,10 @@ static QVariant percent_string(fraction_t fraction) QVariant CylindersModel::data(const QModelIndex &index, int role) const { - if (!index.isValid() || index.row() >= MAX_CYLINDERS) + if (!index.isValid() || index.row() >= rows) return QVariant(); - const cylinder_t *cyl = &displayed_dive.cylinder[index.row()]; + const cylinder_t *cyl = &displayed_dive.cylinders.cylinders[index.row()]; switch (role) { case Qt::BackgroundRole: { @@ -259,7 +259,7 @@ QVariant CylindersModel::data(const QModelIndex &index, int role) const cylinder_t *CylindersModel::cylinderAt(const QModelIndex &index) { - return &displayed_dive.cylinder[index.row()]; + return &displayed_dive.cylinders.cylinders[index.row()]; } // this is our magic 'pass data in' function that allows the delegate to get @@ -420,16 +420,14 @@ int CylindersModel::rowCount(const QModelIndex&) const void CylindersModel::add() { - if (rows >= MAX_CYLINDERS) { - return; - } - int row = rows; - fill_default_cylinder(&displayed_dive, row); - displayed_dive.cylinder[row].start = displayed_dive.cylinder[row].type.workingpressure; - displayed_dive.cylinder[row].manually_added = true; - displayed_dive.cylinder[row].cylinder_use = OC_GAS; + cylinder_t cyl = { 0 }; + fill_default_cylinder(&displayed_dive, &cyl); + cyl.start = cyl.type.workingpressure; + cyl.manually_added = true; + cyl.cylinder_use = OC_GAS; beginInsertRows(QModelIndex(), row, row); + add_to_cylinder_table(&displayed_dive.cylinders, row, cyl); rows++; changed = true; endInsertRows(); @@ -446,12 +444,12 @@ void CylindersModel::clear() static bool show_cylinder(struct dive *dive, int i) { - cylinder_t *cyl = dive->cylinder + i; - + if (i < 0 || i >= dive->cylinders.nr) + return false; if (is_cylinder_used(dive, i)) return true; - if (cylinder_none(cyl)) - return false; + + cylinder_t *cyl = dive->cylinders.cylinders + i; if (cyl->start.mbar || cyl->sample_start.mbar || cyl->end.mbar || cyl->sample_end.mbar) return true; @@ -467,34 +465,18 @@ static bool show_cylinder(struct dive *dive, int i) void CylindersModel::updateDive() { - clear(); - rows = 0; #ifdef DEBUG_CYL dump_cylinders(&displayed_dive, true); #endif - for (int i = 0; i < MAX_CYLINDERS; i++) { - if (show_cylinder(&displayed_dive, i)) - rows = i + 1; - } - if (rows > 0) { - beginInsertRows(QModelIndex(), 0, rows - 1); - endInsertRows(); - } -} - -void CylindersModel::copyFromDive(dive *d) -{ - if (!d) - return; + 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 < MAX_CYLINDERS; i++) { - if (show_cylinder(d, i)) - rows = i + 1; - } - if (rows > 0) { - beginInsertRows(QModelIndex(), 0, rows - 1); - endInsertRows(); + for (int i = 0; i < displayed_dive.cylinders.nr; ++i) { + if (show_cylinder(&displayed_dive, i)) + ++rows; } + endResetModel(); } Qt::ItemFlags CylindersModel::flags(const QModelIndex &index) const @@ -506,7 +488,6 @@ Qt::ItemFlags CylindersModel::flags(const QModelIndex &index) const void CylindersModel::remove(const QModelIndex &index) { - std::vector<int> mapping(MAX_CYLINDERS); if (index.column() == USE) { cylinder_t *cyl = cylinderAt(index); @@ -518,48 +499,53 @@ void CylindersModel::remove(const QModelIndex &index) dataChanged(index, index); return; } - if (index.column() != REMOVE) { + + if (index.column() != REMOVE) return; - } if ((in_planner() && DivePlannerPointsModel::instance()->tankInUse(index.row())) || (!in_planner() && is_cylinder_prot(&displayed_dive, index.row()))) return; - beginRemoveRows(QModelIndex(), index.row(), index.row()); // yah, know, ugly. + beginRemoveRows(QModelIndex(), index.row(), index.row()); rows--; - remove_cylinder(&displayed_dive, index.row()); - for (int i = 0; i < index.row(); i++) - mapping[i] = i; - // No mapping for removed gas, set to -1 + changed = true; + endRemoveRows(); + + // Create a mapping of cylinder indexes: + // 1) Fill mapping[0]..mapping[index-1] with 0..index + // 2) Set mapping[index] to -1 + // 3) Fill mapping[index+1]..mapping[end] with index.. + std::vector<int> mapping(displayed_dive.cylinders.nr + 1); + std::iota(mapping.begin(), mapping.begin() + index.row(), 0); mapping[index.row()] = -1; - for (int i = index.row() + 1; i < MAX_CYLINDERS; i++) - mapping[i] = i - 1; + std::iota(mapping.begin() + index.row() + 1, mapping.end(), index.row()); cylinder_renumber(&displayed_dive, &mapping[0]); if (in_planner()) DivePlannerPointsModel::instance()->cylinderRenumber(&mapping[0]); changed = true; - endRemoveRows(); - dataChanged(index, index); } void CylindersModel::moveAtFirst(int cylid) { - std::vector<int> mapping(MAX_CYLINDERS); cylinder_t temp_cyl; beginMoveRows(QModelIndex(), cylid, cylid, QModelIndex(), 0); - memmove(&temp_cyl, &displayed_dive.cylinder[cylid], sizeof(temp_cyl)); - for (int i = cylid - 1; i >= 0; i--) { - memmove(&displayed_dive.cylinder[i + 1], &displayed_dive.cylinder[i], sizeof(temp_cyl)); - mapping[i] = i + 1; - } - memmove(&displayed_dive.cylinder[0], &temp_cyl, sizeof(temp_cyl)); + memmove(&temp_cyl, &displayed_dive.cylinders.cylinders[cylid], sizeof(temp_cyl)); + for (int i = cylid - 1; i >= 0; i--) + memmove(&displayed_dive.cylinders.cylinders[i + 1], &displayed_dive.cylinders.cylinders[i], sizeof(temp_cyl)); + memmove(&displayed_dive.cylinders.cylinders[0], &temp_cyl, sizeof(temp_cyl)); + + // Create a mapping of cylinder indexes: + // 1) Fill mapping[0]..mapping[cyl] with 0..index + // 2) Set mapping[cyl] to 0 + // 3) Fill mapping[cyl+1]..mapping[end] with cyl.. + std::vector<int> mapping(displayed_dive.cylinders.nr); + std::iota(mapping.begin(), mapping.begin() + cylid, 1); mapping[cylid] = 0; - for (int i = cylid + 1; i < MAX_CYLINDERS; i++) - mapping[i] = i; + std::iota(mapping.begin() + (cylid + 1), mapping.end(), cylid); cylinder_renumber(&displayed_dive, &mapping[0]); if (in_planner()) DivePlannerPointsModel::instance()->cylinderRenumber(&mapping[0]); @@ -571,28 +557,28 @@ void CylindersModel::updateDecoDepths(pressure_t olddecopo2) { pressure_t decopo2; decopo2.mbar = prefs.decopo2; - for (int i = 0; i < MAX_CYLINDERS; i++) { - cylinder_t *cyl = &displayed_dive.cylinder[i]; + for (int i = 0; i < displayed_dive.cylinders.nr; i++) { + cylinder_t *cyl = &displayed_dive.cylinders.cylinders[i]; /* If the gas's deco MOD matches the old pO2, it will have been automatically calculated and should be updated. * If they don't match, we should leave the user entered depth as it is */ if (cyl->depth.mm == gas_mod(cyl->gasmix, olddecopo2, &displayed_dive, M_OR_FT(3, 10)).mm) { cyl->depth = gas_mod(cyl->gasmix, decopo2, &displayed_dive, M_OR_FT(3, 10)); } } - emit dataChanged(createIndex(0, 0), createIndex(MAX_CYLINDERS - 1, COLUMNS - 1)); + emit dataChanged(createIndex(0, 0), createIndex(displayed_dive.cylinders.nr - 1, COLUMNS - 1)); } void CylindersModel::updateTrashIcon() { - emit dataChanged(createIndex(0, 0), createIndex(MAX_CYLINDERS - 1, 0)); + emit dataChanged(createIndex(0, 0), createIndex(displayed_dive.cylinders.nr - 1, 0)); } bool CylindersModel::updateBestMixes() { // Check if any of the cylinders are best mixes, update if needed bool gasUpdated = false; - for (int i = 0; i < MAX_CYLINDERS; i++) { - cylinder_t *cyl = &displayed_dive.cylinder[i]; + for (int i = 0; i < displayed_dive.cylinders.nr; i++) { + cylinder_t *cyl = &displayed_dive.cylinders.cylinders[i]; if (cyl->bestmix_o2) { cyl->gasmix.o2 = best_o2(displayed_dive.maxdepth, &displayed_dive); // fO2 + fHe must not be greater than 1 @@ -614,7 +600,7 @@ bool CylindersModel::updateBestMixes() /* This slot is called when the bottom pO2 and END preferences are updated, we want to * emit dataChanged so MOD and MND are refreshed, even if the gas mix hasn't been changed */ if (gasUpdated) - emit dataChanged(createIndex(0, 0), createIndex(MAX_CYLINDERS - 1, COLUMNS - 1)); + emit dataChanged(createIndex(0, 0), createIndex(displayed_dive.cylinders.nr - 1, COLUMNS - 1)); return gasUpdated; } @@ -626,7 +612,7 @@ void CylindersModel::cylindersReset(const QVector<dive *> &dives) return; // Copy the cylinders from the current dive to the displayed dive. - copy_cylinders(current_dive, &displayed_dive, false); + copy_cylinders(¤t_dive->cylinders, &displayed_dive.cylinders); // And update the model.. updateDive(); diff --git a/qt-models/cylindermodel.h b/qt-models/cylindermodel.h index 58d11e971..0def53ba9 100644 --- a/qt-models/cylindermodel.h +++ b/qt-models/cylindermodel.h @@ -37,7 +37,6 @@ public: void add(); void clear(); void updateDive(); - void copyFromDive(struct dive *d); void updateDecoDepths(pressure_t olddecopo2); void updateTrashIcon(); void moveAtFirst(int cylid); diff --git a/qt-models/diveplannermodel.cpp b/qt-models/diveplannermodel.cpp index 537bf278f..8d19afcfb 100644 --- a/qt-models/diveplannermodel.cpp +++ b/qt-models/diveplannermodel.cpp @@ -152,29 +152,32 @@ void DivePlannerPointsModel::loadFromDive(dive *d) // setup the cylinder widget accordingly void DivePlannerPointsModel::setupCylinders() { - int i; + clear_cylinder_table(&displayed_dive.cylinders); if (mode == PLAN && current_dive) { // take the displayed cylinders from the selected dive as starting point - CylindersModel::instance()->copyFromDive(current_dive); - copy_cylinders(current_dive, &displayed_dive, !prefs.display_unused_tanks); + copy_used_cylinders(current_dive, &displayed_dive, !prefs.display_unused_tanks); reset_cylinders(&displayed_dive, true); - for (i = 0; i < MAX_CYLINDERS; i++) - if (!cylinder_none(&(displayed_dive.cylinder[i]))) - return; // We have at least one cylinder + if (displayed_dive.cylinders.nr > 0) { + CylindersModel::instance()->updateDive(); + return; // We have at least one cylinder + } } if (!empty_string(prefs.default_cylinder)) { - fill_default_cylinder(&displayed_dive, 0); - displayed_dive.cylinder[0].start = displayed_dive.cylinder[0].type.workingpressure; - } - if (cylinder_none(&displayed_dive.cylinder[0])) { + cylinder_t cyl = { 0 }; + fill_default_cylinder(&displayed_dive, &cyl); + cyl.start = cyl.type.workingpressure; + add_to_cylinder_table(&displayed_dive.cylinders, 0, cyl); + } else { + cylinder_t cyl = { 0 }; // roughly an AL80 - displayed_dive.cylinder[0].type.description = copy_qstring(tr("unknown")); - displayed_dive.cylinder[0].type.size.mliter = 11100; - displayed_dive.cylinder[0].type.workingpressure.mbar = 207000; + cyl.type.description = copy_qstring(tr("unknown")); + cyl.type.size.mliter = 11100; + cyl.type.workingpressure.mbar = 207000; + add_to_cylinder_table(&displayed_dive.cylinders, 0, cyl); } reset_cylinders(&displayed_dive, false); - CylindersModel::instance()->copyFromDive(&displayed_dive); + CylindersModel::instance()->updateDive(); } // Update the dive's maximum depth. Returns true if max. depth changed @@ -265,13 +268,13 @@ QVariant DivePlannerPointsModel::data(const QModelIndex &index, int role) const case GAS: /* Check if we have the same gasmix two or more times * If yes return more verbose string */ - int same_gas = same_gasmix_cylinder(&displayed_dive.cylinder[p.cylinderid], p.cylinderid, &displayed_dive, true); + int same_gas = same_gasmix_cylinder(&displayed_dive.cylinders.cylinders[p.cylinderid], p.cylinderid, &displayed_dive, true); if (same_gas == -1) - return get_gas_string(displayed_dive.cylinder[p.cylinderid].gasmix); + return get_gas_string(displayed_dive.cylinders.cylinders[p.cylinderid].gasmix); else - return get_gas_string(displayed_dive.cylinder[p.cylinderid].gasmix) + + return get_gas_string(displayed_dive.cylinders.cylinders[p.cylinderid].gasmix) + QString(" (%1 %2 ").arg(tr("cyl.")).arg(p.cylinderid + 1) + - displayed_dive.cylinder[p.cylinderid].type.description + ")"; + displayed_dive.cylinders.cylinders[p.cylinderid].type.description + ")"; } } else if (role == Qt::DecorationRole) { switch (index.column()) { @@ -333,7 +336,7 @@ bool DivePlannerPointsModel::setData(const QModelIndex &index, const QVariant &v p.setpoint = po2; } break; case GAS: - if (value.toInt() >= 0 && value.toInt() < MAX_CYLINDERS) + if (value.toInt() >= 0) p.cylinderid = value.toInt(); /* Did we change the start (dp 0) cylinder to another cylinderid than 0? */ if (value.toInt() != 0 && index.row() == 0) @@ -890,8 +893,8 @@ void DivePlannerPointsModel::createTemporaryPlan() // what does the cache do??? struct deco_state *cache = NULL; struct divedatapoint *dp = NULL; - for (int i = 0; i < MAX_CYLINDERS; i++) { - cylinder_t *cyl = &displayed_dive.cylinder[i]; + for (int i = 0; i < displayed_dive.cylinders.nr; i++) { + cylinder_t *cyl = &displayed_dive.cylinders.cylinders[i]; if (cyl->depth.mm && cyl->cylinder_use != NOT_USED) { dp = create_dp(0, cyl->depth.mm, i, 0); if (diveplan.dp) { diff --git a/qt-models/diveplotdatamodel.cpp b/qt-models/diveplotdatamodel.cpp index 164cd04a4..eed13c501 100644 --- a/qt-models/diveplotdatamodel.cpp +++ b/qt-models/diveplotdatamodel.cpp @@ -190,8 +190,8 @@ void DivePlotDataModel::setDive(dive *d, const plot_info &info) pInfo = info; pInfo.entry = (plot_data *)malloc(sizeof(plot_data) * pInfo.nr); memcpy(pInfo.entry, info.entry, sizeof(plot_data) * pInfo.nr); - pInfo.pressures = (plot_pressure_data *)malloc(sizeof(plot_pressure_data) * MAX_CYLINDERS * pInfo.nr); - memcpy(pInfo.pressures, info.pressures, sizeof(plot_pressure_data) * MAX_CYLINDERS * pInfo.nr); + pInfo.pressures = (plot_pressure_data *)malloc(sizeof(plot_pressure_data) * pInfo.nr_cylinders * pInfo.nr); + memcpy(pInfo.pressures, info.pressures, sizeof(plot_pressure_data) * pInfo.nr_cylinders * pInfo.nr); endResetModel(); } diff --git a/qt-models/divetripmodel.cpp b/qt-models/divetripmodel.cpp index 30ab2175b..220d122d4 100644 --- a/qt-models/divetripmodel.cpp +++ b/qt-models/divetripmodel.cpp @@ -157,7 +157,7 @@ QVariant DiveTripModelBase::diveData(const struct dive *d, int column, int role) case SUIT: return QString(d->suit); case CYLINDER: - return QString(d->cylinder[0].type.description); + return d->cylinders.nr > 0 ? QString(d->cylinders.cylinders[0].type.description) : QString(); case SAC: return displaySac(d, prefs.units.show_units_table); case OTU: @@ -1410,7 +1410,9 @@ bool DiveTripModelList::lessThan(const QModelIndex &i1, const QModelIndex &i2) c case SUIT: return lessThanHelper(strCmp(d1->suit, d2->suit), row_diff); case CYLINDER: - return lessThanHelper(strCmp(d1->cylinder[0].type.description, d2->cylinder[0].type.description), row_diff); + if (d1->cylinders.nr > 0 && d2->cylinders.nr > 0) + return lessThanHelper(strCmp(d1->cylinders.cylinders[0].type.description, d2->cylinders.cylinders[0].type.description), row_diff); + return d1->cylinders.nr - d2->cylinders.nr < 0; case GAS: return lessThanHelper(nitrox_sort_value(d1) - nitrox_sort_value(d2), row_diff); case SAC: diff --git a/qt-models/models.cpp b/qt-models/models.cpp index f6b3e927f..ab80f95f0 100644 --- a/qt-models/models.cpp +++ b/qt-models/models.cpp @@ -26,10 +26,8 @@ GasSelectionModel *GasSelectionModel::instance() static QStringList getGasList() { QStringList list; - for (int i = 0; i < MAX_CYLINDERS; i++) { - cylinder_t *cyl = &displayed_dive.cylinder[i]; - if (cylinder_nodata(cyl)) - break; + for (int i = 0; i < displayed_dive.cylinders.nr; i++) { + const cylinder_t *cyl = &displayed_dive.cylinders.cylinders[i]; /* Check if we have the same gasmix two or more times * If yes return more verbose string */ int same_gas = same_gasmix_cylinder(cyl, i, &displayed_dive, true); |