mirror of
https://github.com/subsurface/subsurface.git
synced 2025-02-19 22:16:15 +00:00
Merge branch 'addDiveGasFix'
This commit is contained in:
commit
487efb1ee9
8 changed files with 113 additions and 68 deletions
14
dive.c
14
dive.c
|
@ -195,6 +195,20 @@ struct dive *alloc_dive(void)
|
||||||
return dive;
|
return dive;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* only copies events from the first dive computer */
|
||||||
|
void copy_events(struct dive *s, struct dive *d)
|
||||||
|
{
|
||||||
|
struct event *ev;
|
||||||
|
if (!s || !d)
|
||||||
|
return;
|
||||||
|
ev = s->dc.events;
|
||||||
|
d->dc.events = NULL;
|
||||||
|
while (ev != NULL) {
|
||||||
|
add_event(&d->dc, ev->time.seconds, ev->type, ev->flags, ev->value, ev->name);
|
||||||
|
ev = ev->next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void copy_cylinders(struct dive *s, struct dive *d)
|
void copy_cylinders(struct dive *s, struct dive *d)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
1
dive.h
1
dive.h
|
@ -653,6 +653,7 @@ extern unsigned int dc_airtemp(struct divecomputer *dc);
|
||||||
extern struct dive *merge_dives(struct dive *a, struct dive *b, int offset, bool prefer_downloaded);
|
extern struct dive *merge_dives(struct dive *a, struct dive *b, int offset, bool prefer_downloaded);
|
||||||
extern struct dive *try_to_merge(struct dive *a, struct dive *b, bool prefer_downloaded);
|
extern struct dive *try_to_merge(struct dive *a, struct dive *b, bool prefer_downloaded);
|
||||||
extern void renumber_dives(int nr);
|
extern void renumber_dives(int nr);
|
||||||
|
extern void copy_events(struct dive *s, struct dive *d);
|
||||||
extern void copy_cylinders(struct dive *s, struct dive *d);
|
extern void copy_cylinders(struct dive *s, struct dive *d);
|
||||||
extern void copy_samples(struct dive *s, struct dive *d);
|
extern void copy_samples(struct dive *s, struct dive *d);
|
||||||
|
|
||||||
|
|
|
@ -233,6 +233,7 @@ struct dive *create_dive_from_plan(struct diveplan *diveplan, const char **error
|
||||||
int time = dp->time;
|
int time = dp->time;
|
||||||
int depth = dp->depth;
|
int depth = dp->depth;
|
||||||
|
|
||||||
|
#if 0 // the new planner doesn't use that any more
|
||||||
if (time == 0) {
|
if (time == 0) {
|
||||||
/* special entries that just inform the algorithm about
|
/* special entries that just inform the algorithm about
|
||||||
* additional gases that are available */
|
* additional gases that are available */
|
||||||
|
@ -241,6 +242,7 @@ struct dive *create_dive_from_plan(struct diveplan *diveplan, const char **error
|
||||||
dp = dp->next;
|
dp = dp->next;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
if (!o2 && !he) {
|
if (!o2 && !he) {
|
||||||
o2 = oldo2;
|
o2 = oldo2;
|
||||||
he = oldhe;
|
he = oldhe;
|
||||||
|
@ -256,14 +258,14 @@ struct dive *create_dive_from_plan(struct diveplan *diveplan, const char **error
|
||||||
/* Create new gas, and gas change event if necessary;
|
/* Create new gas, and gas change event if necessary;
|
||||||
* Sadly, we inherited our gaschange event from libdivecomputer which only
|
* Sadly, we inherited our gaschange event from libdivecomputer which only
|
||||||
* support percentage values, so round the entries */
|
* support percentage values, so round the entries */
|
||||||
if (o2 != oldo2 || he != oldhe) {
|
if (time == 0 || o2 != oldo2 || he != oldhe) {
|
||||||
int plano2 = (o2 + 5) / 10 * 10;
|
int plano2 = (o2 + 5) / 10 * 10;
|
||||||
int planhe = (he + 5) / 10 * 10;
|
int planhe = (he + 5) / 10 * 10;
|
||||||
int value;
|
int value;
|
||||||
if (add_gas(dive, plano2, planhe) < 0)
|
if (add_gas(dive, plano2, planhe) < 0)
|
||||||
goto gas_error_exit;
|
goto gas_error_exit;
|
||||||
value = (plano2 / 10) | ((planhe / 10) << 16);
|
value = (plano2 / 10) | ((planhe / 10) << 16);
|
||||||
add_event(dc, lasttime, 25, 0, value, "gaschange"); // SAMPLE_EVENT_GASCHANGE2
|
add_event(dc, time, 25, 0, value, "gaschange"); // SAMPLE_EVENT_GASCHANGE2
|
||||||
oldo2 = o2; oldhe = he;
|
oldo2 = o2; oldhe = he;
|
||||||
}
|
}
|
||||||
/* Create sample */
|
/* Create sample */
|
||||||
|
@ -614,6 +616,7 @@ void plan(struct diveplan *diveplan, char **cached_datap, struct dive **divep, b
|
||||||
for (stopidx = 0; stopidx < sizeof(decostoplevels) / sizeof(int); stopidx++)
|
for (stopidx = 0; stopidx < sizeof(decostoplevels) / sizeof(int); stopidx++)
|
||||||
if (decostoplevels[stopidx] >= depth)
|
if (decostoplevels[stopidx] >= depth)
|
||||||
break;
|
break;
|
||||||
|
if (stopidx > 0)
|
||||||
stopidx--;
|
stopidx--;
|
||||||
|
|
||||||
/* so now we know the first decostop level above us
|
/* so now we know the first decostop level above us
|
||||||
|
|
|
@ -11,6 +11,7 @@ extern int validate_po2(const char *text, int *mbar_po2);
|
||||||
extern timestamp_t current_time_notz(void);
|
extern timestamp_t current_time_notz(void);
|
||||||
extern void show_planned_dive(char **error_string_p);
|
extern void show_planned_dive(char **error_string_p);
|
||||||
extern void set_last_stop(bool last_stop_6m);
|
extern void set_last_stop(bool last_stop_6m);
|
||||||
|
extern void get_gas_from_events(struct divecomputer *dc, int time, int *o2, int *he);
|
||||||
|
|
||||||
extern struct diveplan diveplan;
|
extern struct diveplan diveplan;
|
||||||
extern struct dive *planned_dive;
|
extern struct dive *planned_dive;
|
||||||
|
|
|
@ -41,7 +41,7 @@ QStringListModel *airTypes() {
|
||||||
}
|
}
|
||||||
|
|
||||||
QString strForAir(const divedatapoint& p) {
|
QString strForAir(const divedatapoint& p) {
|
||||||
return p.o2 == 209 ? QObject::tr("AIR")
|
return is_air(p.o2, p.he) ? QObject::tr("AIR")
|
||||||
: p.o2 == 320 ? QObject::tr("EAN32")
|
: p.o2 == 320 ? QObject::tr("EAN32")
|
||||||
: p.o2 == 360 ? QObject::tr("EAN36")
|
: p.o2 == 360 ? QObject::tr("EAN36")
|
||||||
: QObject::tr("Choose Gas");
|
: QObject::tr("Choose Gas");
|
||||||
|
@ -412,17 +412,16 @@ void DivePlannerGraphics::mouseDoubleClickEvent(QMouseEvent* event)
|
||||||
|
|
||||||
int minutes = rint(timeLine->valueAt(mappedPos));
|
int minutes = rint(timeLine->valueAt(mappedPos));
|
||||||
int milimeters = rint(depthLine->valueAt(mappedPos) / M_OR_FT(1,1)) * M_OR_FT(1,1);
|
int milimeters = rint(depthLine->valueAt(mappedPos) / M_OR_FT(1,1)) * M_OR_FT(1,1);
|
||||||
plannerModel->addStop(milimeters, minutes * 60, tr("Air"), 0);
|
plannerModel->addStop(milimeters, minutes * 60, O2_IN_AIR, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DivePlannerPointsModel::createSimpleDive()
|
void DivePlannerPointsModel::createSimpleDive()
|
||||||
{
|
{
|
||||||
plannerModel->addStop(M_OR_FT(15,45), 1 * 60, tr("Air"), 0);
|
plannerModel->addStop(0, 0, O2_IN_AIR, 0, 0);
|
||||||
plannerModel->addStop(M_OR_FT(15,45), 40 * 60, tr("Air"), 0);
|
plannerModel->addStop(M_OR_FT(15,45), 1 * 60, O2_IN_AIR, 0, 0);
|
||||||
// plannerModel->addStop(9000, 26 * 60, tr("Air"), 0);
|
plannerModel->addStop(M_OR_FT(15,45), 40 * 60, O2_IN_AIR, 0, 0);
|
||||||
// plannerModel->addStop(9000, 41 * 60, tr("Air"), 0);
|
plannerModel->addStop(M_OR_FT(5,15), 42 * 60, O2_IN_AIR, 0, 0);
|
||||||
plannerModel->addStop(M_OR_FT(5,15), 42 * 60, tr("Air"), 0);
|
plannerModel->addStop(M_OR_FT(5,15), 45 * 60, O2_IN_AIR, 0, 0);
|
||||||
plannerModel->addStop(M_OR_FT(5,15), 45 * 60, tr("Air"), 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void DivePlannerPointsModel::loadFromDive(dive* d)
|
void DivePlannerPointsModel::loadFromDive(dive* d)
|
||||||
|
@ -431,14 +430,22 @@ void DivePlannerPointsModel::loadFromDive(dive* d)
|
||||||
* as soon as the model is modified, it will
|
* as soon as the model is modified, it will
|
||||||
* remove all samples from the current dive.
|
* remove all samples from the current dive.
|
||||||
* */
|
* */
|
||||||
|
struct dive *backupDive = alloc_dive();
|
||||||
|
backupDive->when = current_dive->when; // do we need anything else?
|
||||||
|
copy_samples(current_dive, backupDive);
|
||||||
|
copy_cylinders(current_dive, backupDive);
|
||||||
|
copy_events(current_dive, backupDive);
|
||||||
backupSamples.clear();
|
backupSamples.clear();
|
||||||
for(int i = 1; i < d->dc.samples-1; i++){
|
for(int i = 0; i < d->dc.samples-1; i++){
|
||||||
backupSamples.push_back( d->dc.sample[i]);
|
backupSamples.push_back( d->dc.sample[i]);
|
||||||
}
|
}
|
||||||
|
save_dive(stdout, current_dive);
|
||||||
|
save_dive(stdout, backupDive);
|
||||||
Q_FOREACH(const sample &s, backupSamples){
|
Q_FOREACH(const sample &s, backupSamples){
|
||||||
// we need to use the correct gas
|
int o2 = 0, he = 0;
|
||||||
plannerModel->addStop(s.depth.mm, s.time.seconds, tr("Air"), 0);
|
get_gas_from_events(&backupDive->dc, s.time.seconds, &o2, &he);
|
||||||
|
qDebug() << "time / depth" << s.time.seconds << s.depth.mm << "o2/he" << o2 << he;
|
||||||
|
plannerModel->addStop(s.depth.mm, s.time.seconds, o2, he, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -466,6 +473,10 @@ void DivePlannerGraphics::drawProfile()
|
||||||
plannerModel->createTemporaryPlan();
|
plannerModel->createTemporaryPlan();
|
||||||
struct diveplan diveplan = plannerModel->getDiveplan();
|
struct diveplan diveplan = plannerModel->getDiveplan();
|
||||||
struct divedatapoint *dp = diveplan.dp;
|
struct divedatapoint *dp = diveplan.dp;
|
||||||
|
if (!dp) {
|
||||||
|
plannerModel->deleteTemporaryPlan();
|
||||||
|
return;
|
||||||
|
}
|
||||||
while(dp->next)
|
while(dp->next)
|
||||||
dp = dp->next;
|
dp = dp->next;
|
||||||
|
|
||||||
|
@ -476,16 +487,16 @@ void DivePlannerGraphics::drawProfile()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Re-position the user generated dive handlers
|
// Re-position the user generated dive handlers
|
||||||
for (int i = 0; i < plannerModel->rowCount(); i++) {
|
for (int i = 1; i < plannerModel->rowCount(); i++) {
|
||||||
divedatapoint dp = plannerModel->at(i);
|
divedatapoint dp = plannerModel->at(i);
|
||||||
DiveHandler *h = handles.at(i);
|
DiveHandler *h = handles.at(i);
|
||||||
h->setPos(timeLine->posAtValue(dp.time / 60), depthLine->posAtValue(dp.depth));
|
h->setPos(timeLine->posAtValue(dp.time / 60), depthLine->posAtValue(dp.depth));
|
||||||
QPointF p1 = (i == 0) ? QPointF(timeLine->posAtValue(0), depthLine->posAtValue(0)) : handles[i-1]->pos();
|
QPointF p1 = handles[i-1]->pos();
|
||||||
QPointF p2 = handles[i]->pos();
|
QPointF p2 = handles[i]->pos();
|
||||||
QLineF line(p1, p2);
|
QLineF line(p1, p2);
|
||||||
QPointF pos = line.pointAt(0.5);
|
QPointF pos = line.pointAt(0.5);
|
||||||
gases[i]->setPos(pos);
|
gases[i]->setPos(pos);
|
||||||
gases[i]->setText( strForAir(dp));
|
gases[i]->setText(strForAir(plannerModel->at(i-1)));
|
||||||
}
|
}
|
||||||
|
|
||||||
// (re-) create the profile with different colors for segments that were
|
// (re-) create the profile with different colors for segments that were
|
||||||
|
@ -956,7 +967,12 @@ QVariant DivePlannerPointsModel::data(const QModelIndex& index, int role) const
|
||||||
case CCSETPOINT: return p.po2;
|
case CCSETPOINT: return p.po2;
|
||||||
case DEPTH: return rint(get_depth_units(p.depth, NULL, NULL));
|
case DEPTH: return rint(get_depth_units(p.depth, NULL, NULL));
|
||||||
case DURATION: return p.time / 60;
|
case DURATION: return p.time / 60;
|
||||||
case GAS: return strForAir(p);
|
case GAS:
|
||||||
|
if (index.row() > 0) {
|
||||||
|
p = divepoints.at(index.row() - 1);
|
||||||
|
return strForAir(p);
|
||||||
|
}
|
||||||
|
return "";
|
||||||
}
|
}
|
||||||
} else if (role == Qt::DecorationRole) {
|
} else if (role == Qt::DecorationRole) {
|
||||||
switch(index.column()) {
|
switch(index.column()) {
|
||||||
|
@ -980,17 +996,24 @@ bool DivePlannerPointsModel::setData(const QModelIndex& index, const QVariant& v
|
||||||
QByteArray gasv = value.toByteArray();
|
QByteArray gasv = value.toByteArray();
|
||||||
if (validate_po2(gasv.data(), &po2))
|
if (validate_po2(gasv.data(), &po2))
|
||||||
p.po2 = po2;
|
p.po2 = po2;
|
||||||
} break;
|
}
|
||||||
|
break;
|
||||||
case GAS: {
|
case GAS: {
|
||||||
|
if (index.row() == 0) {
|
||||||
|
qDebug() << "how can index.row be 0???";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
divedatapoint& pp = divepoints[index.row() - 1];
|
||||||
int o2 = 0;
|
int o2 = 0;
|
||||||
int he = 0;
|
int he = 0;
|
||||||
QByteArray gasv = value.toByteArray();
|
QByteArray gasv = value.toByteArray();
|
||||||
if (validate_gas(gasv.data(), &o2, &he)) {
|
if (validate_gas(gasv.data(), &o2, &he)) {
|
||||||
p.o2 = o2;
|
pp.o2 = o2;
|
||||||
p.he = he;
|
pp.he = he;
|
||||||
}break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
editStop(index.row(), p);
|
editStop(index.row(), p);
|
||||||
}
|
}
|
||||||
return QAbstractItemModel::setData(index, value, role);
|
return QAbstractItemModel::setData(index, value, role);
|
||||||
|
@ -1076,23 +1099,32 @@ bool divePointsLessThan(const divedatapoint& p1, const divedatapoint& p2)
|
||||||
return p1.time <= p2.time;
|
return p1.time <= p2.time;
|
||||||
}
|
}
|
||||||
|
|
||||||
int DivePlannerPointsModel::addStop(int milimeters, int minutes, const QString& gas, int ccpoint)
|
int DivePlannerPointsModel::addStop(int milimeters, int minutes, int o2, int he, int ccpoint)
|
||||||
{
|
{
|
||||||
int row = divepoints.count();
|
int row = divepoints.count();
|
||||||
if(milimeters == 0 && minutes == 0) {
|
|
||||||
if(row == 0) {
|
if(row == 0) {
|
||||||
milimeters = M_OR_FT(10,30);
|
beginInsertRows(QModelIndex(), row, row);
|
||||||
minutes = 600;
|
divedatapoint point;
|
||||||
} else {
|
point.depth = 0;
|
||||||
divedatapoint p = at(row-1);
|
point.time = 0;
|
||||||
milimeters = p.depth;
|
point.o2 = o2;
|
||||||
minutes = p.time + 600;
|
point.he = he;
|
||||||
}
|
point.po2 = ccpoint;
|
||||||
|
divepoints.append( point );
|
||||||
|
endInsertRows();
|
||||||
|
row++;
|
||||||
}
|
}
|
||||||
|
|
||||||
// check if there's already a new stop before this one:
|
// check if there's already a new stop before this one:
|
||||||
for (int i = 0; i < divepoints.count(); i++) {
|
for (int i = 0; i < row; i++) {
|
||||||
const divedatapoint& dp = divepoints.at(i);
|
const divedatapoint& dp = divepoints.at(i);
|
||||||
|
if (dp.time == minutes) {
|
||||||
|
row = i;
|
||||||
|
beginRemoveRows(QModelIndex(), row, row);
|
||||||
|
divepoints.remove(row);
|
||||||
|
endRemoveRows();
|
||||||
|
break;
|
||||||
|
}
|
||||||
if (dp.time > minutes ) {
|
if (dp.time > minutes ) {
|
||||||
row = i;
|
row = i;
|
||||||
break;
|
break;
|
||||||
|
@ -1104,16 +1136,9 @@ int DivePlannerPointsModel::addStop(int milimeters, int minutes, const QString&
|
||||||
divedatapoint point;
|
divedatapoint point;
|
||||||
point.depth = milimeters;
|
point.depth = milimeters;
|
||||||
point.time = minutes;
|
point.time = minutes;
|
||||||
if (row == 0) {
|
point.o2 = o2;
|
||||||
point.o2 = 209;
|
point.he = he;
|
||||||
point.he = 0;
|
point.po2 = ccpoint;
|
||||||
point.po2 = 0;
|
|
||||||
} else {
|
|
||||||
divedatapoint before = at(row-1);
|
|
||||||
point.o2 = before.o2;
|
|
||||||
point.he = before.he;
|
|
||||||
point.po2 = 0;
|
|
||||||
}
|
|
||||||
divepoints.append( point );
|
divepoints.append( point );
|
||||||
std::sort(divepoints.begin(), divepoints.end(), divePointsLessThan);
|
std::sort(divepoints.begin(), divepoints.end(), divePointsLessThan);
|
||||||
endInsertRows();
|
endInsertRows();
|
||||||
|
@ -1185,8 +1210,8 @@ void DivePlannerPointsModel::createTemporaryPlan()
|
||||||
// Get the user-input and calculate the dive info
|
// Get the user-input and calculate the dive info
|
||||||
// Not sure if this is the place to create the diveplan...
|
// Not sure if this is the place to create the diveplan...
|
||||||
// We just start with a surface node at time = 0
|
// We just start with a surface node at time = 0
|
||||||
struct divedatapoint *dp = create_dp(0, 0, 209, 0, 0);
|
struct divedatapoint *dp = NULL; // create_dp(0, 0, 209, 0, 0);
|
||||||
dp->entered = TRUE;
|
// dp->entered = TRUE;
|
||||||
diveplan.dp = dp;
|
diveplan.dp = dp;
|
||||||
int lastIndex = -1;
|
int lastIndex = -1;
|
||||||
for (int i = 0; i < rowCount(); i++) {
|
for (int i = 0; i < rowCount(); i++) {
|
||||||
|
@ -1205,6 +1230,7 @@ void DivePlannerPointsModel::createTemporaryPlan()
|
||||||
if (mode == ADD) {
|
if (mode == ADD) {
|
||||||
copy_samples(tempDive, current_dive);
|
copy_samples(tempDive, current_dive);
|
||||||
copy_cylinders(tempDive, current_dive);
|
copy_cylinders(tempDive, current_dive);
|
||||||
|
copy_events(tempDive, current_dive);
|
||||||
}
|
}
|
||||||
#if DEBUG_PLAN
|
#if DEBUG_PLAN
|
||||||
dump_plan(&diveplan);
|
dump_plan(&diveplan);
|
||||||
|
@ -1215,7 +1241,9 @@ void DivePlannerPointsModel::undoEdition()
|
||||||
{
|
{
|
||||||
clear();
|
clear();
|
||||||
Q_FOREACH(const sample &s, backupSamples){
|
Q_FOREACH(const sample &s, backupSamples){
|
||||||
plannerModel->addStop(s.depth.mm, s.time.seconds, tr("Air"), 0);
|
int o2, he;
|
||||||
|
get_gas_from_events(¤t_dive->dc, s.time.seconds, &o2, &he);
|
||||||
|
plannerModel->addStop(s.depth.mm, s.time.seconds, o2, he, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -42,7 +42,7 @@ public:
|
||||||
int size();
|
int size();
|
||||||
struct diveplan getDiveplan();
|
struct diveplan getDiveplan();
|
||||||
public slots:
|
public slots:
|
||||||
int addStop(int meters = 0, int minutes = 0,const QString& gas = QString(), int ccpoint = 0 );
|
int addStop(int meters = 0, int minutes = 0, int o2 = 0, int he = 0, int ccpoint = 0 );
|
||||||
void setGFHigh(short gfhigh);
|
void setGFHigh(short gfhigh);
|
||||||
void setGFLow(short ghflow);
|
void setGFLow(short ghflow);
|
||||||
void setSurfacePressure(int pressure);
|
void setSurfacePressure(int pressure);
|
||||||
|
|
|
@ -544,9 +544,8 @@ void MainTab::rejectChanges()
|
||||||
// clean up
|
// clean up
|
||||||
delete_single_dive(selected_dive);
|
delete_single_dive(selected_dive);
|
||||||
DivePlannerPointsModel::instance()->cancelPlan();
|
DivePlannerPointsModel::instance()->cancelPlan();
|
||||||
}
|
} else if (editMode == MANUALLY_ADDED_DIVE ) {
|
||||||
else if (editMode == MANUALLY_ADDED_DIVE ){
|
DivePlannerPointsModel::instance()->undoEdition(); // that's BOGUS... just copy the original dive back and be done with it...
|
||||||
DivePlannerPointsModel::instance()->undoEdition();
|
|
||||||
}
|
}
|
||||||
struct dive *curr = current_dive;
|
struct dive *curr = current_dive;
|
||||||
ui.notes->setText(notesBackup[curr].notes );
|
ui.notes->setText(notesBackup[curr].notes );
|
||||||
|
|
|
@ -94,7 +94,6 @@ private:
|
||||||
* dive to this structure, making all editions there,
|
* dive to this structure, making all editions there,
|
||||||
* then applying the changes on the other dives.*/
|
* then applying the changes on the other dives.*/
|
||||||
struct dive multiEditEquipmentPlaceholder;
|
struct dive multiEditEquipmentPlaceholder;
|
||||||
|
|
||||||
Completers completers;
|
Completers completers;
|
||||||
void resetPallete();
|
void resetPallete();
|
||||||
void saveTags();
|
void saveTags();
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue