aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--desktop-widgets/divelogexportdialog.cpp191
1 files changed, 177 insertions, 14 deletions
diff --git a/desktop-widgets/divelogexportdialog.cpp b/desktop-widgets/divelogexportdialog.cpp
index 890bfa0f7..ec591ba53 100644
--- a/desktop-widgets/divelogexportdialog.cpp
+++ b/desktop-widgets/divelogexportdialog.cpp
@@ -3,6 +3,7 @@
#include <QShortcut>
#include <QSettings>
#include <QtConcurrent>
+#include <string.h> // Allows string comparisons and substitutions in TeX export
#include "desktop-widgets/divelogexportdialog.h"
#include "core/divelogexportlogic.h"
@@ -13,13 +14,14 @@
#include "core/save-html.h"
#include "desktop-widgets/mainwindow.h"
#include "profile-widget/profilewidget2.h"
+#include "core/dive.h" // Allows access to helper functions in TeX export.
-
-#define GET_UNIT(name, field, f, t) \
- v = settings.value(QString(name)); \
- if (v.isValid()) \
+// Retrieves the current unit settings defined in the Subsurface preferences.
+#define GET_UNIT(name, field, f, t) \
+ v = settings.value(QString(name)); \
+ if (v.isValid()) \
field = (v.toInt() == 0) ? (t) : (f); \
- else \
+ else \
field = default_prefs.units.field
DiveLogExportDialog::DiveLogExportDialog(QWidget *parent) : QDialog(parent),
@@ -237,7 +239,10 @@ void DiveLogExportDialog::export_TeX(const char *filename, const bool selected_o
{
FILE *f;
struct dive *dive;
+ struct units *units = get_units();
+ const char *unit;
int i;
+ int tmp;
bool need_pagebreak = false;
struct membuffer buf = {};
@@ -245,7 +250,52 @@ void DiveLogExportDialog::export_TeX(const char *filename, const bool selected_o
put_format(&buf, "\\input subsurfacetemplate\n");
put_format(&buf, "%% This is a plain TeX file. Compile with pdftex, not pdflatex!\n");
put_format(&buf, "%% You will also need a subsurfacetemplate.tex in the current directory.\n");
- put_format(&buf, "%% You can downlaod an example from http://www.atdotde.de/~robert/subsurfacetemplate\n%%\n");
+ put_format(&buf, "%% You can download an example from http://www.atdotde.de/~robert/subsurfacetemplate\n%%\n");
+ put_format(&buf, "%%\n");
+ put_format(&buf, "%% Notes: TeX/LaTex will not render the degree symbol correctly by default. In LaTeX, you may\n");
+ put_format(&buf, "%% add the following line to the end of the preamble of your template to ensure correct output:\n");
+ put_format(&buf, "%% \\usepackage[utf8]{inputenc}\n");
+ put_format(&buf, "%% \\usepackage{gensymb}\n");
+ put_format(&buf, "%% \\DeclareUnicodeCharacter{00B0}{\degree}\n"); //replaces ° with \degree
+ put_format(&buf, "%%\n");
+
+ /* Define text fields with the units used for export. These values are set in the Subsurface Preferences
+ * and the text fields created here are included in the data fields below.
+ */
+ put_format(&buf, "\n%% These fields contain the units used in other fields below. They may be\n");
+ put_format(&buf, "%% referenced as needed in TeX templates.\n");
+ put_format(&buf, "%% \n");
+ put_format(&buf, "%% By default, Subsurface exports units of volume as \"ℓ\" and \"cuft\", which do\n");
+ put_format(&buf, "%% not render well in TeX/LaTeX. The code below substitutes \"L\" and \"ft$^{3}$\",\n");
+ put_format(&buf, "%% respectively. If you wish to display the original values, you may edit this\n");
+ put_format(&buf, "%% list and all calls to those units will be updated in your document.\n");
+
+ tmp = get_depth_units(1, NULL, &unit);
+ put_format(&buf, "\\def\\depthunit{%s}\n", unit);
+ tmp = get_weight_units(1, NULL, &unit);
+ put_format(&buf, "\\def\\weightunit{%s}\n", unit);
+ tmp = get_pressure_units(1, &unit);
+ put_format(&buf, "\\def\\pressureunit{%s}\n", unit);
+ tmp = get_temp_units(1, &unit);
+ put_format(&buf, "\\def\\temperatureunit{%s}\n", unit);
+ tmp = get_volume_units(1, NULL, &unit);
+ if (strcmp(unit, "ℓ") == 0)
+ {
+ put_format(&buf, "\\def\\volumeunit{L}\n");
+ }
+ else if (strcmp(unit, "cuft") == 0)
+ {
+ put_format(&buf, "\\def\\volumeunit{ft$^{3}$}\n");
+ }
+ else
+ {
+ put_format(&buf, "\\def\\volumeunit{%s}\n", unit);
+ }
+ tmp = get_vertical_speed_units(1, NULL, &unit);
+ put_format(&buf, "\\def\\verticalspeedunit{%s}\n", unit);
+
+ put_format(&buf, "\n%%%%%%%%%% Begin Dive Data: %%%%%%%%%%\n");
+
for_each_dive (i, dive) {
if (selected_only && !dive->selected)
continue;
@@ -259,7 +309,6 @@ void DiveLogExportDialog::export_TeX(const char *filename, const bool selected_o
pix.save(filename.arg(dive->number));
-
struct tm tm;
utc_mkdate(dive->when, &tm);
@@ -275,31 +324,145 @@ void DiveLogExportDialog::export_TeX(const char *filename, const bool selected_o
QString star = "*";
QString viz = star.repeated(dive->visibility);
- int i;
+ QString rating = star.repeated(dive->rating);
- for (i = 0; i < MAX_CYLINDERS; i++)
- if (is_cylinder_used(dive, i))
- delta_p.mbar += dive->cylinder[i].start.mbar - dive->cylinder[i].end.mbar;
+ int i;
+ int qty_cyl;
+ int qty_weight;
+ float total_weight;
if (need_pagebreak)
put_format(&buf, "\\vfill\\eject\n");
need_pagebreak = true;
+ put_format(&buf, "\n%% Time, Date, and location:\n");
put_format(&buf, "\\def\\date{%04u-%02u-%02u}\n",
tm.tm_year, tm.tm_mon+1, tm.tm_mday);
put_format(&buf, "\\def\\number{%d}\n", dive->number);
put_format(&buf, "\\def\\place{%s}\n", site ? site->name : "");
put_format(&buf, "\\def\\spot{}\n");
+ put_format(&buf, "\\def\\sitename{%s}\n", site ? site->name : "");
+ site ? put_format(&buf, "\\def\\gpslat{%f}\n", site->latitude.udeg / 1000000.0) : put_format(&buf, "\\def\\gpslat{}\n");
+ site ? put_format(&buf, "\\def\\gpslon{%f}\n", site->longitude.udeg / 1000000.0) : put_format(&buf, "\\def\\gpslon{}\n");
+ put_format(&buf, "\\def\\gpslat{%f}\n", site ? site->latitude.udeg / 1000000.0 : 0);
+ put_format(&buf, "\\def\\gpslon{%f}\n", site ? site->longitude.udeg / 1000000.0 : 0);
+ put_format(&buf, "\\def\\computer{%s}\n", dive->dc.model);
put_format(&buf, "\\def\\country{%s}\n", country.toUtf8().data());
- put_format(&buf, "\\def\\entrance{}\n");
put_format(&buf, "\\def\\time{%u:%02u}\n", FRACTION(dive->duration.seconds, 60));
- put_format(&buf, "\\def\\depth{%u.%01um}\n", FRACTION(dive->maxdepth.mm / 100, 10));
- put_format(&buf, "\\def\\gasuse{%u.%01ubar}\n", FRACTION(delta_p.mbar / 100, 10));
+
+ // Code has generally been reworked to use helper functions to access data, and to print a blank field "{}" if data is not plausible (i.e. 0 deg K)
+ put_format(&buf, "\n%% Dive Profile Details:\n");
+ get_temp_units(dive->maxtemp.mkelvin, &unit) > 0 ? put_format(&buf, "\\def\\maxtemp{%.1f\\temperatureunit}\n", get_temp_units(dive->maxtemp.mkelvin, &unit)) : put_format(&buf, "\\def\\maxtemp{}\n");
+ get_temp_units(dive->mintemp.mkelvin, &unit) > 0 ? put_format(&buf, "\\def\\mintemp{%.1f\\temperatureunit}\n", get_temp_units(dive->mintemp.mkelvin, &unit)) : put_format(&buf, "\\def\\mintemp{}\n");
+ get_temp_units(dive->watertemp.mkelvin, &unit) > 0 ? put_format(&buf, "\\def\\watertemp{%.1f\\temperatureunit}\n", get_temp_units(dive->watertemp.mkelvin, &unit)) : put_format(&buf, "\\def\\watertemp{}\n");
+ get_temp_units(dive->airtemp.mkelvin, &unit) > 0 ? put_format(&buf, "\\def\\airtemp{%.1f\\temperatureunit}\n", get_temp_units(dive->airtemp.mkelvin, &unit)) : put_format(&buf, "\\def\\airtemp{}\n");
+ get_depth_units(dive->maxdepth.mm, NULL, &unit) > 0 ? put_format(&buf, "\\def\\maximumdepth{%.1f \\depthunit}\n", get_depth_units(dive->maxdepth.mm, NULL, &unit)) : put_format(&buf, "\\def\\maximumdepth{}\n");
+ get_depth_units(dive->meandepth.mm, NULL, &unit) > 0 ? put_format(&buf, "\\def\\meandepth{%.1f \\depthunit}\n", get_depth_units(dive->meandepth.mm, NULL, &unit)) : put_format(&buf, "\\def\\meandepth{}\n");
+
+ // HERE BE TROUBLE
+ //Code block for misc dive parameters
+ put_format(&buf, "\\def\\type{%s}\n", dive->tag_list ? dive->tag_list->tag->name : ""); // this currently prints only a single tag.
+ put_format(&buf, "\\def\\maxtemp{%.2f}\n", (dive->maxtemp.mkelvin) ? (dive->maxtemp.mkelvin / 1000.0) - 273.15 : 0);
+ put_format(&buf, "\\def\\mintemp{%.2f}\n", (dive->mintemp.mkelvin) ? (dive->mintemp.mkelvin / 1000.0) - 273.15 : 0);
+ put_format(&buf, "\\def\\watertemp{%.2f}\n", (dive->watertemp.mkelvin) ? (dive->watertemp.mkelvin / 1000.0) - 273.15 : 0);
+ put_format(&buf, "\\def\\airtemp{%.2f}\n", (dive->airtemp.mkelvin) ? (dive->airtemp.mkelvin / 1000.0) - 273.15 : 0);
+ put_format(&buf, "\\def\\maxdepth{%u.%01u m}\n", FRACTION(dive->maxdepth.mm / 100, 10));
+ put_format(&buf, "\\def\\avedepth{%u.%01u m}\n", FRACTION(dive->meandepth.mm / 100, 10));
+
+ //Code block prints start/end press. for all cylinders used, number of cyl. used, SAC, and total delta_p
+ qty_cyl = 0;
+ for (i = 0; i < MAX_CYLINDERS; i++)
+ if (is_cylinder_used(dive, i)){
+ put_format(&buf, "\\def\\cyl%ddescription{%s}\n", i + 1, dive->cylinder[i].type.description);
+ if (dive->cylinder[i].gasmix.o2.permille > 0){ //This code assumes that all gas must have oxygen, so a zero value indicated that the gas in question is AIR
+ put_format(&buf, "\\def\\cyl%dmixO2{%u\%}\n", i + 1, FRACTION(dive->cylinder[i].gasmix.o2.permille, 10));
+ put_format(&buf, "\\def\\cyl%dmixN2{%u\%}\n", i + 1, FRACTION(1000 - dive->cylinder[i].gasmix.o2.permille - dive->cylinder[i].gasmix.he.permille, 10));
+ put_format(&buf, "\\def\\cyl%dmixHe{%u\%}\n", i + 1, FRACTION(dive->cylinder[i].gasmix.he.permille, 10));
+ } else {
+ put_format(&buf, "\\def\\cyl%dmixO2{21\%}\n", i + 1);
+ put_format(&buf, "\\def\\cyl%dmixN2{79\%}\n", i + 1);
+ put_format(&buf, "\\def\\cyl%dmixHe{0\%}\n", i + 1);
+ }
+ delta_p.mbar += dive->cylinder[i].start.mbar - dive->cylinder[i].end.mbar;
+ put_format(&buf, "\\def\\cyl%dstartpress{%u.%01u bar}\n", i + 1, FRACTION(dive->cylinder[i].start.mbar / 100, 10));
+ put_format(&buf, "\\def\\cyl%dendpress{%u.%01u bar}\n", i + 1, FRACTION(dive->cylinder[i].end.mbar / 100, 10));
+ qty_cyl += 1;
+ }
+ put_format(&buf, "\\def\\qtycyl{%d}\n", qty_cyl);
+ put_format(&buf, "\\def\\gasuse{%u.%01u bar}\n", FRACTION(delta_p.mbar / 100, 10));
put_format(&buf, "\\def\\sac{%u.%01u l/min}\n", FRACTION(dive->sac/100,10));
+
+ //Code block prints all weights used.
+ qty_weight = 0;
+ total_weight = 0;
+ for (i = 0; i < MAX_WEIGHTSYSTEMS; i++)
+ if (dive->weightsystem[i].weight.grams != NULL){
+ put_format(&buf, "\\def\\weight%dtype{%s}\n", i + 1, dive->weightsystem[i].description);
+ put_format(&buf, "\\def\\weight%damt{%u.%01u kg}\n", i + 1, FRACTION(dive->weightsystem[i].weight.grams, 1000));
+ qty_weight += 1;
+ total_weight += dive->weightsystem[i].weight.grams;
+ }
+
+ put_format(&buf, "\\def\\qtyweights{%d}\n", qty_weight);
+ put_format(&buf, "\\def\\totalweight{%u.%01u kg}\n", FRACTION(total_weight, 1000));
+
put_format(&buf, "\\def\\type{%s}\n", dive->tag_list ? dive->tag_list->tag->name : "");
put_format(&buf, "\\def\\viz{%s}\n", viz.toUtf8().data());
+ put_format(&buf, "\\def\\rating{%s}\n", rating.toUtf8().data());
put_format(&buf, "\\def\\plot{\\includegraphics[width=9cm,height=4cm]{profile%d}}\n", dive->number);
put_format(&buf, "\\def\\comment{%s}\n", dive->notes ? dive->notes : "");
put_format(&buf, "\\def\\buddy{%s}\n", dive->buddy ? dive->buddy : "");
+ put_format(&buf, "\\def\\divemaster{%s}\n", dive->divemaster ? dive->divemaster : "");
+ put_format(&buf, "\\def\\suit{%s}\n", dive->suit ? dive->suit : "");
+
+ //Code block prints start/end press. for all cylinders defined in dive, number of cyl. used, SAC, and total delta_p
+ put_format(&buf, "\n%% Gas use information:\n");
+ qty_cyl = 0;
+ for (i = 0; i < MAX_CYLINDERS; i++){
+
+ /* Previously, this IF statement used "is_cylinder_used(...)" to print only the cylinders where pressure
+ * identified by Subsurface as being used. Now it prints all cylinders that are associated with the
+ * dive. This way, bailout cylinders that are not needed are still shown, rather than disappearing,*/
+ if (dive->cylinder[i].type.description != NULL){
+ put_format(&buf, "\\def\\cyl%ddescription{%s}\n", i + 1, dive->cylinder[i].type.description);
+ put_format(&buf, "\\def\\cyl%dmixO2{%.1f\\%}\n", i + 1, get_o2(&dive->cylinder[i].gasmix)/10.0);
+ put_format(&buf, "\\def\\cyl%dmixHe{%.1f\\%}\n", i + 1, get_he(&dive->cylinder[i].gasmix)/10.0);
+ put_format(&buf, "\\def\\cyl%dmixN2{%.1f\\%}\n", i + 1, (100.0 - (get_o2(&dive->cylinder[i].gasmix)/10.0) - (get_he(&dive->cylinder[i].gasmix)/10.0)));
+ delta_p.mbar += dive->cylinder[i].start.mbar - dive->cylinder[i].end.mbar;
+ put_format(&buf, "\\def\\cyl%dstartpress{%.1f \\pressureunit}\n", i + 1, get_pressure_units(dive->cylinder[i].start.mbar, &unit)/1.0);
+ put_format(&buf, "\\def\\cyl%dendpress{%.1f \\pressureunit}\n", i + 1, get_pressure_units(dive->cylinder[i].end.mbar, &unit)/1.0);
+ qty_cyl += 1;
+ }
+ }
+ put_format(&buf, "\\def\\qtycyl{%d}\n", qty_cyl);
+ put_format(&buf, "\\def\\gasuse{%.1f \\pressureunit}\n", get_pressure_units(delta_p.mbar, &unit)/1.0);
+ put_format(&buf, "\\def\\sac{%.2f \\volumeunit/min}\n", get_volume_units(dive->sac, NULL, &unit));
+
+ //Code block prints all weights listed in dive.
+ put_format(&buf, "\n%% Weighting information:\n");
+ qty_weight = 0;
+ total_weight = 0;
+ for (i = 0; i < MAX_WEIGHTSYSTEMS; i++){
+ if (dive->weightsystem[i].weight.grams != NULL){
+ put_format(&buf, "\\def\\weight%dtype{%s}\n", i + 1, dive->weightsystem[i].description);
+ put_format(&buf, "\\def\\weight%damt{%.3f \\weightunit}\n", i + 1, get_weight_units(dive->weightsystem[i].weight.grams, NULL, &unit));
+ qty_weight += 1;
+ total_weight += get_weight_units(dive->weightsystem[i].weight.grams, NULL, &unit);
+ }
+ }
+ put_format(&buf, "\\def\\qtyweights{%d}\n", qty_weight);
+ put_format(&buf, "\\def\\totalweight{%.2f \\weightunit}\n", total_weight);
+ unit = "";
+
+ // Deprecated fields
+ put_format(&buf, "\n%% Deprecated Fields - kept to maintain compatibility with legacy templates:\n");
+ put_format(&buf, "%% The following fields are deprecated and may not return any value!\n");
+ put_format(&buf, "%% They have been let here to preserve functionality in legacy templates.");
+ put_format(&buf, "%% Do not use these fields in future templates.\n");
+ put_format(&buf, "\\def\\spot{} %% Deprecated - does not return a value\n"); // Deprecated - remains for use in legacy templates
+ put_format(&buf, "\\def\\entrance{} %% Deprecated - does not return a value\n"); // Deprecated - remains for use in legacy templates
+ put_format(&buf, "\\def\\place{%s} %% Deprecated - use \\sitename instead\n", site ? site->name : ""); // Deprecated - remains for use in legacy templates
+ get_depth_units(dive->maxdepth.mm, NULL, &unit) > 0 ? put_format(&buf, "\\def\\depth{%.1f \\depthunit}%% Deprecated - use \\maximumdepth instead\n", get_depth_units(dive->maxdepth.mm, NULL, &unit)) : put_format(&buf, "\\def\\depth{} %% Deprecated - use \\maximumdepth instead\n"); // Deprecated - remains for use in legacy templates
+
put_format(&buf, "\\page\n");
}