summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--core/dive.c28
-rw-r--r--core/dive.h2
-rw-r--r--core/load-git.c12
-rw-r--r--core/parse-xml.c2
-rw-r--r--core/save-git.c3
-rw-r--r--core/save-xml.c3
-rw-r--r--core/subsurface-qt/DiveListNotifier.h1
-rw-r--r--core/units.h11
-rw-r--r--desktop-widgets/command.cpp5
-rw-r--r--desktop-widgets/command.h1
-rw-r--r--desktop-widgets/command_edit.cpp21
-rw-r--r--desktop-widgets/command_edit.h9
-rw-r--r--desktop-widgets/tab-widgets/TabDiveInformation.cpp79
-rw-r--r--desktop-widgets/tab-widgets/TabDiveInformation.h4
-rw-r--r--desktop-widgets/tab-widgets/TabDiveInformation.ui28
-rw-r--r--dives/TestAtmPress.xml50
-rw-r--r--tests/CMakeLists.txt2
-rw-r--r--tests/testAirPressure.cpp63
-rw-r--r--tests/testAirPressure.h19
19 files changed, 323 insertions, 20 deletions
diff --git a/core/dive.c b/core/dive.c
index 0f67ebe61..d20350a80 100644
--- a/core/dive.c
+++ b/core/dive.c
@@ -1317,9 +1317,10 @@ static struct event *find_previous_event(struct divecomputer *dc, struct event *
return previous;
}
-static void fixup_surface_pressure(struct dive *dive)
+pressure_t calculate_surface_pressure(const struct dive *dive)
{
- struct divecomputer *dc;
+ const struct divecomputer *dc;
+ pressure_t res;
int sum = 0, nr = 0;
for_each_dc (dive, dc) {
@@ -1328,8 +1329,24 @@ static void fixup_surface_pressure(struct dive *dive)
nr++;
}
}
- if (nr)
- dive->surface_pressure.mbar = (sum + nr / 2) / nr;
+ res.mbar = nr ? (sum + nr / 2) / nr : 0;
+ return res;
+}
+
+static void fixup_surface_pressure(struct dive *dive)
+{
+ dive->surface_pressure = calculate_surface_pressure(dive);
+}
+
+/* if the surface pressure in the dive data is redundant to the calculated
+ * value (i.e., it was added by running fixup on the dive) return 0,
+ * otherwise return the air temperature given in the dive */
+pressure_t un_fixup_surface_pressure(const struct dive *d)
+{
+ pressure_t res = d->surface_pressure;
+ if (res.mbar && res.mbar == calculate_surface_pressure(d).mbar)
+ res.mbar = 0;
+ return res;
}
static void fixup_water_salinity(struct dive *dive)
@@ -1823,7 +1840,8 @@ struct dive *fixup_dive(struct dive *dive)
fixup_dive_dc(dive, dc);
fixup_water_salinity(dive);
- fixup_surface_pressure(dive);
+ if (!dive->surface_pressure.mbar)
+ fixup_surface_pressure(dive);
fixup_meandepth(dive);
fixup_duration(dive);
fixup_watertemp(dive);
diff --git a/core/dive.h b/core/dive.h
index 6f75aff43..7aea050b6 100644
--- a/core/dive.h
+++ b/core/dive.h
@@ -533,6 +533,8 @@ extern bool dive_or_trip_less_than(struct dive_or_trip a, struct dive_or_trip b)
extern void sort_dive_table(struct dive_table *table);
extern void sort_trip_table(struct trip_table *table);
extern struct dive *fixup_dive(struct dive *dive);
+extern pressure_t calculate_surface_pressure(const struct dive *dive);
+extern pressure_t un_fixup_surface_pressure(const struct dive *d);
extern void fixup_dc_duration(struct divecomputer *dc);
extern int dive_getUniqID();
extern unsigned int dc_airtemp(const struct divecomputer *dc);
diff --git a/core/load-git.c b/core/load-git.c
index c6b3400a8..a0baedecd 100644
--- a/core/load-git.c
+++ b/core/load-git.c
@@ -76,6 +76,13 @@ static weight_t get_weight(const char *line)
return w;
}
+static pressure_t get_airpressure(const char *line)
+{
+ pressure_t p;
+ p.mbar = lrint(ascii_strtod(line, NULL));
+ return p;
+}
+
static pressure_t get_pressure(const char *line)
{
pressure_t p;
@@ -245,6 +252,9 @@ static void parse_dive_airtemp(char *line, struct membuffer *str, void *_dive)
static void parse_dive_watertemp(char *line, struct membuffer *str, void *_dive)
{ UNUSED(str); struct dive *dive = _dive; dive->watertemp = get_temperature(line); }
+static void parse_dive_airpressure(char *line, struct membuffer *str, void *_dive)
+{ UNUSED(str); struct dive *dive = _dive; dive->surface_pressure = get_airpressure(line); }
+
static void parse_dive_duration(char *line, struct membuffer *str, void *_dive)
{ UNUSED(str); struct dive *dive = _dive; dive->duration = get_duration(line); }
@@ -980,7 +990,7 @@ static void divecomputer_parser(char *line, struct membuffer *str, void *_dc)
struct keyword_action dive_action[] = {
#undef D
#define D(x) { #x, parse_dive_ ## x }
- D(airtemp), D(buddy), D(cylinder), D(divemaster), D(divesiteid), D(duration),
+ D(airpressure), D(airtemp), D(buddy), D(cylinder), D(divemaster), D(divesiteid), D(duration),
D(gps), D(location), D(notes), D(notrip), D(rating), D(suit),
D(tags), D(visibility), D(watertemp), D(weightsystem)
};
diff --git a/core/parse-xml.c b/core/parse-xml.c
index 483614c6e..43d0049a7 100644
--- a/core/parse-xml.c
+++ b/core/parse-xml.c
@@ -1306,6 +1306,8 @@ static void try_to_fill_dive(struct dive *dive, const char *name, char *buf, str
return;
if (MATCH("visibility.dive", get_rating, &dive->visibility))
return;
+ if (MATCH_STATE("airpressure.dive", pressure, &dive->surface_pressure))
+ return;
if (state->cur_ws_index < MAX_WEIGHTSYSTEMS) {
if (MATCH("description.weightsystem", utf8_string, &dive->weightsystem[state->cur_ws_index].description))
return;
diff --git a/core/save-git.c b/core/save-git.c
index b13921c60..a5f6f0dde 100644
--- a/core/save-git.c
+++ b/core/save-git.c
@@ -425,10 +425,13 @@ static void save_dc(struct membuffer *b, struct dive *dive, struct divecomputer
*/
static void create_dive_buffer(struct dive *dive, struct membuffer *b)
{
+ pressure_t surface_pressure = un_fixup_surface_pressure(dive);
if (dive->dc.duration.seconds > 0)
put_format(b, "duration %u:%02u min\n", FRACTION(dive->dc.duration.seconds, 60));
SAVE("rating", rating);
SAVE("visibility", visibility);
+ if (surface_pressure.mbar)
+ SAVE("airpressure", surface_pressure.mbar);
cond_put_format(dive->notrip, b, "notrip\n");
save_tags(b, dive->tag_list);
if (dive->dive_site)
diff --git a/core/save-xml.c b/core/save-xml.c
index 02cb2bf87..f043ab6d8 100644
--- a/core/save-xml.c
+++ b/core/save-xml.c
@@ -473,6 +473,7 @@ static void save_picture(struct membuffer *b, struct picture *pic)
void save_one_dive_to_mb(struct membuffer *b, struct dive *dive, bool anonymize)
{
struct divecomputer *dc;
+ pressure_t surface_pressure = un_fixup_surface_pressure(dive);
put_string(b, "<dive");
if (dive->number)
@@ -488,6 +489,8 @@ void save_one_dive_to_mb(struct membuffer *b, struct dive *dive, bool anonymize)
put_format(b, " divesiteid='%8x'", dive->dive_site->uuid);
}
show_date(b, dive->when);
+ if (surface_pressure.mbar)
+ put_pressure(b, surface_pressure, " airpressure='", " bar'");
if (dive->dc.duration.seconds > 0)
put_format(b, " duration='%u:%02u min'>\n",
FRACTION(dive->dc.duration.seconds, 60));
diff --git a/core/subsurface-qt/DiveListNotifier.h b/core/subsurface-qt/DiveListNotifier.h
index b57595aa6..95a67a1e8 100644
--- a/core/subsurface-qt/DiveListNotifier.h
+++ b/core/subsurface-qt/DiveListNotifier.h
@@ -19,6 +19,7 @@ enum class DiveField {
DURATION,
AIR_TEMP,
WATER_TEMP,
+ ATM_PRESS,
DIVESITE,
DIVEMASTER,
BUDDY,
diff --git a/core/units.h b/core/units.h
index c9920ac14..2307622e9 100644
--- a/core/units.h
+++ b/core/units.h
@@ -254,6 +254,17 @@ static inline int mbar_to_PSI(int mbar)
return to_PSI(p);
}
+static inline int32_t altitude_to_pressure(int32_t altitude) // altitude in mm above sea level
+{ // returns atmospheric pressure in mbar
+ return (int32_t) (1013.0 * exp(- altitude / 7800000.0));
+}
+
+
+static inline int32_t pressure_to_altitude(int32_t pressure) // pressure in mbar
+{ // returns altitude in mm above sea level
+ return (int32_t) (log(1013.0 / pressure) * 7800000);
+}
+
/*
* We keep our internal data in well-specified units, but
* the input and output may come in some random format. This
diff --git a/desktop-widgets/command.cpp b/desktop-widgets/command.cpp
index 00bb49872..e5244e92a 100644
--- a/desktop-widgets/command.cpp
+++ b/desktop-widgets/command.cpp
@@ -171,6 +171,11 @@ void editWaterTemp(int newValue, bool currentDiveOnly)
execute(new EditWaterTemp(newValue, currentDiveOnly));
}
+void editAtmPress(int newValue, bool currentDiveOnly)
+{
+ execute(new EditAtmPress(newValue, currentDiveOnly));
+}
+
void editDepth(int newValue, bool currentDiveOnly)
{
execute(new EditDepth(newValue, currentDiveOnly));
diff --git a/desktop-widgets/command.h b/desktop-widgets/command.h
index 8e8157acf..2686255ee 100644
--- a/desktop-widgets/command.h
+++ b/desktop-widgets/command.h
@@ -61,6 +61,7 @@ void editRating(int newValue, bool currentDiveOnly);
void editVisibility(int newValue, bool currentDiveOnly);
void editAirTemp(int newValue, bool currentDiveOnly);
void editWaterTemp(int newValue, bool currentDiveOnly);
+void editAtmPress(int newValue, bool currentDiveOnly);
void editDepth(int newValue, bool currentDiveOnly);
void editDuration(int newValue, bool currentDiveOnly);
void editDiveSite(struct dive_site *newValue, bool currentDiveOnly);
diff --git a/desktop-widgets/command_edit.cpp b/desktop-widgets/command_edit.cpp
index 3419749d7..5207d1ac1 100644
--- a/desktop-widgets/command_edit.cpp
+++ b/desktop-widgets/command_edit.cpp
@@ -248,6 +248,27 @@ DiveField EditWaterTemp::fieldId() const
return DiveField::WATER_TEMP;
}
+// ***** Atmospheric pressure *****
+void EditAtmPress::set(struct dive *d, int value) const
+{
+ d->surface_pressure.mbar = value > 0 ? (uint32_t)value : 0u;
+}
+
+int EditAtmPress::data(struct dive *d) const
+{
+ return (int)d->surface_pressure.mbar;
+}
+
+QString EditAtmPress::fieldName() const
+{
+ return tr("Atm. pressure");
+}
+
+DiveField EditAtmPress::fieldId() const
+{
+ return DiveField::ATM_PRESS;
+}
+
// ***** Duration *****
void EditDuration::set(struct dive *d, int value) const
{
diff --git a/desktop-widgets/command_edit.h b/desktop-widgets/command_edit.h
index 1f627c7ef..a1050d65e 100644
--- a/desktop-widgets/command_edit.h
+++ b/desktop-widgets/command_edit.h
@@ -102,6 +102,15 @@ public:
DiveField fieldId() const override;
};
+class EditAtmPress : public EditBase<int> {
+public:
+ using EditBase<int>::EditBase; // Use constructor of base class.
+ void set(struct dive *d, int value) const override;
+ int data(struct dive *d) const override;
+ QString fieldName() const override;
+ DiveField fieldId() const override;
+};
+
class EditDuration : public EditBase<int> {
public:
using EditBase<int>::EditBase; // Use constructor of base class.
diff --git a/desktop-widgets/tab-widgets/TabDiveInformation.cpp b/desktop-widgets/tab-widgets/TabDiveInformation.cpp
index 5fe6ea714..4511f9b61 100644
--- a/desktop-widgets/tab-widgets/TabDiveInformation.cpp
+++ b/desktop-widgets/tab-widgets/TabDiveInformation.cpp
@@ -2,15 +2,24 @@
#include "TabDiveInformation.h"
#include "ui_TabDiveInformation.h"
#include "../tagwidget.h"
+#include "core/units.h"
+#include "core/dive.h"
+#include "desktop-widgets/command.h"
#include <core/qthelper.h>
#include <core/statistics.h>
#include <core/display.h>
+#define COMBO_CHANGED 0
+#define TEXT_EDITED 1
+
TabDiveInformation::TabDiveInformation(QWidget *parent) : TabBase(parent), ui(new Ui::TabDiveInformation())
{
ui->setupUi(this);
connect(&diveListNotifier, &DiveListNotifier::divesChanged, this, &TabDiveInformation::divesChanged);
+ QStringList atmPressTypes { "mbar", get_depth_unit() ,"use dc"};
+ ui->atmPressType->insertItems(0, atmPressTypes);
+ pressTypeIndex = 0;
}
TabDiveInformation::~TabDiveInformation()
@@ -32,7 +41,7 @@ void TabDiveInformation::clear()
ui->averageDepthText->clear();
ui->waterTemperatureText->clear();
ui->airTemperatureText->clear();
- ui->airPressureText->clear();
+ ui->atmPressVal->clear();
ui->salinityText->clear();
}
@@ -74,6 +83,17 @@ void TabDiveInformation::updateProfile()
" ", current_dive->dc.divemode == FREEDIVE));
ui->sacText->setText( mean[0] ? SACs : QString());
+
+ if (current_dive->surface_pressure.mbar == 0) {
+ ui->atmPressVal->clear(); // If no atm pressure for dive then clear text box
+ }
+ else {
+
+ ui->atmPressVal->setEnabled(true);
+ QString pressStr;
+ pressStr.sprintf("%d",current_dive->surface_pressure.mbar);
+ ui->atmPressVal->setText(pressStr); // else display atm pressure
+ }
}
// Update fields that depend on start of dive
@@ -99,15 +119,15 @@ void TabDiveInformation::updateData()
ui->waterTemperatureText->setText(get_temperature_string(current_dive->watertemp, true));
ui->airTemperatureText->setText(get_temperature_string(current_dive->airtemp, true));
- if (current_dive->surface_pressure.mbar) /* this is ALWAYS displayed in mbar */
- ui->airPressureText->setText(QString("%1mbar").arg(current_dive->surface_pressure.mbar));
- else
- ui->airPressureText->clear();
-
if (current_dive->salinity)
ui->salinityText->setText(QString("%1g/ℓ").arg(current_dive->salinity / 10.0));
else
ui->salinityText->clear();
+
+ ui->atmPressType->setEditable(true);
+ ui->atmPressType->setItemText(1, get_depth_unit()); // Check for changes in depth unit (imperial/metric)
+ ui->atmPressType->setEditable(false);
+ ui->atmPressType->setCurrentIndex(0); // Set the atmospheric pressure combo box to mbar
}
// This function gets called if a field gets updated by an undo command.
@@ -130,6 +150,9 @@ void TabDiveInformation::divesChanged(dive_trip *trip, const QVector<dive *> &di
case DiveField::WATER_TEMP:
ui->waterTemperatureText->setText(get_temperature_string(current_dive->watertemp, true));
break;
+ case DiveField::ATM_PRESS:
+ ui->atmPressVal->setText(ui->atmPressVal->text().sprintf("%d",current_dive->surface_pressure.mbar));
+ break;
case DiveField::DATETIME:
updateWhen();
break;
@@ -137,3 +160,47 @@ void TabDiveInformation::divesChanged(dive_trip *trip, const QVector<dive *> &di
break;
}
}
+
+void TabDiveInformation::on_atmPressType_currentIndexChanged(int index) { updateTextBox(COMBO_CHANGED); }
+
+void TabDiveInformation::on_atmPressVal_editingFinished() { updateTextBox(TEXT_EDITED); }
+
+void TabDiveInformation::updateTextBox(int event) // Either the text box has been edited or the pressure type has changed.
+{ // Either way this gets a numeric value and puts it on the text box atmPressVal,
+ pressure_t atmpress = { 0 }; // then stores it in dive->surface_pressure.The undo stack for the text box content is
+ double altitudeVal; // maintained even though two independent events trigger saving the text box contents.
+ if (current_dive) {
+ switch (ui->atmPressType->currentIndex()) {
+ case 0: // If an atm pressure has been specified in mbar:
+ if (event == TEXT_EDITED) // this is only triggered by on_atmPressVal_editingFinished()
+ atmpress.mbar = ui->atmPressVal->text().toInt(); // use the specified mbar pressure
+ break;
+ case 1: // If an altitude has been specified:
+ if (event == TEXT_EDITED) { // this is only triggered by on_atmPressVal_editingFinished()
+ altitudeVal = (ui->atmPressVal->text().toFloat()); // get altitude from text box
+ if (prefs.units.length == units::FEET) // if altitude in feet
+ altitudeVal = feet_to_mm(altitudeVal); // imperial: convert altitude from feet to mm
+ else
+ altitudeVal = altitudeVal * 1000; // metric: convert altitude from meters to mm
+ atmpress.mbar = altitude_to_pressure((int32_t) altitudeVal); // convert altitude (mm) to pressure (mbar)
+ ui->atmPressVal->setText(ui->atmPressVal->text().sprintf("%d",atmpress.mbar));
+ ui->atmPressType->setCurrentIndex(0); // reset combobox to mbar
+ } else { // i.e. event == COMBO_CHANGED, that is, "m" or "ft" was selected from combobox
+ ui->atmPressVal->clear(); // Clear the text box so that altitude can be typed
+ }
+ break;
+ case 2: // i.e. event = COMBO_CHANGED, that is, the option "Use dc" was selected from combobox
+ atmpress = calculate_surface_pressure(current_dive); // re-calculate air pressure from dc data
+ ui->atmPressVal->setText(QString::number(atmpress.mbar)); // display it in text box
+ ui->atmPressType->setCurrentIndex(0); // reset combobox to mbar
+ break;
+ default:
+ atmpress.mbar = 1013; // This line should never execute
+ break;
+ }
+ if (atmpress.mbar)
+ Command::editAtmPress(atmpress.mbar, false); // and save the pressure for undo
+ }
+}
+
+
diff --git a/desktop-widgets/tab-widgets/TabDiveInformation.h b/desktop-widgets/tab-widgets/TabDiveInformation.h
index a61b9b414..e2b2e3c94 100644
--- a/desktop-widgets/tab-widgets/TabDiveInformation.h
+++ b/desktop-widgets/tab-widgets/TabDiveInformation.h
@@ -18,10 +18,14 @@ public:
void clear() override;
private slots:
void divesChanged(dive_trip *trip, const QVector<dive *> &dives, DiveField field);
+ void on_atmPressVal_editingFinished();
+ void on_atmPressType_currentIndexChanged(int index);
private:
Ui::TabDiveInformation *ui;
void updateProfile();
void updateWhen();
+ int pressTypeIndex;
+ void updateTextBox(int event);
};
#endif
diff --git a/desktop-widgets/tab-widgets/TabDiveInformation.ui b/desktop-widgets/tab-widgets/TabDiveInformation.ui
index f81ab6fe5..b35ddf01d 100644
--- a/desktop-widgets/tab-widgets/TabDiveInformation.ui
+++ b/desktop-widgets/tab-widgets/TabDiveInformation.ui
@@ -224,25 +224,37 @@
</layout>
</widget>
</item>
- <item row="2" column="2">
+
+ <item row="2" column="2" colspan="1">
<widget class="QGroupBox" name="groupBox_10">
<property name="title">
- <string>Air pressure</string>
+ <string>Atm. pressure</string>
</property>
+ <property name="alignment">
+ <set>Qt::AlignHCenter</set>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="Maximum">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
<layout class="QHBoxLayout" name="diveInfoAirPressureLayout">
<item>
- <widget class="QLabel" name="airPressureText">
- <property name="text">
- <string/>
- </property>
- <property name="alignment">
- <set>Qt::AlignCenter</set>
+ <widget class="QLineEdit" name="atmPressVal">
+ <property name="readOnly">
+ <bool>false</bool>
</property>
</widget>
</item>
+ <item>
+ <widget class="QComboBox" name="atmPressType">
+ </widget>
+ </item>
</layout>
</widget>
</item>
+
<item row="3" column="2">
<widget class="QGroupBox" name="groupBox_9">
<property name="title">
diff --git a/dives/TestAtmPress.xml b/dives/TestAtmPress.xml
new file mode 100644
index 000000000..93bbe3960
--- /dev/null
+++ b/dives/TestAtmPress.xml
@@ -0,0 +1,50 @@
+<divelog program='subsurface' version='3'>
+<settings>
+ <autogroup state='1' />
+</settings>
+<divesites>
+<site uuid='4fdcf19b' name='Loc1'>
+</site>
+<site uuid='b15ad032' name='Loc2'>
+</site>
+</divesites>
+<dives>
+<trip date='2019-04-09' time='09:15:16' location='Scottburgh'>
+<dive number='524' tripflag='NOTRIP' divesiteid='b15ad032' date='2019-04-09' time='09:15:16' airpressure='1.012 bar' duration='42:08 min'>
+ <cylinder size='10.0 l' workpressure='232.0 bar' description='10ℓ 232 bar' o2='30.0%' depth='42.96 m' />
+ <cylinder size='10.0 l' workpressure='232.0 bar' description='10ℓ 232 bar' o2='30.0%' depth='42.96 m' />
+ <weightsystem weight='3.0 kg' description='belt' />
+ <divecomputer model='Uwatec Galileo Trimix' deviceid='462769ce' diveid='14106bf6'>
+ <depth max='30.068 m' mean='21.394 m' />
+ <temperature air='24.6 C' water='23.2 C' />
+ <water salinity='1025 g/l' />
+ <sample time='0:00 min' depth='0.0 m' temp='24.4 C' rbt='99:00 min' />
+ <sample time='0:04 min' depth='2.439 m' temp='24.8 C' rbt='99:00 min' />
+ <sample time='0:08 min' depth='3.395 m' temp='24.4 C' rbt='99:00 min' />
+ <sample time='0:12 min' depth='3.902 m' temp='24.8 C' pressure='208.5 bar' rbt='99:00 min' />
+ <sample time='45:16 min' depth='4.488 m' pressure='208.25 bar' rbt='98:00 min' />
+ </divecomputer>
+</dive>
+<dive number='525' divesiteid='4fdcf19b' date='2019-04-10' time='08:14:01' airpressure='0.991 bar' duration='41:24 min'>
+ <cylinder size='10.0 l' workpressure='232.0 bar' description='10ℓ 232 bar' o2='31.0%' depth='41.25 m' />
+ <cylinder description='unknown' o2='31.0%' depth='41.25 m' />
+ <weightsystem weight='3.0 kg' description='belt' />
+ <divecomputer model='Uwatec Galileo Trimix' deviceid='462769ce' diveid='04c0cf94'>
+ <depth max='26.166 m' mean='19.561 m' />
+ <temperature air='24.8 C' water='23.6 C' />
+ <water salinity='1025 g/l' />
+ <sample time='0:00 min' depth='0.0 m' temp='26.8 C' rbt='99:00 min' />
+ <sample time='0:04 min' depth='3.61 m' rbt='99:00 min' />
+ <sample time='0:08 min' depth='4.741 m' temp='25.6 C' pressure='217.25 bar' rbt='99:00 min' />
+ <sample time='0:12 min' depth='6.478 m' pressure='216.75 bar' rbt='97:00 min' />
+ <sample time='0:16 min' depth='7.785 m' rbt='94:00 min' />
+ <sample time='44:04 min' depth='0.0 m' rbt='99:00 min' />
+ <sample time='44:08 min' depth='0.02 m' rbt='99:00 min' />
+ <sample time='44:12 min' depth='0.098 m' rbt='99:00 min' />
+ <sample time='44:16 min' depth='0.059 m' rbt='99:00 min' />
+ <sample time='44:20 min' depth='0.059 m' rbt='99:00 min' />
+ </divecomputer>
+</dive>
+</trip>
+</dives>
+</divelog>
diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt
index 229054631..887e1b34d 100644
--- a/tests/CMakeLists.txt
+++ b/tests/CMakeLists.txt
@@ -92,6 +92,7 @@ TEST(TestUnitConversion testunitconversion.cpp)
TEST(TestProfile testprofile.cpp)
TEST(TestGpsCoords testgpscoords.cpp)
TEST(TestParse testparse.cpp)
+TEST(TestAirPressure testAirPressure.cpp)
if (BTSUPPORT)
TEST(TestHelper testhelper.cpp)
endif()
@@ -128,6 +129,7 @@ add_custom_target(check COMMAND ${CMAKE_CTEST_COMMAND}
TestParse
TestGitStorage
TestPlan
+ TestAirPressure
TestDiveSiteDuplication
TestRenumber
TestPicture
diff --git a/tests/testAirPressure.cpp b/tests/testAirPressure.cpp
new file mode 100644
index 000000000..aa6b13014
--- /dev/null
+++ b/tests/testAirPressure.cpp
@@ -0,0 +1,63 @@
+// SPDX-License-Identifier: GPL-2.0
+#include "testAirPressure.h"
+#include "core/divesite.h"
+#include "core/divelist.h"
+#include "core/file.h"
+#include "core/dive.h"
+#include <QString>
+#include <core/qthelper.h>
+
+void TestAirPressure::initTestCase()
+{
+ /* we need to manually tell that the resource exists, because we are using it as library. */
+ Q_INIT_RESOURCE(subsurface);
+}
+
+void TestAirPressure::get_dives()
+{
+ struct dive *dive;
+ verbose = 1;
+
+ QCOMPARE(parse_file(SUBSURFACE_TEST_DATA "/dives/TestAtmPress.xml", &dive_table, &trip_table, &dive_site_table), 0);
+ dive = get_dive(0);
+ dive->selected = true;
+ QVERIFY(dive != NULL);
+}
+
+void TestAirPressure::testReadAirPressure()
+{
+ struct dive *dive;
+ dive = get_dive(0);
+ QVERIFY(dive != NULL);
+ dive->selected = true;
+ QCOMPARE(1012, dive->surface_pressure.mbar);
+ dive = get_dive(1);
+ QVERIFY(dive != NULL);
+ dive->selected = true;
+ QCOMPARE(991, dive->surface_pressure.mbar);
+}
+
+void TestAirPressure::testConvertAltitudetoAirPressure()
+{
+ QCOMPARE(891,altitude_to_pressure(1000000)); // 1000 m altitude in mm
+ QCOMPARE(1013,altitude_to_pressure(0)); // sea level
+}
+
+void TestAirPressure::testWriteReadBackAirPressure()
+{
+ struct dive *dive;
+ int32_t ap = 1111;
+ dive = get_dive(0);
+ QVERIFY(dive != NULL);
+ dive->selected = true;
+ dive->surface_pressure.mbar = ap;
+ QCOMPARE(save_dives("./testout.ssrf"), 0);
+ clear_dive_file_data();
+ QCOMPARE(parse_file("./testout.ssrf", &dive_table, &trip_table, &dive_site_table), 0);
+ dive = get_dive(0);
+ QVERIFY(dive != NULL);
+ dive->selected = true;
+ QCOMPARE(ap, dive->surface_pressure.mbar);
+}
+
+QTEST_GUILESS_MAIN(TestAirPressure)
diff --git a/tests/testAirPressure.h b/tests/testAirPressure.h
new file mode 100644
index 000000000..18544eb47
--- /dev/null
+++ b/tests/testAirPressure.h
@@ -0,0 +1,19 @@
+// SPDX-License-Identifier: GPL-2.0
+#ifndef TESTPICTURE_H
+#define TESTPICTURE_H
+
+#include <QtTest>
+
+class TestAirPressure : public QObject {
+ Q_OBJECT
+private slots:
+ void initTestCase();
+ void get_dives();
+ void testReadAirPressure();
+ void testWriteReadBackAirPressure();
+ void testConvertAltitudetoAirPressure();
+};
+
+#endif
+
+