[PATCH 1/3] Add unit-aware cylinder size string parserc

Linus Torvalds torvalds at linux-foundation.org
Wed Jan 8 18:51:40 UTC 2014


From: Linus Torvalds <torvalds at linux-foundation.org>
Date: Thu, 9 Jan 2014 10:34:25 +0800
Subject: [PATCH 1/3] Add unit-aware cylinder size string parserc

Whittling down on the string parsing that doesn't check user-specified
units.  Still need to handle temperatures (and will do percentages to
match the pattern too), but this is getting us closer to always honoring
user-specified units.

With this you can say that you have a "10l" cylinder at "3000psi", and
it will do the right thing (it's basically a 72 cuft cylinder in
imperial measurements).

Signed-off-by: Linus Torvalds <torvalds at linux-foundation.org>
---
 dive.h           |  1 +
 qt-ui/models.cpp | 64 ++++++++++++++++++++++++++++++++++++--------------------
 2 files changed, 42 insertions(+), 23 deletions(-)

diff --git a/dive.h b/dive.h
index ca717704ccf3..f7d1c04b3156 100644
--- a/dive.h
+++ b/dive.h
@@ -819,6 +819,7 @@ extern double strtod_flags(const char *str, const char **ptr, unsigned int flags
 extern weight_t string_to_weight(const char *str);
 extern depth_t string_to_depth(const char *str);
 extern pressure_t string_to_pressure(const char *str);
+extern volume_t string_to_volume(const char *str, pressure_t workp);
 
 #include "pref.h"
 
diff --git a/qt-ui/models.cpp b/qt-ui/models.cpp
index 0da5aa222311..f70a81a94572 100644
--- a/qt-ui/models.cpp
+++ b/qt-ui/models.cpp
@@ -206,29 +206,15 @@ bool CylindersModel::setData(const QModelIndex& index, const QVariant& value, in
 		}
 		break;
 	case SIZE:
-		if (CHANGED(toDouble, "cuft", "l")) {
-			// if units are CUFT then this value is meaningless until we have working pressure
-			if (vString.toDouble() != 0.0) {
-				TankInfoModel *tanks = TankInfoModel::instance();
-				QModelIndexList matches = tanks->match(tanks->index(0,0), Qt::DisplayRole, cyl->type.description);
-				int mbar = cyl->type.workingpressure.mbar;
-				int mliter;
-
-				if (mbar && prefs.units.volume == prefs.units.CUFT) {
-					double liters = cuft_to_l(vString.toDouble());
-					liters /= bar_to_atm(mbar / 1000.0);
-					mliter = rint(liters * 1000);
-				} else {
-					mliter = rint(vString.toDouble() * 1000);
-				}
-				if (cyl->type.size.mliter != mliter) {
-					mark_divelist_changed(TRUE);
-					cyl->type.size.mliter = mliter;
-					if (!matches.isEmpty())
-						tanks->setData(tanks->index(matches.first().row(), TankInfoModel::ML), cyl->type.size.mliter);
-				}
-				changed = true;
-			}
+		if (CHANGED(data, "", "")) {
+			TankInfoModel *tanks = TankInfoModel::instance();
+			QModelIndexList matches = tanks->match(tanks->index(0,0), Qt::DisplayRole, cyl->type.description);
+
+			cyl->type.size = string_to_volume(vString.toUtf8().data(), cyl->type.workingpressure);
+			mark_divelist_changed(TRUE);
+			if (!matches.isEmpty())
+				tanks->setData(tanks->index(matches.first().row(), TankInfoModel::ML), cyl->type.size.mliter);
+			changed = true;
 		}
 		break;
 	case WORKINGPRESS:
@@ -513,6 +499,38 @@ psi:
 	return pressure;
 }
 
+/* Imperial cylinder volumes need working pressure to be meaningful */
+volume_t string_to_volume(const char *str, pressure_t workp)
+{
+	const char *end;
+	double value = strtod_flags(str, &end, 0);
+	QString rest = QString(end).trimmed();
+	QString local_l = CylindersModel::tr("l");
+	QString local_cuft = CylindersModel::tr("cuft");
+	volume_t volume;
+
+	if (rest.startsWith("l") || rest.startsWith(local_l))
+		goto l;
+	if (rest.startsWith("cuft") || rest.startsWith(local_cuft))
+		goto cuft;
+	/*
+	 * If we don't have explicit units, and there is no working
+	 * pressure, we're going to assume "liter" even in imperial
+	 * measurements.
+	 */
+	if (!workp.mbar)
+		goto l;
+	if (prefs.units.volume == prefs.units.LITER)
+		goto l;
+cuft:
+	if (workp.mbar)
+		value /= bar_to_atm(workp.mbar / 1000.0);
+	value = cuft_to_l(value);
+l:
+	volume.mliter = rint(value * 1000);
+	return volume;
+}
+
 bool WeightModel::setData(const QModelIndex& index, const QVariant& value, int role)
 {
 	QString vString = value.toString();
-- 
1.8.4.2



More information about the subsurface mailing list