summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--planner.c16
-rw-r--r--qt-ui/diveplanner.cpp89
-rw-r--r--qt-ui/diveplanner.h1
3 files changed, 70 insertions, 36 deletions
diff --git a/planner.c b/planner.c
index 687da8273..03efe7465 100644
--- a/planner.c
+++ b/planner.c
@@ -233,7 +233,6 @@ struct dive *create_dive_from_plan(struct diveplan *diveplan, const char **error
int time = dp->time;
int depth = dp->depth;
-#if 0 // the new planner doesn't use that any more
if (time == 0) {
/* special entries that just inform the algorithm about
* additional gases that are available */
@@ -242,7 +241,6 @@ struct dive *create_dive_from_plan(struct diveplan *diveplan, const char **error
dp = dp->next;
continue;
}
-#endif
if (!o2 && !he) {
o2 = oldo2;
he = oldhe;
@@ -258,14 +256,14 @@ struct dive *create_dive_from_plan(struct diveplan *diveplan, const char **error
/* Create new gas, and gas change event if necessary;
* Sadly, we inherited our gaschange event from libdivecomputer which only
* support percentage values, so round the entries */
- if (time == 0 || o2 != oldo2 || he != oldhe) {
+ if (o2 != oldo2 || he != oldhe) {
int plano2 = (o2 + 5) / 10 * 10;
int planhe = (he + 5) / 10 * 10;
int value;
if (add_gas(dive, plano2, planhe) < 0)
goto gas_error_exit;
value = (plano2 / 10) | ((planhe / 10) << 16);
- add_event(dc, time, 25, 0, value, "gaschange"); // SAMPLE_EVENT_GASCHANGE2
+ add_event(dc, lasttime, 25, 0, value, "gaschange"); // SAMPLE_EVENT_GASCHANGE2
oldo2 = o2; oldhe = he;
}
/* Create sample */
@@ -350,7 +348,7 @@ void add_to_end_of_diveplan(struct diveplan *diveplan, struct divedatapoint *dp)
lastdp = &(*lastdp)->next;
}
*lastdp = dp;
- if (ldp)
+ if (ldp && dp->time != 0)
dp->time += lasttime;
}
@@ -565,9 +563,9 @@ void plan(struct diveplan *diveplan, char **cached_datap, struct dive **divep, b
int transitiontime, gi;
unsigned int stopidx, depth, ceiling;
double tissue_tolerance;
- struct gaschanges *gaschanges;
+ struct gaschanges *gaschanges = NULL;
int gaschangenr;
- unsigned int *stoplevels;
+ unsigned int *stoplevels = NULL;
set_gf(diveplan->gflow, diveplan->gfhigh);
if (!diveplan->surface_pressure)
@@ -613,6 +611,8 @@ void plan(struct diveplan *diveplan, char **cached_datap, struct dive **divep, b
#endif
if (depth < ceiling) /* that's not good... */
depth = ceiling;
+ if (depth == 0 && ceiling == 0) /* we are done here */
+ goto done;
for (stopidx = 0; stopidx < sizeof(decostoplevels) / sizeof(int); stopidx++)
if (decostoplevels[stopidx] >= depth)
break;
@@ -687,6 +687,8 @@ void plan(struct diveplan *diveplan, char **cached_datap, struct dive **divep, b
stopidx--;
}
+done:
+
#if DO_WE_WANT_THIS_IN_QT
add_plan_to_notes(diveplan, dive);
#endif
diff --git a/qt-ui/diveplanner.cpp b/qt-ui/diveplanner.cpp
index 1a20e4f9b..c7aea75e7 100644
--- a/qt-ui/diveplanner.cpp
+++ b/qt-ui/diveplanner.cpp
@@ -418,7 +418,7 @@ void DivePlannerGraphics::mouseDoubleClickEvent(QMouseEvent* event)
int minutes = rint(timeLine->valueAt(mappedPos));
int milimeters = rint(depthLine->valueAt(mappedPos) / M_OR_FT(1,1)) * M_OR_FT(1,1);
- plannerModel->addStop(milimeters, minutes * 60, O2_IN_AIR, 0, 0);
+ plannerModel->addStop(milimeters, minutes * 60, -1, 0, 0);
}
void DivePlannerPointsModel::createSimpleDive()
@@ -511,16 +511,20 @@ void DivePlannerGraphics::drawProfile()
}
// Re-position the user generated dive handlers
+ int last = 0;
for (int i = 1; i < plannerModel->rowCount(); i++) {
divedatapoint dp = plannerModel->at(i);
+ if (dp.time == 0) // those are the magic entries for tanks
+ continue;
DiveHandler *h = handles.at(i);
h->setPos(timeLine->posAtValue(dp.time / 60), depthLine->posAtValue(dp.depth));
- QPointF p1 = handles[i-1]->pos();
+ QPointF p1 = handles[last]->pos();
QPointF p2 = handles[i]->pos();
QLineF line(p1, p2);
QPointF pos = line.pointAt(0.5);
gases[i]->setPos(pos);
- gases[i]->setText(dpGasToStr(plannerModel->at(i-1)));
+ gases[i]->setText(dpGasToStr(plannerModel->at(i)));
+ last = i;
}
// (re-) create the profile with different colors for segments that were
@@ -532,6 +536,8 @@ void DivePlannerGraphics::drawProfile()
poly.append(QPointF(lastx, lasty));
for (dp = diveplan.dp; dp != NULL; dp = dp->next) {
+ if (dp->time == 0) // magic entry for available tank
+ continue;
double xpos = timeLine->posAtValue(dp->time / 60.0);
double ypos = depthLine->posAtValue(dp->depth);
if (!dp->entered) {
@@ -944,10 +950,6 @@ DivePlannerWidget::DivePlannerWidget(QWidget* parent, Qt::WindowFlags f): QWidge
void DivePlannerPointsModel::addCylinder_clicked()
{
- qDebug() << "add Cylinder clicked";
- if (!stagingDive)
- stagingDive = alloc_dive();
- CylindersModel::instance()->setDive(stagingDive);
CylindersModel::instance()->add();
}
@@ -1009,12 +1011,7 @@ QVariant DivePlannerPointsModel::data(const QModelIndex& index, int role) const
case CCSETPOINT: return p.po2;
case DEPTH: return rint(get_depth_units(p.depth, NULL, NULL));
case DURATION: return p.time / 60;
- case GAS:
- if (index.row() > 0) {
- p = divepoints.at(index.row() - 1);
- return dpGasToStr(p);
- }
- return "";
+ case GAS: return dpGasToStr(p);
}
} else if (role == Qt::DecorationRole) {
switch(index.column()) {
@@ -1028,6 +1025,8 @@ QVariant DivePlannerPointsModel::data(const QModelIndex& index, int role) const
bool DivePlannerPointsModel::setData(const QModelIndex& index, const QVariant& value, int role)
{
+ int o2 = 0;
+ int he = 0;
if(role == Qt::EditRole) {
divedatapoint& p = divepoints[index.row()];
switch(index.column()) {
@@ -1040,19 +1039,11 @@ bool DivePlannerPointsModel::setData(const QModelIndex& index, const QVariant& v
p.po2 = po2;
}
break;
- 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 he = 0;
+ case GAS:
QByteArray gasv = value.toByteArray();
if (validate_gas(gasv.data(), &o2, &he)) {
- pp.o2 = o2;
- pp.he = he;
- }
+ p.o2 = o2;
+ p.he = he;
}
break;
}
@@ -1143,10 +1134,38 @@ bool divePointsLessThan(const divedatapoint& p1, const divedatapoint& p2)
return p1.time <= p2.time;
}
+bool DivePlannerPointsModel::addGas(int o2, int he)
+{
+ cylinder_t *cyl = stagingDive->cylinder;
+ if (is_air(o2, he))
+ o2 = 0;
+
+ for (int i = 0; i < MAX_CYLINDERS; i++) {
+ if (cylinder_nodata(cyl)) {
+ cyl->type.description = strdup("Cylinder for planning");
+ cyl->gasmix.o2.permille = o2;
+ cyl->gasmix.he.permille = he;
+ CylindersModel::instance()->setDive(stagingDive);
+ return true;
+ }
+ if (cyl->gasmix.o2.permille == o2 && cyl->gasmix.he.permille == he)
+ return true;
+ }
+ qDebug("too many gases");
+ return false;
+}
+
int DivePlannerPointsModel::addStop(int milimeters, int minutes, int o2, int he, int ccpoint)
{
int row = divepoints.count();
+ if (o2 != -1)
+ if (!addGas(o2, he))
+ qDebug("addGas failed"); // FIXME add error propagation
if(row == 0) {
+ if (o2 == -1) {
+ o2 = O2_IN_AIR;
+ (void)addGas(o2, 0); // I know this is the first gas - won't fail
+ }
beginInsertRows(QModelIndex(), row, row);
divedatapoint point;
point.depth = 0;
@@ -1249,6 +1268,10 @@ DivePlannerPointsModel::Mode DivePlannerPointsModel::currentMode() const
void DivePlannerPointsModel::clear()
{
+ if (!stagingDive)
+ stagingDive = alloc_dive();
+ memset(stagingDive->cylinder, 0, MAX_CYLINDERS * sizeof(cylinder_t));
+ CylindersModel::instance()->setDive(stagingDive);
beginRemoveRows(QModelIndex(), 0, rowCount()-1);
divepoints.clear();
endRemoveRows();
@@ -1262,8 +1285,8 @@ void DivePlannerPointsModel::createTemporaryPlan()
// Get the user-input and calculate the dive info
// Not sure if this is the place to create the diveplan...
// We just start with a surface node at time = 0
- struct divedatapoint *dp = NULL; // create_dp(0, 0, 209, 0, 0);
-// dp->entered = TRUE;
+ struct divedatapoint *dp = create_dp(0, 0, 209, 0, 0);
+ dp->entered = TRUE;
diveplan.dp = dp;
int lastIndex = -1;
for (int i = 0; i < rowCount(); i++) {
@@ -1272,12 +1295,20 @@ void DivePlannerPointsModel::createTemporaryPlan()
lastIndex = i;
dp = plan_add_segment(&diveplan, deltaT, p.depth, p.o2, p.he, p.po2);
}
-#if DEBUG_PLAN
- dump_plan(&diveplan);
-#endif
char *cache = NULL;
tempDive = NULL;
const char *errorString = NULL;
+ for (int i = 0; i < MAX_CYLINDERS; i++) {
+ cylinder_t *cyl = &stagingDive->cylinder[i];
+ if (cyl->depth.mm) {
+ dp = create_dp(0, cyl->depth.mm, cyl->gasmix.o2.permille, cyl->gasmix.he.permille, 0);
+ dp->next = diveplan.dp->next;
+ diveplan.dp->next = dp;
+ }
+ }
+#if DEBUG_PLAN
+ dump_plan(&diveplan);
+#endif
plan(&diveplan, &cache, &tempDive, isPlanner(), &errorString);
if (mode == ADD) {
copy_samples(tempDive, current_dive);
diff --git a/qt-ui/diveplanner.h b/qt-ui/diveplanner.h
index 8a3d6635f..f22112d85 100644
--- a/qt-ui/diveplanner.h
+++ b/qt-ui/diveplanner.h
@@ -65,6 +65,7 @@ signals:
private:
explicit DivePlannerPointsModel(QObject* parent = 0);
+ bool addGas(int o2, int he);
struct diveplan diveplan;
Mode mode;
QVector<divedatapoint> divepoints;