Massive automated whitespace cleanup

I know everyone will hate it.
Go ahead. Complain. Call me names.
At least now things are consistent and reproducible.
If you want changes, have your complaint come with a patch to
scripts/whitespace.pl so that we can automate it.

Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
This commit is contained in:
Dirk Hohndel 2014-02-27 20:09:57 -08:00
parent 006265d7a0
commit 76e6420f6b
114 changed files with 4370 additions and 3717 deletions

View file

@ -30,12 +30,12 @@
* 230 bytes and 234 bytes respectively. * 230 bytes and 234 bytes respectively.
*/ */
static unsigned int partial_decode(unsigned int start, unsigned int end, static unsigned int partial_decode(unsigned int start, unsigned int end,
const unsigned char *decode, unsigned offset, unsigned mod, const unsigned char *decode, unsigned offset, unsigned mod,
const unsigned char *buf, unsigned int size, unsigned char *dst) const unsigned char *buf, unsigned int size, unsigned char *dst)
{ {
unsigned i, sum = 0; unsigned i, sum = 0;
for (i = start ; i < end; i++) { for (i = start; i < end; i++) {
unsigned char d = decode[offset++]; unsigned char d = decode[offset++];
if (i >= size) if (i >= size)
break; break;
@ -79,7 +79,7 @@ static int figure_out_modulus(const unsigned char *decode, const unsigned char *
return best; return best;
} }
#define hexchar(n) ("0123456789abcdef"[(n)&15]) #define hexchar(n) ("0123456789abcdef"[(n) & 15])
static int show_line(unsigned offset, const unsigned char *data, unsigned size, int show_empty) static int show_line(unsigned offset, const unsigned char *data, unsigned size, int show_empty)
{ {
@ -94,11 +94,11 @@ static int show_line(unsigned offset, const unsigned char *data, unsigned size,
memset(buffer, ' ', sizeof(buffer)); memset(buffer, ' ', sizeof(buffer));
off = sprintf(buffer, "%06x ", offset); off = sprintf(buffer, "%06x ", offset);
for (i = 0; i < size; i++) { for (i = 0; i < size; i++) {
char *hex = buffer + off + 3*i; char *hex = buffer + off + 3 * i;
char *asc = buffer + off + 50 + i; char *asc = buffer + off + 50 + i;
unsigned char byte = data[i]; unsigned char byte = data[i];
hex[0] = hexchar(byte>>4); hex[0] = hexchar(byte >> 4);
hex[1] = hexchar(byte); hex[1] = hexchar(byte);
bits |= byte; bits |= byte;
if (byte < 32 || byte > 126) if (byte < 32 || byte > 126)
@ -125,13 +125,13 @@ static void cochran_debug_write(const char *filename, const unsigned char *data,
} }
static void parse_cochran_header(const char *filename, static void parse_cochran_header(const char *filename,
const unsigned char *decode, unsigned mod, const unsigned char *decode, unsigned mod,
const unsigned char *in, unsigned size) const unsigned char *in, unsigned size)
{ {
char *buf = malloc(size); char *buf = malloc(size);
/* Do the "null decode" using a one-byte decode array of '\0' */ /* Do the "null decode" using a one-byte decode array of '\0' */
partial_decode(0 , 0x0b14, "", 0, 1, in, size, buf); partial_decode(0, 0x0b14, "", 0, 1, in, size, buf);
/* /*
* The header scrambling is different form the dive * The header scrambling is different form the dive
@ -142,7 +142,7 @@ static void parse_cochran_header(const char *filename,
partial_decode(0x1b14, 0x2b14, decode, 0, mod, in, size, buf); partial_decode(0x1b14, 0x2b14, decode, 0, mod, in, size, buf);
partial_decode(0x2b14, 0x3b14, decode, 0, mod, in, size, buf); partial_decode(0x2b14, 0x3b14, decode, 0, mod, in, size, buf);
partial_decode(0x3b14, 0x5414, decode, 0, mod, in, size, buf); partial_decode(0x3b14, 0x5414, decode, 0, mod, in, size, buf);
partial_decode(0x5414, size, decode, 0, mod, in, size, buf); partial_decode(0x5414, size, decode, 0, mod, in, size, buf);
printf("\n%s, header\n\n", filename); printf("\n%s, header\n\n", filename);
cochran_debug_write(filename, buf, size); cochran_debug_write(filename, buf, size);
@ -204,13 +204,13 @@ static void cochran_profile_write(const unsigned char *buf, int size)
for (i = 0; i < size; i++) { for (i = 0; i < size; i++) {
unsigned char c = buf[i]; unsigned char c = buf[i];
printf("%d %d\n", printf("%d %d\n",
c >> 6, c & 0x3f); c >> 6, c & 0x3f);
} }
} }
static void parse_cochran_dive(const char *filename, int dive, static void parse_cochran_dive(const char *filename, int dive,
const unsigned char *decode, unsigned mod, const unsigned char *decode, unsigned mod,
const unsigned char *in, unsigned size) const unsigned char *in, unsigned size)
{ {
char *buf = malloc(size); char *buf = malloc(size);
#ifdef DON #ifdef DON
@ -229,7 +229,7 @@ static void parse_cochran_dive(const char *filename, int dive,
* the same way the file size is off by one. It's as if the * the same way the file size is off by one. It's as if the
* cochran software forgot to write one byte at the beginning. * cochran software forgot to write one byte at the beginning.
*/ */
partial_decode(0 , 0x0fff, decode, 1, mod, in, size, buf); partial_decode(0, 0x0fff, decode, 1, mod, in, size, buf);
partial_decode(0x0fff, 0x1fff, decode, 0, mod, in, size, buf); partial_decode(0x0fff, 0x1fff, decode, 0, mod, in, size, buf);
partial_decode(0x1fff, 0x2fff, decode, 0, mod, in, size, buf); partial_decode(0x1fff, 0x2fff, decode, 0, mod, in, size, buf);
partial_decode(0x2fff, 0x48ff, decode, 0, mod, in, size, buf); partial_decode(0x2fff, 0x48ff, decode, 0, mod, in, size, buf);
@ -241,7 +241,7 @@ static void parse_cochran_dive(const char *filename, int dive,
* so this just descrambles part of it: * so this just descrambles part of it:
*/ */
partial_decode(0x48ff, offset, decode, 0, mod, in, size, buf); partial_decode(0x48ff, offset, decode, 0, mod, in, size, buf);
partial_decode(offset, size, decode, 0, mod, in, size, buf); partial_decode(offset, size, decode, 0, mod, in, size, buf);
printf("\n%s, dive %d\n\n", filename, dive); printf("\n%s, dive %d\n\n", filename, dive);
cochran_debug_write(filename, buf, size); cochran_debug_write(filename, buf, size);
@ -271,12 +271,12 @@ int try_to_open_cochran(const char *filename, struct memblock *mem, GError **err
for (i = 0; i < 65534; i++) { for (i = 0; i < 65534; i++) {
dive1 = offsets[i]; dive1 = offsets[i];
dive2 = offsets[i+1]; dive2 = offsets[i + 1];
if (dive2 < dive1) if (dive2 < dive1)
break; break;
if (dive2 > mem->size) if (dive2 > mem->size)
break; break;
parse_cochran_dive(filename, i+1, decode, mod, mem->buffer + dive1, dive2 - dive1); parse_cochran_dive(filename, i + 1, decode, mod, mem->buffer + dive1, dive2 - dive1);
} }
exit(0); exit(0);

80
color.h
View file

@ -7,54 +7,54 @@
#include <QColor> #include <QColor>
// Greens // Greens
#define CAMARONE1 QColor::fromRgbF( 0.0, 0.4, 0.0, 1 ) #define CAMARONE1 QColor::fromRgbF(0.0, 0.4, 0.0, 1)
#define FUNGREEN1 QColor::fromRgbF( 0.0, 0.4, 0.2, 1 ) #define FUNGREEN1 QColor::fromRgbF(0.0, 0.4, 0.2, 1)
#define FUNGREEN1_HIGH_TRANS QColor::fromRgbF( 0.0, 0.4, 0.2, 0.25 ) #define FUNGREEN1_HIGH_TRANS QColor::fromRgbF(0.0, 0.4, 0.2, 0.25)
#define KILLARNEY1 QColor::fromRgbF( 0.2, 0.4, 0.2, 1 ) #define KILLARNEY1 QColor::fromRgbF(0.2, 0.4, 0.2, 1)
#define APPLE1 QColor::fromRgbF( 0.2, 0.6, 0.2, 1 ) #define APPLE1 QColor::fromRgbF(0.2, 0.6, 0.2, 1)
#define APPLE1_MED_TRANS QColor::fromRgbF( 0.2, 0.6, 0.2, 0.5 ) #define APPLE1_MED_TRANS QColor::fromRgbF(0.2, 0.6, 0.2, 0.5)
#define APPLE1_HIGH_TRANS QColor::fromRgbF( 0.2, 0.6, 0.2, 0.25 ) #define APPLE1_HIGH_TRANS QColor::fromRgbF(0.2, 0.6, 0.2, 0.25)
#define LIMENADE1 QColor::fromRgbF( 0.4, 0.8, 0.0, 1 ) #define LIMENADE1 QColor::fromRgbF(0.4, 0.8, 0.0, 1)
#define ATLANTIS1 QColor::fromRgbF( 0.4, 0.8, 0.2, 1 ) #define ATLANTIS1 QColor::fromRgbF(0.4, 0.8, 0.2, 1)
#define ATLANTIS2 QColor::fromRgbF( 0.6, 0.8, 0.2, 1 ) #define ATLANTIS2 QColor::fromRgbF(0.6, 0.8, 0.2, 1)
#define RIOGRANDE1 QColor::fromRgbF( 0.8, 0.8, 0.0, 1 ) #define RIOGRANDE1 QColor::fromRgbF(0.8, 0.8, 0.0, 1)
#define EARLSGREEN1 QColor::fromRgbF( 0.8, 0.8, 0.2, 1 ) #define EARLSGREEN1 QColor::fromRgbF(0.8, 0.8, 0.2, 1)
#define FORESTGREEN1 QColor::fromRgbF( 0.1, 0.5, 0.1, 1 ) #define FORESTGREEN1 QColor::fromRgbF(0.1, 0.5, 0.1, 1)
// Reds // Reds
#define PERSIANRED1 QColor::fromRgbF( 0.8, 0.2, 0.2, 1 ) #define PERSIANRED1 QColor::fromRgbF(0.8, 0.2, 0.2, 1)
#define TUSCANY1 QColor::fromRgbF( 0.8, 0.4, 0.2, 1 ) #define TUSCANY1 QColor::fromRgbF(0.8, 0.4, 0.2, 1)
#define PIRATEGOLD1 QColor::fromRgbF( 0.8, 0.5, 0.0, 1 ) #define PIRATEGOLD1 QColor::fromRgbF(0.8, 0.5, 0.0, 1)
#define HOKEYPOKEY1 QColor::fromRgbF( 0.8, 0.6, 0.2, 1 ) #define HOKEYPOKEY1 QColor::fromRgbF(0.8, 0.6, 0.2, 1)
#define CINNABAR1 QColor::fromRgbF( 0.9, 0.3, 0.2, 1 ) #define CINNABAR1 QColor::fromRgbF(0.9, 0.3, 0.2, 1)
#define REDORANGE1 QColor::fromRgbF( 1.0, 0.2, 0.2, 1 ) #define REDORANGE1 QColor::fromRgbF(1.0, 0.2, 0.2, 1)
#define REDORANGE1_HIGH_TRANS QColor::fromRgbF( 1.0, 0.2, 0.2, 0.25 ) #define REDORANGE1_HIGH_TRANS QColor::fromRgbF(1.0, 0.2, 0.2, 0.25)
#define REDORANGE1_MED_TRANS QColor::fromRgbF( 1.0, 0.2, 0.2, 0.5 ) #define REDORANGE1_MED_TRANS QColor::fromRgbF(1.0, 0.2, 0.2, 0.5)
#define RED1_MED_TRANS QColor::fromRgbF( 1.0, 0.0, 0.0, 0.5 ) #define RED1_MED_TRANS QColor::fromRgbF(1.0, 0.0, 0.0, 0.5)
#define RED1 QColor::fromRgbF( 1.0, 0.0, 0.0, 1 ) #define RED1 QColor::fromRgbF(1.0, 0.0, 0.0, 1)
// Monochromes // Monochromes
#define BLACK1 QColor::fromRgbF( 0.0, 0.0, 0.0, 1 ) #define BLACK1 QColor::fromRgbF(0.0, 0.0, 0.0, 1)
#define BLACK1_LOW_TRANS QColor::fromRgbF( 0.0, 0.0, 0.0, 0.75 ) #define BLACK1_LOW_TRANS QColor::fromRgbF(0.0, 0.0, 0.0, 0.75)
#define BLACK1_HIGH_TRANS QColor::fromRgbF( 0.0, 0.0, 0.0, 0.25 ) #define BLACK1_HIGH_TRANS QColor::fromRgbF(0.0, 0.0, 0.0, 0.25)
#define TUNDORA1_MED_TRANS QColor::fromRgbF( 0.3, 0.3, 0.3, 0.5 ) #define TUNDORA1_MED_TRANS QColor::fromRgbF(0.3, 0.3, 0.3, 0.5)
#define MERCURY1_MED_TRANS QColor::fromRgbF( 0.9, 0.9, 0.9, 0.5 ) #define MERCURY1_MED_TRANS QColor::fromRgbF(0.9, 0.9, 0.9, 0.5)
#define CONCRETE1_LOWER_TRANS QColor::fromRgbF( 0.95, 0.95, 0.95, 0.9 ) #define CONCRETE1_LOWER_TRANS QColor::fromRgbF(0.95, 0.95, 0.95, 0.9)
#define WHITE1_MED_TRANS QColor::fromRgbF( 1.0, 1.0, 1.0, 0.5 ) #define WHITE1_MED_TRANS QColor::fromRgbF(1.0, 1.0, 1.0, 0.5)
#define WHITE1 QColor::fromRgbF( 1.0, 1.0, 1.0, 1 ) #define WHITE1 QColor::fromRgbF(1.0, 1.0, 1.0, 1)
// Blues // Blues
#define GOVERNORBAY2 QColor::fromRgbF( 0.2, 0.2, 0.7, 1 ) #define GOVERNORBAY2 QColor::fromRgbF(0.2, 0.2, 0.7, 1)
#define GOVERNORBAY1_MED_TRANS QColor::fromRgbF( 0.2, 0.2, 0.8, 0.5 ) #define GOVERNORBAY1_MED_TRANS QColor::fromRgbF(0.2, 0.2, 0.8, 0.5)
#define ROYALBLUE2 QColor::fromRgbF( 0.2, 0.2, 0.9, 1 ) #define ROYALBLUE2 QColor::fromRgbF(0.2, 0.2, 0.9, 1)
#define ROYALBLUE2_LOW_TRANS QColor::fromRgbF( 0.2, 0.2, 0.9, 0.75 ) #define ROYALBLUE2_LOW_TRANS QColor::fromRgbF(0.2, 0.2, 0.9, 0.75)
// Yellows / BROWNS // Yellows / BROWNS
#define SPRINGWOOD1 QColor::fromRgbF( 0.95, 0.95, 0.9, 1 ) #define SPRINGWOOD1 QColor::fromRgbF(0.95, 0.95, 0.9, 1)
#define BROOM1_LOWER_TRANS QColor::fromRgbF( 1.0, 1.0, 0.1, 0.9 ) #define BROOM1_LOWER_TRANS QColor::fromRgbF(1.0, 1.0, 0.1, 0.9)
#define PEANUT QColor::fromRgbF( 0.5, 0.2, 0.1, 1.0 ) #define PEANUT QColor::fromRgbF(0.5, 0.2, 0.1, 1.0)
#define PEANUT_MED_TRANS QColor::fromRgbF( 0.5, 0.2, 0.1, 0.5 ) #define PEANUT_MED_TRANS QColor::fromRgbF(0.5, 0.2, 0.1, 0.5)
// Magentas // Magentas
#define MEDIUMREDVIOLET1_HIGHER_TRANS QColor::fromRgbF( 0.7, 0.2, 0.7, 0.1 ) #define MEDIUMREDVIOLET1_HIGHER_TRANS QColor::fromRgbF(0.7, 0.2, 0.7, 0.1)
#endif // COLOR_H #endif // COLOR_H

88
deco.c
View file

@ -21,57 +21,59 @@
//! Option structure for Buehlmann decompression. //! Option structure for Buehlmann decompression.
struct buehlmann_config { struct buehlmann_config {
double satmult; //! safety at inert gas accumulation as percentage of effect (more than 100). double satmult; //! safety at inert gas accumulation as percentage of effect (more than 100).
double desatmult; //! safety at inert gas depletion as percentage of effect (less than 100). double desatmult; //! safety at inert gas depletion as percentage of effect (less than 100).
unsigned int last_deco_stop_in_mtr; //! depth of last_deco_stop. unsigned int last_deco_stop_in_mtr; //! depth of last_deco_stop.
double gf_high; //! gradient factor high (at surface). double gf_high; //! gradient factor high (at surface).
double gf_low; //! gradient factor low (at bottom/start of deco calculation). double gf_low; //! gradient factor low (at bottom/start of deco calculation).
double gf_low_position_min; //! gf_low_position below surface_min_shallow. double gf_low_position_min; //! gf_low_position below surface_min_shallow.
bool gf_low_at_maxdepth; //! if true, gf_low applies at max depth instead of at deepest ceiling. bool gf_low_at_maxdepth; //! if true, gf_low applies at max depth instead of at deepest ceiling.
}; };
struct buehlmann_config buehlmann_config = { 1.0, 1.01, 0, 0.75, 0.35, 2.0, false }; struct buehlmann_config buehlmann_config = { 1.0, 1.01, 0, 0.75, 0.35, 2.0, false };
const double buehlmann_N2_a[] = {1.1696, 1.0, 0.8618, 0.7562, const double buehlmann_N2_a[] = { 1.1696, 1.0, 0.8618, 0.7562,
0.62, 0.5043, 0.441, 0.4, 0.62, 0.5043, 0.441, 0.4,
0.375, 0.35, 0.3295, 0.3065, 0.375, 0.35, 0.3295, 0.3065,
0.2835, 0.261, 0.248, 0.2327}; 0.2835, 0.261, 0.248, 0.2327 };
const double buehlmann_N2_b[] = {0.5578, 0.6514, 0.7222, 0.7825, const double buehlmann_N2_b[] = { 0.5578, 0.6514, 0.7222, 0.7825,
0.8126, 0.8434, 0.8693, 0.8910, 0.8126, 0.8434, 0.8693, 0.8910,
0.9092, 0.9222, 0.9319, 0.9403, 0.9092, 0.9222, 0.9319, 0.9403,
0.9477, 0.9544, 0.9602, 0.9653}; 0.9477, 0.9544, 0.9602, 0.9653 };
const double buehlmann_N2_t_halflife[] = {5.0, 8.0, 12.5, 18.5, const double buehlmann_N2_t_halflife[] = { 5.0, 8.0, 12.5, 18.5,
27.0, 38.3, 54.3, 77.0, 27.0, 38.3, 54.3, 77.0,
109.0, 146.0, 187.0, 239.0, 109.0, 146.0, 187.0, 239.0,
305.0, 390.0, 498.0, 635.0}; 305.0, 390.0, 498.0, 635.0 };
const double buehlmann_N2_factor_expositon_one_second[] = { const double buehlmann_N2_factor_expositon_one_second[] = {
2.30782347297664E-003, 1.44301447809736E-003, 9.23769302935806E-004, 6.24261986779007E-004, 2.30782347297664E-003, 1.44301447809736E-003, 9.23769302935806E-004, 6.24261986779007E-004,
4.27777107246730E-004, 3.01585140931371E-004, 2.12729727268379E-004, 1.50020603047807E-004, 4.27777107246730E-004, 3.01585140931371E-004, 2.12729727268379E-004, 1.50020603047807E-004,
1.05980191127841E-004, 7.91232600646508E-005, 6.17759153688224E-005, 4.83354552742732E-005, 1.05980191127841E-004, 7.91232600646508E-005, 6.17759153688224E-005, 4.83354552742732E-005,
3.78761777920511E-005, 2.96212356654113E-005, 2.31974277413727E-005, 1.81926738960225E-005}; 3.78761777920511E-005, 2.96212356654113E-005, 2.31974277413727E-005, 1.81926738960225E-005
};
const double buehlmann_He_a[] = { 1.6189, 1.383 , 1.1919, 1.0458, const double buehlmann_He_a[] = { 1.6189, 1.383, 1.1919, 1.0458,
0.922 , 0.8205, 0.7305, 0.6502, 0.922, 0.8205, 0.7305, 0.6502,
0.595 , 0.5545, 0.5333, 0.5189, 0.595, 0.5545, 0.5333, 0.5189,
0.5181, 0.5176, 0.5172, 0.5119}; 0.5181, 0.5176, 0.5172, 0.5119 };
const double buehlmann_He_b[] = {0.4770, 0.5747, 0.6527, 0.7223, const double buehlmann_He_b[] = { 0.4770, 0.5747, 0.6527, 0.7223,
0.7582, 0.7957, 0.8279, 0.8553, 0.7582, 0.7957, 0.8279, 0.8553,
0.8757, 0.8903, 0.8997, 0.9073, 0.8757, 0.8903, 0.8997, 0.9073,
0.9122, 0.9171, 0.9217, 0.9267}; 0.9122, 0.9171, 0.9217, 0.9267 };
const double buehlmann_He_t_halflife[] = {1.88, 3.02, 4.72, 6.99, const double buehlmann_He_t_halflife[] = { 1.88, 3.02, 4.72, 6.99,
10.21, 14.48, 20.53, 29.11, 10.21, 14.48, 20.53, 29.11,
41.20, 55.19, 70.69, 90.34, 41.20, 55.19, 70.69, 90.34,
115.29, 147.42, 188.24, 240.03}; 115.29, 147.42, 188.24, 240.03 };
const double buehlmann_He_factor_expositon_one_second[] = { const double buehlmann_He_factor_expositon_one_second[] = {
6.12608039419837E-003, 3.81800836683133E-003, 2.44456078654209E-003, 1.65134647076792E-003, 6.12608039419837E-003, 3.81800836683133E-003, 2.44456078654209E-003, 1.65134647076792E-003,
1.13084424730725E-003, 7.97503165599123E-004, 5.62552521860549E-004, 3.96776399429366E-004, 1.13084424730725E-003, 7.97503165599123E-004, 5.62552521860549E-004, 3.96776399429366E-004,
2.80360036664540E-004, 2.09299583354805E-004, 1.63410794820518E-004, 1.27869320250551E-004, 2.80360036664540E-004, 2.09299583354805E-004, 1.63410794820518E-004, 1.27869320250551E-004,
1.00198406028040E-004, 7.83611475491108E-005, 6.13689891868496E-005, 4.81280465299827E-005}; 1.00198406028040E-004, 7.83611475491108E-005, 6.13689891868496E-005, 4.81280465299827E-005
};
#define WV_PRESSURE 0.0627 // water vapor pressure in bar #define WV_PRESSURE 0.0627 // water vapor pressure in bar
#define DECO_STOPS_MULTIPLIER_MM 3000.0 #define DECO_STOPS_MULTIPLIER_MM 3000.0
@ -94,8 +96,7 @@ static double tissue_tolerance_calc(const struct dive *dive)
double gf_low = buehlmann_config.gf_low; double gf_low = buehlmann_config.gf_low;
double surface = get_surface_pressure_in_mbar(dive, true) / 1000.0; double surface = get_surface_pressure_in_mbar(dive, true) / 1000.0;
for (ci = 0; ci < 16; ci++) for (ci = 0; ci < 16; ci++) {
{
double tolerated; double tolerated;
tissue_inertgas_saturation = tissue_n2_sat[ci] + tissue_he_sat[ci]; tissue_inertgas_saturation = tissue_n2_sat[ci] + tissue_he_sat[ci];
@ -106,22 +107,21 @@ static double tissue_tolerance_calc(const struct dive *dive)
if (!buehlmann_config.gf_low_at_maxdepth) { if (!buehlmann_config.gf_low_at_maxdepth) {
double lowest_ceiling = (buehlmann_inertgas_b * tissue_inertgas_saturation - gf_low * buehlmann_inertgas_a * buehlmann_inertgas_b) / double lowest_ceiling = (buehlmann_inertgas_b * tissue_inertgas_saturation - gf_low * buehlmann_inertgas_a * buehlmann_inertgas_b) /
((1.0 - buehlmann_inertgas_b) * gf_low + buehlmann_inertgas_b); ((1.0 - buehlmann_inertgas_b) * gf_low + buehlmann_inertgas_b);
if (lowest_ceiling > gf_low_pressure_this_dive) if (lowest_ceiling > gf_low_pressure_this_dive)
gf_low_pressure_this_dive = lowest_ceiling; gf_low_pressure_this_dive = lowest_ceiling;
} }
tolerated = (-buehlmann_inertgas_a * buehlmann_inertgas_b * (gf_high * gf_low_pressure_this_dive - gf_low * surface) - tolerated = (-buehlmann_inertgas_a * buehlmann_inertgas_b * (gf_high * gf_low_pressure_this_dive - gf_low * surface) -
(1.0 - buehlmann_inertgas_b) * (gf_high - gf_low) * gf_low_pressure_this_dive * surface + (1.0 - buehlmann_inertgas_b) * (gf_high - gf_low) * gf_low_pressure_this_dive * surface +
buehlmann_inertgas_b * (gf_low_pressure_this_dive - surface) * tissue_inertgas_saturation) / buehlmann_inertgas_b * (gf_low_pressure_this_dive - surface) * tissue_inertgas_saturation) /
(-buehlmann_inertgas_a * buehlmann_inertgas_b * (gf_high - gf_low) + (-buehlmann_inertgas_a * buehlmann_inertgas_b * (gf_high - gf_low) +
(1.0 - buehlmann_inertgas_b)*(gf_low * gf_low_pressure_this_dive - gf_high * surface) + (1.0 - buehlmann_inertgas_b) * (gf_low * gf_low_pressure_this_dive - gf_high * surface) +
buehlmann_inertgas_b * (gf_low_pressure_this_dive - surface)); buehlmann_inertgas_b * (gf_low_pressure_this_dive - surface));
tolerated_by_tissue[ci] = tolerated; tolerated_by_tissue[ci] = tolerated;
if (tolerated > ret_tolerance_limit_ambient_pressure) if (tolerated > ret_tolerance_limit_ambient_pressure) {
{
ci_pointing_to_guiding_tissue = ci; ci_pointing_to_guiding_tissue = ci;
ret_tolerance_limit_ambient_pressure = tolerated; ret_tolerance_limit_ambient_pressure = tolerated;
} }
@ -151,7 +151,7 @@ double n2_factor(int period_in_seconds, int ci)
if (period_in_seconds != cache[ci].last_period) { if (period_in_seconds != cache[ci].last_period) {
cache[ci].last_period = period_in_seconds; cache[ci].last_period = period_in_seconds;
cache[ci].last_factor = 1 - pow(2.0, - period_in_seconds / (buehlmann_N2_t_halflife[ci] * 60)); cache[ci].last_factor = 1 - pow(2.0, -period_in_seconds / (buehlmann_N2_t_halflife[ci] * 60));
} }
return cache[ci].last_factor; return cache[ci].last_factor;
@ -166,7 +166,7 @@ double he_factor(int period_in_seconds, int ci)
if (period_in_seconds != cache[ci].last_period) { if (period_in_seconds != cache[ci].last_period) {
cache[ci].last_period = period_in_seconds; cache[ci].last_period = period_in_seconds;
cache[ci].last_factor = 1 - pow(2.0, - period_in_seconds / (buehlmann_He_t_halflife[ci] * 60)); cache[ci].last_factor = 1 - pow(2.0, -period_in_seconds / (buehlmann_He_t_halflife[ci] * 60));
} }
return cache[ci].last_factor; return cache[ci].last_factor;

View file

@ -63,19 +63,23 @@
*/ */
static int fill_samples(struct sample *s, int max_d, int avg_d, int max_t, double slope, double d_frac) static int fill_samples(struct sample *s, int max_d, int avg_d, int max_t, double slope, double d_frac)
{ {
double t_frac = max_t*(1-avg_d/(double)max_d); double t_frac = max_t * (1 - avg_d / (double)max_d);
int t1 = max_d / slope; int t1 = max_d / slope;
int t4 = max_t - t1*d_frac; int t4 = max_t - t1 * d_frac;
int t3 = t4-(t_frac-t1)/(1-d_frac); int t3 = t4 - (t_frac - t1) / (1 - d_frac);
int t2 = t3-t1*(1-d_frac); int t2 = t3 - t1 * (1 - d_frac);
if (t1 < 0 || t1 > t2 || t2 > t3 || t3 > t4 || t4 > max_t) if (t1 < 0 || t1 > t2 || t2 > t3 || t3 > t4 || t4 > max_t)
return 0; return 0;
s[1].time.seconds = t1; s[1].depth.mm = max_d; s[1].time.seconds = t1;
s[2].time.seconds = t2; s[2].depth.mm = max_d; s[1].depth.mm = max_d;
s[3].time.seconds = t3; s[3].depth.mm = max_d * d_frac; s[2].time.seconds = t2;
s[4].time.seconds = t4; s[4].depth.mm = max_d * d_frac; s[2].depth.mm = max_d;
s[3].time.seconds = t3;
s[3].depth.mm = max_d * d_frac;
s[4].time.seconds = t4;
s[4].depth.mm = max_d * d_frac;
return 1; return 1;
} }
@ -88,8 +92,10 @@ static void fill_samples_no_avg(struct sample *s, int max_d, int max_t, double s
{ {
// shallow or short dives are just trapecoids based on the given slope // shallow or short dives are just trapecoids based on the given slope
if (max_d < 10000 || max_t < 600) { if (max_d < 10000 || max_t < 600) {
s[1].time.seconds = max_d / slope; s[1].depth.mm = max_d; s[1].time.seconds = max_d / slope;
s[2].time.seconds = max_t - max_d / slope; s[2].depth.mm = max_d; s[1].depth.mm = max_d;
s[2].time.seconds = max_t - max_d / slope;
s[2].depth.mm = max_d;
} else { } else {
s[1].time.seconds = max_d / slope; s[1].time.seconds = max_d / slope;
s[1].depth.mm = max_d; s[1].depth.mm = max_d;
@ -102,7 +108,7 @@ static void fill_samples_no_avg(struct sample *s, int max_d, int max_t, double s
} }
} }
struct divecomputer* fake_dc(struct divecomputer* dc) struct divecomputer *fake_dc(struct divecomputer *dc)
{ {
static struct sample fake[6]; static struct sample fake[6];
static struct divecomputer fakedc; static struct divecomputer fakedc;
@ -139,7 +145,7 @@ struct divecomputer* fake_dc(struct divecomputer* dc)
return &fakedc; return &fakedc;
} }
if (avg_d < max_d / 10 || avg_d >= max_d) { if (avg_d < max_d / 10 || avg_d >= max_d) {
avg_d = (max_d+10000)/3; avg_d = (max_d + 10000) / 3;
if (avg_d > max_d) if (avg_d > max_d)
avg_d = max_d * 2 / 3; avg_d = max_d * 2 / 3;
} }

View file

@ -6,7 +6,7 @@
extern "C" { extern "C" {
#endif #endif
extern struct divecomputer *fake_dc(struct divecomputer* dc); extern struct divecomputer *fake_dc(struct divecomputer *dc);
extern void create_device_node(const char *model, uint32_t deviceid, const char *serial, const char *firmware, const char *nickname); extern void create_device_node(const char *model, uint32_t deviceid, const char *serial, const char *firmware, const char *nickname);
extern void call_for_each_dc(void *f, void (*callback)(void *, const char *, uint32_t, extern void call_for_each_dc(void *f, void (*callback)(void *, const char *, uint32_t,
const char *, const char *, const char *)); const char *, const char *, const char *));

View file

@ -39,13 +39,20 @@ struct graphics_context {
struct plot_info pi; struct plot_info pi;
}; };
typedef enum { SC_SCREEN, SC_PRINT } scale_mode_t; typedef enum {
SC_SCREEN,
SC_PRINT
} scale_mode_t;
extern struct divecomputer *select_dc(struct divecomputer *main); extern struct divecomputer *select_dc(struct divecomputer *main);
extern void get_plot_details(struct graphics_context *gc, int time, struct membuffer *mb); extern void get_plot_details(struct graphics_context *gc, int time, struct membuffer *mb);
struct options { struct options {
enum { PRETTY, TABLE, TWOPERPAGE } type; enum {
PRETTY,
TABLE,
TWOPERPAGE
} type;
int print_selected; int print_selected;
int color_selected; int color_selected;
bool notes_up; bool notes_up;
@ -59,8 +66,8 @@ extern unsigned int amount_selected;
extern int is_default_dive_computer_device(const char *); extern int is_default_dive_computer_device(const char *);
extern int is_default_dive_computer(const char *, const char *); extern int is_default_dive_computer(const char *, const char *);
typedef void (*device_callback_t) (const char *name, void *userdata); typedef void (*device_callback_t)(const char *name, void *userdata);
int enumerate_devices (device_callback_t callback, void *userdata); int enumerate_devices(device_callback_t callback, void *userdata);
extern const char *default_dive_computer_vendor; extern const char *default_dive_computer_vendor;
extern const char *default_dive_computer_product; extern const char *default_dive_computer_product;

179
dive.c
View file

@ -9,9 +9,9 @@
struct tag_entry *g_tag_list = NULL; struct tag_entry *g_tag_list = NULL;
static const char* default_tags[] = { static const char *default_tags[] = {
QT_TRANSLATE_NOOP("gettextFromC", "boat"), QT_TRANSLATE_NOOP("gettextFromC", "shore"), QT_TRANSLATE_NOOP("gettextFromC", "drift"), QT_TRANSLATE_NOOP("gettextFromC", "boat"), QT_TRANSLATE_NOOP("gettextFromC", "shore"), QT_TRANSLATE_NOOP("gettextFromC", "drift"),
QT_TRANSLATE_NOOP("gettextFromC", "deep"), QT_TRANSLATE_NOOP("gettextFromC", "cavern") , QT_TRANSLATE_NOOP("gettextFromC", "ice"), QT_TRANSLATE_NOOP("gettextFromC", "deep"), QT_TRANSLATE_NOOP("gettextFromC", "cavern"), QT_TRANSLATE_NOOP("gettextFromC", "ice"),
QT_TRANSLATE_NOOP("gettextFromC", "wreck"), QT_TRANSLATE_NOOP("gettextFromC", "cave"), QT_TRANSLATE_NOOP("gettextFromC", "altitude"), QT_TRANSLATE_NOOP("gettextFromC", "wreck"), QT_TRANSLATE_NOOP("gettextFromC", "cave"), QT_TRANSLATE_NOOP("gettextFromC", "altitude"),
QT_TRANSLATE_NOOP("gettextFromC", "pool"), QT_TRANSLATE_NOOP("gettextFromC", "lake"), QT_TRANSLATE_NOOP("gettextFromC", "river"), QT_TRANSLATE_NOOP("gettextFromC", "pool"), QT_TRANSLATE_NOOP("gettextFromC", "lake"), QT_TRANSLATE_NOOP("gettextFromC", "river"),
QT_TRANSLATE_NOOP("gettextFromC", "night"), QT_TRANSLATE_NOOP("gettextFromC", "fresh"), QT_TRANSLATE_NOOP("gettextFromC", "student"), QT_TRANSLATE_NOOP("gettextFromC", "night"), QT_TRANSLATE_NOOP("gettextFromC", "fresh"), QT_TRANSLATE_NOOP("gettextFromC", "student"),
@ -48,22 +48,22 @@ void add_event(struct divecomputer *dc, int time, int type, int flags, int value
int get_pressure_units(unsigned int mb, const char **units) int get_pressure_units(unsigned int mb, const char **units)
{ {
int pressure; int pressure;
const char* unit; const char *unit;
struct units *units_p = get_units(); struct units *units_p = get_units();
switch (units_p->pressure) { switch (units_p->pressure) {
case PASCAL: case PASCAL:
pressure = mb * 100; pressure = mb * 100;
unit = translate("gettextFromC","pascal"); unit = translate("gettextFromC", "pascal");
break; break;
case BAR: case BAR:
default: default:
pressure = (mb + 500) / 1000; pressure = (mb + 500) / 1000;
unit = translate("gettextFromC","bar"); unit = translate("gettextFromC", "bar");
break; break;
case PSI: case PSI:
pressure = mbar_to_PSI(mb); pressure = mbar_to_PSI(mb);
unit = translate("gettextFromC","psi"); unit = translate("gettextFromC", "psi");
break; break;
} }
if (units) if (units)
@ -100,12 +100,12 @@ double get_volume_units(unsigned int ml, int *frac, const char **units)
case LITER: case LITER:
default: default:
vol = ml / 1000.0; vol = ml / 1000.0;
unit = translate("gettextFromC","l"); unit = translate("gettextFromC", "l");
decimals = 1; decimals = 1;
break; break;
case CUFT: case CUFT:
vol = ml_to_cuft(ml); vol = ml_to_cuft(ml);
unit = translate("gettextFromC","cuft"); unit = translate("gettextFromC", "cuft");
decimals = 2; decimals = 2;
break; break;
} }
@ -134,12 +134,12 @@ double get_depth_units(unsigned int mm, int *frac, const char **units)
case METERS: case METERS:
default: default:
d = mm / 1000.0; d = mm / 1000.0;
unit = translate("gettextFromC","m"); unit = translate("gettextFromC", "m");
decimals = d < 20; decimals = d < 20;
break; break;
case FEET: case FEET:
d = mm_to_feet(mm); d = mm_to_feet(mm);
unit = translate("gettextFromC","ft"); unit = translate("gettextFromC", "ft");
decimals = 0; decimals = 0;
break; break;
} }
@ -161,11 +161,11 @@ double get_vertical_speed_units(unsigned int mms, int *frac, const char **units)
case METERS: case METERS:
default: default:
d = mms / 1000.0 * time_factor; d = mms / 1000.0 * time_factor;
unit = translate("gettextFromC",(units_p->vertical_speed_time == MINUTES) ? "m/min" : "m/s"); unit = translate("gettextFromC", (units_p->vertical_speed_time == MINUTES) ? "m/min" : "m/s");
break; break;
case FEET: case FEET:
d = mm_to_feet(mms) * time_factor; d = mm_to_feet(mms) * time_factor;
unit = translate("gettextFromC",(units_p->vertical_speed_time == MINUTES) ? "ft/min" : "ft/s"); unit = translate("gettextFromC", (units_p->vertical_speed_time == MINUTES) ? "ft/min" : "ft/s");
break; break;
} }
if (frac) if (frac)
@ -179,16 +179,16 @@ double get_weight_units(unsigned int grams, int *frac, const char **units)
{ {
int decimals; int decimals;
double value; double value;
const char* unit; const char *unit;
struct units *units_p = get_units(); struct units *units_p = get_units();
if (units_p->weight == LBS) { if (units_p->weight == LBS) {
value = grams_to_lbs(grams); value = grams_to_lbs(grams);
unit = translate("gettextFromC","lbs"); unit = translate("gettextFromC", "lbs");
decimals = 0; decimals = 0;
} else { } else {
value = grams / 1000.0; value = grams / 1000.0;
unit = translate("gettextFromC","kg"); unit = translate("gettextFromC", "kg");
decimals = 1; decimals = 1;
} }
if (frac) if (frac)
@ -255,7 +255,7 @@ struct sample *prepare_sample(struct divecomputer *dc)
if (nr >= alloc_samples) { if (nr >= alloc_samples) {
struct sample *newsamples; struct sample *newsamples;
alloc_samples = (alloc_samples * 3)/2 + 10; alloc_samples = (alloc_samples * 3) / 2 + 10;
newsamples = realloc(dc->sample, alloc_samples * sizeof(struct sample)); newsamples = realloc(dc->sample, alloc_samples * sizeof(struct sample));
if (!newsamples) if (!newsamples)
return NULL; return NULL;
@ -333,21 +333,21 @@ static void fixup_dc_duration(struct divecomputer *dc)
/* We ignore segments at the surface */ /* We ignore segments at the surface */
if (depth > SURFACE_THRESHOLD || lastdepth > SURFACE_THRESHOLD) { if (depth > SURFACE_THRESHOLD || lastdepth > SURFACE_THRESHOLD) {
duration += time - lasttime; duration += time - lasttime;
depthtime += (time - lasttime)*(depth+lastdepth)/2; depthtime += (time - lasttime) * (depth + lastdepth) / 2;
} }
lastdepth = depth; lastdepth = depth;
lasttime = time; lasttime = time;
} }
if (duration) { if (duration) {
dc->duration.seconds = duration; dc->duration.seconds = duration;
dc->meandepth.mm = (depthtime + duration/2) / duration; dc->meandepth.mm = (depthtime + duration / 2) / duration;
} }
} }
void per_cylinder_mean_depth(struct dive *dive, struct divecomputer *dc, int *mean, int *duration) void per_cylinder_mean_depth(struct dive *dive, struct divecomputer *dc, int *mean, int *duration)
{ {
int i; int i;
int depthtime[MAX_CYLINDERS] = {0,}; int depthtime[MAX_CYLINDERS] = { 0, };
int lasttime = 0, lastdepth = 0; int lasttime = 0, lastdepth = 0;
int idx = 0; int idx = 0;
@ -426,7 +426,7 @@ double surface_volume_multiplier(pressure_t pressure)
double bar = pressure.mbar / 1000.0; double bar = pressure.mbar / 1000.0;
if (bar > 200) if (bar > 200)
bar = 0.00038*bar*bar + 0.51629*bar + 81.542; bar = 0.00038 * bar * bar + 0.51629 * bar + 81.542;
return bar_to_atm(bar); return bar_to_atm(bar);
} }
@ -469,7 +469,7 @@ static void sanitize_gasmix(struct gasmix *mix)
} }
/* Sane mix? */ /* Sane mix? */
if (o2 <= 1000 && he <= 1000 && o2+he <= 1000) if (o2 <= 1000 && he <= 1000 && o2 + he <= 1000)
return; return;
fprintf(stderr, "Odd gasmix: %u O2 %u He\n", o2, he); fprintf(stderr, "Odd gasmix: %u O2 %u He\n", o2, he);
memset(mix, 0, sizeof(*mix)); memset(mix, 0, sizeof(*mix));
@ -495,29 +495,29 @@ static void match_standard_cylinder(cylinder_type_t *type)
psi = to_PSI(type->workingpressure); psi = to_PSI(type->workingpressure);
switch (psi) { switch (psi) {
case 2300 ... 2500: /* 2400 psi: LP tank */ case 2300 ... 2500: /* 2400 psi: LP tank */
fmt = "LP%d"; fmt = "LP%d";
break; break;
case 2600 ... 2700: /* 2640 psi: LP+10% */ case 2600 ... 2700: /* 2640 psi: LP+10% */
fmt = "LP%d"; fmt = "LP%d";
break; break;
case 2900 ... 3100: /* 3000 psi: ALx tank */ case 2900 ... 3100: /* 3000 psi: ALx tank */
fmt = "AL%d"; fmt = "AL%d";
break; break;
case 3400 ... 3500: /* 3442 psi: HP tank */ case 3400 ... 3500: /* 3442 psi: HP tank */
fmt = "HP%d"; fmt = "HP%d";
break; break;
case 3700 ... 3850: /* HP+10% */ case 3700 ... 3850: /* HP+10% */
fmt = "HP%d+"; fmt = "HP%d+";
break; break;
default: default:
return; return;
} }
len = snprintf(buffer, sizeof(buffer), fmt, rint(cuft)); len = snprintf(buffer, sizeof(buffer), fmt, rint(cuft));
p = malloc(len+1); p = malloc(len + 1);
if (!p) if (!p)
return; return;
memcpy(p, buffer, len+1); memcpy(p, buffer, len + 1);
type->description = p; type->description = p;
} }
@ -631,7 +631,7 @@ static void fixup_surface_pressure(struct dive *dive)
} }
} }
if (nr) if (nr)
dive->surface_pressure.mbar = (sum + nr/2)/nr; dive->surface_pressure.mbar = (sum + nr / 2) / nr;
} }
static void fixup_water_salinity(struct dive *dive) static void fixup_water_salinity(struct dive *dive)
@ -646,7 +646,7 @@ static void fixup_water_salinity(struct dive *dive)
} }
} }
if (nr) if (nr)
dive->salinity = (sum + nr/2)/nr; dive->salinity = (sum + nr / 2) / nr;
} }
static void fixup_meandepth(struct dive *dive) static void fixup_meandepth(struct dive *dive)
@ -670,7 +670,7 @@ static void fixup_duration(struct dive *dive)
int duration = 0; int duration = 0;
for_each_dc(dive, dc) for_each_dc(dive, dc)
duration = MAX(duration, dc->duration.seconds); duration = MAX(duration, dc->duration.seconds);
dive->duration.seconds = duration; dive->duration.seconds = duration;
} }
@ -786,7 +786,7 @@ static void fixup_dive_dc(struct dive *dive, struct divecomputer *dc)
int mintemp = 0; int mintemp = 0;
int lastdepth = 0; int lastdepth = 0;
int lasttemp = 0, lastpressure = 0; int lasttemp = 0, lastpressure = 0;
int pressure_delta[MAX_CYLINDERS] = {INT_MAX, }; int pressure_delta[MAX_CYLINDERS] = { INT_MAX, };
/* Fixup duration and mean depth */ /* Fixup duration and mean depth */
fixup_dc_duration(dc); fixup_dc_duration(dc);
@ -871,9 +871,9 @@ static void fixup_dive_dc(struct dive *dive, struct divecomputer *dc)
for (i = 0; i < dc->samples; i++) for (i = 0; i < dc->samples; i++)
if (dc->sample[i].sensor == j) if (dc->sample[i].sensor == j)
dc->sample[i].cylinderpressure.mbar = 0; dc->sample[i].cylinderpressure.mbar = 0;
if (! cyl->start.mbar) if (!cyl->start.mbar)
cyl->start.mbar = cyl->sample_start.mbar; cyl->start.mbar = cyl->sample_start.mbar;
if (! cyl->end.mbar) if (!cyl->end.mbar)
cyl->end.mbar = cyl->sample_end.mbar; cyl->end.mbar = cyl->sample_end.mbar;
cyl->sample_start.mbar = 0; cyl->sample_start.mbar = 0;
cyl->sample_end.mbar = 0; cyl->sample_end.mbar = 0;
@ -896,7 +896,7 @@ struct dive *fixup_dive(struct dive *dive)
dive->maxcns = dive->cns; dive->maxcns = dive->cns;
for_each_dc(dive, dc) for_each_dc(dive, dc)
fixup_dive_dc(dive, dc); fixup_dive_dc(dive, dc);
fixup_water_salinity(dive); fixup_water_salinity(dive);
fixup_surface_pressure(dive); fixup_surface_pressure(dive);
@ -924,7 +924,7 @@ struct dive *fixup_dive(struct dive *dive)
/* Don't pick a zero for MERGE_MIN() */ /* Don't pick a zero for MERGE_MIN() */
#define MERGE_MAX(res, a, b, n) res->n = MAX(a->n, b->n) #define MERGE_MAX(res, a, b, n) res->n = MAX(a->n, b->n)
#define MERGE_MIN(res, a, b, n) res->n = (a->n)?(b->n)?MIN(a->n, b->n):(a->n):(b->n) #define MERGE_MIN(res, a, b, n) res->n = (a->n) ? (b->n) ? MIN(a->n, b->n) : (a->n) : (b->n)
#define MERGE_TXT(res, a, b, n) res->n = merge_text(a->n, b->n) #define MERGE_TXT(res, a, b, n) res->n = merge_text(a->n, b->n)
#define MERGE_NONZERO(res, a, b, n) res->n = a->n ? a->n : b->n #define MERGE_NONZERO(res, a, b, n) res->n = a->n ? a->n : b->n
@ -950,7 +950,7 @@ static struct sample *add_sample(struct sample *sample, int time, struct divecom
*/ */
static void merge_one_sample(struct sample *sample, int time, struct divecomputer *dc) static void merge_one_sample(struct sample *sample, int time, struct divecomputer *dc)
{ {
int last = dc->samples-1; int last = dc->samples - 1;
if (last >= 0) { if (last >= 0) {
static struct sample surface; static struct sample surface;
struct sample *prev = dc->sample + last; struct sample *prev = dc->sample + last;
@ -962,7 +962,7 @@ static void merge_one_sample(struct sample *sample, int time, struct divecompute
* a minute apart, and shallower than 5m * a minute apart, and shallower than 5m
*/ */
if (time > last_time + 60 && last_depth < 5000) { if (time > last_time + 60 && last_depth < 5000) {
add_sample(&surface, last_time+20, dc); add_sample(&surface, last_time + 20, dc);
add_sample(&surface, time - 20, dc); add_sample(&surface, time - 20, dc);
} }
} }
@ -1011,7 +1011,7 @@ static void merge_samples(struct divecomputer *res, struct divecomputer *a, stru
/* Only samples from a? */ /* Only samples from a? */
if (bt < 0) { if (bt < 0) {
add_sample_a: add_sample_a:
merge_one_sample(as, at, res); merge_one_sample(as, at, res);
as++; as++;
asamples--; asamples--;
@ -1020,7 +1020,7 @@ add_sample_a:
/* Only samples from b? */ /* Only samples from b? */
if (at < 0) { if (at < 0) {
add_sample_b: add_sample_b:
merge_one_sample(bs, bt, res); merge_one_sample(bs, bt, res);
bs++; bs++;
bsamples--; bsamples--;
@ -1073,24 +1073,25 @@ static char *merge_text(const char *a, const char *b)
return b ? strdup(b) : NULL; return b ? strdup(b) : NULL;
if (!b || !*b) if (!b || !*b)
return strdup(a); return strdup(a);
if (!strcmp(a,b)) if (!strcmp(a, b))
return a ? strdup(a) : NULL; return a ? strdup(a) : NULL;
res = malloc(strlen(a) + strlen(b) + 32); res = malloc(strlen(a) + strlen(b) + 32);
if (!res) if (!res)
return (char *)a; return (char *)a;
sprintf(res, translate("gettextFromC","(%s) or (%s)"), a, b); sprintf(res, translate("gettextFromC", "(%s) or (%s)"), a, b);
return res; return res;
} }
#define SORT(a,b,field) \ #define SORT(a, b, field) \
if (a->field != b->field) return a->field < b->field ? -1 : 1 if (a->field != b->field) \
return a->field < b->field ? -1 : 1
static int sort_event(struct event *a, struct event *b) static int sort_event(struct event *a, struct event *b)
{ {
SORT(a,b,time.seconds); SORT(a, b, time.seconds);
SORT(a,b,type); SORT(a, b, type);
SORT(a,b,flags); SORT(a, b, flags);
SORT(a,b,value); SORT(a, b, value);
return strcmp(a->name, b->name); return strcmp(a->name, b->name);
} }
@ -1185,8 +1186,8 @@ static int gasmix_distance(const struct gasmix *a, const struct gasmix *b)
int a_he = get_he(a), b_he = get_he(b); int a_he = get_he(a), b_he = get_he(b);
int delta_o2 = a_o2 - b_o2, delta_he = a_he - b_he; int delta_o2 = a_o2 - b_o2, delta_he = a_he - b_he;
delta_he = delta_he*delta_he; delta_he = delta_he * delta_he;
delta_o2 = delta_o2*delta_o2; delta_o2 = delta_o2 * delta_o2;
return delta_he + delta_o2; return delta_he + delta_o2;
} }
@ -1201,9 +1202,9 @@ static int find_cylinder_match(cylinder_t *cyl, cylinder_t array[], unsigned int
const cylinder_t *match; const cylinder_t *match;
int distance; int distance;
if (used & (1<<i)) if (used & (1 << i))
continue; continue;
match = array+i; match = array + i;
distance = gasmix_distance(&cyl->gasmix, &match->gasmix); distance = gasmix_distance(&cyl->gasmix, &match->gasmix);
if (distance >= score) if (distance >= score)
continue; continue;
@ -1235,7 +1236,7 @@ static void dc_cylinder_renumber(struct dive *dive, struct divecomputer *dc, int
/* Remap the sensor indexes */ /* Remap the sensor indexes */
for (i = 0; i < dc->samples; i++) { for (i = 0; i < dc->samples; i++) {
struct sample *s = dc->sample+i; struct sample *s = dc->sample + i;
int sensor; int sensor;
if (!s->cylinderpressure.mbar) if (!s->cylinderpressure.mbar)
@ -1291,7 +1292,7 @@ static void merge_cylinders(struct dive *res, struct dive *a, struct dive *b)
if (j < 0) if (j < 0)
continue; continue;
used |= 1 << j; used |= 1 << j;
merge_cylinder_info(cyl, res->cylinder+j); merge_cylinder_info(cyl, res->cylinder + j);
/* If that renumbered the cylinders, fix it up! */ /* If that renumbered the cylinders, fix it up! */
if (i != j) if (i != j)
@ -1307,7 +1308,7 @@ static void merge_equipment(struct dive *res, struct dive *a, struct dive *b)
merge_cylinders(res, a, b); merge_cylinders(res, a, b);
for (i = 0; i < MAX_WEIGHTSYSTEMS; i++) for (i = 0; i < MAX_WEIGHTSYSTEMS; i++)
merge_weightsystem_info(res->weightsystem+i, a->weightsystem + i, b->weightsystem + i); merge_weightsystem_info(res->weightsystem + i, a->weightsystem + i, b->weightsystem + i);
} }
static void merge_airtemps(struct dive *res, struct dive *a, struct dive *b) static void merge_airtemps(struct dive *res, struct dive *a, struct dive *b)
@ -1410,7 +1411,7 @@ static int compare_sample(struct sample *s, struct sample *a, struct sample *b,
/* cut off at one meter difference */ /* cut off at one meter difference */
if (diff > 1000) if (diff > 1000)
diff = 1000; diff = 1000;
return diff*diff; return diff * diff;
} }
/* /*
@ -1434,7 +1435,8 @@ static unsigned long sample_difference(struct divecomputer *a, struct divecomput
* skip the first sample - this way we know can always look at * skip the first sample - this way we know can always look at
* as/bs[-1] to look at the samples around it in the loop. * as/bs[-1] to look at the samples around it in the loop.
*/ */
as++; bs++; as++;
bs++;
asamples--; asamples--;
bsamples--; bsamples--;
@ -1459,17 +1461,19 @@ static unsigned long sample_difference(struct divecomputer *a, struct divecomput
} }
if (at < bt) { if (at < bt) {
diff = compare_sample(as, bs-1, bs, bt - at); diff = compare_sample(as, bs - 1, bs, bt - at);
as++; as++;
asamples--; asamples--;
} else if (at > bt) { } else if (at > bt) {
diff = compare_sample(bs, as-1, as, at - bt); diff = compare_sample(bs, as - 1, as, at - bt);
bs++; bs++;
bsamples--; bsamples--;
} else { } else {
diff = compare_sample(as, bs, NULL, 0); diff = compare_sample(as, bs, NULL, 0);
as++; bs++; as++;
asamples--; bsamples--; bs++;
asamples--;
bsamples--;
} }
/* Invalid comparison point? */ /* Invalid comparison point? */
@ -1559,7 +1563,8 @@ static int similar(unsigned long a, unsigned long b, unsigned long expected)
if (a && b) { if (a && b) {
unsigned long min, max, diff; unsigned long min, max, diff;
min = a; max = b; min = a;
max = b;
if (a > b) { if (a > b) {
min = b; min = b;
max = a; max = a;
@ -1570,7 +1575,7 @@ static int similar(unsigned long a, unsigned long b, unsigned long expected)
if (diff < expected) if (diff < expected)
return 1; return 1;
/* Error less than 10% or the maximum */ /* Error less than 10% or the maximum */
if (diff*10 < max) if (diff * 10 < max)
return 1; return 1;
} }
return 0; return 0;
@ -1672,7 +1677,7 @@ static int likely_same_dive(struct dive *a, struct dive *b)
*/ */
if (!similar(a->maxdepth.mm, b->maxdepth.mm, 1000) || if (!similar(a->maxdepth.mm, b->maxdepth.mm, 1000) ||
(a->meandepth.mm && b->meandepth.mm && !similar(a->meandepth.mm, b->meandepth.mm, 1000)) || (a->meandepth.mm && b->meandepth.mm && !similar(a->meandepth.mm, b->meandepth.mm, 1000)) ||
!similar(a->duration.seconds, b->duration.seconds, 5*60)) !similar(a->duration.seconds, b->duration.seconds, 5 * 60))
return 0; return 0;
/* See if we can get an exact match on the dive computer */ /* See if we can get an exact match on the dive computer */
@ -1761,7 +1766,7 @@ static int same_dc(struct divecomputer *a, struct divecomputer *b)
if (a->samples != b->samples) if (a->samples != b->samples)
return 0; return 0;
for (i = 0; i < a->samples; i++) for (i = 0; i < a->samples; i++)
if (!same_sample(a->sample+i, b->sample+i)) if (!same_sample(a->sample + i, b->sample + i))
return 0; return 0;
eva = a->events; eva = a->events;
evb = b->events; evb = b->events;
@ -1852,7 +1857,7 @@ static void copy_dive_computer(struct divecomputer *res, struct divecomputer *a)
* merge them. If not, we just take the data from 'a'. * merge them. If not, we just take the data from 'a'.
*/ */
static void interleave_dive_computers(struct divecomputer *res, static void interleave_dive_computers(struct divecomputer *res,
struct divecomputer *a, struct divecomputer *b, int offset) struct divecomputer *a, struct divecomputer *b, int offset)
{ {
do { do {
struct divecomputer *match; struct divecomputer *match;
@ -1921,19 +1926,20 @@ static void join_dive_computers(struct divecomputer *res, struct divecomputer *a
remove_redundant_dc(res, prefer_downloaded); remove_redundant_dc(res, prefer_downloaded);
} }
int taglist_get_tagstring(struct tag_entry *tag_list, char *buffer, int len) { int taglist_get_tagstring(struct tag_entry *tag_list, char *buffer, int len)
{
int i = 0; int i = 0;
struct tag_entry *tmp; struct tag_entry *tmp;
tmp = tag_list->next; tmp = tag_list->next;
memset(buffer, 0, len); memset(buffer, 0, len);
while(tmp != NULL) { while (tmp != NULL) {
int newlength = strlen(tmp->tag->name); int newlength = strlen(tmp->tag->name);
if (i > 0) if (i > 0)
newlength += 2; newlength += 2;
if ((i+newlength) < len) { if ((i + newlength) < len) {
if (i > 0) { if (i > 0) {
strcpy(buffer+i, ", "); strcpy(buffer + i, ", ");
strcpy(buffer+i+2, tmp->tag->name); strcpy(buffer + i + 2, tmp->tag->name);
} else { } else {
strcpy(buffer, tmp->tag->name); strcpy(buffer, tmp->tag->name);
} }
@ -1950,7 +1956,7 @@ struct divetag *taglist_get_tag(struct tag_entry *tag_list, const char *tag)
{ {
struct tag_entry *tmp; struct tag_entry *tmp;
tmp = tag_list->next; tmp = tag_list->next;
while(tmp != NULL) { while (tmp != NULL) {
if (tmp->tag != NULL) { if (tmp->tag != NULL) {
if (strcmp(tmp->tag->name, tag) == 0) if (strcmp(tmp->tag->name, tag) == 0)
return tmp->tag; return tmp->tag;
@ -1961,7 +1967,8 @@ struct divetag *taglist_get_tag(struct tag_entry *tag_list, const char *tag)
return NULL; return NULL;
} }
static inline void taglist_free_divetag(struct divetag *tag) { static inline void taglist_free_divetag(struct divetag *tag)
{
if (tag->name != NULL) if (tag->name != NULL)
free(tag->name); free(tag->name);
if (tag->source != NULL) if (tag->source != NULL)
@ -1975,7 +1982,7 @@ static struct divetag *taglist_add_divetag(struct tag_entry *tag_list, struct di
struct tag_entry *tmp, *last; struct tag_entry *tmp, *last;
last = tag_list; last = tag_list;
tmp = tag_list->next; tmp = tag_list->next;
while(1) { while (1) {
if (tmp == NULL || strcmp(tmp->tag->name, tag->name) > 0) { if (tmp == NULL || strcmp(tmp->tag->name, tag->name) > 0) {
/* Insert in front of it */ /* Insert in front of it */
last->next = malloc(sizeof(struct tag_entry)); last->next = malloc(sizeof(struct tag_entry));
@ -1999,7 +2006,7 @@ struct divetag *taglist_add_tag(struct tag_entry *tag_list, const char *tag)
const char *translation; const char *translation;
new_tag = malloc(sizeof(struct divetag)); new_tag = malloc(sizeof(struct divetag));
for (i=0; i<sizeof(default_tags)/sizeof(char*); i++) { for (i = 0; i < sizeof(default_tags) / sizeof(char *); i++) {
if (strcmp(default_tags[i], tag) == 0) { if (strcmp(default_tags[i], tag) == 0) {
is_default_tag = 1; is_default_tag = 1;
break; break;
@ -2008,14 +2015,14 @@ struct divetag *taglist_add_tag(struct tag_entry *tag_list, const char *tag)
/* Only translate default tags */ /* Only translate default tags */
if (is_default_tag) { if (is_default_tag) {
translation = translate("gettextFromC", tag); translation = translate("gettextFromC", tag);
new_tag->name = malloc(strlen(translation)+1); new_tag->name = malloc(strlen(translation) + 1);
memcpy(new_tag->name, translation, strlen(translation)+1); memcpy(new_tag->name, translation, strlen(translation) + 1);
new_tag->source = malloc(strlen(tag)+1); new_tag->source = malloc(strlen(tag) + 1);
memcpy(new_tag->source, tag, strlen(tag)+1); memcpy(new_tag->source, tag, strlen(tag) + 1);
} else { } else {
new_tag->source = NULL; new_tag->source = NULL;
new_tag->name = malloc(strlen(tag)+1); new_tag->name = malloc(strlen(tag) + 1);
memcpy(new_tag->name, tag, strlen(tag)+1); memcpy(new_tag->name, tag, strlen(tag) + 1);
} }
/* Try to insert new_tag into g_tag_list if we are not operating on it */ /* Try to insert new_tag into g_tag_list if we are not operating on it */
if (tag_list != g_tag_list) { if (tag_list != g_tag_list) {
@ -2032,14 +2039,16 @@ struct divetag *taglist_add_tag(struct tag_entry *tag_list, const char *tag)
return ret_tag; return ret_tag;
} }
void taglist_init(struct tag_entry **tag_list) { void taglist_init(struct tag_entry **tag_list)
{
*tag_list = malloc(sizeof(struct tag_entry)); *tag_list = malloc(sizeof(struct tag_entry));
(*tag_list)->next = NULL; (*tag_list)->next = NULL;
(*tag_list)->tag = NULL; (*tag_list)->tag = NULL;
} }
/* Clear everything but the first element */ /* Clear everything but the first element */
void taglist_clear(struct tag_entry *tag_list) { void taglist_clear(struct tag_entry *tag_list)
{
struct tag_entry *current_tag_entry, *next; struct tag_entry *current_tag_entry, *next;
current_tag_entry = tag_list->next; current_tag_entry = tag_list->next;
while (current_tag_entry != NULL) { while (current_tag_entry != NULL) {
@ -2071,7 +2080,7 @@ void taglist_init_global()
int i; int i;
taglist_init(&g_tag_list); taglist_init(&g_tag_list);
for(i=0; i<sizeof(default_tags)/sizeof(char*); i++) for (i = 0; i < sizeof(default_tags) / sizeof(char *); i++)
taglist_add_tag(g_tag_list, default_tags[i]); taglist_add_tag(g_tag_list, default_tags[i]);
} }
@ -2166,7 +2175,7 @@ void shift_times(const timestamp_t amount)
int i; int i;
struct dive *dive; struct dive *dive;
for_each_dive (i, dive) { for_each_dive(i, dive) {
if (!dive->selected) if (!dive->selected)
continue; continue;
dive->when += amount; dive->when += amount;

184
dive.h
View file

@ -21,7 +21,7 @@
(void) (&_max1 == &_max2); \ (void) (&_max1 == &_max2); \
_max1 > _max2 ? _max1 : _max2; }) _max1 > _max2 ? _max1 : _max2; })
#define IS_FP_SAME(_a,_b) (fabs((_a) - (_b)) < 0.000001 * MAX(fabs(_a), fabs(_b))) #define IS_FP_SAME(_a, _b) (fabs((_a) - (_b)) < 0.000001 * MAX(fabs(_a), fabs(_b)))
#include <libxml/tree.h> #include <libxml/tree.h>
#include <libxslt/transform.h> #include <libxslt/transform.h>
@ -34,18 +34,18 @@ extern "C" {
#include <stdbool.h> #include <stdbool.h>
#endif #endif
#define O2_IN_AIR 209 // permille #define O2_IN_AIR 209 // permille
#define N2_IN_AIR 781 #define N2_IN_AIR 781
#define O2_DENSITY 1429 // mg/Liter #define O2_DENSITY 1429 // mg/Liter
#define N2_DENSITY 1251 #define N2_DENSITY 1251
#define HE_DENSITY 179 #define HE_DENSITY 179
#define SURFACE_PRESSURE 1013 // mbar #define SURFACE_PRESSURE 1013 // mbar
#define SURFACE_PRESSURE_STRING "1013" #define SURFACE_PRESSURE_STRING "1013"
#define ZERO_C_IN_MKELVIN 273150 // mKelvin #define ZERO_C_IN_MKELVIN 273150 // mKelvin
/* Salinity is expressed in weight in grams per 10l */ /* Salinity is expressed in weight in grams per 10l */
#define SEAWATER_SALINITY 10300 #define SEAWATER_SALINITY 10300
#define FRESHWATER_SALINITY 10000 #define FRESHWATER_SALINITY 10000
/* /*
* Some silly typedefs to make our units very explicit. * Some silly typedefs to make our units very explicit.
@ -84,35 +84,43 @@ extern "C" {
*/ */
typedef int64_t timestamp_t; typedef int64_t timestamp_t;
typedef struct { typedef struct
{
int seconds; int seconds;
} duration_t; } duration_t;
typedef struct { typedef struct
{
int mm; int mm;
} depth_t; } depth_t;
typedef struct { typedef struct
{
int mbar; int mbar;
} pressure_t; } pressure_t;
typedef struct { typedef struct
{
int mkelvin; int mkelvin;
} temperature_t; } temperature_t;
typedef struct { typedef struct
{
int mliter; int mliter;
} volume_t; } volume_t;
typedef struct { typedef struct
{
int permille; int permille;
} fraction_t; } fraction_t;
typedef struct { typedef struct
{
int grams; int grams;
} weight_t; } weight_t;
typedef struct { typedef struct
{
int udeg; int udeg;
} degrees_t; } degrees_t;
@ -121,13 +129,15 @@ struct gasmix {
fraction_t he; fraction_t he;
}; };
typedef struct { typedef struct
{
volume_t size; volume_t size;
pressure_t workingpressure; pressure_t workingpressure;
const char *description; /* "LP85", "AL72", "AL80", "HP100+" or whatever */ const char *description; /* "LP85", "AL72", "AL80", "HP100+" or whatever */
} cylinder_type_t; } cylinder_type_t;
typedef struct { typedef struct
{
cylinder_type_t type; cylinder_type_t type;
struct gasmix gasmix; struct gasmix gasmix;
pressure_t start, end, sample_start, sample_end; pressure_t start, end, sample_start, sample_end;
@ -135,9 +145,10 @@ typedef struct {
bool used; bool used;
} cylinder_t; } cylinder_t;
typedef struct { typedef struct
{
weight_t weight; weight_t weight;
const char *description; /* "integrated", "belt", "ankle" */ const char *description; /* "integrated", "belt", "ankle" */
} weightsystem_t; } weightsystem_t;
extern int get_pressure_units(unsigned int mb, const char **units); extern int get_pressure_units(unsigned int mb, const char **units);
@ -196,7 +207,7 @@ static inline double mkelvin_to_F(int mkelvin)
static inline unsigned long F_to_mkelvin(double f) static inline unsigned long F_to_mkelvin(double f)
{ {
return rint((f-32) * 1000 / 1.8 + ZERO_C_IN_MKELVIN); return rint((f - 32) * 1000 / 1.8 + ZERO_C_IN_MKELVIN);
} }
static inline unsigned long C_to_mkelvin(double c) static inline unsigned long C_to_mkelvin(double c)
@ -211,7 +222,7 @@ static inline double psi_to_bar(double psi)
static inline long psi_to_mbar(double psi) static inline long psi_to_mbar(double psi)
{ {
return rint(psi_to_bar(psi)*1000); return rint(psi_to_bar(psi) * 1000);
} }
static inline int to_PSI(pressure_t pressure) static inline int to_PSI(pressure_t pressure)
@ -226,7 +237,7 @@ static inline double bar_to_atm(double bar)
static inline double mbar_to_atm(int mbar) static inline double mbar_to_atm(int mbar)
{ {
return (double) mbar / SURFACE_PRESSURE; return (double)mbar / SURFACE_PRESSURE;
} }
/* Volume in mliter of a cylinder at pressure 'p' */ /* Volume in mliter of a cylinder at pressure 'p' */
@ -235,13 +246,13 @@ extern int wet_volume(double cuft, pressure_t p);
static inline int mbar_to_PSI(int mbar) static inline int mbar_to_PSI(int mbar)
{ {
pressure_t p = {mbar}; pressure_t p = { mbar };
return to_PSI(p); return to_PSI(p);
} }
static inline int get_o2(const struct gasmix *mix) static inline int get_o2(const struct gasmix *mix)
{ {
return mix->o2.permille ? : O2_IN_AIR; return mix->o2.permille ?: O2_IN_AIR;
} }
static inline int get_he(const struct gasmix *mix) static inline int get_he(const struct gasmix *mix)
@ -258,7 +269,7 @@ static inline bool is_air(int o2, int he)
static inline int interpolate(int a, int b, int part, int whole) static inline int interpolate(int a, int b, int part, int whole)
{ {
/* It is doubtful that we actually need floating point for this, but whatever */ /* It is doubtful that we actually need floating point for this, but whatever */
double x = (double) a * (whole - part) + (double) b * part; double x = (double)a * (whole - part) + (double)b * part;
return rint(x / whole); return rint(x / whole);
} }
@ -267,7 +278,7 @@ struct sample {
depth_t depth; depth_t depth;
temperature_t temperature; temperature_t temperature;
pressure_t cylinderpressure; pressure_t cylinderpressure;
int sensor; /* Cylinder pressure sensor index */ int sensor; /* Cylinder pressure sensor index */
duration_t ndl; duration_t ndl;
duration_t stoptime; duration_t stoptime;
depth_t stopdepth; depth_t stopdepth;
@ -366,16 +377,23 @@ struct divecomputer {
#define W_IDX_PRIMARY 0 #define W_IDX_PRIMARY 0
#define W_IDX_SECONDARY 1 #define W_IDX_SECONDARY 1
typedef enum { TF_NONE, NO_TRIP, IN_TRIP, ASSIGNED_TRIP, NUM_TRIPFLAGS } tripflag_t; typedef enum {
TF_NONE,
NO_TRIP,
IN_TRIP,
ASSIGNED_TRIP,
NUM_TRIPFLAGS
} tripflag_t;
typedef struct dive_trip { typedef struct dive_trip
{
timestamp_t when; timestamp_t when;
char *location; char *location;
char *notes; char *notes;
struct dive *dives; struct dive *dives;
int nrdives; int nrdives;
int index; int index;
unsigned expanded:1, selected:1, autogen:1, fixup:1; unsigned expanded : 1, selected : 1, autogen : 1, fixup : 1;
struct dive_trip *next; struct dive_trip *next;
} dive_trip_t; } dive_trip_t;
@ -486,7 +504,7 @@ extern short autogroup;
/* random threashold: three days without diving -> new trip /* random threashold: three days without diving -> new trip
* this works very well for people who usually dive as part of a trip and don't * this works very well for people who usually dive as part of a trip and don't
* regularly dive at a local facility; this is why trips are an optional feature */ * regularly dive at a local facility; this is why trips are an optional feature */
#define TRIP_THRESHOLD 3600*24*3 #define TRIP_THRESHOLD 3600 * 24 * 3
#define UNGROUPED_DIVE(_dive) ((_dive)->tripflag == NO_TRIP) #define UNGROUPED_DIVE(_dive) ((_dive)->tripflag == NO_TRIP)
#define DIVE_IN_TRIP(_dive) ((_dive)->tripflag == IN_TRIP || (_dive)->tripflag == ASSIGNED_TRIP) #define DIVE_IN_TRIP(_dive) ((_dive)->tripflag == IN_TRIP || (_dive)->tripflag == ASSIGNED_TRIP)
@ -509,12 +527,32 @@ extern void insert_trip(dive_trip_t **trip);
#undef PASCAL #undef PASCAL
#endif #endif
struct units { struct units {
enum { METERS, FEET } length; enum {
enum { LITER, CUFT } volume; METERS,
enum { BAR, PSI, PASCAL } pressure; FEET
enum { CELSIUS, FAHRENHEIT, KELVIN } temperature; } length;
enum { KG, LBS } weight; enum {
enum { SECONDS, MINUTES } vertical_speed_time; LITER,
CUFT
} volume;
enum {
BAR,
PSI,
PASCAL
} pressure;
enum {
CELSIUS,
FAHRENHEIT,
KELVIN
} temperature;
enum {
KG,
LBS
} weight;
enum {
SECONDS,
MINUTES
} vertical_speed_time;
}; };
/* /*
@ -524,23 +562,15 @@ struct units {
* actually use. Similarly, C instead of Kelvin. * actually use. Similarly, C instead of Kelvin.
* And kg instead of g. * And kg instead of g.
*/ */
#define SI_UNITS { \ #define SI_UNITS \
.length = METERS, \ { \
.volume = LITER, \ .length = METERS, .volume = LITER, .pressure = BAR, .temperature = CELSIUS, .weight = KG, .vertical_speed_time = MINUTES \
.pressure = BAR, \ }
.temperature = CELSIUS, \
.weight = KG, \
.vertical_speed_time = MINUTES \
}
#define IMPERIAL_UNITS { \ #define IMPERIAL_UNITS \
.length = FEET, \ { \
.volume = CUFT, \ .length = FEET, .volume = CUFT, .pressure = PSI, .temperature = FAHRENHEIT, .weight = LBS, .vertical_speed_time = MINUTES \
.pressure = PSI, \ }
.temperature = FAHRENHEIT, \
.weight = LBS, \
.vertical_speed_time = MINUTES \
}
extern const struct units SI_units, IMPERIAL_units; extern const struct units SI_units, IMPERIAL_units;
extern struct units xml_parsing_units; extern struct units xml_parsing_units;
@ -589,14 +619,14 @@ static inline struct divecomputer *get_dive_dc(struct dive *dive, int nr)
* I don't think anybody really wants the index, and we could make * I don't think anybody really wants the index, and we could make
* it local to the for-loop, but that would make us requires C99. * it local to the for-loop, but that would make us requires C99.
*/ */
#define for_each_dive(_i,_x) \ #define for_each_dive(_i, _x) \
for ((_i) = 0; ((_x) = get_dive(_i)) != NULL; (_i)++) for ((_i) = 0; ((_x) = get_dive(_i)) != NULL; (_i)++)
#define for_each_dc(_dive,_dc) \ #define for_each_dc(_dive, _dc) \
for (_dc = &_dive->dc; _dc; _dc = _dc->next) for (_dc = &_dive->dc; _dc; _dc = _dc->next)
#define for_each_gps_location(_i,_x) \ #define for_each_gps_location(_i, _x) \
for ((_i) = 0; ((_x) = get_gps_location(_i, &gps_location_table)) != NULL; (_i)++) for ((_i) = 0; ((_x) = get_gps_location(_i, &gps_location_table)) != NULL; (_i)++)
static inline struct dive *get_dive_by_diveid(uint32_t diveid, uint32_t deviceid) static inline struct dive *get_dive_by_diveid(uint32_t diveid, uint32_t deviceid)
{ {
@ -731,19 +761,19 @@ const char *monthname(int mon);
#define UTF8_SUBSCRIPT_2 "\xe2\x82\x82" #define UTF8_SUBSCRIPT_2 "\xe2\x82\x82"
#define UTF8_WHITESTAR "\xe2\x98\x86" #define UTF8_WHITESTAR "\xe2\x98\x86"
#define UTF8_BLACKSTAR "\xe2\x98\x85" #define UTF8_BLACKSTAR "\xe2\x98\x85"
#define ZERO_STARS UTF8_WHITESTAR UTF8_WHITESTAR UTF8_WHITESTAR UTF8_WHITESTAR UTF8_WHITESTAR #define ZERO_STARS UTF8_WHITESTAR UTF8_WHITESTAR UTF8_WHITESTAR UTF8_WHITESTAR UTF8_WHITESTAR
#define ONE_STARS UTF8_BLACKSTAR UTF8_WHITESTAR UTF8_WHITESTAR UTF8_WHITESTAR UTF8_WHITESTAR #define ONE_STARS UTF8_BLACKSTAR UTF8_WHITESTAR UTF8_WHITESTAR UTF8_WHITESTAR UTF8_WHITESTAR
#define TWO_STARS UTF8_BLACKSTAR UTF8_BLACKSTAR UTF8_WHITESTAR UTF8_WHITESTAR UTF8_WHITESTAR #define TWO_STARS UTF8_BLACKSTAR UTF8_BLACKSTAR UTF8_WHITESTAR UTF8_WHITESTAR UTF8_WHITESTAR
#define THREE_STARS UTF8_BLACKSTAR UTF8_BLACKSTAR UTF8_BLACKSTAR UTF8_WHITESTAR UTF8_WHITESTAR #define THREE_STARS UTF8_BLACKSTAR UTF8_BLACKSTAR UTF8_BLACKSTAR UTF8_WHITESTAR UTF8_WHITESTAR
#define FOUR_STARS UTF8_BLACKSTAR UTF8_BLACKSTAR UTF8_BLACKSTAR UTF8_BLACKSTAR UTF8_WHITESTAR #define FOUR_STARS UTF8_BLACKSTAR UTF8_BLACKSTAR UTF8_BLACKSTAR UTF8_BLACKSTAR UTF8_WHITESTAR
#define FIVE_STARS UTF8_BLACKSTAR UTF8_BLACKSTAR UTF8_BLACKSTAR UTF8_BLACKSTAR UTF8_BLACKSTAR #define FIVE_STARS UTF8_BLACKSTAR UTF8_BLACKSTAR UTF8_BLACKSTAR UTF8_BLACKSTAR UTF8_BLACKSTAR
extern const char *star_strings[]; extern const char *star_strings[];
extern const char *existing_filename; extern const char *existing_filename;
extern void subsurface_command_line_init(int *, char ***); extern void subsurface_command_line_init(int *, char ***);
extern void subsurface_command_line_exit(int *, char ***); extern void subsurface_command_line_exit(int *, char ***);
#define FRACTION(n,x) ((unsigned)(n)/(x)),((unsigned)(n)%(x)) #define FRACTION(n, x) ((unsigned)(n) / (x)), ((unsigned)(n) % (x))
extern double add_segment(double pressure, const struct gasmix *gasmix, int period_in_seconds, int setpoint, const struct dive *dive); extern double add_segment(double pressure, const struct gasmix *gasmix, int period_in_seconds, int setpoint, const struct dive *dive);
extern void clear_deco(double surface_pressure); extern void clear_deco(double surface_pressure);
@ -766,9 +796,9 @@ struct divedatapoint {
struct diveplan { struct diveplan {
timestamp_t when; timestamp_t when;
int lastdive_nr; int lastdive_nr;
int surface_pressure; /* mbar */ int surface_pressure; /* mbar */
int bottomsac; /* ml/min */ int bottomsac; /* ml/min */
int decosac; /* ml/min */ int decosac; /* ml/min */
short gflow; short gflow;
short gfhigh; short gfhigh;
struct divedatapoint *dp; struct divedatapoint *dp;
@ -814,15 +844,15 @@ extern void remove_weightsystem(struct dive *dive, int idx);
/* /*
* String handling. * String handling.
*/ */
#define STRTOD_NO_SIGN 0x01 #define STRTOD_NO_SIGN 0x01
#define STRTOD_NO_DOT 0x02 #define STRTOD_NO_DOT 0x02
#define STRTOD_NO_COMMA 0x04 #define STRTOD_NO_COMMA 0x04
#define STRTOD_NO_EXPONENT 0x08 #define STRTOD_NO_EXPONENT 0x08
extern double strtod_flags(const char *str, const char **ptr, unsigned int flags); extern double strtod_flags(const char *str, const char **ptr, unsigned int flags);
#define STRTOD_ASCII (STRTOD_NO_COMMA) #define STRTOD_ASCII (STRTOD_NO_COMMA)
#define ascii_strtod(str,ptr) strtod_flags(str,ptr,STRTOD_ASCII) #define ascii_strtod(str, ptr) strtod_flags(str, ptr, STRTOD_ASCII)
#ifdef __cplusplus #ifdef __cplusplus
} }

View file

@ -133,9 +133,8 @@ void get_dive_gas(struct dive *dive, int *o2_p, int *he_p, int *o2low_p)
if (is_air(o2, he)) { if (is_air(o2, he)) {
if (is_air(event_o2 * 10, event_he * 10)) if (is_air(event_o2 * 10, event_he * 10))
used = 1; used = 1;
} } else {
else { if (he == event_he * 10 && o2 == event_o2 * 10)
if (he == event_he*10 && o2 == event_o2*10)
used = 1; used = 1;
} }
} }
@ -164,7 +163,7 @@ void get_dive_gas(struct dive *dive, int *o2_p, int *he_p, int *o2low_p)
continue; continue;
if (o2 <= maxo2) if (o2 <= maxo2)
continue; continue;
newmax: newmax:
maxhe = he; maxhe = he;
maxo2 = o2; maxo2 = o2;
} }
@ -181,7 +180,7 @@ int total_weight(struct dive *dive)
int i, total_grams = 0; int i, total_grams = 0;
if (dive) if (dive)
for (i=0; i< MAX_WEIGHTSYSTEMS; i++) for (i = 0; i < MAX_WEIGHTSYSTEMS; i++)
total_grams += dive->weightsystem[i].weight.grams; total_grams += dive->weightsystem[i].weight.grams;
return total_grams; return total_grams;
} }
@ -199,7 +198,7 @@ static int active_o2(struct dive *dive, struct divecomputer *dc, duration_t time
break; break;
if (strcmp(event->name, "gaschange")) if (strcmp(event->name, "gaschange"))
continue; continue;
o2permille = 10*(event->value & 0xffff); o2permille = 10 * (event->value & 0xffff);
} }
return o2permille; return o2permille;
} }
@ -230,18 +229,18 @@ static int calculate_otu(struct dive *dive)
} }
/* calculate CNS for a dive - this only takes the first divecomputer into account */ /* calculate CNS for a dive - this only takes the first divecomputer into account */
int const cns_table[][3] = { int const cns_table[][3] = {
/* po2, Maximum Single Exposure, Maximum 24 hour Exposure */ /* po2, Maximum Single Exposure, Maximum 24 hour Exposure */
{1600, 45 * 60, 150 * 60}, { 1600, 45 * 60, 150 * 60 },
{1500, 120 * 60, 180 * 60}, { 1500, 120 * 60, 180 * 60 },
{1400, 150 * 60, 180 * 60}, { 1400, 150 * 60, 180 * 60 },
{1300, 180 * 60, 210 * 60}, { 1300, 180 * 60, 210 * 60 },
{1200, 210 * 60, 240 * 60}, { 1200, 210 * 60, 240 * 60 },
{1100, 240 * 60, 270 * 60}, { 1100, 240 * 60, 270 * 60 },
{1000, 300 * 60, 300 * 60}, { 1000, 300 * 60, 300 * 60 },
{ 900, 360 * 60, 360 * 60}, { 900, 360 * 60, 360 * 60 },
{ 800, 450 * 60, 450 * 60}, { 800, 450 * 60, 450 * 60 },
{ 700, 570 * 60, 570 * 60}, { 700, 570 * 60, 570 * 60 },
{ 600, 720 * 60, 720 * 60} { 600, 720 * 60, 720 * 60 }
}; };
/* this only gets called if dive->maxcns == 0 which means we know that /* this only gets called if dive->maxcns == 0 which means we know that
@ -265,12 +264,12 @@ static int calculate_cns(struct dive *dive)
*/ */
divenr = get_divenr(dive); divenr = get_divenr(dive);
if (divenr) { if (divenr) {
prev_dive = get_dive(divenr -1 ); prev_dive = get_dive(divenr - 1);
if (prev_dive) { if (prev_dive) {
endtime = prev_dive->when + prev_dive->duration.seconds; endtime = prev_dive->when + prev_dive->duration.seconds;
if (dive->when < (endtime + 3600 * 12)) { if (dive->when < (endtime + 3600 * 12)) {
cns = calculate_cns(prev_dive); cns = calculate_cns(prev_dive);
cns = cns * 1/pow(2, (dive->when - endtime) / (90.0 * 60.0)); cns = cns * 1 / pow(2, (dive->when - endtime) / (90.0 * 60.0));
} }
} }
} }
@ -288,11 +287,11 @@ static int calculate_cns(struct dive *dive)
po2 = o2 / depth_to_atm(sample->depth.mm, dive); po2 = o2 / depth_to_atm(sample->depth.mm, dive);
} }
/* Find what table-row we should calculate % for */ /* Find what table-row we should calculate % for */
for (j = 1; j < sizeof(cns_table)/(sizeof(int) * 3); j++) for (j = 1; j < sizeof(cns_table) / (sizeof(int) * 3); j++)
if (po2 > cns_table[j][0]) if (po2 > cns_table[j][0])
break; break;
j--; j--;
cns += ((double)t)/((double)cns_table[j][1]) * 100; cns += ((double)t) / ((double)cns_table[j][1]) * 100;
} }
/* save calculated cns in dive struct */ /* save calculated cns in dive struct */
dive->cns = cns; dive->cns = cns;
@ -362,8 +361,8 @@ static void add_dive_to_deco(struct dive *dive)
for (j = t0; j < t1; j++) { for (j = t0; j < t1; j++) {
int depth = interpolate(psample->depth.mm, sample->depth.mm, j - t0, t1 - t0); int depth = interpolate(psample->depth.mm, sample->depth.mm, j - t0, t1 - t0);
(void) add_segment(depth_to_mbar(depth, dive) / 1000.0, (void)add_segment(depth_to_mbar(depth, dive) / 1000.0,
&dive->cylinder[sample->sensor].gasmix, 1, sample->po2, dive); &dive->cylinder[sample->sensor].gasmix, 1, sample->po2, dive);
} }
} }
} }
@ -373,8 +372,8 @@ int get_divenr(struct dive *dive)
int i; int i;
struct dive *d; struct dive *d;
for_each_dive(i, d) for_each_dive(i, d)
if (d == dive) if (d == dive)
return i; return i;
return -1; return -1;
} }
@ -396,7 +395,7 @@ double init_decompression(struct dive *dive)
when = dive->when; when = dive->when;
i = divenr; i = divenr;
while (i && --i) { while (i && --i) {
struct dive* pdive = get_dive(i); struct dive *pdive = get_dive(i);
/* we don't want to mix dives from different trips as we keep looking /* we don't want to mix dives from different trips as we keep looking
* for how far back we need to go */ * for how far back we need to go */
if (dive->divetrip && pdive->divetrip != dive->divetrip) if (dive->divetrip && pdive->divetrip != dive->divetrip)
@ -407,7 +406,7 @@ double init_decompression(struct dive *dive)
lasttime = when + pdive->duration.seconds; lasttime = when + pdive->duration.seconds;
} }
while (++i < divenr) { while (++i < divenr) {
struct dive* pdive = get_dive(i); struct dive *pdive = get_dive(i);
/* again skip dives from different trips */ /* again skip dives from different trips */
if (dive->divetrip && dive->divetrip != pdive->divetrip) if (dive->divetrip && dive->divetrip != pdive->divetrip)
continue; continue;
@ -429,7 +428,7 @@ double init_decompression(struct dive *dive)
lasttime = pdive->when + pdive->duration.seconds; lasttime = pdive->when + pdive->duration.seconds;
tissue_tolerance = add_segment(surface_pressure, &air, surface_time, 0, dive); tissue_tolerance = add_segment(surface_pressure, &air, surface_time, 0, dive);
#if DECO_CALC_DEBUG & 2 #if DECO_CALC_DEBUG & 2
printf("after surface intervall of %d:%02u\n", FRACTION(surface_time,60)); printf("after surface intervall of %d:%02u\n", FRACTION(surface_time, 60));
dump_tissues(); dump_tissues();
#endif #endif
} }
@ -440,7 +439,7 @@ double init_decompression(struct dive *dive)
surface_pressure = get_surface_pressure_in_mbar(dive, true) / 1000.0; surface_pressure = get_surface_pressure_in_mbar(dive, true) / 1000.0;
tissue_tolerance = add_segment(surface_pressure, &air, surface_time, 0, dive); tissue_tolerance = add_segment(surface_pressure, &air, surface_time, 0, dive);
#if DECO_CALC_DEBUG & 2 #if DECO_CALC_DEBUG & 2
printf("after surface intervall of %d:%02u\n", FRACTION(surface_time,60)); printf("after surface intervall of %d:%02u\n", FRACTION(surface_time, 60));
dump_tissues(); dump_tissues();
#endif #endif
} }
@ -488,7 +487,7 @@ char *get_nitrox_string(struct dive *dive)
else else
snprintf(buffer, MAX_NITROX_STRING, "%d" UTF8_ELLIPSIS "%d", o2low, o2); snprintf(buffer, MAX_NITROX_STRING, "%d" UTF8_ELLIPSIS "%d", o2low, o2);
else else
strcpy(buffer, translate("gettextFromC","air")); strcpy(buffer, translate("gettextFromC", "air"));
} }
return buffer; return buffer;
} }
@ -500,7 +499,7 @@ char *get_nitrox_string(struct dive *dive)
void dump_trip_list(void) void dump_trip_list(void)
{ {
dive_trip_t *trip; dive_trip_t *trip;
int i=0; int i = 0;
timestamp_t last_time = 0; timestamp_t last_time = 0;
for (trip = dive_trip_list; trip; trip = trip->next) { for (trip = dive_trip_list; trip; trip = trip->next) {
@ -509,10 +508,10 @@ void dump_trip_list(void)
if (trip->when < last_time) if (trip->when < last_time)
printf("\n\ndive_trip_list OUT OF ORDER!!!\n\n\n"); printf("\n\ndive_trip_list OUT OF ORDER!!!\n\n\n");
printf("%s trip %d to \"%s\" on %04u-%02u-%02u %02u:%02u:%02u (%d dives - %p)\n", printf("%s trip %d to \"%s\" on %04u-%02u-%02u %02u:%02u:%02u (%d dives - %p)\n",
trip->autogen ? "autogen " : "", trip->autogen ? "autogen " : "",
++i, trip->location, ++i, trip->location,
tm.tm_year + 1900, tm.tm_mon+1, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec, tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec,
trip->nrdives, trip); trip->nrdives, trip);
last_time = trip->when; last_time = trip->when;
} }
printf("-----\n"); printf("-----\n");
@ -537,9 +536,9 @@ dive_trip_t *find_matching_trip(timestamp_t when)
struct tm tm; struct tm tm;
utc_mkdate(trip->when, &tm); utc_mkdate(trip->when, &tm);
printf("found trip %p @ %04d-%02d-%02d %02d:%02d:%02d\n", printf("found trip %p @ %04d-%02d-%02d %02d:%02d:%02d\n",
trip, trip,
tm.tm_year+1900, tm.tm_mon+1, tm.tm_mday, tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday,
tm.tm_hour, tm.tm_min, tm.tm_sec); tm.tm_hour, tm.tm_min, tm.tm_sec);
} }
#endif #endif
return trip; return trip;
@ -560,9 +559,9 @@ void insert_trip(dive_trip_t **dive_trip_p)
p = &trip->next; p = &trip->next;
if (trip && trip->when == dive_trip->when) { if (trip && trip->when == dive_trip->when) {
if (! trip->location) if (!trip->location)
trip->location = dive_trip->location; trip->location = dive_trip->location;
if (! trip->notes) if (!trip->notes)
trip->notes = dive_trip->notes; trip->notes = dive_trip->notes;
divep = dive_trip->dives; divep = dive_trip->dives;
while (divep) { while (divep) {
@ -729,7 +728,7 @@ void delete_single_dive(int idx)
if (dive->selected) if (dive->selected)
deselect_dive(idx); deselect_dive(idx);
for (i = idx; i < dive_table.nr - 1; i++) for (i = idx; i < dive_table.nr - 1; i++)
dive_table.dives[i] = dive_table.dives[i+1]; dive_table.dives[i] = dive_table.dives[i + 1];
dive_table.dives[--dive_table.nr] = NULL; dive_table.dives[--dive_table.nr] = NULL;
/* free all allocations */ /* free all allocations */
free(dive->dc.sample); free(dive->dc.sample);
@ -757,7 +756,7 @@ void add_single_dive(int idx, struct dive *dive)
dive_table.nr++; dive_table.nr++;
if (dive->selected) if (dive->selected)
amount_selected++; amount_selected++;
for (i = idx; i < dive_table.nr ; i++) { for (i = idx; i < dive_table.nr; i++) {
struct dive *tmp = dive_table.dives[i]; struct dive *tmp = dive_table.dives[i];
dive_table.dives[i] = dive; dive_table.dives[i] = dive;
dive = tmp; dive = tmp;
@ -791,7 +790,7 @@ bool consecutive_selected()
struct dive *merge_two_dives(struct dive *a, struct dive *b) struct dive *merge_two_dives(struct dive *a, struct dive *b)
{ {
struct dive *res; struct dive *res;
int i,j; int i, j;
int id = a->id; int id = a->id;
if (!a || !b) if (!a || !b)
@ -803,7 +802,7 @@ struct dive *merge_two_dives(struct dive *a, struct dive *b)
return NULL; return NULL;
add_single_dive(i, res); add_single_dive(i, res);
delete_single_dive(i+1); delete_single_dive(i + 1);
delete_single_dive(j); delete_single_dive(j);
// now make sure that we keep the id of the first dive. // now make sure that we keep the id of the first dive.
// why? // why?
@ -909,7 +908,7 @@ static void try_to_renumber(struct dive *last, int preexisting)
* we're going to expect the user to do a manual * we're going to expect the user to do a manual
* renumbering. * renumbering.
*/ */
if (preexisting && get_dive(preexisting-1) != last) if (preexisting && get_dive(preexisting - 1) != last)
return; return;
/* /*
@ -952,12 +951,12 @@ void process_dives(bool is_imported, bool prefer_imported)
set_dc_nickname(dive_table.dives[i]); set_dc_nickname(dive_table.dives[i]);
/* This does the right thing for -1: NULL */ /* This does the right thing for -1: NULL */
last = get_dive(preexisting-1); last = get_dive(preexisting - 1);
sort_table(&dive_table); sort_table(&dive_table);
for (i = 1; i < dive_table.nr; i++) { for (i = 1; i < dive_table.nr; i++) {
struct dive **pp = &dive_table.dives[i-1]; struct dive **pp = &dive_table.dives[i - 1];
struct dive *prev = pp[0]; struct dive *prev = pp[0];
struct dive *dive = pp[1]; struct dive *dive = pp[1];
struct dive *merged; struct dive *merged;
@ -983,8 +982,8 @@ void process_dives(bool is_imported, bool prefer_imported)
/* Redo the new 'i'th dive */ /* Redo the new 'i'th dive */
i--; i--;
add_single_dive(i, merged); add_single_dive(i, merged);
delete_single_dive(i+1); delete_single_dive(i + 1);
delete_single_dive(i+1); delete_single_dive(i + 1);
// keep the id or the first dive for the merged dive // keep the id or the first dive for the merged dive
merged->id = id; merged->id = id;
} }

View file

@ -11,7 +11,7 @@ extern void update_cylinder_related_info(struct dive *);
extern void mark_divelist_changed(int); extern void mark_divelist_changed(int);
extern int unsaved_changes(void); extern int unsaved_changes(void);
extern void remove_autogen_trips(void); extern void remove_autogen_trips(void);
extern double init_decompression(struct dive * dive); extern double init_decompression(struct dive *dive);
/* divelist core logic functions */ /* divelist core logic functions */
extern void process_dives(bool imported, bool prefer_imported); extern void process_dives(bool imported, bool prefer_imported);

View file

@ -50,19 +50,19 @@ void add_weightsystem_description(weightsystem_t *weightsystem)
bool cylinder_nodata(cylinder_t *cyl) bool cylinder_nodata(cylinder_t *cyl)
{ {
return !cyl->type.size.mliter && return !cyl->type.size.mliter &&
!cyl->type.workingpressure.mbar && !cyl->type.workingpressure.mbar &&
!cyl->type.description && !cyl->type.description &&
!cyl->gasmix.o2.permille && !cyl->gasmix.o2.permille &&
!cyl->gasmix.he.permille && !cyl->gasmix.he.permille &&
!cyl->start.mbar && !cyl->start.mbar &&
!cyl->end.mbar; !cyl->end.mbar;
} }
static bool cylinder_nosamples(cylinder_t *cyl) static bool cylinder_nosamples(cylinder_t *cyl)
{ {
return !cyl->sample_start.mbar && return !cyl->sample_start.mbar &&
!cyl->sample_end.mbar; !cyl->sample_end.mbar;
} }
bool cylinder_none(void *_data) bool cylinder_none(void *_data)
@ -75,8 +75,8 @@ bool cylinder_none(void *_data)
and the same text */ and the same text */
static bool description_equal(const char *desc1, const char *desc2) static bool description_equal(const char *desc1, const char *desc2)
{ {
return ((! desc1 && ! desc2) || return ((!desc1 && !desc2) ||
(desc1 && desc2 && strcmp(desc1, desc2) == 0)); (desc1 && desc2 && strcmp(desc1, desc2) == 0));
} }
bool weightsystem_none(void *_data) bool weightsystem_none(void *_data)
@ -98,7 +98,7 @@ bool no_weightsystems(weightsystem_t *ws)
static bool one_weightsystem_equal(weightsystem_t *ws1, weightsystem_t *ws2) static bool one_weightsystem_equal(weightsystem_t *ws1, weightsystem_t *ws2)
{ {
return ws1->weight.grams == ws2->weight.grams && return ws1->weight.grams == ws2->weight.grams &&
description_equal(ws1->description, ws2->description); description_equal(ws1->description, ws2->description);
} }
bool weightsystems_equal(weightsystem_t *ws1, weightsystem_t *ws2) bool weightsystems_equal(weightsystem_t *ws1, weightsystem_t *ws2)
@ -125,38 +125,38 @@ struct tank_info_t tank_info[100] = {
{ "11.1 l", .ml = 11100 }, { "11.1 l", .ml = 11100 },
/* Most common AL cylinders */ /* Most common AL cylinders */
{ "AL40", .cuft = 40, .psi = 3000 }, { "AL40", .cuft = 40, .psi = 3000 },
{ "AL50", .cuft = 50, .psi = 3000 }, { "AL50", .cuft = 50, .psi = 3000 },
{ "AL63", .cuft = 63, .psi = 3000 }, { "AL63", .cuft = 63, .psi = 3000 },
{ "AL72", .cuft = 72, .psi = 3000 }, { "AL72", .cuft = 72, .psi = 3000 },
{ "AL80", .cuft = 80, .psi = 3000 }, { "AL80", .cuft = 80, .psi = 3000 },
{ "AL100", .cuft = 100, .psi = 3300 }, { "AL100", .cuft = 100, .psi = 3300 },
/* Somewhat common LP steel cylinders */ /* Somewhat common LP steel cylinders */
{ "LP85", .cuft = 85, .psi = 2640 }, { "LP85", .cuft = 85, .psi = 2640 },
{ "LP95", .cuft = 95, .psi = 2640 }, { "LP95", .cuft = 95, .psi = 2640 },
{ "LP108", .cuft = 108, .psi = 2640 }, { "LP108", .cuft = 108, .psi = 2640 },
{ "LP121", .cuft = 121, .psi = 2640 }, { "LP121", .cuft = 121, .psi = 2640 },
/* Somewhat common HP steel cylinders */ /* Somewhat common HP steel cylinders */
{ "HP65", .cuft = 65, .psi = 3442 }, { "HP65", .cuft = 65, .psi = 3442 },
{ "HP80", .cuft = 80, .psi = 3442 }, { "HP80", .cuft = 80, .psi = 3442 },
{ "HP100", .cuft = 100, .psi = 3442 }, { "HP100", .cuft = 100, .psi = 3442 },
{ "HP119", .cuft = 119, .psi = 3442 }, { "HP119", .cuft = 119, .psi = 3442 },
{ "HP130", .cuft = 130, .psi = 3442 }, { "HP130", .cuft = 130, .psi = 3442 },
/* Common European steel cylinders */ /* Common European steel cylinders */
{ "3L 232 bar", .ml = 3000, .bar = 232 }, { "3L 232 bar", .ml = 3000, .bar = 232 },
{ "3L 300 bar", .ml = 3000, .bar = 300 }, { "3L 300 bar", .ml = 3000, .bar = 300 },
{ "10L 300 bar", .ml = 10000, .bar = 300 }, { "10L 300 bar", .ml = 10000, .bar = 300 },
{ "12L 200 bar", .ml = 12000, .bar = 200 }, { "12L 200 bar", .ml = 12000, .bar = 200 },
{ "12L 232 bar", .ml = 12000, .bar = 232 }, { "12L 232 bar", .ml = 12000, .bar = 232 },
{ "12L 300 bar", .ml = 12000, .bar = 300 }, { "12L 300 bar", .ml = 12000, .bar = 300 },
{ "15L 200 bar", .ml = 15000, .bar = 200 }, { "15L 200 bar", .ml = 15000, .bar = 200 },
{ "15L 232 bar", .ml = 15000, .bar = 232 }, { "15L 232 bar", .ml = 15000, .bar = 232 },
{ "D7 300 bar", .ml = 14000, .bar = 300 }, { "D7 300 bar", .ml = 14000, .bar = 300 },
{ "D8.5 232 bar", .ml = 17000, .bar = 232 }, { "D8.5 232 bar", .ml = 17000, .bar = 232 },
{ "D12 232 bar", .ml = 24000, .bar = 232 }, { "D12 232 bar", .ml = 24000, .bar = 232 },
/* We'll fill in more from the dive log dynamically */ /* We'll fill in more from the dive log dynamically */
{ NULL, } { NULL, }
@ -167,11 +167,11 @@ struct tank_info_t tank_info[100] = {
* This is a bit odd as the weight system types don't usually encode weight * This is a bit odd as the weight system types don't usually encode weight
*/ */
struct ws_info_t ws_info[100] = { struct ws_info_t ws_info[100] = {
{ QT_TRANSLATE_NOOP("gettextFromC","integrated"), 0 }, { QT_TRANSLATE_NOOP("gettextFromC", "integrated"), 0 },
{ QT_TRANSLATE_NOOP("gettextFromC","belt"), 0 }, { QT_TRANSLATE_NOOP("gettextFromC", "belt"), 0 },
{ QT_TRANSLATE_NOOP("gettextFromC","ankle"), 0 }, { QT_TRANSLATE_NOOP("gettextFromC", "ankle"), 0 },
{ QT_TRANSLATE_NOOP("gettextFromC","backplate weight"), 0 }, { QT_TRANSLATE_NOOP("gettextFromC", "backplate weight"), 0 },
{ QT_TRANSLATE_NOOP("gettextFromC","clip-on"), 0 }, { QT_TRANSLATE_NOOP("gettextFromC", "clip-on"), 0 },
}; };
void remove_cylinder(struct dive *dive, int idx) void remove_cylinder(struct dive *dive, int idx)

40
file.c
View file

@ -37,7 +37,7 @@ int readfile(const char *filename, struct memblock *mem)
ret = 0; ret = 0;
if (!st.st_size) if (!st.st_size)
goto out; goto out;
buf = malloc(st.st_size+1); buf = malloc(st.st_size + 1);
ret = -1; ret = -1;
errno = ENOMEM; errno = ENOMEM;
if (!buf) if (!buf)
@ -67,7 +67,7 @@ static void zip_read(struct zip_file *file, char **error, const char *filename)
int size = 1024, n, read = 0; int size = 1024, n, read = 0;
char *mem = malloc(size); char *mem = malloc(size);
while ((n = zip_fread(file, mem+read, size-read)) > 0) { while ((n = zip_fread(file, mem + read, size - read)) > 0) {
read += n; read += n;
size = read * 3 / 2; size = read * 3 / 2;
mem = realloc(mem, size); mem = realloc(mem, size);
@ -85,7 +85,7 @@ static int try_to_open_zip(const char *filename, struct memblock *mem, char **er
if (zip) { if (zip) {
int index; int index;
for (index = 0; ;index++) { for (index = 0;; index++) {
struct zip_file *file = zip_fopen_index(zip, index, 0); struct zip_file *file = zip_fopen_index(zip, index, 0);
if (!file) if (!file)
break; break;
@ -104,9 +104,9 @@ static int try_to_xslt_open_csv(const char *filename, struct memblock *mem, char
if (readfile(filename, mem) < 0) { if (readfile(filename, mem) < 0) {
if (error) { if (error) {
int len = strlen(translate("gettextFromC","Failed to read '%s'")) + strlen(filename); int len = strlen(translate("gettextFromC", "Failed to read '%s'")) + strlen(filename);
*error = malloc(len); *error = malloc(len);
snprintf(*error, len, translate("gettextFromC","Failed to read '%s'"), filename); snprintf(*error, len, translate("gettextFromC", "Failed to read '%s'"), filename);
} }
return 1; return 1;
@ -167,7 +167,7 @@ static int try_to_open_db(const char *filename, struct memblock *mem, char **err
retval = sqlite3_open(filename, &handle); retval = sqlite3_open(filename, &handle);
if (retval) { if (retval) {
fprintf(stderr, translate("gettextFromC","Database connection failed '%s'.\n"), filename); fprintf(stderr, translate("gettextFromC", "Database connection failed '%s'.\n"), filename);
return 1; return 1;
} }
@ -208,7 +208,7 @@ timestamp_t parse_date(const char *date)
} }
if (tm.tm_mon > 11) if (tm.tm_mon > 11)
return 0; return 0;
date = p+3; date = p + 3;
tm.tm_year = strtol(date, &p, 10); tm.tm_year = strtol(date, &p, 10);
if (date == p) if (date == p)
return 0; return 0;
@ -225,7 +225,9 @@ timestamp_t parse_date(const char *date)
} }
enum csv_format { enum csv_format {
CSV_DEPTH, CSV_TEMP, CSV_PRESSURE CSV_DEPTH,
CSV_TEMP,
CSV_PRESSURE
}; };
static void add_sample_data(struct sample *sample, enum csv_format type, double val) static void add_sample_data(struct sample *sample, enum csv_format type, double val)
@ -238,7 +240,7 @@ static void add_sample_data(struct sample *sample, enum csv_format type, double
sample->temperature.mkelvin = F_to_mkelvin(val); sample->temperature.mkelvin = F_to_mkelvin(val);
break; break;
case CSV_PRESSURE: case CSV_PRESSURE:
sample->cylinderpressure.mbar = psi_to_mbar(val*4); sample->cylinderpressure.mbar = psi_to_mbar(val * 4);
break; break;
} }
} }
@ -292,7 +294,7 @@ static int try_to_open_csv(const char *filename, struct memblock *mem, enum csv_
struct sample *sample; struct sample *sample;
errno = 0; errno = 0;
val = strtod(p,&end); // FIXME == localization issue val = strtod(p, &end); // FIXME == localization issue
if (end == p) if (end == p)
break; break;
if (errno) if (errno)
@ -307,7 +309,7 @@ static int try_to_open_csv(const char *filename, struct memblock *mem, enum csv_
dc->duration.seconds = time; dc->duration.seconds = time;
if (*end != ',') if (*end != ',')
break; break;
p = end+1; p = end + 1;
} }
record_dive(dive); record_dive(dive);
return 1; return 1;
@ -343,7 +345,7 @@ static int open_by_filename(const char *filename, const char *fmt, struct memblo
static void parse_file_buffer(const char *filename, struct memblock *mem, char **error) static void parse_file_buffer(const char *filename, struct memblock *mem, char **error)
{ {
char *fmt = strrchr(filename, '.'); char *fmt = strrchr(filename, '.');
if (fmt && open_by_filename(filename, fmt+1, mem, error)) if (fmt && open_by_filename(filename, fmt + 1, mem, error))
return; return;
if (!mem->size || !mem->buffer) if (!mem->size || !mem->buffer)
@ -359,13 +361,13 @@ void parse_file(const char *filename, char **error)
if (readfile(filename, &mem) < 0) { if (readfile(filename, &mem) < 0) {
/* we don't want to display an error if this was the default file */ /* we don't want to display an error if this was the default file */
if (prefs.default_filename && ! strcmp(filename, prefs.default_filename)) if (prefs.default_filename && !strcmp(filename, prefs.default_filename))
return; return;
if (error) { if (error) {
int len = strlen(translate("gettextFromC","Failed to read '%s'")) + strlen(filename); int len = strlen(translate("gettextFromC", "Failed to read '%s'")) + strlen(filename);
*error = malloc(len); *error = malloc(len);
snprintf(*error, len, translate("gettextFromC","Failed to read '%s'"), filename); snprintf(*error, len, translate("gettextFromC", "Failed to read '%s'"), filename);
} }
return; return;
@ -388,7 +390,7 @@ void parse_file(const char *filename, char **error)
void parse_csv_file(const char *filename, int timef, int depthf, int tempf, int po2f, int cnsf, int stopdepthf, int sepidx, const char *csvtemplate, int unitidx, char **error) void parse_csv_file(const char *filename, int timef, int depthf, int tempf, int po2f, int cnsf, int stopdepthf, int sepidx, const char *csvtemplate, int unitidx, char **error)
{ {
struct memblock mem; struct memblock mem;
int pnr=0; int pnr = 0;
char *params[21]; char *params[21];
char timebuf[MAXCOLDIGITS]; char timebuf[MAXCOLDIGITS];
char depthbuf[MAXCOLDIGITS]; char depthbuf[MAXCOLDIGITS];
@ -403,7 +405,7 @@ void parse_csv_file(const char *filename, int timef, int depthf, int tempf, int
char curdate[9]; char curdate[9];
char curtime[6]; char curtime[6];
if (timef >= MAXCOLS || depthf >= MAXCOLS || tempf >= MAXCOLS || po2f >= MAXCOLS || cnsf >= MAXCOLS || stopdepthf >= MAXCOLS ) { if (timef >= MAXCOLS || depthf >= MAXCOLS || tempf >= MAXCOLS || po2f >= MAXCOLS || cnsf >= MAXCOLS || stopdepthf >= MAXCOLS) {
int len = strlen(translate("gettextFromC", "Maximum number of supported columns on CSV import is %d")) + MAXCOLDIGITS; int len = strlen(translate("gettextFromC", "Maximum number of supported columns on CSV import is %d")) + MAXCOLDIGITS;
*error = malloc(len); *error = malloc(len);
snprintf(*error, len, translate("gettextFromC", "Maximum number of supported columns on CSV import is %d"), MAXCOLS); snprintf(*error, len, translate("gettextFromC", "Maximum number of supported columns on CSV import is %d"), MAXCOLS);
@ -461,7 +463,7 @@ void parse_csv_file(const char *filename, int timef, int depthf, int tempf, int
void parse_manual_file(const char *filename, int sepidx, int units, int numberf, int datef, int timef, int durationf, int locationf, int gpsf, int maxdepthf, int meandepthf, int buddyf, int notesf, int weightf, int tagsf, char **error) void parse_manual_file(const char *filename, int sepidx, int units, int numberf, int datef, int timef, int durationf, int locationf, int gpsf, int maxdepthf, int meandepthf, int buddyf, int notesf, int weightf, int tagsf, char **error)
{ {
struct memblock mem; struct memblock mem;
int pnr=0; int pnr = 0;
char *params[33]; char *params[33];
char numberbuf[MAXCOLDIGITS]; char numberbuf[MAXCOLDIGITS];
char datebuf[MAXCOLDIGITS]; char datebuf[MAXCOLDIGITS];
@ -482,7 +484,7 @@ void parse_manual_file(const char *filename, int sepidx, int units, int numberf,
char curdate[9]; char curdate[9];
char curtime[6]; char curtime[6];
if ( numberf >= MAXCOLS || datef >= MAXCOLS || timef >= MAXCOLS || durationf >= MAXCOLS || locationf >= MAXCOLS || gpsf >= MAXCOLS || maxdepthf >= MAXCOLS || meandepthf >= MAXCOLS || buddyf >= MAXCOLS || notesf >= MAXCOLS || weightf >= MAXCOLS || tagsf >= MAXCOLS ) { if (numberf >= MAXCOLS || datef >= MAXCOLS || timef >= MAXCOLS || durationf >= MAXCOLS || locationf >= MAXCOLS || gpsf >= MAXCOLS || maxdepthf >= MAXCOLS || meandepthf >= MAXCOLS || buddyf >= MAXCOLS || notesf >= MAXCOLS || weightf >= MAXCOLS || tagsf >= MAXCOLS) {
int len = strlen(translate("gettextFromC", "Maximum number of supported columns on CSV import is %d")) + MAXCOLDIGITS; int len = strlen(translate("gettextFromC", "Maximum number of supported columns on CSV import is %d")) + MAXCOLDIGITS;
*error = malloc(len); *error = malloc(len);
snprintf(*error, len, translate("gettextFromC", "Maximum number of supported columns on CSV import is %d"), MAXCOLS); snprintf(*error, len, translate("gettextFromC", "Maximum number of supported columns on CSV import is %d"), MAXCOLS);

View file

@ -15,7 +15,7 @@ void gettextFromC::reset(void)
translationCache.clear(); translationCache.clear();
} }
gettextFromC* gettextFromC::instance() gettextFromC *gettextFromC::instance()
{ {
static QScopedPointer<gettextFromC> self(new gettextFromC()); static QScopedPointer<gettextFromC> self(new gettextFromC());
return self.data(); return self.data();

View file

@ -5,14 +5,13 @@
extern "C" const char *trGettext(const char *text); extern "C" const char *trGettext(const char *text);
class gettextFromC class gettextFromC {
{ Q_DECLARE_TR_FUNCTIONS(gettextFromC)
Q_DECLARE_TR_FUNCTIONS(gettextFromC)
public: public:
static gettextFromC *instance(); static gettextFromC *instance();
const char *trGettext(const char *text); const char *trGettext(const char *text);
void reset(void); void reset(void);
QHash <QByteArray, QByteArray> translationCache; QHash<QByteArray, QByteArray> translationCache;
}; };
#endif // GETTEXTFROMC_H #endif // GETTEXTFROMC_H

View file

@ -28,18 +28,18 @@ void set_default_dive_computer_device(const char *name);
QString getSubsurfaceDataPath(QString folderToFind); QString getSubsurfaceDataPath(QString folderToFind);
extern const QString get_dc_nickname(const char *model, uint32_t deviceid); extern const QString get_dc_nickname(const char *model, uint32_t deviceid);
int gettimezoneoffset(); int gettimezoneoffset();
int parseTemperatureToMkelvin(const QString& text); int parseTemperatureToMkelvin(const QString &text);
QString get_dive_date_string(timestamp_t when); QString get_dive_date_string(timestamp_t when);
QString get_short_dive_date_string(timestamp_t when); QString get_short_dive_date_string(timestamp_t when);
QString get_trip_date_string(timestamp_t when, int nr); QString get_trip_date_string(timestamp_t when, int nr);
extern DiveComputerList dcList; extern DiveComputerList dcList;
#define M_OR_FT(_m,_f) ((prefs.units.length == units::METERS) ? ((_m) * 1000) : (feet_to_mm(_f))) #define M_OR_FT(_m, _f) ((prefs.units.length == units::METERS) ? ((_m) * 1000) : (feet_to_mm(_f)))
#if defined __APPLE__ #if defined __APPLE__
#define TITLE_OR_TEXT(_t,_m) "", _t + "\n" + _m #define TITLE_OR_TEXT(_t, _m) "", _t + "\n" + _m
#else #else
#define TITLE_OR_TEXT(_t,_m) _t, _m #define TITLE_OR_TEXT(_t, _m) _t, _m
#endif #endif
#endif // HELPERS_H #endif // HELPERS_H

View file

@ -12,10 +12,10 @@
/* Christ. Libdivecomputer has the worst configuration system ever. */ /* Christ. Libdivecomputer has the worst configuration system ever. */
#ifdef HW_FROG_H #ifdef HW_FROG_H
#define NOT_FROG , 0 #define NOT_FROG , 0
#define LIBDIVECOMPUTER_SUPPORTS_FROG #define LIBDIVECOMPUTER_SUPPORTS_FROG
#else #else
#define NOT_FROG #define NOT_FROG
#endif #endif
char *dumpfile_name; char *dumpfile_name;
@ -40,16 +40,16 @@ static dc_status_t create_parser(device_data_t *devdata, dc_parser_t **parser)
struct atomics_gas_info { struct atomics_gas_info {
uint8_t gas_nr; uint8_t gas_nr;
uint8_t po2imit; uint8_t po2imit;
uint8_t tankspecmethod; /* 1: CF@psi 2: CF@bar 3: wet vol in deciliter */ uint8_t tankspecmethod; /* 1: CF@psi 2: CF@bar 3: wet vol in deciliter */
uint8_t gasmixtype; uint8_t gasmixtype;
uint8_t fo2; uint8_t fo2;
uint8_t fhe; uint8_t fhe;
uint16_t startpressure; /* in psi */ uint16_t startpressure; /* in psi */
uint16_t tanksize; /* CF or dl */ uint16_t tanksize; /* CF or dl */
uint16_t workingpressure; uint16_t workingpressure;
uint16_t sensorid; uint16_t sensorid;
uint16_t endpressure; /* in psi */ uint16_t endpressure; /* in psi */
uint16_t totalconsumption; /* in liters */ uint16_t totalconsumption; /* in liters */
}; };
#define COBALT_CFATPSI 1 #define COBALT_CFATPSI 1
#define COBALT_CFATBAR 2 #define COBALT_CFATBAR 2
@ -72,7 +72,7 @@ static bool get_tanksize(device_data_t *devdata, const unsigned char *data, cyli
printf("incorrect header for Atomics dive\n"); printf("incorrect header for Atomics dive\n");
return false; return false;
} }
atomics_gas_info = (void*)(data + COBALT_HEADER); atomics_gas_info = (void *)(data + COBALT_HEADER);
switch (atomics_gas_info[idx].tankspecmethod) { switch (atomics_gas_info[idx].tankspecmethod) {
case COBALT_CFATPSI: case COBALT_CFATPSI:
airvolume = cuft_to_l(atomics_gas_info[idx].tanksize) * 1000.0; airvolume = cuft_to_l(atomics_gas_info[idx].tanksize) * 1000.0;
@ -96,13 +96,13 @@ static bool get_tanksize(device_data_t *devdata, const unsigned char *data, cyli
} }
static int parse_gasmixes(device_data_t *devdata, struct dive *dive, dc_parser_t *parser, int ngases, static int parse_gasmixes(device_data_t *devdata, struct dive *dive, dc_parser_t *parser, int ngases,
const unsigned char *data) const unsigned char *data)
{ {
int i; int i;
for (i = 0; i < ngases; i++) { for (i = 0; i < ngases; i++) {
int rc; int rc;
dc_gasmix_t gasmix = {0}; dc_gasmix_t gasmix = { 0 };
int o2, he; int o2, he;
rc = dc_parser_get_field(parser, DC_FIELD_GASMIX, i, &gasmix); rc = dc_parser_get_field(parser, DC_FIELD_GASMIX, i, &gasmix);
@ -118,7 +118,7 @@ static int parse_gasmixes(device_data_t *devdata, struct dive *dive, dc_parser_t
/* Ignore bogus data - libdivecomputer does some crazy stuff */ /* Ignore bogus data - libdivecomputer does some crazy stuff */
if (o2 + he <= O2_IN_AIR || o2 >= 1000) if (o2 + he <= O2_IN_AIR || o2 >= 1000)
o2 = 0; o2 = 0;
if (he < 0 || he >= 800 || o2+he >= 1000) if (he < 0 || he >= 800 || o2 + he >= 1000)
he = 0; he = 0;
dive->cylinder[i].gasmix.o2.permille = o2; dive->cylinder[i].gasmix.o2.permille = o2;
@ -136,12 +136,12 @@ static void handle_event(struct divecomputer *dc, struct sample *sample, dc_samp
/* we mark these for translation here, but we store the untranslated strings /* we mark these for translation here, but we store the untranslated strings
* and only translate them when they are displayed on screen */ * and only translate them when they are displayed on screen */
static const char *events[] = { static const char *events[] = {
QT_TRANSLATE_NOOP("gettextFromC","none"), QT_TRANSLATE_NOOP("gettextFromC","deco stop"), QT_TRANSLATE_NOOP("gettextFromC","rbt"), QT_TRANSLATE_NOOP("gettextFromC","ascent"), QT_TRANSLATE_NOOP("gettextFromC","ceiling"), QT_TRANSLATE_NOOP("gettextFromC","workload"), QT_TRANSLATE_NOOP("gettextFromC", "none"), QT_TRANSLATE_NOOP("gettextFromC", "deco stop"), QT_TRANSLATE_NOOP("gettextFromC", "rbt"), QT_TRANSLATE_NOOP("gettextFromC", "ascent"), QT_TRANSLATE_NOOP("gettextFromC", "ceiling"), QT_TRANSLATE_NOOP("gettextFromC", "workload"),
QT_TRANSLATE_NOOP("gettextFromC","transmitter"), QT_TRANSLATE_NOOP("gettextFromC","violation"), QT_TRANSLATE_NOOP("gettextFromC","bookmark"), QT_TRANSLATE_NOOP("gettextFromC","surface"), QT_TRANSLATE_NOOP("gettextFromC","safety stop"), QT_TRANSLATE_NOOP("gettextFromC", "transmitter"), QT_TRANSLATE_NOOP("gettextFromC", "violation"), QT_TRANSLATE_NOOP("gettextFromC", "bookmark"), QT_TRANSLATE_NOOP("gettextFromC", "surface"), QT_TRANSLATE_NOOP("gettextFromC", "safety stop"),
QT_TRANSLATE_NOOP("gettextFromC","gaschange"), QT_TRANSLATE_NOOP("gettextFromC","safety stop (voluntary)"), QT_TRANSLATE_NOOP("gettextFromC","safety stop (mandatory)"), QT_TRANSLATE_NOOP("gettextFromC", "gaschange"), QT_TRANSLATE_NOOP("gettextFromC", "safety stop (voluntary)"), QT_TRANSLATE_NOOP("gettextFromC", "safety stop (mandatory)"),
QT_TRANSLATE_NOOP("gettextFromC","deepstop"), QT_TRANSLATE_NOOP("gettextFromC","ceiling (safety stop)"), QT_TRANSLATE_NOOP3("gettextFromC","below floor","event showing dive is below deco floor and adding deco time"), QT_TRANSLATE_NOOP("gettextFromC","divetime"), QT_TRANSLATE_NOOP("gettextFromC", "deepstop"), QT_TRANSLATE_NOOP("gettextFromC", "ceiling (safety stop)"), QT_TRANSLATE_NOOP3("gettextFromC", "below floor", "event showing dive is below deco floor and adding deco time"), QT_TRANSLATE_NOOP("gettextFromC", "divetime"),
QT_TRANSLATE_NOOP("gettextFromC","maxdepth"), QT_TRANSLATE_NOOP("gettextFromC","OLF"), QT_TRANSLATE_NOOP("gettextFromC","PO2"), QT_TRANSLATE_NOOP("gettextFromC","airtime"), QT_TRANSLATE_NOOP("gettextFromC","rgbm"), QT_TRANSLATE_NOOP("gettextFromC","heading"), QT_TRANSLATE_NOOP("gettextFromC", "maxdepth"), QT_TRANSLATE_NOOP("gettextFromC", "OLF"), QT_TRANSLATE_NOOP("gettextFromC", "PO2"), QT_TRANSLATE_NOOP("gettextFromC", "airtime"), QT_TRANSLATE_NOOP("gettextFromC", "rgbm"), QT_TRANSLATE_NOOP("gettextFromC", "heading"),
QT_TRANSLATE_NOOP("gettextFromC","tissue level warning"), QT_TRANSLATE_NOOP("gettextFromC","gaschange"), QT_TRANSLATE_NOOP("gettextFromC","non stop time") QT_TRANSLATE_NOOP("gettextFromC", "tissue level warning"), QT_TRANSLATE_NOOP("gettextFromC", "gaschange"), QT_TRANSLATE_NOOP("gettextFromC", "non stop time")
}; };
const int nr_events = sizeof(events) / sizeof(const char *); const int nr_events = sizeof(events) / sizeof(const char *);
const char *name; const char *name;
@ -158,7 +158,7 @@ static void handle_event(struct divecomputer *dc, struct sample *sample, dc_samp
* Other evens might be more interesting, but for now we just print them out. * Other evens might be more interesting, but for now we just print them out.
*/ */
type = value.event.type; type = value.event.type;
name = QT_TRANSLATE_NOOP("gettextFromC","invalid event number"); name = QT_TRANSLATE_NOOP("gettextFromC", "invalid event number");
if (type < nr_events) if (type < nr_events)
name = events[type]; name = events[type];
@ -180,7 +180,7 @@ sample_cb(dc_sample_type_t type, dc_sample_value_t value, void *userdata)
* We fill in the "previous" sample - except for DC_SAMPLE_TIME, * We fill in the "previous" sample - except for DC_SAMPLE_TIME,
* which creates a new one. * which creates a new one.
*/ */
sample = dc->samples ? dc->sample+dc->samples-1 : NULL; sample = dc->samples ? dc->sample + dc->samples - 1 : NULL;
/* /*
* Ok, sanity check. * Ok, sanity check.
@ -227,9 +227,9 @@ sample_cb(dc_sample_type_t type, dc_sample_value_t value, void *userdata)
break; break;
case DC_SAMPLE_VENDOR: case DC_SAMPLE_VENDOR:
printf(" <vendor time='%u:%02u' type=\"%u\" size=\"%u\">", FRACTION(sample->time.seconds, 60), printf(" <vendor time='%u:%02u' type=\"%u\" size=\"%u\">", FRACTION(sample->time.seconds, 60),
value.vendor.type, value.vendor.size); value.vendor.type, value.vendor.size);
for (i = 0; i < value.vendor.size; ++i) for (i = 0; i < value.vendor.size; ++i)
printf("%02X", ((unsigned char *) value.vendor.data)[i]); printf("%02X", ((unsigned char *)value.vendor.data)[i]);
printf("</vendor>\n"); printf("</vendor>\n");
break; break;
#if DC_VERSION_CHECK(0, 3, 0) #if DC_VERSION_CHECK(0, 3, 0)
@ -358,9 +358,9 @@ static char *str_printf(const char *fmt, ...)
char buf[1024]; char buf[1024];
va_start(args, fmt); va_start(args, fmt);
vsnprintf(buf, sizeof(buf)-1, fmt, args); vsnprintf(buf, sizeof(buf) - 1, fmt, args);
va_end(args); va_end(args);
buf[sizeof(buf)-1] = 0; buf[sizeof(buf) - 1] = 0;
return strdup(buf); return strdup(buf);
} }
@ -384,13 +384,13 @@ static uint32_t calculate_diveid(const unsigned char *fingerprint, unsigned int
/* returns true if we want libdivecomputer's dc_device_foreach() to continue, /* returns true if we want libdivecomputer's dc_device_foreach() to continue,
* false otherwise */ * false otherwise */
static int dive_cb(const unsigned char *data, unsigned int size, static int dive_cb(const unsigned char *data, unsigned int size,
const unsigned char *fingerprint, unsigned int fsize, const unsigned char *fingerprint, unsigned int fsize,
void *userdata) void *userdata)
{ {
int rc; int rc;
dc_parser_t *parser = NULL; dc_parser_t *parser = NULL;
device_data_t *devdata = userdata; device_data_t *devdata = userdata;
dc_datetime_t dt = {0}; dc_datetime_t dt = { 0 };
struct tm tm; struct tm tm;
struct dive *dive; struct dive *dive;
@ -400,13 +400,13 @@ static int dive_cb(const unsigned char *data, unsigned int size,
rc = create_parser(devdata, &parser); rc = create_parser(devdata, &parser);
if (rc != DC_STATUS_SUCCESS) { if (rc != DC_STATUS_SUCCESS) {
dev_info(devdata, translate("gettextFromC","Unable to create parser for %s %s"), devdata->vendor, devdata->product); dev_info(devdata, translate("gettextFromC", "Unable to create parser for %s %s"), devdata->vendor, devdata->product);
return false; return false;
} }
rc = dc_parser_set_data(parser, data, size); rc = dc_parser_set_data(parser, data, size);
if (rc != DC_STATUS_SUCCESS) { if (rc != DC_STATUS_SUCCESS) {
dev_info(devdata, translate("gettextFromC","Error registering the data")); dev_info(devdata, translate("gettextFromC", "Error registering the data"));
dc_parser_destroy(parser); dc_parser_destroy(parser);
return false; return false;
} }
@ -415,7 +415,7 @@ static int dive_cb(const unsigned char *data, unsigned int size,
dive = alloc_dive(); dive = alloc_dive();
rc = dc_parser_get_datetime(parser, &dt); rc = dc_parser_get_datetime(parser, &dt);
if (rc != DC_STATUS_SUCCESS && rc != DC_STATUS_UNSUPPORTED) { if (rc != DC_STATUS_SUCCESS && rc != DC_STATUS_UNSUPPORTED) {
dev_info(devdata, translate("gettextFromC","Error parsing the datetime")); dev_info(devdata, translate("gettextFromC", "Error parsing the datetime"));
dc_parser_destroy(parser); dc_parser_destroy(parser);
return false; return false;
} }
@ -424,7 +424,7 @@ static int dive_cb(const unsigned char *data, unsigned int size,
dive->dc.diveid = calculate_diveid(fingerprint, fsize); dive->dc.diveid = calculate_diveid(fingerprint, fsize);
tm.tm_year = dt.year; tm.tm_year = dt.year;
tm.tm_mon = dt.month-1; tm.tm_mon = dt.month - 1;
tm.tm_mday = dt.day; tm.tm_mday = dt.day;
tm.tm_hour = dt.hour; tm.tm_hour = dt.hour;
tm.tm_min = dt.minute; tm.tm_min = dt.minute;
@ -432,12 +432,12 @@ static int dive_cb(const unsigned char *data, unsigned int size,
dive->when = dive->dc.when = utc_mktime(&tm); dive->when = dive->dc.when = utc_mktime(&tm);
// Parse the divetime. // Parse the divetime.
dev_info(devdata, translate("gettextFromC","Dive %d: %s %d %04d"), import_dive_number, dev_info(devdata, translate("gettextFromC", "Dive %d: %s %d %04d"), import_dive_number,
monthname(tm.tm_mon), tm.tm_mday, year(tm.tm_year)); monthname(tm.tm_mon), tm.tm_mday, year(tm.tm_year));
unsigned int divetime = 0; unsigned int divetime = 0;
rc = dc_parser_get_field (parser, DC_FIELD_DIVETIME, 0, &divetime); rc = dc_parser_get_field(parser, DC_FIELD_DIVETIME, 0, &divetime);
if (rc != DC_STATUS_SUCCESS && rc != DC_STATUS_UNSUPPORTED) { if (rc != DC_STATUS_SUCCESS && rc != DC_STATUS_UNSUPPORTED) {
dev_info(devdata, translate("gettextFromC","Error parsing the divetime")); dev_info(devdata, translate("gettextFromC", "Error parsing the divetime"));
dc_parser_destroy(parser); dc_parser_destroy(parser);
return false; return false;
} }
@ -447,7 +447,7 @@ static int dive_cb(const unsigned char *data, unsigned int size,
double maxdepth = 0.0; double maxdepth = 0.0;
rc = dc_parser_get_field(parser, DC_FIELD_MAXDEPTH, 0, &maxdepth); rc = dc_parser_get_field(parser, DC_FIELD_MAXDEPTH, 0, &maxdepth);
if (rc != DC_STATUS_SUCCESS && rc != DC_STATUS_UNSUPPORTED) { if (rc != DC_STATUS_SUCCESS && rc != DC_STATUS_UNSUPPORTED) {
dev_info(devdata, translate("gettextFromC","Error parsing the maxdepth")); dev_info(devdata, translate("gettextFromC", "Error parsing the maxdepth"));
dc_parser_destroy(parser); dc_parser_destroy(parser);
return false; return false;
} }
@ -457,7 +457,7 @@ static int dive_cb(const unsigned char *data, unsigned int size,
unsigned int ngases = 0; unsigned int ngases = 0;
rc = dc_parser_get_field(parser, DC_FIELD_GASMIX_COUNT, 0, &ngases); rc = dc_parser_get_field(parser, DC_FIELD_GASMIX_COUNT, 0, &ngases);
if (rc != DC_STATUS_SUCCESS && rc != DC_STATUS_UNSUPPORTED) { if (rc != DC_STATUS_SUCCESS && rc != DC_STATUS_UNSUPPORTED) {
dev_info(devdata, translate("gettextFromC","Error parsing the gas mix count")); dev_info(devdata, translate("gettextFromC", "Error parsing the gas mix count"));
dc_parser_destroy(parser); dc_parser_destroy(parser);
return false; return false;
} }
@ -466,11 +466,11 @@ static int dive_cb(const unsigned char *data, unsigned int size,
// Check if the libdivecomputer version already supports salinity & atmospheric // Check if the libdivecomputer version already supports salinity & atmospheric
dc_salinity_t salinity = { dc_salinity_t salinity = {
.type = DC_WATER_SALT, .type = DC_WATER_SALT,
.density = SEAWATER_SALINITY/10.0 .density = SEAWATER_SALINITY / 10.0
}; };
rc = dc_parser_get_field(parser, DC_FIELD_SALINITY, 0, &salinity); rc = dc_parser_get_field(parser, DC_FIELD_SALINITY, 0, &salinity);
if (rc != DC_STATUS_SUCCESS && rc != DC_STATUS_UNSUPPORTED) { if (rc != DC_STATUS_SUCCESS && rc != DC_STATUS_UNSUPPORTED) {
dev_info(devdata, translate("gettextFromC","Error obtaining water salinity")); dev_info(devdata, translate("gettextFromC", "Error obtaining water salinity"));
dc_parser_destroy(parser); dc_parser_destroy(parser);
return false; return false;
} }
@ -479,7 +479,7 @@ static int dive_cb(const unsigned char *data, unsigned int size,
double surface_pressure = 0; double surface_pressure = 0;
rc = dc_parser_get_field(parser, DC_FIELD_ATMOSPHERIC, 0, &surface_pressure); rc = dc_parser_get_field(parser, DC_FIELD_ATMOSPHERIC, 0, &surface_pressure);
if (rc != DC_STATUS_SUCCESS && rc != DC_STATUS_UNSUPPORTED) { if (rc != DC_STATUS_SUCCESS && rc != DC_STATUS_UNSUPPORTED) {
dev_info(devdata, translate("gettextFromC","Error obtaining surface pressure")); dev_info(devdata, translate("gettextFromC", "Error obtaining surface pressure"));
dc_parser_destroy(parser); dc_parser_destroy(parser);
return false; return false;
} }
@ -488,7 +488,7 @@ static int dive_cb(const unsigned char *data, unsigned int size,
rc = parse_gasmixes(devdata, dive, parser, ngases, data); rc = parse_gasmixes(devdata, dive, parser, ngases, data);
if (rc != DC_STATUS_SUCCESS) { if (rc != DC_STATUS_SUCCESS) {
dev_info(devdata, translate("gettextFromC","Error parsing the gas mix")); dev_info(devdata, translate("gettextFromC", "Error parsing the gas mix"));
dc_parser_destroy(parser); dc_parser_destroy(parser);
return false; return false;
} }
@ -496,7 +496,7 @@ static int dive_cb(const unsigned char *data, unsigned int size,
// Initialize the sample data. // Initialize the sample data.
rc = parse_samples(devdata, &dive->dc, parser); rc = parse_samples(devdata, &dive->dc, parser);
if (rc != DC_STATUS_SUCCESS) { if (rc != DC_STATUS_SUCCESS) {
dev_info(devdata, translate("gettextFromC","Error parsing the samples")); dev_info(devdata, translate("gettextFromC", "Error parsing the samples"));
dc_parser_destroy(parser); dc_parser_destroy(parser);
return false; return false;
} }
@ -570,10 +570,14 @@ static unsigned int undo_libdivecomputer_suunto_nr_changes(unsigned int serial)
return serial; return serial;
/* Nope, it was converted. */ /* Nope, it was converted. */
b0 = serial % 100; serial /= 100; b0 = serial % 100;
b1 = serial % 100; serial /= 100; serial /= 100;
b2 = serial % 100; serial /= 100; b1 = serial % 100;
b3 = serial % 100; serial /= 100; serial /= 100;
b2 = serial % 100;
serial /= 100;
b3 = serial % 100;
serial /= 100;
serial = b0 + (b1 << 8) + (b2 << 16) + (b3 << 24); serial = b0 + (b1 << 8) + (b2 << 16) + (b3 << 24);
return serial; return serial;
@ -591,16 +595,16 @@ static unsigned int fixup_suunto_versions(device_data_t *devdata, const dc_event
if (serial) { if (serial) {
snprintf(serial_nr, sizeof(serial_nr), "%02d%02d%02d%02d", snprintf(serial_nr, sizeof(serial_nr), "%02d%02d%02d%02d",
(devinfo->serial >> 24) & 0xff, (devinfo->serial >> 24) & 0xff,
(devinfo->serial >> 16) & 0xff, (devinfo->serial >> 16) & 0xff,
(devinfo->serial >> 8) & 0xff, (devinfo->serial >> 8) & 0xff,
(devinfo->serial >> 0) & 0xff); (devinfo->serial >> 0) & 0xff);
} }
if (devinfo->firmware) { if (devinfo->firmware) {
snprintf(firmware, sizeof(firmware), "%d.%d.%d", snprintf(firmware, sizeof(firmware), "%d.%d.%d",
(devinfo->firmware >> 16) & 0xff, (devinfo->firmware >> 16) & 0xff,
(devinfo->firmware >> 8) & 0xff, (devinfo->firmware >> 8) & 0xff,
(devinfo->firmware >> 0) & 0xff); (devinfo->firmware >> 0) & 0xff);
} }
create_device_node(devdata->model, devdata->deviceid, serial_nr, firmware, ""); create_device_node(devdata->model, devdata->deviceid, serial_nr, firmware, "");
@ -618,18 +622,18 @@ static void event_cb(dc_device_t *device, dc_event_type_t event, const void *dat
switch (event) { switch (event) {
case DC_EVENT_WAITING: case DC_EVENT_WAITING:
dev_info(devdata, translate("gettextFromC","Event: waiting for user action")); dev_info(devdata, translate("gettextFromC", "Event: waiting for user action"));
break; break;
case DC_EVENT_PROGRESS: case DC_EVENT_PROGRESS:
if (!progress->maximum) if (!progress->maximum)
break; break;
progress_bar_fraction = (double) progress->current / (double) progress->maximum; progress_bar_fraction = (double)progress->current / (double)progress->maximum;
break; break;
case DC_EVENT_DEVINFO: case DC_EVENT_DEVINFO:
dev_info(devdata, translate("gettextFromC","model=%u (0x%08x), firmware=%u (0x%08x), serial=%u (0x%08x)"), dev_info(devdata, translate("gettextFromC", "model=%u (0x%08x), firmware=%u (0x%08x), serial=%u (0x%08x)"),
devinfo->model, devinfo->model, devinfo->model, devinfo->model,
devinfo->firmware, devinfo->firmware, devinfo->firmware, devinfo->firmware,
devinfo->serial, devinfo->serial); devinfo->serial, devinfo->serial);
if (devdata->libdc_logfile) { if (devdata->libdc_logfile) {
fprintf(devdata->libdc_logfile, "Event: model=%u (0x%08x), firmware=%u (0x%08x), serial=%u (0x%08x)\n", fprintf(devdata->libdc_logfile, "Event: model=%u (0x%08x), firmware=%u (0x%08x), serial=%u (0x%08x)\n",
devinfo->model, devinfo->model, devinfo->model, devinfo->model,
@ -647,10 +651,10 @@ static void event_cb(dc_device_t *device, dc_event_type_t event, const void *dat
break; break;
case DC_EVENT_CLOCK: case DC_EVENT_CLOCK:
dev_info(devdata, translate("gettextFromC","Event: systime=%"PRId64", devtime=%u\n"), dev_info(devdata, translate("gettextFromC", "Event: systime=%" PRId64 ", devtime=%u\n"),
(uint64_t)clock->systime, clock->devtime); (uint64_t)clock->systime, clock->devtime);
if (devdata->libdc_logfile) { if (devdata->libdc_logfile) {
fprintf(devdata->libdc_logfile, "Event: systime=%"PRId64", devtime=%u\n", fprintf(devdata->libdc_logfile, "Event: systime=%" PRId64 ", devtime=%u\n",
(uint64_t)clock->systime, clock->devtime); (uint64_t)clock->systime, clock->devtime);
} }
break; break;
@ -659,7 +663,7 @@ static void event_cb(dc_device_t *device, dc_event_type_t event, const void *dat
fprintf(devdata->libdc_logfile, "Event: vendor="); fprintf(devdata->libdc_logfile, "Event: vendor=");
for (unsigned int i = 0; i < vendor->size; ++i) for (unsigned int i = 0; i < vendor->size; ++i)
fprintf(devdata->libdc_logfile, "%02X", vendor->data[i]); fprintf(devdata->libdc_logfile, "%02X", vendor->data[i]);
fprintf(devdata->libdc_logfile,"\n"); fprintf(devdata->libdc_logfile, "\n");
} }
break; break;
default: default:
@ -667,7 +671,7 @@ static void event_cb(dc_device_t *device, dc_event_type_t event, const void *dat
} }
} }
int import_thread_cancelled; int import_thread_cancelled;
static int static int
cancel_cb(void *userdata) cancel_cb(void *userdata)
@ -686,33 +690,33 @@ static const char *do_device_import(device_data_t *data)
int events = DC_EVENT_WAITING | DC_EVENT_PROGRESS | DC_EVENT_DEVINFO | DC_EVENT_CLOCK | DC_EVENT_VENDOR; int events = DC_EVENT_WAITING | DC_EVENT_PROGRESS | DC_EVENT_DEVINFO | DC_EVENT_CLOCK | DC_EVENT_VENDOR;
rc = dc_device_set_events(device, events, event_cb, data); rc = dc_device_set_events(device, events, event_cb, data);
if (rc != DC_STATUS_SUCCESS) if (rc != DC_STATUS_SUCCESS)
return translate("gettextFromC","Error registering the event handler."); return translate("gettextFromC", "Error registering the event handler.");
// Register the cancellation handler. // Register the cancellation handler.
rc = dc_device_set_cancel(device, cancel_cb, data); rc = dc_device_set_cancel(device, cancel_cb, data);
if (rc != DC_STATUS_SUCCESS) if (rc != DC_STATUS_SUCCESS)
return translate("gettextFromC","Error registering the cancellation handler."); return translate("gettextFromC", "Error registering the cancellation handler.");
if (data->libdc_dump) { if (data->libdc_dump) {
dc_buffer_t *buffer = dc_buffer_new (0); dc_buffer_t *buffer = dc_buffer_new(0);
rc = dc_device_dump (device, buffer); rc = dc_device_dump(device, buffer);
if (rc == DC_STATUS_SUCCESS && dumpfile_name) { if (rc == DC_STATUS_SUCCESS && dumpfile_name) {
FILE* fp = subsurface_fopen(dumpfile_name, "wb"); FILE *fp = subsurface_fopen(dumpfile_name, "wb");
if (fp != NULL) { if (fp != NULL) {
fwrite (dc_buffer_get_data (buffer), 1, dc_buffer_get_size (buffer), fp); fwrite(dc_buffer_get_data(buffer), 1, dc_buffer_get_size(buffer), fp);
fclose (fp); fclose(fp);
} }
} }
dc_buffer_free (buffer); dc_buffer_free(buffer);
} else { } else {
rc = dc_device_foreach(device, dive_cb, data); rc = dc_device_foreach(device, dive_cb, data);
} }
if (rc != DC_STATUS_SUCCESS) { if (rc != DC_STATUS_SUCCESS) {
progress_bar_fraction = 0.0; progress_bar_fraction = 0.0;
return translate("gettextFromC","Dive data import error"); return translate("gettextFromC", "Dive data import error");
} }
/* All good */ /* All good */
@ -722,9 +726,9 @@ static const char *do_device_import(device_data_t *data)
static void static void
logfunc(dc_context_t *context, dc_loglevel_t loglevel, const char *file, unsigned int line, const char *function, const char *msg, void *userdata) logfunc(dc_context_t *context, dc_loglevel_t loglevel, const char *file, unsigned int line, const char *function, const char *msg, void *userdata)
{ {
const char *loglevels[] = {"NONE", "ERROR", "WARNING", "INFO", "DEBUG", "ALL"}; const char *loglevels[] = { "NONE", "ERROR", "WARNING", "INFO", "DEBUG", "ALL" };
FILE *fp = (FILE *) userdata; FILE *fp = (FILE *)userdata;
if (loglevel == DC_LOGLEVEL_ERROR || loglevel == DC_LOGLEVEL_WARNING) { if (loglevel == DC_LOGLEVEL_ERROR || loglevel == DC_LOGLEVEL_WARNING) {
fprintf(fp, "%s: %s [in %s:%d (%s)]\n", loglevels[loglevel], msg, file, line, function); fprintf(fp, "%s: %s [in %s:%d (%s)]\n", loglevels[loglevel], msg, file, line, function);
@ -751,14 +755,14 @@ const char *do_libdivecomputer_import(device_data_t *data)
rc = dc_context_new(&data->context); rc = dc_context_new(&data->context);
if (rc != DC_STATUS_SUCCESS) if (rc != DC_STATUS_SUCCESS)
return translate("gettextFromC","Unable to create libdivecomputer context"); return translate("gettextFromC", "Unable to create libdivecomputer context");
if (fp) { if (fp) {
dc_context_set_loglevel(data->context, DC_LOGLEVEL_ALL); dc_context_set_loglevel(data->context, DC_LOGLEVEL_ALL);
dc_context_set_logfunc(data->context, logfunc, fp); dc_context_set_logfunc(data->context, logfunc, fp);
} }
err = translate("gettextFromC","Unable to open %s %s (%s)"); err = translate("gettextFromC", "Unable to open %s %s (%s)");
rc = dc_device_open(&data->device, data->context, data->descriptor, data->devname); rc = dc_device_open(&data->device, data->context, data->descriptor, data->devname);
if (rc == DC_STATUS_SUCCESS) { if (rc == DC_STATUS_SUCCESS) {
err = do_device_import(data); err = do_device_import(data);

View file

@ -15,7 +15,8 @@ extern "C" {
/* don't forget to include the UI toolkit specific display-XXX.h first /* don't forget to include the UI toolkit specific display-XXX.h first
to get the definition of progressbar_t */ to get the definition of progressbar_t */
typedef struct device_data_t { typedef struct device_data_t
{
dc_descriptor_t *descriptor; dc_descriptor_t *descriptor;
const char *vendor, *product, *devname; const char *vendor, *product, *devname;
const char *model; const char *model;

20
linux.c
View file

@ -25,7 +25,7 @@ const char *system_default_filename(void)
return buffer; return buffer;
} }
int enumerate_devices (device_callback_t callback, void *userdata) int enumerate_devices(device_callback_t callback, void *userdata)
{ {
int index = -1; int index = -1;
DIR *dp = NULL; DIR *dp = NULL;
@ -44,28 +44,28 @@ int enumerate_devices (device_callback_t callback, void *userdata)
char *fname; char *fname;
size_t len; size_t len;
dp = opendir (dirname); dp = opendir(dirname);
if (dp == NULL) { if (dp == NULL) {
return -1; return -1;
} }
while ((ep = readdir (dp)) != NULL) { while ((ep = readdir(dp)) != NULL) {
for (i = 0; patterns[i] != NULL; ++i) { for (i = 0; patterns[i] != NULL; ++i) {
if (fnmatch (patterns[i], ep->d_name, 0) == 0) { if (fnmatch(patterns[i], ep->d_name, 0) == 0) {
char filename[1024]; char filename[1024];
int n = snprintf (filename, sizeof (filename), "%s/%s", dirname, ep->d_name); int n = snprintf(filename, sizeof(filename), "%s/%s", dirname, ep->d_name);
if (n >= sizeof (filename)) { if (n >= sizeof(filename)) {
closedir (dp); closedir(dp);
return -1; return -1;
} }
callback (filename, userdata); callback(filename, userdata);
if (is_default_dive_computer_device(filename)) if (is_default_dive_computer_device(filename))
index = i; index = i;
break; break;
} }
} }
} }
closedir (dp); closedir(dp);
file = fopen("/proc/mounts", "r"); file = fopen("/proc/mounts", "r");
if (file == NULL) if (file == NULL)
@ -91,7 +91,7 @@ int enumerate_devices (device_callback_t callback, void *userdata)
index = i; index = i;
i++; i++;
free((void *)fname); free((void *)fname);
} }
} }
free(line); free(line);

24
macos.c
View file

@ -17,9 +17,9 @@
* but no similar macros if a C string variable is supposed to be * but no similar macros if a C string variable is supposed to be
* the argument. We add this here (hardcoding the default allocator * the argument. We add this here (hardcoding the default allocator
* and MacRoman encoding */ * and MacRoman encoding */
#define CFSTR_VAR(_var) CFStringCreateWithCStringNoCopy(kCFAllocatorDefault, \ #define CFSTR_VAR(_var) CFStringCreateWithCStringNoCopy(kCFAllocatorDefault, \
(_var), kCFStringEncodingMacRoman, \ (_var), kCFStringEncodingMacRoman, \
kCFAllocatorNull) kCFAllocatorNull)
#define SUBSURFACE_PREFERENCES CFSTR("org.hohndel.subsurface") #define SUBSURFACE_PREFERENCES CFSTR("org.hohndel.subsurface")
#define ICON_NAME "Subsurface.icns" #define ICON_NAME "Subsurface.icns"
@ -41,7 +41,7 @@ const char *system_default_filename(void)
return buffer; return buffer;
} }
int enumerate_devices (device_callback_t callback, void *userdata) int enumerate_devices(device_callback_t callback, void *userdata)
{ {
int index = -1; int index = -1;
DIR *dp = NULL; DIR *dp = NULL;
@ -54,21 +54,21 @@ int enumerate_devices (device_callback_t callback, void *userdata)
NULL NULL
}; };
dp = opendir (dirname); dp = opendir(dirname);
if (dp == NULL) { if (dp == NULL) {
return -1; return -1;
} }
while ((ep = readdir (dp)) != NULL) { while ((ep = readdir(dp)) != NULL) {
for (i = 0; patterns[i] != NULL; ++i) { for (i = 0; patterns[i] != NULL; ++i) {
if (fnmatch (patterns[i], ep->d_name, 0) == 0) { if (fnmatch(patterns[i], ep->d_name, 0) == 0) {
char filename[1024]; char filename[1024];
int n = snprintf (filename, sizeof (filename), "%s/%s", dirname, ep->d_name); int n = snprintf(filename, sizeof(filename), "%s/%s", dirname, ep->d_name);
if (n >= sizeof (filename)) { if (n >= sizeof(filename)) {
closedir (dp); closedir(dp);
return -1; return -1;
} }
callback (filename, userdata); callback(filename, userdata);
if (is_default_dive_computer_device(filename)) if (is_default_dive_computer_device(filename))
index = i; index = i;
break; break;
@ -77,7 +77,7 @@ int enumerate_devices (device_callback_t callback, void *userdata)
} }
// TODO: list UEMIS mount point from /proc/mounts // TODO: list UEMIS mount point from /proc/mounts
closedir (dp); closedir(dp);
return index; return index;
} }

View file

@ -45,7 +45,7 @@ int main(int argc, char **argv)
if (no_filenames) { if (no_filenames) {
QString defaultFile(prefs.default_filename); QString defaultFile(prefs.default_filename);
if (!defaultFile.isEmpty()) if (!defaultFile.isEmpty())
files.push_back( QString(prefs.default_filename) ); files.push_back(QString(prefs.default_filename));
} }
parse_xml_exit(); parse_xml_exit();
MainWindow::instance()->loadFiles(files); MainWindow::instance()->loadFiles(files);

View file

@ -24,7 +24,7 @@ void flush_buffer(struct membuffer *b, FILE *f)
void strip_mb(struct membuffer *b) void strip_mb(struct membuffer *b)
{ {
while (b->len && isspace(b->buffer[b->len-1])) while (b->len && isspace(b->buffer[b->len - 1]))
b->len--; b->len--;
} }

View file

@ -13,9 +13,9 @@ struct membuffer {
}; };
#ifdef __GNUC__ #ifdef __GNUC__
#define __printf(x,y) __attribute__ ((__format__ (__printf__, x, y))) #define __printf(x, y) __attribute__((__format__(__printf__, x, y)))
#else #else
#define __printf(x,y) #define __printf(x, y)
#endif #endif
extern void free_buffer(struct membuffer *); extern void free_buffer(struct membuffer *);
@ -23,8 +23,8 @@ extern void flush_buffer(struct membuffer *, FILE *);
extern void put_bytes(struct membuffer *, const char *, int); extern void put_bytes(struct membuffer *, const char *, int);
extern void put_string(struct membuffer *, const char *); extern void put_string(struct membuffer *, const char *);
extern void strip_mb(struct membuffer *); extern void strip_mb(struct membuffer *);
extern __printf(2,0) void put_vformat(struct membuffer *, const char *, va_list); extern __printf(2, 0) void put_vformat(struct membuffer *, const char *, va_list);
extern __printf(2,3) void put_format(struct membuffer *, const char *fmt, ...); extern __printf(2, 3) void put_format(struct membuffer *, const char *fmt, ...);
/* Output one of our "milli" values with type and pre/post data */ /* Output one of our "milli" values with type and pre/post data */
extern void put_milli(struct membuffer *, const char *, int, const char *); extern void put_milli(struct membuffer *, const char *, int, const char *);

View file

@ -18,8 +18,7 @@ unsigned int decostoplevels[] = { 0, 3000, 6000, 9000, 12000, 15000, 18000, 2100
60000, 63000, 66000, 69000, 72000, 75000, 78000, 81000, 84000, 87000, 60000, 63000, 66000, 69000, 72000, 75000, 78000, 81000, 84000, 87000,
90000, 100000, 110000, 120000, 130000, 140000, 150000, 160000, 170000, 90000, 100000, 110000, 120000, 130000, 140000, 150000, 160000, 170000,
180000, 190000, 200000, 220000, 240000, 260000, 280000, 300000, 180000, 190000, 200000, 220000, 240000, 260000, 280000, 300000,
320000, 340000, 360000, 380000 320000, 340000, 360000, 380000 };
};
double plangflow, plangfhigh; double plangflow, plangfhigh;
char *disclaimer; char *disclaimer;
@ -30,21 +29,20 @@ void dump_plan(struct diveplan *diveplan)
struct tm tm; struct tm tm;
if (!diveplan) { if (!diveplan) {
printf ("Diveplan NULL\n"); printf("Diveplan NULL\n");
return; return;
} }
utc_mkdate(diveplan->when, &tm); utc_mkdate(diveplan->when, &tm);
printf("\nDiveplan @ %04d-%02d-%02d %02d:%02d:%02d (surfpres %dmbar):\n", printf("\nDiveplan @ %04d-%02d-%02d %02d:%02d:%02d (surfpres %dmbar):\n",
tm.tm_year+1900, tm.tm_mon+1, tm.tm_mday, tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday,
tm.tm_hour, tm.tm_min, tm.tm_sec, tm.tm_hour, tm.tm_min, tm.tm_sec,
diveplan->surface_pressure); diveplan->surface_pressure);
dp = diveplan->dp; dp = diveplan->dp;
while (dp) { while (dp) {
printf("\t%3u:%02u: %dmm gas: %d o2 %d h2\n", FRACTION(dp->time, 60), dp->depth, dp->o2, dp->he); printf("\t%3u:%02u: %dmm gas: %d o2 %d h2\n", FRACTION(dp->time, 60), dp->depth, dp->o2, dp->he);
dp = dp->next; dp = dp->next;
} }
} }
#endif #endif
@ -94,11 +92,11 @@ int get_gasidx(struct dive *dive, int o2, int he)
void get_gas_string(int o2, int he, char *text, int len) void get_gas_string(int o2, int he, char *text, int len)
{ {
if (is_air(o2, he)) if (is_air(o2, he))
snprintf(text, len, "%s", translate("gettextFromC","air")); snprintf(text, len, "%s", translate("gettextFromC", "air"));
else if (he == 0) else if (he == 0)
snprintf(text, len, translate("gettextFromC","EAN%d"), (o2 + 5) / 10); snprintf(text, len, translate("gettextFromC", "EAN%d"), (o2 + 5) / 10);
else else
snprintf(text, len, "(%d/%d)", (o2 + 5) / 10, (he + 5) / 10); snprintf(text, len, "(%d/%d)", (o2 + 5) / 10, (he + 5) / 10);
} }
/* returns the tissue tolerance at the end of this (partial) dive */ /* returns the tissue tolerance at the end of this (partial) dive */
@ -131,7 +129,7 @@ double tissue_at_end(struct dive *dive, char **cached_datap, const char **error_
t1 = sample->time.seconds; t1 = sample->time.seconds;
get_gas_from_events(&dive->dc, t0, &o2, &he); get_gas_from_events(&dive->dc, t0, &o2, &he);
if ((gasidx = get_gasidx(dive, o2, he)) == -1) { if ((gasidx = get_gasidx(dive, o2, he)) == -1) {
snprintf(buf, sizeof(buf),translate("gettextFromC","Can't find gas %d/%d"), (o2 + 5) / 10, (he + 5) / 10); snprintf(buf, sizeof(buf), translate("gettextFromC", "Can't find gas %d/%d"), (o2 + 5) / 10, (he + 5) / 10);
*error_string_p = buf; *error_string_p = buf;
gasidx = 0; gasidx = 0;
} }
@ -288,10 +286,11 @@ struct dive *create_dive_from_plan(struct diveplan *diveplan, const char **error
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 idx; int idx;
if ((idx = add_gas(dive, plano2, planhe)) < 0) if ((idx = add_gas(dive, plano2, planhe)) < 0)
goto gas_error_exit; goto gas_error_exit;
add_gas_switch_event(dive, dc, lasttime, idx); add_gas_switch_event(dive, dc, lasttime, idx);
oldo2 = o2; oldhe = he; oldo2 = o2;
oldhe = he;
} }
/* Create sample */ /* Create sample */
sample = prepare_sample(dc); sample = prepare_sample(dc);
@ -318,7 +317,7 @@ struct dive *create_dive_from_plan(struct diveplan *diveplan, const char **error
gas_error_exit: gas_error_exit:
free(dive); free(dive);
*error_string = translate("gettextFromC","Too many gas mixes"); *error_string = translate("gettextFromC", "Too many gas mixes");
return NULL; return NULL;
} }
@ -379,11 +378,11 @@ void add_to_end_of_diveplan(struct diveplan *diveplan, struct divedatapoint *dp)
dp->time += lasttime; dp->time += lasttime;
} }
struct divedatapoint * plan_add_segment(struct diveplan *diveplan, int duration, int depth, int o2, int he, int po2) struct divedatapoint *plan_add_segment(struct diveplan *diveplan, int duration, int depth, int o2, int he, int po2)
{ {
struct divedatapoint *dp = create_dp(duration, depth, o2, he, po2); struct divedatapoint *dp = create_dp(duration, depth, o2, he, po2);
add_to_end_of_diveplan(diveplan, dp); add_to_end_of_diveplan(diveplan, dp);
return(dp); return (dp);
} }
struct gaschanges { struct gaschanges {
@ -427,8 +426,8 @@ static struct gaschanges *analyze_gaslist(struct diveplan *diveplan, struct dive
#if DEBUG_PLAN & 16 #if DEBUG_PLAN & 16
for (nr = 0; nr < *gaschangenr; nr++) for (nr = 0; nr < *gaschangenr; nr++)
printf("gaschange nr %d: @ %5.2lfm gasidx %d (%d/%d)\n", nr, gaschanges[nr].depth / 1000.0, printf("gaschange nr %d: @ %5.2lfm gasidx %d (%d/%d)\n", nr, gaschanges[nr].depth / 1000.0,
gaschanges[nr].gasidx, (dive->cylinder[gaschanges[nr].gasidx].gasmix.o2.permille + 5) / 10, gaschanges[nr].gasidx, (dive->cylinder[gaschanges[nr].gasidx].gasmix.o2.permille + 5) / 10,
(dive->cylinder[gaschanges[nr].gasidx].gasmix.he.permille + 5) / 10); (dive->cylinder[gaschanges[nr].gasidx].gasmix.he.permille + 5) / 10);
#endif #endif
return gaschanges; return gaschanges;
} }
@ -477,8 +476,8 @@ static unsigned int *sort_stops(unsigned int *dstops, int dnr, struct gaschanges
#if DEBUG_PLAN & 16 #if DEBUG_PLAN & 16
int k; int k;
for (k = gnr + dnr -1; k >= 0; k--) { for (k = gnr + dnr - 1; k >= 0; k--) {
printf("stoplevel[%d]: %5.2lfm\n", k, stoplevels[k]/1000.0); printf("stoplevel[%d]: %5.2lfm\n", k, stoplevels[k] / 1000.0);
if (stoplevels[k] == 0) if (stoplevels[k] == 0)
break; break;
} }
@ -498,8 +497,8 @@ static void add_plan_to_notes(struct diveplan *diveplan, struct dive *dive)
if (!dp) if (!dp)
return; return;
snprintf(buffer, sizeof(buffer), translate("gettextFromC","%s\nSubsurface dive plan\nbased on GFlow = %.0f and GFhigh = %.0f\n\n"), snprintf(buffer, sizeof(buffer), translate("gettextFromC", "%s\nSubsurface dive plan\nbased on GFlow = %.0f and GFhigh = %.0f\n\n"),
disclaimer, plangflow * 100, plangfhigh * 100); disclaimer, plangflow * 100, plangfhigh * 100);
/* we start with gas 0, then check if that was changed */ /* we start with gas 0, then check if that was changed */
o2 = dive->cylinder[0].gasmix.o2.permille; o2 = dive->cylinder[0].gasmix.o2.permille;
he = dive->cylinder[0].gasmix.he.permille; he = dive->cylinder[0].gasmix.he.permille;
@ -538,28 +537,28 @@ static void add_plan_to_notes(struct diveplan *diveplan, struct dive *dive)
len = strlen(buffer); len = strlen(buffer);
if (dp->depth != lastdepth) { if (dp->depth != lastdepth) {
used = diveplan->bottomsac / 1000.0 * depth_to_mbar((dp->depth + lastdepth) / 2, dive) * used = diveplan->bottomsac / 1000.0 * depth_to_mbar((dp->depth + lastdepth) / 2, dive) *
(dp->time - lasttime) / 60; (dp->time - lasttime) / 60;
snprintf(buffer + len, sizeof(buffer) - len, translate("gettextFromC","Transition to %.*f %s in %d:%02d min - runtime %d:%02u on %s\n"), snprintf(buffer + len, sizeof(buffer) - len, translate("gettextFromC", "Transition to %.*f %s in %d:%02d min - runtime %d:%02u on %s\n"),
decimals, depthvalue, depth_unit, decimals, depthvalue, depth_unit,
FRACTION(dp->time - lasttime, 60), FRACTION(dp->time - lasttime, 60),
FRACTION(dp->time, 60), FRACTION(dp->time, 60),
gas); gas);
} else { } else {
/* we use deco SAC rate during the calculated deco stops, bottom SAC rate everywhere else */ /* we use deco SAC rate during the calculated deco stops, bottom SAC rate everywhere else */
int sac = dp->entered ? diveplan->bottomsac : diveplan->decosac; int sac = dp->entered ? diveplan->bottomsac : diveplan->decosac;
used = sac / 1000.0 * depth_to_mbar(dp->depth, dive) * (dp->time - lasttime) / 60; used = sac / 1000.0 * depth_to_mbar(dp->depth, dive) * (dp->time - lasttime) / 60;
snprintf(buffer + len, sizeof(buffer) - len, translate("gettextFromC","Stay at %.*f %s for %d:%02d min - runtime %d:%02u on %s\n"), snprintf(buffer + len, sizeof(buffer) - len, translate("gettextFromC", "Stay at %.*f %s for %d:%02d min - runtime %d:%02u on %s\n"),
decimals, depthvalue, depth_unit, decimals, depthvalue, depth_unit,
FRACTION(dp->time - lasttime, 60), FRACTION(dp->time - lasttime, 60),
FRACTION(dp->time, 60), FRACTION(dp->time, 60),
gas); gas);
} }
if (gasidx != -1) if (gasidx != -1)
consumption[gasidx] += used; consumption[gasidx] += used;
get_gas_string(newo2, newhe, gas, sizeof(gas)); get_gas_string(newo2, newhe, gas, sizeof(gas));
if (o2 != newo2 || he != newhe) { if (o2 != newo2 || he != newhe) {
len = strlen(buffer); len = strlen(buffer);
snprintf(buffer + len, sizeof(buffer) - len, translate("gettextFromC","Switch gas to %s\n"), gas); snprintf(buffer + len, sizeof(buffer) - len, translate("gettextFromC", "Switch gas to %s\n"), gas);
} }
o2 = newo2; o2 = newo2;
he = newhe; he = newhe;
@ -567,7 +566,7 @@ static void add_plan_to_notes(struct diveplan *diveplan, struct dive *dive)
lastdepth = dp->depth; lastdepth = dp->depth;
} while ((dp = dp->next) != NULL); } while ((dp = dp->next) != NULL);
len = strlen(buffer); len = strlen(buffer);
snprintf(buffer + len, sizeof(buffer) - len, translate("gettextFromC","Gas consumption:\n")); snprintf(buffer + len, sizeof(buffer) - len, translate("gettextFromC", "Gas consumption:\n"));
for (gasidx = 0; gasidx < MAX_CYLINDERS; gasidx++) { for (gasidx = 0; gasidx < MAX_CYLINDERS; gasidx++) {
double volume; double volume;
const char *unit; const char *unit;
@ -577,8 +576,8 @@ static void add_plan_to_notes(struct diveplan *diveplan, struct dive *dive)
len = strlen(buffer); len = strlen(buffer);
volume = get_volume_units(consumption[gasidx], NULL, &unit); volume = get_volume_units(consumption[gasidx], NULL, &unit);
get_gas_string(dive->cylinder[gasidx].gasmix.o2.permille, get_gas_string(dive->cylinder[gasidx].gasmix.o2.permille,
dive->cylinder[gasidx].gasmix.he.permille, gas, sizeof(gas)); dive->cylinder[gasidx].gasmix.he.permille, gas, sizeof(gas));
snprintf(buffer + len, sizeof(buffer) - len, translate("gettextFromC","%.0f%s of %s\n"), volume, unit, gas); snprintf(buffer + len, sizeof(buffer) - len, translate("gettextFromC", "%.0f%s of %s\n"), volume, unit, gas);
} }
dive->notes = strdup(buffer); dive->notes = strdup(buffer);
} }
@ -679,7 +678,7 @@ void plan(struct diveplan *diveplan, char **cached_datap, struct dive **divep, b
he = dive->cylinder[gaschanges[gi].gasidx].gasmix.he.permille; he = dive->cylinder[gaschanges[gi].gasidx].gasmix.he.permille;
#if DEBUG_PLAN & 16 #if DEBUG_PLAN & 16
printf("switch to gas %d (%d/%d) @ %5.2lfm\n", gaschanges[gi].gasidx, printf("switch to gas %d (%d/%d) @ %5.2lfm\n", gaschanges[gi].gasidx,
(o2 + 5) / 10, (he + 5) / 10, gaschanges[gi].depth / 1000.0); (o2 + 5) / 10, (he + 5) / 10, gaschanges[gi].depth / 1000.0);
#endif #endif
gi--; gi--;
} }
@ -691,7 +690,7 @@ void plan(struct diveplan *diveplan, char **cached_datap, struct dive **divep, b
tissue_tolerance = tissue_at_end(dive, cached_datap, error_string_p); tissue_tolerance = tissue_at_end(dive, cached_datap, error_string_p);
ceiling = deco_allowed_depth(tissue_tolerance, diveplan->surface_pressure / 1000.0, dive, 1); ceiling = deco_allowed_depth(tissue_tolerance, diveplan->surface_pressure / 1000.0, dive, 1);
printf("waittime %d:%02d at depth %5.2lfm; ceiling %5.2lfm\n", FRACTION(wait_time, 60), printf("waittime %d:%02d at depth %5.2lfm; ceiling %5.2lfm\n", FRACTION(wait_time, 60),
stoplevels[stopidx] / 1000.0, ceiling / 1000.0); stoplevels[stopidx] / 1000.0, ceiling / 1000.0);
#endif #endif
if (wait_time) if (wait_time)
plan_add_segment(diveplan, wait_time, stoplevels[stopidx], o2, he, po2); plan_add_segment(diveplan, wait_time, stoplevels[stopidx], o2, he, po2);
@ -773,14 +772,18 @@ int validate_gas(const char *text, int *o2_p, int *he_p)
if (!*text) if (!*text)
return 0; return 0;
if (!strcasecmp(text, translate("gettextFromC","air"))) { if (!strcasecmp(text, translate("gettextFromC", "air"))) {
o2 = O2_IN_AIR; he = 0; text += strlen(translate("gettextFromC","air")); o2 = O2_IN_AIR;
} else if (!strncasecmp(text, translate("gettextFromC","ean"), 3)) { he = 0;
o2 = get_permille(text+3, &text); he = 0; text += strlen(translate("gettextFromC", "air"));
} else if (!strncasecmp(text, translate("gettextFromC", "ean"), 3)) {
o2 = get_permille(text + 3, &text);
he = 0;
} else { } else {
o2 = get_permille(text, &text); he = 0; o2 = get_permille(text, &text);
he = 0;
if (*text == '/') if (*text == '/')
he = get_permille(text+1, &text); he = get_permille(text + 1, &text);
} }
/* We don't want any extra crud */ /* We don't want any extra crud */
@ -790,7 +793,7 @@ int validate_gas(const char *text, int *o2_p, int *he_p)
return 0; return 0;
/* Validate the gas mix */ /* Validate the gas mix */
if (*text || o2 < 1 || o2 > 1000 || he < 0 || o2+he > 1000) if (*text || o2 < 1 || o2 > 1000 || he < 0 || o2 + he > 1000)
return 0; return 0;
/* Let it rip */ /* Let it rip */
@ -821,4 +824,3 @@ int validate_po2(const char *text, int *mbar_po2)
*mbar_po2 = po2 * 100; *mbar_po2 = po2 * 100;
return 1; return 1;
} }

9
pref.h
View file

@ -6,7 +6,8 @@ extern "C" {
#endif #endif
/* can't use 'bool' for the boolean values - different size in C and C++ */ /* can't use 'bool' for the boolean values - different size in C and C++ */
typedef struct { typedef struct
{
short po2; short po2;
short pn2; short pn2;
short phe; short phe;
@ -40,7 +41,11 @@ struct preferences {
bool display_unused_tanks; bool display_unused_tanks;
bool zoomed_plot; bool zoomed_plot;
}; };
enum unit_system_values { METRIC, IMPERIAL, PERSONALIZE }; enum unit_system_values {
METRIC,
IMPERIAL,
PERSONALIZE
};
extern struct preferences prefs, default_prefs; extern struct preferences prefs, default_prefs;

292
profile.c
View file

@ -23,31 +23,31 @@ static struct plot_data *last_pi_entry = NULL, *last_pi_entry_new = NULL;
#ifdef DEBUG_PI #ifdef DEBUG_PI
/* debugging tool - not normally used */ /* debugging tool - not normally used */
static void dump_pi (struct plot_info *pi) static void dump_pi(struct plot_info *pi)
{ {
int i; int i;
printf("pi:{nr:%d maxtime:%d meandepth:%d maxdepth:%d \n" printf("pi:{nr:%d maxtime:%d meandepth:%d maxdepth:%d \n"
" maxpressure:%d mintemp:%d maxtemp:%d\n", " maxpressure:%d mintemp:%d maxtemp:%d\n",
pi->nr, pi->maxtime, pi->meandepth, pi->maxdepth, pi->nr, pi->maxtime, pi->meandepth, pi->maxdepth,
pi->maxpressure, pi->mintemp, pi->maxtemp); pi->maxpressure, pi->mintemp, pi->maxtemp);
for (i = 0; i < pi->nr; i++) { for (i = 0; i < pi->nr; i++) {
struct plot_data *entry = &pi->entry[i]; struct plot_data *entry = &pi->entry[i];
printf(" entry[%d]:{cylinderindex:%d sec:%d pressure:{%d,%d}\n" printf(" entry[%d]:{cylinderindex:%d sec:%d pressure:{%d,%d}\n"
" time:%d:%02d temperature:%d depth:%d stopdepth:%d stoptime:%d ndl:%d smoothed:%d po2:%lf phe:%lf pn2:%lf sum-pp %lf}\n", " time:%d:%02d temperature:%d depth:%d stopdepth:%d stoptime:%d ndl:%d smoothed:%d po2:%lf phe:%lf pn2:%lf sum-pp %lf}\n",
i, entry->cylinderindex, entry->sec, i, entry->cylinderindex, entry->sec,
entry->pressure[0], entry->pressure[1], entry->pressure[0], entry->pressure[1],
entry->sec / 60, entry->sec % 60, entry->sec / 60, entry->sec % 60,
entry->temperature, entry->depth, entry->stopdepth, entry->stoptime, entry->ndl, entry->smoothed, entry->temperature, entry->depth, entry->stopdepth, entry->stoptime, entry->ndl, entry->smoothed,
entry->po2, entry->phe, entry->pn2, entry->po2, entry->phe, entry->pn2,
entry->po2 + entry->phe + entry->pn2); entry->po2 + entry->phe + entry->pn2);
} }
printf(" }\n"); printf(" }\n");
} }
#endif #endif
#define ROUND_UP(x,y) ((((x)+(y)-1)/(y))*(y)) #define ROUND_UP(x, y) ((((x) + (y) - 1) / (y)) * (y))
#define DIV_UP(x,y) (((x)+(y)-1)/(y)) #define DIV_UP(x, y) (((x) + (y) - 1) / (y))
/* /*
* When showing dive profiles, we scale things to the * When showing dive profiles, we scale things to the
@ -68,12 +68,12 @@ int get_maxtime(struct plot_info *pi)
* This is seamless since 600/4 = 150. * This is seamless since 600/4 = 150.
*/ */
if (seconds < 600) if (seconds < 600)
return ROUND_UP(seconds+seconds/4, 60); return ROUND_UP(seconds + seconds / 4, 60);
else else
return ROUND_UP(seconds+150, 60); return ROUND_UP(seconds + 150, 60);
} else { } else {
/* min 30 minutes, rounded up to 5 minutes, with at least 2.5 minutes to spare */ /* min 30 minutes, rounded up to 5 minutes, with at least 2.5 minutes to spare */
return MAX(30*60, ROUND_UP(seconds+150, 60*5)); return MAX(30 * 60, ROUND_UP(seconds + 150, 60 * 5));
} }
} }
@ -87,10 +87,10 @@ int get_maxdepth(struct plot_info *pi)
if (prefs.zoomed_plot) { if (prefs.zoomed_plot) {
/* Rounded up to 10m, with at least 3m to spare */ /* Rounded up to 10m, with at least 3m to spare */
md = ROUND_UP(mm+3000, 10000); md = ROUND_UP(mm + 3000, 10000);
} else { } else {
/* Minimum 30m, rounded up to 10m, with at least 3m to spare */ /* Minimum 30m, rounded up to 10m, with at least 3m to spare */
md = MAX((unsigned)30000, ROUND_UP(mm+3000, 10000)); md = MAX((unsigned)30000, ROUND_UP(mm + 3000, 10000));
} }
md += pi->maxpp * 9000; md += pi->maxpp * 9000;
return md; return md;
@ -102,13 +102,12 @@ int evn_allocated;
int evn_used; int evn_used;
#if WE_DONT_USE_THIS /* we need to implement event filters in Qt */ #if WE_DONT_USE_THIS /* we need to implement event filters in Qt */
int evn_foreach(void (*callback)(const char *, bool *, void *), void *data) int evn_foreach(void (*callback)(const char *, bool *, void *), void *data) {
{
int i; int i;
for (i = 0; i < evn_used; i++) { for (i = 0; i < evn_used; i++) {
/* here we display an event name on screen - so translate */ /* here we display an event name on screen - so translate */
callback(translate("gettextFromC",ev_namelist[i].ev_name), &ev_namelist[i].plot_ev, data); callback(translate("gettextFromC", ev_namelist[i].ev_name), &ev_namelist[i].plot_ev, data);
} }
return i; return i;
} }
@ -133,7 +132,7 @@ void remember_event(const char *eventname)
if (evn_used == evn_allocated) { if (evn_used == evn_allocated) {
evn_allocated += 10; evn_allocated += 10;
ev_namelist = realloc(ev_namelist, evn_allocated * sizeof(struct ev_select)); ev_namelist = realloc(ev_namelist, evn_allocated * sizeof(struct ev_select));
if (! ev_namelist) if (!ev_namelist)
/* we are screwed, but let's just bail out */ /* we are screwed, but let's just bail out */
return; return;
} }
@ -152,13 +151,14 @@ int setup_temperature_limits(struct graphics_context *gc)
mintemp = pi->mintemp; mintemp = pi->mintemp;
maxtemp = pi->maxtemp; maxtemp = pi->maxtemp;
gc->leftx = 0; gc->rightx = maxtime; gc->leftx = 0;
gc->rightx = maxtime;
/* Show temperatures in roughly the lower third, but make sure the scale /* Show temperatures in roughly the lower third, but make sure the scale
is at least somewhat reasonable */ is at least somewhat reasonable */
delta = maxtemp - mintemp; delta = maxtemp - mintemp;
if (delta < 3000) /* less than 3K in fluctuation */ if (delta < 3000) /* less than 3K in fluctuation */
delta = 3000; delta = 3000;
gc->topy = maxtemp + delta*2; gc->topy = maxtemp + delta * 2;
if (PP_GRAPHS_ENABLED) if (PP_GRAPHS_ENABLED)
gc->bottomy = mintemp - delta * 2; gc->bottomy = mintemp - delta * 2;
@ -198,7 +198,7 @@ int get_cylinder_pressure_range(struct graphics_context *gc)
return false; return false;
while (gc->pi.endtempcoord <= SCALEY(gc, gc->pi.minpressure - (gc->topy) * 0.1)) while (gc->pi.endtempcoord <= SCALEY(gc, gc->pi.minpressure - (gc->topy) * 0.1))
gc->bottomy -= gc->topy * 0.1 * gc->maxy/abs(gc->maxy); gc->bottomy -= gc->topy * 0.1 * gc->maxy / abs(gc->maxy);
return true; return true;
} }
@ -239,7 +239,7 @@ static void analyze_plot_info_minmax_minute(struct plot_data *entry, struct plot
{ {
struct plot_data *p = entry; struct plot_data *p = entry;
int time = entry->sec; int time = entry->sec;
int seconds = 90*(index+1); int seconds = 90 * (index + 1);
struct plot_data *min, *max; struct plot_data *min, *max;
int avg, nr; int avg, nr;
@ -259,7 +259,7 @@ static void analyze_plot_info_minmax_minute(struct plot_data *entry, struct plot
if (p->sec > time + seconds) if (p->sec > time + seconds)
break; break;
avg += depth; avg += depth;
nr ++; nr++;
if (depth < min->depth) if (depth < min->depth)
min = p; min = p;
if (depth > max->depth) if (depth > max->depth)
@ -267,7 +267,7 @@ static void analyze_plot_info_minmax_minute(struct plot_data *entry, struct plot
} }
entry->min[index] = min; entry->min[index] = min;
entry->max[index] = max; entry->max[index] = max;
entry->avg[index] = (avg + nr/2) / nr; entry->avg[index] = (avg + nr / 2) / nr;
} }
static void analyze_plot_info_minmax(struct plot_data *entry, struct plot_data *first, struct plot_data *last) static void analyze_plot_info_minmax(struct plot_data *entry, struct plot_data *first, struct plot_data *last)
@ -312,12 +312,12 @@ struct plot_info *analyze_plot_info(struct plot_info *pi)
/* Smoothing function: 5-point triangular smooth */ /* Smoothing function: 5-point triangular smooth */
for (i = 2; i < nr; i++) { for (i = 2; i < nr; i++) {
struct plot_data *entry = pi->entry+i; struct plot_data *entry = pi->entry + i;
int depth; int depth;
if (i < nr-2) { if (i < nr - 2) {
depth = entry[-2].depth + 2*entry[-1].depth + 3*entry[0].depth + 2*entry[1].depth + entry[2].depth; depth = entry[-2].depth + 2 * entry[-1].depth + 3 * entry[0].depth + 2 * entry[1].depth + entry[2].depth;
entry->smoothed = (depth+4) / 9; entry->smoothed = (depth + 4) / 9;
} }
/* vertical velocity in mm/sec */ /* vertical velocity in mm/sec */
/* Linus wants to smooth this - let's at least look at the samples that aren't FAST or CRAZY */ /* Linus wants to smooth this - let's at least look at the samples that aren't FAST or CRAZY */
@ -327,10 +327,10 @@ struct plot_info *analyze_plot_info(struct plot_info *pi)
/* if our samples are short and we aren't too FAST*/ /* if our samples are short and we aren't too FAST*/
if (entry[0].sec - entry[-1].sec < 15 && entry->velocity < FAST) { if (entry[0].sec - entry[-1].sec < 15 && entry->velocity < FAST) {
int past = -2; int past = -2;
while (i+past > 0 && entry[0].sec - entry[past].sec < 15) while (i + past > 0 && entry[0].sec - entry[past].sec < 15)
past--; past--;
entry->velocity = velocity((entry[0].depth - entry[past].depth) / entry->velocity = velocity((entry[0].depth - entry[past].depth) /
(entry[0].sec - entry[past].sec)); (entry[0].sec - entry[past].sec));
} }
} else { } else {
entry->velocity = STABLE; entry->velocity = STABLE;
@ -340,8 +340,8 @@ struct plot_info *analyze_plot_info(struct plot_info *pi)
/* One-, two- and three-minute minmax data */ /* One-, two- and three-minute minmax data */
for (i = 0; i < nr; i++) { for (i = 0; i < nr; i++) {
struct plot_data *entry = pi->entry +i; struct plot_data *entry = pi->entry + i;
analyze_plot_info_minmax(entry, pi->entry, pi->entry+nr); analyze_plot_info_minmax(entry, pi->entry, pi->entry + nr);
} }
return pi; return pi;
@ -361,7 +361,8 @@ struct pr_track_struct {
pr_track_t *next; pr_track_t *next;
}; };
static pr_track_t *pr_track_alloc(int start, int t_start) { static pr_track_t *pr_track_alloc(int start, int t_start)
{
pr_track_t *pt = malloc(sizeof(pr_track_t)); pr_track_t *pt = malloc(sizeof(pr_track_t));
pt->start = start; pt->start = start;
pt->end = 0; pt->end = 0;
@ -410,7 +411,7 @@ static void dump_pr_track(pr_track_t **track_pr)
list = track_pr[cyl]; list = track_pr[cyl];
while (list) { while (list) {
printf("cyl%d: start %d end %d t_start %d t_end %d pt %d\n", cyl, printf("cyl%d: start %d end %d t_start %d t_end %d pt %d\n", cyl,
list->start, list->end, list->t_start, list->t_end, list->pressure_time); list->start, list->end, list->t_start, list->t_end, list->pressure_time);
list = list->next; list = list->next;
} }
} }
@ -487,7 +488,7 @@ static void fill_missing_segment_pressures(pr_track_t *list)
pt += list->pressure_time; pt += list->pressure_time;
pressure = start; pressure = start;
if (pt_sum) if (pt_sum)
pressure -= (start-end)*(double)pt/pt_sum; pressure -= (start - end) * (double)pt / pt_sum;
list->end = pressure; list->end = pressure;
if (list == tmp) if (list == tmp)
break; break;
@ -514,7 +515,7 @@ static void fill_missing_segment_pressures(pr_track_t *list)
static inline int pressure_time(struct dive *dive, struct divecomputer *dc, struct plot_data *a, struct plot_data *b) static inline int pressure_time(struct dive *dive, struct divecomputer *dc, struct plot_data *a, struct plot_data *b)
{ {
int time = b->sec - a->sec; int time = b->sec - a->sec;
int depth = (a->depth + b->depth)/2; int depth = (a->depth + b->depth) / 2;
if (depth <= SURFACE_THRESHOLD) if (depth <= SURFACE_THRESHOLD)
return 0; return 0;
@ -623,7 +624,7 @@ static void fill_missing_tank_pressures(struct dive *dive, struct plot_info *pi,
/* if this segment has pressure time, calculate a new interpolated pressure */ /* if this segment has pressure time, calculate a new interpolated pressure */
if (interpolate.pressure_time) { if (interpolate.pressure_time) {
/* Overall pressure change over total pressure-time for this segment*/ /* Overall pressure change over total pressure-time for this segment*/
magic = (interpolate.end - interpolate.start) / (double) interpolate.pressure_time; magic = (interpolate.end - interpolate.start) / (double)interpolate.pressure_time;
/* Use that overall pressure change to update the current pressure */ /* Use that overall pressure change to update the current pressure */
cur_pr[cyl] = rint(interpolate.start + magic * interpolate.acc_pressure_time); cur_pr[cyl] = rint(interpolate.start + magic * interpolate.acc_pressure_time);
@ -650,7 +651,7 @@ int get_cylinder_index(struct dive *dive, struct event *ev)
* mix. * mix.
*/ */
for (i = 0; i < MAX_CYLINDERS; i++) { for (i = 0; i < MAX_CYLINDERS; i++) {
cylinder_t *cyl = dive->cylinder+i; cylinder_t *cyl = dive->cylinder + i;
int delta_o2, delta_he, distance; int delta_o2, delta_he, distance;
if (cylinder_nodata(cyl)) if (cylinder_nodata(cyl))
@ -700,7 +701,7 @@ static int count_events(struct divecomputer *dc)
static int set_cylinder_index(struct plot_info *pi, int i, int cylinderindex, unsigned int end) static int set_cylinder_index(struct plot_info *pi, int i, int cylinderindex, unsigned int end)
{ {
while (i < pi->nr) { while (i < pi->nr) {
struct plot_data *entry = pi->entry+i; struct plot_data *entry = pi->entry + i;
if (entry->sec > end) if (entry->sec > end)
break; break;
if (entry->cylinderindex != cylinderindex) { if (entry->cylinderindex != cylinderindex) {
@ -869,12 +870,12 @@ void calculate_max_limits(struct dive *dive, struct divecomputer *dc, struct gra
/* copy the previous entry (we know this exists), update time and depth /* copy the previous entry (we know this exists), update time and depth
* and zero out the sensor pressure (since this is a synthetic entry) * and zero out the sensor pressure (since this is a synthetic entry)
* increment the entry pointer and the count of synthetic entries. */ * increment the entry pointer and the count of synthetic entries. */
#define INSERT_ENTRY(_time,_depth) \ #define INSERT_ENTRY(_time, _depth) \
*entry = entry[-1]; \ *entry = entry[-1]; \
entry->sec = _time; \ entry->sec = _time; \
entry->depth = _depth; \ entry->depth = _depth; \
SENSOR_PRESSURE(entry) = 0; \ SENSOR_PRESSURE(entry) = 0; \
entry++; \ entry++; \
idx++ idx++
struct plot_data *populate_plot_entries(struct dive *dive, struct divecomputer *dc, struct plot_info *pi) struct plot_data *populate_plot_entries(struct dive *dive, struct divecomputer *dc, struct plot_info *pi)
@ -908,7 +909,7 @@ struct plot_data *populate_plot_entries(struct dive *dive, struct divecomputer *
ev = ev->next; ev = ev->next;
for (i = 0; i < dc->samples; i++) { for (i = 0; i < dc->samples; i++) {
struct plot_data *entry = plot_data + idx; struct plot_data *entry = plot_data + idx;
struct sample *sample = dc->sample+i; struct sample *sample = dc->sample + i;
int time = sample->time.seconds; int time = sample->time.seconds;
int depth = sample->depth.mm; int depth = sample->depth.mm;
int offset, delta; int offset, delta;
@ -975,8 +976,8 @@ struct plot_data *populate_plot_entries(struct dive *dive, struct divecomputer *
} }
/* Add two final surface events */ /* Add two final surface events */
plot_data[idx++].sec = lasttime+1; plot_data[idx++].sec = lasttime + 1;
plot_data[idx++].sec = lasttime+2; plot_data[idx++].sec = lasttime + 2;
pi->nr = idx; pi->nr = idx;
return plot_data; return plot_data;
@ -990,7 +991,7 @@ static void populate_cylinder_pressure_data(int idx, int start, int end, struct
/* First: check that none of the entries has sensor pressure for this cylinder index */ /* First: check that none of the entries has sensor pressure for this cylinder index */
for (i = 0; i < pi->nr; i++) { for (i = 0; i < pi->nr; i++) {
struct plot_data *entry = pi->entry+i; struct plot_data *entry = pi->entry + i;
if (entry->cylinderindex != idx) if (entry->cylinderindex != idx)
continue; continue;
if (SENSOR_PRESSURE(entry)) if (SENSOR_PRESSURE(entry))
@ -999,7 +1000,7 @@ static void populate_cylinder_pressure_data(int idx, int start, int end, struct
/* Then: populate the first entry with the beginning cylinder pressure */ /* Then: populate the first entry with the beginning cylinder pressure */
for (i = 0; i < pi->nr; i++) { for (i = 0; i < pi->nr; i++) {
struct plot_data *entry = pi->entry+i; struct plot_data *entry = pi->entry + i;
if (entry->cylinderindex != idx) if (entry->cylinderindex != idx)
continue; continue;
SENSOR_PRESSURE(entry) = start; SENSOR_PRESSURE(entry) = start;
@ -1008,7 +1009,7 @@ static void populate_cylinder_pressure_data(int idx, int start, int end, struct
/* .. and the last entry with the ending cylinder pressure */ /* .. and the last entry with the ending cylinder pressure */
for (i = pi->nr; --i >= 0; /* nothing */) { for (i = pi->nr; --i >= 0; /* nothing */) {
struct plot_data *entry = pi->entry+i; struct plot_data *entry = pi->entry + i;
if (entry->cylinderindex != idx) if (entry->cylinderindex != idx)
continue; continue;
SENSOR_PRESSURE(entry) = end; SENSOR_PRESSURE(entry) = end;
@ -1022,7 +1023,7 @@ static void calculate_sac(struct dive *dive, struct plot_info *pi)
struct plot_data *last_entry = NULL; struct plot_data *last_entry = NULL;
for (i = 0; i < pi->nr; i++) { for (i = 0; i < pi->nr; i++) {
struct plot_data *entry = pi->entry+i; struct plot_data *entry = pi->entry + i;
if (!last_entry || last_entry->cylinderindex != entry->cylinderindex) { if (!last_entry || last_entry->cylinderindex != entry->cylinderindex) {
last = i; last = i;
last_entry = entry; last_entry = entry;
@ -1053,9 +1054,9 @@ static void setup_gas_sensor_pressure(struct dive *dive, struct divecomputer *dc
/* First, populate the pressures with the manual cylinder data.. */ /* First, populate the pressures with the manual cylinder data.. */
for (i = 0; i < MAX_CYLINDERS; i++) { for (i = 0; i < MAX_CYLINDERS; i++) {
cylinder_t *cyl = dive->cylinder+i; cylinder_t *cyl = dive->cylinder + i;
int start = cyl->start.mbar ? : cyl->sample_start.mbar; int start = cyl->start.mbar ?: cyl->sample_start.mbar;
int end = cyl->end.mbar ? : cyl->sample_end.mbar; int end = cyl->end.mbar ?: cyl->sample_end.mbar;
if (!start || !end) if (!start || !end)
continue; continue;
@ -1079,7 +1080,7 @@ static void setup_gas_sensor_pressure(struct dive *dive, struct divecomputer *dc
static void populate_pressure_information(struct dive *dive, struct divecomputer *dc, struct plot_info *pi) static void populate_pressure_information(struct dive *dive, struct divecomputer *dc, struct plot_info *pi)
{ {
int i, cylinderindex; int i, cylinderindex;
pr_track_t *track_pr[MAX_CYLINDERS] = {NULL, }; pr_track_t *track_pr[MAX_CYLINDERS] = { NULL, };
pr_track_t *current; pr_track_t *current;
bool missing_pr = false; bool missing_pr = false;
@ -1091,7 +1092,7 @@ static void populate_pressure_information(struct dive *dive, struct divecomputer
/* discrete integration of pressure over time to get the SAC rate equivalent */ /* discrete integration of pressure over time to get the SAC rate equivalent */
if (current) { if (current) {
entry->pressure_time = pressure_time(dive, dc, entry-1, entry); entry->pressure_time = pressure_time(dive, dc, entry - 1, entry);
current->pressure_time += entry->pressure_time; current->pressure_time += entry->pressure_time;
current->t_end = entry->sec; current->t_end = entry->sec;
} }
@ -1112,7 +1113,7 @@ static void populate_pressure_information(struct dive *dive, struct divecomputer
current->end = pressure; current->end = pressure;
/* Was it continuous? */ /* Was it continuous? */
if (SENSOR_PRESSURE(entry-1)) if (SENSOR_PRESSURE(entry - 1))
continue; continue;
/* transmitter changed its working status */ /* transmitter changed its working status */
@ -1128,7 +1129,8 @@ static void populate_pressure_information(struct dive *dive, struct divecomputer
} }
/* calculate DECO STOP / TTS / NDL */ /* calculate DECO STOP / TTS / NDL */
static void calculate_ndl_tts(double tissue_tolerance, struct plot_data *entry, struct dive *dive, double surface_pressure) { static void calculate_ndl_tts(double tissue_tolerance, struct plot_data *entry, struct dive *dive, double surface_pressure)
{
/* FIXME: This should be configurable */ /* FIXME: This should be configurable */
/* ascent speed up to first deco stop */ /* ascent speed up to first deco stop */
const int ascent_s_per_step = 1; const int ascent_s_per_step = 1;
@ -1157,7 +1159,7 @@ static void calculate_ndl_tts(double tissue_tolerance, struct plot_data *entry,
while (entry->ndl_calc < max_ndl && deco_allowed_depth(tissue_tolerance, surface_pressure, dive, 1) <= 0) { while (entry->ndl_calc < max_ndl && deco_allowed_depth(tissue_tolerance, surface_pressure, dive, 1) <= 0) {
entry->ndl_calc += time_stepsize; entry->ndl_calc += time_stepsize;
tissue_tolerance = add_segment(depth_to_mbar(entry->depth, dive) / 1000.0, tissue_tolerance = add_segment(depth_to_mbar(entry->depth, dive) / 1000.0,
&dive->cylinder[cylinderindex].gasmix, time_stepsize, entry->po2 * 1000, dive); &dive->cylinder[cylinderindex].gasmix, time_stepsize, entry->po2 * 1000, dive);
} }
/* we don't need to calculate anything else */ /* we don't need to calculate anything else */
return; return;
@ -1169,7 +1171,7 @@ static void calculate_ndl_tts(double tissue_tolerance, struct plot_data *entry,
/* Add segments for movement to stopdepth */ /* Add segments for movement to stopdepth */
for (; ascent_depth > next_stop; ascent_depth -= ascent_mm_per_step, entry->tts_calc += ascent_s_per_step) { for (; ascent_depth > next_stop; ascent_depth -= ascent_mm_per_step, entry->tts_calc += ascent_s_per_step) {
tissue_tolerance = add_segment(depth_to_mbar(ascent_depth, dive) / 1000.0, tissue_tolerance = add_segment(depth_to_mbar(ascent_depth, dive) / 1000.0,
&dive->cylinder[cylinderindex].gasmix, ascent_s_per_step, entry->po2 * 1000, dive); &dive->cylinder[cylinderindex].gasmix, ascent_s_per_step, entry->po2 * 1000, dive);
next_stop = ROUND_UP(deco_allowed_depth(tissue_tolerance, surface_pressure, dive, 1), deco_stepsize); next_stop = ROUND_UP(deco_allowed_depth(tissue_tolerance, surface_pressure, dive, 1), deco_stepsize);
} }
ascent_depth = next_stop; ascent_depth = next_stop;
@ -1180,20 +1182,20 @@ static void calculate_ndl_tts(double tissue_tolerance, struct plot_data *entry,
next_stop -= deco_stepsize; next_stop -= deco_stepsize;
/* And how long is the total TTS */ /* And how long is the total TTS */
while(next_stop >= 0) { while (next_stop >= 0) {
/* save the time for the first stop to show in the graph */ /* save the time for the first stop to show in the graph */
if (ascent_depth == entry->stopdepth_calc) if (ascent_depth == entry->stopdepth_calc)
entry->stoptime_calc += time_stepsize; entry->stoptime_calc += time_stepsize;
entry->tts_calc += time_stepsize; entry->tts_calc += time_stepsize;
tissue_tolerance = add_segment(depth_to_mbar(ascent_depth, dive) / 1000.0, tissue_tolerance = add_segment(depth_to_mbar(ascent_depth, dive) / 1000.0,
&dive->cylinder[cylinderindex].gasmix, time_stepsize, entry->po2 * 1000, dive); &dive->cylinder[cylinderindex].gasmix, time_stepsize, entry->po2 * 1000, dive);
if (deco_allowed_depth(tissue_tolerance, surface_pressure, dive, 1) <= next_stop) { if (deco_allowed_depth(tissue_tolerance, surface_pressure, dive, 1) <= next_stop) {
/* move to the next stop and add the travel between stops */ /* move to the next stop and add the travel between stops */
for (; ascent_depth > next_stop ; ascent_depth -= ascent_mm_per_deco_step, entry->tts_calc += ascent_s_per_deco_step) for (; ascent_depth > next_stop; ascent_depth -= ascent_mm_per_deco_step, entry->tts_calc += ascent_s_per_deco_step)
tissue_tolerance = add_segment(depth_to_mbar(ascent_depth, dive) / 1000.0, tissue_tolerance = add_segment(depth_to_mbar(ascent_depth, dive) / 1000.0,
&dive->cylinder[cylinderindex].gasmix, ascent_s_per_deco_step, entry->po2 * 1000, dive); &dive->cylinder[cylinderindex].gasmix, ascent_s_per_deco_step, entry->po2 * 1000, dive);
ascent_depth = next_stop; ascent_depth = next_stop;
next_stop -= deco_stepsize; next_stop -= deco_stepsize;
} }
@ -1211,17 +1213,17 @@ void calculate_deco_information(struct dive *dive, struct divecomputer *dc, stru
for (i = 1; i < pi->nr; i++) { for (i = 1; i < pi->nr; i++) {
struct plot_data *entry = pi->entry + i; struct plot_data *entry = pi->entry + i;
int j, t0 = (entry - 1)->sec, t1 = entry->sec; int j, t0 = (entry - 1)->sec, t1 = entry->sec;
for (j = t0+1; j <= t1; j++) { for (j = t0 + 1; j <= t1; j++) {
int depth = interpolate(entry[-1].depth, entry[0].depth, j - t0, t1 - t0); int depth = interpolate(entry[-1].depth, entry[0].depth, j - t0, t1 - t0);
double min_pressure = add_segment(depth_to_mbar(depth, dive) / 1000.0, double min_pressure = add_segment(depth_to_mbar(depth, dive) / 1000.0,
&dive->cylinder[entry->cylinderindex].gasmix, 1, entry->po2 * 1000, dive); &dive->cylinder[entry->cylinderindex].gasmix, 1, entry->po2 * 1000, dive);
tissue_tolerance = min_pressure; tissue_tolerance = min_pressure;
} }
if (t0 == t1) if (t0 == t1)
entry->ceiling = (entry - 1)->ceiling; entry->ceiling = (entry - 1)->ceiling;
else else
entry->ceiling = deco_allowed_depth(tissue_tolerance, surface_pressure, dive, !prefs.calc_ceiling_3m_incr); entry->ceiling = deco_allowed_depth(tissue_tolerance, surface_pressure, dive, !prefs.calc_ceiling_3m_incr);
for (j=0; j<16; j++) for (j = 0; j < 16; j++)
entry->ceilings[j] = deco_allowed_depth(tolerated_by_tissue[j], surface_pressure, dive, 1); entry->ceilings[j] = deco_allowed_depth(tolerated_by_tissue[j], surface_pressure, dive, 1);
/* should we do more calculations? /* should we do more calculations?
@ -1241,7 +1243,7 @@ void calculate_deco_information(struct dive *dive, struct divecomputer *dc, stru
#endif #endif
} }
static void calculate_gas_information(struct dive *dive, struct plot_info *pi) static void calculate_gas_information(struct dive *dive, struct plot_info *pi)
{ {
int i; int i;
double amb_pressure; double amb_pressure;
@ -1276,13 +1278,17 @@ static void calculate_gas_information(struct dive *dive, struct plot_info *pi)
* END just uses N2 */ * END just uses N2 */
entry->mod = (prefs.mod_ppO2 / fo2 * 1000 - 1) * 10000; entry->mod = (prefs.mod_ppO2 / fo2 * 1000 - 1) * 10000;
entry->ead = (entry->depth + 10000) * entry->ead = (entry->depth + 10000) *
(entry->po2 + (amb_pressure - entry->po2) * (1 - ratio)) / amb_pressure - 10000; (entry->po2 + (amb_pressure - entry->po2) * (1 - ratio)) / amb_pressure -
10000;
entry->end = (entry->depth + 10000) * entry->end = (entry->depth + 10000) *
(amb_pressure - entry->po2) * (1 - ratio) / amb_pressure / N2_IN_AIR * 1000 - 10000; (amb_pressure - entry->po2) * (1 - ratio) / amb_pressure / N2_IN_AIR * 1000 -
10000;
entry->eadd = (entry->depth + 10000) * entry->eadd = (entry->depth + 10000) *
(entry->po2 / amb_pressure * O2_DENSITY + entry->pn2 / amb_pressure * (entry->po2 / amb_pressure * O2_DENSITY + entry->pn2 / amb_pressure *
N2_DENSITY + entry->phe / amb_pressure * HE_DENSITY) / N2_DENSITY +
(O2_IN_AIR * O2_DENSITY + N2_IN_AIR * N2_DENSITY) * 1000 -10000; entry->phe / amb_pressure * HE_DENSITY) /
(O2_IN_AIR * O2_DENSITY + N2_IN_AIR * N2_DENSITY) * 1000 -
10000;
if (entry->mod < 0) if (entry->mod < 0)
entry->mod = 0; entry->mod = 0;
if (entry->ead < 0) if (entry->ead < 0)
@ -1302,7 +1308,7 @@ static void calculate_gas_information(struct dive *dive, struct plot_info *pi)
} }
static void calculate_gas_information_new(struct dive *dive, struct plot_info *pi) static void calculate_gas_information_new(struct dive *dive, struct plot_info *pi)
{ {
int i; int i;
double amb_pressure; double amb_pressure;
@ -1337,13 +1343,17 @@ static void calculate_gas_information_new(struct dive *dive, struct plot_info *
* END just uses N2 */ * END just uses N2 */
entry->mod = (prefs.mod_ppO2 / fo2 * 1000 - 1) * 10000; entry->mod = (prefs.mod_ppO2 / fo2 * 1000 - 1) * 10000;
entry->ead = (entry->depth + 10000) * entry->ead = (entry->depth + 10000) *
(entry->po2 + (amb_pressure - entry->po2) * (1 - ratio)) / amb_pressure - 10000; (entry->po2 + (amb_pressure - entry->po2) * (1 - ratio)) / amb_pressure -
10000;
entry->end = (entry->depth + 10000) * entry->end = (entry->depth + 10000) *
(amb_pressure - entry->po2) * (1 - ratio) / amb_pressure / N2_IN_AIR * 1000 - 10000; (amb_pressure - entry->po2) * (1 - ratio) / amb_pressure / N2_IN_AIR * 1000 -
10000;
entry->eadd = (entry->depth + 10000) * entry->eadd = (entry->depth + 10000) *
(entry->po2 / amb_pressure * O2_DENSITY + entry->pn2 / amb_pressure * (entry->po2 / amb_pressure * O2_DENSITY + entry->pn2 / amb_pressure *
N2_DENSITY + entry->phe / amb_pressure * HE_DENSITY) / N2_DENSITY +
(O2_IN_AIR * O2_DENSITY + N2_IN_AIR * N2_DENSITY) * 1000 -10000; entry->phe / amb_pressure * HE_DENSITY) /
(O2_IN_AIR * O2_DENSITY + N2_IN_AIR * N2_DENSITY) * 1000 -
10000;
if (entry->mod < 0) if (entry->mod < 0)
entry->mod = 0; entry->mod = 0;
if (entry->ead < 0) if (entry->ead < 0)
@ -1408,15 +1418,15 @@ struct plot_info *create_plot_info(struct dive *dive, struct divecomputer *dc, s
void create_plot_info_new(struct dive *dive, struct divecomputer *dc, struct plot_info *pi) void create_plot_info_new(struct dive *dive, struct divecomputer *dc, struct plot_info *pi)
{ {
init_decompression(dive); init_decompression(dive);
if (last_pi_entry_new) /* Create the new plot data */ if (last_pi_entry_new) /* Create the new plot data */
free((void *)last_pi_entry_new); free((void *)last_pi_entry_new);
last_pi_entry_new = populate_plot_entries(dive, dc, pi); last_pi_entry_new = populate_plot_entries(dive, dc, pi);
check_gas_change_events(dive, dc, pi); /* Populate the gas index from the gas change events */ check_gas_change_events(dive, dc, pi); /* Populate the gas index from the gas change events */
setup_gas_sensor_pressure(dive, dc, pi); /* Try to populate our gas pressure knowledge */ setup_gas_sensor_pressure(dive, dc, pi); /* Try to populate our gas pressure knowledge */
populate_pressure_information(dive, dc, pi);/* .. calculate missing pressure entries */ populate_pressure_information(dive, dc, pi); /* .. calculate missing pressure entries */
calculate_sac(dive, pi); /* Calculate sac */ calculate_sac(dive, pi); /* Calculate sac */
calculate_deco_information(dive, dc, pi, false); calculate_deco_information(dive, dc, pi, false);
calculate_gas_information_new(dive, pi); /* And finaly calculate gas partial pressures */ calculate_gas_information_new(dive, pi); /* And finaly calculate gas partial pressures */
pi->meandepth = dive->dc.meandepth.mm; pi->meandepth = dive->dc.meandepth.mm;
analyze_plot_info(pi); analyze_plot_info(pi);
} }
@ -1456,98 +1466,98 @@ static void plot_string(struct plot_data *entry, struct membuffer *b, bool has_n
double depthvalue, tempvalue, speedvalue; double depthvalue, tempvalue, speedvalue;
depthvalue = get_depth_units(entry->depth, NULL, &depth_unit); depthvalue = get_depth_units(entry->depth, NULL, &depth_unit);
put_format(b, translate("gettextFromC","@: %d:%02d\nD: %.1f%s\n"), FRACTION(entry->sec, 60), depthvalue, depth_unit); put_format(b, translate("gettextFromC", "@: %d:%02d\nD: %.1f%s\n"), FRACTION(entry->sec, 60), depthvalue, depth_unit);
if (GET_PRESSURE(entry)) { if (GET_PRESSURE(entry)) {
pressurevalue = get_pressure_units(GET_PRESSURE(entry), &pressure_unit); pressurevalue = get_pressure_units(GET_PRESSURE(entry), &pressure_unit);
put_format(b, translate("gettextFromC","P: %d%s\n"), pressurevalue, pressure_unit); put_format(b, translate("gettextFromC", "P: %d%s\n"), pressurevalue, pressure_unit);
} }
if (entry->temperature) { if (entry->temperature) {
tempvalue = get_temp_units(entry->temperature, &temp_unit); tempvalue = get_temp_units(entry->temperature, &temp_unit);
put_format(b, translate("gettextFromC","T: %.1f%s\n"), tempvalue, temp_unit); put_format(b, translate("gettextFromC", "T: %.1f%s\n"), tempvalue, temp_unit);
} }
speedvalue = get_vertical_speed_units(abs(entry->speed), NULL, &vertical_speed_unit); speedvalue = get_vertical_speed_units(abs(entry->speed), NULL, &vertical_speed_unit);
/* Ascending speeds are positive, descending are negative */ /* Ascending speeds are positive, descending are negative */
if (entry->speed > 0) if (entry->speed > 0)
speedvalue *= -1; speedvalue *= -1;
put_format(b, translate("gettextFromC","V: %.1f%s\n"), speedvalue, vertical_speed_unit); put_format(b, translate("gettextFromC", "V: %.1f%s\n"), speedvalue, vertical_speed_unit);
if (entry->sac && prefs.show_sac) if (entry->sac && prefs.show_sac)
put_format(b, translate("gettextFromC","SAC: %2.1fl/min\n"), entry->sac / 1000.0); put_format(b, translate("gettextFromC", "SAC: %2.1fl/min\n"), entry->sac / 1000.0);
if (entry->cns) if (entry->cns)
put_format(b, translate("gettextFromC","CNS: %u%%\n"), entry->cns); put_format(b, translate("gettextFromC", "CNS: %u%%\n"), entry->cns);
if (prefs.pp_graphs.po2) if (prefs.pp_graphs.po2)
put_format(b, translate("gettextFromC","pO%s: %.2fbar\n"), UTF8_SUBSCRIPT_2, entry->po2); put_format(b, translate("gettextFromC", "pO%s: %.2fbar\n"), UTF8_SUBSCRIPT_2, entry->po2);
if (prefs.pp_graphs.pn2) if (prefs.pp_graphs.pn2)
put_format(b, translate("gettextFromC","pN%s: %.2fbar\n"), UTF8_SUBSCRIPT_2, entry->pn2); put_format(b, translate("gettextFromC", "pN%s: %.2fbar\n"), UTF8_SUBSCRIPT_2, entry->pn2);
if (prefs.pp_graphs.phe) if (prefs.pp_graphs.phe)
put_format(b, translate("gettextFromC","pHe: %.2fbar\n"), entry->phe); put_format(b, translate("gettextFromC", "pHe: %.2fbar\n"), entry->phe);
if (prefs.mod) { if (prefs.mod) {
mod = (int)get_depth_units(entry->mod, NULL, &depth_unit); mod = (int)get_depth_units(entry->mod, NULL, &depth_unit);
put_format(b, translate("gettextFromC","MOD: %d%s\n"), mod, depth_unit); put_format(b, translate("gettextFromC", "MOD: %d%s\n"), mod, depth_unit);
} }
if (prefs.ead) { if (prefs.ead) {
ead = (int)get_depth_units(entry->ead, NULL, &depth_unit); ead = (int)get_depth_units(entry->ead, NULL, &depth_unit);
end = (int)get_depth_units(entry->end, NULL, &depth_unit); end = (int)get_depth_units(entry->end, NULL, &depth_unit);
eadd = (int)get_depth_units(entry->eadd, NULL, &depth_unit); eadd = (int)get_depth_units(entry->eadd, NULL, &depth_unit);
put_format(b, translate("gettextFromC","EAD: %d%s\nEND: %d%s\nEADD: %d%s\n"), ead, depth_unit, end, depth_unit, eadd, depth_unit); put_format(b, translate("gettextFromC", "EAD: %d%s\nEND: %d%s\nEADD: %d%s\n"), ead, depth_unit, end, depth_unit, eadd, depth_unit);
} }
if (entry->stopdepth) { if (entry->stopdepth) {
depthvalue = get_depth_units(entry->stopdepth, NULL, &depth_unit); depthvalue = get_depth_units(entry->stopdepth, NULL, &depth_unit);
if (entry->ndl) { if (entry->ndl) {
/* this is a safety stop as we still have ndl */ /* this is a safety stop as we still have ndl */
if (entry->stoptime) if (entry->stoptime)
put_format(b, translate("gettextFromC","Safetystop: %umin @ %.0f%s\n"), DIV_UP(entry->stoptime, 60), put_format(b, translate("gettextFromC", "Safetystop: %umin @ %.0f%s\n"), DIV_UP(entry->stoptime, 60),
depthvalue, depth_unit); depthvalue, depth_unit);
else else
put_format(b, translate("gettextFromC","Safetystop: unkn time @ %.0f%s\n"), put_format(b, translate("gettextFromC", "Safetystop: unkn time @ %.0f%s\n"),
depthvalue, depth_unit); depthvalue, depth_unit);
} else { } else {
/* actual deco stop */ /* actual deco stop */
if (entry->stoptime) if (entry->stoptime)
put_format(b, translate("gettextFromC","Deco: %umin @ %.0f%s\n"), DIV_UP(entry->stoptime, 60), put_format(b, translate("gettextFromC", "Deco: %umin @ %.0f%s\n"), DIV_UP(entry->stoptime, 60),
depthvalue, depth_unit); depthvalue, depth_unit);
else else
put_format(b, translate("gettextFromC","Deco: unkn time @ %.0f%s\n"), put_format(b, translate("gettextFromC", "Deco: unkn time @ %.0f%s\n"),
depthvalue, depth_unit); depthvalue, depth_unit);
} }
} else if (entry->in_deco) { } else if (entry->in_deco) {
put_string(b, translate("gettextFromC","In deco\n")); put_string(b, translate("gettextFromC", "In deco\n"));
} else if (has_ndl) { } else if (has_ndl) {
put_format(b, translate("gettextFromC","NDL: %umin\n"), DIV_UP(entry->ndl, 60)); put_format(b, translate("gettextFromC", "NDL: %umin\n"), DIV_UP(entry->ndl, 60));
} }
if (entry->stopdepth_calc && entry->stoptime_calc) { if (entry->stopdepth_calc && entry->stoptime_calc) {
depthvalue = get_depth_units(entry->stopdepth_calc, NULL, &depth_unit); depthvalue = get_depth_units(entry->stopdepth_calc, NULL, &depth_unit);
put_format(b, translate("gettextFromC","Deco: %umin @ %.0f%s (calc)\n"), DIV_UP(entry->stoptime_calc, 60), put_format(b, translate("gettextFromC", "Deco: %umin @ %.0f%s (calc)\n"), DIV_UP(entry->stoptime_calc, 60),
depthvalue, depth_unit); depthvalue, depth_unit);
} else if (entry->in_deco_calc) { } else if (entry->in_deco_calc) {
/* This means that we have no NDL left, /* This means that we have no NDL left,
* and we have no deco stop, * and we have no deco stop,
* so if we just accend to the surface slowly * so if we just accend to the surface slowly
* (ascent_mm_per_step / ascent_s_per_step) * (ascent_mm_per_step / ascent_s_per_step)
* everything will be ok. */ * everything will be ok. */
put_string(b, translate("gettextFromC","In deco (calc)\n")); put_string(b, translate("gettextFromC", "In deco (calc)\n"));
} else if (prefs.calc_ndl_tts && entry->ndl_calc != 0) { } else if (prefs.calc_ndl_tts && entry->ndl_calc != 0) {
put_format(b, translate("gettextFromC","NDL: %umin (calc)\n"), DIV_UP(entry->ndl_calc, 60)); put_format(b, translate("gettextFromC", "NDL: %umin (calc)\n"), DIV_UP(entry->ndl_calc, 60));
} }
if (entry->tts_calc) if (entry->tts_calc)
put_format(b, translate("gettextFromC","TTS: %umin (calc)\n"), DIV_UP(entry->tts_calc, 60)); put_format(b, translate("gettextFromC", "TTS: %umin (calc)\n"), DIV_UP(entry->tts_calc, 60));
if (entry->ceiling) { if (entry->ceiling) {
depthvalue = get_depth_units(entry->ceiling, NULL, &depth_unit); depthvalue = get_depth_units(entry->ceiling, NULL, &depth_unit);
put_format(b, translate("gettextFromC","Calculated ceiling %.0f%s\n"), depthvalue, depth_unit); put_format(b, translate("gettextFromC", "Calculated ceiling %.0f%s\n"), depthvalue, depth_unit);
if (prefs.calc_all_tissues) { if (prefs.calc_all_tissues) {
int k; int k;
for (k=0; k<16; k++) { for (k = 0; k < 16; k++) {
if (entry->ceilings[k]) { if (entry->ceilings[k]) {
depthvalue = get_depth_units(entry->ceilings[k], NULL, &depth_unit); depthvalue = get_depth_units(entry->ceilings[k], NULL, &depth_unit);
put_format(b, translate("gettextFromC","Tissue %.0fmin: %.0f%s\n"), buehlmann_N2_t_halflife[k], depthvalue, depth_unit); put_format(b, translate("gettextFromC", "Tissue %.0fmin: %.0f%s\n"), buehlmann_N2_t_halflife[k], depthvalue, depth_unit);
} }
} }
} }
} }
if (entry->heartbeat) if (entry->heartbeat)
put_format(b, translate("gettextFromC","heartbeat: %d\n"), entry->heartbeat); put_format(b, translate("gettextFromC", "heartbeat: %d\n"), entry->heartbeat);
if (entry->bearing) if (entry->bearing)
put_format(b, translate("gettextFromC","bearing: %d\n"), entry->bearing); put_format(b, translate("gettextFromC", "bearing: %d\n"), entry->bearing);
strip_mb(b); strip_mb(b);
} }
@ -1615,8 +1625,8 @@ void compare_samples(struct plot_data *e1, struct plot_data *e2, char *buf, int
max_asc_speed = 0; max_asc_speed = 0;
max_desc_speed = 0; max_desc_speed = 0;
delta_depth = abs(start->depth-stop->depth); delta_depth = abs(start->depth - stop->depth);
delta_time = abs(start->sec-stop->sec); delta_time = abs(start->sec - stop->sec);
avg_depth = 0; avg_depth = 0;
max_depth = 0; max_depth = 0;
min_depth = INT_MAX; min_depth = INT_MAX;
@ -1627,12 +1637,12 @@ void compare_samples(struct plot_data *e1, struct plot_data *e2, char *buf, int
data = start; data = start;
while (data != stop) { while (data != stop) {
data = start+count; data = start + count;
if (sum) if (sum)
avg_speed += abs(data->speed)*(data->sec-last_sec); avg_speed += abs(data->speed) * (data->sec - last_sec);
else else
avg_speed += data->speed*(data->sec-last_sec); avg_speed += data->speed * (data->sec - last_sec);
avg_depth += data->depth*(data->sec-last_sec); avg_depth += data->depth * (data->sec - last_sec);
if (data->speed > max_desc_speed) if (data->speed > max_desc_speed)
max_desc_speed = data->speed; max_desc_speed = data->speed;
@ -1644,52 +1654,52 @@ void compare_samples(struct plot_data *e1, struct plot_data *e2, char *buf, int
if (data->depth > max_depth) if (data->depth > max_depth)
max_depth = data->depth; max_depth = data->depth;
/* Try to detect gas changes */ /* Try to detect gas changes */
if (GET_PRESSURE(data) < last_pressure+2000) if (GET_PRESSURE(data) < last_pressure + 2000)
bar_used += last_pressure-GET_PRESSURE(data); bar_used += last_pressure - GET_PRESSURE(data);
count+=1; count += 1;
last_sec = data->sec; last_sec = data->sec;
last_pressure = GET_PRESSURE(data); last_pressure = GET_PRESSURE(data);
} }
avg_depth /= stop->sec-start->sec; avg_depth /= stop->sec - start->sec;
avg_speed /= stop->sec-start->sec; avg_speed /= stop->sec - start->sec;
snprintf(buf, bufsize, translate("gettextFromC","%sT: %d:%02d min"), UTF8_DELTA, delta_time/60, delta_time%60); snprintf(buf, bufsize, translate("gettextFromC", "%sT: %d:%02d min"), UTF8_DELTA, delta_time / 60, delta_time % 60);
memcpy(buf2, buf, bufsize); memcpy(buf2, buf, bufsize);
depthvalue = get_depth_units(delta_depth, NULL, &depth_unit); depthvalue = get_depth_units(delta_depth, NULL, &depth_unit);
snprintf(buf, bufsize, translate("gettextFromC","%s %sD:%.1f%s"), buf2, UTF8_DELTA, depthvalue, depth_unit); snprintf(buf, bufsize, translate("gettextFromC", "%s %sD:%.1f%s"), buf2, UTF8_DELTA, depthvalue, depth_unit);
memcpy(buf2, buf, bufsize); memcpy(buf2, buf, bufsize);
depthvalue = get_depth_units(min_depth, NULL, &depth_unit); depthvalue = get_depth_units(min_depth, NULL, &depth_unit);
snprintf(buf, bufsize, translate("gettextFromC","%s %sD:%.1f%s"), buf2, UTF8_DOWNWARDS_ARROW, depthvalue, depth_unit); snprintf(buf, bufsize, translate("gettextFromC", "%s %sD:%.1f%s"), buf2, UTF8_DOWNWARDS_ARROW, depthvalue, depth_unit);
memcpy(buf2, buf, bufsize); memcpy(buf2, buf, bufsize);
depthvalue = get_depth_units(max_depth, NULL, &depth_unit); depthvalue = get_depth_units(max_depth, NULL, &depth_unit);
snprintf(buf, bufsize, translate("gettextFromC","%s %sD:%.1f%s"), buf2, UTF8_UPWARDS_ARROW, depthvalue, depth_unit); snprintf(buf, bufsize, translate("gettextFromC", "%s %sD:%.1f%s"), buf2, UTF8_UPWARDS_ARROW, depthvalue, depth_unit);
memcpy(buf2, buf, bufsize); memcpy(buf2, buf, bufsize);
depthvalue = get_depth_units(avg_depth, NULL, &depth_unit); depthvalue = get_depth_units(avg_depth, NULL, &depth_unit);
snprintf(buf, bufsize, translate("gettextFromC","%s %sD:%.1f%s\n"), buf2, UTF8_AVERAGE, depthvalue, depth_unit); snprintf(buf, bufsize, translate("gettextFromC", "%s %sD:%.1f%s\n"), buf2, UTF8_AVERAGE, depthvalue, depth_unit);
memcpy(buf2, buf, bufsize); memcpy(buf2, buf, bufsize);
speedvalue = get_vertical_speed_units(abs(max_desc_speed), NULL, &vertical_speed_unit); speedvalue = get_vertical_speed_units(abs(max_desc_speed), NULL, &vertical_speed_unit);
snprintf(buf, bufsize, translate("gettextFromC","%s%sV:%.2f%s"), buf2, UTF8_DOWNWARDS_ARROW, speedvalue, vertical_speed_unit); snprintf(buf, bufsize, translate("gettextFromC", "%s%sV:%.2f%s"), buf2, UTF8_DOWNWARDS_ARROW, speedvalue, vertical_speed_unit);
memcpy(buf2, buf, bufsize); memcpy(buf2, buf, bufsize);
speedvalue = get_vertical_speed_units(abs(max_asc_speed), NULL, &vertical_speed_unit); speedvalue = get_vertical_speed_units(abs(max_asc_speed), NULL, &vertical_speed_unit);
snprintf(buf, bufsize, translate("gettextFromC","%s %sV:%.2f%s"), buf2, UTF8_UPWARDS_ARROW, speedvalue, vertical_speed_unit); snprintf(buf, bufsize, translate("gettextFromC", "%s %sV:%.2f%s"), buf2, UTF8_UPWARDS_ARROW, speedvalue, vertical_speed_unit);
memcpy(buf2, buf, bufsize); memcpy(buf2, buf, bufsize);
speedvalue = get_vertical_speed_units(abs(avg_speed), NULL, &vertical_speed_unit); speedvalue = get_vertical_speed_units(abs(avg_speed), NULL, &vertical_speed_unit);
snprintf(buf, bufsize, translate("gettextFromC","%s %sV:%.2f%s"), buf2, UTF8_AVERAGE, speedvalue, vertical_speed_unit); snprintf(buf, bufsize, translate("gettextFromC", "%s %sV:%.2f%s"), buf2, UTF8_AVERAGE, speedvalue, vertical_speed_unit);
memcpy(buf2, buf, bufsize); memcpy(buf2, buf, bufsize);
/* Only print if gas has been used */ /* Only print if gas has been used */
if (bar_used) { if (bar_used) {
pressurevalue = get_pressure_units(bar_used, &pressure_unit); pressurevalue = get_pressure_units(bar_used, &pressure_unit);
memcpy(buf2, buf, bufsize); memcpy(buf2, buf, bufsize);
snprintf(buf, bufsize, translate("gettextFromC","%s %sP:%d %s"), buf2, UTF8_DELTA, pressurevalue, pressure_unit); snprintf(buf, bufsize, translate("gettextFromC", "%s %sP:%d %s"), buf2, UTF8_DELTA, pressurevalue, pressure_unit);
} }
free(buf2); free(buf2);

View file

@ -5,14 +5,20 @@
extern "C" { extern "C" {
#endif #endif
typedef enum { STABLE, SLOW, MODERATE, FAST, CRAZY } velocity_t; typedef enum {
STABLE,
SLOW,
MODERATE,
FAST,
CRAZY
} velocity_t;
struct membuffer; struct membuffer;
struct divecomputer; struct divecomputer;
struct graphics_context; struct graphics_context;
struct plot_info; struct plot_info;
struct plot_data { struct plot_data {
unsigned int in_deco:1; unsigned int in_deco : 1;
int cylinderindex; int cylinderindex;
int sec; int sec;
/* pressure[0] is sensor pressure /* pressure[0] is sensor pressure
@ -37,7 +43,7 @@ struct plot_data {
struct plot_data *max[3]; struct plot_data *max[3];
int avg[3]; int avg[3];
/* values calculated by us */ /* values calculated by us */
unsigned int in_deco_calc:1; unsigned int in_deco_calc : 1;
int ndl_calc; int ndl_calc;
int tts_calc; int tts_calc;
int stoptime_calc; int stoptime_calc;
@ -109,13 +115,13 @@ void setup_pp_limits(struct graphics_context *gc);
#define MIDDLE (-0.5) #define MIDDLE (-0.5)
#define BOTTOM (-1) #define BOTTOM (-1)
#define SCALEXGC(x) (((x) - gc.leftx) / (gc.rightx - gc.leftx) * gc.maxx) #define SCALEXGC(x) (((x) - gc.leftx) / (gc.rightx - gc.leftx) * gc.maxx)
#define SCALEYGC(y) (((y) - gc.topy) / (gc.bottomy - gc.topy) * gc.maxy) #define SCALEYGC(y) (((y) - gc.topy) / (gc.bottomy - gc.topy) * gc.maxy)
#define SCALEGC(x,y) SCALEXGC(x),SCALEYGC(y) #define SCALEGC(x, y) SCALEXGC(x), SCALEYGC(y)
#define SCALEX(gc,x) (((x)-gc->leftx)/(gc->rightx-gc->leftx)*gc->maxx) #define SCALEX(gc, x) (((x) - gc->leftx) / (gc->rightx - gc->leftx) * gc->maxx)
#define SCALEY(gc,y) (((y)-gc->topy)/(gc->bottomy-gc->topy)*gc->maxy) #define SCALEY(gc, y) (((y) - gc->topy) / (gc->bottomy - gc->topy) * gc->maxy)
#define SCALE(gc,x,y) SCALEX(gc,x),SCALEY(gc,y) #define SCALE(gc, x, y) SCALEX(gc, x), SCALEY(gc, y)
#define SENSOR_PR 0 #define SENSOR_PR 0
#define INTERPOLATED_PR 1 #define INTERPOLATED_PR 1
@ -123,7 +129,7 @@ void setup_pp_limits(struct graphics_context *gc);
#define INTERPOLATED_PRESSURE(_entry) (_entry)->pressure[INTERPOLATED_PR] #define INTERPOLATED_PRESSURE(_entry) (_entry)->pressure[INTERPOLATED_PR]
#define GET_PRESSURE(_entry) (SENSOR_PRESSURE(_entry) ? SENSOR_PRESSURE(_entry) : INTERPOLATED_PRESSURE(_entry)) #define GET_PRESSURE(_entry) (SENSOR_PRESSURE(_entry) ? SENSOR_PRESSURE(_entry) : INTERPOLATED_PRESSURE(_entry))
#define SAC_WINDOW 45 /* sliding window in seconds for current SAC calculation */ #define SAC_WINDOW 45 /* sliding window in seconds for current SAC calculation */
#ifdef __cplusplus #ifdef __cplusplus
} }

View file

@ -53,7 +53,7 @@ DiveComputerList dcList;
static QApplication *application = NULL; static QApplication *application = NULL;
static MainWindow *window = NULL; static MainWindow *window = NULL;
int error_count; int error_count;
const char *existing_filename; const char *existing_filename;
const char *getSetting(QSettings &s, QString name) const char *getSetting(QSettings &s, QString name)
@ -94,10 +94,10 @@ void init_ui(int *argcp, char ***argvp)
// 106 is "UTF-8", this is faster than lookup by name // 106 is "UTF-8", this is faster than lookup by name
// [http://www.iana.org/assignments/character-sets/character-sets.xml] // [http://www.iana.org/assignments/character-sets/character-sets.xml]
QTextCodec::setCodecForCStrings(QTextCodec::codecForMib(106)); QTextCodec::setCodecForCStrings(QTextCodec::codecForMib(106));
# ifdef Q_OS_WIN #ifdef Q_OS_WIN
QFile::setDecodingFunction(decodeUtf8); QFile::setDecodingFunction(decodeUtf8);
QFile::setEncodingFunction(encodeUtf8); QFile::setEncodingFunction(encodeUtf8);
# endif #endif
#endif #endif
QCoreApplication::setOrganizationName("Subsurface"); QCoreApplication::setOrganizationName("Subsurface");
QCoreApplication::setOrganizationDomain("subsurface.hohndel.org"); QCoreApplication::setOrganizationDomain("subsurface.hohndel.org");
@ -109,7 +109,7 @@ void init_ui(int *argcp, char ***argvp)
s.beginGroup("Language"); s.beginGroup("Language");
QLocale loc; QLocale loc;
if (!s.value("UseSystemLanguage", true).toBool()){ if (!s.value("UseSystemLanguage", true).toBool()) {
loc = QLocale(s.value("UiLanguage", QLocale().uiLanguages().first()).toString()); loc = QLocale(s.value("UiLanguage", QLocale().uiLanguages().first()).toString());
} }
@ -128,16 +128,15 @@ void init_ui(int *argcp, char ***argvp)
// on Linux this tends to be en-US, but on the Mac it's just en // on Linux this tends to be en-US, but on the Mac it's just en
if (!uiLang.startsWith("en")) { if (!uiLang.startsWith("en")) {
qtTranslator = new QTranslator; qtTranslator = new QTranslator;
if (qtTranslator->load(loc,"qt", "_", QLibraryInfo::location(QLibraryInfo::TranslationsPath))) { if (qtTranslator->load(loc, "qt", "_", QLibraryInfo::location(QLibraryInfo::TranslationsPath))) {
application->installTranslator(qtTranslator); application->installTranslator(qtTranslator);
} else { } else {
qDebug() << "can't find Qt localization for locale" << uiLang << qDebug() << "can't find Qt localization for locale" << uiLang << "searching in" << QLibraryInfo::location(QLibraryInfo::TranslationsPath);
"searching in" << QLibraryInfo::location(QLibraryInfo::TranslationsPath);
} }
ssrfTranslator = new QTranslator; ssrfTranslator = new QTranslator;
if (ssrfTranslator->load(loc,"subsurface", "_") || if (ssrfTranslator->load(loc, "subsurface", "_") ||
ssrfTranslator->load(loc,"subsurface", "_", getSubsurfaceDataPath("translations")) || ssrfTranslator->load(loc, "subsurface", "_", getSubsurfaceDataPath("translations")) ||
ssrfTranslator->load(loc,"subsurface", "_", getSubsurfaceDataPath("../translations"))) { ssrfTranslator->load(loc, "subsurface", "_", getSubsurfaceDataPath("../translations"))) {
application->installTranslator(ssrfTranslator); application->installTranslator(ssrfTranslator);
} else { } else {
qDebug() << "can't find Subsurface localization for locale" << uiLang; qDebug() << "can't find Subsurface localization for locale" << uiLang;
@ -146,7 +145,7 @@ void init_ui(int *argcp, char ***argvp)
s.beginGroup("DiveComputer"); s.beginGroup("DiveComputer");
default_dive_computer_vendor = getSetting(s, "dive_computer_vendor"); default_dive_computer_vendor = getSetting(s, "dive_computer_vendor");
default_dive_computer_product = getSetting(s,"dive_computer_product"); default_dive_computer_product = getSetting(s, "dive_computer_product");
default_dive_computer_device = getSetting(s, "dive_computer_device"); default_dive_computer_device = getSetting(s, "dive_computer_device");
s.endGroup(); s.endGroup();
@ -230,10 +229,10 @@ QString get_depth_string(int mm, bool showunit, bool showdecimal)
{ {
if (prefs.units.length == units::METERS) { if (prefs.units.length == units::METERS) {
double meters = mm / 1000.0; double meters = mm / 1000.0;
return QString("%1%2").arg(meters, 0, 'f', (showdecimal && meters < 20.0) ? 1 : 0 ).arg(showunit ? translate("gettextFromC","m") : ""); return QString("%1%2").arg(meters, 0, 'f', (showdecimal && meters < 20.0) ? 1 : 0).arg(showunit ? translate("gettextFromC", "m") : "");
} else { } else {
double feet = mm_to_feet(mm); double feet = mm_to_feet(mm);
return QString("%1%2").arg(feet, 0, 'f', showdecimal ? 1 : 0). arg(showunit ? translate("gettextFromC","ft") : ""); return QString("%1%2").arg(feet, 0, 'f', showdecimal ? 1 : 0).arg(showunit ? translate("gettextFromC", "ft") : "");
} }
} }
@ -245,18 +244,18 @@ QString get_depth_string(depth_t depth, bool showunit, bool showdecimal)
QString get_depth_unit() QString get_depth_unit()
{ {
if (prefs.units.length == units::METERS) if (prefs.units.length == units::METERS)
return QString("%1").arg(translate("gettextFromC","m")); return QString("%1").arg(translate("gettextFromC", "m"));
else else
return QString("%1").arg(translate("gettextFromC","ft")); return QString("%1").arg(translate("gettextFromC", "ft"));
} }
QString get_weight_string(weight_t weight, bool showunit) QString get_weight_string(weight_t weight, bool showunit)
{ {
QString str = weight_string (weight.grams); QString str = weight_string(weight.grams);
if (get_units()->weight == units::KG) { if (get_units()->weight == units::KG) {
str = QString ("%1%2").arg(str).arg(showunit ? translate("gettextFromC","kg") : ""); str = QString("%1%2").arg(str).arg(showunit ? translate("gettextFromC", "kg") : "");
} else { } else {
str = QString ("%1%2").arg(str).arg(showunit ? translate("gettextFromC","lbs") : ""); str = QString("%1%2").arg(str).arg(showunit ? translate("gettextFromC", "lbs") : "");
} }
return (str); return (str);
} }
@ -264,20 +263,20 @@ QString get_weight_string(weight_t weight, bool showunit)
QString get_weight_unit() QString get_weight_unit()
{ {
if (prefs.units.weight == units::KG) if (prefs.units.weight == units::KG)
return QString("%1").arg(translate("gettextFromC","kg")); return QString("%1").arg(translate("gettextFromC", "kg"));
else else
return QString("%1").arg(translate("gettextFromC","lbs")); return QString("%1").arg(translate("gettextFromC", "lbs"));
} }
/* these methods retrieve used gas per cylinder */ /* these methods retrieve used gas per cylinder */
static unsigned start_pressure(cylinder_t *cyl) static unsigned start_pressure(cylinder_t *cyl)
{ {
return cyl->start.mbar ? : cyl->sample_start.mbar; return cyl->start.mbar ?: cyl->sample_start.mbar;
} }
static unsigned end_pressure(cylinder_t *cyl) static unsigned end_pressure(cylinder_t *cyl)
{ {
return cyl->end.mbar ? : cyl->sample_end.mbar; return cyl->end.mbar ?: cyl->sample_end.mbar;
} }
QString get_cylinder_used_gas_string(cylinder_t *cyl, bool showunit) QString get_cylinder_used_gas_string(cylinder_t *cyl, bool showunit)
@ -303,15 +302,13 @@ QString get_cylinder_used_gas_string(cylinder_t *cyl, bool showunit)
QString get_temperature_string(temperature_t temp, bool showunit) QString get_temperature_string(temperature_t temp, bool showunit)
{ {
if (temp.mkelvin == 0) { if (temp.mkelvin == 0) {
return ""; //temperature not defined return ""; //temperature not defined
} else if (prefs.units.temperature == units::CELSIUS) { } else if (prefs.units.temperature == units::CELSIUS) {
double celsius = mkelvin_to_C(temp.mkelvin); double celsius = mkelvin_to_C(temp.mkelvin);
return QString("%1%2%3").arg(celsius, 0, 'f', 1).arg(showunit ? (UTF8_DEGREE): "") return QString("%1%2%3").arg(celsius, 0, 'f', 1).arg(showunit ? (UTF8_DEGREE) : "").arg(showunit ? translate("gettextFromC", "C") : "");
.arg(showunit ? translate("gettextFromC","C") : "");
} else { } else {
double fahrenheit = mkelvin_to_F(temp.mkelvin); double fahrenheit = mkelvin_to_F(temp.mkelvin);
return QString("%1%2%3").arg(fahrenheit, 0, 'f', 1).arg(showunit ? (UTF8_DEGREE): "") return QString("%1%2%3").arg(fahrenheit, 0, 'f', 1).arg(showunit ? (UTF8_DEGREE) : "").arg(showunit ? translate("gettextFromC", "F") : "");
.arg(showunit ? translate("gettextFromC","F") : "");
} }
} }
@ -327,12 +324,12 @@ QString get_volume_string(volume_t volume, bool showunit, unsigned int mbar)
{ {
if (prefs.units.volume == units::LITER) { if (prefs.units.volume == units::LITER) {
double liter = volume.mliter / 1000.0; double liter = volume.mliter / 1000.0;
return QString("%1%2").arg(liter, 0, 'f', liter >= 40.0 ? 0 : 1 ).arg(showunit ? translate("gettextFromC","l") : ""); return QString("%1%2").arg(liter, 0, 'f', liter >= 40.0 ? 0 : 1).arg(showunit ? translate("gettextFromC", "l") : "");
} else { } else {
double cuft = ml_to_cuft(volume.mliter); double cuft = ml_to_cuft(volume.mliter);
if (mbar) if (mbar)
cuft *= bar_to_atm(mbar / 1000.0); cuft *= bar_to_atm(mbar / 1000.0);
return QString("%1%2").arg(cuft, 0, 'f', cuft >= 20.0 ? 0 : (cuft >= 2.0 ? 1 : 2)).arg(showunit ? translate("gettextFromC","cuft") : ""); return QString("%1%2").arg(cuft, 0, 'f', cuft >= 20.0 ? 0 : (cuft >= 2.0 ? 1 : 2)).arg(showunit ? translate("gettextFromC", "cuft") : "");
} }
} }
@ -348,10 +345,10 @@ QString get_pressure_string(pressure_t pressure, bool showunit)
{ {
if (prefs.units.pressure == units::BAR) { if (prefs.units.pressure == units::BAR) {
double bar = pressure.mbar / 1000.0; double bar = pressure.mbar / 1000.0;
return QString("%1%2").arg(bar, 0, 'f', 1).arg(showunit ? translate("gettextFromC","bar") : ""); return QString("%1%2").arg(bar, 0, 'f', 1).arg(showunit ? translate("gettextFromC", "bar") : "");
} else { } else {
double psi = mbar_to_PSI(pressure.mbar); double psi = mbar_to_PSI(pressure.mbar);
return QString("%1%2").arg(psi, 0, 'f', 0).arg(showunit ? translate("gettextFromC","psi") : ""); return QString("%1%2").arg(psi, 0, 'f', 0).arg(showunit ? translate("gettextFromC", "psi") : "");
} }
} }
@ -364,7 +361,7 @@ double get_screen_dpi()
int is_default_dive_computer(const char *vendor, const char *product) int is_default_dive_computer(const char *vendor, const char *product)
{ {
return default_dive_computer_vendor && !strcmp(vendor, default_dive_computer_vendor) && return default_dive_computer_vendor && !strcmp(vendor, default_dive_computer_vendor) &&
default_dive_computer_product && !strcmp(product, default_dive_computer_product); default_dive_computer_product && !strcmp(product, default_dive_computer_product);
} }
int is_default_dive_computer_device(const char *name) int is_default_dive_computer_device(const char *name)
@ -473,11 +470,11 @@ int gettimezoneoffset()
return dt2.secsTo(dt1); return dt2.secsTo(dt1);
} }
int parseTemperatureToMkelvin(const QString& text) int parseTemperatureToMkelvin(const QString &text)
{ {
int mkelvin; int mkelvin;
QString numOnly = text; QString numOnly = text;
numOnly.replace(",",".").remove(QRegExp("[^-0-9.]")); numOnly.replace(",", ".").remove(QRegExp("[^-0-9.]"));
if (numOnly == "") if (numOnly == "")
return 0; return 0;
double number = numOnly.toDouble(); double number = numOnly.toDouble();
@ -492,7 +489,6 @@ int parseTemperatureToMkelvin(const QString& text)
mkelvin = 0; mkelvin = 0;
} }
return mkelvin; return mkelvin;
} }
QString get_dive_date_string(timestamp_t when) QString get_dive_date_string(timestamp_t when)
@ -500,12 +496,12 @@ QString get_dive_date_string(timestamp_t when)
struct tm tm; struct tm tm;
utc_mkdate(when, &tm); utc_mkdate(when, &tm);
return translate("gettextFromC", "%1, %2 %3, %4 %5:%6") return translate("gettextFromC", "%1, %2 %3, %4 %5:%6")
.arg(weekday(tm.tm_wday)) .arg(weekday(tm.tm_wday))
.arg(monthname(tm.tm_mon)) .arg(monthname(tm.tm_mon))
.arg(tm.tm_mday) .arg(tm.tm_mday)
.arg(tm.tm_year + 1900) .arg(tm.tm_year + 1900)
.arg(tm.tm_hour, 2, 10, QChar('0')) .arg(tm.tm_hour, 2, 10, QChar('0'))
.arg(tm.tm_min, 2, 10, QChar('0')); .arg(tm.tm_min, 2, 10, QChar('0'));
} }
QString get_short_dive_date_string(timestamp_t when) QString get_short_dive_date_string(timestamp_t when)
@ -513,11 +509,11 @@ QString get_short_dive_date_string(timestamp_t when)
struct tm tm; struct tm tm;
utc_mkdate(when, &tm); utc_mkdate(when, &tm);
return translate("gettextFromC", "%1 %2, %3\n%4:%5") return translate("gettextFromC", "%1 %2, %3\n%4:%5")
.arg(monthname(tm.tm_mon)) .arg(monthname(tm.tm_mon))
.arg(tm.tm_mday) .arg(tm.tm_mday)
.arg(tm.tm_year + 1900) .arg(tm.tm_year + 1900)
.arg(tm.tm_hour, 2, 10, QChar('0')) .arg(tm.tm_hour, 2, 10, QChar('0'))
.arg(tm.tm_min, 2, 10, QChar('0')); .arg(tm.tm_min, 2, 10, QChar('0'));
} }
QString get_trip_date_string(timestamp_t when, int nr) QString get_trip_date_string(timestamp_t when, int nr)
@ -526,13 +522,13 @@ QString get_trip_date_string(timestamp_t when, int nr)
utc_mkdate(when, &tm); utc_mkdate(when, &tm);
if (nr != 1) if (nr != 1)
return translate("gettextFromC", "%1 %2 (%3 dives)") return translate("gettextFromC", "%1 %2 (%3 dives)")
.arg(monthname(tm.tm_mon)) .arg(monthname(tm.tm_mon))
.arg(tm.tm_year + 1900) .arg(tm.tm_year + 1900)
.arg(nr); .arg(nr);
else else
return translate("gettextFromC", "%1 %2 (1 dive)") return translate("gettextFromC", "%1 %2 (1 dive)")
.arg(monthname(tm.tm_mon)) .arg(monthname(tm.tm_mon))
.arg(tm.tm_year + 1900); .arg(tm.tm_year + 1900);
} }
static xmlDocPtr get_stylesheet_doc(const xmlChar *uri, xmlDictPtr, int, void *, xsltLoadType) static xmlDocPtr get_stylesheet_doc(const xmlChar *uri, xmlDictPtr, int, void *, xsltLoadType)
@ -558,7 +554,7 @@ xsltStylesheetPtr get_stylesheet(const char *name)
if (!doc) if (!doc)
return NULL; return NULL;
// xsltSetGenericErrorFunc(stderr, NULL); // xsltSetGenericErrorFunc(stderr, NULL);
xsltStylesheetPtr xslt = xsltParseStylesheetDoc(doc); xsltStylesheetPtr xslt = xsltParseStylesheetDoc(doc);
if (!xslt) { if (!xslt) {
xmlFreeDoc(doc); xmlFreeDoc(doc);

View file

@ -9,12 +9,12 @@ SubsurfaceAbout::SubsurfaceAbout(QWidget *parent, Qt::WindowFlags f) : QDialog(p
setWindowModality(Qt::ApplicationModal); setWindowModality(Qt::ApplicationModal);
ui.aboutLabel->setText(tr("<span style='font-size: 18pt; font-weight: bold;'>" \ ui.aboutLabel->setText(tr("<span style='font-size: 18pt; font-weight: bold;'>"
"Subsurface %1 </span><br><br>" \ "Subsurface %1 </span><br><br>"
"Multi-platform divelog software<br>" \ "Multi-platform divelog software<br>"
"<span style='font-size: 8pt'>" \ "<span style='font-size: 8pt'>"
"Linus Torvalds, Dirk Hohndel, Tomaz Canabrava, and others, 2011-2014" \ "Linus Torvalds, Dirk Hohndel, Tomaz Canabrava, and others, 2011-2014"
"</span>").arg(VERSION_STRING)); "</span>").arg(VERSION_STRING));
} }
void SubsurfaceAbout::on_licenseButton_clicked() void SubsurfaceAbout::on_licenseButton_clicked()

View file

@ -9,10 +9,12 @@ class SubsurfaceAbout : public QDialog {
Q_OBJECT Q_OBJECT
public: public:
explicit SubsurfaceAbout(QWidget* parent = 0, Qt::WindowFlags f = 0); explicit SubsurfaceAbout(QWidget *parent = 0, Qt::WindowFlags f = 0);
private slots: private
slots:
void on_licenseButton_clicked(); void on_licenseButton_clicked();
void on_websiteButton_clicked(); void on_websiteButton_clicked();
private: private:
Ui::SubsurfaceAbout ui; Ui::SubsurfaceAbout ui;
}; };

View file

@ -2,35 +2,38 @@
#include "dive.h" #include "dive.h"
#include "mainwindow.h" #include "mainwindow.h"
#define CREATE_UPDATE_METHOD(Class, diveStructMember) \ #define CREATE_UPDATE_METHOD(Class, diveStructMember) \
void Class::updateModel() \ void Class::updateModel() \
{ \ { \
QStringList list; \ QStringList list; \
struct dive* dive; \ struct dive *dive; \
int i = 0; \ int i = 0; \
for_each_dive(i, dive) { \ for_each_dive(i, dive) \
QString buddy(dive->diveStructMember); \ { \
if (!list.contains(buddy)) { \ QString buddy(dive->diveStructMember); \
list.append(buddy); \ if (!list.contains(buddy)) { \
} \ list.append(buddy); \
} \ } \
setStringList(list); \ } \
} setStringList(list); \
}
#define CREATE_CSV_UPDATE_METHOD(Class, diveStructMember) \ #define CREATE_CSV_UPDATE_METHOD(Class, diveStructMember) \
void Class::updateModel() \ void Class::updateModel() \
{ \ { \
QSet<QString> set; \ QSet<QString> set; \
struct dive* dive; \ struct dive *dive; \
int i = 0; \ int i = 0; \
for_each_dive(i, dive) { \ for_each_dive(i, dive) \
QString buddy(dive->diveStructMember); \ { \
foreach (const QString &value, buddy.split(",", QString::SkipEmptyParts)) { \ QString buddy(dive->diveStructMember); \
set.insert(value.trimmed()); \ foreach(const QString &value, buddy.split(",", QString::SkipEmptyParts)) \
} \ { \
} \ set.insert(value.trimmed()); \
setStringList(set.toList()); \ } \
} } \
setStringList(set.toList()); \
}
CREATE_CSV_UPDATE_METHOD(BuddyCompletionModel, buddy); CREATE_CSV_UPDATE_METHOD(BuddyCompletionModel, buddy);
CREATE_CSV_UPDATE_METHOD(DiveMasterCompletionModel, divemaster); CREATE_CSV_UPDATE_METHOD(DiveMasterCompletionModel, divemaster);

View file

@ -5,7 +5,7 @@
#include "../qthelper.h" #include "../qthelper.h"
#include "../helpers.h" #include "../helpers.h"
DiveComputerManagementDialog::DiveComputerManagementDialog(QWidget* parent, Qt::WindowFlags f): QDialog(parent, f), DiveComputerManagementDialog::DiveComputerManagementDialog(QWidget *parent, Qt::WindowFlags f) : QDialog(parent, f),
model(0) model(0)
{ {
ui.setupUi(this); ui.setupUi(this);
@ -20,7 +20,7 @@ void DiveComputerManagementDialog::init()
ui.tableView->setModel(model); ui.tableView->setModel(model);
} }
DiveComputerManagementDialog* DiveComputerManagementDialog::instance() DiveComputerManagementDialog *DiveComputerManagementDialog::instance()
{ {
static DiveComputerManagementDialog *self = new DiveComputerManagementDialog(MainWindow::instance()); static DiveComputerManagementDialog *self = new DiveComputerManagementDialog(MainWindow::instance());
self->setAttribute(Qt::WA_QuitOnClose, false); self->setAttribute(Qt::WA_QuitOnClose, false);
@ -35,17 +35,16 @@ void DiveComputerManagementDialog::update()
layout()->activate(); layout()->activate();
} }
void DiveComputerManagementDialog::tryRemove(const QModelIndex& index) void DiveComputerManagementDialog::tryRemove(const QModelIndex &index)
{ {
if (index.column() != DiveComputerModel::REMOVE) if (index.column() != DiveComputerModel::REMOVE)
return; return;
QMessageBox::StandardButton response = QMessageBox::question( QMessageBox::StandardButton response = QMessageBox::question(
this, TITLE_OR_TEXT( this, TITLE_OR_TEXT(
tr("Remove the selected Dive Computer?"), tr("Remove the selected Dive Computer?"),
tr("Are you sure that you want to \n remove the selected dive computer?")), tr("Are you sure that you want to \n remove the selected dive computer?")),
QMessageBox::Ok | QMessageBox::Cancel QMessageBox::Ok | QMessageBox::Cancel);
);
if (response == QMessageBox::Ok) if (response == QMessageBox::Ok)
model->remove(index); model->remove(index);

View file

@ -6,21 +6,22 @@
class QModelIndex; class QModelIndex;
class DiveComputerModel; class DiveComputerModel;
class DiveComputerManagementDialog : public QDialog{ class DiveComputerManagementDialog : public QDialog {
Q_OBJECT Q_OBJECT
public: public:
static DiveComputerManagementDialog *instance(); static DiveComputerManagementDialog *instance();
void update(); void update();
void init(); void init();
public slots: public
void tryRemove(const QModelIndex& index); slots:
void tryRemove(const QModelIndex &index);
void accept(); void accept();
void reject(); void reject();
private: private:
explicit DiveComputerManagementDialog(QWidget* parent = 0, Qt::WindowFlags f = 0); explicit DiveComputerManagementDialog(QWidget *parent = 0, Qt::WindowFlags f = 0);
Ui::DiveComputerManagementDialog ui; Ui::DiveComputerManagementDialog ui;
DiveComputerModel *model; DiveComputerModel *model;
}; };

View file

@ -27,8 +27,7 @@
#include <iostream> #include <iostream>
DiveListView::DiveListView(QWidget *parent) : QTreeView(parent), mouseClickSelection(false), DiveListView::DiveListView(QWidget *parent) : QTreeView(parent), mouseClickSelection(false), sortColumn(0), currentOrder(Qt::DescendingOrder), searchBox(this)
sortColumn(0), currentOrder(Qt::DescendingOrder), searchBox(this)
{ {
setItemDelegate(new DiveListDelegate(this)); setItemDelegate(new DiveListDelegate(this));
setUniformRowHeights(true); setUniformRowHeights(true);
@ -47,7 +46,7 @@ DiveListView::DiveListView(QWidget *parent) : QTreeView(parent), mouseClickSelec
header()->setMinimumHeight(metrics.height() + 10); header()->setMinimumHeight(metrics.height() + 10);
header()->setStretchLastSection(true); header()->setStretchLastSection(true);
QAction *showSearchBox = new QAction(tr("Show Search Box"), this); QAction *showSearchBox = new QAction(tr("Show Search Box"), this);
showSearchBox->setShortcut( Qt::CTRL + Qt::Key_F); showSearchBox->setShortcut(Qt::CTRL + Qt::Key_F);
showSearchBox->setShortcutContext(Qt::WindowShortcut); showSearchBox->setShortcutContext(Qt::WindowShortcut);
addAction(showSearchBox); addAction(showSearchBox);
@ -112,23 +111,23 @@ int DiveListView::lastVisibleColumn()
void DiveListView::backupExpandedRows() void DiveListView::backupExpandedRows()
{ {
expandedRows.clear(); expandedRows.clear();
for(int i = 0; i < model()->rowCount(); i++) for (int i = 0; i < model()->rowCount(); i++)
if (isExpanded( model()->index(i, 0) )) if (isExpanded(model()->index(i, 0)))
expandedRows.push_back(i); expandedRows.push_back(i);
} }
void DiveListView::restoreExpandedRows() void DiveListView::restoreExpandedRows()
{ {
setAnimated(false); setAnimated(false);
Q_FOREACH(const int &i, expandedRows) Q_FOREACH(const int & i, expandedRows)
setExpanded( model()->index(i, 0), true ); setExpanded(model()->index(i, 0), true);
setAnimated(true); setAnimated(true);
} }
void DiveListView::fixMessyQtModelBehaviour() void DiveListView::fixMessyQtModelBehaviour()
{ {
QAbstractItemModel *m = model(); QAbstractItemModel *m = model();
for(int i = 0; i < model()->rowCount(); i++) for (int i = 0; i < model()->rowCount(); i++)
if (m->rowCount( m->index(i, 0) ) != 0) if (m->rowCount(m->index(i, 0)) != 0)
setFirstColumnSpanned(i, QModelIndex(), true); setFirstColumnSpanned(i, QModelIndex(), true);
} }
@ -137,10 +136,10 @@ void DiveListView::rememberSelection()
{ {
selectedDives.clear(); selectedDives.clear();
QItemSelection selection = selectionModel()->selection(); QItemSelection selection = selectionModel()->selection();
Q_FOREACH(const QModelIndex& index , selection.indexes()) { Q_FOREACH(const QModelIndex & index, selection.indexes()) {
if (index.column() != 0) // We only care about the dives, so, let's stick to rows and discard columns. if (index.column() != 0) // We only care about the dives, so, let's stick to rows and discard columns.
continue; continue;
struct dive *d = (struct dive *) index.data(DiveTripModel::DIVE_ROLE).value<void*>(); struct dive *d = (struct dive *)index.data(DiveTripModel::DIVE_ROLE).value<void *>();
if (d) if (d)
selectedDives.insert(d->divetrip, get_divenr(d)); selectedDives.insert(d->divetrip, get_divenr(d));
} }
@ -149,7 +148,7 @@ void DiveListView::rememberSelection()
void DiveListView::restoreSelection() void DiveListView::restoreSelection()
{ {
unselectDives(); unselectDives();
Q_FOREACH(dive_trip_t *trip, selectedDives.keys()) { Q_FOREACH(dive_trip_t * trip, selectedDives.keys()) {
QList<int> divesOnTrip = getDivesInTrip(trip); QList<int> divesOnTrip = getDivesInTrip(trip);
QList<int> selectedDivesOnTrip = selectedDives.values(trip); QList<int> selectedDivesOnTrip = selectedDives.values(trip);
@ -167,18 +166,18 @@ void DiveListView::restoreSelection()
} }
} }
void DiveListView::selectTrip ( dive_trip_t* trip ) void DiveListView::selectTrip(dive_trip_t *trip)
{ {
if (!trip) if (!trip)
return; return;
QSortFilterProxyModel *m = qobject_cast<QSortFilterProxyModel*>(model()); QSortFilterProxyModel *m = qobject_cast<QSortFilterProxyModel *>(model());
QModelIndexList match = m->match(m->index(0,0), DiveTripModel::TRIP_ROLE, QVariant::fromValue<void*>(trip), 2, Qt::MatchRecursive); QModelIndexList match = m->match(m->index(0, 0), DiveTripModel::TRIP_ROLE, QVariant::fromValue<void *>(trip), 2, Qt::MatchRecursive);
QItemSelectionModel::SelectionFlags flags; QItemSelectionModel::SelectionFlags flags;
if (!match.count()) if (!match.count())
return; return;
QModelIndex idx = match.first(); QModelIndex idx = match.first();
flags = QItemSelectionModel::Select; flags = QItemSelectionModel::Select;
flags |= QItemSelectionModel::Rows; flags |= QItemSelectionModel::Rows;
selectionModel()->select(idx, flags); selectionModel()->select(idx, flags);
expand(idx); expand(idx);
@ -189,12 +188,12 @@ void DiveListView::unselectDives()
selectionModel()->clearSelection(); selectionModel()->clearSelection();
} }
QList< dive_trip_t* > DiveListView::selectedTrips() QList<dive_trip_t *> DiveListView::selectedTrips()
{ {
QModelIndexList indexes = selectionModel()->selectedRows(); QModelIndexList indexes = selectionModel()->selectedRows();
QList<dive_trip_t*> ret; QList<dive_trip_t *> ret;
Q_FOREACH(const QModelIndex& index, indexes) { Q_FOREACH(const QModelIndex & index, indexes) {
dive_trip_t *trip = static_cast<dive_trip_t*>(index.data(DiveTripModel::TRIP_ROLE).value<void*>()); dive_trip_t *trip = static_cast<dive_trip_t *>(index.data(DiveTripModel::TRIP_ROLE).value<void *>());
if (!trip) if (!trip)
continue; continue;
ret.push_back(trip); ret.push_back(trip);
@ -204,10 +203,10 @@ QList< dive_trip_t* > DiveListView::selectedTrips()
void DiveListView::selectDive(int i, bool scrollto, bool toggle) void DiveListView::selectDive(int i, bool scrollto, bool toggle)
{ {
if ( i == -1) if (i == -1)
return; return;
QSortFilterProxyModel *m = qobject_cast<QSortFilterProxyModel*>(model()); QSortFilterProxyModel *m = qobject_cast<QSortFilterProxyModel *>(model());
QModelIndexList match = m->match(m->index(0,0), DiveTripModel::DIVE_IDX, i, 2, Qt::MatchRecursive); QModelIndexList match = m->match(m->index(0, 0), DiveTripModel::DIVE_IDX, i, 2, Qt::MatchRecursive);
QItemSelectionModel::SelectionFlags flags; QItemSelectionModel::SelectionFlags flags;
QModelIndex idx = match.first(); QModelIndex idx = match.first();
flags = toggle ? QItemSelectionModel::Toggle : QItemSelectionModel::Select; flags = toggle ? QItemSelectionModel::Toggle : QItemSelectionModel::Select;
@ -222,19 +221,19 @@ void DiveListView::selectDive(int i, bool scrollto, bool toggle)
scrollTo(idx, PositionAtCenter); scrollTo(idx, PositionAtCenter);
} }
void DiveListView::selectDives(const QList< int >& newDiveSelection) void DiveListView::selectDives(const QList<int> &newDiveSelection)
{ {
if (!newDiveSelection.count()) if (!newDiveSelection.count())
return; return;
disconnect(selectionModel(), SIGNAL(selectionChanged(QItemSelection,QItemSelection)), disconnect(selectionModel(), SIGNAL(selectionChanged(QItemSelection, QItemSelection)),
this, SLOT(selectionChanged(QItemSelection,QItemSelection))); this, SLOT(selectionChanged(QItemSelection, QItemSelection)));
disconnect(selectionModel(), SIGNAL(currentChanged(QModelIndex,QModelIndex)), disconnect(selectionModel(), SIGNAL(currentChanged(QModelIndex, QModelIndex)),
this, SLOT(currentChanged(QModelIndex,QModelIndex))); this, SLOT(currentChanged(QModelIndex, QModelIndex)));
setAnimated(false); setAnimated(false);
collapseAll(); collapseAll();
QSortFilterProxyModel *m = qobject_cast<QSortFilterProxyModel*>(model()); QSortFilterProxyModel *m = qobject_cast<QSortFilterProxyModel *>(model());
QItemSelectionModel::SelectionFlags flags = QItemSelectionModel::Select | QItemSelectionModel::Rows; QItemSelectionModel::SelectionFlags flags = QItemSelectionModel::Select | QItemSelectionModel::Rows;
QItemSelection newDeselected = selectionModel()->selection(); QItemSelection newDeselected = selectionModel()->selection();
@ -246,17 +245,17 @@ void DiveListView::selectDives(const QList< int >& newDiveSelection)
struct dive *dive; struct dive *dive;
for_each_dive(i, dive) { for_each_dive(i, dive) {
dive->selected = newDiveSelection.contains(i) == true; dive->selected = newDiveSelection.contains(i) == true;
if (firstSelectedDive == -1 && dive->selected ) { if (firstSelectedDive == -1 && dive->selected) {
firstSelectedDive = i; firstSelectedDive = i;
} }
} }
} }
select_dive(firstSelectedDive); select_dive(firstSelectedDive);
Q_FOREACH(int i, newDiveSelection) { Q_FOREACH(int i, newDiveSelection) {
diveList.append(m->match(m->index(0,0), DiveTripModel::DIVE_IDX, diveList.append(m->match(m->index(0, 0), DiveTripModel::DIVE_IDX,
i, 2, Qt::MatchRecursive).first()); i, 2, Qt::MatchRecursive).first());
} }
Q_FOREACH(const QModelIndex& idx, diveList) { Q_FOREACH(const QModelIndex & idx, diveList) {
selectionModel()->select(idx, flags); selectionModel()->select(idx, flags);
if (idx.parent().isValid() && !isExpanded(idx.parent())) { if (idx.parent().isValid() && !isExpanded(idx.parent())) {
expand(idx.parent()); expand(idx.parent());
@ -264,12 +263,12 @@ void DiveListView::selectDives(const QList< int >& newDiveSelection)
} }
setAnimated(true); setAnimated(true);
QTreeView::selectionChanged(selectionModel()->selection(), newDeselected); QTreeView::selectionChanged(selectionModel()->selection(), newDeselected);
connect(selectionModel(), SIGNAL(selectionChanged(QItemSelection,QItemSelection)), connect(selectionModel(), SIGNAL(selectionChanged(QItemSelection, QItemSelection)),
this, SLOT(selectionChanged(QItemSelection,QItemSelection))); this, SLOT(selectionChanged(QItemSelection, QItemSelection)));
connect(selectionModel(), SIGNAL(currentChanged(QModelIndex,QModelIndex)), connect(selectionModel(), SIGNAL(currentChanged(QModelIndex, QModelIndex)),
this, SLOT(currentChanged(QModelIndex,QModelIndex))); this, SLOT(currentChanged(QModelIndex, QModelIndex)));
Q_EMIT currentDiveChanged(selected_dive); Q_EMIT currentDiveChanged(selected_dive);
const QModelIndex& idx = m->match(m->index(0,0), DiveTripModel::DIVE_IDX,selected_dive, 2, Qt::MatchRecursive).first(); const QModelIndex &idx = m->match(m->index(0, 0), DiveTripModel::DIVE_IDX, selected_dive, 2, Qt::MatchRecursive).first();
scrollTo(idx); scrollTo(idx);
} }
@ -279,17 +278,17 @@ void DiveListView::showSearchEdit()
searchBox.setFocus(); searchBox.setFocus();
} }
bool DiveListView::eventFilter(QObject* , QEvent* event) bool DiveListView::eventFilter(QObject *, QEvent *event)
{ {
if (event->type() != QEvent::KeyPress) if (event->type() != QEvent::KeyPress)
return false; return false;
QKeyEvent *keyEv = static_cast<QKeyEvent*>(event); QKeyEvent *keyEv = static_cast<QKeyEvent *>(event);
if (keyEv->key() != Qt::Key_Escape) if (keyEv->key() != Qt::Key_Escape)
return false; return false;
searchBox.clear(); searchBox.clear();
searchBox.hide(); searchBox.hide();
QSortFilterProxyModel *m = qobject_cast<QSortFilterProxyModel*>(model()); QSortFilterProxyModel *m = qobject_cast<QSortFilterProxyModel *>(model());
m->setFilterFixedString(QString()); m->setFilterFixedString(QString());
return true; return true;
} }
@ -300,7 +299,7 @@ bool DiveListView::eventFilter(QObject* , QEvent* event)
// index. TRIP_ROLE vs DIVE_ROLE? // index. TRIP_ROLE vs DIVE_ROLE?
void DiveListView::headerClicked(int i) void DiveListView::headerClicked(int i)
{ {
DiveTripModel::Layout newLayout = i == (int) DiveTripModel::NR ? DiveTripModel::TREE : DiveTripModel::LIST; DiveTripModel::Layout newLayout = i == (int)DiveTripModel::NR ? DiveTripModel::TREE : DiveTripModel::LIST;
rememberSelection(); rememberSelection();
unselectDives(); unselectDives();
/* No layout change? Just re-sort, and scroll to first selection, making sure all selections are expanded */ /* No layout change? Just re-sort, and scroll to first selection, making sure all selections are expanded */
@ -328,14 +327,14 @@ void DiveListView::reload(DiveTripModel::Layout layout, bool forceSort)
layout = currentLayout; layout = currentLayout;
else else
currentLayout = layout; currentLayout = layout;
#if QT_VERSION < QT_VERSION_CHECK(5,0,0) #if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
header()->setClickable(true); header()->setClickable(true);
#else #else
header()->setSectionsClickable(true); header()->setSectionsClickable(true);
#endif #endif
connect(header(), SIGNAL(sectionPressed(int)), this, SLOT(headerClicked(int)), Qt::UniqueConnection); connect(header(), SIGNAL(sectionPressed(int)), this, SLOT(headerClicked(int)), Qt::UniqueConnection);
QSortFilterProxyModel *m = qobject_cast<QSortFilterProxyModel*>(model()); QSortFilterProxyModel *m = qobject_cast<QSortFilterProxyModel *>(model());
QAbstractItemModel *oldModel = m->sourceModel(); QAbstractItemModel *oldModel = m->sourceModel();
if (oldModel) { if (oldModel) {
oldModel->deleteLater(); oldModel->deleteLater();
@ -352,10 +351,10 @@ void DiveListView::reload(DiveTripModel::Layout layout, bool forceSort)
if (amount_selected && current_dive != NULL) { if (amount_selected && current_dive != NULL) {
selectDive(selected_dive, true); selectDive(selected_dive, true);
} else { } else {
QModelIndex firstDiveOrTrip = m->index(0,0); QModelIndex firstDiveOrTrip = m->index(0, 0);
if (firstDiveOrTrip.isValid()) { if (firstDiveOrTrip.isValid()) {
if (m->index(0,0, firstDiveOrTrip).isValid()) if (m->index(0, 0, firstDiveOrTrip).isValid())
setCurrentIndex(m->index(0,0, firstDiveOrTrip)); setCurrentIndex(m->index(0, 0, firstDiveOrTrip));
else else
setCurrentIndex(firstDiveOrTrip); setCurrentIndex(firstDiveOrTrip);
} }
@ -382,19 +381,12 @@ void DiveListView::reloadHeaderActions()
if (!header()->actions().size()) { if (!header()->actions().size()) {
QSettings s; QSettings s;
s.beginGroup("DiveListColumnState"); s.beginGroup("DiveListColumnState");
for(int i = 0; i < model()->columnCount(); i++) { for (int i = 0; i < model()->columnCount(); i++) {
QString title = QString("%1").arg(model()->headerData(i, Qt::Horizontal).toString()); QString title = QString("%1").arg(model()->headerData(i, Qt::Horizontal).toString());
QString settingName = QString("showColumn%1").arg(i); QString settingName = QString("showColumn%1").arg(i);
QAction *a = new QAction(title, header()); QAction *a = new QAction(title, header());
bool showHeaderFirstRun = !( bool showHeaderFirstRun = !(
i == DiveTripModel::MAXCNS i == DiveTripModel::MAXCNS || i == DiveTripModel::NITROX || i == DiveTripModel::OTU || i == DiveTripModel::TEMPERATURE || i == DiveTripModel::TOTALWEIGHT || i == DiveTripModel::SUIT || i == DiveTripModel::CYLINDER || i == DiveTripModel::SAC);
|| i == DiveTripModel::NITROX
|| i == DiveTripModel::OTU
|| i == DiveTripModel::TEMPERATURE
|| i == DiveTripModel::TOTALWEIGHT
|| i == DiveTripModel::SUIT
|| i == DiveTripModel::CYLINDER
|| i == DiveTripModel::SAC );
bool shown = s.value(settingName, showHeaderFirstRun).toBool(); bool shown = s.value(settingName, showHeaderFirstRun).toBool();
a->setCheckable(true); a->setCheckable(true);
a->setChecked(shown); a->setChecked(shown);
@ -406,7 +398,7 @@ void DiveListView::reloadHeaderActions()
} }
s.endGroup(); s.endGroup();
} else { } else {
for(int i = 0; i < model()->columnCount(); i++) { for (int i = 0; i < model()->columnCount(); i++) {
QString title = QString("%1").arg(model()->headerData(i, Qt::Horizontal).toString()); QString title = QString("%1").arg(model()->headerData(i, Qt::Horizontal).toString());
header()->actions()[i]->setText(title); header()->actions()[i]->setText(title);
} }
@ -415,7 +407,7 @@ void DiveListView::reloadHeaderActions()
void DiveListView::toggleColumnVisibilityByIndex() void DiveListView::toggleColumnVisibilityByIndex()
{ {
QAction *action = qobject_cast<QAction*>(sender()); QAction *action = qobject_cast<QAction *>(sender());
if (!action) if (!action)
return; return;
@ -428,29 +420,29 @@ void DiveListView::toggleColumnVisibilityByIndex()
setColumnWidth(lastVisibleColumn(), 10); setColumnWidth(lastVisibleColumn(), 10);
} }
void DiveListView::currentChanged(const QModelIndex& current, const QModelIndex& previous) void DiveListView::currentChanged(const QModelIndex &current, const QModelIndex &previous)
{ {
if (!current.isValid()) if (!current.isValid())
return; return;
scrollTo(current); scrollTo(current);
} }
void DiveListView::selectionChanged(const QItemSelection& selected, const QItemSelection& deselected) void DiveListView::selectionChanged(const QItemSelection &selected, const QItemSelection &deselected)
{ {
QItemSelection newSelected = selected.size() ? selected : selectionModel()->selection(); QItemSelection newSelected = selected.size() ? selected : selectionModel()->selection();
QItemSelection newDeselected = deselected; QItemSelection newDeselected = deselected;
disconnect(selectionModel(), SIGNAL(selectionChanged(QItemSelection,QItemSelection)), this, SLOT(selectionChanged(QItemSelection,QItemSelection))); disconnect(selectionModel(), SIGNAL(selectionChanged(QItemSelection, QItemSelection)), this, SLOT(selectionChanged(QItemSelection, QItemSelection)));
disconnect(selectionModel(), SIGNAL(currentChanged(QModelIndex,QModelIndex)), this, SLOT(currentChanged(QModelIndex,QModelIndex))); disconnect(selectionModel(), SIGNAL(currentChanged(QModelIndex, QModelIndex)), this, SLOT(currentChanged(QModelIndex, QModelIndex)));
Q_FOREACH(const QModelIndex& index, newDeselected.indexes()) { Q_FOREACH(const QModelIndex & index, newDeselected.indexes()) {
if (index.column() != 0) if (index.column() != 0)
continue; continue;
const QAbstractItemModel *model = index.model(); const QAbstractItemModel *model = index.model();
struct dive *dive = (struct dive*) model->data(index, DiveTripModel::DIVE_ROLE).value<void*>(); struct dive *dive = (struct dive *)model->data(index, DiveTripModel::DIVE_ROLE).value<void *>();
if (!dive) { // it's a trip! if (!dive) { // it's a trip!
if (model->rowCount(index)) { if (model->rowCount(index)) {
struct dive *child = (struct dive*) model->data(index.child(0,0), DiveTripModel::DIVE_ROLE).value<void*>(); struct dive *child = (struct dive *)model->data(index.child(0, 0), DiveTripModel::DIVE_ROLE).value<void *>();
while (child) { while (child) {
deselect_dive(get_divenr(child)); deselect_dive(get_divenr(child));
child = child->next; child = child->next;
@ -460,21 +452,21 @@ void DiveListView::selectionChanged(const QItemSelection& selected, const QItemS
deselect_dive(get_divenr(dive)); deselect_dive(get_divenr(dive));
} }
} }
Q_FOREACH(const QModelIndex& index, newSelected.indexes()) { Q_FOREACH(const QModelIndex & index, newSelected.indexes()) {
if (index.column() != 0) if (index.column() != 0)
continue; continue;
const QAbstractItemModel *model = index.model(); const QAbstractItemModel *model = index.model();
struct dive *dive = (struct dive*) model->data(index, DiveTripModel::DIVE_ROLE).value<void*>(); struct dive *dive = (struct dive *)model->data(index, DiveTripModel::DIVE_ROLE).value<void *>();
if (!dive) { // it's a trip! if (!dive) { // it's a trip!
if (model->rowCount(index)) { if (model->rowCount(index)) {
QItemSelection selection; QItemSelection selection;
struct dive *child = (struct dive*) model->data(index.child(0,0), DiveTripModel::DIVE_ROLE).value<void*>(); struct dive *child = (struct dive *)model->data(index.child(0, 0), DiveTripModel::DIVE_ROLE).value<void *>();
while (child) { while (child) {
select_dive(get_divenr(child)); select_dive(get_divenr(child));
child = child->next; child = child->next;
} }
selection.select(index.child(0,0), index.child(model->rowCount(index) -1 , 0)); selection.select(index.child(0, 0), index.child(model->rowCount(index) - 1, 0));
selectionModel()->select(selection, QItemSelectionModel::Select | QItemSelectionModel::Rows); selectionModel()->select(selection, QItemSelectionModel::Select | QItemSelectionModel::Rows);
selectionModel()->setCurrentIndex(index, QItemSelectionModel::Select | QItemSelectionModel::NoUpdate); selectionModel()->setCurrentIndex(index, QItemSelectionModel::Select | QItemSelectionModel::NoUpdate);
if (!isExpanded(index)) if (!isExpanded(index))
@ -485,8 +477,8 @@ void DiveListView::selectionChanged(const QItemSelection& selected, const QItemS
} }
} }
QTreeView::selectionChanged(selectionModel()->selection(), newDeselected); QTreeView::selectionChanged(selectionModel()->selection(), newDeselected);
connect(selectionModel(), SIGNAL(selectionChanged(QItemSelection,QItemSelection)), this, SLOT(selectionChanged(QItemSelection,QItemSelection))); connect(selectionModel(), SIGNAL(selectionChanged(QItemSelection, QItemSelection)), this, SLOT(selectionChanged(QItemSelection, QItemSelection)));
connect(selectionModel(), SIGNAL(currentChanged(QModelIndex,QModelIndex)), this, SLOT(currentChanged(QModelIndex,QModelIndex))); connect(selectionModel(), SIGNAL(currentChanged(QModelIndex, QModelIndex)), this, SLOT(currentChanged(QModelIndex, QModelIndex)));
// now that everything is up to date, update the widgets // now that everything is up to date, update the widgets
Q_EMIT currentDiveChanged(selected_dive); Q_EMIT currentDiveChanged(selected_dive);
} }
@ -498,7 +490,7 @@ static bool can_merge(const struct dive *a, const struct dive *b)
if (a->when > b->when) if (a->when > b->when)
return false; return false;
/* Don't merge dives if there's more than half an hour between them */ /* Don't merge dives if there's more than half an hour between them */
if (a->when + a->duration.seconds + 30*60 < b->when) if (a->when + a->duration.seconds + 30 * 60 < b->when)
return false; return false;
return true; return true;
} }
@ -524,10 +516,10 @@ void DiveListView::mergeDives()
void DiveListView::merge_trip(const QModelIndex &a, int offset) void DiveListView::merge_trip(const QModelIndex &a, int offset)
{ {
int i = a.row() + offset; int i = a.row() + offset;
QModelIndex b = a.sibling(i,0); QModelIndex b = a.sibling(i, 0);
dive_trip_t *trip_a = (dive_trip_t *) a.data(DiveTripModel::TRIP_ROLE).value<void*>(); dive_trip_t *trip_a = (dive_trip_t *)a.data(DiveTripModel::TRIP_ROLE).value<void *>();
dive_trip_t *trip_b = (dive_trip_t *) b.data(DiveTripModel::TRIP_ROLE).value<void*>(); dive_trip_t *trip_b = (dive_trip_t *)b.data(DiveTripModel::TRIP_ROLE).value<void *>();
if (trip_a == trip_b || !trip_a || !trip_b) if (trip_a == trip_b || !trip_a || !trip_b)
return; return;
@ -574,7 +566,7 @@ void DiveListView::newTripAbove()
{ {
dive_trip_t *trip; dive_trip_t *trip;
int idx; int idx;
struct dive *d = (struct dive *) contextMenuIndex.data(DiveTripModel::DIVE_ROLE).value<void*>(); struct dive *d = (struct dive *)contextMenuIndex.data(DiveTripModel::DIVE_ROLE).value<void *>();
if (!d) // shouldn't happen as we only are setting up this action if this is a dive if (!d) // shouldn't happen as we only are setting up this action if this is a dive
return; return;
rememberSelection(); rememberSelection();
@ -595,7 +587,7 @@ void DiveListView::addToTripAbove()
int idx, delta = (currentOrder == Qt::AscendingOrder) ? -1 : +1; int idx, delta = (currentOrder == Qt::AscendingOrder) ? -1 : +1;
dive_trip_t *trip = NULL; dive_trip_t *trip = NULL;
struct dive *pd = NULL; struct dive *pd = NULL;
struct dive *d = (struct dive *) contextMenuIndex.data(DiveTripModel::DIVE_ROLE).value<void*>(); struct dive *d = (struct dive *)contextMenuIndex.data(DiveTripModel::DIVE_ROLE).value<void *>();
if (!d) // shouldn't happen as we only are setting up this action if this is a dive if (!d) // shouldn't happen as we only are setting up this action if this is a dive
return; return;
rememberSelection(); rememberSelection();
@ -638,10 +630,10 @@ void DiveListView::addToTripAbove()
void DiveListView::markDiveInvalid() void DiveListView::markDiveInvalid()
{ {
int i; int i;
struct dive *d = (struct dive *) contextMenuIndex.data(DiveTripModel::DIVE_ROLE).value<void*>(); struct dive *d = (struct dive *)contextMenuIndex.data(DiveTripModel::DIVE_ROLE).value<void *>();
if (!d) if (!d)
return; return;
for_each_dive (i, d) { for_each_dive(i, d) {
if (!d->selected) if (!d->selected)
continue; continue;
// now mark the dive invalid... how do we do THAT? // now mark the dive invalid... how do we do THAT?
@ -663,7 +655,7 @@ void DiveListView::markDiveInvalid()
void DiveListView::deleteDive() void DiveListView::deleteDive()
{ {
int i; int i;
struct dive *d = (struct dive *) contextMenuIndex.data(DiveTripModel::DIVE_ROLE).value<void*>(); struct dive *d = (struct dive *)contextMenuIndex.data(DiveTripModel::DIVE_ROLE).value<void *>();
if (!d) if (!d)
return; return;
// after a dive is deleted the ones following it move forward in the dive_table // after a dive is deleted the ones following it move forward in the dive_table
@ -693,12 +685,12 @@ void DiveListView::deleteDive()
void DiveListView::testSlot() void DiveListView::testSlot()
{ {
struct dive *d = (struct dive *) contextMenuIndex.data(DiveTripModel::DIVE_ROLE).value<void*>(); struct dive *d = (struct dive *)contextMenuIndex.data(DiveTripModel::DIVE_ROLE).value<void *>();
if (d) { if (d) {
qDebug("testSlot called on dive #%d", d->number); qDebug("testSlot called on dive #%d", d->number);
} else { } else {
QModelIndex child = contextMenuIndex.child(0, 0); QModelIndex child = contextMenuIndex.child(0, 0);
d = (struct dive *) child.data(DiveTripModel::DIVE_ROLE).value<void*>(); d = (struct dive *)child.data(DiveTripModel::DIVE_ROLE).value<void *>();
if (d) if (d)
qDebug("testSlot called on trip including dive #%d", d->number); qDebug("testSlot called on trip including dive #%d", d->number);
else else
@ -711,8 +703,8 @@ void DiveListView::contextMenuEvent(QContextMenuEvent *event)
QAction *collapseAction = NULL; QAction *collapseAction = NULL;
// let's remember where we are // let's remember where we are
contextMenuIndex = indexAt(event->pos()); contextMenuIndex = indexAt(event->pos());
struct dive *d = (struct dive *) contextMenuIndex.data(DiveTripModel::DIVE_ROLE).value<void*>(); struct dive *d = (struct dive *)contextMenuIndex.data(DiveTripModel::DIVE_ROLE).value<void *>();
dive_trip_t *trip = (dive_trip_t *) contextMenuIndex.data(DiveTripModel::TRIP_ROLE).value<void*>(); dive_trip_t *trip = (dive_trip_t *)contextMenuIndex.data(DiveTripModel::TRIP_ROLE).value<void *>();
QMenu popup(this); QMenu popup(this);
if (currentLayout == DiveTripModel::TREE) { if (currentLayout == DiveTripModel::TREE) {
popup.addAction(tr("expand all"), this, SLOT(expandAll())); popup.addAction(tr("expand all"), this, SLOT(expandAll()));
@ -746,7 +738,7 @@ void DiveListView::contextMenuEvent(QContextMenuEvent *event)
popup.addAction(tr("upload dive(s) to divelogs.de"), this, SLOT(uploadToDivelogsDE())); popup.addAction(tr("upload dive(s) to divelogs.de"), this, SLOT(uploadToDivelogsDE()));
// "collapse all" really closes all trips, // "collapse all" really closes all trips,
// "collapse" keeps the trip with the selected dive open // "collapse" keeps the trip with the selected dive open
QAction * actionTaken = popup.exec(event->globalPos()); QAction *actionTaken = popup.exec(event->globalPos());
if (actionTaken == collapseAction && collapseAction) { if (actionTaken == collapseAction && collapseAction) {
this->setAnimated(false); this->setAnimated(false);
selectDive(selected_dive, true); selectDive(selected_dive, true);
@ -776,7 +768,7 @@ void DiveListView::saveSelectedDivesAs()
// Keep last open dir // Keep last open dir
QFileInfo fileInfo(fileName); QFileInfo fileInfo(fileName);
settings.beginGroup("FileDialog"); settings.beginGroup("FileDialog");
settings.setValue("LastDir",fileInfo.dir().path()); settings.setValue("LastDir", fileInfo.dir().path());
settings.endGroup(); settings.endGroup();
QByteArray bt = QFile::encodeName(fileName); QByteArray bt = QFile::encodeName(fileName);
@ -821,7 +813,7 @@ void DiveListView::loadImages()
for (int i = 0; i < fileNames.size(); ++i) { for (int i = 0; i < fileNames.size(); ++i) {
if (readfile(fileNames.at(i).toUtf8().data(), &mem) <= 0) if (readfile(fileNames.at(i).toUtf8().data(), &mem) <= 0)
continue; continue;
retval = exif.parseFrom((const unsigned char *) mem.buffer, (unsigned) mem.size); retval = exif.parseFrom((const unsigned char *)mem.buffer, (unsigned)mem.size);
free(mem.buffer); free(mem.buffer);
if (retval != PARSE_EXIF_SUCCESS) if (retval != PARSE_EXIF_SUCCESS)
continue; continue;
@ -831,21 +823,21 @@ void DiveListView::loadImages()
imagetime += shiftDialog.amount(); imagetime += shiftDialog.amount();
int j = 0; int j = 0;
struct dive *dive; struct dive *dive;
for_each_dive(j, dive){ for_each_dive(j, dive) {
if (!dive->selected) if (!dive->selected)
continue; continue;
// FIXME: this adds the events only to the first DC // FIXME: this adds the events only to the first DC
if (dive->when - 3600 < imagetime && dive->when + dive->duration.seconds + 3600 > imagetime){ if (dive->when - 3600 < imagetime && dive->when + dive->duration.seconds + 3600 > imagetime) {
if (dive->when > imagetime) { if (dive->when > imagetime) {
// Before dive // Before dive
add_event(&(dive->dc), 0, 123, 0, 0, fileNames.at(i).toUtf8().data()); add_event(&(dive->dc), 0, 123, 0, 0, fileNames.at(i).toUtf8().data());
} else if (dive->when + dive->duration.seconds < imagetime){ } else if (dive->when + dive->duration.seconds < imagetime) {
// After dive // After dive
add_event(&(dive->dc), dive->duration.seconds, 123, 0, 0, fileNames.at(i).toUtf8().data()); add_event(&(dive->dc), dive->duration.seconds, 123, 0, 0, fileNames.at(i).toUtf8().data());
} else { } else {
add_event(&(dive->dc), imagetime - dive->when, 123, 0, 0, fileNames.at(i).toUtf8().data()); add_event(&(dive->dc), imagetime - dive->when, 123, 0, 0, fileNames.at(i).toUtf8().data());
} }
if (!dive->latitude.udeg && !IS_FP_SAME(exif.GeoLocation.Latitude, 0.0)){ if (!dive->latitude.udeg && !IS_FP_SAME(exif.GeoLocation.Latitude, 0.0)) {
dive->latitude.udeg = lrint(1000000.0 * exif.GeoLocation.Latitude); dive->latitude.udeg = lrint(1000000.0 * exif.GeoLocation.Latitude);
dive->longitude.udeg = lrint(1000000.0 * exif.GeoLocation.Longitude); dive->longitude.udeg = lrint(1000000.0 * exif.GeoLocation.Longitude);
} }
@ -873,7 +865,7 @@ QString DiveListView::lastUsedImageDir()
return lastImageDir; return lastImageDir;
} }
void DiveListView::updateLastUsedImageDir(const QString& dir) void DiveListView::updateLastUsedImageDir(const QString &dir)
{ {
QSettings s; QSettings s;
s.beginGroup("FileDialog"); s.beginGroup("FileDialog");

View file

@ -15,24 +15,24 @@
#include <QLineEdit> #include <QLineEdit>
#include "models.h" #include "models.h"
class DiveListView : public QTreeView class DiveListView : public QTreeView {
{
Q_OBJECT Q_OBJECT
public: public:
DiveListView(QWidget *parent = 0); DiveListView(QWidget *parent = 0);
~DiveListView(); ~DiveListView();
void selectionChanged(const QItemSelection& selected, const QItemSelection& deselected); void selectionChanged(const QItemSelection &selected, const QItemSelection &deselected);
void currentChanged(const QModelIndex& current, const QModelIndex& previous); void currentChanged(const QModelIndex &current, const QModelIndex &previous);
void reload(DiveTripModel::Layout layout, bool forceSort = true); void reload(DiveTripModel::Layout layout, bool forceSort = true);
bool eventFilter(QObject* , QEvent* ); bool eventFilter(QObject *, QEvent *);
void unselectDives(); void unselectDives();
void selectDive(int dive_table_idx, bool scrollto = false, bool toggle = false); void selectDive(int dive_table_idx, bool scrollto = false, bool toggle = false);
void selectDives(const QList<int>& newDiveSelection); void selectDives(const QList<int> &newDiveSelection);
void rememberSelection(); void rememberSelection();
void restoreSelection(); void restoreSelection();
void contextMenuEvent(QContextMenuEvent *event); void contextMenuEvent(QContextMenuEvent *event);
QList<dive_trip_t*> selectedTrips(); QList<dive_trip_t *> selectedTrips();
public slots: public
slots:
void toggleColumnVisibilityByIndex(); void toggleColumnVisibilityByIndex();
void reloadHeaderActions(); void reloadHeaderActions();
void headerClicked(int); void headerClicked(int);
@ -73,8 +73,8 @@ private:
void backupExpandedRows(); void backupExpandedRows();
void restoreExpandedRows(); void restoreExpandedRows();
int lastVisibleColumn(); int lastVisibleColumn();
void selectTrip ( dive_trip_t* trip ); void selectTrip(dive_trip_t *trip);
void updateLastUsedImageDir(const QString& s); void updateLastUsedImageDir(const QString &s);
void updateLastImageTimeOffset(int offset); void updateLastImageTimeOffset(int offset);
int lastImageTimeOffset(); int lastImageTimeOffset();
}; };

View file

@ -5,15 +5,14 @@
#include "ui_divelogimportdialog.h" #include "ui_divelogimportdialog.h"
const DiveLogImportDialog::CSVAppConfig DiveLogImportDialog::CSVApps[CSVAPPS] = { const DiveLogImportDialog::CSVAppConfig DiveLogImportDialog::CSVApps[CSVAPPS] = {
{"", }, { "", },
{"APD Log Viewer", 1, 2, 16, 7, 18, 19, "Tab"}, { "APD Log Viewer", 1, 2, 16, 7, 18, 19, "Tab" },
{"XP5", 1, 2, 10, -1, -1, -1, "Tab"}, { "XP5", 1, 2, 10, -1, -1, -1, "Tab" },
{"SensusCSV", 10, 11, -1, -1, -1, -1, ","}, { "SensusCSV", 10, 11, -1, -1, -1, -1, "," },
{NULL,} { NULL, }
}; };
DiveLogImportDialog::DiveLogImportDialog(QStringList *fn, QWidget *parent) : DiveLogImportDialog::DiveLogImportDialog(QStringList *fn, QWidget *parent) : QDialog(parent),
QDialog(parent),
selector(true), selector(true),
ui(new Ui::DiveLogImportDialog) ui(new Ui::DiveLogImportDialog)
{ {
@ -52,7 +51,7 @@ DiveLogImportDialog::~DiveLogImportDialog()
delete ui; delete ui;
} }
#define VALUE_IF_CHECKED(x) (ui->x->isEnabled() ? ui->x->value() - 1: -1) #define VALUE_IF_CHECKED(x) (ui->x->isEnabled() ? ui->x->value() - 1 : -1)
void DiveLogImportDialog::on_buttonBox_accepted() void DiveLogImportDialog::on_buttonBox_accepted()
{ {
char *error = NULL; char *error = NULL;
@ -60,14 +59,14 @@ void DiveLogImportDialog::on_buttonBox_accepted()
if (ui->tabWidget->currentIndex() == 0) { if (ui->tabWidget->currentIndex() == 0) {
for (int i = 0; i < fileNames.size(); ++i) { for (int i = 0; i < fileNames.size(); ++i) {
parse_csv_file(fileNames[i].toUtf8().data(), ui->CSVTime->value() - 1, parse_csv_file(fileNames[i].toUtf8().data(), ui->CSVTime->value() - 1,
ui->CSVDepth->value() - 1, VALUE_IF_CHECKED(CSVTemperature), ui->CSVDepth->value() - 1, VALUE_IF_CHECKED(CSVTemperature),
VALUE_IF_CHECKED(CSVpo2), VALUE_IF_CHECKED(CSVpo2),
VALUE_IF_CHECKED(CSVcns), VALUE_IF_CHECKED(CSVcns),
VALUE_IF_CHECKED(CSVstopdepth), VALUE_IF_CHECKED(CSVstopdepth),
ui->CSVSeparator->currentIndex(), ui->CSVSeparator->currentIndex(),
specialCSV.contains(ui->knownImports->currentIndex()) ? CSVApps[ui->knownImports->currentIndex()].name.toUtf8().data() : "csv", specialCSV.contains(ui->knownImports->currentIndex()) ? CSVApps[ui->knownImports->currentIndex()].name.toUtf8().data() : "csv",
ui->CSVUnits->currentIndex(), ui->CSVUnits->currentIndex(),
&error); &error);
if (error != NULL) { if (error != NULL) {
MainWindow::instance()->showError(error); MainWindow::instance()->showError(error);
free(error); free(error);
@ -77,16 +76,16 @@ void DiveLogImportDialog::on_buttonBox_accepted()
} else { } else {
for (int i = 0; i < fileNames.size(); ++i) { for (int i = 0; i < fileNames.size(); ++i) {
parse_manual_file(fileNames[i].toUtf8().data(), parse_manual_file(fileNames[i].toUtf8().data(),
ui->ManualSeparator->currentIndex(), ui->ManualSeparator->currentIndex(),
ui->Units->currentIndex(), ui->Units->currentIndex(),
VALUE_IF_CHECKED(DiveNumber), VALUE_IF_CHECKED(DiveNumber),
VALUE_IF_CHECKED(Date), VALUE_IF_CHECKED(Time), VALUE_IF_CHECKED(Date), VALUE_IF_CHECKED(Time),
VALUE_IF_CHECKED(Duration), VALUE_IF_CHECKED(Location), VALUE_IF_CHECKED(Duration), VALUE_IF_CHECKED(Location),
VALUE_IF_CHECKED(Gps), VALUE_IF_CHECKED(MaxDepth), VALUE_IF_CHECKED(Gps), VALUE_IF_CHECKED(MaxDepth),
VALUE_IF_CHECKED(MeanDepth), VALUE_IF_CHECKED(Buddy), VALUE_IF_CHECKED(MeanDepth), VALUE_IF_CHECKED(Buddy),
VALUE_IF_CHECKED(Notes), VALUE_IF_CHECKED(Weight), VALUE_IF_CHECKED(Notes), VALUE_IF_CHECKED(Weight),
VALUE_IF_CHECKED(Tags), VALUE_IF_CHECKED(Tags),
&error); &error);
if (error != NULL) { if (error != NULL) {
MainWindow::instance()->showError(error); MainWindow::instance()->showError(error);
free(error); free(error);
@ -104,8 +103,8 @@ void DiveLogImportDialog::on_buttonBox_accepted()
ui->CSV->setValue(VAL);\ ui->CSV->setValue(VAL);\
ui->CSV->setEnabled(VAL >= 0);\ ui->CSV->setEnabled(VAL >= 0);\
ui->BOX->setChecked(VAL >= 0);\ ui->BOX->setChecked(VAL >= 0);\
ui->CSV->blockSignals(false);\ ui->CSV->blockSignals(false); \
}) })
void DiveLogImportDialog::on_knownImports_currentIndexChanged(int index) void DiveLogImportDialog::on_knownImports_currentIndexChanged(int index)
{ {
if (specialCSV.contains(index)) { if (specialCSV.contains(index)) {

View file

@ -6,19 +6,20 @@
#include "../dive.h" #include "../dive.h"
#include "../divelist.h" #include "../divelist.h"
namespace Ui { namespace Ui
class DiveLogImportDialog; {
class DiveLogImportDialog;
} }
class DiveLogImportDialog : public QDialog class DiveLogImportDialog : public QDialog {
{
Q_OBJECT Q_OBJECT
public: public:
explicit DiveLogImportDialog(QStringList *fn, QWidget *parent = 0); explicit DiveLogImportDialog(QStringList *fn, QWidget *parent = 0);
~DiveLogImportDialog(); ~DiveLogImportDialog();
private slots: private
slots:
void on_buttonBox_accepted(); void on_buttonBox_accepted();
void on_knownImports_currentIndexChanged(int index); void on_knownImports_currentIndexChanged(int index);
void unknownImports(); void unknownImports();

File diff suppressed because it is too large Load diff

View file

@ -12,19 +12,30 @@
class QListView; class QListView;
class QModelIndex; class QModelIndex;
class DivePlannerPointsModel : public QAbstractTableModel{ class DivePlannerPointsModel : public QAbstractTableModel {
Q_OBJECT Q_OBJECT
public: public:
static DivePlannerPointsModel* instance(); static DivePlannerPointsModel *instance();
enum Sections{REMOVE, DEPTH, DURATION, GAS, CCSETPOINT, COLUMNS}; enum Sections {
enum Mode { NOTHING, PLAN, ADD }; REMOVE,
virtual int columnCount(const QModelIndex& parent = QModelIndex()) const; DEPTH,
virtual QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const; DURATION,
virtual int rowCount(const QModelIndex& parent = QModelIndex()) const; GAS,
CCSETPOINT,
COLUMNS
};
enum Mode {
NOTHING,
PLAN,
ADD
};
virtual int columnCount(const QModelIndex &parent = QModelIndex()) const;
virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const;
virtual int rowCount(const QModelIndex &parent = QModelIndex()) const;
virtual QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const; virtual QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const;
virtual bool setData(const QModelIndex& index, const QVariant& value, int role = Qt::EditRole); virtual bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole);
virtual Qt::ItemFlags flags(const QModelIndex& index) const; virtual Qt::ItemFlags flags(const QModelIndex &index) const;
void removeSelectedPoints(const QVector<int>& rows); void removeSelectedPoints(const QVector<int> &rows);
void setPlanMode(Mode mode); void setPlanMode(Mode mode);
bool isPlanner(); bool isPlanner();
void createSimpleDive(); void createSimpleDive();
@ -37,35 +48,37 @@ public:
/** /**
* @return the row number. * @return the row number.
*/ */
void editStop(int row, divedatapoint newData ); void editStop(int row, divedatapoint newData);
divedatapoint at(int row); divedatapoint at(int row);
int size(); int size();
struct diveplan getDiveplan(); struct diveplan getDiveplan();
QStringList &getGasList(); QStringList &getGasList();
QVector<QPair<int, int> > collectGases(dive *d); QVector<QPair<int, int> > collectGases(dive *d);
public slots: public
int addStop(int millimeters = 0, int seconds = 0, int o2 = 0, int he = 0, int ccpoint = 0 ); slots:
int addStop(int millimeters = 0, int seconds = 0, int o2 = 0, int he = 0, int ccpoint = 0);
void addCylinder_clicked(); void addCylinder_clicked();
void setGFHigh(const int gfhigh); void setGFHigh(const int gfhigh);
void setGFLow(const int ghflow); void setGFLow(const int ghflow);
void setSurfacePressure(int pressure); void setSurfacePressure(int pressure);
void setBottomSac(int sac); void setBottomSac(int sac);
void setDecoSac(int sac); void setDecoSac(int sac);
void setStartTime(const QTime& t); void setStartTime(const QTime &t);
void setLastStop6m(bool value); void setLastStop6m(bool value);
void createPlan(); void createPlan();
void remove(const QModelIndex& index); void remove(const QModelIndex &index);
void cancelPlan(); void cancelPlan();
void createTemporaryPlan(); void createTemporaryPlan();
void deleteTemporaryPlan(); void deleteTemporaryPlan();
void loadFromDive(dive* d); void loadFromDive(dive *d);
void restoreBackupDive(); void restoreBackupDive();
signals: signals:
void planCreated(); void planCreated();
void planCanceled(); void planCanceled();
private: private:
explicit DivePlannerPointsModel(QObject* parent = 0); explicit DivePlannerPointsModel(QObject *parent = 0);
bool addGas(int o2, int he); bool addGas(int o2, int he);
struct diveplan diveplan; struct diveplan diveplan;
Mode mode; Mode mode;
@ -81,13 +94,15 @@ private:
class Button : public QObject, public QGraphicsRectItem { class Button : public QObject, public QGraphicsRectItem {
Q_OBJECT Q_OBJECT
public: public:
Button(QObject* parent = 0, QGraphicsItem *itemParent = 0); Button(QObject *parent = 0, QGraphicsItem *itemParent = 0);
void setText(const QString& text); void setText(const QString &text);
void setPixmap(const QPixmap& pixmap); void setPixmap(const QPixmap &pixmap);
protected: protected:
virtual void mousePressEvent(QGraphicsSceneMouseEvent* event); virtual void mousePressEvent(QGraphicsSceneMouseEvent *event);
signals: signals:
void clicked(); void clicked();
private: private:
QGraphicsPixmapItem *icon; QGraphicsPixmapItem *icon;
QGraphicsSimpleTextItem *text; QGraphicsSimpleTextItem *text;
@ -101,27 +116,31 @@ public:
QGraphicsPixmapItem *icon; QGraphicsPixmapItem *icon;
Button *increaseBtn; Button *increaseBtn;
Button *decreaseBtn; Button *decreaseBtn;
private: private:
QGraphicsPixmapItem *bg; QGraphicsPixmapItem *bg;
QGraphicsPixmapItem *leftWing; QGraphicsPixmapItem *leftWing;
QGraphicsPixmapItem *rightWing; QGraphicsPixmapItem *rightWing;
}; };
class DiveHandler : public QObject, public QGraphicsEllipseItem{ class DiveHandler : public QObject, public QGraphicsEllipseItem {
Q_OBJECT Q_OBJECT
public: public:
DiveHandler(); DiveHandler();
protected: protected:
void mousePressEvent(QGraphicsSceneMouseEvent* event); void mousePressEvent(QGraphicsSceneMouseEvent *event);
void contextMenuEvent(QGraphicsSceneContextMenuEvent* event); void contextMenuEvent(QGraphicsSceneContextMenuEvent *event);
private: private:
int parentIndex(); int parentIndex();
public slots: public
slots:
void selfRemove(); void selfRemove();
void changeGas(); void changeGas();
}; };
class Ruler : public QGraphicsLineItem{ class Ruler : public QGraphicsLineItem {
public: public:
Ruler(); Ruler();
~Ruler(); ~Ruler();
@ -133,19 +152,19 @@ public:
void updateTicks(); void updateTicks();
double minimum() const; double minimum() const;
double maximum() const; double maximum() const;
qreal valueAt(const QPointF& p); qreal valueAt(const QPointF &p);
qreal percentAt(const QPointF& p); qreal percentAt(const QPointF &p);
qreal posAtValue(qreal value); qreal posAtValue(qreal value);
void setColor(const QColor& color); void setColor(const QColor &color);
void setTextColor(const QColor& color); void setTextColor(const QColor &color);
int unitSystem; int unitSystem;
private: private:
void eraseAll(); void eraseAll();
Qt::Orientation orientation; Qt::Orientation orientation;
QList<QGraphicsLineItem*> ticks; QList<QGraphicsLineItem *> ticks;
QList<QGraphicsSimpleTextItem*> labels; QList<QGraphicsSimpleTextItem *> labels;
double min; double min;
double max; double max;
double interval; double interval;
@ -156,19 +175,22 @@ private:
class DivePlannerGraphics : public QGraphicsView { class DivePlannerGraphics : public QGraphicsView {
Q_OBJECT Q_OBJECT
public: public:
DivePlannerGraphics(QWidget* parent = 0); DivePlannerGraphics(QWidget *parent = 0);
protected: protected:
virtual void mouseDoubleClickEvent(QMouseEvent* event); virtual void mouseDoubleClickEvent(QMouseEvent *event);
virtual void showEvent(QShowEvent* event); virtual void showEvent(QShowEvent *event);
virtual void resizeEvent(QResizeEvent* event); virtual void resizeEvent(QResizeEvent *event);
virtual void mouseMoveEvent(QMouseEvent* event); virtual void mouseMoveEvent(QMouseEvent *event);
virtual void mousePressEvent(QMouseEvent* event); virtual void mousePressEvent(QMouseEvent *event);
virtual void mouseReleaseEvent(QMouseEvent* event); virtual void mouseReleaseEvent(QMouseEvent *event);
bool isPointOutOfBoundaries(const QPointF& point); bool isPointOutOfBoundaries(const QPointF &point);
qreal fromPercent(qreal percent, Qt::Orientation orientation); qreal fromPercent(qreal percent, Qt::Orientation orientation);
public slots: public
slots:
void settingsChanged(); void settingsChanged();
private slots: private
slots:
void keyEscAction(); void keyEscAction();
void keyDeleteAction(); void keyDeleteAction();
void keyUpAction(); void keyUpAction();
@ -180,17 +202,18 @@ private slots:
void decreaseTime(); void decreaseTime();
void decreaseDepth(); void decreaseDepth();
void drawProfile(); void drawProfile();
void pointInserted(const QModelIndex&, int start, int end); void pointInserted(const QModelIndex &, int start, int end);
void pointsRemoved(const QModelIndex&, int start, int end); void pointsRemoved(const QModelIndex &, int start, int end);
private: private:
void moveActiveHandler(const QPointF& MappedPos, const int pos); void moveActiveHandler(const QPointF &MappedPos, const int pos);
/* This are the lines of the plotted dive. */ /* This are the lines of the plotted dive. */
QList<QGraphicsLineItem*> lines; QList<QGraphicsLineItem *> lines;
/* This is the user-entered handles. */ /* This is the user-entered handles. */
QList<DiveHandler *> handles; QList<DiveHandler *> handles;
QList<QGraphicsSimpleTextItem*> gases; QList<QGraphicsSimpleTextItem *> gases;
/* those are the lines that follows the mouse. */ /* those are the lines that follows the mouse. */
QGraphicsLineItem *verticalLine; QGraphicsLineItem *verticalLine;
@ -219,8 +242,8 @@ private:
ExpanderGraphics *timeHandler; ExpanderGraphics *timeHandler;
int minMinutes; // this holds the minimum requested window time int minMinutes; // this holds the minimum requested window time
int minDepth; // this holds the minimum requested window depth int minDepth; // this holds the minimum requested window depth
int dpMaxTime; // this is the time of the dive calculated by the deco. int dpMaxTime; // this is the time of the dive calculated by the deco.
friend class DiveHandler; friend class DiveHandler;
}; };
@ -230,13 +253,15 @@ private:
class DivePlannerWidget : public QWidget { class DivePlannerWidget : public QWidget {
Q_OBJECT Q_OBJECT
public: public:
explicit DivePlannerWidget(QWidget* parent = 0, Qt::WindowFlags f = 0); explicit DivePlannerWidget(QWidget *parent = 0, Qt::WindowFlags f = 0);
public slots: public
slots:
void settingsChanged(); void settingsChanged();
void atmPressureChanged(const QString& pressure); void atmPressureChanged(const QString &pressure);
void bottomSacChanged(const QString& bottomSac); void bottomSacChanged(const QString &bottomSac);
void decoSacChanged(const QString& decosac); void decoSacChanged(const QString &decosac);
private: private:
Ui::DivePlanner ui; Ui::DivePlanner ui;
}; };

View file

@ -32,11 +32,12 @@ struct mydescriptor {
unsigned int model; unsigned int model;
}; };
namespace DownloadFromDcGlobal { namespace DownloadFromDcGlobal
{
const char *err_string; const char *err_string;
}; };
DownloadFromDCWidget::DownloadFromDCWidget(QWidget* parent, Qt::WindowFlags f) : QDialog(parent, f), DownloadFromDCWidget::DownloadFromDCWidget(QWidget *parent, Qt::WindowFlags f) : QDialog(parent, f),
thread(0), thread(0),
downloading(false), downloading(false),
previousLast(0), previousLast(0),
@ -87,7 +88,7 @@ void DownloadFromDCWidget::updateProgressBar()
ui.progressBar->setFormat(progress_bar_text); ui.progressBar->setFormat(progress_bar_text);
} else { } else {
ui.progressBar->setFormat("%p%"); ui.progressBar->setFormat("%p%");
ui.progressBar->setValue(progress_bar_fraction *100); ui.progressBar->setValue(progress_bar_fraction * 100);
} }
} }
@ -111,8 +112,7 @@ void DownloadFromDCWidget::updateState(states state)
// user pressed cancel but the application isn't doing anything. // user pressed cancel but the application isn't doing anything.
// means close the window // means close the window
else if ((currentState == INITIAL || currentState == CANCELLED || currentState == DONE || currentState == ERROR) else if ((currentState == INITIAL || currentState == CANCELLED || currentState == DONE || currentState == ERROR) && state == CANCELLING) {
&& state == CANCELLING) {
timer->stop(); timer->stop();
reject(); reject();
ui.ok->setText(tr("OK")); ui.ok->setText(tr("OK"));
@ -168,7 +168,7 @@ void DownloadFromDCWidget::updateState(states state)
currentState = state; currentState = state;
} }
void DownloadFromDCWidget::on_vendor_currentIndexChanged(const QString& vendor) void DownloadFromDCWidget::on_vendor_currentIndexChanged(const QString &vendor)
{ {
QAbstractItemModel *currentModel = ui.product->model(); QAbstractItemModel *currentModel = ui.product->model();
if (!currentModel) if (!currentModel)
@ -205,7 +205,7 @@ void DownloadFromDCWidget::fill_computer_list()
QStringList computer; QStringList computer;
dc_descriptor_iterator(&iterator); dc_descriptor_iterator(&iterator);
while (dc_iterator_next (iterator, &descriptor) == DC_STATUS_SUCCESS) { while (dc_iterator_next(iterator, &descriptor) == DC_STATUS_SUCCESS) {
const char *vendor = dc_descriptor_get_vendor(descriptor); const char *vendor = dc_descriptor_get_vendor(descriptor);
const char *product = dc_descriptor_get_product(descriptor); const char *product = dc_descriptor_get_product(descriptor);
@ -225,7 +225,7 @@ void DownloadFromDCWidget::fill_computer_list()
this WILL BREAK if libdivecomputer changes the dc_descriptor struct... this WILL BREAK if libdivecomputer changes the dc_descriptor struct...
eventually the UEMIS code needs to move into libdivecomputer, I guess */ eventually the UEMIS code needs to move into libdivecomputer, I guess */
mydescriptor = (struct mydescriptor*) malloc(sizeof(struct mydescriptor)); mydescriptor = (struct mydescriptor *)malloc(sizeof(struct mydescriptor));
mydescriptor->vendor = "Uemis"; mydescriptor->vendor = "Uemis";
mydescriptor->product = "Zurich"; mydescriptor->product = "Zurich";
mydescriptor->type = DC_FAMILY_NULL; mydescriptor->type = DC_FAMILY_NULL;
@ -246,9 +246,9 @@ void DownloadFromDCWidget::on_search_clicked()
{ {
if (ui.vendor->currentText() == "Uemis") { if (ui.vendor->currentText() == "Uemis") {
QString dirName = QFileDialog::getExistingDirectory(this, QString dirName = QFileDialog::getExistingDirectory(this,
tr("Find Uemis dive computer"), tr("Find Uemis dive computer"),
QDir::homePath(), QDir::homePath(),
QFileDialog::ShowDirsOnly); QFileDialog::ShowDirsOnly);
qDebug() << dirName; qDebug() << dirName;
if (ui.device->findText(dirName) == -1) if (ui.device->findText(dirName) == -1)
ui.device->addItem(dirName); ui.device->addItem(dirName);
@ -284,7 +284,7 @@ void DownloadFromDCWidget::on_ok_clicked()
thread = new DownloadThread(this, &data); thread = new DownloadThread(this, &data);
connect(thread, SIGNAL(finished()), connect(thread, SIGNAL(finished()),
this, SLOT(onDownloadThreadFinished()), Qt::QueuedConnection); this, SLOT(onDownloadThreadFinished()), Qt::QueuedConnection);
MainWindow *w = MainWindow::instance(); MainWindow *w = MainWindow::instance();
connect(thread, SIGNAL(finished()), w, SLOT(refreshDisplay())); connect(thread, SIGNAL(finished()), w, SLOT(refreshDisplay()));
@ -311,7 +311,7 @@ void DownloadFromDCWidget::checkLogFile(int state)
void DownloadFromDCWidget::pickLogFile() void DownloadFromDCWidget::pickLogFile()
{ {
QString filename = existing_filename ? : prefs.default_filename; QString filename = existing_filename ?: prefs.default_filename;
QFileInfo fi(filename); QFileInfo fi(filename);
filename = fi.absolutePath().append(QDir::separator()).append("subsurface.log"); filename = fi.absolutePath().append(QDir::separator()).append("subsurface.log");
logFile = QFileDialog::getSaveFileName(this, tr("Choose file for divecomputer download logfile"), logFile = QFileDialog::getSaveFileName(this, tr("Choose file for divecomputer download logfile"),
@ -340,7 +340,7 @@ void DownloadFromDCWidget::checkDumpFile(int state)
void DownloadFromDCWidget::pickDumpFile() void DownloadFromDCWidget::pickDumpFile()
{ {
QString filename = existing_filename ? : prefs.default_filename; QString filename = existing_filename ?: prefs.default_filename;
QFileInfo fi(filename); QFileInfo fi(filename);
filename = fi.absolutePath().append(QDir::separator()).append("subsurface.bin"); filename = fi.absolutePath().append(QDir::separator()).append("subsurface.bin");
dumpFile = QFileDialog::getSaveFileName(this, tr("Choose file for divecomputer binary dump file"), dumpFile = QFileDialog::getSaveFileName(this, tr("Choose file for divecomputer binary dump file"),
@ -429,7 +429,7 @@ void DownloadFromDCWidget::fill_device_list()
ui.device->setCurrentIndex(deviceIndex); ui.device->setCurrentIndex(deviceIndex);
} }
DownloadThread::DownloadThread(QObject* parent, device_data_t* data): QThread(parent), DownloadThread::DownloadThread(QObject *parent, device_data_t *data) : QThread(parent),
data(data) data(data)
{ {
} }
@ -438,7 +438,7 @@ static QString str_error(const char *fmt, ...)
{ {
va_list args; va_list args;
va_start(args, fmt); va_start(args, fmt);
const QString str = QString().vsprintf( fmt, args ); const QString str = QString().vsprintf(fmt, args);
va_end(args); va_end(args);
return str; return str;
@ -453,5 +453,5 @@ void DownloadThread::run()
else else
errorText = do_libdivecomputer_import(data); errorText = do_libdivecomputer_import(data);
if (errorText) if (errorText)
error = str_error(errorText, data->devname, data->vendor, data->product); error = str_error(errorText, data->devname, data->vendor, data->product);
} }

View file

@ -9,21 +9,22 @@
#include "../libdivecomputer.h" #include "../libdivecomputer.h"
#include "ui_downloadfromdivecomputer.h" #include "ui_downloadfromdivecomputer.h"
class DownloadThread : public QThread{ class DownloadThread : public QThread {
Q_OBJECT Q_OBJECT
public: public:
DownloadThread(QObject* parent, device_data_t* data); DownloadThread(QObject *parent, device_data_t *data);
virtual void run(); virtual void run();
QString error; QString error;
private: private:
device_data_t *data; device_data_t *data;
}; };
class DownloadFromDCWidget : public QDialog{ class DownloadFromDCWidget : public QDialog {
Q_OBJECT Q_OBJECT
public: public:
explicit DownloadFromDCWidget(QWidget* parent = 0, Qt::WindowFlags f = 0); explicit DownloadFromDCWidget(QWidget *parent = 0, Qt::WindowFlags f = 0);
void reject(); void reject();
enum states { enum states {
@ -35,11 +36,12 @@ public:
DONE, DONE,
}; };
public slots: public
slots:
void on_ok_clicked(); void on_ok_clicked();
void on_cancel_clicked(); void on_cancel_clicked();
void on_search_clicked(); void on_search_clicked();
void on_vendor_currentIndexChanged(const QString& vendor); void on_vendor_currentIndexChanged(const QString &vendor);
void on_product_currentIndexChanged(); void on_product_currentIndexChanged();
void onDownloadThreadFinished(); void onDownloadThreadFinished();
@ -76,7 +78,6 @@ public:
bool preferDownloaded(); bool preferDownloaded();
void updateState(states state); void updateState(states state);
states currentState; states currentState;
}; };
#endif // DOWNLOADFROMDIVECOMPUTER_H #endif // DOWNLOADFROMDIVECOMPUTER_H

View file

@ -34,158 +34,166 @@
using std::string; using std::string;
namespace { namespace
// IF Entry {
struct IFEntry { // IF Entry
// Raw fields struct IFEntry {
unsigned short tag; // Raw fields
unsigned short format; unsigned short tag;
unsigned data; unsigned short format;
unsigned length; unsigned data;
unsigned length;
// Parsed fields // Parsed fields
string val_string; string val_string;
unsigned short val_16; unsigned short val_16;
unsigned val_32; unsigned val_32;
double val_rational; double val_rational;
unsigned char val_byte; unsigned char val_byte;
}; };
// Helper functions // Helper functions
unsigned int parse32(const unsigned char *buf, bool intel) { unsigned int parse32(const unsigned char *buf, bool intel)
if (intel) {
return ((unsigned)buf[3]<<24) | if (intel)
((unsigned)buf[2]<<16) | return ((unsigned)buf[3] << 24) |
((unsigned)buf[1]<<8) | ((unsigned)buf[2] << 16) |
buf[0]; ((unsigned)buf[1] << 8) |
buf[0];
return ((unsigned)buf[0]<<24) | return ((unsigned)buf[0] << 24) |
((unsigned)buf[1]<<16) | ((unsigned)buf[1] << 16) |
((unsigned)buf[2]<<8) | ((unsigned)buf[2] << 8) |
buf[3]; buf[3];
} }
unsigned short parse16(const unsigned char *buf, bool intel) { unsigned short parse16(const unsigned char *buf, bool intel)
if (intel) {
return ((unsigned) buf[1]<<8) | buf[0]; if (intel)
return ((unsigned) buf[0]<<8) | buf[1]; return ((unsigned)buf[1] << 8) | buf[0];
} return ((unsigned)buf[0] << 8) | buf[1];
}
string parseEXIFString(const unsigned char *buf, string parseEXIFString(const unsigned char *buf,
const unsigned num_components, const unsigned num_components,
const unsigned data, const unsigned data,
const unsigned base, const unsigned base,
const unsigned len) { const unsigned len)
string value; {
if (num_components <= 4) string value;
value.assign( (const char*)&data, num_components ); if (num_components <= 4)
else { value.assign((const char *)&data, num_components);
if (base+data+num_components <= len) else {
value.assign( (const char*)(buf+base+data), num_components ); if (base + data + num_components <= len)
} value.assign((const char *)(buf + base + data), num_components);
return value; }
} return value;
}
double parseEXIFRational(const unsigned char *buf, bool intel) { double parseEXIFRational(const unsigned char *buf, bool intel)
double numerator = 0; {
double denominator = 1; double numerator = 0;
double denominator = 1;
numerator = (double) parse32(buf, intel); numerator = (double)parse32(buf, intel);
denominator= (double) parse32(buf+4, intel); denominator = (double)parse32(buf + 4, intel);
if(denominator < 1e-20) if (denominator < 1e-20)
return 0; return 0;
return numerator/denominator; return numerator / denominator;
} }
IFEntry parseIFEntry(const unsigned char *buf, IFEntry parseIFEntry(const unsigned char *buf,
const unsigned offs, const unsigned offs,
const bool alignIntel, const bool alignIntel,
const unsigned base, const unsigned base,
const unsigned len) { const unsigned len)
IFEntry result; {
IFEntry result;
// Each directory entry is composed of: // Each directory entry is composed of:
// 2 bytes: tag number (data field) // 2 bytes: tag number (data field)
// 2 bytes: data format // 2 bytes: data format
// 4 bytes: number of components // 4 bytes: number of components
// 4 bytes: data value or offset to data value // 4 bytes: data value or offset to data value
result.tag = parse16(buf + offs, alignIntel); result.tag = parse16(buf + offs, alignIntel);
result.format = parse16(buf + offs + 2, alignIntel); result.format = parse16(buf + offs + 2, alignIntel);
result.length = parse32(buf + offs + 4, alignIntel); result.length = parse32(buf + offs + 4, alignIntel);
result.data = parse32(buf + offs + 8, alignIntel); result.data = parse32(buf + offs + 8, alignIntel);
// Parse value in specified format // Parse value in specified format
switch (result.format) { switch (result.format) {
case 1: case 1:
result.val_byte = (unsigned char) *(buf + offs + 8); result.val_byte = (unsigned char)*(buf + offs + 8);
break; break;
case 2: case 2:
result.val_string = parseEXIFString(buf, result.length, result.data, base, len); result.val_string = parseEXIFString(buf, result.length, result.data, base, len);
break; break;
case 3: case 3:
result.val_16 = parse16((const unsigned char *) buf + offs + 8, alignIntel); result.val_16 = parse16((const unsigned char *)buf + offs + 8, alignIntel);
break; break;
case 4: case 4:
result.val_32 = result.data; result.val_32 = result.data;
break; break;
case 5: case 5:
if (base + result.data + 8 <= len) if (base + result.data + 8 <= len)
result.val_rational = parseEXIFRational(buf + base + result.data, alignIntel); result.val_rational = parseEXIFRational(buf + base + result.data, alignIntel);
break; break;
case 7: case 7:
case 9: case 9:
case 10: case 10:
break; break;
default: default:
result.tag = 0xFF; result.tag = 0xFF;
} }
return result; return result;
} }
} }
// //
// Locates the EXIF segment and parses it using parseFromEXIFSegment // Locates the EXIF segment and parses it using parseFromEXIFSegment
// //
int EXIFInfo::parseFrom(const unsigned char *buf, unsigned len) { int EXIFInfo::parseFrom(const unsigned char *buf, unsigned len)
// Sanity check: all JPEG files start with 0xFFD8 and end with 0xFFD9 {
// This check also ensures that the user has supplied a correct value for len. // Sanity check: all JPEG files start with 0xFFD8 and end with 0xFFD9
if (!buf || len < 4) // This check also ensures that the user has supplied a correct value for len.
return PARSE_EXIF_ERROR_NO_EXIF; if (!buf || len < 4)
if (buf[0] != 0xFF || buf[1] != 0xD8) return PARSE_EXIF_ERROR_NO_EXIF;
return PARSE_EXIF_ERROR_NO_JPEG; if (buf[0] != 0xFF || buf[1] != 0xD8)
if (buf[len-2] != 0xFF || buf[len-1] != 0xD9) return PARSE_EXIF_ERROR_NO_JPEG;
return PARSE_EXIF_ERROR_NO_JPEG; if (buf[len - 2] != 0xFF || buf[len - 1] != 0xD9)
clear(); return PARSE_EXIF_ERROR_NO_JPEG;
clear();
// Scan for EXIF header (bytes 0xFF 0xE1) and do a sanity check by // Scan for EXIF header (bytes 0xFF 0xE1) and do a sanity check by
// looking for bytes "Exif\0\0". The marker length data is in Motorola // looking for bytes "Exif\0\0". The marker length data is in Motorola
// byte order, which results in the 'false' parameter to parse16(). // byte order, which results in the 'false' parameter to parse16().
// The marker has to contain at least the TIFF header, otherwise the // The marker has to contain at least the TIFF header, otherwise the
// EXIF data is corrupt. So the minimum length specified here has to be: // EXIF data is corrupt. So the minimum length specified here has to be:
// 2 bytes: section size // 2 bytes: section size
// 6 bytes: "Exif\0\0" string // 6 bytes: "Exif\0\0" string
// 2 bytes: TIFF header (either "II" or "MM" string) // 2 bytes: TIFF header (either "II" or "MM" string)
// 2 bytes: TIFF magic (short 0x2a00 in Motorola byte order) // 2 bytes: TIFF magic (short 0x2a00 in Motorola byte order)
// 4 bytes: Offset to first IFD // 4 bytes: Offset to first IFD
// ========= // =========
// 16 bytes // 16 bytes
unsigned offs = 0; // current offset into buffer unsigned offs = 0; // current offset into buffer
for (offs = 0; offs < len-1; offs++) for (offs = 0; offs < len - 1; offs++)
if (buf[offs] == 0xFF && buf[offs+1] == 0xE1) if (buf[offs] == 0xFF && buf[offs + 1] == 0xE1)
break; break;
if (offs + 4 > len) if (offs + 4 > len)
return PARSE_EXIF_ERROR_NO_EXIF; return PARSE_EXIF_ERROR_NO_EXIF;
offs += 2; offs += 2;
unsigned short section_length = parse16(buf + offs, false); unsigned short section_length = parse16(buf + offs, false);
if (offs + section_length > len || section_length < 16) if (offs + section_length > len || section_length < 16)
return PARSE_EXIF_ERROR_CORRUPT; return PARSE_EXIF_ERROR_CORRUPT;
offs += 2; offs += 2;
return parseFromEXIFSegment(buf + offs, len - offs); return parseFromEXIFSegment(buf + offs, len - offs);
} }
int EXIFInfo::parseFrom(const string &data) { int EXIFInfo::parseFrom(const string &data)
return parseFrom((const unsigned char *)data.data(), data.length()); {
return parseFrom((const unsigned char *)data.data(), data.length());
} }
// //
@ -194,366 +202,368 @@ int EXIFInfo::parseFrom(const string &data) {
// PARAM: 'buf' start of the EXIF TIFF, which must be the bytes "Exif\0\0". // PARAM: 'buf' start of the EXIF TIFF, which must be the bytes "Exif\0\0".
// PARAM: 'len' length of buffer // PARAM: 'len' length of buffer
// //
int EXIFInfo::parseFromEXIFSegment(const unsigned char *buf, unsigned len) { int EXIFInfo::parseFromEXIFSegment(const unsigned char *buf, unsigned len)
bool alignIntel = true; // byte alignment (defined in EXIF header) {
unsigned offs = 0; // current offset into buffer bool alignIntel = true; // byte alignment (defined in EXIF header)
if (!buf || len < 6) unsigned offs = 0; // current offset into buffer
return PARSE_EXIF_ERROR_NO_EXIF; if (!buf || len < 6)
return PARSE_EXIF_ERROR_NO_EXIF;
if (!std::equal(buf, buf+6, "Exif\0\0")) if (!std::equal(buf, buf + 6, "Exif\0\0"))
return PARSE_EXIF_ERROR_NO_EXIF; return PARSE_EXIF_ERROR_NO_EXIF;
offs += 6; offs += 6;
// Now parsing the TIFF header. The first two bytes are either "II" or // Now parsing the TIFF header. The first two bytes are either "II" or
// "MM" for Intel or Motorola byte alignment. Sanity check by parsing // "MM" for Intel or Motorola byte alignment. Sanity check by parsing
// the unsigned short that follows, making sure it equals 0x2a. The // the unsigned short that follows, making sure it equals 0x2a. The
// last 4 bytes are an offset into the first IFD, which are added to // last 4 bytes are an offset into the first IFD, which are added to
// the global offset counter. For this block, we expect the following // the global offset counter. For this block, we expect the following
// minimum size: // minimum size:
// 2 bytes: 'II' or 'MM' // 2 bytes: 'II' or 'MM'
// 2 bytes: 0x002a // 2 bytes: 0x002a
// 4 bytes: offset to first IDF // 4 bytes: offset to first IDF
// ----------------------------- // -----------------------------
// 8 bytes // 8 bytes
if (offs + 8 > len) if (offs + 8 > len)
return PARSE_EXIF_ERROR_CORRUPT; return PARSE_EXIF_ERROR_CORRUPT;
unsigned tiff_header_start = offs; unsigned tiff_header_start = offs;
if (buf[offs] == 'I' && buf[offs+1] == 'I') if (buf[offs] == 'I' && buf[offs + 1] == 'I')
alignIntel = true; alignIntel = true;
else { else {
if(buf[offs] == 'M' && buf[offs+1] == 'M') if (buf[offs] == 'M' && buf[offs + 1] == 'M')
alignIntel = false; alignIntel = false;
else else
return PARSE_EXIF_ERROR_UNKNOWN_BYTEALIGN; return PARSE_EXIF_ERROR_UNKNOWN_BYTEALIGN;
} }
this->ByteAlign = alignIntel; this->ByteAlign = alignIntel;
offs += 2; offs += 2;
if (0x2a != parse16(buf+offs, alignIntel)) if (0x2a != parse16(buf + offs, alignIntel))
return PARSE_EXIF_ERROR_CORRUPT; return PARSE_EXIF_ERROR_CORRUPT;
offs += 2; offs += 2;
unsigned first_ifd_offset = parse32(buf + offs, alignIntel); unsigned first_ifd_offset = parse32(buf + offs, alignIntel);
offs += first_ifd_offset - 4; offs += first_ifd_offset - 4;
if (offs >= len) if (offs >= len)
return PARSE_EXIF_ERROR_CORRUPT; return PARSE_EXIF_ERROR_CORRUPT;
// Now parsing the first Image File Directory (IFD0, for the main image). // Now parsing the first Image File Directory (IFD0, for the main image).
// An IFD consists of a variable number of 12-byte directory entries. The // An IFD consists of a variable number of 12-byte directory entries. The
// first two bytes of the IFD section contain the number of directory // first two bytes of the IFD section contain the number of directory
// entries in the section. The last 4 bytes of the IFD contain an offset // entries in the section. The last 4 bytes of the IFD contain an offset
// to the next IFD, which means this IFD must contain exactly 6 + 12 * num // to the next IFD, which means this IFD must contain exactly 6 + 12 * num
// bytes of data. // bytes of data.
if (offs + 2 > len) if (offs + 2 > len)
return PARSE_EXIF_ERROR_CORRUPT; return PARSE_EXIF_ERROR_CORRUPT;
int num_entries = parse16(buf + offs, alignIntel); int num_entries = parse16(buf + offs, alignIntel);
if (offs + 6 + 12 * num_entries > len) if (offs + 6 + 12 * num_entries > len)
return PARSE_EXIF_ERROR_CORRUPT; return PARSE_EXIF_ERROR_CORRUPT;
offs += 2; offs += 2;
unsigned exif_sub_ifd_offset = len; unsigned exif_sub_ifd_offset = len;
unsigned gps_sub_ifd_offset = len; unsigned gps_sub_ifd_offset = len;
while (--num_entries >= 0) { while (--num_entries >= 0) {
IFEntry result = parseIFEntry(buf, offs, alignIntel, tiff_header_start, len); IFEntry result = parseIFEntry(buf, offs, alignIntel, tiff_header_start, len);
offs += 12; offs += 12;
switch(result.tag) { switch (result.tag) {
case 0x102: case 0x102:
// Bits per sample // Bits per sample
if (result.format == 3) if (result.format == 3)
this->BitsPerSample = result.val_16; this->BitsPerSample = result.val_16;
break; break;
case 0x10E: case 0x10E:
// Image description // Image description
if (result.format == 2) if (result.format == 2)
this->ImageDescription = result.val_string; this->ImageDescription = result.val_string;
break; break;
case 0x10F: case 0x10F:
// Digicam make // Digicam make
if (result.format == 2) if (result.format == 2)
this->Make = result.val_string; this->Make = result.val_string;
break; break;
case 0x110: case 0x110:
// Digicam model // Digicam model
if (result.format == 2) if (result.format == 2)
this->Model = result.val_string; this->Model = result.val_string;
break; break;
case 0x112: case 0x112:
// Orientation of image // Orientation of image
if (result.format == 3) if (result.format == 3)
this->Orientation = result.val_16; this->Orientation = result.val_16;
break; break;
case 0x131: case 0x131:
// Software used for image // Software used for image
if (result.format == 2) if (result.format == 2)
this->Software = result.val_string; this->Software = result.val_string;
break; break;
case 0x132: case 0x132:
// EXIF/TIFF date/time of image modification // EXIF/TIFF date/time of image modification
if (result.format == 2) if (result.format == 2)
this->DateTime = result.val_string; this->DateTime = result.val_string;
break; break;
case 0x8298: case 0x8298:
// Copyright information // Copyright information
if (result.format == 2) if (result.format == 2)
this->Copyright = result.val_string; this->Copyright = result.val_string;
break; break;
case 0x8825: case 0x8825:
// GPS IFS offset // GPS IFS offset
gps_sub_ifd_offset = tiff_header_start + result.data; gps_sub_ifd_offset = tiff_header_start + result.data;
break; break;
case 0x8769: case 0x8769:
// EXIF SubIFD offset // EXIF SubIFD offset
exif_sub_ifd_offset = tiff_header_start + result.data; exif_sub_ifd_offset = tiff_header_start + result.data;
break; break;
} }
} }
// Jump to the EXIF SubIFD if it exists and parse all the information // Jump to the EXIF SubIFD if it exists and parse all the information
// there. Note that it's possible that the EXIF SubIFD doesn't exist. // there. Note that it's possible that the EXIF SubIFD doesn't exist.
// The EXIF SubIFD contains most of the interesting information that a // The EXIF SubIFD contains most of the interesting information that a
// typical user might want. // typical user might want.
if (exif_sub_ifd_offset + 4 <= len) { if (exif_sub_ifd_offset + 4 <= len) {
offs = exif_sub_ifd_offset; offs = exif_sub_ifd_offset;
int num_entries = parse16(buf + offs, alignIntel); int num_entries = parse16(buf + offs, alignIntel);
if (offs + 6 + 12 * num_entries > len) if (offs + 6 + 12 * num_entries > len)
return PARSE_EXIF_ERROR_CORRUPT; return PARSE_EXIF_ERROR_CORRUPT;
offs += 2; offs += 2;
while (--num_entries >= 0) { while (--num_entries >= 0) {
IFEntry result = parseIFEntry(buf, offs, alignIntel, tiff_header_start, len); IFEntry result = parseIFEntry(buf, offs, alignIntel, tiff_header_start, len);
switch(result.tag) { switch (result.tag) {
case 0x829a: case 0x829a:
// Exposure time in seconds // Exposure time in seconds
if (result.format == 5) if (result.format == 5)
this->ExposureTime = result.val_rational; this->ExposureTime = result.val_rational;
break; break;
case 0x829d: case 0x829d:
// FNumber // FNumber
if (result.format == 5) if (result.format == 5)
this->FNumber = result.val_rational; this->FNumber = result.val_rational;
break; break;
case 0x8827: case 0x8827:
// ISO Speed Rating // ISO Speed Rating
if (result.format == 3) if (result.format == 3)
this->ISOSpeedRatings = result.val_16; this->ISOSpeedRatings = result.val_16;
break; break;
case 0x9003: case 0x9003:
// Original date and time // Original date and time
if (result.format == 2) if (result.format == 2)
this->DateTimeOriginal = result.val_string; this->DateTimeOriginal = result.val_string;
break; break;
case 0x9004: case 0x9004:
// Digitization date and time // Digitization date and time
if (result.format == 2) if (result.format == 2)
this->DateTimeDigitized = result.val_string; this->DateTimeDigitized = result.val_string;
break; break;
case 0x9201: case 0x9201:
// Shutter speed value // Shutter speed value
if (result.format == 5) if (result.format == 5)
this->ShutterSpeedValue = result.val_rational; this->ShutterSpeedValue = result.val_rational;
break; break;
case 0x9204: case 0x9204:
// Exposure bias value // Exposure bias value
if (result.format == 5) if (result.format == 5)
this->ExposureBiasValue = result.val_rational; this->ExposureBiasValue = result.val_rational;
break; break;
case 0x9206: case 0x9206:
// Subject distance // Subject distance
if (result.format == 5) if (result.format == 5)
this->SubjectDistance = result.val_rational; this->SubjectDistance = result.val_rational;
break; break;
case 0x9209: case 0x9209:
// Flash used // Flash used
if (result.format == 3) if (result.format == 3)
this->Flash = result.data ? 1 : 0; this->Flash = result.data ? 1 : 0;
break; break;
case 0x920a: case 0x920a:
// Focal length // Focal length
if (result.format == 5) if (result.format == 5)
this->FocalLength = result.val_rational; this->FocalLength = result.val_rational;
break; break;
case 0x9207: case 0x9207:
// Metering mode // Metering mode
if (result.format == 3) if (result.format == 3)
this->MeteringMode = result.val_16; this->MeteringMode = result.val_16;
break; break;
case 0x9291: case 0x9291:
// Subsecond original time // Subsecond original time
if (result.format == 2) if (result.format == 2)
this->SubSecTimeOriginal = result.val_string; this->SubSecTimeOriginal = result.val_string;
break; break;
case 0xa002: case 0xa002:
// EXIF Image width // EXIF Image width
if (result.format == 4) if (result.format == 4)
this->ImageWidth = result.val_32; this->ImageWidth = result.val_32;
if (result.format == 3) if (result.format == 3)
this->ImageWidth = result.val_16; this->ImageWidth = result.val_16;
break; break;
case 0xa003: case 0xa003:
// EXIF Image height // EXIF Image height
if (result.format == 4) if (result.format == 4)
this->ImageHeight = result.val_32; this->ImageHeight = result.val_32;
if (result.format == 3) if (result.format == 3)
this->ImageHeight = result.val_16; this->ImageHeight = result.val_16;
break; break;
case 0xa405: case 0xa405:
// Focal length in 35mm film // Focal length in 35mm film
if (result.format == 3) if (result.format == 3)
this->FocalLengthIn35mm = result.val_16; this->FocalLengthIn35mm = result.val_16;
break; break;
} }
offs += 12; offs += 12;
} }
} }
// Jump to the GPS SubIFD if it exists and parse all the information // Jump to the GPS SubIFD if it exists and parse all the information
// there. Note that it's possible that the GPS SubIFD doesn't exist. // there. Note that it's possible that the GPS SubIFD doesn't exist.
if (gps_sub_ifd_offset + 4 <= len) { if (gps_sub_ifd_offset + 4 <= len) {
offs = gps_sub_ifd_offset; offs = gps_sub_ifd_offset;
int num_entries = parse16(buf + offs, alignIntel); int num_entries = parse16(buf + offs, alignIntel);
if (offs + 6 + 12 * num_entries > len) if (offs + 6 + 12 * num_entries > len)
return PARSE_EXIF_ERROR_CORRUPT; return PARSE_EXIF_ERROR_CORRUPT;
offs += 2; offs += 2;
while (--num_entries >= 0) { while (--num_entries >= 0) {
unsigned short tag = parse16(buf + offs, alignIntel); unsigned short tag = parse16(buf + offs, alignIntel);
unsigned short format = parse16(buf + offs + 2, alignIntel); unsigned short format = parse16(buf + offs + 2, alignIntel);
unsigned length = parse32(buf + offs + 4, alignIntel); unsigned length = parse32(buf + offs + 4, alignIntel);
unsigned data = parse32(buf + offs + 8, alignIntel); unsigned data = parse32(buf + offs + 8, alignIntel);
switch(tag) { switch (tag) {
case 1: case 1:
// GPS north or south // GPS north or south
this->GeoLocation.LatComponents.direction = *(buf + offs + 8); this->GeoLocation.LatComponents.direction = *(buf + offs + 8);
if ('S' == this->GeoLocation.LatComponents.direction) if ('S' == this->GeoLocation.LatComponents.direction)
this->GeoLocation.Latitude = -this->GeoLocation.Latitude; this->GeoLocation.Latitude = -this->GeoLocation.Latitude;
break; break;
case 2: case 2:
// GPS latitude // GPS latitude
if (format == 5 && length == 3) { if (format == 5 && length == 3) {
this->GeoLocation.LatComponents.degrees = this->GeoLocation.LatComponents.degrees =
parseEXIFRational(buf + data + tiff_header_start, alignIntel); parseEXIFRational(buf + data + tiff_header_start, alignIntel);
this->GeoLocation.LatComponents.minutes = this->GeoLocation.LatComponents.minutes =
parseEXIFRational(buf + data + tiff_header_start + 8, alignIntel); parseEXIFRational(buf + data + tiff_header_start + 8, alignIntel);
this->GeoLocation.LatComponents.seconds = this->GeoLocation.LatComponents.seconds =
parseEXIFRational(buf + data + tiff_header_start + 16, alignIntel); parseEXIFRational(buf + data + tiff_header_start + 16, alignIntel);
this->GeoLocation.Latitude = this->GeoLocation.Latitude =
this->GeoLocation.LatComponents.degrees + this->GeoLocation.LatComponents.degrees +
this->GeoLocation.LatComponents.minutes / 60 + this->GeoLocation.LatComponents.minutes / 60 +
this->GeoLocation.LatComponents.seconds / 3600; this->GeoLocation.LatComponents.seconds / 3600;
if ('S' == this->GeoLocation.LatComponents.direction) if ('S' == this->GeoLocation.LatComponents.direction)
this->GeoLocation.Latitude = -this->GeoLocation.Latitude; this->GeoLocation.Latitude = -this->GeoLocation.Latitude;
} }
break; break;
case 3: case 3:
// GPS east or west // GPS east or west
this->GeoLocation.LonComponents.direction = *(buf + offs + 8); this->GeoLocation.LonComponents.direction = *(buf + offs + 8);
if ('W' == this->GeoLocation.LonComponents.direction) if ('W' == this->GeoLocation.LonComponents.direction)
this->GeoLocation.Longitude = -this->GeoLocation.Longitude; this->GeoLocation.Longitude = -this->GeoLocation.Longitude;
break; break;
case 4: case 4:
// GPS longitude // GPS longitude
if (format == 5 && length == 3) { if (format == 5 && length == 3) {
this->GeoLocation.LonComponents.degrees = this->GeoLocation.LonComponents.degrees =
parseEXIFRational(buf + data + tiff_header_start, alignIntel); parseEXIFRational(buf + data + tiff_header_start, alignIntel);
this->GeoLocation.LonComponents.minutes = this->GeoLocation.LonComponents.minutes =
parseEXIFRational(buf + data + tiff_header_start + 8, alignIntel); parseEXIFRational(buf + data + tiff_header_start + 8, alignIntel);
this->GeoLocation.LonComponents.seconds = this->GeoLocation.LonComponents.seconds =
parseEXIFRational(buf + data + tiff_header_start + 16, alignIntel); parseEXIFRational(buf + data + tiff_header_start + 16, alignIntel);
this->GeoLocation.Longitude = this->GeoLocation.Longitude =
this->GeoLocation.LonComponents.degrees + this->GeoLocation.LonComponents.degrees +
this->GeoLocation.LonComponents.minutes / 60 + this->GeoLocation.LonComponents.minutes / 60 +
this->GeoLocation.LonComponents.seconds / 3600; this->GeoLocation.LonComponents.seconds / 3600;
if ('W' == this->GeoLocation.LonComponents.direction) if ('W' == this->GeoLocation.LonComponents.direction)
this->GeoLocation.Longitude = -this->GeoLocation.Longitude; this->GeoLocation.Longitude = -this->GeoLocation.Longitude;
} }
break; break;
case 5: case 5:
// GPS altitude reference (below or above sea level) // GPS altitude reference (below or above sea level)
this->GeoLocation.AltitudeRef = *(buf + offs + 8); this->GeoLocation.AltitudeRef = *(buf + offs + 8);
if (1 == this->GeoLocation.AltitudeRef) if (1 == this->GeoLocation.AltitudeRef)
this->GeoLocation.Altitude = -this->GeoLocation.Altitude; this->GeoLocation.Altitude = -this->GeoLocation.Altitude;
break; break;
case 6: case 6:
// GPS altitude reference // GPS altitude reference
if (format == 5) { if (format == 5) {
this->GeoLocation.Altitude = this->GeoLocation.Altitude =
parseEXIFRational(buf + data + tiff_header_start, alignIntel); parseEXIFRational(buf + data + tiff_header_start, alignIntel);
if (1 == this->GeoLocation.AltitudeRef) if (1 == this->GeoLocation.AltitudeRef)
this->GeoLocation.Altitude = -this->GeoLocation.Altitude; this->GeoLocation.Altitude = -this->GeoLocation.Altitude;
} }
break; break;
} }
offs += 12; offs += 12;
} }
} }
return PARSE_EXIF_SUCCESS; return PARSE_EXIF_SUCCESS;
} }
void EXIFInfo::clear() { void EXIFInfo::clear()
// Strings {
ImageDescription = ""; // Strings
Make = ""; ImageDescription = "";
Model = ""; Make = "";
Software = ""; Model = "";
DateTime = ""; Software = "";
DateTimeOriginal = ""; DateTime = "";
DateTimeDigitized = ""; DateTimeOriginal = "";
SubSecTimeOriginal= ""; DateTimeDigitized = "";
Copyright = ""; SubSecTimeOriginal = "";
Copyright = "";
// Shorts / unsigned / double // Shorts / unsigned / double
ByteAlign = 0; ByteAlign = 0;
Orientation = 0; Orientation = 0;
BitsPerSample = 0; BitsPerSample = 0;
ExposureTime = 0; ExposureTime = 0;
FNumber = 0; FNumber = 0;
ISOSpeedRatings = 0; ISOSpeedRatings = 0;
ShutterSpeedValue = 0; ShutterSpeedValue = 0;
ExposureBiasValue = 0; ExposureBiasValue = 0;
SubjectDistance = 0; SubjectDistance = 0;
FocalLength = 0; FocalLength = 0;
FocalLengthIn35mm = 0; FocalLengthIn35mm = 0;
Flash = 0; Flash = 0;
MeteringMode = 0; MeteringMode = 0;
ImageWidth = 0; ImageWidth = 0;
ImageHeight = 0; ImageHeight = 0;
// Geolocation // Geolocation
GeoLocation.Latitude = 0; GeoLocation.Latitude = 0;
GeoLocation.Longitude = 0; GeoLocation.Longitude = 0;
GeoLocation.Altitude = 0; GeoLocation.Altitude = 0;
GeoLocation.AltitudeRef = 0; GeoLocation.AltitudeRef = 0;
GeoLocation.LatComponents.degrees = 0; GeoLocation.LatComponents.degrees = 0;
GeoLocation.LatComponents.minutes = 0; GeoLocation.LatComponents.minutes = 0;
GeoLocation.LatComponents.seconds = 0; GeoLocation.LatComponents.seconds = 0;
GeoLocation.LatComponents.direction = 0; GeoLocation.LatComponents.direction = 0;
GeoLocation.LonComponents.degrees = 0; GeoLocation.LonComponents.degrees = 0;
GeoLocation.LonComponents.minutes = 0; GeoLocation.LonComponents.minutes = 0;
GeoLocation.LonComponents.seconds = 0; GeoLocation.LonComponents.seconds = 0;
GeoLocation.LonComponents.direction = 0; GeoLocation.LonComponents.direction = 0;
} }

View file

@ -15,17 +15,17 @@
================ ================
2.1: Released July 2013 2.1: Released July 2013
-- fixed a bug where JPEGs without an EXIF SubIFD would not be parsed -- fixed a bug where JPEGs without an EXIF SubIFD would not be parsed
-- fixed a bug in parsing GPS coordinate seconds -- fixed a bug in parsing GPS coordinate seconds
-- fixed makefile bug -- fixed makefile bug
-- added two pathological test images from Matt Galloway -- added two pathological test images from Matt Galloway
http://www.galloway.me.uk/2012/01/uiimageorientation-exif-orientation-sample-images/ http://www.galloway.me.uk/2012/01/uiimageorientation-exif-orientation-sample-images/
-- split main parsing routine for easier integration into Firefox -- split main parsing routine for easier integration into Firefox
2.0: Released February 2013 2.0: Released February 2013
-- complete rewrite -- complete rewrite
-- no new/delete -- no new/delete
-- added GPS support -- added GPS support
1.0: Released 2010 1.0: Released 2010
@ -58,86 +58,88 @@
// Class responsible for storing and parsing EXIF information from a JPEG blob // Class responsible for storing and parsing EXIF information from a JPEG blob
// //
class EXIFInfo { class EXIFInfo {
public: public:
// Parsing function for an entire JPEG image buffer. // Parsing function for an entire JPEG image buffer.
// //
// PARAM 'data': A pointer to a JPEG image. // PARAM 'data': A pointer to a JPEG image.
// PARAM 'length': The length of the JPEG image. // PARAM 'length': The length of the JPEG image.
// RETURN: PARSE_EXIF_SUCCESS (0) on succes with 'result' filled out // RETURN: PARSE_EXIF_SUCCESS (0) on succes with 'result' filled out
// error code otherwise, as defined by the PARSE_EXIF_ERROR_* macros // error code otherwise, as defined by the PARSE_EXIF_ERROR_* macros
int parseFrom(const unsigned char *data, unsigned length); int parseFrom(const unsigned char *data, unsigned length);
int parseFrom(const std::string &data); int parseFrom(const std::string &data);
// Parsing function for an EXIF segment. This is used internally by parseFrom() // Parsing function for an EXIF segment. This is used internally by parseFrom()
// but can be called for special cases where only the EXIF section is // but can be called for special cases where only the EXIF section is
// available (i.e., a blob starting with the bytes "Exif\0\0"). // available (i.e., a blob starting with the bytes "Exif\0\0").
int parseFromEXIFSegment(const unsigned char *buf, unsigned len); int parseFromEXIFSegment(const unsigned char *buf, unsigned len);
// Set all data members to default values. // Set all data members to default values.
void clear(); void clear();
// Data fields filled out by parseFrom() // Data fields filled out by parseFrom()
char ByteAlign; // 0 = Motorola byte alignment, 1 = Intel char ByteAlign; // 0 = Motorola byte alignment, 1 = Intel
std::string ImageDescription; // Image description std::string ImageDescription; // Image description
std::string Make; // Camera manufacturer's name std::string Make; // Camera manufacturer's name
std::string Model; // Camera model std::string Model; // Camera model
unsigned short Orientation; // Image orientation, start of data corresponds to unsigned short Orientation; // Image orientation, start of data corresponds to
// 0: unspecified in EXIF data // 0: unspecified in EXIF data
// 1: upper left of image // 1: upper left of image
// 3: lower right of image // 3: lower right of image
// 6: upper right of image // 6: upper right of image
// 8: lower left of image // 8: lower left of image
// 9: undefined // 9: undefined
unsigned short BitsPerSample; // Number of bits per component unsigned short BitsPerSample; // Number of bits per component
std::string Software; // Software used std::string Software; // Software used
std::string DateTime; // File change date and time std::string DateTime; // File change date and time
std::string DateTimeOriginal; // Original file date and time (may not exist) std::string DateTimeOriginal; // Original file date and time (may not exist)
std::string DateTimeDigitized; // Digitization date and time (may not exist) std::string DateTimeDigitized; // Digitization date and time (may not exist)
std::string SubSecTimeOriginal; // Sub-second time that original picture was taken std::string SubSecTimeOriginal; // Sub-second time that original picture was taken
std::string Copyright; // File copyright information std::string Copyright; // File copyright information
double ExposureTime; // Exposure time in seconds double ExposureTime; // Exposure time in seconds
double FNumber; // F/stop double FNumber; // F/stop
unsigned short ISOSpeedRatings; // ISO speed unsigned short ISOSpeedRatings; // ISO speed
double ShutterSpeedValue; // Shutter speed (reciprocal of exposure time) double ShutterSpeedValue; // Shutter speed (reciprocal of exposure time)
double ExposureBiasValue; // Exposure bias value in EV double ExposureBiasValue; // Exposure bias value in EV
double SubjectDistance; // Distance to focus point in meters double SubjectDistance; // Distance to focus point in meters
double FocalLength; // Focal length of lens in millimeters double FocalLength; // Focal length of lens in millimeters
unsigned short FocalLengthIn35mm; // Focal length in 35mm film unsigned short FocalLengthIn35mm; // Focal length in 35mm film
char Flash; // 0 = no flash, 1 = flash used char Flash; // 0 = no flash, 1 = flash used
unsigned short MeteringMode; // Metering mode unsigned short MeteringMode; // Metering mode
// 1: average // 1: average
// 2: center weighted average // 2: center weighted average
// 3: spot // 3: spot
// 4: multi-spot // 4: multi-spot
// 5: multi-segment // 5: multi-segment
unsigned ImageWidth; // Image width reported in EXIF data unsigned ImageWidth; // Image width reported in EXIF data
unsigned ImageHeight; // Image height reported in EXIF data unsigned ImageHeight; // Image height reported in EXIF data
struct Geolocation_t { // GPS information embedded in file struct Geolocation_t
double Latitude; // Image latitude expressed as decimal { // GPS information embedded in file
double Longitude; // Image longitude expressed as decimal double Latitude; // Image latitude expressed as decimal
double Altitude; // Altitude in meters, relative to sea level double Longitude; // Image longitude expressed as decimal
char AltitudeRef; // 0 = above sea level, -1 = below sea level double Altitude; // Altitude in meters, relative to sea level
struct Coord_t { char AltitudeRef; // 0 = above sea level, -1 = below sea level
double degrees; struct Coord_t {
double minutes; double degrees;
double seconds; double minutes;
char direction; double seconds;
} LatComponents, LonComponents; // Latitude, Longitude expressed in deg/min/sec char direction;
} GeoLocation; } LatComponents, LonComponents; // Latitude, Longitude expressed in deg/min/sec
EXIFInfo() { } GeoLocation;
clear(); EXIFInfo()
} {
clear();
}
}; };
// Parse was successful // Parse was successful
#define PARSE_EXIF_SUCCESS 0 #define PARSE_EXIF_SUCCESS 0
// No JPEG markers found in buffer, possibly invalid JPEG file // No JPEG markers found in buffer, possibly invalid JPEG file
#define PARSE_EXIF_ERROR_NO_JPEG 1982 #define PARSE_EXIF_ERROR_NO_JPEG 1982
// No EXIF header found in JPEG file. // No EXIF header found in JPEG file.
#define PARSE_EXIF_ERROR_NO_EXIF 1983 #define PARSE_EXIF_ERROR_NO_EXIF 1983
// Byte alignment specified in EXIF file was unknown (not Motorola or Intel). // Byte alignment specified in EXIF file was unknown (not Motorola or Intel).
#define PARSE_EXIF_ERROR_UNKNOWN_BYTEALIGN 1984 #define PARSE_EXIF_ERROR_UNKNOWN_BYTEALIGN 1984
// EXIF header was found, but data was corrupted. // EXIF header was found, but data was corrupted.
#define PARSE_EXIF_ERROR_CORRUPT 1985 #define PARSE_EXIF_ERROR_CORRUPT 1985
#endif // EXIF_H #endif // EXIF_H

View file

@ -24,7 +24,7 @@
#include <QMouseEvent> #include <QMouseEvent>
#include <QMessageBox> #include <QMessageBox>
GlobeGPS::GlobeGPS(QWidget* parent) : MarbleWidget(parent), GlobeGPS::GlobeGPS(QWidget *parent) : MarbleWidget(parent),
loadedDives(0), loadedDives(0),
messageWidget(new KMessageWidget(this)), messageWidget(new KMessageWidget(this)),
fixZoomTimer(new QTimer(this)), fixZoomTimer(new QTimer(this)),
@ -35,7 +35,7 @@ GlobeGPS::GlobeGPS(QWidget* parent) : MarbleWidget(parent),
// if not, check if they are in a known location // if not, check if they are in a known location
MapThemeManager mtm; MapThemeManager mtm;
QStringList list = mtm.mapThemeIds(); QStringList list = mtm.mapThemeIds();
QString subsurfaceDataPath; QString subsurfaceDataPath;
QDir marble; QDir marble;
if (!list.contains("earth/googlesat/googlesat.dgml")) { if (!list.contains("earth/googlesat/googlesat.dgml")) {
subsurfaceDataPath = getSubsurfaceDataPath("marbledata"); subsurfaceDataPath = getSubsurfaceDataPath("marbledata");
@ -55,7 +55,7 @@ GlobeGPS::GlobeGPS(QWidget* parent) : MarbleWidget(parent),
setProjection(Marble::Spherical); setProjection(Marble::Spherical);
setAnimationsEnabled(true); setAnimationsEnabled(true);
Q_FOREACH(AbstractFloatItem *i, floatItems()) { Q_FOREACH(AbstractFloatItem * i, floatItems()) {
i->setVisible(false); i->setVisible(false);
} }
@ -68,7 +68,7 @@ GlobeGPS::GlobeGPS(QWidget* parent) : MarbleWidget(parent),
setShowScaleBar(true); setShowScaleBar(true);
setShowCompass(false); setShowCompass(false);
connect(this, SIGNAL(mouseClickGeoPosition(qreal, qreal, GeoDataCoordinates::Unit)), connect(this, SIGNAL(mouseClickGeoPosition(qreal, qreal, GeoDataCoordinates::Unit)),
this, SLOT(mouseClicked(qreal, qreal, GeoDataCoordinates::Unit))); this, SLOT(mouseClicked(qreal, qreal, GeoDataCoordinates::Unit)));
setMinimumHeight(0); setMinimumHeight(0);
setMinimumWidth(0); setMinimumWidth(0);
@ -86,22 +86,22 @@ bool GlobeGPS::eventFilter(QObject *obj, QEvent *ev)
// we need to move this to our 'contextMenuEvent' // we need to move this to our 'contextMenuEvent'
// if we plan to do a different one in the future. // if we plan to do a different one in the future.
if (ev->type() == QEvent::ContextMenu) { if (ev->type() == QEvent::ContextMenu) {
contextMenuEvent(static_cast<QContextMenuEvent*>(ev)); contextMenuEvent(static_cast<QContextMenuEvent *>(ev));
return true; return true;
} }
if (ev->type() == QEvent::MouseButtonPress) { if (ev->type() == QEvent::MouseButtonPress) {
QMouseEvent *e = static_cast<QMouseEvent*>(ev); QMouseEvent *e = static_cast<QMouseEvent *>(ev);
if (e->button() == Qt::RightButton) if (e->button() == Qt::RightButton)
return true; return true;
} }
return QObject::eventFilter(obj,ev ); return QObject::eventFilter(obj, ev);
} }
void GlobeGPS::contextMenuEvent(QContextMenuEvent* ev) void GlobeGPS::contextMenuEvent(QContextMenuEvent *ev)
{ {
QMenu m; QMenu m;
QAction *a = m.addAction(tr("Edit Selected Dive Locations"), this, SLOT(prepareForGetDiveCoordinates())); QAction *a = m.addAction(tr("Edit Selected Dive Locations"), this, SLOT(prepareForGetDiveCoordinates()));
a->setData(QVariant::fromValue<void*>(&m)); a->setData(QVariant::fromValue<void *>(&m));
m.exec(ev->globalPos()); m.exec(ev->globalPos());
} }
@ -171,7 +171,7 @@ void GlobeGPS::repopulateLabels()
for_each_dive(idx, dive) { for_each_dive(idx, dive) {
if (dive_has_gps_location(dive)) { if (dive_has_gps_location(dive)) {
GeoDataPlacemark *place = new GeoDataPlacemark(dive->location); GeoDataPlacemark *place = new GeoDataPlacemark(dive->location);
place->setCoordinate(dive->longitude.udeg / 1000000.0,dive->latitude.udeg / 1000000.0 , 0, GeoDataCoordinates::Degree); place->setCoordinate(dive->longitude.udeg / 1000000.0, dive->latitude.udeg / 1000000.0, 0, GeoDataCoordinates::Degree);
// don't add dive locations twice, unless they are at least 50m apart // don't add dive locations twice, unless they are at least 50m apart
if (locationMap[QString(dive->location)]) { if (locationMap[QString(dive->location)]) {
GeoDataCoordinates existingLocation = locationMap[QString(dive->location)]->coordinate(); GeoDataCoordinates existingLocation = locationMap[QString(dive->location)]->coordinate();
@ -200,7 +200,7 @@ void GlobeGPS::reload()
repopulateLabels(); repopulateLabels();
} }
void GlobeGPS::centerOn(dive* dive) void GlobeGPS::centerOn(dive *dive)
{ {
// dive has changed, if we had the 'editingDive', hide it. // dive has changed, if we had the 'editingDive', hide it.
if (messageWidget->isVisible() && (!dive || dive_has_gps_location(dive))) if (messageWidget->isVisible() && (!dive || dive_has_gps_location(dive)))
@ -221,12 +221,12 @@ void GlobeGPS::centerOn(dive* dive)
zoomView(zoomFromDistance(3)); zoomView(zoomFromDistance(3));
if (!fixZoomTimer->isActive()) if (!fixZoomTimer->isActive())
currentZoomLevel = zoom(); currentZoomLevel = zoom();
// From the marble source code, the maximum time of // From the marble source code, the maximum time of
// 'spin and fit' is 2 seconds, so wait a bit them zoom again. // 'spin and fit' is 2 seconds, so wait a bit them zoom again.
fixZoomTimer->start(2100); fixZoomTimer->start(2100);
centerOn(longitude,latitude, true); centerOn(longitude, latitude, true);
} }
void GlobeGPS::fixZoom() void GlobeGPS::fixZoom()
@ -260,7 +260,7 @@ void GlobeGPS::changeDiveGeoPosition(qreal lon, qreal lat, GeoDataCoordinates::U
/* change everything on the selection. */ /* change everything on the selection. */
int i; int i;
struct dive* dive; struct dive *dive;
for_each_dive(i, dive) { for_each_dive(i, dive) {
if (!dive->selected) if (!dive->selected)
continue; continue;
@ -273,7 +273,7 @@ void GlobeGPS::changeDiveGeoPosition(qreal lon, qreal lat, GeoDataCoordinates::U
MainWindow::instance()->refreshDisplay(); MainWindow::instance()->refreshDisplay();
} }
void GlobeGPS::mousePressEvent(QMouseEvent* event) void GlobeGPS::mousePressEvent(QMouseEvent *event)
{ {
qreal lat, lon; qreal lat, lon;
bool clickOnGlobe = geoCoordinates(event->pos().x(), event->pos().y(), lon, lat, GeoDataCoordinates::Degree); bool clickOnGlobe = geoCoordinates(event->pos().x(), event->pos().y(), lon, lat, GeoDataCoordinates::Degree);
@ -287,9 +287,9 @@ void GlobeGPS::mousePressEvent(QMouseEvent* event)
} }
} }
void GlobeGPS::resizeEvent(QResizeEvent* event) void GlobeGPS::resizeEvent(QResizeEvent *event)
{ {
int size = event->size().width(); int size = event->size().width();
MarbleWidget::resizeEvent(event); MarbleWidget::resizeEvent(event);
if (size > 600) if (size > 600)
messageWidget->setGeometry((size - 600) / 2, 5, 600, 0); messageWidget->setGeometry((size - 600) / 2, 5, 600, 0);

View file

@ -11,32 +11,34 @@ class KMessageWidget;
using namespace Marble; using namespace Marble;
struct dive; struct dive;
class GlobeGPS : public MarbleWidget{ class GlobeGPS : public MarbleWidget {
Q_OBJECT Q_OBJECT
public: public:
using MarbleWidget::centerOn; using MarbleWidget::centerOn;
GlobeGPS(QWidget *parent); GlobeGPS(QWidget *parent);
void reload(); void reload();
void repopulateLabels(); void repopulateLabels();
void centerOn(struct dive* dive); void centerOn(struct dive *dive);
bool eventFilter(QObject*, QEvent*); bool eventFilter(QObject *, QEvent *);
protected: protected:
/* reimp */ void resizeEvent(QResizeEvent *event); /* reimp */ void resizeEvent(QResizeEvent *event);
/* reimp */ void mousePressEvent(QMouseEvent* event); /* reimp */ void mousePressEvent(QMouseEvent *event);
/* reimp */ void contextMenuEvent(QContextMenuEvent*); /* reimp */ void contextMenuEvent(QContextMenuEvent *);
private: private:
GeoDataDocument *loadedDives; GeoDataDocument *loadedDives;
KMessageWidget* messageWidget; KMessageWidget *messageWidget;
QTimer *fixZoomTimer; QTimer *fixZoomTimer;
int currentZoomLevel; int currentZoomLevel;
bool editingDiveLocation; bool editingDiveLocation;
public slots: public
void changeDiveGeoPosition(qreal lon,qreal lat,GeoDataCoordinates::Unit); slots:
void changeDiveGeoPosition(qreal lon, qreal lat, GeoDataCoordinates::Unit);
void mouseClicked(qreal lon, qreal lat, GeoDataCoordinates::Unit); void mouseClicked(qreal lon, qreal lat, GeoDataCoordinates::Unit);
void fixZoom(); void fixZoom();
void prepareForGetDiveCoordinates(); void prepareForGetDiveCoordinates();
}; };
#endif // GLOBE_H #endif // GLOBE_H

View file

@ -4,58 +4,58 @@ QMap<color_indice_t, QVector<QColor> > profile_color;
void fill_profile_color() void fill_profile_color()
{ {
#define COLOR(x, y, z) QVector<QColor>() << x << y << z; #define COLOR(x, y, z) QVector<QColor>() << x << y << z;
profile_color[SAC_1] = COLOR(FUNGREEN1, BLACK1_LOW_TRANS, FUNGREEN1); profile_color[SAC_1] = COLOR(FUNGREEN1, BLACK1_LOW_TRANS, FUNGREEN1);
profile_color[SAC_2] = COLOR(APPLE1, BLACK1_LOW_TRANS, APPLE1); profile_color[SAC_2] = COLOR(APPLE1, BLACK1_LOW_TRANS, APPLE1);
profile_color[SAC_3] = COLOR(ATLANTIS1, BLACK1_LOW_TRANS, ATLANTIS1); profile_color[SAC_3] = COLOR(ATLANTIS1, BLACK1_LOW_TRANS, ATLANTIS1);
profile_color[SAC_4] = COLOR(ATLANTIS2, BLACK1_LOW_TRANS, ATLANTIS2); profile_color[SAC_4] = COLOR(ATLANTIS2, BLACK1_LOW_TRANS, ATLANTIS2);
profile_color[SAC_5] = COLOR(EARLSGREEN1, BLACK1_LOW_TRANS, EARLSGREEN1); profile_color[SAC_5] = COLOR(EARLSGREEN1, BLACK1_LOW_TRANS, EARLSGREEN1);
profile_color[SAC_6] = COLOR(HOKEYPOKEY1, BLACK1_LOW_TRANS, HOKEYPOKEY1); profile_color[SAC_6] = COLOR(HOKEYPOKEY1, BLACK1_LOW_TRANS, HOKEYPOKEY1);
profile_color[SAC_7] = COLOR(TUSCANY1, BLACK1_LOW_TRANS, TUSCANY1); profile_color[SAC_7] = COLOR(TUSCANY1, BLACK1_LOW_TRANS, TUSCANY1);
profile_color[SAC_8] = COLOR(CINNABAR1, BLACK1_LOW_TRANS, CINNABAR1); profile_color[SAC_8] = COLOR(CINNABAR1, BLACK1_LOW_TRANS, CINNABAR1);
profile_color[SAC_9] = COLOR(REDORANGE1, BLACK1_LOW_TRANS, REDORANGE1); profile_color[SAC_9] = COLOR(REDORANGE1, BLACK1_LOW_TRANS, REDORANGE1);
profile_color[VELO_STABLE] = COLOR(CAMARONE1, BLACK1_LOW_TRANS, CAMARONE1); profile_color[VELO_STABLE] = COLOR(CAMARONE1, BLACK1_LOW_TRANS, CAMARONE1);
profile_color[VELO_SLOW] = COLOR(LIMENADE1, BLACK1_LOW_TRANS, LIMENADE1); profile_color[VELO_SLOW] = COLOR(LIMENADE1, BLACK1_LOW_TRANS, LIMENADE1);
profile_color[VELO_MODERATE] = COLOR(RIOGRANDE1, BLACK1_LOW_TRANS, RIOGRANDE1); profile_color[VELO_MODERATE] = COLOR(RIOGRANDE1, BLACK1_LOW_TRANS, RIOGRANDE1);
profile_color[VELO_FAST] = COLOR(PIRATEGOLD1, BLACK1_LOW_TRANS, PIRATEGOLD1); profile_color[VELO_FAST] = COLOR(PIRATEGOLD1, BLACK1_LOW_TRANS, PIRATEGOLD1);
profile_color[VELO_CRAZY] = COLOR(RED1, BLACK1_LOW_TRANS, RED1); profile_color[VELO_CRAZY] = COLOR(RED1, BLACK1_LOW_TRANS, RED1);
profile_color[PO2] = COLOR(APPLE1, BLACK1_LOW_TRANS, APPLE1); profile_color[PO2] = COLOR(APPLE1, BLACK1_LOW_TRANS, APPLE1);
profile_color[PO2_ALERT] = COLOR(RED1, BLACK1_LOW_TRANS, RED1); profile_color[PO2_ALERT] = COLOR(RED1, BLACK1_LOW_TRANS, RED1);
profile_color[PN2] = COLOR(BLACK1_LOW_TRANS, BLACK1_LOW_TRANS, BLACK1_LOW_TRANS); profile_color[PN2] = COLOR(BLACK1_LOW_TRANS, BLACK1_LOW_TRANS, BLACK1_LOW_TRANS);
profile_color[PN2_ALERT] = COLOR(RED1, BLACK1_LOW_TRANS, RED1); profile_color[PN2_ALERT] = COLOR(RED1, BLACK1_LOW_TRANS, RED1);
profile_color[PHE] = COLOR(PEANUT, BLACK1_LOW_TRANS, PEANUT); profile_color[PHE] = COLOR(PEANUT, BLACK1_LOW_TRANS, PEANUT);
profile_color[PHE_ALERT] = COLOR(RED1, BLACK1_LOW_TRANS, RED1); profile_color[PHE_ALERT] = COLOR(RED1, BLACK1_LOW_TRANS, RED1);
profile_color[PP_LINES] = COLOR(BLACK1_HIGH_TRANS, BLACK1_LOW_TRANS, BLACK1_HIGH_TRANS); profile_color[PP_LINES] = COLOR(BLACK1_HIGH_TRANS, BLACK1_LOW_TRANS, BLACK1_HIGH_TRANS);
profile_color[TEXT_BACKGROUND] = COLOR(CONCRETE1_LOWER_TRANS, WHITE1, CONCRETE1_LOWER_TRANS); profile_color[TEXT_BACKGROUND] = COLOR(CONCRETE1_LOWER_TRANS, WHITE1, CONCRETE1_LOWER_TRANS);
profile_color[ALERT_BG] = COLOR(BROOM1_LOWER_TRANS, BLACK1_LOW_TRANS, BROOM1_LOWER_TRANS); profile_color[ALERT_BG] = COLOR(BROOM1_LOWER_TRANS, BLACK1_LOW_TRANS, BROOM1_LOWER_TRANS);
profile_color[ALERT_FG] = COLOR(BLACK1_LOW_TRANS, WHITE1, BLACK1_LOW_TRANS); profile_color[ALERT_FG] = COLOR(BLACK1_LOW_TRANS, WHITE1, BLACK1_LOW_TRANS);
profile_color[EVENTS] = COLOR(REDORANGE1, BLACK1_LOW_TRANS, REDORANGE1); profile_color[EVENTS] = COLOR(REDORANGE1, BLACK1_LOW_TRANS, REDORANGE1);
profile_color[SAMPLE_DEEP] = COLOR(QColor(Qt::red).darker(), BLACK1, PERSIANRED1); profile_color[SAMPLE_DEEP] = COLOR(QColor(Qt::red).darker(), BLACK1, PERSIANRED1);
profile_color[SAMPLE_SHALLOW] = COLOR(QColor(Qt::red).lighter(), BLACK1_LOW_TRANS, PERSIANRED1); profile_color[SAMPLE_SHALLOW] = COLOR(QColor(Qt::red).lighter(), BLACK1_LOW_TRANS, PERSIANRED1);
profile_color[SMOOTHED] = COLOR(REDORANGE1_HIGH_TRANS, BLACK1_LOW_TRANS, REDORANGE1_HIGH_TRANS); profile_color[SMOOTHED] = COLOR(REDORANGE1_HIGH_TRANS, BLACK1_LOW_TRANS, REDORANGE1_HIGH_TRANS);
profile_color[MINUTE] = COLOR(MEDIUMREDVIOLET1_HIGHER_TRANS, BLACK1_LOW_TRANS, MEDIUMREDVIOLET1_HIGHER_TRANS); profile_color[MINUTE] = COLOR(MEDIUMREDVIOLET1_HIGHER_TRANS, BLACK1_LOW_TRANS, MEDIUMREDVIOLET1_HIGHER_TRANS);
profile_color[TIME_GRID] = COLOR(WHITE1, BLACK1_HIGH_TRANS, TUNDORA1_MED_TRANS); profile_color[TIME_GRID] = COLOR(WHITE1, BLACK1_HIGH_TRANS, TUNDORA1_MED_TRANS);
profile_color[TIME_TEXT] = COLOR(FORESTGREEN1, BLACK1, FORESTGREEN1); profile_color[TIME_TEXT] = COLOR(FORESTGREEN1, BLACK1, FORESTGREEN1);
profile_color[DEPTH_GRID] = COLOR(WHITE1, BLACK1_HIGH_TRANS, TUNDORA1_MED_TRANS); profile_color[DEPTH_GRID] = COLOR(WHITE1, BLACK1_HIGH_TRANS, TUNDORA1_MED_TRANS);
profile_color[MEAN_DEPTH] = COLOR(REDORANGE1_MED_TRANS, BLACK1_LOW_TRANS, REDORANGE1_MED_TRANS); profile_color[MEAN_DEPTH] = COLOR(REDORANGE1_MED_TRANS, BLACK1_LOW_TRANS, REDORANGE1_MED_TRANS);
profile_color[HR_PLOT] = COLOR(REDORANGE1_MED_TRANS, BLACK1_LOW_TRANS, REDORANGE1_MED_TRANS); profile_color[HR_PLOT] = COLOR(REDORANGE1_MED_TRANS, BLACK1_LOW_TRANS, REDORANGE1_MED_TRANS);
profile_color[HR_TEXT] = COLOR(REDORANGE1_MED_TRANS, BLACK1_LOW_TRANS, REDORANGE1_MED_TRANS); profile_color[HR_TEXT] = COLOR(REDORANGE1_MED_TRANS, BLACK1_LOW_TRANS, REDORANGE1_MED_TRANS);
profile_color[DEPTH_BOTTOM] = COLOR(GOVERNORBAY1_MED_TRANS, BLACK1_HIGH_TRANS, GOVERNORBAY1_MED_TRANS); profile_color[DEPTH_BOTTOM] = COLOR(GOVERNORBAY1_MED_TRANS, BLACK1_HIGH_TRANS, GOVERNORBAY1_MED_TRANS);
profile_color[DEPTH_TOP] = COLOR(MERCURY1_MED_TRANS, WHITE1_MED_TRANS, MERCURY1_MED_TRANS); profile_color[DEPTH_TOP] = COLOR(MERCURY1_MED_TRANS, WHITE1_MED_TRANS, MERCURY1_MED_TRANS);
profile_color[TEMP_TEXT] = COLOR(GOVERNORBAY2, BLACK1_LOW_TRANS, GOVERNORBAY2); profile_color[TEMP_TEXT] = COLOR(GOVERNORBAY2, BLACK1_LOW_TRANS, GOVERNORBAY2);
profile_color[TEMP_PLOT] = COLOR(ROYALBLUE2_LOW_TRANS, BLACK1_LOW_TRANS, ROYALBLUE2_LOW_TRANS); profile_color[TEMP_PLOT] = COLOR(ROYALBLUE2_LOW_TRANS, BLACK1_LOW_TRANS, ROYALBLUE2_LOW_TRANS);
profile_color[SAC_DEFAULT] = COLOR(WHITE1, BLACK1_LOW_TRANS, FORESTGREEN1); profile_color[SAC_DEFAULT] = COLOR(WHITE1, BLACK1_LOW_TRANS, FORESTGREEN1);
profile_color[BOUNDING_BOX] = COLOR(WHITE1, BLACK1_LOW_TRANS, TUNDORA1_MED_TRANS); profile_color[BOUNDING_BOX] = COLOR(WHITE1, BLACK1_LOW_TRANS, TUNDORA1_MED_TRANS);
profile_color[PRESSURE_TEXT] = COLOR(KILLARNEY1, BLACK1_LOW_TRANS, KILLARNEY1); profile_color[PRESSURE_TEXT] = COLOR(KILLARNEY1, BLACK1_LOW_TRANS, KILLARNEY1);
profile_color[BACKGROUND] = COLOR(SPRINGWOOD1, WHITE1, SPRINGWOOD1); profile_color[BACKGROUND] = COLOR(SPRINGWOOD1, WHITE1, SPRINGWOOD1);
profile_color[CEILING_SHALLOW] = COLOR(REDORANGE1_HIGH_TRANS, BLACK1_HIGH_TRANS, REDORANGE1_HIGH_TRANS); profile_color[CEILING_SHALLOW] = COLOR(REDORANGE1_HIGH_TRANS, BLACK1_HIGH_TRANS, REDORANGE1_HIGH_TRANS);
profile_color[CEILING_DEEP] = COLOR(RED1_MED_TRANS, BLACK1_HIGH_TRANS, RED1_MED_TRANS); profile_color[CEILING_DEEP] = COLOR(RED1_MED_TRANS, BLACK1_HIGH_TRANS, RED1_MED_TRANS);
profile_color[CALC_CEILING_SHALLOW] = COLOR(FUNGREEN1_HIGH_TRANS, BLACK1_HIGH_TRANS, FUNGREEN1_HIGH_TRANS); profile_color[CALC_CEILING_SHALLOW] = COLOR(FUNGREEN1_HIGH_TRANS, BLACK1_HIGH_TRANS, FUNGREEN1_HIGH_TRANS);
profile_color[CALC_CEILING_DEEP] = COLOR(APPLE1_HIGH_TRANS, BLACK1_HIGH_TRANS, APPLE1_HIGH_TRANS); profile_color[CALC_CEILING_DEEP] = COLOR(APPLE1_HIGH_TRANS, BLACK1_HIGH_TRANS, APPLE1_HIGH_TRANS);
#undef COLOR #undef COLOR
} }
QColor getColor(const color_indice_t i, bool isGrayscale = false) QColor getColor(const color_indice_t i, bool isGrayscale = false)

View file

@ -13,23 +13,62 @@
typedef enum { typedef enum {
/* SAC colors. Order is important, the SAC_COLORS_START_IDX define above. */ /* SAC colors. Order is important, the SAC_COLORS_START_IDX define above. */
SAC_1, SAC_2, SAC_3, SAC_4, SAC_5, SAC_6, SAC_7, SAC_8, SAC_9, SAC_1,
SAC_2,
SAC_3,
SAC_4,
SAC_5,
SAC_6,
SAC_7,
SAC_8,
SAC_9,
/* Velocity colors. Order is still important, ref VELOCITY_COLORS_START_IDX. */ /* Velocity colors. Order is still important, ref VELOCITY_COLORS_START_IDX. */
VELO_STABLE, VELO_SLOW, VELO_MODERATE, VELO_FAST, VELO_CRAZY, VELO_STABLE,
VELO_SLOW,
VELO_MODERATE,
VELO_FAST,
VELO_CRAZY,
/* gas colors */ /* gas colors */
PO2, PO2_ALERT, PN2, PN2_ALERT, PHE, PHE_ALERT, PP_LINES, PO2,
PO2_ALERT,
PN2,
PN2_ALERT,
PHE,
PHE_ALERT,
PP_LINES,
/* Other colors */ /* Other colors */
TEXT_BACKGROUND, ALERT_BG, ALERT_FG, EVENTS, SAMPLE_DEEP, SAMPLE_SHALLOW, TEXT_BACKGROUND,
SMOOTHED, MINUTE, TIME_GRID, TIME_TEXT, DEPTH_GRID, MEAN_DEPTH, HR_TEXT, HR_PLOT, DEPTH_TOP, ALERT_BG,
DEPTH_BOTTOM, TEMP_TEXT, TEMP_PLOT, SAC_DEFAULT, BOUNDING_BOX, PRESSURE_TEXT, BACKGROUND, ALERT_FG,
CEILING_SHALLOW, CEILING_DEEP, CALC_CEILING_SHALLOW, CALC_CEILING_DEEP EVENTS,
SAMPLE_DEEP,
SAMPLE_SHALLOW,
SMOOTHED,
MINUTE,
TIME_GRID,
TIME_TEXT,
DEPTH_GRID,
MEAN_DEPTH,
HR_TEXT,
HR_PLOT,
DEPTH_TOP,
DEPTH_BOTTOM,
TEMP_TEXT,
TEMP_PLOT,
SAC_DEFAULT,
BOUNDING_BOX,
PRESSURE_TEXT,
BACKGROUND,
CEILING_SHALLOW,
CEILING_DEEP,
CALC_CEILING_SHALLOW,
CALC_CEILING_DEEP
} color_indice_t; } color_indice_t;
/* profile_color[color indice] = COLOR(screen color, b/w printer color, color printer}} printer & screen colours could be different */ /* profile_color[color indice] = COLOR(screen color, b/w printer color, color printer}} printer & screen colours could be different */
extern QMap<color_indice_t, QVector<QColor> > profile_color; extern QMap<color_indice_t, QVector<QColor> > profile_color;

View file

@ -54,9 +54,8 @@ struct GroupedLineEdit::Private {
QVector<QColor> colors; QVector<QColor> colors;
}; };
GroupedLineEdit::GroupedLineEdit(QWidget* parent) GroupedLineEdit::GroupedLineEdit(QWidget *parent) : QPlainTextEdit(parent),
: QPlainTextEdit(parent), d(new Private)
d(new Private)
{ {
setWordWrapMode(QTextOption::NoWrap); setWordWrapMode(QTextOption::NoWrap);
setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed); setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
@ -90,7 +89,7 @@ void GroupedLineEdit::addBlock(int start, int end)
block.start = start; block.start = start;
block.end = end; block.end = end;
block.text = text().mid(start, end-start+1).trimmed(); block.text = text().mid(start, end - start + 1).trimmed();
d->blocks.append(block); d->blocks.append(block);
viewport()->update(); viewport()->update();
} }
@ -110,7 +109,7 @@ QStringList GroupedLineEdit::getBlockStringList()
QStringList retList; QStringList retList;
Private::Block block; Private::Block block;
foreach(block, d->blocks) foreach(block, d->blocks)
retList.append(block.text); retList.append(block.text);
return retList; return retList;
} }
@ -150,11 +149,10 @@ void GroupedLineEdit::removeAllBlocks()
QSize GroupedLineEdit::sizeHint() const QSize GroupedLineEdit::sizeHint() const
{ {
QSize rs( QSize rs(
40, 40,
document()->findBlock(0).layout()->lineAt(0).height() + document()->findBlock(0).layout()->lineAt(0).height() +
document()->documentMargin() * 2 + document()->documentMargin() * 2 +
frameWidth() * 2 frameWidth() * 2);
);
return rs; return rs;
} }
@ -191,23 +189,22 @@ void GroupedLineEdit::paintEvent(QPaintEvent *e)
QVectorIterator<QColor> i(d->colors); QVectorIterator<QColor> i(d->colors);
i.toFront(); i.toFront();
foreach (const Private::Block &block, d->blocks) { foreach(const Private::Block & block, d->blocks) {
qreal start_x = line.cursorToX(block.start, QTextLine::Trailing); qreal start_x = line.cursorToX(block.start, QTextLine::Trailing);
qreal end_x = line.cursorToX(block.end + 1, QTextLine::Leading); qreal end_x = line.cursorToX(block.end + 1, QTextLine::Leading);
QPainterPath path; QPainterPath path;
QRectF rectangle( QRectF rectangle(
start_x - 1.0 - double(horizontalScrollBar()->value()), start_x - 1.0 - double(horizontalScrollBar()->value()),
1.0, 1.0,
end_x - start_x + 2.0, end_x - start_x + 2.0,
double(viewport()->height() - 2) double(viewport()->height() - 2));
); if (!i.hasNext())
if (! i.hasNext())
i.toFront(); i.toFront();
path.addRoundedRect(rectangle, 5.0, 5.0); path.addRoundedRect(rectangle, 5.0, 5.0);
painter.setPen(i.peekNext()); painter.setPen(i.peekNext());
if (palette().color(QPalette::Text).lightnessF() <= 0.3 ) if (palette().color(QPalette::Text).lightnessF() <= 0.3)
painter.setBrush(i.next().lighter()); painter.setBrush(i.next().lighter());
else if (palette().color(QPalette::Text).lightnessF() <= 0.6 ) else if (palette().color(QPalette::Text).lightnessF() <= 0.6)
painter.setBrush(i.next()); painter.setBrush(i.next());
else else
painter.setBrush(i.next().darker()); painter.setBrush(i.next().darker());

View file

@ -33,8 +33,7 @@
#include <QPlainTextEdit> #include <QPlainTextEdit>
#include <QStringList> #include <QStringList>
class GroupedLineEdit : public QPlainTextEdit class GroupedLineEdit : public QPlainTextEdit {
{
Q_OBJECT Q_OBJECT
public: public:
@ -65,6 +64,7 @@ signals:
protected: protected:
virtual void paintEvent(QPaintEvent *e); virtual void paintEvent(QPaintEvent *e);
virtual void keyPressEvent(QKeyEvent *e); virtual void keyPressEvent(QKeyEvent *e);
private: private:
struct Private; struct Private;
Private *d; Private *d;

View file

@ -30,7 +30,7 @@
#include <QStyle> #include <QStyle>
#include <QAction> #include <QAction>
void KMessageWidgetPrivate::init(KMessageWidget* q_ptr) void KMessageWidgetPrivate::init(KMessageWidget *q_ptr)
{ {
q = q_ptr; q = q_ptr;
@ -52,10 +52,10 @@ void KMessageWidgetPrivate::init(KMessageWidget* q_ptr)
textLabel = new QLabel(content); textLabel = new QLabel(content);
textLabel->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed); textLabel->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
textLabel->setTextInteractionFlags(Qt::TextBrowserInteraction); textLabel->setTextInteractionFlags(Qt::TextBrowserInteraction);
QObject::connect(textLabel, SIGNAL(linkActivated(const QString&)), q, SIGNAL(linkActivated(const QString&))); QObject::connect(textLabel, SIGNAL(linkActivated(const QString &)), q, SIGNAL(linkActivated(const QString &)));
QObject::connect(textLabel, SIGNAL(linkHovered(const QString&)), q, SIGNAL(linkHovered(const QString&))); QObject::connect(textLabel, SIGNAL(linkHovered(const QString &)), q, SIGNAL(linkHovered(const QString &)));
QAction* closeAction = new QAction(QObject::tr("Close"), q); QAction *closeAction = new QAction(QObject::tr("Close"), q);
q->connect(closeAction, SIGNAL(triggered(bool)), q, SLOT(animatedHide())); q->connect(closeAction, SIGNAL(triggered(bool)), q, SLOT(animatedHide()));
closeButton = new QToolButton(content); closeButton = new QToolButton(content);
@ -74,8 +74,8 @@ void KMessageWidgetPrivate::createLayout()
qDeleteAll(buttons); qDeleteAll(buttons);
buttons.clear(); buttons.clear();
Q_FOREACH(QAction* action, q->actions()) { Q_FOREACH(QAction * action, q->actions()) {
QToolButton* button = new QToolButton(content); QToolButton *button = new QToolButton(content);
button->setDefaultAction(action); button->setDefaultAction(action);
button->setToolButtonStyle(Qt::ToolButtonTextBesideIcon); button->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
buttons.append(button); buttons.append(button);
@ -87,14 +87,14 @@ void KMessageWidgetPrivate::createLayout()
closeButton->setAutoRaise(buttons.isEmpty()); closeButton->setAutoRaise(buttons.isEmpty());
if (wordWrap) { if (wordWrap) {
QGridLayout* layout = new QGridLayout(content); QGridLayout *layout = new QGridLayout(content);
// Set alignment to make sure icon does not move down if text wraps // Set alignment to make sure icon does not move down if text wraps
layout->addWidget(iconLabel, 0, 0, 1, 1, Qt::AlignHCenter | Qt::AlignTop); layout->addWidget(iconLabel, 0, 0, 1, 1, Qt::AlignHCenter | Qt::AlignTop);
layout->addWidget(textLabel, 0, 1); layout->addWidget(textLabel, 0, 1);
QHBoxLayout* buttonLayout = new QHBoxLayout; QHBoxLayout *buttonLayout = new QHBoxLayout;
buttonLayout->addStretch(); buttonLayout->addStretch();
Q_FOREACH(QToolButton* button, buttons) { Q_FOREACH(QToolButton * button, buttons) {
// For some reason, calling show() is necessary if wordwrap is true, // For some reason, calling show() is necessary if wordwrap is true,
// otherwise the buttons do not show up. It is not needed if // otherwise the buttons do not show up. It is not needed if
// wordwrap is false. // wordwrap is false.
@ -104,11 +104,11 @@ void KMessageWidgetPrivate::createLayout()
buttonLayout->addWidget(closeButton); buttonLayout->addWidget(closeButton);
layout->addItem(buttonLayout, 1, 0, 1, 2); layout->addItem(buttonLayout, 1, 0, 1, 2);
} else { } else {
QHBoxLayout* layout = new QHBoxLayout(content); QHBoxLayout *layout = new QHBoxLayout(content);
layout->addWidget(iconLabel); layout->addWidget(iconLabel);
layout->addWidget(textLabel); layout->addWidget(textLabel);
Q_FOREACH(QToolButton* button, buttons) { Q_FOREACH(QToolButton * button, buttons) {
layout->addWidget(button); layout->addWidget(button);
} }
@ -174,16 +174,12 @@ int KMessageWidgetPrivate::bestContentHeight() const
//--------------------------------------------------------------------- //---------------------------------------------------------------------
// KMessageWidget // KMessageWidget
//--------------------------------------------------------------------- //---------------------------------------------------------------------
KMessageWidget::KMessageWidget(QWidget* parent) KMessageWidget::KMessageWidget(QWidget *parent) : QFrame(parent), d(new KMessageWidgetPrivate)
: QFrame(parent)
, d(new KMessageWidgetPrivate)
{ {
d->init(this); d->init(this);
} }
KMessageWidget::KMessageWidget(const QString& text, QWidget* parent) KMessageWidget::KMessageWidget(const QString &text, QWidget *parent) : QFrame(parent), d(new KMessageWidgetPrivate)
: QFrame(parent)
, d(new KMessageWidgetPrivate)
{ {
d->init(this); d->init(this);
setText(text); setText(text);
@ -199,7 +195,7 @@ QString KMessageWidget::text() const
return d->textLabel->text(); return d->textLabel->text();
} }
void KMessageWidget::setText(const QString& text) void KMessageWidget::setText(const QString &text)
{ {
d->textLabel->setText(text); d->textLabel->setText(text);
updateGeometry(); updateGeometry();
@ -242,7 +238,7 @@ void KMessageWidget::setMessageType(KMessageWidget::MessageType type)
bg2 = bg1.darker(110); bg2 = bg1.darker(110);
border = bg2.darker(110); border = bg2.darker(110);
d->content->setStyleSheet( d->content->setStyleSheet(
QString(".QFrame {" QString(".QFrame {"
"background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1," "background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1,"
" stop: 0 %1," " stop: 0 %1,"
" stop: 0.1 %2," " stop: 0.1 %2,"
@ -251,20 +247,17 @@ void KMessageWidget::setMessageType(KMessageWidget::MessageType type)
"border: 1px solid %4;" "border: 1px solid %4;"
"margin: %5px;" "margin: %5px;"
"}" "}"
".QLabel { color: %6; }" ".QLabel { color: %6; }").arg(bg0.name())
).arg(bg0.name())
.arg(bg1.name()) .arg(bg1.name())
.arg(bg2.name()) .arg(bg2.name())
.arg(border.name()) .arg(border.name())
/* /*
DefaultFrameWidth returns the size of the external margin + border width. DefaultFrameWidth returns the size of the external margin + border width.
We know our border is 1px, so we subtract this from the frame We know our border is 1px, so we subtract this from the frame
normal QStyle FrameWidth to get our margin normal QStyle FrameWidth to get our margin
*/ */
.arg(style()->pixelMetric(QStyle::PM_DefaultFrameWidth, 0, this) - 1)
.arg(style()->pixelMetric(QStyle::PM_DefaultFrameWidth, 0, this) -1) .arg(fg.name()));
.arg(fg.name())
);
} }
QSize KMessageWidget::sizeHint() const QSize KMessageWidget::sizeHint() const
@ -279,7 +272,7 @@ QSize KMessageWidget::minimumSizeHint() const
return d->content->minimumSizeHint(); return d->content->minimumSizeHint();
} }
bool KMessageWidget::event(QEvent* event) bool KMessageWidget::event(QEvent *event)
{ {
if (event->type() == QEvent::Polish && !d->content->layout()) { if (event->type() == QEvent::Polish && !d->content->layout()) {
d->createLayout(); d->createLayout();
@ -288,7 +281,7 @@ bool KMessageWidget::event(QEvent* event)
return QFrame::event(event); return QFrame::event(event);
} }
void KMessageWidget::resizeEvent(QResizeEvent* event) void KMessageWidget::resizeEvent(QResizeEvent *event)
{ {
QFrame::resizeEvent(event); QFrame::resizeEvent(event);
@ -303,7 +296,7 @@ int KMessageWidget::heightForWidth(int width) const
return d->content->heightForWidth(width); return d->content->heightForWidth(width);
} }
void KMessageWidget::paintEvent(QPaintEvent* event) void KMessageWidget::paintEvent(QPaintEvent *event)
{ {
QFrame::paintEvent(event); QFrame::paintEvent(event);
@ -314,7 +307,7 @@ void KMessageWidget::paintEvent(QPaintEvent* event)
} }
} }
void KMessageWidget::showEvent(QShowEvent* event) void KMessageWidget::showEvent(QShowEvent *event)
{ {
// Keep this method here to avoid breaking binary compatibility: // Keep this method here to avoid breaking binary compatibility:
// QFrame::showEvent() used to be reimplemented. // QFrame::showEvent() used to be reimplemented.
@ -354,13 +347,13 @@ void KMessageWidget::setCloseButtonVisible(bool show)
updateGeometry(); updateGeometry();
} }
void KMessageWidget::addAction(QAction* action) void KMessageWidget::addAction(QAction *action)
{ {
QFrame::addAction(action); QFrame::addAction(action);
d->updateLayout(); d->updateLayout();
} }
void KMessageWidget::removeAction(QAction* action) void KMessageWidget::removeAction(QAction *action)
{ {
QFrame::removeAction(action); QFrame::removeAction(action);
d->updateLayout(); d->updateLayout();
@ -408,15 +401,14 @@ QIcon KMessageWidget::icon() const
return d->icon; return d->icon;
} }
void KMessageWidget::setIcon(const QIcon& icon) void KMessageWidget::setIcon(const QIcon &icon)
{ {
d->icon = icon; d->icon = icon;
if (d->icon.isNull()) { if (d->icon.isNull()) {
d->iconLabel->hide(); d->iconLabel->hide();
} else { } else {
d->iconLabel->setPixmap(d->icon.pixmap(QSize(16,16))); d->iconLabel->setPixmap(d->icon.pixmap(QSize(16, 16)));
d->iconLabel->show(); d->iconLabel->show();
} }
} }

View file

@ -87,118 +87,118 @@ class KMessageWidgetPrivate;
* @author Aurélien Gâteau <agateau@kde.org> * @author Aurélien Gâteau <agateau@kde.org>
* @since 4.7 * @since 4.7
*/ */
class KMessageWidget : public QFrame class KMessageWidget : public QFrame {
{ Q_OBJECT
Q_OBJECT Q_ENUMS(MessageType)
Q_ENUMS(MessageType)
Q_PROPERTY(QString text READ text WRITE setText) Q_PROPERTY(QString text READ text WRITE setText)
Q_PROPERTY(bool wordWrap READ wordWrap WRITE setWordWrap) Q_PROPERTY(bool wordWrap READ wordWrap WRITE setWordWrap)
Q_PROPERTY(bool closeButtonVisible READ isCloseButtonVisible WRITE setCloseButtonVisible) Q_PROPERTY(bool closeButtonVisible READ isCloseButtonVisible WRITE setCloseButtonVisible)
Q_PROPERTY(MessageType messageType READ messageType WRITE setMessageType) Q_PROPERTY(MessageType messageType READ messageType WRITE setMessageType)
Q_PROPERTY(QIcon icon READ icon WRITE setIcon) Q_PROPERTY(QIcon icon READ icon WRITE setIcon)
public: public:
enum MessageType { enum MessageType {
Positive, Positive,
Information, Information,
Warning, Warning,
Error Error
}; };
/** /**
* Constructs a KMessageWidget with the specified parent. * Constructs a KMessageWidget with the specified parent.
*/ */
explicit KMessageWidget(QWidget *parent = 0); explicit KMessageWidget(QWidget *parent = 0);
explicit KMessageWidget(const QString &text, QWidget *parent = 0); explicit KMessageWidget(const QString &text, QWidget *parent = 0);
~KMessageWidget(); ~KMessageWidget();
QString text() const; QString text() const;
bool wordWrap() const; bool wordWrap() const;
bool isCloseButtonVisible() const; bool isCloseButtonVisible() const;
MessageType messageType() const; MessageType messageType() const;
void addAction(QAction *action); void addAction(QAction *action);
void removeAction(QAction *action); void removeAction(QAction *action);
QSize sizeHint() const; QSize sizeHint() const;
QSize minimumSizeHint() const; QSize minimumSizeHint() const;
int heightForWidth(int width) const; int heightForWidth(int width) const;
/** /**
* The icon shown on the left of the text. By default, no icon is shown. * The icon shown on the left of the text. By default, no icon is shown.
* @since 4.11 * @since 4.11
*/ */
QIcon icon() const; QIcon icon() const;
public Q_SLOTS: public
void setText(const QString &text); Q_SLOTS:
void setText(const QString &text);
void setWordWrap(bool wordWrap); void setWordWrap(bool wordWrap);
void setCloseButtonVisible(bool visible); void setCloseButtonVisible(bool visible);
void setMessageType(KMessageWidget::MessageType type); void setMessageType(KMessageWidget::MessageType type);
/** /**
* Show the widget using an animation, unless * Show the widget using an animation, unless
* KGlobalSettings::graphicsEffectLevel() does not allow simple effects. * KGlobalSettings::graphicsEffectLevel() does not allow simple effects.
*/ */
void animatedShow(); void animatedShow();
/** /**
* Hide the widget using an animation, unless * Hide the widget using an animation, unless
* KGlobalSettings::graphicsEffectLevel() does not allow simple effects. * KGlobalSettings::graphicsEffectLevel() does not allow simple effects.
*/ */
void animatedHide(); void animatedHide();
/** /**
* Define an icon to be shown on the left of the text * Define an icon to be shown on the left of the text
* @since 4.11 * @since 4.11
*/ */
void setIcon(const QIcon &icon); void setIcon(const QIcon &icon);
Q_SIGNALS: Q_SIGNALS:
/** /**
* This signal is emitted when the user clicks a link in the text label. * This signal is emitted when the user clicks a link in the text label.
* The URL referred to by the href anchor is passed in contents. * The URL referred to by the href anchor is passed in contents.
* @param contents text of the href anchor * @param contents text of the href anchor
* @see QLabel::linkActivated() * @see QLabel::linkActivated()
* @since 4.10 * @since 4.10
*/ */
void linkActivated(const QString& contents); void linkActivated(const QString &contents);
/** /**
* This signal is emitted when the user hovers over a link in the text label. * This signal is emitted when the user hovers over a link in the text label.
* The URL referred to by the href anchor is passed in contents. * The URL referred to by the href anchor is passed in contents.
* @param contents text of the href anchor * @param contents text of the href anchor
* @see QLabel::linkHovered() * @see QLabel::linkHovered()
* @since 4.11 * @since 4.11
*/ */
void linkHovered(const QString& contents); void linkHovered(const QString &contents);
protected: protected:
void paintEvent(QPaintEvent *event); void paintEvent(QPaintEvent *event);
bool event(QEvent *event); bool event(QEvent *event);
void resizeEvent(QResizeEvent *event); void resizeEvent(QResizeEvent *event);
void showEvent(QShowEvent *event); void showEvent(QShowEvent *event);
private: private:
KMessageWidgetPrivate *const d; KMessageWidgetPrivate *const d;
friend class KMessageWidgetPrivate; friend class KMessageWidgetPrivate;
Q_PRIVATE_SLOT(d, void slotTimeLineChanged(qreal)) Q_PRIVATE_SLOT(d, void slotTimeLineChanged(qreal))
Q_PRIVATE_SLOT(d, void slotTimeLineFinished()) Q_PRIVATE_SLOT(d, void slotTimeLineFinished())
}; };
//--------------------------------------------------------------------- //---------------------------------------------------------------------
@ -209,22 +209,21 @@ class QToolButton;
class QTimeLine; class QTimeLine;
#include <QIcon> #include <QIcon>
class KMessageWidgetPrivate class KMessageWidgetPrivate {
{
public: public:
void init(KMessageWidget*); void init(KMessageWidget *);
KMessageWidget* q; KMessageWidget *q;
QFrame* content; QFrame *content;
QLabel* iconLabel; QLabel *iconLabel;
QLabel* textLabel; QLabel *textLabel;
QToolButton* closeButton; QToolButton *closeButton;
QTimeLine* timeLine; QTimeLine *timeLine;
QIcon icon; QIcon icon;
KMessageWidget::MessageType messageType; KMessageWidget::MessageType messageType;
bool wordWrap; bool wordWrap;
QList<QToolButton*> buttons; QList<QToolButton *> buttons;
QPixmap contentSnapShot; QPixmap contentSnapShot;
void createLayout(); void createLayout();

View file

@ -26,9 +26,9 @@
#include <QScrollBar> #include <QScrollBar>
MainTab::MainTab(QWidget *parent) : QTabWidget(parent), MainTab::MainTab(QWidget *parent) : QTabWidget(parent),
weightModel(new WeightModel(this)), weightModel(new WeightModel(this)),
cylindersModel(CylindersModel::instance()), cylindersModel(CylindersModel::instance()),
editMode(NONE) editMode(NONE)
{ {
ui.setupUi(this); ui.setupUi(this);
@ -69,8 +69,8 @@ MainTab::MainTab(QWidget *parent) : QTabWidget(parent),
ui.tagWidget->installEventFilter(this); ui.tagWidget->installEventFilter(this);
QList<QObject *> statisticsTabWidgets = ui.statisticsTab->children(); QList<QObject *> statisticsTabWidgets = ui.statisticsTab->children();
Q_FOREACH(QObject* obj, statisticsTabWidgets) { Q_FOREACH(QObject * obj, statisticsTabWidgets) {
QLabel* label = qobject_cast<QLabel *>(obj); QLabel *label = qobject_cast<QLabel *>(obj);
if (label) if (label)
label->setAlignment(Qt::AlignHCenter); label->setAlignment(Qt::AlignHCenter);
} }
@ -134,18 +134,17 @@ MainTab::MainTab(QWidget *parent) : QTabWidget(parent),
" background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1," " background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1,"
" stop: 0 #E0E0E0, stop: 1 #FFFFFF);" " stop: 0 #E0E0E0, stop: 1 #FFFFFF);"
"}"); "}");
Q_FOREACH(QGroupBox *box, findChildren<QGroupBox*>()) { Q_FOREACH(QGroupBox * box, findChildren<QGroupBox *>()) {
box->setStyleSheet(gnomeCss); box->setStyleSheet(gnomeCss);
} }
} }
ui.cylinders->view()->horizontalHeader()->setContextMenuPolicy(Qt::ActionsContextMenu); ui.cylinders->view()->horizontalHeader()->setContextMenuPolicy(Qt::ActionsContextMenu);
QSettings s; QSettings s;
s.beginGroup("cylinders_dialog"); s.beginGroup("cylinders_dialog");
for(int i = 0; i < CylindersModel::COLUMNS; i++) { for (int i = 0; i < CylindersModel::COLUMNS; i++) {
if ((i == CylindersModel::REMOVE) || (i == CylindersModel::TYPE)) if ((i == CylindersModel::REMOVE) || (i == CylindersModel::TYPE))
continue; continue;
bool checked = s.value(QString("column%1_hidden").arg(i)).toBool(); bool checked = s.value(QString("column%1_hidden").arg(i)).toBool();
action = new QAction(cylindersModel->headerData(i, Qt::Horizontal, Qt::DisplayRole).toString(), ui.cylinders->view()); action = new QAction(cylindersModel->headerData(i, Qt::Horizontal, Qt::DisplayRole).toString(), ui.cylinders->view());
action->setCheckable(true); action->setCheckable(true);
@ -161,16 +160,16 @@ MainTab::~MainTab()
{ {
QSettings s; QSettings s;
s.beginGroup("cylinders_dialog"); s.beginGroup("cylinders_dialog");
for(int i = 0; i < CylindersModel::COLUMNS; i++) { for (int i = 0; i < CylindersModel::COLUMNS; i++) {
if ((i == CylindersModel::REMOVE) || (i == CylindersModel::TYPE)) if ((i == CylindersModel::REMOVE) || (i == CylindersModel::TYPE))
continue; continue;
s.setValue(QString("column%1_hidden").arg(i), ui.cylinders->view()->isColumnHidden(i)); s.setValue(QString("column%1_hidden").arg(i), ui.cylinders->view()->isColumnHidden(i));
} }
} }
void MainTab::toggleTriggeredColumn() void MainTab::toggleTriggeredColumn()
{ {
QAction *action = qobject_cast<QAction*>(sender()); QAction *action = qobject_cast<QAction *>(sender());
int col = action->data().toInt(); int col = action->data().toInt();
QTableView *view = ui.cylinders->view(); QTableView *view = ui.cylinders->view();
@ -178,8 +177,7 @@ void MainTab::toggleTriggeredColumn()
view->showColumn(col); view->showColumn(col);
if (view->columnWidth(col) <= 15) if (view->columnWidth(col) <= 15)
view->setColumnWidth(col, 80); view->setColumnWidth(col, 80);
} } else
else
view->hideColumn(col); view->hideColumn(col);
} }
@ -188,7 +186,7 @@ void MainTab::addDiveStarted()
enableEdition(ADD); enableEdition(ADD);
} }
void MainTab::addMessageAction(QAction* action) void MainTab::addMessageAction(QAction *action)
{ {
ui.diveEquipmentMessage->addAction(action); ui.diveEquipmentMessage->addAction(action);
ui.diveNotesMessage->addAction(action); ui.diveNotesMessage->addAction(action);
@ -272,7 +270,7 @@ void MainTab::enableEdition(EditMode newEditMode)
notesBackup[mydive].visibility = mydive->visibility; notesBackup[mydive].visibility = mydive->visibility;
notesBackup[mydive].latitude = mydive->latitude; notesBackup[mydive].latitude = mydive->latitude;
notesBackup[mydive].longitude = mydive->longitude; notesBackup[mydive].longitude = mydive->longitude;
notesBackup[mydive].coordinates = ui.coordinates->text(); notesBackup[mydive].coordinates = ui.coordinates->text();
notesBackup[mydive].airtemp = get_temperature_string(mydive->airtemp, true); notesBackup[mydive].airtemp = get_temperature_string(mydive->airtemp, true);
notesBackup[mydive].watertemp = get_temperature_string(mydive->watertemp, true); notesBackup[mydive].watertemp = get_temperature_string(mydive->watertemp, true);
notesBackup[mydive].datetime = QDateTime::fromTime_t(mydive->when).toUTC().toString(); notesBackup[mydive].datetime = QDateTime::fromTime_t(mydive->when).toUTC().toString();
@ -293,7 +291,7 @@ void MainTab::enableEdition(EditMode newEditMode)
} }
} }
bool MainTab::eventFilter(QObject* object, QEvent* event) bool MainTab::eventFilter(QObject *object, QEvent *event)
{ {
if (!isEnabled()) if (!isEnabled())
return false; return false;
@ -349,17 +347,17 @@ void MainTab::clearStats()
ui.timeLimits->clear(); ui.timeLimits->clear();
} }
#define UPDATE_TEXT(d, field) \ #define UPDATE_TEXT(d, field) \
if (!d || !d->field) \ if (!d || !d->field) \
ui.field->setText(""); \ ui.field->setText(""); \
else \ else \
ui.field->setText(d->field) ui.field->setText(d->field)
#define UPDATE_TEMP(d, field) \ #define UPDATE_TEMP(d, field) \
if (!d || d->field.mkelvin == 0) \ if (!d || d->field.mkelvin == 0) \
ui.field->setText(""); \ ui.field->setText(""); \
else \ else \
ui.field->setText(get_temperature_string(d->field, true)) ui.field->setText(get_temperature_string(d->field, true))
bool MainTab::isEditing() bool MainTab::isEditing()
{ {
@ -480,7 +478,7 @@ void MainTab::updateDiveInfo(int dive)
} else { } else {
SACs = QString(tr("unknown")); SACs = QString(tr("unknown"));
} }
for(int i=1; i < MAX_CYLINDERS && gases[i].mliter != 0; i++) { for (int i = 1; i < MAX_CYLINDERS && gases[i].mliter != 0; i++) {
volumes.append("\n" + get_volume_string(gases[i], true)); volumes.append("\n" + get_volume_string(gases[i], true));
if (duration[i]) { if (duration[i]) {
sac.mliter = gases[i].mliter / (depth_to_atm(mean[i], d) * duration[i] / 60); sac.mliter = gases[i].mliter / (depth_to_atm(mean[i], d) * duration[i] / 60);
@ -507,7 +505,7 @@ void MainTab::updateDiveInfo(int dive)
else else
ui.airPressureText->clear(); ui.airPressureText->clear();
if (d->salinity) if (d->salinity)
ui.salinityText->setText(QString("%1g/l").arg(d->salinity/10.0)); ui.salinityText->setText(QString("%1g/l").arg(d->salinity / 10.0));
else else
ui.salinityText->clear(); ui.salinityText->clear();
ui.depthLimits->setMaximum(get_depth_string(stats_selection.max_depth, true)); ui.depthLimits->setMaximum(get_depth_string(stats_selection.max_depth, true));
@ -542,7 +540,7 @@ void MainTab::updateDiveInfo(int dive)
ui.coordinates->clear(); ui.coordinates->clear();
ui.visibility->setCurrentStars(0); ui.visibility->setCurrentStars(0);
/* turns out this is non-trivial for a dateTimeEdit... this is a partial hack */ /* turns out this is non-trivial for a dateTimeEdit... this is a partial hack */
QLineEdit *le = ui.dateTimeEdit->findChild<QLineEdit*>(); QLineEdit *le = ui.dateTimeEdit->findChild<QLineEdit *>();
le->setText(""); le->setText("");
} }
} }
@ -580,28 +578,28 @@ void MainTab::acceptChanges()
/* now figure out if things have changed */ /* now figure out if things have changed */
if (MainWindow::instance() && MainWindow::instance()->dive_list()->selectedTrips().count() == 1) { if (MainWindow::instance() && MainWindow::instance()->dive_list()->selectedTrips().count() == 1) {
if (notesBackup[NULL].notes != ui.notes->toPlainText() || if (notesBackup[NULL].notes != ui.notes->toPlainText() ||
notesBackup[NULL].location != ui.location->text()) notesBackup[NULL].location != ui.location->text())
mark_divelist_changed(true); mark_divelist_changed(true);
} else { } else {
struct dive *curr = current_dive; struct dive *curr = current_dive;
//Reset coordinates field, in case it contains garbage. //Reset coordinates field, in case it contains garbage.
updateGpsCoordinates(curr); updateGpsCoordinates(curr);
if (notesBackup[curr].buddy != ui.buddy->text() || if (notesBackup[curr].buddy != ui.buddy->text() ||
notesBackup[curr].suit != ui.suit->text() || notesBackup[curr].suit != ui.suit->text() ||
notesBackup[curr].notes != ui.notes->toPlainText() || notesBackup[curr].notes != ui.notes->toPlainText() ||
notesBackup[curr].divemaster != ui.divemaster->text() || notesBackup[curr].divemaster != ui.divemaster->text() ||
notesBackup[curr].location != ui.location->text() || notesBackup[curr].location != ui.location->text() ||
notesBackup[curr].coordinates != ui.coordinates->text() || notesBackup[curr].coordinates != ui.coordinates->text() ||
notesBackup[curr].rating != ui.visibility->currentStars() || notesBackup[curr].rating != ui.visibility->currentStars() ||
notesBackup[curr].airtemp != ui.airtemp->text() || notesBackup[curr].airtemp != ui.airtemp->text() ||
notesBackup[curr].watertemp != ui.watertemp->text() || notesBackup[curr].watertemp != ui.watertemp->text() ||
notesBackup[curr].datetime != ui.dateTimeEdit->dateTime().toString() || notesBackup[curr].datetime != ui.dateTimeEdit->dateTime().toString() ||
notesBackup[curr].visibility != ui.rating->currentStars() || notesBackup[curr].visibility != ui.rating->currentStars() ||
notesBackup[curr].tags != ui.tagWidget->text()) { notesBackup[curr].tags != ui.tagWidget->text()) {
mark_divelist_changed(true); mark_divelist_changed(true);
} }
if (notesBackup[curr].location != ui.location->text() || if (notesBackup[curr].location != ui.location->text() ||
notesBackup[curr].coordinates != ui.coordinates->text()) { notesBackup[curr].coordinates != ui.coordinates->text()) {
MainWindow::instance()->globe()->reload(); MainWindow::instance()->globe()->reload();
} }
@ -611,7 +609,7 @@ void MainTab::acceptChanges()
DivePlannerPointsModel::instance()->copyCylinders(curr); DivePlannerPointsModel::instance()->copyCylinders(curr);
} else if (editMode != ADD && cylindersModel->changed) { } else if (editMode != ADD && cylindersModel->changed) {
mark_divelist_changed(true); mark_divelist_changed(true);
Q_FOREACH (dive *d, notesBackup.keys()) { Q_FOREACH(dive * d, notesBackup.keys()) {
for (int i = 0; i < MAX_CYLINDERS; i++) { for (int i = 0; i < MAX_CYLINDERS; i++) {
if (notesBackup.keys().count() > 1) if (notesBackup.keys().count() > 1)
// only copy the cylinder type, none of the other values // only copy the cylinder type, none of the other values
@ -624,13 +622,12 @@ void MainTab::acceptChanges()
if (weightModel->changed) { if (weightModel->changed) {
mark_divelist_changed(true); mark_divelist_changed(true);
Q_FOREACH (dive *d, notesBackup.keys()) { Q_FOREACH(dive * d, notesBackup.keys()) {
for (int i = 0; i < MAX_WEIGHTSYSTEMS; i++) { for (int i = 0; i < MAX_WEIGHTSYSTEMS; i++) {
d->weightsystem[i] = multiEditEquipmentPlaceholder.weightsystem[i]; d->weightsystem[i] = multiEditEquipmentPlaceholder.weightsystem[i];
} }
} }
} }
} }
if (current_dive->divetrip) { if (current_dive->divetrip) {
current_dive->divetrip->when = current_dive->when; current_dive->divetrip->when = current_dive->when;
@ -650,7 +647,7 @@ void MainTab::acceptChanges()
} }
// each dive that was selected might have had the temperatures in its active divecomputer changed // each dive that was selected might have had the temperatures in its active divecomputer changed
// so re-populate the temperatures - easiest way to do this is by calling fixup_dive // so re-populate the temperatures - easiest way to do this is by calling fixup_dive
Q_FOREACH(dive *d, notesBackup.keys()) { Q_FOREACH(dive * d, notesBackup.keys()) {
if (d) if (d)
fixup_dive(d); fixup_dive(d);
} }
@ -658,13 +655,13 @@ void MainTab::acceptChanges()
resetPallete(); resetPallete();
if (editMode == ADD || editMode == MANUALLY_ADDED_DIVE) { if (editMode == ADD || editMode == MANUALLY_ADDED_DIVE) {
MainWindow::instance()->dive_list()->unselectDives(); MainWindow::instance()->dive_list()->unselectDives();
struct dive *d = get_dive(dive_table.nr -1 ); struct dive *d = get_dive(dive_table.nr - 1);
// mark the dive as remembered (abusing the selected flag) // mark the dive as remembered (abusing the selected flag)
// and then clear that flag out on the other side of the sort_table() // and then clear that flag out on the other side of the sort_table()
d->selected = true; d->selected = true;
sort_table(&dive_table); sort_table(&dive_table);
int i = 0; int i = 0;
for_each_dive(i,d) { for_each_dive(i, d) {
if (d->selected) { if (d->selected) {
d->selected = false; d->selected = false;
break; break;
@ -672,7 +669,7 @@ void MainTab::acceptChanges()
} }
editMode = NONE; editMode = NONE;
MainWindow::instance()->refreshDisplay(); MainWindow::instance()->refreshDisplay();
MainWindow::instance()->dive_list()->selectDive( i, true ); MainWindow::instance()->dive_list()->selectDive(i, true);
} else { } else {
editMode = NONE; editMode = NONE;
MainWindow::instance()->dive_list()->rememberSelection(); MainWindow::instance()->dive_list()->rememberSelection();
@ -700,14 +697,14 @@ void MainTab::resetPallete()
ui.tagWidget->setPalette(p); ui.tagWidget->setPalette(p);
} }
#define EDIT_TEXT2(what, text) \ #define EDIT_TEXT2(what, text) \
textByteArray = text.toUtf8(); \ textByteArray = text.toUtf8(); \
free(what);\ free(what); \
what = strdup(textByteArray.data()); what = strdup(textByteArray.data());
#define EDIT_TEXT(what, text) \ #define EDIT_TEXT(what, text) \
QByteArray textByteArray = text.toUtf8(); \ QByteArray textByteArray = text.toUtf8(); \
free(what);\ free(what); \
what = strdup(textByteArray.data()); what = strdup(textByteArray.data());
void MainTab::rejectChanges() void MainTab::rejectChanges()
@ -718,19 +715,19 @@ void MainTab::rejectChanges()
MainWindow::instance()->dive_list()->setEnabled(true); MainWindow::instance()->dive_list()->setEnabled(true);
if (MainWindow::instance() && MainWindow::instance()->dive_list()->selectedTrips().count() == 1) { if (MainWindow::instance() && MainWindow::instance()->dive_list()->selectedTrips().count() == 1) {
ui.notes->setText(notesBackup[NULL].notes ); ui.notes->setText(notesBackup[NULL].notes);
ui.location->setText(notesBackup[NULL].location); ui.location->setText(notesBackup[NULL].location);
} else { } else {
if (lastMode == ADD) { if (lastMode == ADD) {
// clean up // clean up
DivePlannerPointsModel::instance()->cancelPlan(); DivePlannerPointsModel::instance()->cancelPlan();
} else if (lastMode == MANUALLY_ADDED_DIVE ) { } else if (lastMode == MANUALLY_ADDED_DIVE) {
// when we tried to edit a manually added dive, we destroyed // when we tried to edit a manually added dive, we destroyed
// the dive we edited, so let's just restore it from backup // the dive we edited, so let's just restore it from backup
DivePlannerPointsModel::instance()->restoreBackupDive(); DivePlannerPointsModel::instance()->restoreBackupDive();
} }
struct dive *curr = current_dive; struct dive *curr = current_dive;
ui.notes->setText(notesBackup[curr].notes ); ui.notes->setText(notesBackup[curr].notes);
ui.location->setText(notesBackup[curr].location); ui.location->setText(notesBackup[curr].location);
ui.buddy->setText(notesBackup[curr].buddy); ui.buddy->setText(notesBackup[curr].buddy);
ui.suit->setText(notesBackup[curr].suit); ui.suit->setText(notesBackup[curr].suit);
@ -744,7 +741,7 @@ void MainTab::rejectChanges()
if (curr) { if (curr) {
ui.dateTimeEdit->setDateTime(QDateTime::fromString(notesBackup[curr].datetime)); ui.dateTimeEdit->setDateTime(QDateTime::fromString(notesBackup[curr].datetime));
} else { } else {
QLineEdit *le = ui.dateTimeEdit->findChild<QLineEdit*>(); QLineEdit *le = ui.dateTimeEdit->findChild<QLineEdit *>();
le->setText(""); le->setText("");
} }
@ -810,74 +807,72 @@ void MainTab::rejectChanges()
} }
#undef EDIT_TEXT2 #undef EDIT_TEXT2
#define EDIT_SELECTED_DIVES( WHAT ) do { \ #define EDIT_SELECTED_DIVES(WHAT) \
if (editMode == NONE) \ do { \
return; \ if (editMode == NONE) \
\ return; \
for (int _i = 0; _i < dive_table.nr; _i++) { \ \
struct dive *mydive = get_dive(_i); \ for (int _i = 0; _i < dive_table.nr; _i++) { \
if (!mydive) \ struct dive *mydive = get_dive(_i); \
continue; \ if (!mydive) \
if (!mydive->selected) \ continue; \
continue; \ if (!mydive->selected) \
\ continue; \
WHAT; \ \
} \ WHAT; \
} while(0) } \
} while (0)
void markChangedWidget(QWidget *w) { void markChangedWidget(QWidget *w)
{
QPalette p; QPalette p;
qreal h, s, l, a; qreal h, s, l, a;
qApp->palette().color(QPalette::Text).getHslF(&h, &s, &l, &a); qApp->palette().color(QPalette::Text).getHslF(&h, &s, &l, &a);
p.setBrush(QPalette::Base, ( l <= 0.3 ) ? QColor(Qt::yellow).lighter() p.setBrush(QPalette::Base, (l <= 0.3) ? QColor(Qt::yellow).lighter() : (l <= 0.6) ? QColor(Qt::yellow).light() : /* else */ QColor(Qt::yellow).darker(300));
:( l <= 0.6 ) ? QColor(Qt::yellow).light()
:/* else */ QColor(Qt::yellow).darker(300)
);
w->setPalette(p); w->setPalette(p);
} }
void MainTab::on_buddy_textChanged() void MainTab::on_buddy_textChanged()
{ {
QString text = ui.buddy->toPlainText().split(",", QString::SkipEmptyParts).join(", "); QString text = ui.buddy->toPlainText().split(",", QString::SkipEmptyParts).join(", ");
EDIT_SELECTED_DIVES( EDIT_TEXT(mydive->buddy, text) ); EDIT_SELECTED_DIVES(EDIT_TEXT(mydive->buddy, text));
markChangedWidget(ui.buddy); markChangedWidget(ui.buddy);
} }
void MainTab::on_divemaster_textChanged() void MainTab::on_divemaster_textChanged()
{ {
QString text = ui.divemaster->toPlainText().split(",", QString::SkipEmptyParts).join(", "); QString text = ui.divemaster->toPlainText().split(",", QString::SkipEmptyParts).join(", ");
EDIT_SELECTED_DIVES( EDIT_TEXT(mydive->divemaster, text) ); EDIT_SELECTED_DIVES(EDIT_TEXT(mydive->divemaster, text));
markChangedWidget(ui.divemaster); markChangedWidget(ui.divemaster);
} }
void MainTab::on_airtemp_textChanged(const QString& text) void MainTab::on_airtemp_textChanged(const QString &text)
{ {
EDIT_SELECTED_DIVES( select_dc(&mydive->dc)->airtemp.mkelvin = parseTemperatureToMkelvin(text) ); EDIT_SELECTED_DIVES(select_dc(&mydive->dc)->airtemp.mkelvin = parseTemperatureToMkelvin(text));
markChangedWidget(ui.airtemp); markChangedWidget(ui.airtemp);
} }
void MainTab::on_watertemp_textChanged(const QString& text) void MainTab::on_watertemp_textChanged(const QString &text)
{ {
EDIT_SELECTED_DIVES( select_dc(&mydive->dc)->watertemp.mkelvin = parseTemperatureToMkelvin(text) ); EDIT_SELECTED_DIVES(select_dc(&mydive->dc)->watertemp.mkelvin = parseTemperatureToMkelvin(text));
markChangedWidget(ui.watertemp); markChangedWidget(ui.watertemp);
} }
void MainTab::on_dateTimeEdit_dateTimeChanged(const QDateTime& datetime) void MainTab::on_dateTimeEdit_dateTimeChanged(const QDateTime &datetime)
{ {
QDateTime dateTimeUtc(datetime); QDateTime dateTimeUtc(datetime);
dateTimeUtc.setTimeSpec(Qt::UTC); dateTimeUtc.setTimeSpec(Qt::UTC);
EDIT_SELECTED_DIVES( mydive->when = dateTimeUtc.toTime_t() ); EDIT_SELECTED_DIVES(mydive->when = dateTimeUtc.toTime_t());
markChangedWidget(ui.dateTimeEdit); markChangedWidget(ui.dateTimeEdit);
} }
void MainTab::saveTags() void MainTab::saveTags()
{ {
EDIT_SELECTED_DIVES( EDIT_SELECTED_DIVES(
QString tag; QString tag;
taglist_clear(mydive->tag_list); taglist_clear(mydive->tag_list);
foreach (tag, ui.tagWidget->getBlockStringList()) foreach(tag, ui.tagWidget->getBlockStringList())
taglist_add_tag(mydive->tag_list, tag.toUtf8().data()); taglist_add_tag(mydive->tag_list, tag.toUtf8().data()););
);
} }
void MainTab::on_tagWidget_textChanged() void MainTab::on_tagWidget_textChanged()
@ -885,7 +880,7 @@ void MainTab::on_tagWidget_textChanged()
markChangedWidget(ui.tagWidget); markChangedWidget(ui.tagWidget);
} }
void MainTab::on_location_textChanged(const QString& text) void MainTab::on_location_textChanged(const QString &text)
{ {
if (editMode == NONE) if (editMode == NONE)
return; return;
@ -896,14 +891,14 @@ void MainTab::on_location_textChanged(const QString& text)
} else if (editMode == DIVE || editMode == ADD || editMode == MANUALLY_ADDED_DIVE) { } else if (editMode == DIVE || editMode == ADD || editMode == MANUALLY_ADDED_DIVE) {
if (!ui.coordinates->isModified() || if (!ui.coordinates->isModified() ||
ui.coordinates->text().trimmed().isEmpty()) { ui.coordinates->text().trimmed().isEmpty()) {
struct dive* dive; struct dive *dive;
int i = 0; int i = 0;
for_each_dive(i, dive) { for_each_dive(i, dive) {
QString location(dive->location); QString location(dive->location);
if (location == text && if (location == text &&
(dive->latitude.udeg || dive->longitude.udeg)) { (dive->latitude.udeg || dive->longitude.udeg)) {
EDIT_SELECTED_DIVES( mydive->latitude = dive->latitude ); EDIT_SELECTED_DIVES(mydive->latitude = dive->latitude);
EDIT_SELECTED_DIVES( mydive->longitude = dive->longitude ); EDIT_SELECTED_DIVES(mydive->longitude = dive->longitude);
//Don't use updateGpsCoordinates() since we don't want to set modified state yet //Don't use updateGpsCoordinates() since we don't want to set modified state yet
ui.coordinates->setText(printGPSCoords(dive->latitude.udeg, dive->longitude.udeg)); ui.coordinates->setText(printGPSCoords(dive->latitude.udeg, dive->longitude.udeg));
markChangedWidget(ui.coordinates); markChangedWidget(ui.coordinates);
@ -911,15 +906,15 @@ void MainTab::on_location_textChanged(const QString& text)
} }
} }
} }
EDIT_SELECTED_DIVES( EDIT_TEXT(mydive->location, text) ); EDIT_SELECTED_DIVES(EDIT_TEXT(mydive->location, text));
MainWindow::instance()->globe()->repopulateLabels(); MainWindow::instance()->globe()->repopulateLabels();
} }
markChangedWidget(ui.location); markChangedWidget(ui.location);
} }
void MainTab::on_suit_textChanged(const QString& text) void MainTab::on_suit_textChanged(const QString &text)
{ {
EDIT_SELECTED_DIVES( EDIT_TEXT(mydive->suit, text) ); EDIT_SELECTED_DIVES(EDIT_TEXT(mydive->suit, text));
markChangedWidget(ui.suit); markChangedWidget(ui.suit);
} }
@ -932,14 +927,14 @@ void MainTab::on_notes_textChanged()
dive_trip_t *currentTrip = *MainWindow::instance()->dive_list()->selectedTrips().begin(); dive_trip_t *currentTrip = *MainWindow::instance()->dive_list()->selectedTrips().begin();
EDIT_TEXT(currentTrip->notes, ui.notes->toPlainText()); EDIT_TEXT(currentTrip->notes, ui.notes->toPlainText());
} else if (editMode == DIVE || editMode == ADD || editMode == MANUALLY_ADDED_DIVE) { } else if (editMode == DIVE || editMode == ADD || editMode == MANUALLY_ADDED_DIVE) {
EDIT_SELECTED_DIVES( EDIT_TEXT(mydive->notes, ui.notes->toPlainText()) ); EDIT_SELECTED_DIVES(EDIT_TEXT(mydive->notes, ui.notes->toPlainText()));
} }
markChangedWidget(ui.notes); markChangedWidget(ui.notes);
} }
#undef EDIT_TEXT #undef EDIT_TEXT
void MainTab::on_coordinates_textChanged(const QString& text) void MainTab::on_coordinates_textChanged(const QString &text)
{ {
bool gpsChanged = false; bool gpsChanged = false;
bool parsed = false; bool parsed = false;
@ -955,15 +950,15 @@ void MainTab::on_coordinates_textChanged(const QString& text)
void MainTab::on_rating_valueChanged(int value) void MainTab::on_rating_valueChanged(int value)
{ {
EDIT_SELECTED_DIVES(mydive->rating = value ); EDIT_SELECTED_DIVES(mydive->rating = value);
} }
void MainTab::on_visibility_valueChanged(int value) void MainTab::on_visibility_valueChanged(int value)
{ {
EDIT_SELECTED_DIVES( mydive->visibility = value ); EDIT_SELECTED_DIVES(mydive->visibility = value);
} }
void MainTab::editCylinderWidget(const QModelIndex& index) void MainTab::editCylinderWidget(const QModelIndex &index)
{ {
if (editMode == NONE) if (editMode == NONE)
enableEdition(); enableEdition();
@ -972,7 +967,7 @@ void MainTab::editCylinderWidget(const QModelIndex& index)
ui.cylinders->edit(index); ui.cylinders->edit(index);
} }
void MainTab::editWeightWidget(const QModelIndex& index) void MainTab::editWeightWidget(const QModelIndex &index)
{ {
if (editMode == NONE) if (editMode == NONE)
enableEdition(); enableEdition();
@ -985,7 +980,7 @@ QString MainTab::printGPSCoords(int lat, int lon)
{ {
unsigned int latdeg, londeg; unsigned int latdeg, londeg;
unsigned int latmin, lonmin; unsigned int latmin, lonmin;
double latsec, lonsec; double latsec, lonsec;
QString lath, lonh, result; QString lath, lonh, result;
if (!lat && !lon) if (!lat && !lon)

View file

@ -18,7 +18,7 @@
class QCompleter; class QCompleter;
struct dive; struct dive;
struct NotesBackup{ struct NotesBackup {
QString airtemp; QString airtemp;
QString watertemp; QString watertemp;
QString datetime; QString datetime;
@ -34,10 +34,10 @@ struct NotesBackup{
QString divemaster; QString divemaster;
QString tags; QString tags;
cylinder_t cylinders[MAX_CYLINDERS]; cylinder_t cylinders[MAX_CYLINDERS];
weightsystem_t weightsystem[MAX_WEIGHTSYSTEMS ]; weightsystem_t weightsystem[MAX_WEIGHTSYSTEMS];
}; };
struct Completers{ struct Completers {
QCompleter *location; QCompleter *location;
QCompleter *divemaster; QCompleter *divemaster;
QCompleter *buddy; QCompleter *buddy;
@ -45,11 +45,16 @@ struct Completers{
QCompleter *tags; QCompleter *tags;
}; };
class MainTab : public QTabWidget class MainTab : public QTabWidget {
{
Q_OBJECT Q_OBJECT
public: public:
enum EditMode { NONE, DIVE, TRIP, ADD, MANUALLY_ADDED_DIVE }; enum EditMode {
NONE,
DIVE,
TRIP,
ADD,
MANUALLY_ADDED_DIVE
};
MainTab(QWidget *parent); MainTab(QWidget *parent);
~MainTab(); ~MainTab();
@ -57,42 +62,44 @@ public:
void clearInfo(); void clearInfo();
void clearEquipment(); void clearEquipment();
void reload(); void reload();
bool eventFilter(QObject* , QEvent*); bool eventFilter(QObject *, QEvent *);
void initialUiSetup(); void initialUiSetup();
bool isEditing(); bool isEditing();
void updateCoordinatesText(qreal lat, qreal lon); void updateCoordinatesText(qreal lat, qreal lon);
public slots: public
slots:
void addCylinder_clicked(); void addCylinder_clicked();
void addWeight_clicked(); void addWeight_clicked();
void updateDiveInfo(int dive = selected_dive); void updateDiveInfo(int dive = selected_dive);
void acceptChanges(); void acceptChanges();
void rejectChanges(); void rejectChanges();
void on_location_textChanged(const QString& text); void on_location_textChanged(const QString &text);
void on_coordinates_textChanged(const QString& text); void on_coordinates_textChanged(const QString &text);
void on_divemaster_textChanged(); void on_divemaster_textChanged();
void on_buddy_textChanged(); void on_buddy_textChanged();
void on_suit_textChanged(const QString& text); void on_suit_textChanged(const QString &text);
void on_notes_textChanged(); void on_notes_textChanged();
void on_airtemp_textChanged(const QString& text); void on_airtemp_textChanged(const QString &text);
void on_watertemp_textChanged(const QString& text); void on_watertemp_textChanged(const QString &text);
void on_dateTimeEdit_dateTimeChanged(const QDateTime& datetime); void on_dateTimeEdit_dateTimeChanged(const QDateTime &datetime);
void on_rating_valueChanged(int value); void on_rating_valueChanged(int value);
void on_visibility_valueChanged(int value); void on_visibility_valueChanged(int value);
void on_tagWidget_textChanged(); void on_tagWidget_textChanged();
void editCylinderWidget(const QModelIndex& index); void editCylinderWidget(const QModelIndex &index);
void editWeightWidget(const QModelIndex& index); void editWeightWidget(const QModelIndex &index);
void addDiveStarted(); void addDiveStarted();
void addMessageAction(QAction* action); void addMessageAction(QAction *action);
void hideMessage(); void hideMessage();
void closeMessage(); void closeMessage();
void displayMessage(QString str); void displayMessage(QString str);
void enableEdition(EditMode newEditMode = NONE); void enableEdition(EditMode newEditMode = NONE);
void toggleTriggeredColumn(); void toggleTriggeredColumn();
private: private:
Ui::MainTab ui; Ui::MainTab ui;
WeightModel *weightModel; WeightModel *weightModel;
CylindersModel *cylindersModel; CylindersModel *cylindersModel;
QMap<dive*, NotesBackup> notesBackup; QMap<dive *, NotesBackup> notesBackup;
EditMode editMode; EditMode editMode;
BuddyCompletionModel buddyModel; BuddyCompletionModel buddyModel;

View file

@ -29,16 +29,33 @@ class MainTab;
class ProfileGraphicsView; class ProfileGraphicsView;
class QWebView; class QWebView;
enum MainWindowTitleFormat { MWTF_DEFAULT, MWTF_FILENAME }; enum MainWindowTitleFormat {
MWTF_DEFAULT,
MWTF_FILENAME
};
class MainWindow : public QMainWindow class MainWindow : public QMainWindow {
{ Q_OBJECT
Q_OBJECT
public: public:
enum {COLLAPSED, EXPANDED}; enum {
enum StackWidgetIndexes{ PROFILE, PLANNERPROFILE}; COLLAPSED,
enum InfoWidgetIndexes{ MAINTAB, PLANNERWIDGET}; EXPANDED
enum CurrentState{ VIEWALL, GLOBE_MAXIMIZED, INFO_MAXIMIZED, PROFILE_MAXIMIZED, LIST_MAXIMIZED}; };
enum StackWidgetIndexes {
PROFILE,
PLANNERPROFILE
};
enum InfoWidgetIndexes {
MAINTAB,
PLANNERWIDGET
};
enum CurrentState {
VIEWALL,
GLOBE_MAXIMIZED,
INFO_MAXIMIZED,
PROFILE_MAXIMIZED,
LIST_MAXIMIZED
};
MainWindow(); MainWindow();
virtual ~MainWindow(); virtual ~MainWindow();
@ -60,7 +77,8 @@ public:
void importFiles(const QStringList importFiles); void importFiles(const QStringList importFiles);
void cleanUpEmpty(); void cleanUpEmpty();
QTabWidget *tabWidget(); QTabWidget *tabWidget();
private slots: private
slots:
/* file menu action */ /* file menu action */
void recentFileTriggered(bool checked); void recentFileTriggered(bool checked);
void on_actionNew_triggered(); void on_actionNew_triggered();
@ -127,7 +145,8 @@ private slots:
protected: protected:
void closeEvent(QCloseEvent *); void closeEvent(QCloseEvent *);
public slots: public
slots:
void readSettings(); void readSettings();
void refreshDisplay(bool recreateDiveList = true); void refreshDisplay(bool recreateDiveList = true);
void showProfile(); void showProfile();
@ -149,7 +168,7 @@ private:
void beginChangeState(CurrentState s); void beginChangeState(CurrentState s);
void saveSplitterSizes(); void saveSplitterSizes();
QString lastUsedDir(); QString lastUsedDir();
void updateLastUsedDir(const QString& s); void updateLastUsedDir(const QString &s);
}; };
MainWindow *mainWindow(); MainWindow *mainWindow();

View file

@ -18,9 +18,9 @@
#include <QAbstractItemView> #include <QAbstractItemView>
#include <QApplication> #include <QApplication>
QSize DiveListDelegate::sizeHint(const QStyleOptionViewItem& option, const QModelIndex& index) const QSize DiveListDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const
{ {
return QSize(50,22); return QSize(50, 22);
} }
// Gets the index of the model in the currentRow and column. // Gets the index of the model in the currentRow and column.
@ -28,14 +28,12 @@ QSize DiveListDelegate::sizeHint(const QStyleOptionViewItem& option, const QMode
#define IDX(_XX) mymodel->index(currCombo.currRow, (_XX)) #define IDX(_XX) mymodel->index(currCombo.currRow, (_XX))
static bool keyboardFinished = false; static bool keyboardFinished = false;
StarWidgetsDelegate::StarWidgetsDelegate(QWidget* parent): StarWidgetsDelegate::StarWidgetsDelegate(QWidget *parent) : QStyledItemDelegate(parent),
QStyledItemDelegate(parent),
parentWidget(parent) parentWidget(parent)
{ {
} }
void StarWidgetsDelegate::paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const void StarWidgetsDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
{ {
QStyledItemDelegate::paint(painter, option, index); QStyledItemDelegate::paint(painter, option, index);
if (!index.isValid()) if (!index.isValid())
@ -46,7 +44,7 @@ void StarWidgetsDelegate::paint(QPainter* painter, const QStyleOptionViewItem& o
return; return;
int rating = value.toInt(); int rating = value.toInt();
int deltaY = option.rect.height() / 2 - StarWidget::starActive().height() / 2 ; int deltaY = option.rect.height() / 2 - StarWidget::starActive().height() / 2;
painter->save(); painter->save();
painter->setRenderHint(QPainter::Antialiasing, true); painter->setRenderHint(QPainter::Antialiasing, true);
for (int i = 0; i < rating; i++) for (int i = 0; i < rating; i++)
@ -56,20 +54,20 @@ void StarWidgetsDelegate::paint(QPainter* painter, const QStyleOptionViewItem& o
painter->restore(); painter->restore();
} }
QSize StarWidgetsDelegate::sizeHint(const QStyleOptionViewItem& option, const QModelIndex& index) const QSize StarWidgetsDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const
{ {
return QSize(IMG_SIZE * TOTALSTARS + SPACING * (TOTALSTARS-1), IMG_SIZE); return QSize(IMG_SIZE * TOTALSTARS + SPACING * (TOTALSTARS - 1), IMG_SIZE);
} }
ComboBoxDelegate::ComboBoxDelegate(QAbstractItemModel *model, QObject* parent): QStyledItemDelegate(parent), model(model) ComboBoxDelegate::ComboBoxDelegate(QAbstractItemModel *model, QObject *parent) : QStyledItemDelegate(parent), model(model)
{ {
connect(this, SIGNAL(closeEditor(QWidget*,QAbstractItemDelegate::EndEditHint)), connect(this, SIGNAL(closeEditor(QWidget *, QAbstractItemDelegate::EndEditHint)),
this, SLOT(revertModelData(QWidget*, QAbstractItemDelegate::EndEditHint))); this, SLOT(revertModelData(QWidget *, QAbstractItemDelegate::EndEditHint)));
} }
void ComboBoxDelegate::setEditorData(QWidget* editor, const QModelIndex& index) const void ComboBoxDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const
{ {
QComboBox *c = qobject_cast<QComboBox*>(editor); QComboBox *c = qobject_cast<QComboBox *>(editor);
QString data = index.model()->data(index, Qt::DisplayRole).toString(); QString data = index.model()->data(index, Qt::DisplayRole).toString();
int i = c->findText(data); int i = c->findText(data);
if (i != -1) if (i != -1)
@ -86,7 +84,7 @@ struct CurrSelected {
bool ignoreSelection; bool ignoreSelection;
} currCombo; } currCombo;
QWidget* ComboBoxDelegate::createEditor(QWidget* parent, const QStyleOptionViewItem& option, const QModelIndex& index) const QWidget *ComboBoxDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const
{ {
QComboBox *comboDelegate = new QComboBox(parent); QComboBox *comboDelegate = new QComboBox(parent);
comboDelegate->setModel(model); comboDelegate->setModel(model);
@ -95,14 +93,14 @@ QWidget* ComboBoxDelegate::createEditor(QWidget* parent, const QStyleOptionViewI
comboDelegate->setAutoCompletionCaseSensitivity(Qt::CaseInsensitive); comboDelegate->setAutoCompletionCaseSensitivity(Qt::CaseInsensitive);
comboDelegate->completer()->setCompletionMode(QCompleter::PopupCompletion); comboDelegate->completer()->setCompletionMode(QCompleter::PopupCompletion);
comboDelegate->view()->setEditTriggers(QAbstractItemView::AllEditTriggers); comboDelegate->view()->setEditTriggers(QAbstractItemView::AllEditTriggers);
comboDelegate->lineEdit()->installEventFilter( const_cast<QObject*>(qobject_cast<const QObject*>(this))); comboDelegate->lineEdit()->installEventFilter(const_cast<QObject *>(qobject_cast<const QObject *>(this)));
comboDelegate->view()->installEventFilter( const_cast<QObject*>(qobject_cast<const QObject*>(this))); comboDelegate->view()->installEventFilter(const_cast<QObject *>(qobject_cast<const QObject *>(this)));
connect(comboDelegate, SIGNAL(highlighted(QString)), this, SLOT(testActivation(QString))); connect(comboDelegate, SIGNAL(highlighted(QString)), this, SLOT(testActivation(QString)));
connect(comboDelegate, SIGNAL(activated(QString)), this, SLOT(fakeActivation())); connect(comboDelegate, SIGNAL(activated(QString)), this, SLOT(fakeActivation()));
connect(this, SIGNAL(closeEditor(QWidget*,QAbstractItemDelegate::EndEditHint)), this, SLOT(fixTabBehavior())); connect(this, SIGNAL(closeEditor(QWidget *, QAbstractItemDelegate::EndEditHint)), this, SLOT(fixTabBehavior()));
currCombo.comboEditor = comboDelegate; currCombo.comboEditor = comboDelegate;
currCombo.currRow = index.row(); currCombo.currRow = index.row();
currCombo.model = const_cast<QAbstractItemModel*>(index.model()); currCombo.model = const_cast<QAbstractItemModel *>(index.model());
keyboardFinished = false; keyboardFinished = false;
// Current display of things on Gnome3 looks like shit, so // Current display of things on Gnome3 looks like shit, so
@ -122,14 +120,15 @@ QWidget* ComboBoxDelegate::createEditor(QWidget* parent, const QStyleOptionViewI
* One thing is important, if the user writes a *new* cylinder or weight type, it will * One thing is important, if the user writes a *new* cylinder or weight type, it will
* be ADDED to the list, and the user will need to fill the other data. * be ADDED to the list, and the user will need to fill the other data.
*/ */
void ComboBoxDelegate::testActivation(const QString& currText) void ComboBoxDelegate::testActivation(const QString &currText)
{ {
currCombo.activeText = currText.isEmpty() ? currCombo.comboEditor->currentText() : currText; currCombo.activeText = currText.isEmpty() ? currCombo.comboEditor->currentText() : currText;
setModelData(currCombo.comboEditor, currCombo.model, QModelIndex()); setModelData(currCombo.comboEditor, currCombo.model, QModelIndex());
} }
// HACK, send a fake event so Qt thinks we hit 'enter' on the line edit. // HACK, send a fake event so Qt thinks we hit 'enter' on the line edit.
void ComboBoxDelegate::fakeActivation() { void ComboBoxDelegate::fakeActivation()
{
/* this test is needed because as soon as I show the selector, /* this test is needed because as soon as I show the selector,
* the first item gots selected, this sending an activated signal, * the first item gots selected, this sending an activated signal,
* calling this fakeActivation code and setting as the current, * calling this fakeActivation code and setting as the current,
@ -151,28 +150,28 @@ void ComboBoxDelegate::fakeActivation() {
void ComboBoxDelegate::fixTabBehavior() void ComboBoxDelegate::fixTabBehavior()
{ {
if (keyboardFinished) { if (keyboardFinished) {
setModelData(0,0,QModelIndex()); setModelData(0, 0, QModelIndex());
} }
} }
bool ComboBoxDelegate::eventFilter(QObject* object, QEvent* event) bool ComboBoxDelegate::eventFilter(QObject *object, QEvent *event)
{ {
// Reacts on Key_UP and Key_DOWN to show the QComboBox - list of choices. // Reacts on Key_UP and Key_DOWN to show the QComboBox - list of choices.
if (event->type() == QEvent::KeyPress || event->type() == QEvent::ShortcutOverride) { if (event->type() == QEvent::KeyPress || event->type() == QEvent::ShortcutOverride) {
if (object == currCombo.comboEditor) { // the 'LineEdit' part if (object == currCombo.comboEditor) { // the 'LineEdit' part
QKeyEvent *ev = static_cast<QKeyEvent*>(event); QKeyEvent *ev = static_cast<QKeyEvent *>(event);
if (ev->key() == Qt::Key_Up || ev->key() == Qt::Key_Down) { if (ev->key() == Qt::Key_Up || ev->key() == Qt::Key_Down) {
currCombo.ignoreSelection = true; currCombo.ignoreSelection = true;
currCombo.comboEditor->showPopup(); currCombo.comboEditor->showPopup();
} }
if (ev->key() == Qt::Key_Tab || ev->key() == Qt::Key_Enter || ev->key() == Qt::Key_Return) { if (ev->key() == Qt::Key_Tab || ev->key() == Qt::Key_Enter || ev->key() == Qt::Key_Return) {
currCombo.activeText = currCombo.comboEditor->currentText(); currCombo.activeText = currCombo.comboEditor->currentText();
keyboardFinished = true; keyboardFinished = true;
} }
} else { // the 'Drop Down Menu' part. } else { // the 'Drop Down Menu' part.
QKeyEvent *ev = static_cast<QKeyEvent*>(event); QKeyEvent *ev = static_cast<QKeyEvent *>(event);
if (ev->key() == Qt::Key_Enter || ev->key() == Qt::Key_Return || if (ev->key() == Qt::Key_Enter || ev->key() == Qt::Key_Return ||
ev->key() == Qt::Key_Tab || ev->key() == Qt::Key_Backtab || ev->key() == Qt::Key_Tab || ev->key() == Qt::Key_Backtab ||
ev->key() == Qt::Key_Escape) { ev->key() == Qt::Key_Escape) {
// treat Qt as a silly little boy - pretending that the key_return nwas pressed on the combo, // treat Qt as a silly little boy - pretending that the key_return nwas pressed on the combo,
// instead of the list of choices. this can be extended later for // instead of the list of choices. this can be extended later for
@ -185,13 +184,13 @@ bool ComboBoxDelegate::eventFilter(QObject* object, QEvent* event)
return QStyledItemDelegate::eventFilter(object, event); return QStyledItemDelegate::eventFilter(object, event);
} }
void ComboBoxDelegate::updateEditorGeometry(QWidget* editor, const QStyleOptionViewItem& option, const QModelIndex& index) const void ComboBoxDelegate::updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &index) const
{ {
QRect defaultRect = option.rect; QRect defaultRect = option.rect;
defaultRect.setX( defaultRect.x() -1); defaultRect.setX(defaultRect.x() - 1);
defaultRect.setY( defaultRect.y() -1); defaultRect.setY(defaultRect.y() - 1);
defaultRect.setWidth( defaultRect.width() + 2); defaultRect.setWidth(defaultRect.width() + 2);
defaultRect.setHeight( defaultRect.height() + 2); defaultRect.setHeight(defaultRect.height() + 2);
editor->setGeometry(defaultRect); editor->setGeometry(defaultRect);
} }
@ -201,16 +200,16 @@ struct RevertCylinderData {
int size; int size;
} currCylinderData; } currCylinderData;
void TankInfoDelegate::setModelData(QWidget* editor, QAbstractItemModel* model, const QModelIndex& thisindex) const void TankInfoDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &thisindex) const
{ {
CylindersModel *mymodel = qobject_cast<CylindersModel *>(currCombo.model); CylindersModel *mymodel = qobject_cast<CylindersModel *>(currCombo.model);
TankInfoModel *tanks = TankInfoModel::instance(); TankInfoModel *tanks = TankInfoModel::instance();
QModelIndexList matches = tanks->match(tanks->index(0,0), Qt::DisplayRole, currCombo.activeText); QModelIndexList matches = tanks->match(tanks->index(0, 0), Qt::DisplayRole, currCombo.activeText);
int row; int row;
if (matches.isEmpty()) { if (matches.isEmpty()) {
// we need to add this // we need to add this
tanks->insertRows(tanks->rowCount(), 1); tanks->insertRows(tanks->rowCount(), 1);
tanks->setData(tanks->index(tanks->rowCount() -1, 0), currCombo.activeText); tanks->setData(tanks->index(tanks->rowCount() - 1, 0), currCombo.activeText);
row = tanks->rowCount() - 1; row = tanks->rowCount() - 1;
} else { } else {
row = matches.first().row(); row = matches.first().row();
@ -223,17 +222,17 @@ void TankInfoDelegate::setModelData(QWidget* editor, QAbstractItemModel* model,
mymodel->passInData(IDX(CylindersModel::SIZE), tankSize); mymodel->passInData(IDX(CylindersModel::SIZE), tankSize);
} }
TankInfoDelegate::TankInfoDelegate(QObject* parent): ComboBoxDelegate(TankInfoModel::instance(), parent) TankInfoDelegate::TankInfoDelegate(QObject *parent) : ComboBoxDelegate(TankInfoModel::instance(), parent)
{ {
} }
void TankInfoDelegate::revertModelData(QWidget* widget, QAbstractItemDelegate::EndEditHint hint) void TankInfoDelegate::revertModelData(QWidget *widget, QAbstractItemDelegate::EndEditHint hint)
{ {
if ( if (
#if !defined __APPLE__ #if !defined __APPLE__
hint == QAbstractItemDelegate::NoHint || hint == QAbstractItemDelegate::NoHint ||
#endif #endif
hint == QAbstractItemDelegate::RevertModelCache) { hint == QAbstractItemDelegate::RevertModelCache) {
CylindersModel *mymodel = qobject_cast<CylindersModel *>(currCombo.model); CylindersModel *mymodel = qobject_cast<CylindersModel *>(currCombo.model);
mymodel->setData(IDX(CylindersModel::TYPE), currCylinderData.type, Qt::EditRole); mymodel->setData(IDX(CylindersModel::TYPE), currCylinderData.type, Qt::EditRole);
mymodel->passInData(IDX(CylindersModel::WORKINGPRESS), currCylinderData.pressure); mymodel->passInData(IDX(CylindersModel::WORKINGPRESS), currCylinderData.pressure);
@ -241,7 +240,7 @@ void TankInfoDelegate::revertModelData(QWidget* widget, QAbstractItemDelegate::E
} }
} }
QWidget* TankInfoDelegate::createEditor(QWidget* parent, const QStyleOptionViewItem& option, const QModelIndex& index) const QWidget *TankInfoDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const
{ {
// ncreate editor needs to be called before because it will populate a few // ncreate editor needs to be called before because it will populate a few
// things in the currCombo global var. // things in the currCombo global var.
@ -259,24 +258,24 @@ struct RevertWeightData {
int weight; int weight;
} currWeight; } currWeight;
void WSInfoDelegate::revertModelData(QWidget* widget, QAbstractItemDelegate::EndEditHint hint) void WSInfoDelegate::revertModelData(QWidget *widget, QAbstractItemDelegate::EndEditHint hint)
{ {
if ( if (
#if !defined __APPLE__ #if !defined __APPLE__
hint == QAbstractItemDelegate::NoHint || hint == QAbstractItemDelegate::NoHint ||
#endif #endif
hint == QAbstractItemDelegate::RevertModelCache) { hint == QAbstractItemDelegate::RevertModelCache) {
WeightModel *mymodel = qobject_cast<WeightModel *>(currCombo.model); WeightModel *mymodel = qobject_cast<WeightModel *>(currCombo.model);
mymodel->setData(IDX(WeightModel::TYPE), currWeight.type, Qt::EditRole); mymodel->setData(IDX(WeightModel::TYPE), currWeight.type, Qt::EditRole);
mymodel->passInData(IDX(WeightModel::WEIGHT), currWeight.weight); mymodel->passInData(IDX(WeightModel::WEIGHT), currWeight.weight);
} }
} }
void WSInfoDelegate::setModelData(QWidget* editor, QAbstractItemModel* model, const QModelIndex& thisindex) const void WSInfoDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &thisindex) const
{ {
WeightModel *mymodel = qobject_cast<WeightModel *>(currCombo.model); WeightModel *mymodel = qobject_cast<WeightModel *>(currCombo.model);
WSInfoModel *wsim = WSInfoModel::instance(); WSInfoModel *wsim = WSInfoModel::instance();
QModelIndexList matches = wsim->match(wsim->index(0,0), Qt::DisplayRole, currCombo.activeText); QModelIndexList matches = wsim->match(wsim->index(0, 0), Qt::DisplayRole, currCombo.activeText);
int row; int row;
if (matches.isEmpty()) { if (matches.isEmpty()) {
// we need to add this puppy // we need to add this puppy
@ -293,11 +292,11 @@ void WSInfoDelegate::setModelData(QWidget* editor, QAbstractItemModel* model, co
mymodel->passInData(IDX(WeightModel::WEIGHT), grams); mymodel->passInData(IDX(WeightModel::WEIGHT), grams);
} }
WSInfoDelegate::WSInfoDelegate(QObject* parent): ComboBoxDelegate(WSInfoModel::instance(), parent) WSInfoDelegate::WSInfoDelegate(QObject *parent) : ComboBoxDelegate(WSInfoModel::instance(), parent)
{ {
} }
QWidget* WSInfoDelegate::createEditor(QWidget* parent, const QStyleOptionViewItem& option, const QModelIndex& index) const QWidget *WSInfoDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const
{ {
/* First, call the combobox-create editor, it will setup our globals. */ /* First, call the combobox-create editor, it will setup our globals. */
QWidget *editor = ComboBoxDelegate::createEditor(parent, option, index); QWidget *editor = ComboBoxDelegate::createEditor(parent, option, index);
@ -308,24 +307,23 @@ QWidget* WSInfoDelegate::createEditor(QWidget* parent, const QStyleOptionViewIte
return editor; return editor;
} }
void AirTypesDelegate::revertModelData(QWidget* widget, QAbstractItemDelegate::EndEditHint hint) void AirTypesDelegate::revertModelData(QWidget *widget, QAbstractItemDelegate::EndEditHint hint)
{ {
} }
void AirTypesDelegate::setModelData(QWidget* editor, QAbstractItemModel* model, const QModelIndex& index) const void AirTypesDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const
{ {
if (!index.isValid()) if (!index.isValid())
return; return;
QComboBox *combo = qobject_cast<QComboBox*>(editor); QComboBox *combo = qobject_cast<QComboBox *>(editor);
model->setData(index, QVariant(combo->currentText())); model->setData(index, QVariant(combo->currentText()));
} }
AirTypesDelegate::AirTypesDelegate(QObject* parent) : ComboBoxDelegate(GasSelectionModel::instance(), parent) AirTypesDelegate::AirTypesDelegate(QObject *parent) : ComboBoxDelegate(GasSelectionModel::instance(), parent)
{ {
} }
ProfilePrintDelegate::ProfilePrintDelegate(QObject *parent) ProfilePrintDelegate::ProfilePrintDelegate(QObject *parent) : QStyledItemDelegate(parent)
: QStyledItemDelegate(parent)
{ {
} }

View file

@ -5,75 +5,83 @@
class QComboBox; class QComboBox;
class QPainter; class QPainter;
class DiveListDelegate : public QStyledItemDelegate{ class DiveListDelegate : public QStyledItemDelegate {
public: public:
explicit DiveListDelegate(QObject *parent = 0): QStyledItemDelegate(parent){} explicit DiveListDelegate(QObject *parent = 0)
QSize sizeHint ( const QStyleOptionViewItem & option, const QModelIndex & index ) const; : QStyledItemDelegate(parent)
{
}
QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const;
}; };
class StarWidgetsDelegate : public QStyledItemDelegate { class StarWidgetsDelegate : public QStyledItemDelegate {
Q_OBJECT Q_OBJECT
public: public:
explicit StarWidgetsDelegate(QWidget* parent = 0); explicit StarWidgetsDelegate(QWidget *parent = 0);
virtual void paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const; virtual void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const;
virtual QSize sizeHint(const QStyleOptionViewItem& option, const QModelIndex& index) const; virtual QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const;
private: private:
QWidget *parentWidget; QWidget *parentWidget;
}; };
class ComboBoxDelegate : public QStyledItemDelegate{ class ComboBoxDelegate : public QStyledItemDelegate {
Q_OBJECT Q_OBJECT
public: public:
explicit ComboBoxDelegate(QAbstractItemModel *model, QObject* parent = 0); explicit ComboBoxDelegate(QAbstractItemModel *model, QObject *parent = 0);
virtual QWidget* createEditor(QWidget* parent, const QStyleOptionViewItem& option, const QModelIndex& index) const; virtual QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const;
virtual void setEditorData(QWidget* editor, const QModelIndex& index) const; virtual void setEditorData(QWidget *editor, const QModelIndex &index) const;
virtual void updateEditorGeometry(QWidget* editor, const QStyleOptionViewItem& option, const QModelIndex& index) const; virtual void updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &index) const;
virtual bool eventFilter(QObject* object, QEvent* event); virtual bool eventFilter(QObject *object, QEvent *event);
public slots: public
void testActivation(const QString& currString = QString()); slots:
void testActivation(const QString &currString = QString());
//HACK: try to get rid of this in the future. //HACK: try to get rid of this in the future.
void fakeActivation(); void fakeActivation();
void fixTabBehavior(); void fixTabBehavior();
virtual void revertModelData(QWidget* widget, QAbstractItemDelegate::EndEditHint hint) = 0; virtual void revertModelData(QWidget *widget, QAbstractItemDelegate::EndEditHint hint) = 0;
protected: protected:
QAbstractItemModel *model; QAbstractItemModel *model;
}; };
class TankInfoDelegate : public ComboBoxDelegate{ class TankInfoDelegate : public ComboBoxDelegate {
Q_OBJECT Q_OBJECT
public: public:
explicit TankInfoDelegate(QObject* parent = 0); explicit TankInfoDelegate(QObject *parent = 0);
virtual void setModelData(QWidget* editor, QAbstractItemModel* model, const QModelIndex& index) const; virtual void setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const;
virtual QWidget* createEditor(QWidget* parent, const QStyleOptionViewItem& option, const QModelIndex& index) const; virtual QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const;
public slots: public
void revertModelData(QWidget* widget, QAbstractItemDelegate::EndEditHint hint); slots:
void revertModelData(QWidget *widget, QAbstractItemDelegate::EndEditHint hint);
}; };
class WSInfoDelegate : public ComboBoxDelegate{ class WSInfoDelegate : public ComboBoxDelegate {
Q_OBJECT Q_OBJECT
public: public:
explicit WSInfoDelegate(QObject* parent = 0); explicit WSInfoDelegate(QObject *parent = 0);
virtual void setModelData(QWidget* editor, QAbstractItemModel* model, const QModelIndex& index) const; virtual void setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const;
virtual QWidget* createEditor(QWidget* parent, const QStyleOptionViewItem& option, const QModelIndex& index) const; virtual QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const;
public slots: public
void revertModelData(QWidget* widget, QAbstractItemDelegate::EndEditHint hint); slots:
void revertModelData(QWidget *widget, QAbstractItemDelegate::EndEditHint hint);
}; };
class AirTypesDelegate : public ComboBoxDelegate{ class AirTypesDelegate : public ComboBoxDelegate {
Q_OBJECT Q_OBJECT
public: public:
explicit AirTypesDelegate(QObject* parent = 0); explicit AirTypesDelegate(QObject *parent = 0);
virtual void setModelData(QWidget* editor, QAbstractItemModel* model, const QModelIndex& index) const; virtual void setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const;
public slots: public
void revertModelData(QWidget* widget, QAbstractItemDelegate::EndEditHint hint); slots:
void revertModelData(QWidget *widget, QAbstractItemDelegate::EndEditHint hint);
}; };
/* ProfilePrintDelagate: /* ProfilePrintDelagate:
* this delegate is used to modify the look of the table that is printed * this delegate is used to modify the look of the table that is printed
* bellow profiles. * bellow profiles.
*/ */
class ProfilePrintDelegate : public QStyledItemDelegate class ProfilePrintDelegate : public QStyledItemDelegate {
{
public: public:
explicit ProfilePrintDelegate(QObject *parent = 0); explicit ProfilePrintDelegate(QObject *parent = 0);
void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const; void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const;

File diff suppressed because it is too large Load diff

View file

@ -19,14 +19,16 @@
QFont defaultModelFont(); QFont defaultModelFont();
// Encapsulates Boilerplate. // Encapsulates Boilerplate.
class CleanerTableModel : public QAbstractTableModel{ class CleanerTableModel : public QAbstractTableModel {
Q_OBJECT Q_OBJECT
public: public:
explicit CleanerTableModel(QObject *parent = 0); explicit CleanerTableModel(QObject *parent = 0);
virtual int columnCount(const QModelIndex& parent = QModelIndex()) const; virtual int columnCount(const QModelIndex &parent = QModelIndex()) const;
virtual QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const; virtual QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const;
protected: protected:
void setHeaderDataStrings(const QStringList& headers); void setHeaderDataStrings(const QStringList &headers);
private: private:
QStringList headers; QStringList headers;
}; };
@ -34,21 +36,27 @@ private:
/* Encapsulates the tank_info global variable /* Encapsulates the tank_info global variable
* to show on Qt's Model View System.*/ * to show on Qt's Model View System.*/
class TankInfoModel : public CleanerTableModel { class TankInfoModel : public CleanerTableModel {
Q_OBJECT Q_OBJECT
public: public:
static TankInfoModel* instance(); static TankInfoModel *instance();
enum Column {DESCRIPTION, ML, BAR}; enum Column {
DESCRIPTION,
ML,
BAR
};
TankInfoModel(); TankInfoModel();
/*reimp*/ QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const; /*reimp*/ QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const;
/*reimp*/ int rowCount(const QModelIndex& parent = QModelIndex()) const; /*reimp*/ int rowCount(const QModelIndex &parent = QModelIndex()) const;
/*reimp*/ bool insertRows(int row, int count, const QModelIndex& parent = QModelIndex()); /*reimp*/ bool insertRows(int row, int count, const QModelIndex &parent = QModelIndex());
/*reimp*/ bool setData(const QModelIndex& index, const QVariant& value, int role = Qt::EditRole); /*reimp*/ bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole);
const QString& biggerString() const; const QString &biggerString() const;
void clear(); void clear();
public slots: public
slots:
void update(); void update();
private: private:
int rows; int rows;
QString biggerEntry; QString biggerEntry;
@ -56,21 +64,25 @@ private:
/* Encapsulate ws_info */ /* Encapsulate ws_info */
class WSInfoModel : public CleanerTableModel { class WSInfoModel : public CleanerTableModel {
Q_OBJECT Q_OBJECT
public: public:
static WSInfoModel* instance(); static WSInfoModel *instance();
enum Column {DESCRIPTION, GR}; enum Column {
DESCRIPTION,
GR
};
WSInfoModel(); WSInfoModel();
/*reimp*/ QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const; /*reimp*/ QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const;
/*reimp*/ int rowCount(const QModelIndex& parent = QModelIndex()) const; /*reimp*/ int rowCount(const QModelIndex &parent = QModelIndex()) const;
/*reimp*/ bool insertRows(int row, int count, const QModelIndex& parent = QModelIndex()); /*reimp*/ bool insertRows(int row, int count, const QModelIndex &parent = QModelIndex());
/*reimp*/ bool setData(const QModelIndex& index, const QVariant& value, int role = Qt::EditRole); /*reimp*/ bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole);
const QString& biggerString() const; const QString &biggerString() const;
void clear(); void clear();
void update(); void update();
void updateInfo(); void updateInfo();
private: private:
int rows; int rows;
QString biggerEntry; QString biggerEntry;
@ -79,27 +91,38 @@ private:
/* Encapsulation of the Cylinder Model, that presents the /* Encapsulation of the Cylinder Model, that presents the
* Current cylinders that are used on a dive. */ * Current cylinders that are used on a dive. */
class CylindersModel : public CleanerTableModel { class CylindersModel : public CleanerTableModel {
Q_OBJECT Q_OBJECT
public: public:
enum Column {REMOVE, TYPE, SIZE, WORKINGPRESS, START, END, O2, HE, /* DEPTH, */ COLUMNS}; enum Column {
REMOVE,
TYPE,
SIZE,
WORKINGPRESS,
START,
END,
O2,
HE,
/* DEPTH, */ COLUMNS
};
explicit CylindersModel(QObject* parent = 0); explicit CylindersModel(QObject *parent = 0);
static CylindersModel *instance(); static CylindersModel *instance();
/*reimp*/ QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const; /*reimp*/ QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const;
/*reimp*/ int rowCount(const QModelIndex& parent = QModelIndex()) const; /*reimp*/ int rowCount(const QModelIndex &parent = QModelIndex()) const;
/*reimp*/ Qt::ItemFlags flags(const QModelIndex& index) const; /*reimp*/ Qt::ItemFlags flags(const QModelIndex &index) const;
/*reimp*/ bool setData(const QModelIndex& index, const QVariant& value, int role = Qt::EditRole); /*reimp*/ bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole);
void passInData(const QModelIndex& index, const QVariant& value); void passInData(const QModelIndex &index, const QVariant &value);
void add(); void add();
void clear(); void clear();
void update(); void update();
void setDive(struct dive *d); void setDive(struct dive *d);
cylinder_t *cylinderAt(const QModelIndex& index); cylinder_t *cylinderAt(const QModelIndex &index);
bool changed; bool changed;
public slots: public
void remove(const QModelIndex& index); slots:
void remove(const QModelIndex &index);
private: private:
struct dive *current; struct dive *current;
@ -109,26 +132,31 @@ private:
/* Encapsulation of the Weight Model, that represents /* Encapsulation of the Weight Model, that represents
* the current weights on a dive. */ * the current weights on a dive. */
class WeightModel : public CleanerTableModel { class WeightModel : public CleanerTableModel {
Q_OBJECT Q_OBJECT
public: public:
enum Column {REMOVE, TYPE, WEIGHT}; enum Column {
REMOVE,
TYPE,
WEIGHT
};
explicit WeightModel(QObject *parent = 0); explicit WeightModel(QObject *parent = 0);
/*reimp*/ QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const; /*reimp*/ QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const;
/*reimp*/ int rowCount(const QModelIndex& parent = QModelIndex()) const; /*reimp*/ int rowCount(const QModelIndex &parent = QModelIndex()) const;
/*reimp*/ Qt::ItemFlags flags(const QModelIndex& index) const; /*reimp*/ Qt::ItemFlags flags(const QModelIndex &index) const;
/*reimp*/ bool setData(const QModelIndex& index, const QVariant& value, int role = Qt::EditRole); /*reimp*/ bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole);
void passInData(const QModelIndex& index, const QVariant& value); void passInData(const QModelIndex &index, const QVariant &value);
void add(); void add();
void clear(); void clear();
void update(); void update();
void setDive(struct dive *d); void setDive(struct dive *d);
weightsystem_t *weightSystemAt(const QModelIndex& index); weightsystem_t *weightSystemAt(const QModelIndex &index);
bool changed; bool changed;
public slots: public
void remove(const QModelIndex& index); slots:
void remove(const QModelIndex &index);
private: private:
struct dive *current; struct dive *current;
@ -140,27 +168,43 @@ private:
*/ */
struct TreeItem { struct TreeItem {
Q_DECLARE_TR_FUNCTIONS (TreeItemDT); Q_DECLARE_TR_FUNCTIONS(TreeItemDT);
public: public:
virtual ~TreeItem(); virtual ~TreeItem();
TreeItem(); TreeItem();
virtual QVariant data (int column, int role) const; virtual QVariant data(int column, int role) const;
virtual bool setData(const QModelIndex& index, const QVariant& value, int role = Qt::EditRole); virtual bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole);
virtual Qt::ItemFlags flags(const QModelIndex &index) const; virtual Qt::ItemFlags flags(const QModelIndex &index) const;
int row() const; int row() const;
QList<TreeItem*> children; QList<TreeItem *> children;
TreeItem *parent; TreeItem *parent;
}; };
struct DiveItem : public TreeItem { struct DiveItem : public TreeItem {
enum Column {NR, DATE, RATING, DEPTH, DURATION, TEMPERATURE, TOTALWEIGHT, enum Column {
SUIT, CYLINDER, NITROX, SAC, OTU, MAXCNS, LOCATION, COLUMNS }; NR,
DATE,
RATING,
DEPTH,
DURATION,
TEMPERATURE,
TOTALWEIGHT,
SUIT,
CYLINDER,
NITROX,
SAC,
OTU,
MAXCNS,
LOCATION,
COLUMNS
};
virtual QVariant data(int column, int role) const; virtual QVariant data(int column, int role) const;
int diveId; int diveId;
virtual bool setData(const QModelIndex& index, const QVariant& value, int role = Qt::EditRole); virtual bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole);
virtual Qt::ItemFlags flags(const QModelIndex& index) const; virtual Qt::ItemFlags flags(const QModelIndex &index) const;
QString displayDate() const; QString displayDate() const;
QString displayDuration() const; QString displayDuration() const;
QString displayDepth() const; QString displayDepth() const;
@ -172,14 +216,13 @@ struct DiveItem : public TreeItem {
struct TripItem; struct TripItem;
class TreeModel : public QAbstractItemModel class TreeModel : public QAbstractItemModel {
{
Q_OBJECT Q_OBJECT
public: public:
TreeModel(QObject *parent = 0); TreeModel(QObject *parent = 0);
virtual ~TreeModel(); virtual ~TreeModel();
virtual QVariant data(const QModelIndex &index, int role) const; virtual QVariant data(const QModelIndex &index, int role) const;
/*reimp*/ int rowCount(const QModelIndex &parent = QModelIndex()) const; /*reimp*/ int rowCount(const QModelIndex &parent = QModelIndex()) const;
/*reimp*/ int columnCount(const QModelIndex &parent = QModelIndex()) const; /*reimp*/ int columnCount(const QModelIndex &parent = QModelIndex()) const;
/*reimp*/ QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const; /*reimp*/ QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const;
@ -193,40 +236,72 @@ protected:
class DiveTripModel : public TreeModel { class DiveTripModel : public TreeModel {
Q_OBJECT Q_OBJECT
public: public:
enum Column {NR, DATE, RATING, DEPTH, DURATION, TEMPERATURE, TOTALWEIGHT, enum Column {
SUIT, CYLINDER, NITROX, SAC, OTU, MAXCNS, LOCATION, COLUMNS }; NR,
DATE,
RATING,
DEPTH,
DURATION,
TEMPERATURE,
TOTALWEIGHT,
SUIT,
CYLINDER,
NITROX,
SAC,
OTU,
MAXCNS,
LOCATION,
COLUMNS
};
enum ExtraRoles{STAR_ROLE = Qt::UserRole + 1, DIVE_ROLE, TRIP_ROLE, SORT_ROLE, DIVE_IDX}; enum ExtraRoles {
enum Layout{TREE, LIST, CURRENT}; STAR_ROLE = Qt::UserRole + 1,
DIVE_ROLE,
TRIP_ROLE,
SORT_ROLE,
DIVE_IDX
};
enum Layout {
TREE,
LIST,
CURRENT
};
Qt::ItemFlags flags(const QModelIndex &index) const; Qt::ItemFlags flags(const QModelIndex &index) const;
virtual QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const; virtual QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const;
virtual bool setData(const QModelIndex& index, const QVariant& value, int role = Qt::EditRole); virtual bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole);
DiveTripModel(QObject* parent = 0); DiveTripModel(QObject *parent = 0);
Layout layout() const; Layout layout() const;
void setLayout(Layout layout); void setLayout(Layout layout);
private: private:
void setupModelData(); void setupModelData();
QMap<dive_trip_t*, TripItem*> trips; QMap<dive_trip_t *, TripItem *> trips;
Layout currentLayout; Layout currentLayout;
}; };
class DiveComputerModel : public CleanerTableModel class DiveComputerModel : public CleanerTableModel {
{
Q_OBJECT Q_OBJECT
public: public:
enum {REMOVE, MODEL, ID, NICKNAME}; enum {
REMOVE,
MODEL,
ID,
NICKNAME
};
DiveComputerModel(QMultiMap<QString, DiveComputerNode> &dcMap, QObject *parent = 0); DiveComputerModel(QMultiMap<QString, DiveComputerNode> &dcMap, QObject *parent = 0);
virtual QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const; virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const;
virtual int rowCount(const QModelIndex& parent = QModelIndex()) const; virtual int rowCount(const QModelIndex &parent = QModelIndex()) const;
virtual Qt::ItemFlags flags(const QModelIndex& index) const; virtual Qt::ItemFlags flags(const QModelIndex &index) const;
virtual bool setData(const QModelIndex& index, const QVariant& value, int role = Qt::EditRole); virtual bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole);
void update(); void update();
void keepWorkingList(); void keepWorkingList();
void dropWorkingList(); void dropWorkingList();
public slots: public
void remove(const QModelIndex& index); slots:
void remove(const QModelIndex &index);
private: private:
int numRows; int numRows;
QMultiMap<QString, DiveComputerNode> dcWorkingMap; QMultiMap<QString, DiveComputerNode> dcWorkingMap;
@ -235,11 +310,27 @@ private:
class YearlyStatisticsModel : public TreeModel { class YearlyStatisticsModel : public TreeModel {
Q_OBJECT Q_OBJECT
public: public:
enum { YEAR,DIVES,TOTAL_TIME,AVERAGE_TIME,SHORTEST_TIME,LONGEST_TIME,AVG_DEPTH,MIN_DEPTH, enum {
MAX_DEPTH,AVG_SAC,MIN_SAC,MAX_SAC,AVG_TEMP,MIN_TEMP,MAX_TEMP,COLUMNS}; YEAR,
DIVES,
TOTAL_TIME,
AVERAGE_TIME,
SHORTEST_TIME,
LONGEST_TIME,
AVG_DEPTH,
MIN_DEPTH,
MAX_DEPTH,
AVG_SAC,
MIN_SAC,
MAX_SAC,
AVG_TEMP,
MIN_TEMP,
MAX_TEMP,
COLUMNS
};
virtual QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const; virtual QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const;
YearlyStatisticsModel(QObject* parent = 0); YearlyStatisticsModel(QObject *parent = 0);
void update_yearly_stats(); void update_yearly_stats();
}; };
@ -262,8 +353,7 @@ struct TablePrintItem {
unsigned int colorBackground; unsigned int colorBackground;
}; };
class TablePrintModel : public QAbstractTableModel class TablePrintModel : public QAbstractTableModel {
{
Q_OBJECT Q_OBJECT
private: private:
@ -277,7 +367,7 @@ public:
void insertRow(int index = -1); void insertRow(int index = -1);
void callReset(); void callReset();
QVariant data(const QModelIndex &index, int role) const; QVariant data(const QModelIndex &index, int role) const;
bool setData(const QModelIndex &index, const QVariant &value, int role); bool setData(const QModelIndex &index, const QVariant &value, int role);
int rowCount(const QModelIndex &parent) const; int rowCount(const QModelIndex &parent) const;
int columnCount(const QModelIndex &parent) const; int columnCount(const QModelIndex &parent) const;
@ -287,8 +377,7 @@ public:
* this model is used when printing a data table under a profile. it requires * this model is used when printing a data table under a profile. it requires
* some exact usage of setSpan(..) on the target QTableView widget. * some exact usage of setSpan(..) on the target QTableView widget.
*/ */
class ProfilePrintModel : public QAbstractTableModel class ProfilePrintModel : public QAbstractTableModel {
{
Q_OBJECT Q_OBJECT
private: private:
@ -303,13 +392,14 @@ public:
void setDive(struct dive *divePtr); void setDive(struct dive *divePtr);
}; };
class GasSelectionModel : public QStringListModel{ class GasSelectionModel : public QStringListModel {
Q_OBJECT Q_OBJECT
public: public:
static GasSelectionModel* instance(); static GasSelectionModel *instance();
Qt::ItemFlags flags(const QModelIndex& index) const; Qt::ItemFlags flags(const QModelIndex &index) const;
virtual QVariant data(const QModelIndex& index, int role) const; virtual QVariant data(const QModelIndex &index, int role) const;
public slots: public
slots:
void repopulate(); void repopulate();
}; };
@ -317,11 +407,12 @@ public slots:
class LanguageModel : public QAbstractListModel { class LanguageModel : public QAbstractListModel {
Q_OBJECT Q_OBJECT
public: public:
static LanguageModel* instance(); static LanguageModel *instance();
virtual QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const; virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const;
virtual int rowCount(const QModelIndex& parent = QModelIndex()) const; virtual int rowCount(const QModelIndex &parent = QModelIndex()) const;
private: private:
LanguageModel(QObject* parent = 0); LanguageModel(QObject *parent = 0);
QStringList languages; QStringList languages;
}; };

View file

@ -6,7 +6,7 @@
#include <QMessageBox> #include <QMessageBox>
#include <QSortFilterProxyModel> #include <QSortFilterProxyModel>
PreferencesDialog* PreferencesDialog::instance() PreferencesDialog *PreferencesDialog::instance()
{ {
static PreferencesDialog *dialog = new PreferencesDialog(MainWindow::instance()); static PreferencesDialog *dialog = new PreferencesDialog(MainWindow::instance());
dialog->setAttribute(Qt::WA_QuitOnClose, false); dialog->setAttribute(Qt::WA_QuitOnClose, false);
@ -14,10 +14,10 @@ PreferencesDialog* PreferencesDialog::instance()
return dialog; return dialog;
} }
PreferencesDialog::PreferencesDialog(QWidget* parent, Qt::WindowFlags f) : QDialog(parent, f) PreferencesDialog::PreferencesDialog(QWidget *parent, Qt::WindowFlags f) : QDialog(parent, f)
{ {
ui.setupUi(this); ui.setupUi(this);
connect(ui.buttonBox, SIGNAL(clicked(QAbstractButton*)), this, SLOT(buttonClicked(QAbstractButton*))); connect(ui.buttonBox, SIGNAL(clicked(QAbstractButton *)), this, SLOT(buttonClicked(QAbstractButton *)));
connect(ui.gflow, SIGNAL(valueChanged(int)), this, SLOT(gflowChanged(int))); connect(ui.gflow, SIGNAL(valueChanged(int)), this, SLOT(gflowChanged(int)));
connect(ui.gfhigh, SIGNAL(valueChanged(int)), this, SLOT(gfhighChanged(int))); connect(ui.gfhigh, SIGNAL(valueChanged(int)), this, SLOT(gfhighChanged(int)));
loadSettings(); loadSettings();
@ -25,7 +25,7 @@ PreferencesDialog::PreferencesDialog(QWidget* parent, Qt::WindowFlags f) : QDial
rememberPrefs(); rememberPrefs();
} }
#define DANGER_GF ( gf > 100 ) ? "* { color: red; }" : "" #define DANGER_GF (gf > 100) ? "* { color: red; }" : ""
void PreferencesDialog::gflowChanged(int gf) void PreferencesDialog::gflowChanged(int gf)
{ {
ui.gflow->setStyleSheet(DANGER_GF); ui.gflow->setStyleSheet(DANGER_GF);
@ -80,7 +80,7 @@ void PreferencesDialog::setUiFromPrefs()
ui.fontsize->setValue(prefs.font_size); ui.fontsize->setValue(prefs.font_size);
ui.defaultfilename->setText(prefs.default_filename); ui.defaultfilename->setText(prefs.default_filename);
ui.default_cylinder->clear(); ui.default_cylinder->clear();
for(int i=0; tank_info[i].name != NULL; i++) { for (int i = 0; tank_info[i].name != NULL; i++) {
ui.default_cylinder->addItem(tank_info[i].name); ui.default_cylinder->addItem(tank_info[i].name);
if (prefs.default_cylinder && strcmp(tank_info[i].name, prefs.default_cylinder) == 0) if (prefs.default_cylinder && strcmp(tank_info[i].name, prefs.default_cylinder) == 0)
ui.default_cylinder->setCurrentIndex(i); ui.default_cylinder->setCurrentIndex(i);
@ -101,7 +101,7 @@ void PreferencesDialog::setUiFromPrefs()
s.beginGroup("Language"); s.beginGroup("Language");
ui.languageSystemDefault->setChecked(s.value("UseSystemLanguage", true).toBool()); ui.languageSystemDefault->setChecked(s.value("UseSystemLanguage", true).toBool());
QAbstractItemModel *m = ui.languageView->model(); QAbstractItemModel *m = ui.languageView->model();
QModelIndexList languages = m->match( m->index(0,0), Qt::UserRole, s.value("UiLanguage").toString()); QModelIndexList languages = m->match(m->index(0, 0), Qt::UserRole, s.value("UiLanguage").toString());
if (languages.count()) if (languages.count())
ui.languageView->setCurrentIndex(languages.first()); ui.languageView->setCurrentIndex(languages.first());
} }
@ -120,47 +120,47 @@ void PreferencesDialog::rememberPrefs()
#define SB(V, B) s.setValue(V, (int)(B->isChecked() ? 1 : 0)) #define SB(V, B) s.setValue(V, (int)(B->isChecked() ? 1 : 0))
#define GET_UNIT(name, field, f, t) \ #define GET_UNIT(name, field, f, t) \
v = s.value(QString(name)); \ v = s.value(QString(name)); \
if (v.isValid()) \ if (v.isValid()) \
prefs.units.field = (v.toInt() == (t)) ? (t) : (f); \ prefs.units.field = (v.toInt() == (t)) ? (t) : (f); \
else \ else \
prefs.units.field = default_prefs.units.field prefs.units.field = default_prefs.units.field
#define GET_BOOL(name, field) \ #define GET_BOOL(name, field) \
v = s.value(QString(name)); \ v = s.value(QString(name)); \
if (v.isValid()) \ if (v.isValid()) \
prefs.field = v.toInt() ? true : false; \ prefs.field = v.toInt() ? true : false; \
else \ else \
prefs.field = default_prefs.field prefs.field = default_prefs.field
#define GET_DOUBLE(name, field) \ #define GET_DOUBLE(name, field) \
v = s.value(QString(name)); \ v = s.value(QString(name)); \
if (v.isValid()) \ if (v.isValid()) \
prefs.field = v.toDouble(); \ prefs.field = v.toDouble(); \
else \ else \
prefs.field = default_prefs.field prefs.field = default_prefs.field
#define GET_INT(name, field) \ #define GET_INT(name, field) \
v = s.value(QString(name)); \ v = s.value(QString(name)); \
if (v.isValid()) \ if (v.isValid()) \
prefs.field = v.toInt(); \ prefs.field = v.toInt(); \
else \ else \
prefs.field = default_prefs.field prefs.field = default_prefs.field
#define GET_TXT(name, field) \ #define GET_TXT(name, field) \
v = s.value(QString(name)); \ v = s.value(QString(name)); \
if (v.isValid()) \ if (v.isValid()) \
prefs.field = strdup(v.toString().toUtf8().constData()); \ prefs.field = strdup(v.toString().toUtf8().constData()); \
else \ else \
prefs.field = default_prefs.field prefs.field = default_prefs.field
#define GET_TXT(name, field) \ #define GET_TXT(name, field) \
v = s.value(QString(name)); \ v = s.value(QString(name)); \
if (v.isValid()) \ if (v.isValid()) \
prefs.field = strdup(v.toString().toUtf8().constData()); \ prefs.field = strdup(v.toString().toUtf8().constData()); \
else \ else \
prefs.field = default_prefs.field prefs.field = default_prefs.field
void PreferencesDialog::syncSettings() void PreferencesDialog::syncSettings()
{ {
@ -288,7 +288,7 @@ void PreferencesDialog::loadSettings()
s.endGroup(); s.endGroup();
} }
void PreferencesDialog::buttonClicked(QAbstractButton* button) void PreferencesDialog::buttonClicked(QAbstractButton *button)
{ {
switch (ui.buttonBox->standardButton(button)) { switch (ui.buttonBox->standardButton(button)) {
case QDialogButtonBox::Discard: case QDialogButtonBox::Discard:
@ -313,7 +313,7 @@ void PreferencesDialog::on_chooseFile_clicked()
QFileInfo fi(system_default_filename()); QFileInfo fi(system_default_filename());
QString choosenFileName = QFileDialog::getOpenFileName(this, tr("Open Default Log File"), fi.absolutePath(), tr("Subsurface XML files (*.ssrf *.xml *.XML)")); QString choosenFileName = QFileDialog::getOpenFileName(this, tr("Open Default Log File"), fi.absolutePath(), tr("Subsurface XML files (*.ssrf *.xml *.XML)"));
if(!choosenFileName.isEmpty()) if (!choosenFileName.isEmpty())
ui.defaultfilename->setText(choosenFileName); ui.defaultfilename->setText(choosenFileName);
} }

View file

@ -9,16 +9,17 @@
class QAbstractButton; class QAbstractButton;
class PreferencesDialog :public QDialog{ class PreferencesDialog : public QDialog {
Q_OBJECT Q_OBJECT
public: public:
static PreferencesDialog* instance(); static PreferencesDialog *instance();
void showEvent(QShowEvent* ); void showEvent(QShowEvent *);
void emitSettingsChanged(); void emitSettingsChanged();
signals: signals:
void settingsChanged(); void settingsChanged();
public slots: public
void buttonClicked(QAbstractButton* button); slots:
void buttonClicked(QAbstractButton *button);
void on_chooseFile_clicked(); void on_chooseFile_clicked();
void syncSettings(); void syncSettings();
void loadSettings(); void loadSettings();
@ -28,7 +29,7 @@ public slots:
void gfhighChanged(int gf); void gfhighChanged(int gf);
private: private:
explicit PreferencesDialog(QWidget* parent = 0, Qt::WindowFlags f = 0); explicit PreferencesDialog(QWidget *parent = 0, Qt::WindowFlags f = 0);
void setUiFromPrefs(); void setUiFromPrefs();
Ui::PreferencesDialog ui; Ui::PreferencesDialog ui;
struct preferences oldPrefs; struct preferences oldPrefs;

View file

@ -14,7 +14,7 @@
PrintDialog::PrintDialog(QWidget *parent, Qt::WindowFlags f) : QDialog(parent, f) PrintDialog::PrintDialog(QWidget *parent, Qt::WindowFlags f) : QDialog(parent, f)
{ {
// options template (are we storing these in the settings?) // options template (are we storing these in the settings?)
struct options tempOptions = {options::PRETTY, 0, 2, false, 65, 15, 12}; struct options tempOptions = { options::PRETTY, 0, 2, false, 65, 15, 12 };
printOptions = tempOptions; printOptions = tempOptions;
// create a print layout and pass the printer and options // create a print layout and pass the printer and options

View file

@ -11,7 +11,7 @@ class PrintLayout;
// should be based on a custom QPrintDialog class // should be based on a custom QPrintDialog class
class PrintDialog : public QDialog { class PrintDialog : public QDialog {
Q_OBJECT Q_OBJECT
public: public:
struct options printOptions; struct options printOptions;
@ -23,7 +23,8 @@ private:
QProgressBar *progressBar; QProgressBar *progressBar;
QPrinter printer; QPrinter printer;
private slots: private
slots:
void previewClicked(); void previewClicked();
void printClicked(); void printClicked();
void onPaintRequested(QPrinter *); void onPaintRequested(QPrinter *);

View file

@ -43,7 +43,7 @@ PrintLayout::PrintLayout(PrintDialog *dialogPtr, QPrinter *printerPtr, struct op
profilePrintColumnWidths.append(dw - 3); profilePrintColumnWidths.append(dw - 3);
profilePrintColumnWidths.append(dw - 3); profilePrintColumnWidths.append(dw - 3);
profilePrintColumnWidths.append(dw + 6); // fit to 100% profilePrintColumnWidths.append(dw + 6); // fit to 100%
const int sr = 12; // smallest row height in pixels const int sr = 12; // smallest row height in pixels
profilePrintRowHeights.append(sr); profilePrintRowHeights.append(sr);
profilePrintRowHeights.append(sr + 4); profilePrintRowHeights.append(sr + 4);
profilePrintRowHeights.append(sr); profilePrintRowHeights.append(sr);
@ -84,8 +84,8 @@ void PrintLayout::setup()
printerDpi = printer->resolution(); printerDpi = printer->resolution();
pageRect = printer->pageRect(); pageRect = printer->pageRect();
scaleX = (qreal)printerDpi/(qreal)screenDpiX; scaleX = (qreal)printerDpi / (qreal)screenDpiX;
scaleY = (qreal)printerDpi/(qreal)screenDpiY; scaleY = (qreal)printerDpi / (qreal)screenDpiY;
// a printer page scalled to screen DPI // a printer page scalled to screen DPI
scaledPageW = pageRect.width() / scaleX; scaledPageW = pageRect.width() / scaleX;
@ -114,7 +114,7 @@ int PrintLayout::estimateTotalDives() const
* p is the padding between elements * p is the padding between elements
*/ */
#define ESTIMATE_DIVE_DIM(S, n, p) \ #define ESTIMATE_DIVE_DIM(S, n, p) \
((S) - ((n) - 1) * (p)) / (n); ((S) - ((n) - 1) * (p)) / (n);
void PrintLayout::printProfileDives(int divesPerRow, int divesPerColumn) void PrintLayout::printProfileDives(int divesPerRow, int divesPerColumn)
{ {
@ -220,7 +220,7 @@ QTableView *PrintLayout::createProfileTable(ProfilePrintModel *model, const int
table->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); table->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
hHeader->setVisible(false); hHeader->setVisible(false);
vHeader->setVisible(false); vHeader->setVisible(false);
#if QT_VERSION < QT_VERSION_CHECK(5,0,0) #if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
hHeader->setResizeMode(QHeaderView::Fixed); hHeader->setResizeMode(QHeaderView::Fixed);
vHeader->setResizeMode(QHeaderView::Fixed); vHeader->setResizeMode(QHeaderView::Fixed);
#else #else
@ -269,8 +269,7 @@ QTableView *PrintLayout::createProfileTable(ProfilePrintModel *model, const int
table->setShowGrid(false); table->setShowGrid(false);
table->setStyleSheet( table->setStyleSheet(
"QTableView { border: none }" "QTableView { border: none }"
"QTableView::item { border: 0px; padding-left: 2px; padding-right: 2px; }" "QTableView::item { border: 0px; padding-left: 2px; padding-right: 2px; }");
);
// return // return
return table; return table;
} }
@ -290,7 +289,7 @@ void PrintLayout::printTable()
table.setFocusPolicy(Qt::NoFocus); table.setFocusPolicy(Qt::NoFocus);
table.horizontalHeader()->setVisible(false); table.horizontalHeader()->setVisible(false);
table.verticalHeader()->setVisible(false); table.verticalHeader()->setVisible(false);
#if QT_VERSION < QT_VERSION_CHECK(5,0,0) #if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
table.horizontalHeader()->setResizeMode(QHeaderView::Fixed); table.horizontalHeader()->setResizeMode(QHeaderView::Fixed);
table.verticalHeader()->setResizeMode(QHeaderView::ResizeToContents); table.verticalHeader()->setResizeMode(QHeaderView::ResizeToContents);
#else #else
@ -300,12 +299,11 @@ void PrintLayout::printTable()
table.setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); table.setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
table.setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); table.setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
// fit table to one page initially // fit table to one page initially
table.resize(scaledPageW, scaledPageH); table.resize(scaledPageW, scaledPageH);
// don't show border // don't show border
table.setStyleSheet( table.setStyleSheet(
"QTableView { border: none }" "QTableView { border: none }");
);
// create and fill a table model // create and fill a table model
TablePrintModel model; TablePrintModel model;

View file

@ -43,7 +43,7 @@ private:
void addTablePrintHeadingRow(TablePrintModel *model, int row) const; void addTablePrintHeadingRow(TablePrintModel *model, int row) const;
signals: signals:
void signalProgress(int); void signalProgress(int);
}; };
#endif // PRINTLAYOUT_H #endif // PRINTLAYOUT_H

View file

@ -9,7 +9,7 @@
// should be based on a custom QPrintDialog class // should be based on a custom QPrintDialog class
class PrintOptions : public QWidget { class PrintOptions : public QWidget {
Q_OBJECT Q_OBJECT
public: public:
explicit PrintOptions(QWidget *parent = 0, struct options *printOpt = 0); explicit PrintOptions(QWidget *parent = 0, struct options *printOpt = 0);
@ -23,7 +23,8 @@ private:
struct options *printOptions; struct options *printOptions;
bool hasSetupSlots; bool hasSetupSlots;
private slots: private
slots:
void sliderPHeightMoved(int value); void sliderPHeightMoved(int value);
void sliderOHeightMoved(int value); void sliderOHeightMoved(int value);
void sliderNHeightMoved(int value); void sliderNHeightMoved(int value);

View file

@ -2,37 +2,37 @@
#include <QPropertyAnimation> #include <QPropertyAnimation>
#include <QPointF> #include <QPointF>
namespace Animations { namespace Animations
void hide(QObject* obj)
{ {
QPropertyAnimation *animation = new QPropertyAnimation(obj, "opacity");
animation->setStartValue(1);
animation->setEndValue(0);
animation->start(QAbstractAnimation::DeleteWhenStopped);
}
void animDelete(QObject* obj) void hide(QObject *obj)
{ {
QPropertyAnimation *animation = new QPropertyAnimation(obj, "opacity"); QPropertyAnimation *animation = new QPropertyAnimation(obj, "opacity");
obj->connect(animation, SIGNAL(finished()), SLOT(deleteLater())); animation->setStartValue(1);
animation->setStartValue(1); animation->setEndValue(0);
animation->setEndValue(0); animation->start(QAbstractAnimation::DeleteWhenStopped);
animation->start(QAbstractAnimation::DeleteWhenStopped); }
}
void moveTo(QObject* obj, qreal x, qreal y, int msecs) void animDelete(QObject *obj)
{ {
QPropertyAnimation *animation = new QPropertyAnimation(obj, "pos"); QPropertyAnimation *animation = new QPropertyAnimation(obj, "opacity");
animation->setDuration(msecs); obj->connect(animation, SIGNAL(finished()), SLOT(deleteLater()));
animation->setStartValue(obj->property("pos").toPointF()); animation->setStartValue(1);
animation->setEndValue(QPointF(x, y)); animation->setEndValue(0);
animation->start(QAbstractAnimation::DeleteWhenStopped); animation->start(QAbstractAnimation::DeleteWhenStopped);
} }
void moveTo(QObject* obj, const QPointF& pos, int msecs) void moveTo(QObject *obj, qreal x, qreal y, int msecs)
{ {
moveTo(obj, pos.x(), pos.y(), msecs); QPropertyAnimation *animation = new QPropertyAnimation(obj, "pos");
} animation->setDuration(msecs);
animation->setStartValue(obj->property("pos").toPointF());
animation->setEndValue(QPointF(x, y));
animation->start(QAbstractAnimation::DeleteWhenStopped);
}
void moveTo(QObject *obj, const QPointF &pos, int msecs)
{
moveTo(obj, pos.x(), pos.y(), msecs);
}
} }

View file

@ -6,10 +6,11 @@
class QObject; class QObject;
namespace Animations{ namespace Animations
{
void hide(QObject *obj); void hide(QObject *obj);
void moveTo(QObject *obj, qreal x, qreal y, int msecs = 500); void moveTo(QObject *obj, qreal x, qreal y, int msecs = 500);
void moveTo(QObject *obj, const QPointF& pos, int msecs = 500); void moveTo(QObject *obj, const QPointF &pos, int msecs = 500);
void animDelete(QObject *obj); void animDelete(QObject *obj);
} }

View file

@ -12,7 +12,8 @@
#include <QStyleOption> #include <QStyleOption>
#include <QSettings> #include <QSettings>
static QPen gridPen(){ static QPen gridPen()
{
QPen pen; QPen pen;
pen.setColor(getColor(TIME_GRID)); pen.setColor(getColor(TIME_GRID));
pen.setWidth(2); pen.setWidth(2);
@ -50,7 +51,7 @@ void DiveCartesianAxis::setMinimum(double minimum)
min = minimum; min = minimum;
} }
void DiveCartesianAxis::setTextColor(const QColor& color) void DiveCartesianAxis::setTextColor(const QColor &color)
{ {
textColor = color; textColor = color;
} }
@ -73,7 +74,6 @@ DiveCartesianAxis::DiveCartesianAxis() : QObject(),
DiveCartesianAxis::~DiveCartesianAxis() DiveCartesianAxis::~DiveCartesianAxis()
{ {
} }
void DiveCartesianAxis::setLineSize(qreal lineSize) void DiveCartesianAxis::setLineSize(qreal lineSize)
@ -93,31 +93,33 @@ QColor DiveCartesianAxis::colorForValue(double value)
void DiveCartesianAxis::setTextVisible(bool arg1) void DiveCartesianAxis::setTextVisible(bool arg1)
{ {
if(textVisibility == arg1){ if (textVisibility == arg1) {
return; return;
} }
textVisibility = arg1; textVisibility = arg1;
Q_FOREACH(DiveTextItem *item, labels){ Q_FOREACH(DiveTextItem * item, labels) {
item->setVisible(textVisibility); item->setVisible(textVisibility);
} }
} }
void DiveCartesianAxis::setLinesVisible(bool arg1) void DiveCartesianAxis::setLinesVisible(bool arg1)
{ {
if(lineVisibility == arg1){ if (lineVisibility == arg1) {
return; return;
} }
lineVisibility = arg1; lineVisibility = arg1;
Q_FOREACH(DiveLineItem *item, lines){ Q_FOREACH(DiveLineItem * item, lines) {
item->setVisible(lineVisibility ); item->setVisible(lineVisibility);
} }
} }
template<typename T> void emptyList( QList<T*>& list, double steps){ template <typename T>
void emptyList(QList<T *> &list, double steps)
{
if (!list.isEmpty() && list.size() > steps) { if (!list.isEmpty() && list.size() > steps) {
while (list.size() > steps) { while (list.size() > steps) {
T *removedItem = list.takeLast(); T *removedItem = list.takeLast();
Animations::animDelete(removedItem); Animations::animDelete(removedItem);
} }
} }
} }
@ -148,7 +150,7 @@ void DiveCartesianAxis::updateTicks()
} else if (orientation == BottomToTop) { } else if (orientation == BottomToTop) {
begin = m.y2(); begin = m.y2();
stepSize = (m.y2() - m.y1()); stepSize = (m.y2() - m.y1());
} else if (orientation == LeftToRight ) { } else if (orientation == LeftToRight) {
begin = m.x1(); begin = m.x1();
stepSize = (m.x2() - m.x1()); stepSize = (m.x2() - m.x1());
} else if (orientation == RightToLeft) { } else if (orientation == RightToLeft) {
@ -159,11 +161,11 @@ void DiveCartesianAxis::updateTicks()
for (int i = 0, count = labels.size(); i < count; i++, currValueText += interval) { for (int i = 0, count = labels.size(); i < count; i++, currValueText += interval) {
qreal childPos = (orientation == TopToBottom || orientation == LeftToRight) ? qreal childPos = (orientation == TopToBottom || orientation == LeftToRight) ?
begin + i * stepSize : begin + i * stepSize :
begin - i * stepSize; begin - i * stepSize;
labels[i]->setText(textForValue(currValueText)); labels[i]->setText(textForValue(currValueText));
if ( orientation == LeftToRight || orientation == RightToLeft) { if (orientation == LeftToRight || orientation == RightToLeft) {
labels[i]->animateMoveTo(childPos, m.y1() + tick_size); labels[i]->animateMoveTo(childPos, m.y1() + tick_size);
} else { } else {
labels[i]->animateMoveTo(m.x1() - tick_size, childPos); labels[i]->animateMoveTo(m.x1() - tick_size, childPos);
@ -172,10 +174,10 @@ void DiveCartesianAxis::updateTicks()
for (int i = 0, count = lines.size(); i < count; i++, currValueLine += interval) { for (int i = 0, count = lines.size(); i < count; i++, currValueLine += interval) {
qreal childPos = (orientation == TopToBottom || orientation == LeftToRight) ? qreal childPos = (orientation == TopToBottom || orientation == LeftToRight) ?
begin + i * stepSize : begin + i * stepSize :
begin - i * stepSize; begin - i * stepSize;
if ( orientation == LeftToRight || orientation == RightToLeft) { if (orientation == LeftToRight || orientation == RightToLeft) {
lines[i]->animateMoveTo(childPos, m.y1()); lines[i]->animateMoveTo(childPos, m.y1());
} else { } else {
lines[i]->animateMoveTo(m.x1(), childPos); lines[i]->animateMoveTo(m.x1(), childPos);
@ -183,10 +185,10 @@ void DiveCartesianAxis::updateTicks()
} }
// Add's the rest of the needed Ticks / Text. // Add's the rest of the needed Ticks / Text.
for (int i = labels.size(); i < steps; i++, currValueText += interval) { for (int i = labels.size(); i < steps; i++, currValueText += interval) {
qreal childPos; qreal childPos;
if (orientation == TopToBottom || orientation == LeftToRight) { if (orientation == TopToBottom || orientation == LeftToRight) {
childPos = begin + i * stepSize; childPos = begin + i * stepSize;
} else { } else {
childPos = begin - i * stepSize; childPos = begin - i * stepSize;
} }
@ -202,17 +204,17 @@ void DiveCartesianAxis::updateTicks()
label->setPos(scene()->sceneRect().width() + 10, m.y1() + tick_size); // position it outside of the scene); label->setPos(scene()->sceneRect().width() + 10, m.y1() + tick_size); // position it outside of the scene);
label->animateMoveTo(childPos, m.y1() + tick_size); label->animateMoveTo(childPos, m.y1() + tick_size);
} else { } else {
label->setAlignment(Qt::AlignVCenter| Qt::AlignLeft); label->setAlignment(Qt::AlignVCenter | Qt::AlignLeft);
label->setPos(m.x1() - tick_size, scene()->sceneRect().height() + 10); label->setPos(m.x1() - tick_size, scene()->sceneRect().height() + 10);
label->animateMoveTo(m.x1() - tick_size, childPos); label->animateMoveTo(m.x1() - tick_size, childPos);
} }
} }
// Add's the rest of the needed Ticks / Text. // Add's the rest of the needed Ticks / Text.
for (int i = lines.size(); i < steps; i++, currValueText += interval) { for (int i = lines.size(); i < steps; i++, currValueText += interval) {
qreal childPos; qreal childPos;
if (orientation == TopToBottom || orientation == LeftToRight) { if (orientation == TopToBottom || orientation == LeftToRight) {
childPos = begin + i * stepSize; childPos = begin + i * stepSize;
} else { } else {
childPos = begin - i * stepSize; childPos = begin - i * stepSize;
} }
@ -225,7 +227,7 @@ void DiveCartesianAxis::updateTicks()
line->setZValue(0); line->setZValue(0);
lines.push_back(line); lines.push_back(line);
if (orientation == RightToLeft || orientation == LeftToRight) { if (orientation == RightToLeft || orientation == LeftToRight) {
line->setLine(0,-line_size,0, 0); line->setLine(0, -line_size, 0, 0);
line->animateMoveTo(childPos, m.y1()); line->animateMoveTo(childPos, m.y1());
} else { } else {
QPointF p1 = mapFromScene(3, 0); QPointF p1 = mapFromScene(3, 0);
@ -235,13 +237,13 @@ void DiveCartesianAxis::updateTicks()
} }
} }
Q_FOREACH(DiveTextItem *item, labels) Q_FOREACH(DiveTextItem * item, labels)
item->setVisible(textVisibility); item->setVisible(textVisibility);
Q_FOREACH(DiveLineItem *item, lines) Q_FOREACH(DiveLineItem * item, lines)
item->setVisible(lineVisibility); item->setVisible(lineVisibility);
} }
void DiveCartesianAxis::animateChangeLine(const QLineF& newLine) void DiveCartesianAxis::animateChangeLine(const QLineF &newLine)
{ {
setLine(newLine); setLine(newLine);
updateTicks(); updateTicks();
@ -263,15 +265,15 @@ void DiveCartesianAxis::setTickInterval(double i)
interval = i; interval = i;
} }
qreal DiveCartesianAxis::valueAt(const QPointF& p) const qreal DiveCartesianAxis::valueAt(const QPointF &p) const
{ {
QLineF m = line(); QLineF m = line();
QPointF relativePosition = p; QPointF relativePosition = p;
relativePosition -= pos(); // normalize p based on the axis' offset on screen relativePosition -= pos(); // normalize p based on the axis' offset on screen
double retValue = (orientation == LeftToRight || orientation == RightToLeft) ? double retValue = (orientation == LeftToRight || orientation == RightToLeft) ?
max * (relativePosition.x() - m.x1()) / (m.x2() - m.x1()) : max * (relativePosition.x() - m.x1()) / (m.x2() - m.x1()) :
max * (relativePosition.y() - m.y1()) / (m.y2() - m.y1()); max * (relativePosition.y() - m.y1()) / (m.y2() - m.y1());
return retValue; return retValue;
} }
@ -283,12 +285,12 @@ qreal DiveCartesianAxis::posAtValue(qreal value)
double size = max - min; double size = max - min;
// unused for now: // unused for now:
// double distanceFromOrigin = value - min; // double distanceFromOrigin = value - min;
double percent = IS_FP_SAME(min,max) ? 0.0 : (value - min) / size; double percent = IS_FP_SAME(min, max) ? 0.0 : (value - min) / size;
double realSize = orientation == LeftToRight || orientation == RightToLeft? double realSize = orientation == LeftToRight || orientation == RightToLeft ?
m.x2() - m.x1() : m.x2() - m.x1() :
m.y2() - m.y1(); m.y2() - m.y1();
// Inverted axis, just invert the percentage. // Inverted axis, just invert the percentage.
if (orientation == RightToLeft || orientation == BottomToTop) if (orientation == RightToLeft || orientation == BottomToTop)
@ -296,14 +298,14 @@ qreal DiveCartesianAxis::posAtValue(qreal value)
double retValue = realSize * percent; double retValue = realSize * percent;
double adjusted = double adjusted =
orientation == LeftToRight ? retValue + m.x1() + p.x() : orientation == LeftToRight ? retValue + m.x1() + p.x() :
orientation == RightToLeft ? retValue + m.x1() + p.x() : orientation == RightToLeft ? retValue + m.x1() + p.x() :
orientation == TopToBottom ? retValue + m.y1() + p.y() : orientation == TopToBottom ? retValue + m.y1() + p.y() :
/* entation == BottomToTop */ retValue + m.y1() + p.y() ; /* entation == BottomToTop */ retValue + m.y1() + p.y();
return adjusted; return adjusted;
} }
qreal DiveCartesianAxis::percentAt(const QPointF& p) qreal DiveCartesianAxis::percentAt(const QPointF &p)
{ {
qreal value = valueAt(p); qreal value = valueAt(p);
double size = max - min; double size = max - min;
@ -326,7 +328,7 @@ double DiveCartesianAxis::fontLabelScale() const
return labelScale; return labelScale;
} }
void DiveCartesianAxis::setColor(const QColor& color) void DiveCartesianAxis::setColor(const QColor &color)
{ {
QPen defaultPen(color); QPen defaultPen(color);
defaultPen.setJoinStyle(Qt::RoundJoin); defaultPen.setJoinStyle(Qt::RoundJoin);
@ -361,24 +363,24 @@ DepthAxis::DepthAxis() : showWithPPGraph(false)
{ {
connect(PreferencesDialog::instance(), SIGNAL(settingsChanged()), this, SLOT(settingsChanged())); connect(PreferencesDialog::instance(), SIGNAL(settingsChanged()), this, SLOT(settingsChanged()));
// force the correct size of the line. // force the correct size of the line.
showWithPPGraph = !isPPGraphEnabled(); showWithPPGraph = !isPPGraphEnabled();
settingsChanged(); settingsChanged();
} }
void DepthAxis::settingsChanged() void DepthAxis::settingsChanged()
{ {
// bool ppGraph = isPPGraphEnabled(); // bool ppGraph = isPPGraphEnabled();
// if ( ppGraph == showWithPPGraph){ // if ( ppGraph == showWithPPGraph){
// return; // return;
// } // }
// //
// if (ppGraph) { // if (ppGraph) {
// animateChangeLine(shrinkedLine); // animateChangeLine(shrinkedLine);
// } else { // } else {
// animateChangeLine(expandedLine); // animateChangeLine(expandedLine);
// } // }
// showWithPPGraph = ppGraph; // showWithPPGraph = ppGraph;
} }
QColor TimeAxis::colorForValue(double value) QColor TimeAxis::colorForValue(double value)
@ -390,16 +392,16 @@ QColor TimeAxis::colorForValue(double value)
QString TimeAxis::textForValue(double value) QString TimeAxis::textForValue(double value)
{ {
int nr = value / 60; int nr = value / 60;
if (maximum() < 600 ) if (maximum() < 600)
return QString("%1:%2").arg(nr).arg( (int)value%60, 2, 10, QChar('0')); return QString("%1:%2").arg(nr).arg((int)value % 60, 2, 10, QChar('0'));
return QString::number(nr); return QString::number(nr);
} }
void TimeAxis::updateTicks() void TimeAxis::updateTicks()
{ {
DiveCartesianAxis::updateTicks(); DiveCartesianAxis::updateTicks();
if (maximum() > 600){ if (maximum() > 600) {
for(int i = 0; i < labels.count(); i++){ for (int i = 0; i < labels.count(); i++) {
labels[i]->setVisible(i % 2); labels[i]->setVisible(i % 2);
} }
} }
@ -407,7 +409,7 @@ void TimeAxis::updateTicks()
QString TemperatureAxis::textForValue(double value) QString TemperatureAxis::textForValue(double value)
{ {
return QString::number(mkelvin_to_C( (int) value)); return QString::number(mkelvin_to_C((int)value));
} }
PartialGasPressureAxis::PartialGasPressureAxis() PartialGasPressureAxis::PartialGasPressureAxis()
@ -415,7 +417,7 @@ PartialGasPressureAxis::PartialGasPressureAxis()
connect(PreferencesDialog::instance(), SIGNAL(settingsChanged()), this, SLOT(preferencesChanged())); connect(PreferencesDialog::instance(), SIGNAL(settingsChanged()), this, SLOT(preferencesChanged()));
} }
void PartialGasPressureAxis::setModel(DivePlotDataModel* m) void PartialGasPressureAxis::setModel(DivePlotDataModel *m)
{ {
model = m; model = m;
connect(model, SIGNAL(dataChanged(QModelIndex, QModelIndex)), this, SLOT(preferencesChanged())); connect(model, SIGNAL(dataChanged(QModelIndex, QModelIndex)), this, SLOT(preferencesChanged()));
@ -435,8 +437,8 @@ void PartialGasPressureAxis::preferencesChanged()
double max = showPhe ? model->pheMax() : -1; double max = showPhe ? model->pheMax() : -1;
if (showPn2 && model->pn2Max() > max) if (showPn2 && model->pn2Max() > max)
max = model->pn2Max(); max = model->pn2Max();
if( showPo2 && model->po2Max() > max) if (showPo2 && model->po2Max() > max)
max = model->po2Max(); max = model->po2Max();
qreal pp = floor(max * 10.0) / 10.0 + 0.2; qreal pp = floor(max * 10.0) / 10.0 + 0.2;
@ -444,6 +446,6 @@ void PartialGasPressureAxis::preferencesChanged()
return; return;
setMaximum(pp); setMaximum(pp);
setTickInterval( pp > 4 ? 0.5 : 0.25 ); setTickInterval(pp > 4 ? 0.5 : 0.25);
updateTicks(); updateTicks();
} }

View file

@ -9,14 +9,19 @@ class DiveTextItem;
class DiveLineItem; class DiveLineItem;
class DivePlotDataModel; class DivePlotDataModel;
class DiveCartesianAxis : public QObject, public QGraphicsLineItem{ class DiveCartesianAxis : public QObject, public QGraphicsLineItem {
Q_OBJECT Q_OBJECT
Q_PROPERTY(QLineF line WRITE setLine READ line) Q_PROPERTY(QLineF line WRITE setLine READ line)
Q_PROPERTY(QPointF pos WRITE setPos READ pos) Q_PROPERTY(QPointF pos WRITE setPos READ pos)
Q_PROPERTY(qreal x WRITE setX READ x) Q_PROPERTY(qreal x WRITE setX READ x)
Q_PROPERTY(qreal y WRITE setY READ y) Q_PROPERTY(qreal y WRITE setY READ y)
public: public:
enum Orientation{TopToBottom, BottomToTop, LeftToRight, RightToLeft}; enum Orientation {
TopToBottom,
BottomToTop,
LeftToRight,
RightToLeft
};
DiveCartesianAxis(); DiveCartesianAxis();
virtual ~DiveCartesianAxis(); virtual ~DiveCartesianAxis();
void setMinimum(double minimum); void setMinimum(double minimum);
@ -30,28 +35,30 @@ public:
double tickInterval() const; double tickInterval() const;
double tickSize() const; double tickSize() const;
double fontLabelScale() const; double fontLabelScale() const;
qreal valueAt(const QPointF& p) const; qreal valueAt(const QPointF &p) const;
qreal percentAt(const QPointF& p); qreal percentAt(const QPointF &p);
qreal posAtValue(qreal value); qreal posAtValue(qreal value);
void setColor(const QColor& color); void setColor(const QColor &color);
void setTextColor(const QColor& color); void setTextColor(const QColor &color);
void animateChangeLine(const QLineF& newLine); void animateChangeLine(const QLineF &newLine);
void setTextVisible(bool arg1); void setTextVisible(bool arg1);
void setLinesVisible(bool arg1); void setLinesVisible(bool arg1);
void setLineSize(qreal lineSize); void setLineSize(qreal lineSize);
int unitSystem; int unitSystem;
public slots: public
slots:
virtual void updateTicks(); virtual void updateTicks();
signals: signals:
void sizeChanged(); void sizeChanged();
void maxChanged(); void maxChanged();
protected: protected:
virtual QString textForValue(double value); virtual QString textForValue(double value);
virtual QColor colorForValue(double value); virtual QColor colorForValue(double value);
Orientation orientation; Orientation orientation;
QList<DiveTextItem*> labels; QList<DiveTextItem *> labels;
QList<DiveLineItem*> lines; QList<DiveLineItem *> lines;
double min; double min;
double max; double max;
double interval; double interval;
@ -67,11 +74,14 @@ class DepthAxis : public DiveCartesianAxis {
Q_OBJECT Q_OBJECT
public: public:
DepthAxis(); DepthAxis();
protected: protected:
QString textForValue(double value); QString textForValue(double value);
QColor colorForValue(double value); QColor colorForValue(double value);
private slots: private
slots:
void settingsChanged(); void settingsChanged();
private: private:
bool showWithPPGraph; bool showWithPPGraph;
}; };
@ -80,24 +90,27 @@ class TimeAxis : public DiveCartesianAxis {
Q_OBJECT Q_OBJECT
public: public:
virtual void updateTicks(); virtual void updateTicks();
protected: protected:
QString textForValue(double value); QString textForValue(double value);
QColor colorForValue(double value); QColor colorForValue(double value);
}; };
class TemperatureAxis : public DiveCartesianAxis{ class TemperatureAxis : public DiveCartesianAxis {
Q_OBJECT Q_OBJECT
protected: protected:
QString textForValue(double value); QString textForValue(double value);
}; };
class PartialGasPressureAxis : public DiveCartesianAxis{ class PartialGasPressureAxis : public DiveCartesianAxis {
Q_OBJECT Q_OBJECT
public: public:
PartialGasPressureAxis(); PartialGasPressureAxis();
void setModel(DivePlotDataModel *model); void setModel(DivePlotDataModel *model);
public slots: public
slots:
void preferencesChanged(); void preferencesChanged();
private: private:
DivePlotDataModel *model; DivePlotDataModel *model;
}; };

View file

@ -6,26 +6,29 @@
#include "dive.h" #include "dive.h"
#include <QDebug> #include <QDebug>
DiveEventItem::DiveEventItem(QObject* parent): DivePixmapItem(parent), DiveEventItem::DiveEventItem(QObject *parent) : DivePixmapItem(parent),
vAxis(NULL), hAxis(NULL), dataModel(NULL), internalEvent(NULL) vAxis(NULL),
hAxis(NULL),
dataModel(NULL),
internalEvent(NULL)
{ {
setFlag(ItemIgnoresTransformations); setFlag(ItemIgnoresTransformations);
} }
void DiveEventItem::setHorizontalAxis(DiveCartesianAxis* axis) void DiveEventItem::setHorizontalAxis(DiveCartesianAxis *axis)
{ {
hAxis = axis; hAxis = axis;
recalculatePos(true); recalculatePos(true);
} }
void DiveEventItem::setModel(DivePlotDataModel* model) void DiveEventItem::setModel(DivePlotDataModel *model)
{ {
dataModel = model; dataModel = model;
recalculatePos(true); recalculatePos(true);
} }
void DiveEventItem::setVerticalAxis(DiveCartesianAxis* axis) void DiveEventItem::setVerticalAxis(DiveCartesianAxis *axis)
{ {
vAxis = axis; vAxis = axis;
recalculatePos(true); recalculatePos(true);
@ -37,7 +40,7 @@ struct event *DiveEventItem::getEvent()
return internalEvent; return internalEvent;
} }
void DiveEventItem::setEvent(struct event* ev) void DiveEventItem::setEvent(struct event *ev)
{ {
if (!ev) if (!ev)
return; return;
@ -49,7 +52,7 @@ void DiveEventItem::setEvent(struct event* ev)
void DiveEventItem::setupPixmap() void DiveEventItem::setupPixmap()
{ {
#define EVENT_PIXMAP( PIX ) QPixmap(QString(PIX)).scaled(20, 20, Qt::KeepAspectRatio, Qt::SmoothTransformation) #define EVENT_PIXMAP(PIX) QPixmap(QString(PIX)).scaled(20, 20, Qt::KeepAspectRatio, Qt::SmoothTransformation)
if (!internalEvent->name) { if (!internalEvent->name) {
setPixmap(EVENT_PIXMAP(":warning")); setPixmap(EVENT_PIXMAP(":warning"));
} else if ((strcmp(internalEvent->name, "bookmark") == 0)) { } else if ((strcmp(internalEvent->name, "bookmark") == 0)) {
@ -84,7 +87,7 @@ void DiveEventItem::setupToolTipString()
else else
name += QString(tr("EAN%1")).arg(o2); name += QString(tr("EAN%1")).arg(o2);
} else if (name == "SP change") { } else if (name == "SP change") {
name += QString(":%1").arg((double) value / 1000); name += QString(":%1").arg((double)value / 1000);
} else { } else {
name += QString(":%1").arg(value); name += QString(":%1").arg(value);
} }
@ -98,7 +101,7 @@ void DiveEventItem::setupToolTipString()
setToolTip(name); setToolTip(name);
} }
void DiveEventItem::eventVisibilityChanged(const QString& eventName, bool visible) void DiveEventItem::eventVisibilityChanged(const QString &eventName, bool visible)
{ {
} }
@ -107,7 +110,7 @@ void DiveEventItem::recalculatePos(bool instant)
if (!vAxis || !hAxis || !internalEvent || !dataModel) if (!vAxis || !hAxis || !internalEvent || !dataModel)
return; return;
QModelIndexList result = dataModel->match(dataModel->index(0,DivePlotDataModel::TIME), Qt::DisplayRole, internalEvent->time.seconds ); QModelIndexList result = dataModel->match(dataModel->index(0, DivePlotDataModel::TIME), Qt::DisplayRole, internalEvent->time.seconds);
if (result.isEmpty()) { if (result.isEmpty()) {
Q_ASSERT("can't find a spot in the dataModel"); Q_ASSERT("can't find a spot in the dataModel");
hide(); hide();
@ -122,5 +125,5 @@ void DiveEventItem::recalculatePos(bool instant)
if (!instant) if (!instant)
Animations::moveTo(this, x, y, 500); Animations::moveTo(this, x, y, 500);
else else
setPos(x,y); setPos(x, y);
} }

View file

@ -10,22 +10,24 @@ struct event;
class DiveEventItem : public DivePixmapItem { class DiveEventItem : public DivePixmapItem {
Q_OBJECT Q_OBJECT
public: public:
DiveEventItem(QObject* parent = 0); DiveEventItem(QObject *parent = 0);
void setEvent(struct event *ev); void setEvent(struct event *ev);
struct event *getEvent(); struct event *getEvent();
void eventVisibilityChanged(const QString& eventName, bool visible); void eventVisibilityChanged(const QString &eventName, bool visible);
void setVerticalAxis(DiveCartesianAxis *axis); void setVerticalAxis(DiveCartesianAxis *axis);
void setHorizontalAxis(DiveCartesianAxis *axis); void setHorizontalAxis(DiveCartesianAxis *axis);
void setModel(DivePlotDataModel *model); void setModel(DivePlotDataModel *model);
public slots: public
slots:
void recalculatePos(bool instant = false); void recalculatePos(bool instant = false);
private: private:
void setupToolTipString(); void setupToolTipString();
void setupPixmap(); void setupPixmap();
DiveCartesianAxis *vAxis; DiveCartesianAxis *vAxis;
DiveCartesianAxis *hAxis; DiveCartesianAxis *hAxis;
DivePlotDataModel *dataModel; DivePlotDataModel *dataModel;
struct event* internalEvent; struct event *internalEvent;
}; };
#endif // DIVEEVENTITEM_H #endif // DIVEEVENTITEM_H

View file

@ -4,7 +4,6 @@
DiveLineItem::DiveLineItem(QGraphicsItem *parent) : QGraphicsLineItem(parent) DiveLineItem::DiveLineItem(QGraphicsItem *parent) : QGraphicsLineItem(parent)
{ {
} }
void DiveLineItem::animatedHide() void DiveLineItem::animatedHide()

View file

@ -1,6 +1,5 @@
#include "divepixmapitem.h" #include "divepixmapitem.h"
DivePixmapItem::DivePixmapItem(QObject* parent): QObject(parent), QGraphicsPixmapItem() DivePixmapItem::DivePixmapItem(QObject *parent) : QObject(parent), QGraphicsPixmapItem()
{ {
} }

View file

@ -4,14 +4,14 @@
#include <QObject> #include <QObject>
#include <QGraphicsPixmapItem> #include <QGraphicsPixmapItem>
class DivePixmapItem : public QObject, public QGraphicsPixmapItem{ class DivePixmapItem : public QObject, public QGraphicsPixmapItem {
Q_OBJECT Q_OBJECT
Q_PROPERTY(qreal opacity WRITE setOpacity READ opacity) Q_PROPERTY(qreal opacity WRITE setOpacity READ opacity)
Q_PROPERTY(QPointF pos WRITE setPos READ pos) Q_PROPERTY(QPointF pos WRITE setPos READ pos)
Q_PROPERTY(qreal x WRITE setX READ x) Q_PROPERTY(qreal x WRITE setX READ x)
Q_PROPERTY(qreal y WRITE setY READ y) Q_PROPERTY(qreal y WRITE setY READ y)
public: public:
DivePixmapItem(QObject* parent = 0); DivePixmapItem(QObject *parent = 0);
}; };
#endif // DIVEPIXMAPITEM_H #endif // DIVEPIXMAPITEM_H

View file

@ -8,60 +8,76 @@
#include "divelist.h" #include "divelist.h"
#include <QDebug> #include <QDebug>
DivePlotDataModel::DivePlotDataModel(QObject* parent) : QAbstractTableModel(parent) , diveId(0) DivePlotDataModel::DivePlotDataModel(QObject *parent) : QAbstractTableModel(parent), diveId(0)
{ {
memset(&pInfo, 0, sizeof(pInfo)); memset(&pInfo, 0, sizeof(pInfo));
} }
int DivePlotDataModel::columnCount(const QModelIndex& parent) const int DivePlotDataModel::columnCount(const QModelIndex &parent) const
{ {
return COLUMNS; return COLUMNS;
} }
QVariant DivePlotDataModel::data(const QModelIndex& index, int role) const QVariant DivePlotDataModel::data(const QModelIndex &index, int role) const
{ {
if ((!index.isValid())||(index.row() >= pInfo.nr)) if ((!index.isValid()) || (index.row() >= pInfo.nr))
return QVariant(); return QVariant();
plot_data item = pInfo.entry[index.row()]; plot_data item = pInfo.entry[index.row()];
if (role == Qt::DisplayRole) { if (role == Qt::DisplayRole) {
switch (index.column()) { switch (index.column()) {
case DEPTH: return item.depth; case DEPTH:
case TIME: return item.sec; return item.depth;
case PRESSURE: return item.pressure[0]; case TIME:
case TEMPERATURE: return item.temperature; return item.sec;
case COLOR: return item.velocity; case PRESSURE:
case USERENTERED: return false; return item.pressure[0];
case CYLINDERINDEX: return item.cylinderindex; case TEMPERATURE:
case SENSOR_PRESSURE: return item.pressure[0]; return item.temperature;
case INTERPOLATED_PRESSURE: return item.pressure[1]; case COLOR:
case CEILING: return item.ceiling; return item.velocity;
case SAC: return item.sac; case USERENTERED:
case PN2: return item.pn2; return false;
case PHE: return item.phe; case CYLINDERINDEX:
case PO2: return item.po2; return item.cylinderindex;
case HEARTBEAT: return item.heartbeat; case SENSOR_PRESSURE:
return item.pressure[0];
case INTERPOLATED_PRESSURE:
return item.pressure[1];
case CEILING:
return item.ceiling;
case SAC:
return item.sac;
case PN2:
return item.pn2;
case PHE:
return item.phe;
case PO2:
return item.po2;
case HEARTBEAT:
return item.heartbeat;
} }
} }
if (role == Qt::DisplayRole && index.column() >= TISSUE_1 && index.column() <= TISSUE_16){ if (role == Qt::DisplayRole && index.column() >= TISSUE_1 && index.column() <= TISSUE_16) {
return item.ceilings[ index.column() - TISSUE_1]; return item.ceilings[index.column() - TISSUE_1];
} }
if (role == Qt::BackgroundRole) { if (role == Qt::BackgroundRole) {
switch (index.column()) { switch (index.column()) {
case COLOR: return getColor((color_indice_t)(VELOCITY_COLORS_START_IDX + item.velocity)); case COLOR:
return getColor((color_indice_t)(VELOCITY_COLORS_START_IDX + item.velocity));
} }
} }
return QVariant(); return QVariant();
} }
const plot_info& DivePlotDataModel::data() const const plot_info &DivePlotDataModel::data() const
{ {
return pInfo; return pInfo;
} }
int DivePlotDataModel::rowCount(const QModelIndex& parent) const int DivePlotDataModel::rowCount(const QModelIndex &parent) const
{ {
return pInfo.nr; return pInfo.nr;
} }
@ -75,22 +91,36 @@ QVariant DivePlotDataModel::headerData(int section, Qt::Orientation orientation,
return QVariant(); return QVariant();
switch (section) { switch (section) {
case DEPTH: return tr("Depth"); case DEPTH:
case TIME: return tr("Time"); return tr("Depth");
case PRESSURE: return tr("Pressure"); case TIME:
case TEMPERATURE: return tr("Temperature"); return tr("Time");
case COLOR: return tr("Color"); case PRESSURE:
case USERENTERED: return tr("User Entered"); return tr("Pressure");
case CYLINDERINDEX: return tr("Cylinder Index"); case TEMPERATURE:
case SENSOR_PRESSURE: return tr("Pressure S"); return tr("Temperature");
case INTERPOLATED_PRESSURE: return tr("Pressure I"); case COLOR:
case CEILING: return tr("Ceiling"); return tr("Color");
case SAC: return tr("SAC"); case USERENTERED:
case PN2: return tr("PN2"); return tr("User Entered");
case PHE: return tr("PHE"); case CYLINDERINDEX:
case PO2: return tr("PO2"); return tr("Cylinder Index");
case SENSOR_PRESSURE:
return tr("Pressure S");
case INTERPOLATED_PRESSURE:
return tr("Pressure I");
case CEILING:
return tr("Ceiling");
case SAC:
return tr("SAC");
case PN2:
return tr("PN2");
case PHE:
return tr("PHE");
case PO2:
return tr("PO2");
} }
if (role == Qt::DisplayRole && section >= TISSUE_1 && section <= TISSUE_16){ if (role == Qt::DisplayRole && section >= TISSUE_1 && section <= TISSUE_16) {
return QString("Ceiling: %1").arg(section - TISSUE_1); return QString("Ceiling: %1").arg(section - TISSUE_1);
} }
return QVariant(); return QVariant();
@ -107,14 +137,14 @@ void DivePlotDataModel::clear()
} }
} }
void DivePlotDataModel::setDive(dive* d, const plot_info& info) void DivePlotDataModel::setDive(dive *d, const plot_info &info)
{ {
clear(); clear();
Q_ASSERT(d != NULL); Q_ASSERT(d != NULL);
diveId = d->id; diveId = d->id;
dcNr = dc_number; dcNr = dc_number;
pInfo = info; pInfo = info;
beginInsertRows(QModelIndex(), 0, pInfo.nr-1); beginInsertRows(QModelIndex(), 0, pInfo.nr - 1);
endInsertRows(); endInsertRows();
} }
@ -128,16 +158,16 @@ int DivePlotDataModel::dcShown() const
return dcNr; return dcNr;
} }
#define MAX_PPGAS_FUNC( GAS, GASFUNC ) \ #define MAX_PPGAS_FUNC(GAS, GASFUNC) \
double DivePlotDataModel::GASFUNC() \ double DivePlotDataModel::GASFUNC() \
{ \ { \
double ret = -1; \ double ret = -1; \
for(int i = 0, count = rowCount(); i < count; i++){ \ for (int i = 0, count = rowCount(); i < count; i++) { \
if (pInfo.entry[i].GAS > ret) \ if (pInfo.entry[i].GAS > ret) \
ret = pInfo.entry[i].GAS; \ ret = pInfo.entry[i].GAS; \
} \ } \
return ret; \ return ret; \
} }
MAX_PPGAS_FUNC(phe, pheMax); MAX_PPGAS_FUNC(phe, pheMax);
MAX_PPGAS_FUNC(pn2, pn2Max); MAX_PPGAS_FUNC(pn2, pn2Max);
@ -156,5 +186,5 @@ void DivePlotDataModel::calculateDecompression()
struct divecomputer *dc = select_dc(&d->dc); struct divecomputer *dc = select_dc(&d->dc);
init_decompression(d); init_decompression(d);
calculate_deco_information(d, dc, &pInfo, false); calculate_deco_information(d, dc, &pInfo, false);
dataChanged(index(0, CEILING), index(pInfo.nr-1, TISSUE_16)); dataChanged(index(0, CEILING), index(pInfo.nr - 1, TISSUE_16));
} }

View file

@ -9,20 +9,51 @@ struct dive;
struct plot_data; struct plot_data;
struct plot_info; struct plot_info;
class DivePlotDataModel : public QAbstractTableModel{ class DivePlotDataModel : public QAbstractTableModel {
Q_OBJECT Q_OBJECT
public: public:
enum {DEPTH, TIME, PRESSURE, TEMPERATURE, USERENTERED, COLOR, CYLINDERINDEX, SENSOR_PRESSURE, INTERPOLATED_PRESSURE, enum {
SAC, CEILING, TISSUE_1,TISSUE_2,TISSUE_3,TISSUE_4,TISSUE_5,TISSUE_6,TISSUE_7,TISSUE_8,TISSUE_9,TISSUE_10, DEPTH,
TISSUE_11,TISSUE_12,TISSUE_13,TISSUE_14,TISSUE_15,TISSUE_16, PN2,PHE,PO2, HEARTBEAT, COLUMNS}; TIME,
explicit DivePlotDataModel(QObject* parent = 0); PRESSURE,
virtual int columnCount(const QModelIndex& parent = QModelIndex()) const; TEMPERATURE,
USERENTERED,
COLOR,
CYLINDERINDEX,
SENSOR_PRESSURE,
INTERPOLATED_PRESSURE,
SAC,
CEILING,
TISSUE_1,
TISSUE_2,
TISSUE_3,
TISSUE_4,
TISSUE_5,
TISSUE_6,
TISSUE_7,
TISSUE_8,
TISSUE_9,
TISSUE_10,
TISSUE_11,
TISSUE_12,
TISSUE_13,
TISSUE_14,
TISSUE_15,
TISSUE_16,
PN2,
PHE,
PO2,
HEARTBEAT,
COLUMNS
};
explicit DivePlotDataModel(QObject *parent = 0);
virtual int columnCount(const QModelIndex &parent = QModelIndex()) const;
virtual QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const; virtual QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const;
virtual QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const; virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const;
virtual int rowCount(const QModelIndex& parent = QModelIndex()) const; virtual int rowCount(const QModelIndex &parent = QModelIndex()) const;
void clear(); void clear();
void setDive(struct dive *d, const plot_info& pInfo); void setDive(struct dive *d, const plot_info &pInfo);
const plot_info& data() const; const plot_info &data() const;
int id() const; int id() const;
int dcShown() const; int dcShown() const;
double pheMax(); double pheMax();
@ -30,6 +61,7 @@ public:
double po2Max(); double po2Max();
void emitDataChanged(); void emitDataChanged();
void calculateDecompression(); void calculateDecompression();
private: private:
plot_info pInfo; plot_info pInfo;
int diveId; int diveId;

View file

@ -17,8 +17,7 @@
#include <QGraphicsItem> #include <QGraphicsItem>
#include <QSettings> #include <QSettings>
AbstractProfilePolygonItem::AbstractProfilePolygonItem(): QObject(), QGraphicsPolygonItem(), AbstractProfilePolygonItem::AbstractProfilePolygonItem() : QObject(), QGraphicsPolygonItem(), hAxis(NULL), vAxis(NULL), dataModel(NULL), hDataColumn(-1), vDataColumn(-1)
hAxis(NULL), vAxis(NULL), dataModel(NULL), hDataColumn(-1), vDataColumn(-1)
{ {
connect(PreferencesDialog::instance(), SIGNAL(settingsChanged()), this, SLOT(preferencesChanged())); connect(PreferencesDialog::instance(), SIGNAL(settingsChanged()), this, SLOT(preferencesChanged()));
} }
@ -27,7 +26,7 @@ void AbstractProfilePolygonItem::preferencesChanged()
{ {
} }
void AbstractProfilePolygonItem::setHorizontalAxis(DiveCartesianAxis* horizontal) void AbstractProfilePolygonItem::setHorizontalAxis(DiveCartesianAxis *horizontal)
{ {
hAxis = horizontal; hAxis = horizontal;
connect(hAxis, SIGNAL(sizeChanged()), this, SLOT(modelDataChanged())); connect(hAxis, SIGNAL(sizeChanged()), this, SLOT(modelDataChanged()));
@ -40,22 +39,22 @@ void AbstractProfilePolygonItem::setHorizontalDataColumn(int column)
modelDataChanged(); modelDataChanged();
} }
void AbstractProfilePolygonItem::setModel(DivePlotDataModel* model) void AbstractProfilePolygonItem::setModel(DivePlotDataModel *model)
{ {
dataModel = model; dataModel = model;
connect(dataModel, SIGNAL(dataChanged(QModelIndex,QModelIndex)), this, SLOT(modelDataChanged(QModelIndex, QModelIndex))); connect(dataModel, SIGNAL(dataChanged(QModelIndex, QModelIndex)), this, SLOT(modelDataChanged(QModelIndex, QModelIndex)));
connect(dataModel, SIGNAL(rowsAboutToBeRemoved(QModelIndex,int,int)), this, SLOT(modelDataRemoved(QModelIndex, int, int))); connect(dataModel, SIGNAL(rowsAboutToBeRemoved(QModelIndex, int, int)), this, SLOT(modelDataRemoved(QModelIndex, int, int)));
modelDataChanged(); modelDataChanged();
} }
void AbstractProfilePolygonItem::modelDataRemoved(const QModelIndex& parent, int from, int to) void AbstractProfilePolygonItem::modelDataRemoved(const QModelIndex &parent, int from, int to)
{ {
setPolygon(QPolygonF()); setPolygon(QPolygonF());
qDeleteAll(texts); qDeleteAll(texts);
texts.clear(); texts.clear();
} }
void AbstractProfilePolygonItem::setVerticalAxis(DiveCartesianAxis* vertical) void AbstractProfilePolygonItem::setVerticalAxis(DiveCartesianAxis *vertical)
{ {
vAxis = vertical; vAxis = vertical;
connect(vAxis, SIGNAL(sizeChanged()), this, SLOT(modelDataChanged())); connect(vAxis, SIGNAL(sizeChanged()), this, SLOT(modelDataChanged()));
@ -69,7 +68,7 @@ void AbstractProfilePolygonItem::setVerticalDataColumn(int column)
modelDataChanged(); modelDataChanged();
} }
bool AbstractProfilePolygonItem::shouldCalculateStuff(const QModelIndex& topLeft, const QModelIndex& bottomRight) bool AbstractProfilePolygonItem::shouldCalculateStuff(const QModelIndex &topLeft, const QModelIndex &bottomRight)
{ {
if (!hAxis || !vAxis) if (!hAxis || !vAxis)
return false; return false;
@ -77,16 +76,16 @@ bool AbstractProfilePolygonItem::shouldCalculateStuff(const QModelIndex& topLeft
return false; return false;
if (hDataColumn == -1 || vDataColumn == -1) if (hDataColumn == -1 || vDataColumn == -1)
return false; return false;
if ( topLeft.isValid() && bottomRight.isValid()){ if (topLeft.isValid() && bottomRight.isValid()) {
if ((topLeft.column() >= vDataColumn || topLeft.column() >= hDataColumn ) && if ((topLeft.column() >= vDataColumn || topLeft.column() >= hDataColumn) &&
(bottomRight.column() <= vDataColumn || topLeft.column() <= hDataColumn )){ (bottomRight.column() <= vDataColumn || topLeft.column() <= hDataColumn)) {
return true; return true;
} }
} }
return true; return true;
} }
void AbstractProfilePolygonItem::modelDataChanged(const QModelIndex& topLeft, const QModelIndex& bottomRight) void AbstractProfilePolygonItem::modelDataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight)
{ {
// We don't have enougth data to calculate things, quit. // We don't have enougth data to calculate things, quit.
@ -99,7 +98,7 @@ void AbstractProfilePolygonItem::modelDataChanged(const QModelIndex& topLeft, co
for (int i = 0, modelDataCount = dataModel->rowCount(); i < modelDataCount; i++) { for (int i = 0, modelDataCount = dataModel->rowCount(); i < modelDataCount; i++) {
qreal horizontalValue = dataModel->index(i, hDataColumn).data().toReal(); qreal horizontalValue = dataModel->index(i, hDataColumn).data().toReal();
qreal verticalValue = dataModel->index(i, vDataColumn).data().toReal(); qreal verticalValue = dataModel->index(i, vDataColumn).data().toReal();
QPointF point( hAxis->posAtValue(horizontalValue), vAxis->posAtValue(verticalValue)); QPointF point(hAxis->posAtValue(horizontalValue), vAxis->posAtValue(verticalValue));
poly.append(point); poly.append(point);
} }
setPolygon(poly); setPolygon(poly);
@ -110,12 +109,12 @@ void AbstractProfilePolygonItem::modelDataChanged(const QModelIndex& topLeft, co
DiveProfileItem::DiveProfileItem() : show_reported_ceiling(0), reported_ceiling_in_red(0) DiveProfileItem::DiveProfileItem() : show_reported_ceiling(0), reported_ceiling_in_red(0)
{ {
} }
void DiveProfileItem::paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget) { void DiveProfileItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
{
Q_UNUSED(widget); Q_UNUSED(widget);
if(polygon().isEmpty()) if (polygon().isEmpty())
return; return;
// This paints the Polygon + Background. I'm setting the pen to QPen() so we don't get a black line here, // This paints the Polygon + Background. I'm setting the pen to QPen() so we don't get a black line here,
@ -134,13 +133,13 @@ void DiveProfileItem::paint(QPainter* painter, const QStyleOptionGraphicsItem* o
QModelIndex colorIndex = dataModel->index(i, DivePlotDataModel::COLOR); QModelIndex colorIndex = dataModel->index(i, DivePlotDataModel::COLOR);
pen.setBrush(QBrush(colorIndex.data(Qt::BackgroundRole).value<QColor>())); pen.setBrush(QBrush(colorIndex.data(Qt::BackgroundRole).value<QColor>()));
painter->setPen(pen); painter->setPen(pen);
painter->drawLine(poly[i-1],poly[i]); painter->drawLine(poly[i - 1], poly[i]);
} }
} }
void DiveProfileItem::modelDataChanged(const QModelIndex& topLeft, const QModelIndex& bottomRight) void DiveProfileItem::modelDataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight)
{ {
if(!shouldCalculateStuff(topLeft, bottomRight)) if (!shouldCalculateStuff(topLeft, bottomRight))
return; return;
AbstractProfilePolygonItem::modelDataChanged(topLeft, bottomRight); AbstractProfilePolygonItem::modelDataChanged(topLeft, bottomRight);
@ -153,7 +152,7 @@ void DiveProfileItem::modelDataChanged(const QModelIndex& topLeft, const QModelI
/* Show any ceiling we may have encountered */ /* Show any ceiling we may have encountered */
if (prefs.profile_dc_ceiling && !prefs.profile_red_ceiling) { if (prefs.profile_dc_ceiling && !prefs.profile_red_ceiling) {
QPolygonF p = polygon(); QPolygonF p = polygon();
plot_data *entry = dataModel->data().entry + dataModel->rowCount()-1; plot_data *entry = dataModel->data().entry + dataModel->rowCount() - 1;
for (int i = dataModel->rowCount() - 1; i >= 0; i--, entry--) { for (int i = dataModel->rowCount() - 1; i >= 0; i--, entry--) {
if (!entry->in_deco) { if (!entry->in_deco) {
/* not in deco implies this is a safety stop, no ceiling */ /* not in deco implies this is a safety stop, no ceiling */
@ -167,7 +166,7 @@ void DiveProfileItem::modelDataChanged(const QModelIndex& topLeft, const QModelI
setPolygon(p); setPolygon(p);
} }
// This is the blueish gradient that the Depth Profile should have. // This is the blueish gradient that the Depth Profile should have.
// It's a simple QLinearGradient with 2 stops, starting from top to bottom. // It's a simple QLinearGradient with 2 stops, starting from top to bottom.
QLinearGradient pat(0, polygon().boundingRect().top(), 0, polygon().boundingRect().bottom()); QLinearGradient pat(0, polygon().boundingRect().top(), 0, polygon().boundingRect().bottom());
pat.setColorAt(1, getColor(DEPTH_BOTTOM)); pat.setColorAt(1, getColor(DEPTH_BOTTOM));
@ -175,9 +174,9 @@ void DiveProfileItem::modelDataChanged(const QModelIndex& topLeft, const QModelI
setBrush(QBrush(pat)); setBrush(QBrush(pat));
int last = -1; int last = -1;
for (int i = 0, count = dataModel->rowCount(); i < count; i++) { for (int i = 0, count = dataModel->rowCount(); i < count; i++) {
struct plot_data *entry = dataModel->data().entry+i; struct plot_data *entry = dataModel->data().entry + i;
if (entry->depth < 2000) if (entry->depth < 2000)
continue; continue;
@ -201,10 +200,10 @@ void DiveProfileItem::preferencesChanged()
//TODO: Only modelDataChanged() here if we need to rebuild the graph ( for instance, //TODO: Only modelDataChanged() here if we need to rebuild the graph ( for instance,
// if the prefs.profile_dc_ceiling are enabled, but prefs.profile_red_ceiling is disabled // if the prefs.profile_dc_ceiling are enabled, but prefs.profile_red_ceiling is disabled
// and only if it changed something. let's not waste cpu cycles repoloting something we don't need to. // and only if it changed something. let's not waste cpu cycles repoloting something we don't need to.
modelDataChanged(); modelDataChanged();
} }
void DiveProfileItem::plot_depth_sample(struct plot_data *entry,QFlags<Qt::AlignmentFlag> flags,const QColor& color) void DiveProfileItem::plot_depth_sample(struct plot_data *entry, QFlags<Qt::AlignmentFlag> flags, const QColor &color)
{ {
int decimals; int decimals;
double d = get_depth_units(entry->depth, &decimals, NULL); double d = get_depth_units(entry->depth, &decimals, NULL);
@ -231,7 +230,7 @@ void DiveHeartrateItem::modelDataChanged(const QModelIndex &topLeft, const QMode
struct { struct {
int sec; int sec;
int hr; int hr;
} hist[3] = {0}; } hist[3] = { 0 };
// We don't have enougth data to calculate things, quit. // We don't have enougth data to calculate things, quit.
if (!shouldCalculateStuff(topLeft, bottomRight)) if (!shouldCalculateStuff(topLeft, bottomRight))
@ -246,7 +245,7 @@ void DiveHeartrateItem::modelDataChanged(const QModelIndex &topLeft, const QMode
if (!hr) if (!hr)
continue; continue;
sec = dataModel->index(i, hDataColumn).data().toInt(); sec = dataModel->index(i, hDataColumn).data().toInt();
QPointF point( hAxis->posAtValue(sec), vAxis->posAtValue(hr)); QPointF point(hAxis->posAtValue(sec), vAxis->posAtValue(hr));
poly.append(point); poly.append(point);
if (hr == hist[2].hr) if (hr == hist[2].hr)
// same as last one, no point in looking at printing // same as last one, no point in looking at printing
@ -276,7 +275,7 @@ void DiveHeartrateItem::modelDataChanged(const QModelIndex &topLeft, const QMode
} }
setPolygon(poly); setPolygon(poly);
if( texts.count()) if (texts.count())
texts.last()->setAlignment(Qt::AlignLeft | Qt::AlignBottom); texts.last()->setAlignment(Qt::AlignLeft | Qt::AlignBottom);
} }
@ -291,9 +290,9 @@ void DiveHeartrateItem::createTextItem(int sec, int hr)
texts.append(text); texts.append(text);
} }
void DiveHeartrateItem::paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget) void DiveHeartrateItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
{ {
if(polygon().isEmpty()) if (polygon().isEmpty())
return; return;
painter->setPen(pen()); painter->setPen(pen());
painter->drawPolyline(polygon()); painter->drawPolyline(polygon());
@ -308,7 +307,7 @@ DiveTemperatureItem::DiveTemperatureItem()
setPen(pen); setPen(pen);
} }
void DiveTemperatureItem::modelDataChanged(const QModelIndex& topLeft, const QModelIndex& bottomRight) void DiveTemperatureItem::modelDataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight)
{ {
int last = -300, last_printed_temp = 0, sec = 0, last_valid_temp = 0; int last = -300, last_printed_temp = 0, sec = 0, last_valid_temp = 0;
// We don't have enougth data to calculate things, quit. // We don't have enougth data to calculate things, quit.
@ -325,7 +324,7 @@ void DiveTemperatureItem::modelDataChanged(const QModelIndex& topLeft, const QMo
continue; continue;
last_valid_temp = mkelvin; last_valid_temp = mkelvin;
sec = dataModel->index(i, hDataColumn).data().toInt(); sec = dataModel->index(i, hDataColumn).data().toInt();
QPointF point( hAxis->posAtValue(sec), vAxis->posAtValue(mkelvin)); QPointF point(hAxis->posAtValue(sec), vAxis->posAtValue(mkelvin));
poly.append(point); poly.append(point);
/* don't print a temperature /* don't print a temperature
@ -338,7 +337,7 @@ void DiveTemperatureItem::modelDataChanged(const QModelIndex& topLeft, const QMo
continue; continue;
last = sec; last = sec;
if (mkelvin > 200000) if (mkelvin > 200000)
createTextItem(sec,mkelvin); createTextItem(sec, mkelvin);
last_printed_temp = mkelvin; last_printed_temp = mkelvin;
} }
setPolygon(poly); setPolygon(poly);
@ -350,7 +349,7 @@ void DiveTemperatureItem::modelDataChanged(const QModelIndex& topLeft, const QMo
((abs(last_valid_temp - last_printed_temp) > 500) || ((double)last / (double)sec < 0.75))) { ((abs(last_valid_temp - last_printed_temp) > 500) || ((double)last / (double)sec < 0.75))) {
createTextItem(sec, last_valid_temp); createTextItem(sec, last_valid_temp);
} }
if( texts.count()) if (texts.count())
texts.last()->setAlignment(Qt::AlignLeft | Qt::AlignBottom); texts.last()->setAlignment(Qt::AlignLeft | Qt::AlignBottom);
} }
@ -369,15 +368,15 @@ void DiveTemperatureItem::createTextItem(int sec, int mkelvin)
texts.append(text); texts.append(text);
} }
void DiveTemperatureItem::paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget) void DiveTemperatureItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
{ {
if(polygon().isEmpty()) if (polygon().isEmpty())
return; return;
painter->setPen(pen()); painter->setPen(pen());
painter->drawPolyline(polygon()); painter->drawPolyline(polygon());
} }
void DiveGasPressureItem::modelDataChanged(const QModelIndex& topLeft, const QModelIndex& bottomRight) void DiveGasPressureItem::modelDataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight)
{ {
// We don't have enougth data to calculate things, quit. // We don't have enougth data to calculate things, quit.
if (!shouldCalculateStuff(topLeft, bottomRight)) if (!shouldCalculateStuff(topLeft, bottomRight))
@ -387,7 +386,7 @@ void DiveGasPressureItem::modelDataChanged(const QModelIndex& topLeft, const QMo
polygons.clear(); polygons.clear();
for (int i = 0, count = dataModel->rowCount(); i < count; i++) { for (int i = 0, count = dataModel->rowCount(); i < count; i++) {
plot_data* entry = dataModel->data().entry + i; plot_data *entry = dataModel->data().entry + i;
int mbar = GET_PRESSURE(entry); int mbar = GET_PRESSURE(entry);
if (entry->cylinderindex != last_index) { if (entry->cylinderindex != last_index) {
@ -399,7 +398,7 @@ void DiveGasPressureItem::modelDataChanged(const QModelIndex& topLeft, const QMo
} }
QPointF point(hAxis->posAtValue(entry->sec), vAxis->posAtValue(mbar)); QPointF point(hAxis->posAtValue(entry->sec), vAxis->posAtValue(mbar));
boundingPoly.push_back(point); // The BoundingRect boundingPoly.push_back(point); // The BoundingRect
polygons.last().push_back(point); // The polygon thta will be plotted. polygons.last().push_back(point); // The polygon thta will be plotted.
} }
setPolygon(boundingPoly); setPolygon(boundingPoly);
@ -425,8 +424,8 @@ void DiveGasPressureItem::modelDataChanged(const QModelIndex& topLeft, const QMo
if (!seen_cyl[cyl]) { if (!seen_cyl[cyl]) {
plot_pressure_value(mbar, entry->sec, Qt::AlignRight | Qt::AlignTop); plot_pressure_value(mbar, entry->sec, Qt::AlignRight | Qt::AlignTop);
plot_gas_value(mbar, entry->sec, Qt::AlignRight | Qt::AlignBottom, plot_gas_value(mbar, entry->sec, Qt::AlignRight | Qt::AlignBottom,
get_o2(&dive->cylinder[cyl].gasmix), get_o2(&dive->cylinder[cyl].gasmix),
get_he(&dive->cylinder[cyl].gasmix)); get_he(&dive->cylinder[cyl].gasmix));
seen_cyl[cyl] = true; seen_cyl[cyl] = true;
} }
} }
@ -446,7 +445,7 @@ void DiveGasPressureItem::plot_pressure_value(int mbar, int sec, QFlags<Qt::Alig
const char *unit; const char *unit;
int pressure = get_pressure_units(mbar, &unit); int pressure = get_pressure_units(mbar, &unit);
DiveTextItem *text = new DiveTextItem(this); DiveTextItem *text = new DiveTextItem(this);
text->setPos(hAxis->posAtValue(sec), vAxis->posAtValue(mbar)-0.5); text->setPos(hAxis->posAtValue(sec), vAxis->posAtValue(mbar) - 0.5);
text->setText(QString("%1 %2").arg(pressure).arg(unit)); text->setText(QString("%1 %2").arg(pressure).arg(unit));
text->setAlignment(flags); text->setAlignment(flags);
text->setBrush(getColor(PRESSURE_TEXT)); text->setBrush(getColor(PRESSURE_TEXT));
@ -455,9 +454,9 @@ void DiveGasPressureItem::plot_pressure_value(int mbar, int sec, QFlags<Qt::Alig
void DiveGasPressureItem::plot_gas_value(int mbar, int sec, QFlags<Qt::AlignmentFlag> flags, int o2, int he) void DiveGasPressureItem::plot_gas_value(int mbar, int sec, QFlags<Qt::AlignmentFlag> flags, int o2, int he)
{ {
QString gas = (is_air(o2, he)) ? tr("air") : QString gas = (is_air(o2, he)) ? tr("air") :
(he == 0) ? QString(tr("EAN%1")).arg((o2 + 5) / 10) : (he == 0) ? QString(tr("EAN%1")).arg((o2 + 5) / 10) :
QString("%1/%2").arg((o2 + 5) / 10).arg((he + 5) / 10); QString("%1/%2").arg((o2 + 5) / 10).arg((he + 5) / 10);
DiveTextItem *text = new DiveTextItem(this); DiveTextItem *text = new DiveTextItem(this);
text->setPos(hAxis->posAtValue(sec), vAxis->posAtValue(mbar)); text->setPos(hAxis->posAtValue(sec), vAxis->posAtValue(mbar));
text->setText(gas); text->setText(gas);
@ -466,9 +465,9 @@ void DiveGasPressureItem::plot_gas_value(int mbar, int sec, QFlags<Qt::Alignment
texts.push_back(text); texts.push_back(text);
} }
void DiveGasPressureItem::paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget) void DiveGasPressureItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
{ {
if(polygon().isEmpty()) if (polygon().isEmpty())
return; return;
QPen pen; QPen pen;
pen.setCosmetic(true); pen.setCosmetic(true);
@ -477,11 +476,11 @@ void DiveGasPressureItem::paint(QPainter* painter, const QStyleOptionGraphicsIte
if (!d) if (!d)
return; return;
struct plot_data *entry = dataModel->data().entry; struct plot_data *entry = dataModel->data().entry;
Q_FOREACH(const QPolygonF& poly, polygons) { Q_FOREACH(const QPolygonF & poly, polygons) {
for (int i = 1, count = poly.count(); i < count; i++, entry++) { for (int i = 1, count = poly.count(); i < count; i++, entry++) {
pen.setBrush(getSacColor(entry->sac, d->sac)); pen.setBrush(getSacColor(entry->sac, d->sac));
painter->setPen(pen); painter->setPen(pen);
painter->drawLine(poly[i-1],poly[i]); painter->drawLine(poly[i - 1], poly[i]);
} }
} }
} }
@ -494,7 +493,7 @@ DiveCalculatedCeiling::DiveCalculatedCeiling() : is3mIncrement(false), gradientF
preferencesChanged(); preferencesChanged();
} }
void DiveCalculatedCeiling::modelDataChanged(const QModelIndex& topLeft, const QModelIndex& bottomRight) void DiveCalculatedCeiling::modelDataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight)
{ {
// We don't have enougth data to calculate things, quit. // We don't have enougth data to calculate things, quit.
if (!shouldCalculateStuff(topLeft, bottomRight)) if (!shouldCalculateStuff(topLeft, bottomRight))
@ -514,16 +513,16 @@ void DiveCalculatedCeiling::modelDataChanged(const QModelIndex& topLeft, const Q
QLinearGradient pat(0, polygon().boundingRect().top(), 0, polygon().boundingRect().bottom()); QLinearGradient pat(0, polygon().boundingRect().top(), 0, polygon().boundingRect().bottom());
pat.setColorAt(0, getColor(CALC_CEILING_SHALLOW)); pat.setColorAt(0, getColor(CALC_CEILING_SHALLOW));
pat.setColorAt(1, getColor(CALC_CEILING_DEEP)); pat.setColorAt(1, getColor(CALC_CEILING_DEEP));
setPen(QPen(QBrush(Qt::NoBrush),0)); setPen(QPen(QBrush(Qt::NoBrush), 0));
setBrush(pat); setBrush(pat);
gradientFactor->setX(poly.boundingRect().width()/2 + poly.boundingRect().x()); gradientFactor->setX(poly.boundingRect().width() / 2 + poly.boundingRect().x());
gradientFactor->setText(QString("GF %1/%2").arg(prefs.gflow).arg(prefs.gfhigh)); gradientFactor->setText(QString("GF %1/%2").arg(prefs.gflow).arg(prefs.gfhigh));
} }
void DiveCalculatedCeiling::paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget) void DiveCalculatedCeiling::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
{ {
if(polygon().isEmpty()) if (polygon().isEmpty())
return; return;
QGraphicsPolygonItem::paint(painter, option, widget); QGraphicsPolygonItem::paint(painter, option, widget);
} }
@ -540,9 +539,9 @@ void DiveCalculatedTissue::preferencesChanged()
setVisible(s.value("calcalltissues").toBool() && s.value("calcceiling").toBool()); setVisible(s.value("calcalltissues").toBool() && s.value("calcceiling").toBool());
} }
void DiveReportedCeiling::modelDataChanged(const QModelIndex& topLeft, const QModelIndex& bottomRight) void DiveReportedCeiling::modelDataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight)
{ {
if(!shouldCalculateStuff(topLeft, bottomRight)) if (!shouldCalculateStuff(topLeft, bottomRight))
return; return;
QPolygonF p; QPolygonF p;
@ -563,7 +562,7 @@ void DiveReportedCeiling::modelDataChanged(const QModelIndex& topLeft, const QMo
QLinearGradient pat(0, p.boundingRect().top(), 0, p.boundingRect().bottom()); QLinearGradient pat(0, p.boundingRect().top(), 0, p.boundingRect().bottom());
pat.setColorAt(0, getColor(CEILING_SHALLOW)); pat.setColorAt(0, getColor(CEILING_SHALLOW));
pat.setColorAt(1, getColor(CEILING_DEEP)); pat.setColorAt(1, getColor(CEILING_DEEP));
setPen(QPen(QBrush(Qt::NoBrush),0)); setPen(QPen(QBrush(Qt::NoBrush), 0));
setBrush(pat); setBrush(pat);
} }
@ -573,7 +572,7 @@ void DiveCalculatedCeiling::preferencesChanged()
s.beginGroup("TecDetails"); s.beginGroup("TecDetails");
bool shouldShow3mIncrement = s.value("calcceiling3m").toBool(); bool shouldShow3mIncrement = s.value("calcceiling3m").toBool();
if ( dataModel && is3mIncrement != shouldShow3mIncrement){ if (dataModel && is3mIncrement != shouldShow3mIncrement) {
// recalculate that part. // recalculate that part.
dataModel->calculateDecompression(); dataModel->calculateDecompression();
} }
@ -588,9 +587,9 @@ void DiveReportedCeiling::preferencesChanged()
setVisible(s.value("redceiling").toBool()); setVisible(s.value("redceiling").toBool());
} }
void DiveReportedCeiling::paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget) void DiveReportedCeiling::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
{ {
if(polygon().isEmpty()) if (polygon().isEmpty())
return; return;
QGraphicsPolygonItem::paint(painter, option, widget); QGraphicsPolygonItem::paint(painter, option, widget);
} }
@ -619,18 +618,18 @@ void MeanDepthLine::setMeanDepth(int value)
meanDepth = value; meanDepth = value;
} }
void MeanDepthLine::setAxis(DiveCartesianAxis* a) void MeanDepthLine::setAxis(DiveCartesianAxis *a)
{ {
connect(a, SIGNAL(sizeChanged()), this, SLOT(axisLineChanged())); connect(a, SIGNAL(sizeChanged()), this, SLOT(axisLineChanged()));
} }
void MeanDepthLine::axisLineChanged() void MeanDepthLine::axisLineChanged()
{ {
DiveCartesianAxis *axis = qobject_cast<DiveCartesianAxis*>(sender()); DiveCartesianAxis *axis = qobject_cast<DiveCartesianAxis *>(sender());
animateMoveTo(x(),axis->posAtValue(meanDepth)); animateMoveTo(x(), axis->posAtValue(meanDepth));
} }
void PartialPressureGasItem::modelDataChanged(const QModelIndex& topLeft, const QModelIndex& bottomRight) void PartialPressureGasItem::modelDataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight)
{ {
//AbstractProfilePolygonItem::modelDataChanged(); //AbstractProfilePolygonItem::modelDataChanged();
if (!shouldCalculateStuff(topLeft, bottomRight)) if (!shouldCalculateStuff(topLeft, bottomRight))
@ -642,11 +641,11 @@ void PartialPressureGasItem::modelDataChanged(const QModelIndex& topLeft, const
QSettings s; QSettings s;
s.beginGroup("TecDetails"); s.beginGroup("TecDetails");
double threshould = s.value(threshouldKey).toDouble(); double threshould = s.value(threshouldKey).toDouble();
for(int i = 0; i < dataModel->rowCount(); i++, entry++){ for (int i = 0; i < dataModel->rowCount(); i++, entry++) {
double value = dataModel->index(i, vDataColumn).data().toDouble(); double value = dataModel->index(i, vDataColumn).data().toDouble();
int time = dataModel->index(i, hDataColumn).data().toInt(); int time = dataModel->index(i, hDataColumn).data().toInt();
QPointF point(hAxis->posAtValue(time), vAxis->posAtValue(value)); QPointF point(hAxis->posAtValue(time), vAxis->posAtValue(value));
poly.push_back( point ); poly.push_back(point);
if (value >= threshould) if (value >= threshould)
alertPoly.push_back(point); alertPoly.push_back(point);
} }
@ -656,7 +655,7 @@ void PartialPressureGasItem::modelDataChanged(const QModelIndex& topLeft, const
*/ */
} }
void PartialPressureGasItem::paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget) void PartialPressureGasItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
{ {
painter->setPen(normalColor); painter->setPen(normalColor);
painter->drawPolyline(polygon()); painter->drawPolyline(polygon());
@ -664,7 +663,7 @@ void PartialPressureGasItem::paint(QPainter* painter, const QStyleOptionGraphics
painter->drawPolyline(alertPoly); painter->drawPolyline(alertPoly);
} }
void PartialPressureGasItem::setThreshouldSettingsKey(const QString& threshouldSettingsKey) void PartialPressureGasItem::setThreshouldSettingsKey(const QString &threshouldSettingsKey)
{ {
threshouldKey = threshouldSettingsKey; threshouldKey = threshouldSettingsKey;
} }
@ -677,15 +676,15 @@ void PartialPressureGasItem::preferencesChanged()
{ {
QSettings s; QSettings s;
s.beginGroup("TecDetails"); s.beginGroup("TecDetails");
setVisible( s.value(visibilityKey).toBool() ); setVisible(s.value(visibilityKey).toBool());
} }
void PartialPressureGasItem::setVisibilitySettingsKey(const QString& key) void PartialPressureGasItem::setVisibilitySettingsKey(const QString &key)
{ {
visibilityKey = key; visibilityKey = key;
} }
void PartialPressureGasItem::setColors(const QColor& normal, const QColor& alert) void PartialPressureGasItem::setColors(const QColor &normal, const QColor &alert)
{ {
normalColor = normal; normalColor = normal;
alertColor = alert; alertColor = alert;

View file

@ -28,7 +28,7 @@ class DiveCartesianAxis;
class QAbstractTableModel; class QAbstractTableModel;
struct plot_data; struct plot_data;
class AbstractProfilePolygonItem : public QObject, public QGraphicsPolygonItem{ class AbstractProfilePolygonItem : public QObject, public QGraphicsPolygonItem {
Q_OBJECT Q_OBJECT
Q_PROPERTY(QPointF pos WRITE setPos READ pos) Q_PROPERTY(QPointF pos WRITE setPos READ pos)
Q_PROPERTY(qreal x WRITE setX READ x) Q_PROPERTY(qreal x WRITE setX READ x)
@ -40,12 +40,16 @@ public:
void setModel(DivePlotDataModel *model); void setModel(DivePlotDataModel *model);
void setHorizontalDataColumn(int column); void setHorizontalDataColumn(int column);
void setVerticalDataColumn(int column); void setVerticalDataColumn(int column);
virtual void paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget = 0) = 0; virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0) = 0;
virtual void clear(){} virtual void clear()
public slots: {
}
public
slots:
virtual void preferencesChanged(); virtual void preferencesChanged();
virtual void modelDataChanged(const QModelIndex& topLeft = QModelIndex(), const QModelIndex& bottomRight = QModelIndex()); virtual void modelDataChanged(const QModelIndex &topLeft = QModelIndex(), const QModelIndex &bottomRight = QModelIndex());
virtual void modelDataRemoved(const QModelIndex& parent, int from, int to); virtual void modelDataRemoved(const QModelIndex &parent, int from, int to);
protected: protected:
/* when the model emits a 'datachanged' signal, this method below should be used to check if the /* when the model emits a 'datachanged' signal, this method below should be used to check if the
* modified data affects this particular item ( for example, when setting the '3m increment' * modified data affects this particular item ( for example, when setting the '3m increment'
@ -54,36 +58,38 @@ protected:
* into consideration when returning 'true' for "yes, continue the calculation', and 'false' for * into consideration when returning 'true' for "yes, continue the calculation', and 'false' for
* 'do not recalculate, we already have the right data. * 'do not recalculate, we already have the right data.
*/ */
bool shouldCalculateStuff(const QModelIndex& topLeft, const QModelIndex& bottomRight); bool shouldCalculateStuff(const QModelIndex &topLeft, const QModelIndex &bottomRight);
DiveCartesianAxis *hAxis; DiveCartesianAxis *hAxis;
DiveCartesianAxis *vAxis; DiveCartesianAxis *vAxis;
DivePlotDataModel *dataModel; DivePlotDataModel *dataModel;
int hDataColumn; int hDataColumn;
int vDataColumn; int vDataColumn;
QList<DiveTextItem*> texts; QList<DiveTextItem *> texts;
}; };
class DiveProfileItem : public AbstractProfilePolygonItem{ class DiveProfileItem : public AbstractProfilePolygonItem {
Q_OBJECT Q_OBJECT
public: public:
DiveProfileItem(); DiveProfileItem();
virtual void paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget = 0); virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0);
virtual void modelDataChanged(const QModelIndex& topLeft = QModelIndex(), const QModelIndex& bottomRight = QModelIndex()); virtual void modelDataChanged(const QModelIndex &topLeft = QModelIndex(), const QModelIndex &bottomRight = QModelIndex());
virtual void preferencesChanged(); virtual void preferencesChanged();
void plot_depth_sample(struct plot_data *entry,QFlags<Qt::AlignmentFlag> flags,const QColor& color); void plot_depth_sample(struct plot_data *entry, QFlags<Qt::AlignmentFlag> flags, const QColor &color);
private: private:
unsigned int show_reported_ceiling; unsigned int show_reported_ceiling;
unsigned int reported_ceiling_in_red; unsigned int reported_ceiling_in_red;
}; };
class DiveTemperatureItem : public AbstractProfilePolygonItem{ class DiveTemperatureItem : public AbstractProfilePolygonItem {
Q_OBJECT Q_OBJECT
public: public:
DiveTemperatureItem(); DiveTemperatureItem();
virtual void modelDataChanged(const QModelIndex& topLeft = QModelIndex(), const QModelIndex& bottomRight = QModelIndex()); virtual void modelDataChanged(const QModelIndex &topLeft = QModelIndex(), const QModelIndex &bottomRight = QModelIndex());
virtual void paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget = 0); virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0);
private: private:
void createTextItem(int seconds, int mkelvin); void createTextItem(int seconds, int mkelvin);
}; };
@ -94,41 +100,44 @@ public:
DiveHeartrateItem(); DiveHeartrateItem();
virtual void modelDataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight); virtual void modelDataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight);
virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget); virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
private: private:
void createTextItem(int seconds, int hr); void createTextItem(int seconds, int hr);
}; };
class DiveGasPressureItem : public AbstractProfilePolygonItem{ class DiveGasPressureItem : public AbstractProfilePolygonItem {
Q_OBJECT Q_OBJECT
public: public:
virtual void modelDataChanged(const QModelIndex& topLeft = QModelIndex(), const QModelIndex& bottomRight = QModelIndex()); virtual void modelDataChanged(const QModelIndex &topLeft = QModelIndex(), const QModelIndex &bottomRight = QModelIndex());
virtual void paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget = 0); virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0);
private: private:
void plot_pressure_value(int mbar, int sec, QFlags<Qt::AlignmentFlag> align); void plot_pressure_value(int mbar, int sec, QFlags<Qt::AlignmentFlag> align);
void plot_gas_value(int mbar, int sec, QFlags<Qt::AlignmentFlag> align, int o2, int he); void plot_gas_value(int mbar, int sec, QFlags<Qt::AlignmentFlag> align, int o2, int he);
QVector<QPolygonF> polygons; QVector<QPolygonF> polygons;
}; };
class DiveCalculatedCeiling : public AbstractProfilePolygonItem{ class DiveCalculatedCeiling : public AbstractProfilePolygonItem {
Q_OBJECT Q_OBJECT
public: public:
DiveCalculatedCeiling(); DiveCalculatedCeiling();
virtual void modelDataChanged(const QModelIndex& topLeft = QModelIndex(), const QModelIndex& bottomRight = QModelIndex()); virtual void modelDataChanged(const QModelIndex &topLeft = QModelIndex(), const QModelIndex &bottomRight = QModelIndex());
virtual void paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget = 0); virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0);
virtual void preferencesChanged(); virtual void preferencesChanged();
private: private:
bool is3mIncrement; bool is3mIncrement;
DiveTextItem *gradientFactor; DiveTextItem *gradientFactor;
}; };
class DiveReportedCeiling : public AbstractProfilePolygonItem{ class DiveReportedCeiling : public AbstractProfilePolygonItem {
Q_OBJECT Q_OBJECT
public: public:
virtual void modelDataChanged(const QModelIndex& topLeft = QModelIndex(), const QModelIndex& bottomRight = QModelIndex()); virtual void modelDataChanged(const QModelIndex &topLeft = QModelIndex(), const QModelIndex &bottomRight = QModelIndex());
virtual void paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget = 0); virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0);
virtual void preferencesChanged(); virtual void preferencesChanged();
}; };
@ -146,24 +155,27 @@ public:
void setMeanDepth(int value); void setMeanDepth(int value);
void setLine(qreal x1, qreal y1, qreal x2, qreal y2); void setLine(qreal x1, qreal y1, qreal x2, qreal y2);
void setAxis(DiveCartesianAxis *a); void setAxis(DiveCartesianAxis *a);
public slots: public
slots:
void axisLineChanged(); void axisLineChanged();
private: private:
int meanDepth; int meanDepth;
DiveTextItem *leftText; DiveTextItem *leftText;
DiveTextItem *rightText; DiveTextItem *rightText;
}; };
class PartialPressureGasItem : public AbstractProfilePolygonItem{ class PartialPressureGasItem : public AbstractProfilePolygonItem {
Q_OBJECT Q_OBJECT
public: public:
PartialPressureGasItem(); PartialPressureGasItem();
virtual void paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget = 0); virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0);
virtual void modelDataChanged(const QModelIndex& topLeft = QModelIndex(), const QModelIndex& bottomRight = QModelIndex()); virtual void modelDataChanged(const QModelIndex &topLeft = QModelIndex(), const QModelIndex &bottomRight = QModelIndex());
virtual void preferencesChanged(); virtual void preferencesChanged();
void setThreshouldSettingsKey(const QString& threshouldSettingsKey); void setThreshouldSettingsKey(const QString &threshouldSettingsKey);
void setVisibilitySettingsKey(const QString& setVisibilitySettingsKey); void setVisibilitySettingsKey(const QString &setVisibilitySettingsKey);
void setColors(const QColor& normalColor, const QColor& alertColor); void setColors(const QColor &normalColor, const QColor &alertColor);
private: private:
QPolygonF alertPoly; QPolygonF alertPoly;
QString threshouldKey; QString threshouldKey;

View file

@ -1,6 +1,5 @@
#include "diverectitem.h" #include "diverectitem.h"
DiveRectItem::DiveRectItem(QObject* parent, QGraphicsItem* parentItem): QObject(parent), QGraphicsRectItem(parentItem ) DiveRectItem::DiveRectItem(QObject *parent, QGraphicsItem *parentItem) : QObject(parent), QGraphicsRectItem(parentItem)
{ {
} }

View file

@ -4,7 +4,7 @@
#include <QObject> #include <QObject>
#include <QGraphicsRectItem> #include <QGraphicsRectItem>
class DiveRectItem : public QObject, public QGraphicsRectItem{ class DiveRectItem : public QObject, public QGraphicsRectItem {
Q_OBJECT Q_OBJECT
Q_PROPERTY(QRectF rect WRITE setRect READ rect) Q_PROPERTY(QRectF rect WRITE setRect READ rect)
Q_PROPERTY(QPointF pos WRITE setPos READ pos) Q_PROPERTY(QPointF pos WRITE setPos READ pos)

View file

@ -9,7 +9,7 @@
#include <QPen> #include <QPen>
#include <QDebug> #include <QDebug>
DiveTextItem::DiveTextItem(QGraphicsItem* parent): QGraphicsItemGroup(parent), DiveTextItem::DiveTextItem(QGraphicsItem *parent) : QGraphicsItemGroup(parent),
internalAlignFlags(Qt::AlignHCenter | Qt::AlignVCenter), internalAlignFlags(Qt::AlignHCenter | Qt::AlignVCenter),
textBackgroundItem(NULL), textBackgroundItem(NULL),
textItem(NULL), textItem(NULL),
@ -25,7 +25,7 @@ void DiveTextItem::setAlignment(int alignFlags)
updateText(); updateText();
} }
void DiveTextItem::setBrush(const QBrush& b) void DiveTextItem::setBrush(const QBrush &b)
{ {
brush = b; brush = b;
updateText(); updateText();
@ -36,13 +36,13 @@ void DiveTextItem::setScale(double newscale)
scale = newscale; scale = newscale;
} }
void DiveTextItem::setText(const QString& t) void DiveTextItem::setText(const QString &t)
{ {
internalText = t; internalText = t;
updateText(); updateText();
} }
const QString& DiveTextItem::text() const QString &DiveTextItem::text()
{ {
return internalText; return internalText;
} }
@ -54,7 +54,7 @@ void DiveTextItem::updateText()
textItem = NULL; textItem = NULL;
delete textBackgroundItem; delete textBackgroundItem;
textBackgroundItem = NULL; textBackgroundItem = NULL;
if(internalText.isEmpty()){ if (internalText.isEmpty()) {
return; return;
} }
@ -75,14 +75,14 @@ void DiveTextItem::updateText()
QRectF rect = fm.boundingRect(internalText); QRectF rect = fm.boundingRect(internalText);
yPos = (internalAlignFlags & Qt::AlignTop) ? 0 : yPos = (internalAlignFlags & Qt::AlignTop) ? 0 :
(internalAlignFlags & Qt::AlignBottom) ? +rect.height() : (internalAlignFlags & Qt::AlignBottom) ? +rect.height() :
/*(internalAlignFlags & Qt::AlignVCenter ? */ +rect.height() / 4; /*(internalAlignFlags & Qt::AlignVCenter ? */ +rect.height() / 4;
xPos = (internalAlignFlags & Qt::AlignLeft ) ? -rect.width() : xPos = (internalAlignFlags & Qt::AlignLeft) ? -rect.width() :
(internalAlignFlags & Qt::AlignHCenter) ? -rect.width()/2 : (internalAlignFlags & Qt::AlignHCenter) ? -rect.width() / 2 :
/* (internalAlignFlags & Qt::AlignRight) */ 0; /* (internalAlignFlags & Qt::AlignRight) */ 0;
textPath.addText( xPos, yPos, fnt, internalText); textPath.addText(xPos, yPos, fnt, internalText);
QPainterPathStroker stroker; QPainterPathStroker stroker;
stroker.setWidth(3); stroker.setWidth(3);
textBackgroundItem = new QGraphicsPathItem(stroker.createStroke(textPath), this); textBackgroundItem = new QGraphicsPathItem(stroker.createStroke(textPath), this);

View file

@ -7,19 +7,20 @@
#include <QBrush> #include <QBrush>
/* A Line Item that has animated-properties. */ /* A Line Item that has animated-properties. */
class DiveTextItem :public QObject, public QGraphicsItemGroup{ class DiveTextItem : public QObject, public QGraphicsItemGroup {
Q_OBJECT Q_OBJECT
Q_PROPERTY(QPointF pos READ pos WRITE setPos) Q_PROPERTY(QPointF pos READ pos WRITE setPos)
Q_PROPERTY(qreal opacity READ opacity WRITE setOpacity) Q_PROPERTY(qreal opacity READ opacity WRITE setOpacity)
public: public:
DiveTextItem(QGraphicsItem* parent = 0); DiveTextItem(QGraphicsItem *parent = 0);
void setText(const QString& text); void setText(const QString &text);
void setAlignment(int alignFlags); void setAlignment(int alignFlags);
void setScale(double newscale); void setScale(double newscale);
void setBrush(const QBrush& brush); void setBrush(const QBrush &brush);
void animatedHide(); void animatedHide();
void animateMoveTo(qreal x, qreal y); void animateMoveTo(qreal x, qreal y);
const QString& text(); const QString &text();
private: private:
void updateText(); void updateText();
int internalAlignFlags; int internalAlignFlags;

View file

@ -17,7 +17,7 @@
#include "display.h" #include "display.h"
#endif #endif
void ToolTipItem::addToolTip(const QString& toolTip, const QIcon& icon) void ToolTipItem::addToolTip(const QString &toolTip, const QIcon &icon)
{ {
QGraphicsPixmapItem *iconItem = 0; QGraphicsPixmapItem *iconItem = 0;
double yValue = title->boundingRect().height() + SPACING; double yValue = title->boundingRect().height() + SPACING;
@ -25,7 +25,7 @@ void ToolTipItem::addToolTip(const QString& toolTip, const QIcon& icon)
yValue += t.second->boundingRect().height(); yValue += t.second->boundingRect().height();
} }
if (!icon.isNull()) { if (!icon.isNull()) {
iconItem = new QGraphicsPixmapItem(icon.pixmap(ICON_SMALL,ICON_SMALL), this); iconItem = new QGraphicsPixmapItem(icon.pixmap(ICON_SMALL, ICON_SMALL), this);
iconItem->setPos(SPACING, yValue); iconItem->setPos(SPACING, yValue);
} }
@ -47,8 +47,8 @@ void ToolTipItem::refresh(struct graphics_context *gc, QPointF pos)
addToolTip(QString::fromUtf8(mb.buffer, mb.len)); addToolTip(QString::fromUtf8(mb.buffer, mb.len));
free_buffer(&mb); free_buffer(&mb);
QList<QGraphicsItem*> items = scene()->items(pos, Qt::IntersectsItemShape, Qt::DescendingOrder, transform()); QList<QGraphicsItem *> items = scene()->items(pos, Qt::IntersectsItemShape, Qt::DescendingOrder, transform());
Q_FOREACH(QGraphicsItem *item, items) { Q_FOREACH(QGraphicsItem * item, items) {
if (!item->toolTip().isEmpty()) if (!item->toolTip().isEmpty())
addToolTip(item->toolTip()); addToolTip(item->toolTip());
} }
@ -63,7 +63,7 @@ void ToolTipItem::clear()
toolTips.clear(); toolTips.clear();
} }
void ToolTipItem::setRect(const QRectF& r) void ToolTipItem::setRect(const QRectF &r)
{ {
// qDeleteAll(childItems()); // qDeleteAll(childItems());
delete background; delete background;
@ -74,8 +74,8 @@ void ToolTipItem::setRect(const QRectF& r)
// Creates a 2pixels border // Creates a 2pixels border
QPainterPath border; QPainterPath border;
border.addRoundedRect(-4, -4, rectangle.width() + 8, rectangle.height() + 10, 3, 3); border.addRoundedRect(-4, -4, rectangle.width() + 8, rectangle.height() + 10, 3, 3);
border.addRoundedRect(-1, -1, rectangle.width() + 3, rectangle.height() + 4, 3, 3); border.addRoundedRect(-1, -1, rectangle.width() + 3, rectangle.height() + 4, 3, 3);
setPath(border); setPath(border);
QPainterPath bg; QPainterPath bg;
@ -119,10 +119,10 @@ void ToolTipItem::expand()
height += t.second->boundingRect().height(); height += t.second->boundingRect().height();
} }
/* Left padding, Icon Size, space, right padding */ /* Left padding, Icon Size, space, right padding */
width += SPACING + ICON_SMALL + SPACING + SPACING; width += SPACING + ICON_SMALL + SPACING + SPACING;
if (width < title->boundingRect().width() + SPACING*2) if (width < title->boundingRect().width() + SPACING * 2)
width = title->boundingRect().width() + SPACING*2; width = title->boundingRect().width() + SPACING * 2;
if (height < ICON_SMALL) if (height < ICON_SMALL)
height = ICON_SMALL; height = ICON_SMALL;
@ -139,7 +139,7 @@ void ToolTipItem::expand()
status = EXPANDED; status = EXPANDED;
} }
ToolTipItem::ToolTipItem(QGraphicsItem* parent) : QGraphicsPathItem(parent), ToolTipItem::ToolTipItem(QGraphicsItem *parent) : QGraphicsPathItem(parent),
background(0), background(0),
separator(new QGraphicsLineItem(this)), separator(new QGraphicsLineItem(this)),
title(new QGraphicsSimpleTextItem(tr("Information"), this)), title(new QGraphicsSimpleTextItem(tr("Information"), this)),
@ -161,21 +161,21 @@ ToolTipItem::~ToolTipItem()
void ToolTipItem::updateTitlePosition() void ToolTipItem::updateTitlePosition()
{ {
if (rectangle.width() < title->boundingRect().width() + SPACING*4) { if (rectangle.width() < title->boundingRect().width() + SPACING * 4) {
QRectF newRect = rectangle; QRectF newRect = rectangle;
newRect.setWidth(title->boundingRect().width() + SPACING*4); newRect.setWidth(title->boundingRect().width() + SPACING * 4);
newRect.setHeight((newRect.height() && isExpanded()) ? newRect.height() : ICON_SMALL); newRect.setHeight((newRect.height() && isExpanded()) ? newRect.height() : ICON_SMALL);
setRect(newRect); setRect(newRect);
} }
title->setPos(boundingRect().width()/2 - title->boundingRect().width()/2 -1, 0); title->setPos(boundingRect().width() / 2 - title->boundingRect().width() / 2 - 1, 0);
title->setFlag(ItemIgnoresTransformations); title->setFlag(ItemIgnoresTransformations);
title->setPen(QPen(Qt::white, 1)); title->setPen(QPen(Qt::white, 1));
title->setBrush(Qt::white); title->setBrush(Qt::white);
if (toolTips.size() > 0) { if (toolTips.size() > 0) {
double x1 = 3; double x1 = 3;
double y1 = title->pos().y() + SPACING/2 + title->boundingRect().height(); double y1 = title->pos().y() + SPACING / 2 + title->boundingRect().height();
double x2 = boundingRect().width() - 10; double x2 = boundingRect().width() - 10;
double y2 = y1; double y2 = y1;
@ -188,11 +188,12 @@ void ToolTipItem::updateTitlePosition()
} }
} }
bool ToolTipItem::isExpanded() const { bool ToolTipItem::isExpanded() const
{
return status == EXPANDED; return status == EXPANDED;
} }
void ToolTipItem::mouseReleaseEvent(QGraphicsSceneMouseEvent* event) void ToolTipItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
{ {
persistPos(); persistPos();
QGraphicsPathItem::mouseReleaseEvent(event); QGraphicsPathItem::mouseReleaseEvent(event);
@ -212,27 +213,26 @@ void ToolTipItem::readPos()
QSettings s; QSettings s;
s.beginGroup("ProfileMap"); s.beginGroup("ProfileMap");
QPointF value = scene()->views().at(0)->mapToScene( QPointF value = scene()->views().at(0)->mapToScene(
s.value("tooltip_position").toPoint() s.value("tooltip_position").toPoint());
);
if (!scene()->sceneRect().contains(value)) { if (!scene()->sceneRect().contains(value)) {
value = QPointF(0,0); value = QPointF(0, 0);
} }
setPos(value); setPos(value);
} }
void ToolTipItem::setPlotInfo(const plot_info& plot) void ToolTipItem::setPlotInfo(const plot_info &plot)
{ {
pInfo = plot; pInfo = plot;
} }
void ToolTipItem::setTimeAxis(DiveCartesianAxis* axis) void ToolTipItem::setTimeAxis(DiveCartesianAxis *axis)
{ {
timeAxis = axis; timeAxis = axis;
} }
void ToolTipItem::refresh(const QPointF& pos) void ToolTipItem::refresh(const QPointF &pos)
{ {
int time = timeAxis->valueAt( pos ); int time = timeAxis->valueAt(pos);
if (time == lastTime) if (time == lastTime)
return; return;
@ -244,8 +244,8 @@ void ToolTipItem::refresh(const QPointF& pos)
addToolTip(QString::fromUtf8(mb.buffer, mb.len)); addToolTip(QString::fromUtf8(mb.buffer, mb.len));
free_buffer(&mb); free_buffer(&mb);
QList<QGraphicsItem*> items = scene()->items(pos, Qt::IntersectsItemShape, Qt::DescendingOrder, scene()->views().first()->transform()); QList<QGraphicsItem *> items = scene()->items(pos, Qt::IntersectsItemShape, Qt::DescendingOrder, scene()->views().first()->transform());
Q_FOREACH(QGraphicsItem *item, items) { Q_FOREACH(QGraphicsItem * item, items) {
if (!item->toolTip().isEmpty()) if (!item->toolTip().isEmpty())
addToolTip(item->toolTip()); addToolTip(item->toolTip());
} }

View file

@ -17,36 +17,44 @@ struct graphics_context;
/* To use a tooltip, simply ->setToolTip on the QGraphicsItem that you want /* To use a tooltip, simply ->setToolTip on the QGraphicsItem that you want
* or, if it's a "global" tooltip, set it on the mouseMoveEvent of the ProfileGraphicsView. * or, if it's a "global" tooltip, set it on the mouseMoveEvent of the ProfileGraphicsView.
*/ */
class ToolTipItem :public QObject, public QGraphicsPathItem class ToolTipItem : public QObject, public QGraphicsPathItem {
{
Q_OBJECT Q_OBJECT
void updateTitlePosition(); void updateTitlePosition();
Q_PROPERTY(QRectF rect READ boundingRect WRITE setRect) Q_PROPERTY(QRectF rect READ boundingRect WRITE setRect)
public: public:
enum Status{COLLAPSED, EXPANDED}; enum Status {
enum {ICON_SMALL = 16, ICON_MEDIUM = 24, ICON_BIG = 32, SPACING=4}; COLLAPSED,
EXPANDED
};
enum {
ICON_SMALL = 16,
ICON_MEDIUM = 24,
ICON_BIG = 32,
SPACING = 4
};
explicit ToolTipItem(QGraphicsItem* parent = 0); explicit ToolTipItem(QGraphicsItem *parent = 0);
virtual ~ToolTipItem(); virtual ~ToolTipItem();
void collapse(); void collapse();
void expand(); void expand();
void clear(); void clear();
void addToolTip(const QString& toolTip, const QIcon& icon = QIcon()); void addToolTip(const QString &toolTip, const QIcon &icon = QIcon());
void refresh(struct graphics_context* gc, QPointF pos); void refresh(struct graphics_context *gc, QPointF pos);
void refresh(const QPointF& pos); void refresh(const QPointF &pos);
bool isExpanded() const; bool isExpanded() const;
void persistPos(); void persistPos();
void readPos(); void readPos();
void mouseReleaseEvent(QGraphicsSceneMouseEvent* event); void mouseReleaseEvent(QGraphicsSceneMouseEvent *event);
void setTimeAxis(DiveCartesianAxis *axis); void setTimeAxis(DiveCartesianAxis *axis);
void setPlotInfo(const plot_info& plot); void setPlotInfo(const plot_info &plot);
public slots: public
void setRect(const QRectF& rect); slots:
void setRect(const QRectF &rect);
private: private:
typedef QPair<QGraphicsPixmapItem*, QGraphicsSimpleTextItem*> ToolTip; typedef QPair<QGraphicsPixmapItem *, QGraphicsSimpleTextItem *> ToolTip;
QVector<ToolTip> toolTips; QVector<ToolTip> toolTips;
QGraphicsPathItem *background; QGraphicsPathItem *background;
QGraphicsLineItem *separator; QGraphicsLineItem *separator;

View file

@ -35,15 +35,15 @@
* hard coding the item on the scene with a random * hard coding the item on the scene with a random
* value. * value.
*/ */
static struct _ItemPos{ static struct _ItemPos {
struct _Pos{ struct _Pos {
QPointF on; QPointF on;
QPointF off; QPointF off;
}; };
struct _Axis{ struct _Axis {
_Pos pos; _Pos pos;
QLineF shrinked; QLineF shrinked;
QLineF expanded; QLineF expanded;
}; };
_Pos background; _Pos background;
_Pos dcLabel; _Pos dcLabel;
@ -55,12 +55,11 @@ static struct _ItemPos{
_Axis heartBeat; _Axis heartBeat;
} itemPos; } itemPos;
ProfileWidget2::ProfileWidget2(QWidget *parent) : ProfileWidget2::ProfileWidget2(QWidget *parent) : QGraphicsView(parent),
QGraphicsView(parent),
dataModel(new DivePlotDataModel(this)), dataModel(new DivePlotDataModel(this)),
currentState(INVALID), currentState(INVALID),
zoomLevel(0), zoomLevel(0),
background (new DivePixmapItem()), background(new DivePixmapItem()),
toolTipItem(new ToolTipItem()), toolTipItem(new ToolTipItem()),
profileYAxis(new DepthAxis()), profileYAxis(new DepthAxis()),
gasYAxis(new PartialGasPressureAxis()), gasYAxis(new PartialGasPressureAxis()),
@ -74,9 +73,9 @@ ProfileWidget2::ProfileWidget2(QWidget *parent) :
diveComputerText(new DiveTextItem()), diveComputerText(new DiveTextItem()),
diveCeiling(new DiveCalculatedCeiling()), diveCeiling(new DiveCalculatedCeiling()),
reportedCeiling(new DiveReportedCeiling()), reportedCeiling(new DiveReportedCeiling()),
pn2GasItem( new PartialPressureGasItem()), pn2GasItem(new PartialPressureGasItem()),
pheGasItem( new PartialPressureGasItem()), pheGasItem(new PartialPressureGasItem()),
po2GasItem( new PartialPressureGasItem()), po2GasItem(new PartialPressureGasItem()),
heartBeatAxis(new DiveCartesianAxis()), heartBeatAxis(new DiveCartesianAxis()),
heartBeatItem(new DiveHeartrateItem()), heartBeatItem(new DiveHeartrateItem()),
isPlotZoomed(prefs.zoomed_plot), isPlotZoomed(prefs.zoomed_plot),
@ -123,7 +122,7 @@ void ProfileWidget2::addItemsToScene()
scene()->addItem(rulerItem); scene()->addItem(rulerItem);
scene()->addItem(rulerItem->sourceNode()); scene()->addItem(rulerItem->sourceNode());
scene()->addItem(rulerItem->destNode()); scene()->addItem(rulerItem->destNode());
Q_FOREACH(DiveCalculatedTissue *tissue, allTissues){ Q_FOREACH(DiveCalculatedTissue * tissue, allTissues) {
scene()->addItem(tissue); scene()->addItem(tissue);
} }
} }
@ -135,7 +134,7 @@ void ProfileWidget2::setupItemOnScene()
profileYAxis->setOrientation(DiveCartesianAxis::TopToBottom); profileYAxis->setOrientation(DiveCartesianAxis::TopToBottom);
profileYAxis->setMinimum(0); profileYAxis->setMinimum(0);
profileYAxis->setTickInterval(M_OR_FT(10,30)); profileYAxis->setTickInterval(M_OR_FT(10, 30));
profileYAxis->setTickSize(1); profileYAxis->setTickSize(1);
profileYAxis->setLineSize(96); profileYAxis->setLineSize(96);
@ -163,7 +162,7 @@ void ProfileWidget2::setupItemOnScene()
cylinderPressureAxis->setTickSize(2); cylinderPressureAxis->setTickSize(2);
cylinderPressureAxis->setTickInterval(30000); cylinderPressureAxis->setTickInterval(30000);
meanDepth->setLine(0,0,96,0); meanDepth->setLine(0, 0, 96, 0);
meanDepth->setX(3); meanDepth->setX(3);
meanDepth->setPen(QPen(QBrush(Qt::red), 0, Qt::SolidLine)); meanDepth->setPen(QPen(QBrush(Qt::red), 0, Qt::SolidLine));
meanDepth->setZValue(1); meanDepth->setZValue(1);
@ -176,9 +175,9 @@ void ProfileWidget2::setupItemOnScene()
setupItem(reportedCeiling, timeAxis, profileYAxis, dataModel, DivePlotDataModel::CEILING, DivePlotDataModel::TIME, 1); setupItem(reportedCeiling, timeAxis, profileYAxis, dataModel, DivePlotDataModel::CEILING, DivePlotDataModel::TIME, 1);
setupItem(diveCeiling, timeAxis, profileYAxis, dataModel, DivePlotDataModel::CEILING, DivePlotDataModel::TIME, 1); setupItem(diveCeiling, timeAxis, profileYAxis, dataModel, DivePlotDataModel::CEILING, DivePlotDataModel::TIME, 1);
for(int i = 0; i < 16; i++){ for (int i = 0; i < 16; i++) {
DiveCalculatedTissue *tissueItem = new DiveCalculatedTissue(); DiveCalculatedTissue *tissueItem = new DiveCalculatedTissue();
setupItem(tissueItem, timeAxis, profileYAxis, dataModel, DivePlotDataModel::TISSUE_1 + i, DivePlotDataModel::TIME, 1+i); setupItem(tissueItem, timeAxis, profileYAxis, dataModel, DivePlotDataModel::TISSUE_1 + i, DivePlotDataModel::TIME, 1 + i);
allTissues.append(tissueItem); allTissues.append(tissueItem);
} }
setupItem(gasPressureItem, timeAxis, cylinderPressureAxis, dataModel, DivePlotDataModel::TEMPERATURE, DivePlotDataModel::TIME, 1); setupItem(gasPressureItem, timeAxis, cylinderPressureAxis, dataModel, DivePlotDataModel::TEMPERATURE, DivePlotDataModel::TIME, 1);
@ -186,17 +185,17 @@ void ProfileWidget2::setupItemOnScene()
setupItem(heartBeatItem, timeAxis, heartBeatAxis, dataModel, DivePlotDataModel::HEARTBEAT, DivePlotDataModel::TIME, 1); setupItem(heartBeatItem, timeAxis, heartBeatAxis, dataModel, DivePlotDataModel::HEARTBEAT, DivePlotDataModel::TIME, 1);
setupItem(diveProfileItem, timeAxis, profileYAxis, dataModel, DivePlotDataModel::DEPTH, DivePlotDataModel::TIME, 0); setupItem(diveProfileItem, timeAxis, profileYAxis, dataModel, DivePlotDataModel::DEPTH, DivePlotDataModel::TIME, 0);
#define CREATE_PP_GAS( ITEM, VERTICAL_COLUMN, COLOR, COLOR_ALERT, THRESHOULD_SETTINGS, VISIBILITY_SETTINGS ) \ #define CREATE_PP_GAS(ITEM, VERTICAL_COLUMN, COLOR, COLOR_ALERT, THRESHOULD_SETTINGS, VISIBILITY_SETTINGS) \
setupItem(ITEM, timeAxis, gasYAxis, dataModel, DivePlotDataModel::VERTICAL_COLUMN, DivePlotDataModel::TIME, 0); \ setupItem(ITEM, timeAxis, gasYAxis, dataModel, DivePlotDataModel::VERTICAL_COLUMN, DivePlotDataModel::TIME, 0); \
ITEM->setThreshouldSettingsKey(THRESHOULD_SETTINGS); \ ITEM->setThreshouldSettingsKey(THRESHOULD_SETTINGS); \
ITEM->setVisibilitySettingsKey(VISIBILITY_SETTINGS); \ ITEM->setVisibilitySettingsKey(VISIBILITY_SETTINGS); \
ITEM->setColors(getColor(COLOR), getColor(COLOR_ALERT)); \ ITEM->setColors(getColor(COLOR), getColor(COLOR_ALERT)); \
ITEM->preferencesChanged(); \ ITEM->preferencesChanged(); \
ITEM->setZValue(99); ITEM->setZValue(99);
CREATE_PP_GAS( pn2GasItem, PN2, PN2, PN2_ALERT, "pn2threshold", "pn2graph"); CREATE_PP_GAS(pn2GasItem, PN2, PN2, PN2_ALERT, "pn2threshold", "pn2graph");
CREATE_PP_GAS( pheGasItem, PHE, PHE, PHE_ALERT, "phethreshold", "phegraph"); CREATE_PP_GAS(pheGasItem, PHE, PHE, PHE_ALERT, "phethreshold", "phegraph");
CREATE_PP_GAS( po2GasItem, PO2, PO2, PO2_ALERT, "po2threshold", "po2graph"); CREATE_PP_GAS(po2GasItem, PO2, PO2, PO2_ALERT, "po2threshold", "po2graph");
#undef CREATE_PP_GAS #undef CREATE_PP_GAS
temperatureAxis->setTextVisible(false); temperatureAxis->setTextVisible(false);
@ -205,7 +204,7 @@ void ProfileWidget2::setupItemOnScene()
cylinderPressureAxis->setLinesVisible(false); cylinderPressureAxis->setLinesVisible(false);
timeAxis->setLinesVisible(true); timeAxis->setLinesVisible(true);
profileYAxis->setLinesVisible(true); profileYAxis->setLinesVisible(true);
gasYAxis->setZValue(timeAxis->zValue()+1); gasYAxis->setZValue(timeAxis->zValue() + 1);
heartBeatAxis->setTextVisible(true); heartBeatAxis->setTextVisible(true);
heartBeatAxis->setLinesVisible(true); heartBeatAxis->setLinesVisible(true);
} }
@ -229,51 +228,51 @@ void ProfileWidget2::setupItemSizes()
itemPos.depth.pos.on.setY(3); itemPos.depth.pos.on.setY(3);
itemPos.depth.pos.off.setX(-2); itemPos.depth.pos.off.setX(-2);
itemPos.depth.pos.off.setY(3); itemPos.depth.pos.off.setY(3);
itemPos.depth.expanded.setP1(QPointF(0,0)); itemPos.depth.expanded.setP1(QPointF(0, 0));
itemPos.depth.expanded.setP2(QPointF(0,86)); itemPos.depth.expanded.setP2(QPointF(0, 86));
itemPos.depth.shrinked.setP1(QPointF(0,0)); itemPos.depth.shrinked.setP1(QPointF(0, 0));
itemPos.depth.shrinked.setP2(QPointF(0,60)); itemPos.depth.shrinked.setP2(QPointF(0, 60));
// Time Axis Config // Time Axis Config
itemPos.time.pos.on.setX(3); itemPos.time.pos.on.setX(3);
itemPos.time.pos.on.setY(95); itemPos.time.pos.on.setY(95);
itemPos.time.pos.off.setX(3); itemPos.time.pos.off.setX(3);
itemPos.time.pos.off.setY(110); itemPos.time.pos.off.setY(110);
itemPos.time.expanded.setP1(QPointF(0,0)); itemPos.time.expanded.setP1(QPointF(0, 0));
itemPos.time.expanded.setP2(QPointF(94,0)); itemPos.time.expanded.setP2(QPointF(94, 0));
// Partial Gas Axis Config // Partial Gas Axis Config
itemPos.partialPressure.pos.on.setX(97); itemPos.partialPressure.pos.on.setX(97);
itemPos.partialPressure.pos.on.setY(65); itemPos.partialPressure.pos.on.setY(65);
itemPos.partialPressure.pos.off.setX(110); itemPos.partialPressure.pos.off.setX(110);
itemPos.partialPressure.pos.off.setY(63); itemPos.partialPressure.pos.off.setY(63);
itemPos.partialPressure.expanded.setP1(QPointF(0,0)); itemPos.partialPressure.expanded.setP1(QPointF(0, 0));
itemPos.partialPressure.expanded.setP2(QPointF(0,30)); itemPos.partialPressure.expanded.setP2(QPointF(0, 30));
// cylinder axis config // cylinder axis config
itemPos.cylinder.pos.on.setX(3); itemPos.cylinder.pos.on.setX(3);
itemPos.cylinder.pos.on.setY(20); itemPos.cylinder.pos.on.setY(20);
itemPos.cylinder.pos.off.setX(-10); itemPos.cylinder.pos.off.setX(-10);
itemPos.cylinder.pos.off.setY(20); itemPos.cylinder.pos.off.setY(20);
itemPos.cylinder.expanded.setP1(QPointF(0,15)); itemPos.cylinder.expanded.setP1(QPointF(0, 15));
itemPos.cylinder.expanded.setP2(QPointF(0,50)); itemPos.cylinder.expanded.setP2(QPointF(0, 50));
itemPos.cylinder.shrinked.setP1(QPointF(0,0)); itemPos.cylinder.shrinked.setP1(QPointF(0, 0));
itemPos.cylinder.shrinked.setP2(QPointF(0,20)); itemPos.cylinder.shrinked.setP2(QPointF(0, 20));
// Temperature axis config // Temperature axis config
itemPos.temperature.pos.on.setX(3); itemPos.temperature.pos.on.setX(3);
itemPos.temperature.pos.on.setY(40); itemPos.temperature.pos.on.setY(40);
itemPos.temperature.pos.off.setX(-10); itemPos.temperature.pos.off.setX(-10);
itemPos.temperature.pos.off.setY(40); itemPos.temperature.pos.off.setY(40);
itemPos.temperature.expanded.setP1(QPointF(0,30)); itemPos.temperature.expanded.setP1(QPointF(0, 30));
itemPos.temperature.expanded.setP2(QPointF(0,50)); itemPos.temperature.expanded.setP2(QPointF(0, 50));
itemPos.temperature.shrinked.setP1(QPointF(0,5)); itemPos.temperature.shrinked.setP1(QPointF(0, 5));
itemPos.temperature.shrinked.setP2(QPointF(0,15)); itemPos.temperature.shrinked.setP2(QPointF(0, 15));
itemPos.heartBeat.pos.on.setX(3); itemPos.heartBeat.pos.on.setX(3);
itemPos.heartBeat.pos.on.setY(60); itemPos.heartBeat.pos.on.setY(60);
itemPos.heartBeat.expanded.setP1(QPointF(0,0)); itemPos.heartBeat.expanded.setP1(QPointF(0, 0));
itemPos.heartBeat.expanded.setP2(QPointF(0,20)); itemPos.heartBeat.expanded.setP2(QPointF(0, 20));
itemPos.dcLabel.on.setX(3); itemPos.dcLabel.on.setX(3);
itemPos.dcLabel.on.setY(100); itemPos.dcLabel.on.setY(100);
@ -281,7 +280,7 @@ void ProfileWidget2::setupItemSizes()
itemPos.dcLabel.off.setY(100); itemPos.dcLabel.off.setY(100);
} }
void ProfileWidget2::setupItem(AbstractProfilePolygonItem* item, DiveCartesianAxis* hAxis, DiveCartesianAxis* vAxis, DivePlotDataModel* model, int vData, int hData, int zValue) void ProfileWidget2::setupItem(AbstractProfilePolygonItem *item, DiveCartesianAxis *hAxis, DiveCartesianAxis *vAxis, DivePlotDataModel *model, int vData, int hData, int zValue)
{ {
item->setHorizontalAxis(hAxis); item->setHorizontalAxis(hAxis);
item->setVerticalAxis(vAxis); item->setVerticalAxis(vAxis);
@ -306,7 +305,7 @@ void ProfileWidget2::setupSceneAndFlags()
} }
// Currently just one dive, but the plan is to enable All of the selected dives. // Currently just one dive, but the plan is to enable All of the selected dives.
void ProfileWidget2::plotDives(QList<dive*> dives) void ProfileWidget2::plotDives(QList<dive *> dives)
{ {
// I Know that it's a list, but currently we are // I Know that it's a list, but currently we are
// using just the first. // using just the first.
@ -368,7 +367,7 @@ void ProfileWidget2::plotDives(QList<dive*> dives)
timeAxis->setMaximum(maxtime); timeAxis->setMaximum(maxtime);
rulerItem->setPlotInfo(pInfo); rulerItem->setPlotInfo(pInfo);
int i, incr; int i, incr;
static int increments[8] = { 10, 20, 30, 60, 5*60, 10*60, 15*60, 30*60 }; static int increments[8] = { 10, 20, 30, 60, 5 * 60, 10 * 60, 15 * 60, 30 * 60 };
/* Time markers: at most every 10 seconds, but no more than 12 markers. /* Time markers: at most every 10 seconds, but no more than 12 markers.
* We start out with 10 seconds and increment up to 30 minutes, * We start out with 10 seconds and increment up to 30 minutes,
* depending on the dive time. * depending on the dive time.
@ -387,7 +386,7 @@ void ProfileWidget2::plotDives(QList<dive*> dives)
cylinderPressureAxis->setMinimum(pInfo.minpressure); cylinderPressureAxis->setMinimum(pInfo.minpressure);
cylinderPressureAxis->setMaximum(pInfo.maxpressure); cylinderPressureAxis->setMaximum(pInfo.maxpressure);
meanDepth->setMeanDepth(pInfo.meandepth); meanDepth->setMeanDepth(pInfo.meandepth);
meanDepth->setLine(0,0,timeAxis->posAtValue(d->duration.seconds),0); meanDepth->setLine(0, 0, timeAxis->posAtValue(d->duration.seconds), 0);
meanDepth->animateMoveTo(3, profileYAxis->posAtValue(pInfo.meandepth)); meanDepth->animateMoveTo(3, profileYAxis->posAtValue(pInfo.meandepth));
dataModel->emitDataChanged(); dataModel->emitDataChanged();
@ -409,7 +408,7 @@ void ProfileWidget2::plotDives(QList<dive*> dives)
event = event->next; event = event->next;
} }
// Only set visible the ones that should be visible, but how? // Only set visible the ones that should be visible, but how?
Q_FOREACH(DiveEventItem *event, eventItems){ Q_FOREACH(DiveEventItem * event, eventItems) {
event->setVisible(true); event->setVisible(true);
// qDebug() << event->getEvent()->name << "@" << event->getEvent()->time.seconds; // qDebug() << event->getEvent()->name << "@" << event->getEvent()->time.seconds;
} }
@ -420,35 +419,35 @@ void ProfileWidget2::settingsChanged()
{ {
QSettings s; QSettings s;
s.beginGroup("TecDetails"); s.beginGroup("TecDetails");
if(s.value("phegraph").toBool()|| s.value("po2graph").toBool()|| s.value("pn2graph").toBool()){ if (s.value("phegraph").toBool() || s.value("po2graph").toBool() || s.value("pn2graph").toBool()) {
profileYAxis->animateChangeLine(itemPos.depth.shrinked); profileYAxis->animateChangeLine(itemPos.depth.shrinked);
temperatureAxis->animateChangeLine(itemPos.temperature.shrinked); temperatureAxis->animateChangeLine(itemPos.temperature.shrinked);
cylinderPressureAxis->animateChangeLine(itemPos.cylinder.shrinked); cylinderPressureAxis->animateChangeLine(itemPos.cylinder.shrinked);
}else{ } else {
profileYAxis->animateChangeLine(itemPos.depth.expanded); profileYAxis->animateChangeLine(itemPos.depth.expanded);
temperatureAxis->animateChangeLine(itemPos.temperature.expanded); temperatureAxis->animateChangeLine(itemPos.temperature.expanded);
cylinderPressureAxis->animateChangeLine(itemPos.cylinder.expanded); cylinderPressureAxis->animateChangeLine(itemPos.cylinder.expanded);
} }
if(s.value("zoomed_plot").toBool() != isPlotZoomed){ if (s.value("zoomed_plot").toBool() != isPlotZoomed) {
isPlotZoomed = s.value("zoomed_plot").toBool(); isPlotZoomed = s.value("zoomed_plot").toBool();
int diveId = dataModel->id(); int diveId = dataModel->id();
dataModel->clear(); dataModel->clear();
plotDives(QList<dive*>() << getDiveById(diveId)); plotDives(QList<dive *>() << getDiveById(diveId));
} }
if(currentState == PROFILE){ if (currentState == PROFILE) {
bool rulerVisible = s.value("rulergraph", false).toBool(); bool rulerVisible = s.value("rulergraph", false).toBool();
rulerItem->setVisible(rulerVisible); rulerItem->setVisible(rulerVisible);
rulerItem->destNode()->setVisible(rulerVisible ); rulerItem->destNode()->setVisible(rulerVisible);
rulerItem->sourceNode()->setVisible(rulerVisible ); rulerItem->sourceNode()->setVisible(rulerVisible);
}else{ } else {
rulerItem->setVisible(false); rulerItem->setVisible(false);
rulerItem->destNode()->setVisible(false); rulerItem->destNode()->setVisible(false);
rulerItem->sourceNode()->setVisible(false); rulerItem->sourceNode()->setVisible(false);
} }
} }
void ProfileWidget2::resizeEvent(QResizeEvent* event) void ProfileWidget2::resizeEvent(QResizeEvent *event)
{ {
QGraphicsView::resizeEvent(event); QGraphicsView::resizeEvent(event);
fitInView(sceneRect(), Qt::IgnoreAspectRatio); fitInView(sceneRect(), Qt::IgnoreAspectRatio);
@ -457,10 +456,10 @@ void ProfileWidget2::resizeEvent(QResizeEvent* event)
void ProfileWidget2::fixBackgroundPos() void ProfileWidget2::fixBackgroundPos()
{ {
if(currentState != EMPTY) if (currentState != EMPTY)
return; return;
QPixmap toBeScaled; QPixmap toBeScaled;
if (!backgrounds.keys().contains(backgroundFile)){ if (!backgrounds.keys().contains(backgroundFile)) {
backgrounds[backgroundFile] = QPixmap(backgroundFile); backgrounds[backgroundFile] = QPixmap(backgroundFile);
} }
toBeScaled = backgrounds[backgroundFile]; toBeScaled = backgrounds[backgroundFile];
@ -470,7 +469,7 @@ void ProfileWidget2::fixBackgroundPos()
background->setX(mapToScene(x, 0).x()); background->setX(mapToScene(x, 0).x());
} }
void ProfileWidget2::wheelEvent(QWheelEvent* event) void ProfileWidget2::wheelEvent(QWheelEvent *event)
{ {
QPoint toolTipPos = mapFromScene(toolTipItem->pos()); QPoint toolTipPos = mapFromScene(toolTipItem->pos());
double scaleFactor = 1.15; double scaleFactor = 1.15;
@ -486,9 +485,9 @@ void ProfileWidget2::wheelEvent(QWheelEvent* event)
toolTipItem->setPos(mapToScene(toolTipPos)); toolTipItem->setPos(mapToScene(toolTipPos));
} }
void ProfileWidget2::scrollViewTo(const QPoint& pos) void ProfileWidget2::scrollViewTo(const QPoint &pos)
{ {
/* since we cannot use translate() directly on the scene we hack on /* since we cannot use translate() directly on the scene we hack on
* the scroll bars (hidden) functionality */ * the scroll bars (hidden) functionality */
if (!zoomLevel) if (!zoomLevel)
return; return;
@ -500,7 +499,7 @@ void ProfileWidget2::scrollViewTo(const QPoint& pos)
hs->setValue(xRat * hs->maximum()); hs->setValue(xRat * hs->maximum());
} }
void ProfileWidget2::mouseMoveEvent(QMouseEvent* event) void ProfileWidget2::mouseMoveEvent(QMouseEvent *event)
{ {
toolTipItem->refresh(mapToScene(event->pos())); toolTipItem->refresh(mapToScene(event->pos()));
QPoint toolTipPos = mapFromScene(toolTipItem->pos()); QPoint toolTipPos = mapFromScene(toolTipItem->pos());
@ -514,8 +513,8 @@ void ProfileWidget2::mouseMoveEvent(QMouseEvent* event)
bool ProfileWidget2::eventFilter(QObject *object, QEvent *event) bool ProfileWidget2::eventFilter(QObject *object, QEvent *event)
{ {
QGraphicsScene *s = qobject_cast<QGraphicsScene*>(object); QGraphicsScene *s = qobject_cast<QGraphicsScene *>(object);
if (s && event->type() == QEvent::GraphicsSceneHelp){ if (s && event->type() == QEvent::GraphicsSceneHelp) {
event->ignore(); event->ignore();
return true; return true;
} }
@ -529,13 +528,13 @@ void ProfileWidget2::setEmptyState()
return; return;
dataModel->clear(); dataModel->clear();
backgroundFile = QString(":poster%1").arg( rand()%3 +1); backgroundFile = QString(":poster%1").arg(rand() % 3 + 1);
currentState = EMPTY; currentState = EMPTY;
fixBackgroundPos(); fixBackgroundPos();
profileYAxis->setPos(itemPos.depth.pos.off); profileYAxis->setPos(itemPos.depth.pos.off);
gasYAxis->setPos(itemPos.partialPressure.pos.off); gasYAxis->setPos(itemPos.partialPressure.pos.off);
timeAxis->setPos(itemPos.time.pos.off); timeAxis->setPos(itemPos.time.pos.off);
background->setY( itemPos.background.on.y()); background->setY(itemPos.background.on.y());
background->setVisible(true); background->setVisible(true);
toolTipItem->setVisible(false); toolTipItem->setVisible(false);
temperatureAxis->setPos(itemPos.temperature.pos.off); temperatureAxis->setPos(itemPos.temperature.pos.off);
@ -547,10 +546,10 @@ void ProfileWidget2::setEmptyState()
rulerItem->setVisible(false); rulerItem->setVisible(false);
rulerItem->destNode()->setVisible(false); rulerItem->destNode()->setVisible(false);
rulerItem->sourceNode()->setVisible(false); rulerItem->sourceNode()->setVisible(false);
Q_FOREACH(DiveCalculatedTissue *tissue, allTissues){ Q_FOREACH(DiveCalculatedTissue * tissue, allTissues) {
tissue->setVisible(false); tissue->setVisible(false);
} }
Q_FOREACH(DiveEventItem *event, eventItems){ Q_FOREACH(DiveEventItem * event, eventItems) {
event->setVisible(false); event->setVisible(false);
} }
} }
@ -570,11 +569,11 @@ void ProfileWidget2::setProfileState()
profileYAxis->setPos(itemPos.depth.pos.on); profileYAxis->setPos(itemPos.depth.pos.on);
QSettings s; QSettings s;
s.beginGroup("TecDetails"); s.beginGroup("TecDetails");
if(s.value("phegraph").toBool()|| s.value("po2graph").toBool()|| s.value("pn2graph").toBool()){ if (s.value("phegraph").toBool() || s.value("po2graph").toBool() || s.value("pn2graph").toBool()) {
profileYAxis->setLine(itemPos.depth.shrinked); profileYAxis->setLine(itemPos.depth.shrinked);
temperatureAxis->setLine(itemPos.temperature.shrinked); temperatureAxis->setLine(itemPos.temperature.shrinked);
cylinderPressureAxis->setLine(itemPos.cylinder.shrinked); cylinderPressureAxis->setLine(itemPos.cylinder.shrinked);
}else{ } else {
profileYAxis->setLine(itemPos.depth.expanded); profileYAxis->setLine(itemPos.depth.expanded);
temperatureAxis->setLine(itemPos.temperature.expanded); temperatureAxis->setLine(itemPos.temperature.expanded);
cylinderPressureAxis->setLine(itemPos.cylinder.expanded); cylinderPressureAxis->setLine(itemPos.cylinder.expanded);
@ -598,23 +597,23 @@ void ProfileWidget2::setProfileState()
diveCeiling->setVisible(s.value("calcceiling").toBool()); diveCeiling->setVisible(s.value("calcceiling").toBool());
reportedCeiling->setVisible(s.value("dcceiling").toBool()); reportedCeiling->setVisible(s.value("dcceiling").toBool());
if(s.value("calcalltissues").toBool()){ if (s.value("calcalltissues").toBool()) {
Q_FOREACH(DiveCalculatedTissue *tissue, allTissues){ Q_FOREACH(DiveCalculatedTissue * tissue, allTissues) {
tissue->setVisible(true); tissue->setVisible(true);
} }
} }
bool rulerVisible = s.value("rulergraph", false).toBool(); bool rulerVisible = s.value("rulergraph", false).toBool();
rulerItem->setVisible(rulerVisible); rulerItem->setVisible(rulerVisible);
rulerItem->destNode()->setVisible(rulerVisible ); rulerItem->destNode()->setVisible(rulerVisible);
rulerItem->sourceNode()->setVisible(rulerVisible ); rulerItem->sourceNode()->setVisible(rulerVisible);
} }
extern struct ev_select *ev_namelist; extern struct ev_select *ev_namelist;
extern int evn_allocated; extern int evn_allocated;
extern int evn_used; extern int evn_used;
void ProfileWidget2::contextMenuEvent(QContextMenuEvent* event) void ProfileWidget2::contextMenuEvent(QContextMenuEvent *event)
{ {
if (selected_dive == -1) if (selected_dive == -1)
return; return;
@ -625,26 +624,26 @@ void ProfileWidget2::contextMenuEvent(QContextMenuEvent* event)
int rowCount = model->rowCount(); int rowCount = model->rowCount();
for (int i = 0; i < rowCount; i++) { for (int i = 0; i < rowCount; i++) {
QAction *action = new QAction(&m); QAction *action = new QAction(&m);
action->setText( model->data(model->index(i, 0),Qt::DisplayRole).toString()); action->setText(model->data(model->index(i, 0), Qt::DisplayRole).toString());
connect(action, SIGNAL(triggered(bool)), this, SLOT(changeGas())); connect(action, SIGNAL(triggered(bool)), this, SLOT(changeGas()));
action->setData(event->globalPos()); action->setData(event->globalPos());
gasChange->addAction(action); gasChange->addAction(action);
} }
QAction *action = m.addAction(tr("Add Bookmark"), this, SLOT(addBookmark())); QAction *action = m.addAction(tr("Add Bookmark"), this, SLOT(addBookmark()));
action->setData(event->globalPos()); action->setData(event->globalPos());
QList<QGraphicsItem*> itemsAtPos = scene()->items(mapToScene(mapFromGlobal(event->globalPos()))); QList<QGraphicsItem *> itemsAtPos = scene()->items(mapToScene(mapFromGlobal(event->globalPos())));
Q_FOREACH(QGraphicsItem *i, itemsAtPos) { Q_FOREACH(QGraphicsItem * i, itemsAtPos) {
EventItem *item = dynamic_cast<EventItem*>(i); EventItem *item = dynamic_cast<EventItem *>(i);
if (!item) if (!item)
continue; continue;
action = new QAction(&m); action = new QAction(&m);
action->setText(tr("Remove Event")); action->setText(tr("Remove Event"));
action->setData(QVariant::fromValue<void*>(item)); // so we know what to remove. action->setData(QVariant::fromValue<void *>(item)); // so we know what to remove.
connect(action, SIGNAL(triggered(bool)), this, SLOT(removeEvent())); connect(action, SIGNAL(triggered(bool)), this, SLOT(removeEvent()));
m.addAction(action); m.addAction(action);
action = new QAction(&m); action = new QAction(&m);
action->setText(tr("Hide similar events")); action->setText(tr("Hide similar events"));
action->setData(QVariant::fromValue<void*>(item)); action->setData(QVariant::fromValue<void *>(item));
connect(action, SIGNAL(triggered(bool)), this, SLOT(hideEvents())); connect(action, SIGNAL(triggered(bool)), this, SLOT(hideEvents()));
m.addAction(action); m.addAction(action);
break; break;
@ -665,7 +664,7 @@ void ProfileWidget2::contextMenuEvent(QContextMenuEvent* event)
void ProfileWidget2::changeGas() void ProfileWidget2::changeGas()
{ {
QAction *action = qobject_cast<QAction*>(sender()); QAction *action = qobject_cast<QAction *>(sender());
QPointF scenePos = mapToScene(mapFromGlobal(action->data().toPoint())); QPointF scenePos = mapToScene(mapFromGlobal(action->data().toPoint()));
QString gas = action->text(); QString gas = action->text();
// backup the things on the dataModel, since we will clear that out. // backup the things on the dataModel, since we will clear that out.
@ -684,5 +683,5 @@ void ProfileWidget2::changeGas()
// force the redraw of the dive. // force the redraw of the dive.
//TODO: find a way to make this do not need a full redraw //TODO: find a way to make this do not need a full redraw
dataModel->clear(); dataModel->clear();
plotDives(QList<dive*>() << getDiveById(diveId)); plotDives(QList<dive *>() << getDiveById(diveId));
} }

View file

@ -44,32 +44,50 @@ class AbstractProfilePolygonItem;
class ProfileWidget2 : public QGraphicsView { class ProfileWidget2 : public QGraphicsView {
Q_OBJECT Q_OBJECT
public: public:
enum State{ EMPTY, PROFILE, EDIT, ADD, PLAN, INVALID }; enum State {
enum Items{BACKGROUND, PROFILE_Y_AXIS, GAS_Y_AXIS, TIME_AXIS, DEPTH_CONTROLLER, TIME_CONTROLLER, COLUMNS}; EMPTY,
PROFILE,
EDIT,
ADD,
PLAN,
INVALID
};
enum Items {
BACKGROUND,
PROFILE_Y_AXIS,
GAS_Y_AXIS,
TIME_AXIS,
DEPTH_CONTROLLER,
TIME_CONTROLLER,
COLUMNS
};
ProfileWidget2(QWidget *parent); ProfileWidget2(QWidget *parent);
void plotDives(QList<dive*> dives); void plotDives(QList<dive *> dives);
virtual bool eventFilter(QObject*, QEvent*); virtual bool eventFilter(QObject *, QEvent *);
void setupItem( AbstractProfilePolygonItem *item, DiveCartesianAxis *hAxis, DiveCartesianAxis *vAxis, DivePlotDataModel *model, int vData, int hData, int zValue); void setupItem(AbstractProfilePolygonItem *item, DiveCartesianAxis *hAxis, DiveCartesianAxis *vAxis, DivePlotDataModel *model, int vData, int hData, int zValue);
public slots: // Necessary to call from QAction's signals. public
slots: // Necessary to call from QAction's signals.
void settingsChanged(); void settingsChanged();
void setEmptyState(); void setEmptyState();
void setProfileState(); void setProfileState();
void changeGas(); void changeGas();
protected: protected:
virtual void resizeEvent(QResizeEvent* event); virtual void resizeEvent(QResizeEvent *event);
virtual void wheelEvent(QWheelEvent* event); virtual void wheelEvent(QWheelEvent *event);
virtual void mouseMoveEvent(QMouseEvent* event); virtual void mouseMoveEvent(QMouseEvent *event);
virtual void contextMenuEvent(QContextMenuEvent* event); virtual void contextMenuEvent(QContextMenuEvent *event);
private: /*methods*/ private: /*methods*/
void fixBackgroundPos(); void fixBackgroundPos();
void scrollViewTo(const QPoint& pos); void scrollViewTo(const QPoint &pos);
void setupSceneAndFlags(); void setupSceneAndFlags();
void setupItemSizes(); void setupItemSizes();
void addItemsToScene(); void addItemsToScene();
void setupItemOnScene(); void setupItemOnScene();
private: private:
DivePlotDataModel *dataModel; DivePlotDataModel *dataModel;
State currentState; State currentState;
@ -92,10 +110,10 @@ private:
DiveCartesianAxis *cylinderPressureAxis; DiveCartesianAxis *cylinderPressureAxis;
DiveGasPressureItem *gasPressureItem; DiveGasPressureItem *gasPressureItem;
MeanDepthLine *meanDepth; MeanDepthLine *meanDepth;
QList<DiveEventItem*> eventItems; QList<DiveEventItem *> eventItems;
DiveTextItem *diveComputerText; DiveTextItem *diveComputerText;
DiveCalculatedCeiling *diveCeiling; DiveCalculatedCeiling *diveCeiling;
QList<DiveCalculatedTissue*> allTissues; QList<DiveCalculatedTissue *> allTissues;
DiveReportedCeiling *reportedCeiling; DiveReportedCeiling *reportedCeiling;
PartialPressureGasItem *pn2GasItem; PartialPressureGasItem *pn2GasItem;
PartialPressureGasItem *pheGasItem; PartialPressureGasItem *pheGasItem;

View file

@ -13,9 +13,9 @@
#include "profile.h" #include "profile.h"
#include "display.h" #include "display.h"
RulerNodeItem2::RulerNodeItem2(struct plot_info& info) : pInfo(info), entry(NULL) , ruler(NULL) RulerNodeItem2::RulerNodeItem2(struct plot_info &info) : pInfo(info), entry(NULL), ruler(NULL)
{ {
setRect(QRect(QPoint(-8,8),QPoint(8,-8))); setRect(QRect(QPoint(-8, 8), QPoint(8, -8)));
setBrush(QColor(0xff, 0, 0, 127)); setBrush(QColor(0xff, 0, 0, 127));
setPen(QColor("#FF0000")); setPen(QColor("#FF0000"));
setFlag(QGraphicsItem::ItemIsMovable); setFlag(QGraphicsItem::ItemIsMovable);
@ -30,7 +30,7 @@ void RulerNodeItem2::setRuler(RulerItem2 *r)
void RulerNodeItem2::recalculate() void RulerNodeItem2::recalculate()
{ {
struct plot_data *data = pInfo.entry+(pInfo.nr-1); struct plot_data *data = pInfo.entry + (pInfo.nr - 1);
uint16_t count = 0; uint16_t count = 0;
if (x() < 0) { if (x() < 0) {
setPos(0, y()); setPos(0, y());
@ -38,13 +38,13 @@ void RulerNodeItem2::recalculate()
setPos(timeAxis->posAtValue(data->sec), y()); setPos(timeAxis->posAtValue(data->sec), y());
} else { } else {
data = pInfo.entry; data = pInfo.entry;
count=0; count = 0;
while (timeAxis->posAtValue(data->sec) < x() && count < pInfo.nr) { while (timeAxis->posAtValue(data->sec) < x() && count < pInfo.nr) {
data = pInfo.entry+count; data = pInfo.entry + count;
count++; count++;
} }
setPos(timeAxis->posAtValue(data->sec), depthAxis->posAtValue(data->depth)); setPos(timeAxis->posAtValue(data->sec), depthAxis->posAtValue(data->depth));
entry=data; entry = data;
} }
} }
@ -61,8 +61,7 @@ QVariant RulerNodeItem2::itemChange(GraphicsItemChange change, const QVariant &v
return QGraphicsEllipseItem::itemChange(change, value); return QGraphicsEllipseItem::itemChange(change, value);
} }
RulerItem2::RulerItem2(): RulerItem2::RulerItem2() : timeAxis(NULL),
timeAxis(NULL),
depthAxis(NULL), depthAxis(NULL),
source(new RulerNodeItem2(pInfo)), source(new RulerNodeItem2(pInfo)),
dest(new RulerNodeItem2(pInfo)), dest(new RulerNodeItem2(pInfo)),
@ -112,7 +111,6 @@ void RulerItem2::recalculate()
textItem->resetTransform(); textItem->resetTransform();
textItem->setPos(startPoint); textItem->setPos(startPoint);
textItem->rotate(globalLine.angle() * -1); textItem->rotate(globalLine.angle() * -1);
} }
RulerNodeItem2 *RulerItem2::sourceNode() const RulerNodeItem2 *RulerItem2::sourceNode() const
@ -147,7 +145,7 @@ QPainterPath RulerItem2::shape() const
QLineF line_n = line.normalVector(); QLineF line_n = line.normalVector();
line_n.setLength(height); line_n.setLength(height);
if (paint_direction == 1) if (paint_direction == 1)
line_n.setAngle(line_n.angle()+180); line_n.setAngle(line_n.angle() + 180);
path.moveTo(startPoint); path.moveTo(startPoint);
path.lineTo(line_n.p2()); path.lineTo(line_n.p2());
path.lineTo(line_n.p2() + QPointF(line.dx(), line.dy())); path.lineTo(line_n.p2() + QPointF(line.dx(), line.dy()));
@ -164,7 +162,7 @@ void RulerItem2::setPlotInfo(plot_info info)
source->recalculate(); source->recalculate();
} }
void RulerItem2::setAxis(DiveCartesianAxis* time, DiveCartesianAxis* depth) void RulerItem2::setAxis(DiveCartesianAxis *time, DiveCartesianAxis *depth)
{ {
timeAxis = time; timeAxis = time;
depthAxis = depth; depthAxis = depth;

View file

@ -10,37 +10,36 @@
struct plot_data; struct plot_data;
class RulerItem2; class RulerItem2;
class RulerNodeItem2 : public QObject, public QGraphicsEllipseItem class RulerNodeItem2 : public QObject, public QGraphicsEllipseItem {
{
Q_OBJECT Q_OBJECT
friend class RulerItem2; friend class RulerItem2;
public: public:
explicit RulerNodeItem2(struct plot_info& info); explicit RulerNodeItem2(struct plot_info &info);
void setRuler(RulerItem2 *r); void setRuler(RulerItem2 *r);
void recalculate(); void recalculate();
protected: protected:
QVariant itemChange(GraphicsItemChange change, const QVariant & value ); QVariant itemChange(GraphicsItemChange change, const QVariant &value);
private: private:
struct plot_info &pInfo; struct plot_info &pInfo;
struct plot_data *entry; struct plot_data *entry;
RulerItem2* ruler; RulerItem2 *ruler;
DiveCartesianAxis *timeAxis; DiveCartesianAxis *timeAxis;
DiveCartesianAxis *depthAxis; DiveCartesianAxis *depthAxis;
}; };
class RulerItem2 : public QGraphicsObject class RulerItem2 : public QGraphicsObject {
{
Q_OBJECT Q_OBJECT
public: public:
explicit RulerItem2(); explicit RulerItem2();
void recalculate(); void recalculate();
void setPlotInfo(struct plot_info pInfo); void setPlotInfo(struct plot_info pInfo);
RulerNodeItem2* sourceNode() const; RulerNodeItem2 *sourceNode() const;
RulerNodeItem2* destNode() const; RulerNodeItem2 *destNode() const;
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget * widget = 0); void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0);
QRectF boundingRect() const; QRectF boundingRect() const;
QPainterPath shape() const; QPainterPath shape() const;
void setAxis(DiveCartesianAxis *time, DiveCartesianAxis *depth); void setAxis(DiveCartesianAxis *time, DiveCartesianAxis *depth);

View file

@ -43,12 +43,15 @@ extern struct ev_select *ev_namelist;
extern int evn_allocated; extern int evn_allocated;
extern int evn_used; extern int evn_used;
#define TOOLBAR_POS \ #define TOOLBAR_POS QPoint(viewport()->geometry().width() - toolBarProxy->boundingRect().width(), \
QPoint(viewport()->geometry().width() - toolBarProxy->boundingRect().width(), \ viewport()->geometry().height() - toolBarProxy->boundingRect().height())
viewport()->geometry().height() - toolBarProxy->boundingRect().height() )
ProfileGraphicsView::ProfileGraphicsView(QWidget* parent) : QGraphicsView(parent), ProfileGraphicsView::ProfileGraphicsView(QWidget *parent) : QGraphicsView(parent),
toolTip(0) , diveId(0), diveDC(0), rulerItem(0), toolBarProxy(0) toolTip(0),
diveId(0),
diveDC(0),
rulerItem(0),
toolBarProxy(0)
{ {
printMode = false; printMode = false;
isGrayscale = false; isGrayscale = false;
@ -68,8 +71,8 @@ ProfileGraphicsView::ProfileGraphicsView(QWidget* parent) : QGraphicsView(parent
defaultPen.setWidth(2); defaultPen.setWidth(2);
defaultPen.setCosmetic(true); defaultPen.setCosmetic(true);
setHorizontalScrollBarPolicy (Qt::ScrollBarAlwaysOff); setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
setVerticalScrollBarPolicy (Qt::ScrollBarAlwaysOff); setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
} }
/* since we cannot use translate() directly on the scene we hack on /* since we cannot use translate() directly on the scene we hack on
@ -91,7 +94,7 @@ void ProfileGraphicsView::scrollViewTo(const QPoint pos)
hs->setValue(xRat * (hMax - hMin) + hMin * 0.9); hs->setValue(xRat * (hMax - hMin) + hMin * 0.9);
} }
void ProfileGraphicsView::wheelEvent(QWheelEvent* event) void ProfileGraphicsView::wheelEvent(QWheelEvent *event)
{ {
if (!toolTip) if (!toolTip)
return; return;
@ -122,7 +125,7 @@ void ProfileGraphicsView::wheelEvent(QWheelEvent* event)
} }
} }
void ProfileGraphicsView::contextMenuEvent(QContextMenuEvent* event) void ProfileGraphicsView::contextMenuEvent(QContextMenuEvent *event)
{ {
if (selected_dive == -1) if (selected_dive == -1)
return; return;
@ -133,26 +136,26 @@ void ProfileGraphicsView::contextMenuEvent(QContextMenuEvent* event)
int rowCount = model->rowCount(); int rowCount = model->rowCount();
for (int i = 0; i < rowCount; i++) { for (int i = 0; i < rowCount; i++) {
QAction *action = new QAction(&m); QAction *action = new QAction(&m);
action->setText( model->data(model->index(i, 0),Qt::DisplayRole).toString()); action->setText(model->data(model->index(i, 0), Qt::DisplayRole).toString());
connect(action, SIGNAL(triggered(bool)), this, SLOT(changeGas())); connect(action, SIGNAL(triggered(bool)), this, SLOT(changeGas()));
action->setData(event->globalPos()); action->setData(event->globalPos());
gasChange->addAction(action); gasChange->addAction(action);
} }
QAction *action = m.addAction(tr("Add Bookmark"), this, SLOT(addBookmark())); QAction *action = m.addAction(tr("Add Bookmark"), this, SLOT(addBookmark()));
action->setData(event->globalPos()); action->setData(event->globalPos());
QList<QGraphicsItem*> itemsAtPos = scene()->items(mapToScene(mapFromGlobal(event->globalPos()))); QList<QGraphicsItem *> itemsAtPos = scene()->items(mapToScene(mapFromGlobal(event->globalPos())));
Q_FOREACH(QGraphicsItem *i, itemsAtPos) { Q_FOREACH(QGraphicsItem * i, itemsAtPos) {
EventItem *item = dynamic_cast<EventItem*>(i); EventItem *item = dynamic_cast<EventItem *>(i);
if (!item) if (!item)
continue; continue;
action = new QAction(&m); action = new QAction(&m);
action->setText(tr("Remove Event")); action->setText(tr("Remove Event"));
action->setData(QVariant::fromValue<void*>(item)); // so we know what to remove. action->setData(QVariant::fromValue<void *>(item)); // so we know what to remove.
connect(action, SIGNAL(triggered(bool)), this, SLOT(removeEvent())); connect(action, SIGNAL(triggered(bool)), this, SLOT(removeEvent()));
m.addAction(action); m.addAction(action);
action = new QAction(&m); action = new QAction(&m);
action->setText(tr("Hide similar events")); action->setText(tr("Hide similar events"));
action->setData(QVariant::fromValue<void*>(item)); action->setData(QVariant::fromValue<void *>(item));
connect(action, SIGNAL(triggered(bool)), this, SLOT(hideEvents())); connect(action, SIGNAL(triggered(bool)), this, SLOT(hideEvents()));
m.addAction(action); m.addAction(action);
break; break;
@ -173,7 +176,7 @@ void ProfileGraphicsView::contextMenuEvent(QContextMenuEvent* event)
void ProfileGraphicsView::addBookmark() void ProfileGraphicsView::addBookmark()
{ {
QAction *action = qobject_cast<QAction*>(sender()); QAction *action = qobject_cast<QAction *>(sender());
QPoint globalPos = action->data().toPoint(); QPoint globalPos = action->data().toPoint();
QPoint viewPos = mapFromGlobal(globalPos); QPoint viewPos = mapFromGlobal(globalPos);
QPointF scenePos = mapToScene(viewPos); QPointF scenePos = mapToScene(viewPos);
@ -185,7 +188,7 @@ void ProfileGraphicsView::addBookmark()
void ProfileGraphicsView::changeGas() void ProfileGraphicsView::changeGas()
{ {
QAction *action = qobject_cast<QAction*>(sender()); QAction *action = qobject_cast<QAction *>(sender());
QPoint globalPos = action->data().toPoint(); QPoint globalPos = action->data().toPoint();
QPoint viewPos = mapFromGlobal(globalPos); QPoint viewPos = mapFromGlobal(globalPos);
QPointF scenePos = mapToScene(viewPos); QPointF scenePos = mapToScene(viewPos);
@ -203,17 +206,17 @@ void ProfileGraphicsView::changeGas()
void ProfileGraphicsView::hideEvents() void ProfileGraphicsView::hideEvents()
{ {
QAction *action = qobject_cast<QAction*>(sender()); QAction *action = qobject_cast<QAction *>(sender());
EventItem *item = static_cast<EventItem*>(action->data().value<void*>()); EventItem *item = static_cast<EventItem *>(action->data().value<void *>());
struct event *event = item->ev; struct event *event = item->ev;
if (QMessageBox::question(MainWindow::instance(), TITLE_OR_TEXT( if (QMessageBox::question(MainWindow::instance(), TITLE_OR_TEXT(
tr("Hide events"), tr("Hide events"),
tr("Hide all %1 events?").arg(event->name)), tr("Hide all %1 events?").arg(event->name)),
QMessageBox::Ok | QMessageBox::Cancel) == QMessageBox::Ok) { QMessageBox::Ok | QMessageBox::Cancel) == QMessageBox::Ok) {
if (event->name) { if (event->name) {
for (int i = 0; i < evn_used; i++) { for (int i = 0; i < evn_used; i++) {
if (! strcmp(event->name, ev_namelist[i].ev_name)) { if (!strcmp(event->name, ev_namelist[i].ev_name)) {
ev_namelist[i].plot_ev = false; ev_namelist[i].plot_ev = false;
break; break;
} }
@ -233,15 +236,13 @@ void ProfileGraphicsView::unhideEvents()
void ProfileGraphicsView::removeEvent() void ProfileGraphicsView::removeEvent()
{ {
QAction *action = qobject_cast<QAction*>(sender()); QAction *action = qobject_cast<QAction *>(sender());
EventItem *item = static_cast<EventItem*>(action->data().value<void*>()); EventItem *item = static_cast<EventItem *>(action->data().value<void *>());
struct event *event = item->ev; struct event *event = item->ev;
if (QMessageBox::question(MainWindow::instance(), TITLE_OR_TEXT( if (QMessageBox::question(MainWindow::instance(), TITLE_OR_TEXT(
tr("Remove the selected event?"), tr("Remove the selected event?"),
tr("%1 @ %2:%3").arg(event->name) tr("%1 @ %2:%3").arg(event->name).arg(event->time.seconds / 60).arg(event->time.seconds % 60, 2, 10, QChar('0'))),
.arg(event->time.seconds / 60)
.arg(event->time.seconds % 60, 2, 10, QChar('0'))),
QMessageBox::Ok | QMessageBox::Cancel) == QMessageBox::Ok) { QMessageBox::Ok | QMessageBox::Cancel) == QMessageBox::Ok) {
struct event **ep = &current_dc->events; struct event **ep = &current_dc->events;
while (ep && *ep != event) while (ep && *ep != event)
@ -256,12 +257,12 @@ void ProfileGraphicsView::removeEvent()
} }
void ProfileGraphicsView::mouseMoveEvent(QMouseEvent* event) void ProfileGraphicsView::mouseMoveEvent(QMouseEvent *event)
{ {
if (!toolTip) if (!toolTip)
return; return;
toolTip->refresh(&gc, mapToScene(event->pos())); toolTip->refresh(&gc, mapToScene(event->pos()));
QPoint toolTipPos = mapFromScene(toolTip->pos()); QPoint toolTipPos = mapFromScene(toolTip->pos());
scrollViewTo(event->pos()); scrollViewTo(event->pos());
@ -273,7 +274,7 @@ void ProfileGraphicsView::mouseMoveEvent(QMouseEvent* event)
} }
} }
bool ProfileGraphicsView::eventFilter(QObject* obj, QEvent* event) bool ProfileGraphicsView::eventFilter(QObject *obj, QEvent *event)
{ {
if (event->type() == QEvent::Leave) { if (event->type() == QEvent::Leave) {
if (toolTip && toolTip->isExpanded()) if (toolTip && toolTip->isExpanded())
@ -306,7 +307,7 @@ static void plot_set_scale(scale_mode_t scale)
} }
#endif #endif
void ProfileGraphicsView::showEvent(QShowEvent* event) void ProfileGraphicsView::showEvent(QShowEvent *event)
{ {
// Program just opened, // Program just opened,
// but the dive was not ploted. // but the dive was not ploted.
@ -339,7 +340,7 @@ void ProfileGraphicsView::clear()
rulerItem->destNode()->deleteLater(); rulerItem->destNode()->deleteLater();
rulerItem->sourceNode()->deleteLater(); rulerItem->sourceNode()->deleteLater();
rulerItem->deleteLater(); rulerItem->deleteLater();
rulerItem=0; rulerItem = 0;
} }
scene()->clear(); scene()->clear();
} }
@ -382,7 +383,7 @@ void ProfileGraphicsView::plot(struct dive *d, bool forceRedraw)
// best place to put the focus stealer code. // best place to put the focus stealer code.
setFocusProxy(MainWindow::instance()->dive_list()); setFocusProxy(MainWindow::instance()->dive_list());
scene()->setSceneRect(0,0, viewport()->width()-50, viewport()->height()-50); scene()->setSceneRect(0, 0, viewport()->width() - 50, viewport()->height() - 50);
toolTip = new ToolTipItem(); toolTip = new ToolTipItem();
installEventFilter(toolTip); installEventFilter(toolTip);
@ -404,7 +405,7 @@ void ProfileGraphicsView::plot(struct dive *d, bool forceRedraw)
if (nick.isEmpty()) if (nick.isEmpty())
nick = tr("unknown divecomputer"); nick = tr("unknown divecomputer");
if ( tr("unknown divecomputer") == nick) { if (tr("unknown divecomputer") == nick) {
mode = PLAN; mode = PLAN;
} else { } else {
mode = DIVE; mode = DIVE;
@ -432,16 +433,16 @@ void ProfileGraphicsView::plot(struct dive *d, bool forceRedraw)
/* Depth profile */ /* Depth profile */
plot_depth_profile(); // TODO: PARTIALLY PORTED. plot_depth_profile(); // TODO: PARTIALLY PORTED.
plot_events(dc); // PORTED plot_events(dc); // PORTED
if (rulerEnabled && !printMode) // TODO: NOT PORTED. if (rulerEnabled && !printMode) // TODO: NOT PORTED.
create_ruler(); create_ruler();
/* Temperature profile */ /* Temperature profile */
plot_temperature_profile(); // PORTED plot_temperature_profile(); // PORTED
/* Cylinder pressure plot */ /* Cylinder pressure plot */
plot_cylinder_pressure(); // PORTED plot_cylinder_pressure(); // PORTED
/* Text on top of all graphs.. */ // TODO: NOT PORTED, ANY TEXT. /* Text on top of all graphs.. */ // TODO: NOT PORTED, ANY TEXT.
plot_temperature_text(); plot_temperature_text();
@ -451,10 +452,12 @@ void ProfileGraphicsView::plot(struct dive *d, bool forceRedraw)
// NOT PORTED. // NOT PORTED.
/* Put the dive computer name in the lower left corner */ /* Put the dive computer name in the lower left corner */
gc.leftx = 0; gc.rightx = 1.0; gc.leftx = 0;
gc.topy = 0; gc.bottomy = 1.0; gc.rightx = 1.0;
gc.topy = 0;
gc.bottomy = 1.0;
text_render_options_t computer = {DC_TEXT_SIZE, TIME_TEXT, LEFT, TOP}; text_render_options_t computer = { DC_TEXT_SIZE, TIME_TEXT, LEFT, TOP };
diveComputer = plot_text(&computer, QPointF(gc.leftx, gc.bottomy), nick); diveComputer = plot_text(&computer, QPointF(gc.leftx, gc.bottomy), nick);
// The Time ruler should be right after the DiveComputer: // The Time ruler should be right after the DiveComputer:
timeMarkers->setPos(0, diveComputer->y()); timeMarkers->setPos(0, diveComputer->y());
@ -477,7 +480,7 @@ void ProfileGraphicsView::plot(struct dive *d, bool forceRedraw)
#endif #endif
QRectF r = scene()->itemsBoundingRect(); QRectF r = scene()->itemsBoundingRect();
scene()->setSceneRect(r.x() - 15, r.y() -15, r.width() + 30, r.height() + 30); scene()->setSceneRect(r.x() - 15, r.y() - 15, r.width() + 30, r.height() + 30);
if (zoomLevel == 0) { if (zoomLevel == 0) {
fitInView(sceneRect()); fitInView(sceneRect());
} }
@ -485,7 +488,7 @@ void ProfileGraphicsView::plot(struct dive *d, bool forceRedraw)
if (mode == PLAN) { if (mode == PLAN) {
timeEditor = new GraphicsTextEditor(); timeEditor = new GraphicsTextEditor();
timeEditor->setPlainText(d->duration.seconds ? QString::number(d->duration.seconds/60) : tr("Set Duration: 10 minutes")); timeEditor->setPlainText(d->duration.seconds ? QString::number(d->duration.seconds / 60) : tr("Set Duration: 10 minutes"));
timeEditor->setPos(profile_grid_area.width() - timeEditor->boundingRect().width(), timeMarkers->y()); timeEditor->setPos(profile_grid_area.width() - timeEditor->boundingRect().width(), timeMarkers->y());
timeEditor->document(); timeEditor->document();
connect(timeEditor, SIGNAL(editingFinished(QString)), this, SLOT(edit_dive_time(QString))); connect(timeEditor, SIGNAL(editingFinished(QString)), this, SLOT(edit_dive_time(QString)));
@ -504,12 +507,13 @@ void ProfileGraphicsView::plot(struct dive *d, bool forceRedraw)
void ProfileGraphicsView::plot_depth_scale() void ProfileGraphicsView::plot_depth_scale()
{ {
int i, maxdepth, marker; int i, maxdepth, marker;
static text_render_options_t tro = {DEPTH_TEXT_SIZE, SAMPLE_DEEP, RIGHT, MIDDLE}; static text_render_options_t tro = { DEPTH_TEXT_SIZE, SAMPLE_DEEP, RIGHT, MIDDLE };
/* Depth markers: every 30 ft or 10 m*/ /* Depth markers: every 30 ft or 10 m*/
maxdepth = get_maxdepth(&gc.pi); maxdepth = get_maxdepth(&gc.pi);
gc.topy = 0; gc.bottomy = maxdepth; gc.topy = 0;
marker = M_OR_FT(10,30); gc.bottomy = maxdepth;
marker = M_OR_FT(10, 30);
/* don't write depth labels all the way to the bottom as /* don't write depth labels all the way to the bottom as
* there may be other graphs below the depth plot (like * there may be other graphs below the depth plot (like
@ -557,7 +561,7 @@ void ProfileGraphicsView::plot_pp_text()
{ {
double pp, dpp, m; double pp, dpp, m;
int hpos; int hpos;
static text_render_options_t tro = {PP_TEXT_SIZE, PP_LINES, LEFT, -0.75}; static text_render_options_t tro = { PP_TEXT_SIZE, PP_LINES, LEFT, -0.75 };
QGraphicsRectItem *pressureMarkers = new QGraphicsRectItem(); QGraphicsRectItem *pressureMarkers = new QGraphicsRectItem();
setup_pp_limits(&gc); setup_pp_limits(&gc);
@ -571,7 +575,7 @@ void ProfileGraphicsView::plot_pp_text()
QGraphicsLineItem *item = new QGraphicsLineItem(SCALEGC(0, m), SCALEGC(hpos, m)); QGraphicsLineItem *item = new QGraphicsLineItem(SCALEGC(0, m), SCALEGC(hpos, m));
QPen pen(defaultPen); QPen pen(defaultPen);
pen.setColor(c); pen.setColor(c);
if ( IS_FP_SAME(QString::number(m).toDouble(), QString::number(m).toInt())) { if (IS_FP_SAME(QString::number(m).toDouble(), QString::number(m).toInt())) {
pen.setStyle(Qt::DashLine); pen.setStyle(Qt::DashLine);
pen.setWidthF(1.2); pen.setWidthF(1.2);
} }
@ -606,7 +610,7 @@ void ProfileGraphicsView::plot_pp_gas_profile()
setup_pp_limits(&gc); setup_pp_limits(&gc);
QColor c; QColor c;
QPointF from, to; QPointF from, to;
QPointF legendPos = QPointF(scene()->sceneRect().width() * 0.4, scene()->sceneRect().height() - scene()->sceneRect().height()*0.02); QPointF legendPos = QPointF(scene()->sceneRect().width() * 0.4, scene()->sceneRect().height() - scene()->sceneRect().height() * 0.02);
if (prefs.pp_graphs.pn2) { if (prefs.pp_graphs.pn2) {
c = getColor(PN2); c = getColor(PN2);
@ -630,7 +634,7 @@ void ProfileGraphicsView::plot_pp_gas_profile()
else else
from = QPointF(SCALEGC(entry->sec, entry->pn2)); from = QPointF(SCALEGC(entry->sec, entry->pn2));
} }
createPPLegend(trUtf8("pN" UTF8_SUBSCRIPT_2),getColor(PN2), legendPos); createPPLegend(trUtf8("pN" UTF8_SUBSCRIPT_2), getColor(PN2), legendPos);
} }
if (prefs.pp_graphs.phe) { if (prefs.pp_graphs.phe) {
@ -656,7 +660,7 @@ void ProfileGraphicsView::plot_pp_gas_profile()
else else
from = QPointF(SCALEGC(entry->sec, entry->phe)); from = QPointF(SCALEGC(entry->sec, entry->phe));
} }
createPPLegend(trUtf8("pHe"),getColor(PHE), legendPos); createPPLegend(trUtf8("pHe"), getColor(PHE), legendPos);
} }
if (prefs.pp_graphs.po2) { if (prefs.pp_graphs.po2) {
c = getColor(PO2); c = getColor(PO2);
@ -677,27 +681,27 @@ void ProfileGraphicsView::plot_pp_gas_profile()
entry++; entry++;
if (entry->po2 >= prefs.pp_graphs.po2_threshold) if (entry->po2 >= prefs.pp_graphs.po2_threshold)
plot_add_line(entry->sec, entry->po2, c, from); plot_add_line(entry->sec, entry->po2, c, from);
else else
from = QPointF(SCALEGC(entry->sec, entry->po2)); from = QPointF(SCALEGC(entry->sec, entry->po2));
} }
createPPLegend(trUtf8("pO" UTF8_SUBSCRIPT_2),getColor(PO2), legendPos); createPPLegend(trUtf8("pO" UTF8_SUBSCRIPT_2), getColor(PO2), legendPos);
} }
} }
void ProfileGraphicsView::createPPLegend(QString title, const QColor& c, QPointF& legendPos) void ProfileGraphicsView::createPPLegend(QString title, const QColor &c, QPointF &legendPos)
{ {
QGraphicsRectItem *rect = new QGraphicsRectItem(0, 0, scene()->sceneRect().width() * 0.01, scene()->sceneRect().width() * 0.01); QGraphicsRectItem *rect = new QGraphicsRectItem(0, 0, scene()->sceneRect().width() * 0.01, scene()->sceneRect().width() * 0.01);
rect->setBrush(QBrush(c)); rect->setBrush(QBrush(c));
rect->setPos(legendPos); rect->setPos(legendPos);
rect->setPen(QPen(QColor(Qt::transparent))); rect->setPen(QPen(QColor(Qt::transparent)));
QGraphicsSimpleTextItem *text = new QGraphicsSimpleTextItem(title); QGraphicsSimpleTextItem *text = new QGraphicsSimpleTextItem(title);
text->setPos(legendPos.x() + rect->boundingRect().width() + 5, legendPos.y() ); text->setPos(legendPos.x() + rect->boundingRect().width() + 5, legendPos.y());
scene()->addItem(rect); scene()->addItem(rect);
scene()->addItem(text); scene()->addItem(text);
legendPos.setX(text->pos().x() + text->boundingRect().width() + 20); legendPos.setX(text->pos().x() + text->boundingRect().width() + 20);
if (printMode) { if (printMode) {
QFont f = text->font(); QFont f = text->font();
f.setPointSizeF( f.pointSizeF() * 0.7); f.setPointSizeF(f.pointSizeF() * 0.7);
text->setFont(f); text->setFont(f);
} }
} }
@ -707,7 +711,7 @@ void ProfileGraphicsView::plot_deco_text()
if (prefs.profile_calc_ceiling) { if (prefs.profile_calc_ceiling) {
float x = gc.leftx + (gc.rightx - gc.leftx) / 2; float x = gc.leftx + (gc.rightx - gc.leftx) / 2;
float y = gc.topy = 1.0; float y = gc.topy = 1.0;
static text_render_options_t tro = {PRESSURE_TEXT_SIZE, PRESSURE_TEXT, CENTER, BOTTOM}; static text_render_options_t tro = { PRESSURE_TEXT_SIZE, PRESSURE_TEXT, CENTER, BOTTOM };
gc.bottomy = 0.0; gc.bottomy = 0.0;
plot_text(&tro, QPointF(x, y), QString("GF %1/%2").arg(prefs.gflow).arg(prefs.gfhigh)); plot_text(&tro, QPointF(x, y), QString("GF %1/%2").arg(prefs.gflow).arg(prefs.gfhigh));
} }
@ -740,8 +744,8 @@ void ProfileGraphicsView::plot_cylinder_pressure_text()
if (!seen_cyl[cyl]) { if (!seen_cyl[cyl]) {
plot_pressure_value(mbar, entry->sec, LEFT, BOTTOM); plot_pressure_value(mbar, entry->sec, LEFT, BOTTOM);
plot_gas_value(mbar, entry->sec, LEFT, TOP, plot_gas_value(mbar, entry->sec, LEFT, TOP,
get_o2(&dive->cylinder[cyl].gasmix), get_o2(&dive->cylinder[cyl].gasmix),
get_he(&dive->cylinder[cyl].gasmix)); get_he(&dive->cylinder[cyl].gasmix));
seen_cyl[cyl] = true; seen_cyl[cyl] = true;
} }
} }
@ -762,7 +766,7 @@ void ProfileGraphicsView::plot_pressure_value(int mbar, int sec, double xalign,
const char *unit; const char *unit;
pressure = get_pressure_units(mbar, &unit); pressure = get_pressure_units(mbar, &unit);
static text_render_options_t tro = {PRESSURE_TEXT_SIZE, PRESSURE_TEXT, xalign, yalign}; static text_render_options_t tro = { PRESSURE_TEXT_SIZE, PRESSURE_TEXT, xalign, yalign };
plot_text(&tro, QPointF(sec, mbar), QString("%1 %2").arg(pressure).arg(unit)); plot_text(&tro, QPointF(sec, mbar), QString("%1 %2").arg(pressure).arg(unit));
} }
@ -775,9 +779,8 @@ void ProfileGraphicsView::plot_gas_value(int mbar, int sec, double xalign, doubl
gas = QString(tr("EAN%1")).arg((o2 + 5) / 10); gas = QString(tr("EAN%1")).arg((o2 + 5) / 10);
else else
gas = QString("%1/%2").arg((o2 + 5) / 10).arg((he + 5) / 10); gas = QString("%1/%2").arg((o2 + 5) / 10).arg((he + 5) / 10);
static text_render_options_t tro = {PRESSURE_TEXT_SIZE, PRESSURE_TEXT, xalign, yalign}; static text_render_options_t tro = { PRESSURE_TEXT_SIZE, PRESSURE_TEXT, xalign, yalign };
plot_text(&tro, QPointF(sec, mbar), gas); plot_text(&tro, QPointF(sec, mbar), gas);
} }
void ProfileGraphicsView::plot_depth_text() void ProfileGraphicsView::plot_depth_text()
@ -788,20 +791,22 @@ void ProfileGraphicsView::plot_depth_text()
maxtime = get_maxtime(&gc.pi); maxtime = get_maxtime(&gc.pi);
maxdepth = get_maxdepth(&gc.pi); maxdepth = get_maxdepth(&gc.pi);
gc.leftx = 0; gc.rightx = maxtime; gc.leftx = 0;
gc.topy = 0; gc.bottomy = maxdepth; gc.rightx = maxtime;
gc.topy = 0;
gc.bottomy = maxdepth;
plot_text_samples(); plot_text_samples();
} }
void ProfileGraphicsView::plot_text_samples() void ProfileGraphicsView::plot_text_samples()
{ {
static text_render_options_t deep = {14, SAMPLE_DEEP, CENTER, TOP}; static text_render_options_t deep = { 14, SAMPLE_DEEP, CENTER, TOP };
static text_render_options_t shallow = {14, SAMPLE_SHALLOW, CENTER, BOTTOM}; static text_render_options_t shallow = { 14, SAMPLE_SHALLOW, CENTER, BOTTOM };
int i; int i;
int last = -1; int last = -1;
struct plot_info* pi = &gc.pi; struct plot_info *pi = &gc.pi;
for (i = 0; i < pi->nr; i++) { for (i = 0; i < pi->nr; i++) {
struct plot_data *entry = pi->entry + i; struct plot_data *entry = pi->entry + i;
@ -824,7 +829,7 @@ void ProfileGraphicsView::plot_text_samples()
} }
} }
void ProfileGraphicsView::plot_depth_sample(struct plot_data *entry,text_render_options_t *tro) void ProfileGraphicsView::plot_depth_sample(struct plot_data *entry, text_render_options_t *tro)
{ {
int sec = entry->sec, decimals; int sec = entry->sec, decimals;
double d; double d;
@ -845,7 +850,7 @@ void ProfileGraphicsView::plot_temperature_text()
return; return;
for (i = 0; i < pi->nr; i++) { for (i = 0; i < pi->nr; i++) {
struct plot_data *entry = pi->entry+i; struct plot_data *entry = pi->entry + i;
int mkelvin = entry->temperature; int mkelvin = entry->temperature;
sec = entry->sec; sec = entry->sec;
@ -862,7 +867,7 @@ void ProfileGraphicsView::plot_temperature_text()
continue; continue;
last = sec; last = sec;
if (mkelvin > 200000) if (mkelvin > 200000)
plot_single_temp_text(sec,mkelvin); plot_single_temp_text(sec, mkelvin);
last_printed_temp = mkelvin; last_printed_temp = mkelvin;
} }
/* it would be nice to print the end temperature, if it's /* it would be nice to print the end temperature, if it's
@ -877,7 +882,7 @@ void ProfileGraphicsView::plot_single_temp_text(int sec, int mkelvin)
{ {
double deg; double deg;
const char *unit; const char *unit;
static text_render_options_t tro = {TEMP_TEXT_SIZE, TEMP_TEXT, LEFT, TOP}; static text_render_options_t tro = { TEMP_TEXT_SIZE, TEMP_TEXT, LEFT, TOP };
deg = get_temp_units(mkelvin, &unit); deg = get_temp_units(mkelvin, &unit);
plot_text(&tro, QPointF(sec, mkelvin), QString("%1%2").arg(deg, 0, 'f', 1).arg(unit)); //"%.2g%s" plot_text(&tro, QPointF(sec, mkelvin), QString("%1%2").arg(deg, 0, 'f', 1).arg(unit)); //"%.2g%s"
} }
@ -917,7 +922,7 @@ void ProfileGraphicsView::plot_cylinder_pressure()
int prev_pr; int prev_pr;
prev_pr = GET_PRESSURE(entry - 1); prev_pr = GET_PRESSURE(entry - 1);
QGraphicsLineItem *item = new QGraphicsLineItem(SCALEGC((entry-1)->sec, prev_pr), SCALEGC(entry->sec, mbar)); QGraphicsLineItem *item = new QGraphicsLineItem(SCALEGC((entry - 1)->sec, prev_pr), SCALEGC(entry->sec, mbar));
QPen pen(defaultPen); QPen pen(defaultPen);
pen.setColor(c); pen.setColor(c);
item->setPen(pen); item->setPen(pen);
@ -965,9 +970,9 @@ void ProfileGraphicsView::plot_events(struct divecomputer *dc)
{ {
struct event *event = dc->events; struct event *event = dc->events;
// if (gc->printer) { // if (gc->printer) {
// return; // return;
// } // }
while (event) { while (event) {
plot_one_event(event); plot_one_event(event);
@ -984,7 +989,7 @@ void ProfileGraphicsView::plot_one_event(struct event *ev)
/* is plotting of this event disabled? */ /* is plotting of this event disabled? */
if (ev->name) { if (ev->name) {
for (i = 0; i < evn_used; i++) { for (i = 0; i < evn_used; i++) {
if (! strcmp(ev->name, ev_namelist[i].ev_name)) { if (!strcmp(ev->name, ev_namelist[i].ev_name)) {
if (ev_namelist[i].plot_ev) if (ev_namelist[i].plot_ev)
break; break;
else else
@ -1018,7 +1023,7 @@ void ProfileGraphicsView::plot_one_event(struct event *ev)
item->setPos(x, y); item->setPos(x, y);
scene()->addItem(item); scene()->addItem(item);
if (ev->type == 123){ if (ev->type == 123) {
QPixmap picture; QPixmap picture;
picture.load(ev->name); picture.load(ev->name);
scene()->addPixmap(picture.scaledToHeight(100, Qt::SmoothTransformation))->setPos(x, y + 10); scene()->addPixmap(picture.scaledToHeight(100, Qt::SmoothTransformation))->setPos(x, y + 10);
@ -1041,7 +1046,7 @@ void ProfileGraphicsView::plot_one_event(struct event *ev)
name += QString(tr("EAN%1")).arg((o2 + 5) / 10); name += QString(tr("EAN%1")).arg((o2 + 5) / 10);
} else if (ev->name && !strcmp(ev->name, "SP change")) { } else if (ev->name && !strcmp(ev->name, "SP change")) {
name += QString(":%1").arg((double) ev->value / 1000); name += QString(":%1").arg((double)ev->value / 1000);
} else { } else {
name += QString(":%1").arg(ev->value); name += QString(":%1").arg(ev->value);
} }
@ -1049,7 +1054,7 @@ void ProfileGraphicsView::plot_one_event(struct event *ev)
name += "\n" + tr("Bailing out to OC"); name += "\n" + tr("Bailing out to OC");
} else { } else {
name += ev->flags == SAMPLE_FLAGS_BEGIN ? tr(" begin", "Starts with space!") : name += ev->flags == SAMPLE_FLAGS_BEGIN ? tr(" begin", "Starts with space!") :
ev->flags == SAMPLE_FLAGS_END ? tr(" end", "Starts with space!") : ""; ev->flags == SAMPLE_FLAGS_END ? tr(" end", "Starts with space!") : "";
} }
//item->setToolTipController(toolTip); //item->setToolTipController(toolTip);
@ -1059,7 +1064,7 @@ void ProfileGraphicsView::plot_one_event(struct event *ev)
void ProfileGraphicsView::create_ruler() void ProfileGraphicsView::create_ruler()
{ {
int x,y; int x, y;
struct plot_info *pi = &gc.pi; struct plot_info *pi = &gc.pi;
struct plot_data *data = pi->entry; struct plot_data *data = pi->entry;
@ -1069,13 +1074,13 @@ void ProfileGraphicsView::create_ruler()
x = SCALEXGC(data->sec); x = SCALEXGC(data->sec);
y = data->depth; y = data->depth;
first->setPos(x,y); first->setPos(x, y);
data = pi->entry+(pi->nr-1); data = pi->entry + (pi->nr - 1);
x = SCALEXGC(data->sec); x = SCALEXGC(data->sec);
y = data->depth; y = data->depth;
second->setPos(x,y); second->setPos(x, y);
//Make sure that both points already have their entries //Make sure that both points already have their entries
first->recalculate(); first->recalculate();
second->recalculate(); second->recalculate();
@ -1087,7 +1092,7 @@ void ProfileGraphicsView::create_ruler()
void ProfileGraphicsView::add_ruler() void ProfileGraphicsView::add_ruler()
{ {
if (! scene()->items().contains(rulerItem)) { if (!scene()->items().contains(rulerItem)) {
scene()->addItem(rulerItem->sourceNode()); scene()->addItem(rulerItem->sourceNode());
scene()->addItem(rulerItem->destNode()); scene()->addItem(rulerItem->destNode());
scene()->addItem(rulerItem); scene()->addItem(rulerItem);
@ -1113,7 +1118,7 @@ void ProfileGraphicsView::plot_depth_profile()
int sec, depth; int sec, depth;
struct plot_data *entry; struct plot_data *entry;
int maxtime, maxdepth, marker, maxline; int maxtime, maxdepth, marker, maxline;
int increments[8] = { 10, 20, 30, 60, 5*60, 10*60, 15*60, 30*60 }; int increments[8] = { 10, 20, 30, 60, 5 * 60, 10 * 60, 15 * 60, 30 * 60 };
/* Get plot scaling limits */ /* Get plot scaling limits */
maxtime = get_maxtime(&gc.pi); maxtime = get_maxtime(&gc.pi);
@ -1135,8 +1140,10 @@ void ProfileGraphicsView::plot_depth_profile()
while (maxtime / incr > 12) while (maxtime / incr > 12)
incr *= 2; incr *= 2;
gc.leftx = 0; gc.rightx = maxtime; gc.leftx = 0;
gc.topy = 0; gc.bottomy = 1.0; gc.rightx = maxtime;
gc.topy = 0;
gc.bottomy = 1.0;
last_gc = gc; last_gc = gc;
@ -1151,23 +1158,25 @@ void ProfileGraphicsView::plot_depth_profile()
timeMarkers = new QGraphicsRectItem(); timeMarkers = new QGraphicsRectItem();
/* now the text on the time markers */ /* now the text on the time markers */
struct text_render_options tro = {DEPTH_TEXT_SIZE, TIME_TEXT, CENTER, LINE_DOWN}; struct text_render_options tro = { DEPTH_TEXT_SIZE, TIME_TEXT, CENTER, LINE_DOWN };
if (maxtime < 600) { if (maxtime < 600) {
/* Be a bit more verbose with shorter dives */ /* Be a bit more verbose with shorter dives */
for (i = incr; i < maxtime; i += incr) for (i = incr; i < maxtime; i += incr)
plot_text(&tro, QPointF(i, 0), QString("%1:%2").arg(i/60).arg(i%60, 2, 10, QChar('0')), timeMarkers); plot_text(&tro, QPointF(i, 0), QString("%1:%2").arg(i / 60).arg(i % 60, 2, 10, QChar('0')), timeMarkers);
} else { } else {
/* Only render the time on every second marker for normal dives */ /* Only render the time on every second marker for normal dives */
for (i = incr; i < maxtime; i += 2 * incr) for (i = incr; i < maxtime; i += 2 * incr)
plot_text(&tro, QPointF(i, 0), QString("%1").arg(QString::number(i/60)), timeMarkers); plot_text(&tro, QPointF(i, 0), QString("%1").arg(QString::number(i / 60)), timeMarkers);
} }
timeMarkers->setPos(0,0); timeMarkers->setPos(0, 0);
scene()->addItem(timeMarkers); scene()->addItem(timeMarkers);
/* Depth markers: every 30 ft or 10 m*/ /* Depth markers: every 30 ft or 10 m*/
gc.leftx = 0; gc.rightx = 1.0; gc.leftx = 0;
gc.topy = 0; gc.bottomy = maxdepth; gc.rightx = 1.0;
marker = M_OR_FT(10,30); gc.topy = 0;
gc.bottomy = maxdepth;
marker = M_OR_FT(10, 30);
maxline = qMax(gc.pi.maxdepth + marker, maxdepth * 2 / 3); maxline = qMax(gc.pi.maxdepth + marker, maxdepth * 2 / 3);
c = getColor(DEPTH_GRID); c = getColor(DEPTH_GRID);
@ -1180,11 +1189,12 @@ void ProfileGraphicsView::plot_depth_profile()
scene()->addItem(item); scene()->addItem(item);
} }
gc.leftx = 0; gc.rightx = maxtime; gc.leftx = 0;
gc.rightx = maxtime;
c = getColor(MEAN_DEPTH); c = getColor(MEAN_DEPTH);
/* Show mean depth */ /* Show mean depth */
if (! gc.printer) { if (!gc.printer) {
QGraphicsLineItem *item = new QGraphicsLineItem(SCALEGC(0, gc.pi.meandepth), QGraphicsLineItem *item = new QGraphicsLineItem(SCALEGC(0, gc.pi.meandepth),
SCALEGC(gc.pi.entry[gc.pi.nr - 1].sec, gc.pi.meandepth)); SCALEGC(gc.pi.entry[gc.pi.nr - 1].sec, gc.pi.meandepth));
QPen pen(defaultPen); QPen pen(defaultPen);
@ -1192,7 +1202,7 @@ void ProfileGraphicsView::plot_depth_profile()
item->setPen(pen); item->setPen(pen);
scene()->addItem(item); scene()->addItem(item);
struct text_render_options depth_tro = {DEPTH_TEXT_SIZE, MEAN_DEPTH, LEFT, TOP}; struct text_render_options depth_tro = { DEPTH_TEXT_SIZE, MEAN_DEPTH, LEFT, TOP };
QString depthLabel = get_depth_string(gc.pi.meandepth, true, true); QString depthLabel = get_depth_string(gc.pi.meandepth, true, true);
plot_text(&depth_tro, QPointF(gc.leftx, gc.pi.meandepth), depthLabel, item); plot_text(&depth_tro, QPointF(gc.leftx, gc.pi.meandepth), depthLabel, item);
tro.hpos = RIGHT; tro.hpos = RIGHT;
@ -1211,12 +1221,13 @@ void ProfileGraphicsView::plot_depth_profile()
#endif #endif
/* Do the depth profile for the neat fill */ /* Do the depth profile for the neat fill */
gc.topy = 0; gc.bottomy = maxdepth; gc.topy = 0;
gc.bottomy = maxdepth;
entry = gc.pi.entry; entry = gc.pi.entry;
QPolygonF p; QPolygonF p;
QLinearGradient pat(0.0,0.0,0.0,scene()->height()); QLinearGradient pat(0.0, 0.0, 0.0, scene()->height());
QGraphicsPolygonItem *neatFill = NULL; QGraphicsPolygonItem *neatFill = NULL;
p.append(QPointF(SCALEGC(0, 0))); p.append(QPointF(SCALEGC(0, 0)));
@ -1242,7 +1253,7 @@ void ProfileGraphicsView::plot_depth_profile()
neatFill = new QGraphicsPolygonItem(); neatFill = new QGraphicsPolygonItem();
neatFill->setPolygon(p); neatFill->setPolygon(p);
neatFill->setBrush(QBrush(pat)); neatFill->setBrush(QBrush(pat));
neatFill->setPen(QPen(QBrush(Qt::transparent),0)); neatFill->setPen(QPen(QBrush(Qt::transparent), 0));
scene()->addItem(neatFill); scene()->addItem(neatFill);
@ -1271,7 +1282,7 @@ void ProfileGraphicsView::plot_depth_profile()
neatFill = new QGraphicsPolygonItem(); neatFill = new QGraphicsPolygonItem();
neatFill->setBrush(QBrush(pat)); neatFill->setBrush(QBrush(pat));
neatFill->setPolygon(p); neatFill->setPolygon(p);
neatFill->setPen(QPen(QBrush(Qt::NoBrush),0)); neatFill->setPen(QPen(QBrush(Qt::NoBrush), 0));
scene()->addItem(neatFill); scene()->addItem(neatFill);
} }
@ -1289,10 +1300,10 @@ void ProfileGraphicsView::plot_depth_profile()
else else
p.append(QPointF(SCALEGC(entry->sec, 0))); p.append(QPointF(SCALEGC(entry->sec, 0)));
} }
p.append(QPointF(SCALEGC((entry-1)->sec, 0))); p.append(QPointF(SCALEGC((entry - 1)->sec, 0)));
neatFill = new QGraphicsPolygonItem(); neatFill = new QGraphicsPolygonItem();
neatFill->setPolygon(p); neatFill->setPolygon(p);
neatFill->setPen(QPen(QBrush(Qt::NoBrush),0)); neatFill->setPen(QPen(QBrush(Qt::NoBrush), 0));
neatFill->setBrush(pat); neatFill->setBrush(pat);
scene()->addItem(neatFill); scene()->addItem(neatFill);
} }
@ -1300,7 +1311,7 @@ void ProfileGraphicsView::plot_depth_profile()
/* plot the calculated ceiling for all tissues */ /* plot the calculated ceiling for all tissues */
if (prefs.profile_calc_ceiling && prefs.calc_all_tissues) { if (prefs.profile_calc_ceiling && prefs.calc_all_tissues) {
int k; int k;
for (k=0; k<16; k++) { for (k = 0; k < 16; k++) {
pat.setColorAt(0, getColor(CALC_CEILING_SHALLOW)); pat.setColorAt(0, getColor(CALC_CEILING_SHALLOW));
pat.setColorAt(1, QColor(100, 100, 100, 50)); pat.setColorAt(1, QColor(100, 100, 100, 50));
@ -1313,7 +1324,7 @@ void ProfileGraphicsView::plot_depth_profile()
else else
p.append(QPointF(SCALEGC(entry->sec, 0))); p.append(QPointF(SCALEGC(entry->sec, 0)));
} }
p.append(QPointF(SCALEGC((entry-1)->sec, 0))); p.append(QPointF(SCALEGC((entry - 1)->sec, 0)));
neatFill = new QGraphicsPolygonItem(); neatFill = new QGraphicsPolygonItem();
neatFill->setPolygon(p); neatFill->setPolygon(p);
neatFill->setBrush(pat); neatFill->setBrush(pat);
@ -1332,7 +1343,7 @@ void ProfileGraphicsView::plot_depth_profile()
for (i = 0; i < gc.pi.nr; i++, entry++) for (i = 0; i < gc.pi.nr; i++, entry++)
p.append(QPointF(SCALEGC(entry->sec, entry->depth))); p.append(QPointF(SCALEGC(entry->sec, entry->depth)));
for (i-- , entry--; i >= 0; i--, entry--) { for (i--, entry--; i >= 0; i--, entry--) {
if (entry->in_deco && entry->stopdepth > entry->depth) { if (entry->in_deco && entry->stopdepth > entry->depth) {
p.append(QPointF(SCALEGC(entry->sec, entry->stopdepth))); p.append(QPointF(SCALEGC(entry->sec, entry->stopdepth)));
} else { } else {
@ -1342,7 +1353,7 @@ void ProfileGraphicsView::plot_depth_profile()
} }
neatFill = new QGraphicsPolygonItem(); neatFill = new QGraphicsPolygonItem();
neatFill->setPolygon(p); neatFill->setPolygon(p);
neatFill->setPen(QPen(QBrush(Qt::NoBrush),0)); neatFill->setPen(QPen(QBrush(Qt::NoBrush), 0));
neatFill->setBrush(QBrush(pat)); neatFill->setBrush(QBrush(pat));
scene()->addItem(neatFill); scene()->addItem(neatFill);
@ -1363,7 +1374,7 @@ void ProfileGraphicsView::plot_depth_profile()
} }
} }
QGraphicsItemGroup *ProfileGraphicsView::plot_text(text_render_options_t *tro,const QPointF& pos, const QString& text, QGraphicsItem *parent) QGraphicsItemGroup *ProfileGraphicsView::plot_text(text_render_options_t *tro, const QPointF &pos, const QString &text, QGraphicsItem *parent)
{ {
QFont fnt(font()); QFont fnt(font());
QFontMetrics fm(fnt); QFontMetrics fm(fnt);
@ -1439,7 +1450,7 @@ void ProfileGraphicsView::plot_temperature_profile()
} }
} }
void ProfileGraphicsView::edit_dive_time(const QString& time) void ProfileGraphicsView::edit_dive_time(const QString &time)
{ {
// this should set the full time of the dive. // this should set the full time of the dive.
refresh(); refresh();
@ -1462,18 +1473,18 @@ QColor EventItem::getColor(const color_indice_t i)
return profile_color[i].at((isGrayscale) ? 1 : 0); return profile_color[i].at((isGrayscale) ? 1 : 0);
} }
EventItem::EventItem(struct event *ev, QGraphicsItem* parent, bool grayscale): QGraphicsPixmapItem(parent), ev(ev), isGrayscale(grayscale) EventItem::EventItem(struct event *ev, QGraphicsItem *parent, bool grayscale) : QGraphicsPixmapItem(parent), ev(ev), isGrayscale(grayscale)
{ {
if (ev->name && (strcmp(ev->name, "bookmark") == 0 || strcmp(ev->name, "heading") == 0)) { if (ev->name && (strcmp(ev->name, "bookmark") == 0 || strcmp(ev->name, "heading") == 0)) {
setPixmap( QPixmap(QString(":flag")).scaled(20, 20, Qt::KeepAspectRatio, Qt::SmoothTransformation)); setPixmap(QPixmap(QString(":flag")).scaled(20, 20, Qt::KeepAspectRatio, Qt::SmoothTransformation));
} else { } else {
setPixmap( QPixmap(QString(":warning")).scaled(20, 20, Qt::KeepAspectRatio, Qt::SmoothTransformation)); setPixmap(QPixmap(QString(":warning")).scaled(20, 20, Qt::KeepAspectRatio, Qt::SmoothTransformation));
} }
} }
RulerNodeItem::RulerNodeItem(QGraphicsItem *parent, graphics_context context) : QGraphicsEllipseItem(parent), gc(context), entry(NULL) , ruler(NULL) RulerNodeItem::RulerNodeItem(QGraphicsItem *parent, graphics_context context) : QGraphicsEllipseItem(parent), gc(context), entry(NULL), ruler(NULL)
{ {
setRect(QRect(QPoint(-8,8),QPoint(8,-8))); setRect(QRect(QPoint(-8, 8), QPoint(8, -8)));
setBrush(QColor(0xff, 0, 0, 127)); setBrush(QColor(0xff, 0, 0, 127));
setPen(QColor("#FF0000")); setPen(QColor("#FF0000"));
setFlag(QGraphicsItem::ItemIsMovable); setFlag(QGraphicsItem::ItemIsMovable);
@ -1489,7 +1500,7 @@ void RulerNodeItem::setRuler(RulerItem *r)
void RulerNodeItem::recalculate() void RulerNodeItem::recalculate()
{ {
struct plot_info *pi = &gc.pi; struct plot_info *pi = &gc.pi;
struct plot_data *data = pi->entry+(pi->nr-1); struct plot_data *data = pi->entry + (pi->nr - 1);
uint16_t count = 0; uint16_t count = 0;
if (x() < 0) { if (x() < 0) {
setPos(0, y()); setPos(0, y());
@ -1497,13 +1508,13 @@ void RulerNodeItem::recalculate()
setPos(SCALEXGC(data->sec), y()); setPos(SCALEXGC(data->sec), y());
} else { } else {
data = pi->entry; data = pi->entry;
count=0; count = 0;
while (SCALEXGC(data->sec) < x() && count < pi->nr) { while (SCALEXGC(data->sec) < x() && count < pi->nr) {
data = pi->entry+count; data = pi->entry + count;
count++; count++;
} }
setPos(SCALEGC(data->sec, data->depth)); setPos(SCALEGC(data->sec, data->depth));
entry=data; entry = data;
} }
} }
@ -1548,7 +1559,7 @@ void RulerItem::recalculate()
compare_samples(source->entry, dest->entry, buffer, 500, 1); compare_samples(source->entry, dest->entry, buffer, 500, 1);
text = QString(buffer); text = QString(buffer);
QRect r = fm.boundingRect(QRect(QPoint(10,-1*INT_MAX), QPoint(line.length()-10, 0)), Qt::TextWordWrap, text); QRect r = fm.boundingRect(QRect(QPoint(10, -1 * INT_MAX), QPoint(line.length() - 10, 0)), Qt::TextWordWrap, text);
if (r.height() < 10) if (r.height() < 10)
height = 10; height = 10;
else else
@ -1559,7 +1570,7 @@ void RulerItem::recalculate()
if (scene()) { if (scene()) {
/* Determine whether we draw down or upwards */ /* Determine whether we draw down or upwards */
if (scene()->sceneRect().contains(line_n.p2()) && if (scene()->sceneRect().contains(line_n.p2()) &&
scene()->sceneRect().contains(endPoint+QPointF(line_n.dx(),line_n.dy()))) scene()->sceneRect().contains(endPoint + QPointF(line_n.dx(), line_n.dy())))
paint_direction = -1; paint_direction = -1;
else else
paint_direction = 1; paint_direction = 1;
@ -1585,7 +1596,7 @@ void RulerItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option,
line_n.setLength(height); line_n.setLength(height);
if (paint_direction == 1) if (paint_direction == 1)
line_n.setAngle(line_n.angle()+180); line_n.setAngle(line_n.angle() + 180);
painter->drawLine(line); painter->drawLine(line);
painter->drawLine(line_n); painter->drawLine(line_n);
painter->drawLine(line_n.p1() + QPointF(line.dx(), line.dy()), line_n.p2() + QPointF(line.dx(), line.dy())); painter->drawLine(line_n.p1() + QPointF(line.dx(), line.dy()), line_n.p2() + QPointF(line.dx(), line.dy()));
@ -1593,11 +1604,11 @@ void RulerItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option,
//Draw Text //Draw Text
painter->save(); painter->save();
painter->translate(startPoint.x(), startPoint.y()); painter->translate(startPoint.x(), startPoint.y());
painter->rotate(line.angle()*-1); painter->rotate(line.angle() * -1);
if (paint_direction == 1) if (paint_direction == 1)
painter->translate(0, height); painter->translate(0, height);
painter->setPen(Qt::black); painter->setPen(Qt::black);
painter->drawText(QRectF(QPointF(10,-1*height), QPointF(line.length()-10, 0)), Qt::TextWordWrap, text); painter->drawText(QRectF(QPointF(10, -1 * height), QPointF(line.length() - 10, 0)), Qt::TextWordWrap, text);
painter->restore(); painter->restore();
} }
@ -1613,7 +1624,7 @@ QPainterPath RulerItem::shape() const
QLineF line_n = line.normalVector(); QLineF line_n = line.normalVector();
line_n.setLength(height); line_n.setLength(height);
if (paint_direction == 1) if (paint_direction == 1)
line_n.setAngle(line_n.angle()+180); line_n.setAngle(line_n.angle() + 180);
path.moveTo(startPoint); path.moveTo(startPoint);
path.lineTo(line_n.p2()); path.lineTo(line_n.p2());
path.lineTo(line_n.p2() + QPointF(line.dx(), line.dy())); path.lineTo(line_n.p2() + QPointF(line.dx(), line.dy()));
@ -1622,25 +1633,25 @@ QPainterPath RulerItem::shape() const
return path; return path;
} }
GraphicsTextEditor::GraphicsTextEditor(QGraphicsItem* parent): QGraphicsTextItem(parent) GraphicsTextEditor::GraphicsTextEditor(QGraphicsItem *parent) : QGraphicsTextItem(parent)
{ {
} }
void GraphicsTextEditor::mouseDoubleClickEvent(QGraphicsSceneMouseEvent* event) void GraphicsTextEditor::mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event)
{ {
// Remove the proxy filter so we can focus here. // Remove the proxy filter so we can focus here.
MainWindow::instance()->graphics()->setFocusProxy(0); MainWindow::instance()->graphics()->setFocusProxy(0);
setTextInteractionFlags(Qt::TextEditorInteraction | Qt::TextEditable); setTextInteractionFlags(Qt::TextEditorInteraction | Qt::TextEditable);
} }
void GraphicsTextEditor::keyReleaseEvent(QKeyEvent* event) void GraphicsTextEditor::keyReleaseEvent(QKeyEvent *event)
{ {
if (event->key() == Qt::Key_Enter || event->key() == Qt::Key_Return) { if (event->key() == Qt::Key_Enter || event->key() == Qt::Key_Return) {
setTextInteractionFlags(Qt::NoTextInteraction); setTextInteractionFlags(Qt::NoTextInteraction);
emit editingFinished( toPlainText() ); emit editingFinished(toPlainText());
MainWindow::instance()->graphics()->setFocusProxy(MainWindow::instance()->dive_list()); MainWindow::instance()->graphics()->setFocusProxy(MainWindow::instance()->dive_list());
return; return;
} }
emit textChanged( toPlainText() ); emit textChanged(toPlainText());
QGraphicsTextItem::keyReleaseEvent(event); QGraphicsTextItem::keyReleaseEvent(event);
} }

View file

@ -15,36 +15,35 @@ struct plot_info;
class RulerItem; class RulerItem;
class ToolTipItem; class ToolTipItem;
class RulerNodeItem : public QObject, public QGraphicsEllipseItem class RulerNodeItem : public QObject, public QGraphicsEllipseItem {
{
Q_OBJECT Q_OBJECT
friend class RulerItem; friend class RulerItem;
public: public:
explicit RulerNodeItem(QGraphicsItem* parent, graphics_context gc); explicit RulerNodeItem(QGraphicsItem *parent, graphics_context gc);
void setRuler(RulerItem *r); void setRuler(RulerItem *r);
void recalculate(); void recalculate();
protected: protected:
QVariant itemChange(GraphicsItemChange change, const QVariant & value ); QVariant itemChange(GraphicsItemChange change, const QVariant &value);
private: private:
graphics_context gc; graphics_context gc;
struct plot_data *entry; struct plot_data *entry;
RulerItem* ruler; RulerItem *ruler;
}; };
class RulerItem : public QGraphicsObject class RulerItem : public QGraphicsObject {
{
Q_OBJECT Q_OBJECT
public: public:
explicit RulerItem(QGraphicsItem* parent, explicit RulerItem(QGraphicsItem *parent,
RulerNodeItem *sourceMarker, RulerNodeItem *sourceMarker,
RulerNodeItem *destMarker); RulerNodeItem *destMarker);
void recalculate(); void recalculate();
RulerNodeItem* sourceNode() const; RulerNodeItem *sourceNode() const;
RulerNodeItem* destNode() const; RulerNodeItem *destNode() const;
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget * widget = 0); void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0);
QRectF boundingRect() const; QRectF boundingRect() const;
QPainterPath shape() const; QPainterPath shape() const;
@ -56,11 +55,10 @@ private:
int paint_direction; int paint_direction;
}; };
class EventItem : public QGraphicsPixmapItem class EventItem : public QGraphicsPixmapItem {
{
public: public:
explicit EventItem(struct event *ev, QGraphicsItem* parent = 0, bool grayscale = false); explicit EventItem(struct event *ev, QGraphicsItem *parent = 0, bool grayscale = false);
struct event* ev; struct event *ev;
private: private:
QString text; QString text;
@ -69,42 +67,45 @@ private:
QColor getColor(const color_indice_t i); QColor getColor(const color_indice_t i);
}; };
class GraphicsTextEditor : public QGraphicsTextItem{ class GraphicsTextEditor : public QGraphicsTextItem {
Q_OBJECT Q_OBJECT
public: public:
GraphicsTextEditor(QGraphicsItem* parent = 0); GraphicsTextEditor(QGraphicsItem *parent = 0);
protected: protected:
virtual void mouseDoubleClickEvent(QGraphicsSceneMouseEvent* event); virtual void mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event);
virtual void keyReleaseEvent(QKeyEvent* event); virtual void keyReleaseEvent(QKeyEvent *event);
signals: signals:
void textChanged(const QString& text); void textChanged(const QString &text);
void editingFinished(const QString& text); void editingFinished(const QString &text);
}; };
class ProfileGraphicsView : public QGraphicsView class ProfileGraphicsView : public QGraphicsView {
{ Q_OBJECT
Q_OBJECT
public: public:
enum Mode{DIVE, PLAN}; enum Mode {
DIVE,
PLAN
};
ProfileGraphicsView(QWidget* parent = 0); ProfileGraphicsView(QWidget *parent = 0);
void plot(struct dive *d, bool forceRedraw = false); void plot(struct dive *d, bool forceRedraw = false);
bool eventFilter(QObject* obj, QEvent* event); bool eventFilter(QObject *obj, QEvent *event);
void clear(); void clear();
void setPrintMode(bool mode, bool grayscale = false); void setPrintMode(bool mode, bool grayscale = false);
protected: protected:
void resizeEvent(QResizeEvent *event); void resizeEvent(QResizeEvent *event);
void mouseMoveEvent(QMouseEvent* event); void mouseMoveEvent(QMouseEvent *event);
void wheelEvent(QWheelEvent* event); void wheelEvent(QWheelEvent *event);
void showEvent(QShowEvent* event); void showEvent(QShowEvent *event);
void contextMenuEvent(QContextMenuEvent* event); void contextMenuEvent(QContextMenuEvent *event);
public slots: public
slots:
void refresh(); void refresh();
void edit_dive_time(const QString& time); void edit_dive_time(const QString &time);
void on_rulerAction(); void on_rulerAction();
void on_scaleAction(); void on_scaleAction();
void changeGas(); void changeGas();
@ -112,9 +113,10 @@ public slots:
void unhideEvents(); void unhideEvents();
void removeEvent(); void removeEvent();
void addBookmark(); void addBookmark();
private: private:
void plot_depth_profile(); void plot_depth_profile();
QGraphicsItemGroup *plot_text(text_render_options_t *tro, const QPointF& pos, const QString &text, QGraphicsItem *parent = 0); QGraphicsItemGroup *plot_text(text_render_options_t *tro, const QPointF &pos, const QString &text, QGraphicsItem *parent = 0);
void plot_events(struct divecomputer *dc); void plot_events(struct divecomputer *dc);
void plot_one_event(struct event *event); void plot_one_event(struct event *event);
void plot_temperature_profile(); void plot_temperature_profile();
@ -123,7 +125,7 @@ private:
void plot_single_temp_text(int sec, int mkelvin); void plot_single_temp_text(int sec, int mkelvin);
void plot_depth_text(); void plot_depth_text();
void plot_text_samples(); void plot_text_samples();
void plot_depth_sample(plot_data* entry, text_render_options_t* tro); void plot_depth_sample(plot_data *entry, text_render_options_t *tro);
void plot_cylinder_pressure_text(); void plot_cylinder_pressure_text();
void plot_pressure_value(int mbar, int sec, double xalign, double yalign); void plot_pressure_value(int mbar, int sec, double xalign, double yalign);
void plot_gas_value(int mbar, int sec, double xalign, double yalign, int o2, int he); void plot_gas_value(int mbar, int sec, double xalign, double yalign, int o2, int he);
@ -143,7 +145,7 @@ private:
QColor getColor(const color_indice_t i); QColor getColor(const color_indice_t i);
QColor get_sac_color(int sac, int avg_sac); QColor get_sac_color(int sac, int avg_sac);
void scrollViewTo(const QPoint pos); void scrollViewTo(const QPoint pos);
void createPPLegend(QString tr, const QColor& c, QPointF& legendPos); void createPPLegend(QString tr, const QColor &c, QPointF &legendPos);
QPen defaultPen; QPen defaultPen;
QBrush defaultBrush; QBrush defaultBrush;
@ -158,10 +160,10 @@ private:
bool isGrayscale; bool isGrayscale;
// Top Level Items. // Top Level Items.
QGraphicsItem* profileGrid; QGraphicsItem *profileGrid;
QGraphicsItem* timeMarkers; QGraphicsItem *timeMarkers;
QGraphicsItem* depthMarkers; QGraphicsItem *depthMarkers;
QGraphicsItem* diveComputer; QGraphicsItem *diveComputer;
RulerItem *rulerItem; RulerItem *rulerItem;
QGraphicsProxyWidget *toolBarProxy; QGraphicsProxyWidget *toolBarProxy;

View file

@ -25,15 +25,16 @@ public:
QLabel *minIco, *minValue; QLabel *minIco, *minValue;
QLabel *maxIco, *maxValue; QLabel *maxIco, *maxValue;
MinMaxAvgWidgetPrivate(MinMaxAvgWidget *owner) { MinMaxAvgWidgetPrivate(MinMaxAvgWidget *owner)
{
avgIco = new QLabel(owner); avgIco = new QLabel(owner);
avgIco->setPixmap(QIcon(":/average").pixmap(16,16)); avgIco->setPixmap(QIcon(":/average").pixmap(16, 16));
avgIco->setToolTip(QObject::tr("Average")); avgIco->setToolTip(QObject::tr("Average"));
minIco = new QLabel(owner); minIco = new QLabel(owner);
minIco->setPixmap(QIcon(":/minimum").pixmap(16,16)); minIco->setPixmap(QIcon(":/minimum").pixmap(16, 16));
minIco->setToolTip(QObject::tr("Minimum")); minIco->setToolTip(QObject::tr("Minimum"));
maxIco = new QLabel(owner); maxIco = new QLabel(owner);
maxIco->setPixmap(QIcon(":/maximum").pixmap(16,16)); maxIco->setPixmap(QIcon(":/maximum").pixmap(16, 16));
maxIco->setToolTip(QObject::tr("Maximum")); maxIco->setToolTip(QObject::tr("Maximum"));
avgValue = new QLabel(owner); avgValue = new QLabel(owner);
minValue = new QLabel(owner); minValue = new QLabel(owner);
@ -64,9 +65,8 @@ double MinMaxAvgWidget::minimum() const
return d->minValue->text().toDouble(); return d->minValue->text().toDouble();
} }
MinMaxAvgWidget::MinMaxAvgWidget(QWidget* parent) : d(new MinMaxAvgWidgetPrivate(this)) MinMaxAvgWidget::MinMaxAvgWidget(QWidget *parent) : d(new MinMaxAvgWidgetPrivate(this))
{ {
} }
MinMaxAvgWidget::~MinMaxAvgWidget() MinMaxAvgWidget::~MinMaxAvgWidget()
@ -94,28 +94,28 @@ void MinMaxAvgWidget::setMinimum(double minimum)
d->minValue->setText(QString::number(minimum)); d->minValue->setText(QString::number(minimum));
} }
void MinMaxAvgWidget::setAverage(const QString& average) void MinMaxAvgWidget::setAverage(const QString &average)
{ {
d->avgValue->setText(average); d->avgValue->setText(average);
} }
void MinMaxAvgWidget::setMaximum(const QString& maximum) void MinMaxAvgWidget::setMaximum(const QString &maximum)
{ {
d->maxValue->setText(maximum); d->maxValue->setText(maximum);
} }
void MinMaxAvgWidget::setMinimum(const QString& minimum) void MinMaxAvgWidget::setMinimum(const QString &minimum)
{ {
d->minValue->setText(minimum); d->minValue->setText(minimum);
} }
RenumberDialog* RenumberDialog::instance() RenumberDialog *RenumberDialog::instance()
{ {
static RenumberDialog* self = new RenumberDialog(MainWindow::instance()); static RenumberDialog *self = new RenumberDialog(MainWindow::instance());
return self; return self;
} }
void RenumberDialog::buttonClicked(QAbstractButton* button) void RenumberDialog::buttonClicked(QAbstractButton *button)
{ {
if (ui.buttonBox->buttonRole(button) == QDialogButtonBox::AcceptRole) { if (ui.buttonBox->buttonRole(button) == QDialogButtonBox::AcceptRole) {
qDebug() << "Renumbering."; qDebug() << "Renumbering.";
@ -123,19 +123,19 @@ void RenumberDialog::buttonClicked(QAbstractButton* button)
} }
} }
RenumberDialog::RenumberDialog(QWidget *parent): QDialog(parent) RenumberDialog::RenumberDialog(QWidget *parent) : QDialog(parent)
{ {
ui.setupUi(this); ui.setupUi(this);
connect(ui.buttonBox, SIGNAL(clicked(QAbstractButton*)), this, SLOT(buttonClicked(QAbstractButton*))); connect(ui.buttonBox, SIGNAL(clicked(QAbstractButton *)), this, SLOT(buttonClicked(QAbstractButton *)));
} }
ShiftTimesDialog* ShiftTimesDialog::instance() ShiftTimesDialog *ShiftTimesDialog::instance()
{ {
static ShiftTimesDialog* self = new ShiftTimesDialog(MainWindow::instance()); static ShiftTimesDialog *self = new ShiftTimesDialog(MainWindow::instance());
return self; return self;
} }
void ShiftTimesDialog::buttonClicked(QAbstractButton* button) void ShiftTimesDialog::buttonClicked(QAbstractButton *button)
{ {
int amount; int amount;
@ -155,19 +155,18 @@ void ShiftTimesDialog::buttonClicked(QAbstractButton* button)
} }
} }
ShiftTimesDialog::ShiftTimesDialog(QWidget *parent): QDialog(parent) ShiftTimesDialog::ShiftTimesDialog(QWidget *parent) : QDialog(parent)
{ {
ui.setupUi(this); ui.setupUi(this);
connect(ui.buttonBox, SIGNAL(clicked(QAbstractButton*)), this, SLOT(buttonClicked(QAbstractButton*))); connect(ui.buttonBox, SIGNAL(clicked(QAbstractButton *)), this, SLOT(buttonClicked(QAbstractButton *)));
} }
void ShiftImageTimesDialog::buttonClicked(QAbstractButton* button) void ShiftImageTimesDialog::buttonClicked(QAbstractButton *button)
{ {
if (ui.buttonBox->buttonRole(button) == QDialogButtonBox::AcceptRole) { if (ui.buttonBox->buttonRole(button) == QDialogButtonBox::AcceptRole) {
m_amount = ui.timeEdit->time().hour() * 3600 + ui.timeEdit->time().minute() * 60; m_amount = ui.timeEdit->time().hour() * 3600 + ui.timeEdit->time().minute() * 60;
if (ui.backwards->isChecked()) if (ui.backwards->isChecked())
m_amount *= -1; m_amount *= -1;
} }
} }
@ -187,13 +186,13 @@ void ShiftImageTimesDialog::syncCameraClicked()
picture.load(fileNames.at(0)); picture.load(fileNames.at(0));
ui.displayDC->setEnabled(true); ui.displayDC->setEnabled(true);
QGraphicsScene *scene = new QGraphicsScene (this); QGraphicsScene *scene = new QGraphicsScene(this);
scene->addPixmap(picture.scaled(ui.DCImage->size())); scene->addPixmap(picture.scaled(ui.DCImage->size()));
ui.DCImage->setScene(scene); ui.DCImage->setScene(scene);
if (readfile(fileNames.at(0).toUtf8().data(), &mem) <= 0) if (readfile(fileNames.at(0).toUtf8().data(), &mem) <= 0)
return; return;
retval = exiv.parseFrom((const unsigned char *) mem.buffer, (unsigned) mem.size); retval = exiv.parseFrom((const unsigned char *)mem.buffer, (unsigned)mem.size);
free(mem.buffer); free(mem.buffer);
if (retval != PARSE_EXIF_SUCCESS) if (retval != PARSE_EXIF_SUCCESS)
return; return;
@ -228,12 +227,12 @@ void ShiftImageTimesDialog::dcDateTimeChanged(const QDateTime &newDateTime)
setOffset(newDateTime.toTime_t() - dcImageEpoch); setOffset(newDateTime.toTime_t() - dcImageEpoch);
} }
ShiftImageTimesDialog::ShiftImageTimesDialog(QWidget *parent): QDialog(parent), m_amount(0) ShiftImageTimesDialog::ShiftImageTimesDialog(QWidget *parent) : QDialog(parent), m_amount(0)
{ {
ui.setupUi(this); ui.setupUi(this);
connect(ui.buttonBox, SIGNAL(clicked(QAbstractButton*)), this, SLOT(buttonClicked(QAbstractButton*))); connect(ui.buttonBox, SIGNAL(clicked(QAbstractButton *)), this, SLOT(buttonClicked(QAbstractButton *)));
connect(ui.syncCamera, SIGNAL(clicked()), this, SLOT(syncCameraClicked())); connect(ui.syncCamera, SIGNAL(clicked()), this, SLOT(syncCameraClicked()));
dcImageEpoch = (time_t) 0; dcImageEpoch = (time_t)0;
} }
time_t ShiftImageTimesDialog::amount() const time_t ShiftImageTimesDialog::amount() const
@ -260,7 +259,7 @@ bool isGnome3Session()
if (qApp->style()->objectName() != "gtk+") if (qApp->style()->objectName() != "gtk+")
return false; return false;
QProcess p; QProcess p;
p.start("pidof", QStringList() << "gnome-shell" ); p.start("pidof", QStringList() << "gnome-shell");
p.waitForFinished(-1); p.waitForFinished(-1);
QString p_stdout = p.readAllStandardOutput(); QString p_stdout = p.readAllStandardOutput();
return !p_stdout.isEmpty(); return !p_stdout.isEmpty();

View file

@ -12,7 +12,7 @@ class QAbstractButton;
#include "ui_shiftimagetimes.h" #include "ui_shiftimagetimes.h"
#include "exif.h" #include "exif.h"
class MinMaxAvgWidget : public QWidget{ class MinMaxAvgWidget : public QWidget {
Q_OBJECT Q_OBJECT
Q_PROPERTY(double minimum READ minimum WRITE setMinimum) Q_PROPERTY(double minimum READ minimum WRITE setMinimum)
Q_PROPERTY(double maximum READ maximum WRITE setMaximum) Q_PROPERTY(double maximum READ maximum WRITE setMaximum)
@ -26,10 +26,11 @@ public:
void setMinimum(double minimum); void setMinimum(double minimum);
void setMaximum(double maximum); void setMaximum(double maximum);
void setAverage(double average); void setAverage(double average);
void setMinimum(const QString& minimum); void setMinimum(const QString &minimum);
void setMaximum(const QString& maximum); void setMaximum(const QString &maximum);
void setAverage(const QString& average); void setAverage(const QString &average);
void clear(); void clear();
private: private:
QScopedPointer<MinMaxAvgWidgetPrivate> d; QScopedPointer<MinMaxAvgWidgetPrivate> d;
}; };
@ -38,8 +39,10 @@ class RenumberDialog : public QDialog {
Q_OBJECT Q_OBJECT
public: public:
static RenumberDialog *instance(); static RenumberDialog *instance();
private slots: private
slots:
void buttonClicked(QAbstractButton *button); void buttonClicked(QAbstractButton *button);
private: private:
explicit RenumberDialog(QWidget *parent); explicit RenumberDialog(QWidget *parent);
Ui::RenumberDialog ui; Ui::RenumberDialog ui;
@ -49,8 +52,10 @@ class ShiftTimesDialog : public QDialog {
Q_OBJECT Q_OBJECT
public: public:
static ShiftTimesDialog *instance(); static ShiftTimesDialog *instance();
private slots: private
slots:
void buttonClicked(QAbstractButton *button); void buttonClicked(QAbstractButton *button);
private: private:
explicit ShiftTimesDialog(QWidget *parent); explicit ShiftTimesDialog(QWidget *parent);
Ui::ShiftTimesDialog ui; Ui::ShiftTimesDialog ui;
@ -63,10 +68,12 @@ public:
time_t amount() const; time_t amount() const;
void setOffset(time_t offset); void setOffset(time_t offset);
time_t epochFromExiv(EXIFInfo *exif); time_t epochFromExiv(EXIFInfo *exif);
private slots: private
slots:
void buttonClicked(QAbstractButton *button); void buttonClicked(QAbstractButton *button);
void syncCameraClicked(); void syncCameraClicked();
void dcDateTimeChanged(const QDateTime &); void dcDateTimeChanged(const QDateTime &);
private: private:
Ui::ShiftImageTimesDialog ui; Ui::ShiftImageTimesDialog ui;
time_t m_amount; time_t m_amount;

View file

@ -8,8 +8,8 @@
#include <QStyle> #include <QStyle>
#include <QStyleOption> #include <QStyleOption>
QPixmap* StarWidget::activeStar = 0; QPixmap *StarWidget::activeStar = 0;
QPixmap* StarWidget::inactiveStar = 0; QPixmap *StarWidget::inactiveStar = 0;
QPixmap StarWidget::starActive() QPixmap StarWidget::starActive()
{ {
@ -26,7 +26,7 @@ int StarWidget::currentStars() const
return current; return current;
} }
void StarWidget::mouseReleaseEvent(QMouseEvent* event) void StarWidget::mouseReleaseEvent(QMouseEvent *event)
{ {
if (readOnly) { if (readOnly) {
return; return;
@ -45,14 +45,14 @@ void StarWidget::mouseReleaseEvent(QMouseEvent* event)
update(); update();
} }
void StarWidget::paintEvent(QPaintEvent* event) void StarWidget::paintEvent(QPaintEvent *event)
{ {
QPainter p(this); QPainter p(this);
for(int i = 0; i < current; i++) for (int i = 0; i < current; i++)
p.drawPixmap(i * IMG_SIZE + SPACING, 0, starActive()); p.drawPixmap(i * IMG_SIZE + SPACING, 0, starActive());
for(int i = current; i < TOTALSTARS; i++) for (int i = current; i < TOTALSTARS; i++)
p.drawPixmap(i * IMG_SIZE + SPACING, 0, starInactive()); p.drawPixmap(i * IMG_SIZE + SPACING, 0, starInactive());
if (hasFocus()) { if (hasFocus()) {
@ -70,8 +70,7 @@ void StarWidget::setCurrentStars(int value)
Q_EMIT valueChanged(current); Q_EMIT valueChanged(current);
} }
StarWidget::StarWidget(QWidget* parent, Qt::WindowFlags f): StarWidget::StarWidget(QWidget *parent, Qt::WindowFlags f) : QWidget(parent, f),
QWidget(parent, f),
current(0), current(0),
readOnly(false) readOnly(false)
{ {
@ -93,7 +92,7 @@ StarWidget::StarWidget(QWidget* parent, Qt::WindowFlags f):
setFocusPolicy(Qt::StrongFocus); setFocusPolicy(Qt::StrongFocus);
} }
QPixmap StarWidget::grayImage(QPixmap* coloredImg) QPixmap StarWidget::grayImage(QPixmap *coloredImg)
{ {
QImage img = coloredImg->toImage(); QImage img = coloredImg->toImage();
for (int i = 0; i < img.width(); ++i) { for (int i = 0; i < img.width(); ++i) {
@ -113,7 +112,7 @@ QPixmap StarWidget::grayImage(QPixmap* coloredImg)
QSize StarWidget::sizeHint() const QSize StarWidget::sizeHint() const
{ {
return QSize(IMG_SIZE * TOTALSTARS + SPACING * (TOTALSTARS-1), IMG_SIZE); return QSize(IMG_SIZE * TOTALSTARS + SPACING * (TOTALSTARS - 1), IMG_SIZE);
} }
void StarWidget::setReadOnly(bool r) void StarWidget::setReadOnly(bool r)
@ -121,27 +120,27 @@ void StarWidget::setReadOnly(bool r)
readOnly = r; readOnly = r;
} }
void StarWidget::focusInEvent(QFocusEvent* event) void StarWidget::focusInEvent(QFocusEvent *event)
{ {
setFocus(); setFocus();
QWidget::focusInEvent(event); QWidget::focusInEvent(event);
} }
void StarWidget::focusOutEvent(QFocusEvent* event) void StarWidget::focusOutEvent(QFocusEvent *event)
{ {
QWidget::focusOutEvent(event); QWidget::focusOutEvent(event);
} }
void StarWidget::keyPressEvent(QKeyEvent* event) void StarWidget::keyPressEvent(QKeyEvent *event)
{ {
if (event->key() == Qt::Key_Up || event->key() == Qt::Key_Right) { if (event->key() == Qt::Key_Up || event->key() == Qt::Key_Right) {
if (currentStars() < TOTALSTARS) { if (currentStars() < TOTALSTARS) {
setCurrentStars( currentStars()+1); setCurrentStars(currentStars() + 1);
} }
} else if (event->key() == Qt::Key_Down || event->key() == Qt::Key_Left) { } else if (event->key() == Qt::Key_Down || event->key() == Qt::Key_Left) {
if (currentStars() > 0) { if (currentStars() > 0) {
setCurrentStars( currentStars()-1); setCurrentStars(currentStars() - 1);
} }
} }
} }

View file

@ -3,13 +3,16 @@
#include <QWidget> #include <QWidget>
enum StarConfig {SPACING = 2, IMG_SIZE = 16, TOTALSTARS = 5}; enum StarConfig {
SPACING = 2,
IMG_SIZE = 16,
TOTALSTARS = 5
};
class StarWidget : public QWidget class StarWidget : public QWidget {
{
Q_OBJECT Q_OBJECT
public: public:
explicit StarWidget(QWidget* parent = 0, Qt::WindowFlags f = 0); explicit StarWidget(QWidget *parent = 0, Qt::WindowFlags f = 0);
int currentStars() const; int currentStars() const;
/*reimp*/ QSize sizeHint() const; /*reimp*/ QSize sizeHint() const;
@ -20,22 +23,24 @@ public:
signals: signals:
void valueChanged(int stars); void valueChanged(int stars);
public slots: public
slots:
void setCurrentStars(int value); void setCurrentStars(int value);
void setReadOnly( bool readOnly); void setReadOnly(bool readOnly);
protected: protected:
/*reimp*/ void mouseReleaseEvent(QMouseEvent* ); /*reimp*/ void mouseReleaseEvent(QMouseEvent *);
/*reimp*/ void paintEvent(QPaintEvent* ); /*reimp*/ void paintEvent(QPaintEvent *);
/*reimp*/ void focusInEvent(QFocusEvent*); /*reimp*/ void focusInEvent(QFocusEvent *);
/*reimp*/ void focusOutEvent(QFocusEvent*); /*reimp*/ void focusOutEvent(QFocusEvent *);
/*reimp*/ void keyPressEvent(QKeyEvent*); /*reimp*/ void keyPressEvent(QKeyEvent *);
private: private:
int current; int current;
bool readOnly; bool readOnly;
static QPixmap* activeStar; static QPixmap *activeStar;
static QPixmap* inactiveStar; static QPixmap *inactiveStar;
QPixmap grayImage(QPixmap *coloredImg); QPixmap grayImage(QPixmap *coloredImg);
}; };

View file

@ -19,11 +19,11 @@
#include "../divelist.h" #include "../divelist.h"
#ifdef Q_OS_UNIX #ifdef Q_OS_UNIX
# include <unistd.h> // for dup(2) #include <unistd.h> // for dup(2)
#endif #endif
#if QT_VERSION >= QT_VERSION_CHECK(5,0,0) #if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
# include <QUrlQuery> #include <QUrlQuery>
#endif #endif
struct dive_table gps_location_table; struct dive_table gps_location_table;
@ -32,13 +32,13 @@ static bool merge_locations_into_dives(void);
static bool is_automatic_fix(struct dive *gpsfix) static bool is_automatic_fix(struct dive *gpsfix)
{ {
if (gpsfix && gpsfix->location && if (gpsfix && gpsfix->location &&
(!strcmp(gpsfix->location, "automatic fix") || (!strcmp(gpsfix->location, "automatic fix") ||
!strcmp(gpsfix->location, "Auto-created dive"))) !strcmp(gpsfix->location, "Auto-created dive")))
return true; return true;
return false; return false;
} }
#define SAME_GROUP 6 * 3600 // six hours #define SAME_GROUP 6 * 3600 // six hours
static bool merge_locations_into_dives(void) static bool merge_locations_into_dives(void)
{ {
@ -56,7 +56,7 @@ static bool merge_locations_into_dives(void)
utc_mkdate(gpsfix->when, &tm); utc_mkdate(gpsfix->when, &tm);
printf("found dive named %s @ %04d-%02d-%02d %02d:%02d:%02d\n", printf("found dive named %s @ %04d-%02d-%02d %02d:%02d:%02d\n",
gpsfix->location, gpsfix->location,
tm.tm_year+1900, tm.tm_mon+1, tm.tm_mday, tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday,
tm.tm_hour, tm.tm_min, tm.tm_sec); tm.tm_hour, tm.tm_min, tm.tm_sec);
#endif #endif
changed++; changed++;
@ -85,7 +85,7 @@ static bool merge_locations_into_dives(void)
#if DEBUG_WEBSERVICE #if DEBUG_WEBSERVICE
printf("didn't find dive matching gps fix named %s @ %04d-%02d-%02d %02d:%02d:%02d\n", printf("didn't find dive matching gps fix named %s @ %04d-%02d-%02d %02d:%02d:%02d\n",
gpsfix->location, gpsfix->location,
tm.tm_year+1900, tm.tm_mon+1, tm.tm_mday, tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday,
tm.tm_hour, tm.tm_min, tm.tm_sec); tm.tm_hour, tm.tm_min, tm.tm_sec);
#endif #endif
} }
@ -126,7 +126,7 @@ bool DivelogsDeWebServices::prepare_dives_for_divelogs(const QString &tempfile,
char buffer[1024]; char buffer[1024];
zip_error_to_str(buffer, sizeof buffer, error_code, errno); zip_error_to_str(buffer, sizeof buffer, error_code, errno);
*errorMsg = tr("failed to create zip file for upload: %1") *errorMsg = tr("failed to create zip file for upload: %1")
.arg(QString::fromLocal8Bit(buffer)); .arg(QString::fromLocal8Bit(buffer));
return false; return false;
} }
@ -183,7 +183,7 @@ bool DivelogsDeWebServices::prepare_dives_for_divelogs(const QString &tempfile,
free((void *)membuf); free((void *)membuf);
transformed = xsltApplyStylesheet(xslt, doc, NULL); transformed = xsltApplyStylesheet(xslt, doc, NULL);
xmlDocDumpMemory(transformed, (xmlChar **) &membuf, &streamsize); xmlDocDumpMemory(transformed, (xmlChar **)&membuf, &streamsize);
xmlFreeDoc(doc); xmlFreeDoc(doc);
xmlFreeDoc(transformed); xmlFreeDoc(transformed);
@ -209,11 +209,10 @@ error_close_zip:
return false; return false;
} }
WebServices::WebServices(QWidget* parent, Qt::WindowFlags f): QDialog(parent, f) WebServices::WebServices(QWidget *parent, Qt::WindowFlags f) : QDialog(parent, f), reply(0)
, reply(0)
{ {
ui.setupUi(this); ui.setupUi(this);
connect(ui.buttonBox, SIGNAL(clicked(QAbstractButton*)), this, SLOT(buttonClicked(QAbstractButton*))); connect(ui.buttonBox, SIGNAL(clicked(QAbstractButton *)), this, SLOT(buttonClicked(QAbstractButton *)));
connect(ui.download, SIGNAL(clicked(bool)), this, SLOT(startDownload())); connect(ui.download, SIGNAL(clicked(bool)), this, SLOT(startDownload()));
connect(ui.upload, SIGNAL(clicked(bool)), this, SLOT(startUpload())); connect(ui.upload, SIGNAL(clicked(bool)), this, SLOT(startUpload()));
connect(&timeout, SIGNAL(timeout()), this, SLOT(downloadTimedOut())); connect(&timeout, SIGNAL(timeout()), this, SLOT(downloadTimedOut()));
@ -286,8 +285,8 @@ void WebServices::connectSignalsForDownload(QNetworkReply *reply)
connect(reply, SIGNAL(finished()), this, SLOT(downloadFinished())); connect(reply, SIGNAL(finished()), this, SLOT(downloadFinished()));
connect(reply, SIGNAL(error(QNetworkReply::NetworkError)), connect(reply, SIGNAL(error(QNetworkReply::NetworkError)),
this, SLOT(downloadError(QNetworkReply::NetworkError))); this, SLOT(downloadError(QNetworkReply::NetworkError)));
connect(reply, SIGNAL(downloadProgress(qint64,qint64)), this, connect(reply, SIGNAL(downloadProgress(qint64, qint64)), this,
SLOT(updateProgress(qint64,qint64))); SLOT(updateProgress(qint64, qint64)));
timeout.start(30000); // 30s timeout.start(30000); // 30s
} }
@ -299,7 +298,7 @@ void WebServices::resetState()
ui.userID->setEnabled(true); ui.userID->setEnabled(true);
ui.password->setEnabled(true); ui.password->setEnabled(true);
ui.progressBar->reset(); ui.progressBar->reset();
ui.progressBar->setRange(0,1); ui.progressBar->setRange(0, 1);
ui.status->setText(QString()); ui.status->setText(QString());
ui.buttonBox->button(QDialogButtonBox::Apply)->setText(defaultApplyText); ui.buttonBox->button(QDialogButtonBox::Apply)->setText(defaultApplyText);
} }
@ -310,18 +309,18 @@ void WebServices::resetState()
// # // #
// # // #
SubsurfaceWebServices::SubsurfaceWebServices(QWidget* parent, Qt::WindowFlags f) : WebServices(parent, f) SubsurfaceWebServices::SubsurfaceWebServices(QWidget *parent, Qt::WindowFlags f) : WebServices(parent, f)
{ {
QSettings s; QSettings s;
ui.userID->setText(s.value("subsurface_webservice_uid").toString().toUpper()); ui.userID->setText(s.value("subsurface_webservice_uid").toString().toUpper());
hidePassword(); hidePassword();
hideUpload(); hideUpload();
ui.progressBar->setFormat("Enter User ID and click Download"); ui.progressBar->setFormat("Enter User ID and click Download");
ui.progressBar->setRange(0,1); ui.progressBar->setRange(0, 1);
ui.progressBar->setValue(-1); ui.progressBar->setValue(-1);
} }
void SubsurfaceWebServices::buttonClicked(QAbstractButton* button) void SubsurfaceWebServices::buttonClicked(QAbstractButton *button)
{ {
ui.buttonBox->button(QDialogButtonBox::Apply)->setEnabled(false); ui.buttonBox->button(QDialogButtonBox::Apply)->setEnabled(false);
switch (ui.buttonBox->buttonRole(button)) { switch (ui.buttonBox->buttonRole(button)) {
@ -345,8 +344,7 @@ void SubsurfaceWebServices::buttonClicked(QAbstractButton* button)
hide(); hide();
close(); close();
resetState(); resetState();
} } break;
break;
case QDialogButtonBox::RejectRole: case QDialogButtonBox::RejectRole:
if (reply != NULL && reply->isOpen()) { if (reply != NULL && reply->isOpen()) {
reply->abort(); reply->abort();
@ -366,7 +364,7 @@ void SubsurfaceWebServices::buttonClicked(QAbstractButton* button)
void SubsurfaceWebServices::startDownload() void SubsurfaceWebServices::startDownload()
{ {
QUrl url("http://api.hohndel.org/api/dive/get/"); QUrl url("http://api.hohndel.org/api/dive/get/");
#if QT_VERSION < QT_VERSION_CHECK(5,0,0) #if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
url.addQueryItem("login", ui.userID->text().toUpper()); url.addQueryItem("login", ui.userID->text().toUpper());
#else #else
QUrlQuery query; QUrlQuery query;
@ -380,7 +378,7 @@ void SubsurfaceWebServices::startDownload()
reply = manager()->get(request); reply = manager()->get(request);
ui.status->setText(tr("Connecting...")); ui.status->setText(tr("Connecting..."));
ui.progressBar->setEnabled(true); ui.progressBar->setEnabled(true);
ui.progressBar->setRange(0,0); // this makes the progressbar do an 'infinite spin' ui.progressBar->setRange(0, 0); // this makes the progressbar do an 'infinite spin'
ui.download->setEnabled(false); ui.download->setEnabled(false);
ui.buttonBox->button(QDialogButtonBox::Apply)->setEnabled(false); ui.buttonBox->button(QDialogButtonBox::Apply)->setEnabled(false);
connectSignalsForDownload(reply); connectSignalsForDownload(reply);
@ -391,7 +389,7 @@ void SubsurfaceWebServices::downloadFinished()
if (!reply) if (!reply)
return; return;
ui.progressBar->setRange(0,1); ui.progressBar->setRange(0, 1);
ui.progressBar->setValue(1); ui.progressBar->setValue(1);
ui.progressBar->setFormat("%p%"); ui.progressBar->setFormat("%p%");
downloadedData = reply->readAll(); downloadedData = reply->readAll();
@ -420,10 +418,18 @@ void SubsurfaceWebServices::setStatusText(int status)
{ {
QString text; QString text;
switch (status) { switch (status) {
case DD_STATUS_ERROR_CONNECT: text = tr("Connection Error: "); break; case DD_STATUS_ERROR_CONNECT:
case DD_STATUS_ERROR_ID: text = tr("Invalid user identifier!"); break; text = tr("Connection Error: ");
case DD_STATUS_ERROR_PARSE: text = tr("Cannot parse response!"); break; break;
case DD_STATUS_OK: text = tr("Download Success!"); break; case DD_STATUS_ERROR_ID:
text = tr("Invalid user identifier!");
break;
case DD_STATUS_ERROR_PARSE:
text = tr("Cannot parse response!");
break;
case DD_STATUS_OK:
text = tr("Download Success!");
break;
} }
ui.status->setText(text); ui.status->setText(text);
} }
@ -434,17 +440,17 @@ void SubsurfaceWebServices::download_dialog_traverse_xml(xmlNodePtr node, unsign
xmlNodePtr cur_node; xmlNodePtr cur_node;
for (cur_node = node; cur_node; cur_node = cur_node->next) { for (cur_node = node; cur_node; cur_node = cur_node->next) {
if ((!strcmp((const char *)cur_node->name, (const char *)"download")) && if ((!strcmp((const char *)cur_node->name, (const char *)"download")) &&
(!strcmp((const char *)xmlNodeGetContent(cur_node), (const char *)"ok"))) { (!strcmp((const char *)xmlNodeGetContent(cur_node), (const char *)"ok"))) {
*download_status = DD_STATUS_OK; *download_status = DD_STATUS_OK;
return; return;
} else if (!strcmp((const char *)cur_node->name, (const char *)"error")) { } else if (!strcmp((const char *)cur_node->name, (const char *)"error")) {
*download_status = DD_STATUS_ERROR_ID; *download_status = DD_STATUS_ERROR_ID;
return; return;
} }
} }
} }
unsigned int SubsurfaceWebServices::download_dialog_parse_response(const QByteArray& xml) unsigned int SubsurfaceWebServices::download_dialog_parse_response(const QByteArray &xml)
{ {
xmlNodePtr root; xmlNodePtr root;
xmlDocPtr doc = xmlParseMemory(xml.data(), xml.length()); xmlDocPtr doc = xmlParseMemory(xml.data(), xml.length());
@ -470,8 +476,7 @@ end:
// # // #
// # // #
struct DiveListResult struct DiveListResult {
{
QString errorCondition; QString errorCondition;
QString errorDetails; QString errorDetails;
QByteArray idList; // comma-separated, suitable to be sent in the fetch request QByteArray idList; // comma-separated, suitable to be sent in the fetch request
@ -497,8 +502,8 @@ static DiveListResult parseDiveLogsDeDiveList(const QByteArray &xmlData)
if (reader.readNextStartElement() && reader.name() != "DiveDateReader") { if (reader.readNextStartElement() && reader.name() != "DiveDateReader") {
result.errorCondition = invalidXmlError; result.errorCondition = invalidXmlError;
result.errorDetails = result.errorDetails =
DivelogsDeWebServices::tr("Expected XML tag 'DiveDateReader', got instead '%1") DivelogsDeWebServices::tr("Expected XML tag 'DiveDateReader', got instead '%1")
.arg(reader.name().toString()); .arg(reader.name().toString());
goto out; goto out;
} }
@ -551,12 +556,13 @@ out:
// if there was an XML error, overwrite the result or other error conditions // if there was an XML error, overwrite the result or other error conditions
result.errorCondition = invalidXmlError; result.errorCondition = invalidXmlError;
result.errorDetails = DivelogsDeWebServices::tr("Malformed XML response. Line %1: %2") result.errorDetails = DivelogsDeWebServices::tr("Malformed XML response. Line %1: %2")
.arg(reader.lineNumber()).arg(reader.errorString()); .arg(reader.lineNumber())
.arg(reader.errorString());
} }
return result; return result;
} }
DivelogsDeWebServices* DivelogsDeWebServices::instance() DivelogsDeWebServices *DivelogsDeWebServices::instance()
{ {
static DivelogsDeWebServices *self = new DivelogsDeWebServices(MainWindow::instance()); static DivelogsDeWebServices *self = new DivelogsDeWebServices(MainWindow::instance());
self->setAttribute(Qt::WA_QuitOnClose, false); self->setAttribute(Qt::WA_QuitOnClose, false);
@ -617,7 +623,7 @@ void DivelogsDeWebServices::uploadDives(QIODevice *dldContent)
} }
} }
DivelogsDeWebServices::DivelogsDeWebServices(QWidget* parent, Qt::WindowFlags f) : WebServices(parent, f), uploadMode(false) DivelogsDeWebServices::DivelogsDeWebServices(QWidget *parent, Qt::WindowFlags f) : WebServices(parent, f), uploadMode(false)
{ {
QSettings s; QSettings s;
ui.userID->setText(s.value("divelogde_user").toString()); ui.userID->setText(s.value("divelogde_user").toString());
@ -633,7 +639,7 @@ void DivelogsDeWebServices::startUpload()
s.sync(); s.sync();
ui.status->setText(tr("Uploading dive list...")); ui.status->setText(tr("Uploading dive list..."));
ui.progressBar->setRange(0,0); // this makes the progressbar do an 'infinite spin' ui.progressBar->setRange(0, 0); // this makes the progressbar do an 'infinite spin'
ui.upload->setEnabled(false); ui.upload->setEnabled(false);
ui.userID->setEnabled(false); ui.userID->setEnabled(false);
ui.password->setEnabled(false); ui.password->setEnabled(false);
@ -655,8 +661,8 @@ void DivelogsDeWebServices::startUpload()
connect(reply, SIGNAL(finished()), this, SLOT(uploadFinished())); connect(reply, SIGNAL(finished()), this, SLOT(uploadFinished()));
connect(reply, SIGNAL(error(QNetworkReply::NetworkError)), this, connect(reply, SIGNAL(error(QNetworkReply::NetworkError)), this,
SLOT(uploadError(QNetworkReply::NetworkError))); SLOT(uploadError(QNetworkReply::NetworkError)));
connect(reply, SIGNAL(uploadProgress(qint64,qint64)), this, connect(reply, SIGNAL(uploadProgress(qint64, qint64)), this,
SLOT(updateProgress(qint64,qint64))); SLOT(updateProgress(qint64, qint64)));
timeout.start(30000); // 30s timeout.start(30000); // 30s
} }
@ -664,7 +670,7 @@ void DivelogsDeWebServices::startUpload()
void DivelogsDeWebServices::startDownload() void DivelogsDeWebServices::startDownload()
{ {
ui.status->setText(tr("Downloading dive list...")); ui.status->setText(tr("Downloading dive list..."));
ui.progressBar->setRange(0,0); // this makes the progressbar do an 'infinite spin' ui.progressBar->setRange(0, 0); // this makes the progressbar do an 'infinite spin'
ui.download->setEnabled(false); ui.download->setEnabled(false);
ui.userID->setEnabled(false); ui.userID->setEnabled(false);
ui.password->setEnabled(false); ui.password->setEnabled(false);
@ -674,7 +680,7 @@ void DivelogsDeWebServices::startDownload()
request.setRawHeader("Accept", "text/xml, application/xml"); request.setRawHeader("Accept", "text/xml, application/xml");
request.setHeader(QNetworkRequest::ContentTypeHeader, "application/x-www-form-urlencoded"); request.setHeader(QNetworkRequest::ContentTypeHeader, "application/x-www-form-urlencoded");
#if QT_VERSION < QT_VERSION_CHECK(5,0,0) #if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
QUrl body; QUrl body;
body.addQueryItem("user", ui.userID->text()); body.addQueryItem("user", ui.userID->text());
body.addQueryItem("pass", ui.password->text()); body.addQueryItem("pass", ui.password->text());
@ -718,7 +724,7 @@ void DivelogsDeWebServices::listDownloadFinished()
request.setRawHeader("Accept", "application/zip, */*"); request.setRawHeader("Accept", "application/zip, */*");
request.setHeader(QNetworkRequest::ContentTypeHeader, "application/x-www-form-urlencoded"); request.setHeader(QNetworkRequest::ContentTypeHeader, "application/x-www-form-urlencoded");
#if QT_VERSION < QT_VERSION_CHECK(5,0,0) #if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
QUrl body; QUrl body;
body.addQueryItem("user", ui.userID->text()); body.addQueryItem("user", ui.userID->text());
body.addQueryItem("pass", ui.password->text()); body.addQueryItem("pass", ui.password->text());
@ -788,7 +794,7 @@ void DivelogsDeWebServices::uploadFinished()
if (!reply) if (!reply)
return; return;
ui.progressBar->setRange(0,1); ui.progressBar->setRange(0, 1);
ui.upload->setEnabled(true); ui.upload->setEnabled(true);
ui.userID->setEnabled(true); ui.userID->setEnabled(true);
ui.password->setEnabled(true); ui.password->setEnabled(true);
@ -823,7 +829,6 @@ void DivelogsDeWebServices::uploadFinished()
void DivelogsDeWebServices::setStatusText(int status) void DivelogsDeWebServices::setStatusText(int status)
{ {
} }
void DivelogsDeWebServices::downloadError(QNetworkReply::NetworkError) void DivelogsDeWebServices::downloadError(QNetworkReply::NetworkError)
@ -839,7 +844,7 @@ void DivelogsDeWebServices::uploadError(QNetworkReply::NetworkError error)
downloadError(error); downloadError(error);
} }
void DivelogsDeWebServices::buttonClicked(QAbstractButton* button) void DivelogsDeWebServices::buttonClicked(QAbstractButton *button)
{ {
ui.buttonBox->button(QDialogButtonBox::Apply)->setEnabled(false); ui.buttonBox->button(QDialogButtonBox::Apply)->setEnabled(false);
switch (ui.buttonBox->buttonRole(button)) { switch (ui.buttonBox->buttonRole(button)) {
@ -869,8 +874,7 @@ void DivelogsDeWebServices::buttonClicked(QAbstractButton* button)
hide(); hide();
close(); close();
resetState(); resetState();
} } break;
break;
case QDialogButtonBox::RejectRole: case QDialogButtonBox::RejectRole:
// these two seem to be causing a crash: // these two seem to be causing a crash:
// reply->deleteLater(); // reply->deleteLater();

View file

@ -13,23 +13,25 @@ class QAbstractButton;
class QNetworkReply; class QNetworkReply;
class QHttpMultiPart; class QHttpMultiPart;
class WebServices : public QDialog{ class WebServices : public QDialog {
Q_OBJECT Q_OBJECT
public: public:
explicit WebServices(QWidget* parent = 0, Qt::WindowFlags f = 0); explicit WebServices(QWidget *parent = 0, Qt::WindowFlags f = 0);
void hidePassword(); void hidePassword();
void hideUpload(); void hideUpload();
void hideDownload(); void hideDownload();
static QNetworkAccessManager *manager(); static QNetworkAccessManager *manager();
private slots: private
slots:
virtual void startDownload() = 0; virtual void startDownload() = 0;
virtual void startUpload() = 0; virtual void startUpload() = 0;
virtual void buttonClicked(QAbstractButton* button) = 0; virtual void buttonClicked(QAbstractButton *button) = 0;
virtual void downloadTimedOut(); virtual void downloadTimedOut();
protected slots: protected
slots:
void updateProgress(qint64 current, qint64 total); void updateProgress(qint64 current, qint64 total);
protected: protected:
@ -47,30 +49,34 @@ protected:
class SubsurfaceWebServices : public WebServices { class SubsurfaceWebServices : public WebServices {
Q_OBJECT Q_OBJECT
public: public:
explicit SubsurfaceWebServices(QWidget* parent = 0, Qt::WindowFlags f = 0); explicit SubsurfaceWebServices(QWidget *parent = 0, Qt::WindowFlags f = 0);
private slots: private
slots:
void startDownload(); void startDownload();
void buttonClicked(QAbstractButton* button); void buttonClicked(QAbstractButton *button);
void downloadFinished(); void downloadFinished();
void downloadError(QNetworkReply::NetworkError error); void downloadError(QNetworkReply::NetworkError error);
void startUpload(){} /*no op*/ void startUpload()
{
} /*no op*/
private: private:
void setStatusText(int status); void setStatusText(int status);
void download_dialog_traverse_xml(xmlNodePtr node, unsigned int *download_status); void download_dialog_traverse_xml(xmlNodePtr node, unsigned int *download_status);
unsigned int download_dialog_parse_response(const QByteArray& length); unsigned int download_dialog_parse_response(const QByteArray &length);
}; };
class DivelogsDeWebServices : public WebServices { class DivelogsDeWebServices : public WebServices {
Q_OBJECT Q_OBJECT
public: public:
static DivelogsDeWebServices * instance(); static DivelogsDeWebServices *instance();
void downloadDives(); void downloadDives();
void prepareDivesForUpload(); void prepareDivesForUpload();
private slots: private
slots:
void startDownload(); void startDownload();
void buttonClicked(QAbstractButton* button); void buttonClicked(QAbstractButton *button);
void saveToZipFile(); void saveToZipFile();
void listDownloadFinished(); void listDownloadFinished();
void downloadFinished(); void downloadFinished();
@ -78,13 +84,14 @@ private slots:
void downloadError(QNetworkReply::NetworkError error); void downloadError(QNetworkReply::NetworkError error);
void uploadError(QNetworkReply::NetworkError error); void uploadError(QNetworkReply::NetworkError error);
void startUpload(); void startUpload();
private: private:
void uploadDives(QIODevice *dldContent); void uploadDives(QIODevice *dldContent);
explicit DivelogsDeWebServices (QWidget* parent = 0, Qt::WindowFlags f = 0); explicit DivelogsDeWebServices(QWidget *parent = 0, Qt::WindowFlags f = 0);
void setStatusText(int status); void setStatusText(int status);
bool prepare_dives_for_divelogs(const QString &filename, bool selected, QString *errorMsg); bool prepare_dives_for_divelogs(const QString &filename, bool selected, QString *errorMsg);
void download_dialog_traverse_xml(xmlNodePtr node, unsigned int *download_status); void download_dialog_traverse_xml(xmlNodePtr node, unsigned int *download_status);
unsigned int download_dialog_parse_response(const QByteArray& length); unsigned int download_dialog_parse_response(const QByteArray &length);
QHttpMultiPart *multipart; QHttpMultiPart *multipart;
QTemporaryFile zipFile; QTemporaryFile zipFile;

View file

@ -21,7 +21,7 @@ TableView::TableView(QWidget *parent) : QWidget(parent)
plusBtn = new QPushButton(plusIcon, QString(), ui.groupBox); plusBtn = new QPushButton(plusIcon, QString(), ui.groupBox);
plusBtn->setFlat(true); plusBtn->setFlat(true);
plusBtn->setToolTip(tr("Add Cylinder")); plusBtn->setToolTip(tr("Add Cylinder"));
plusBtn->setIconSize(QSize(16,16)); plusBtn->setIconSize(QSize(16, 16));
connect(plusBtn, SIGNAL(clicked(bool)), this, SIGNAL(addButtonClicked())); connect(plusBtn, SIGNAL(clicked(bool)), this, SIGNAL(addButtonClicked()));
} }
@ -35,12 +35,12 @@ TableView::~TableView()
s.endGroup(); s.endGroup();
} }
void TableView::setBtnToolTip(const QString& tooltip) void TableView::setBtnToolTip(const QString &tooltip)
{ {
plusBtn->setToolTip(tooltip); plusBtn->setToolTip(tooltip);
} }
void TableView::setTitle(const QString& title) void TableView::setTitle(const QString &title)
{ {
ui.groupBox->setTitle(title); ui.groupBox->setTitle(title);
} }
@ -54,7 +54,7 @@ void TableView::setModel(QAbstractItemModel *model)
s.beginGroup(objectName()); s.beginGroup(objectName());
const int columnCount = ui.tableView->model()->columnCount(); const int columnCount = ui.tableView->model()->columnCount();
for (int i = 0; i < columnCount; i++) { for (int i = 0; i < columnCount; i++) {
QVariant width = s.value(QString("colwidth%1").arg(i), i == CylindersModel::REMOVE ? 30 : 80 ); QVariant width = s.value(QString("colwidth%1").arg(i), i == CylindersModel::REMOVE ? 30 : 80);
ui.tableView->setColumnWidth(i, width.toInt()); ui.tableView->setColumnWidth(i, width.toInt());
} }
s.endGroup(); s.endGroup();
@ -65,23 +65,23 @@ void TableView::setModel(QAbstractItemModel *model)
void TableView::fixPlusPosition() void TableView::fixPlusPosition()
{ {
plusBtn->setGeometry(ui.groupBox->contentsRect().width() - 30, 2, 24,24); plusBtn->setGeometry(ui.groupBox->contentsRect().width() - 30, 2, 24, 24);
} }
// We need to manually position the 'plus' on cylinder and weight. // We need to manually position the 'plus' on cylinder and weight.
void TableView::resizeEvent(QResizeEvent* event) void TableView::resizeEvent(QResizeEvent *event)
{ {
fixPlusPosition(); fixPlusPosition();
QWidget::resizeEvent(event); QWidget::resizeEvent(event);
} }
void TableView::showEvent(QShowEvent* event) void TableView::showEvent(QShowEvent *event)
{ {
QWidget::showEvent(event); QWidget::showEvent(event);
fixPlusPosition(); fixPlusPosition();
} }
void TableView::edit(const QModelIndex& index) void TableView::edit(const QModelIndex &index)
{ {
ui.tableView->edit(index); ui.tableView->edit(index);
} }

View file

@ -15,23 +15,24 @@ class QModelIndex;
class QTableView; class QTableView;
class TableView : public QWidget { class TableView : public QWidget {
Q_OBJECT Q_OBJECT
public: public:
TableView(QWidget *parent = 0); TableView(QWidget *parent = 0);
virtual ~TableView(); virtual ~TableView();
void setTitle(const QString& title); void setTitle(const QString &title);
/* The model is expected to have a 'remove' slot, that takes a QModelIndex as parameter. /* The model is expected to have a 'remove' slot, that takes a QModelIndex as parameter.
* It's also expected to have the column '1' as a trash icon. I most probably should create a * It's also expected to have the column '1' as a trash icon. I most probably should create a
* proxy model and add that column, will mark that as TODO. see? marked. * proxy model and add that column, will mark that as TODO. see? marked.
*/ */
void setModel(QAbstractItemModel* model); void setModel(QAbstractItemModel *model);
void setBtnToolTip(const QString& tooltip); void setBtnToolTip(const QString &tooltip);
void fixPlusPosition(); void fixPlusPosition();
void edit(const QModelIndex& index); void edit(const QModelIndex &index);
QTableView *view(); QTableView *view();
protected: protected:
virtual void showEvent(QShowEvent* ); virtual void showEvent(QShowEvent *);
virtual void resizeEvent(QResizeEvent* ); virtual void resizeEvent(QResizeEvent *);
signals: signals:
void addButtonClicked(); void addButtonClicked();

View file

@ -14,18 +14,18 @@ TagWidget::TagWidget(QWidget *parent) : GroupedLineEdit(parent), m_completer(NUL
qreal h, s, l, a; qreal h, s, l, a;
textColor.getHslF(&h, &s, &l, &a); textColor.getHslF(&h, &s, &l, &a);
// I use dark themes // I use dark themes
if (l <= 0.3 ) { // very dark text. get a brigth background if (l <= 0.3) { // very dark text. get a brigth background
addColor( QColor(Qt::red).lighter(120) ); addColor(QColor(Qt::red).lighter(120));
addColor( QColor(Qt::green).lighter(120) ); addColor(QColor(Qt::green).lighter(120));
addColor( QColor(Qt::blue).lighter(120) ); addColor(QColor(Qt::blue).lighter(120));
} else if ( l <= 0.6 ) { // moderated dark text. get a somewhat brigth background } else if (l <= 0.6) { // moderated dark text. get a somewhat brigth background
addColor( QColor(Qt::red).lighter(60) ); addColor(QColor(Qt::red).lighter(60));
addColor( QColor(Qt::green).lighter(60) ); addColor(QColor(Qt::green).lighter(60));
addColor( QColor(Qt::blue).lighter(60) ); addColor(QColor(Qt::blue).lighter(60));
} else { } else {
addColor( QColor(Qt::red).darker(120) ); addColor(QColor(Qt::red).darker(120));
addColor( QColor(Qt::green).darker(120) ); addColor(QColor(Qt::green).darker(120));
addColor( QColor(Qt::blue).darker(120) ); addColor(QColor(Qt::blue).darker(120));
} // light text. get a dark background. } // light text. get a dark background.
setFocusPolicy(Qt::StrongFocus); setFocusPolicy(Qt::StrongFocus);
} }
@ -38,13 +38,14 @@ void TagWidget::setCompleter(QCompleter *completer)
connect(m_completer, SIGNAL(highlighted(QString)), this, SLOT(completionSelected(QString))); connect(m_completer, SIGNAL(highlighted(QString)), this, SLOT(completionSelected(QString)));
} }
QPair<int,int> TagWidget::getCursorTagPosition() { QPair<int, int> TagWidget::getCursorTagPosition()
{
int i = 0, start = 0, end = 0; int i = 0, start = 0, end = 0;
/* Parse string near cursor */ /* Parse string near cursor */
i = cursorPosition(); i = cursorPosition();
while (--i > 0) { while (--i > 0) {
if (text().at(i) == ',') { if (text().at(i) == ',') {
if (i > 0 && text().at(i-1) != '\\') { if (i > 0 && text().at(i - 1) != '\\') {
i++; i++;
break; break;
} }
@ -53,7 +54,7 @@ QPair<int,int> TagWidget::getCursorTagPosition() {
start = i; start = i;
while (++i < text().length()) { while (++i < text().length()) {
if (text().at(i) == ',') { if (text().at(i) == ',') {
if (i > 0 && text().at(i-1) != '\\') if (i > 0 && text().at(i - 1) != '\\')
break; break;
} }
} }
@ -62,24 +63,28 @@ QPair<int,int> TagWidget::getCursorTagPosition() {
start = 0; start = 0;
end = 0; end = 0;
} }
return qMakePair(start,end); return qMakePair(start, end);
} }
enum ParseState {FINDSTART, FINDEND}; enum ParseState {
FINDSTART,
FINDEND
};
void TagWidget::highlight() { void TagWidget::highlight()
{
int i = 0, start = 0, end = 0; int i = 0, start = 0, end = 0;
ParseState state = FINDEND; ParseState state = FINDEND;
removeAllBlocks(); removeAllBlocks();
while(i < text().length()) { while (i < text().length()) {
if (text().at(i) == ',') { if (text().at(i) == ',') {
if (state == FINDSTART) { if (state == FINDSTART) {
/* Detect empty tags */ /* Detect empty tags */
} else if (state == FINDEND) { } else if (state == FINDEND) {
/* Found end of tag */ /* Found end of tag */
if (i > 1) { if (i > 1) {
if (text().at(i-1) != '\\') { if (text().at(i - 1) != '\\') {
addBlock(start, end); addBlock(start, end);
state = FINDSTART; state = FINDSTART;
} }
@ -102,7 +107,7 @@ void TagWidget::highlight() {
} }
if (state == FINDEND) { if (state == FINDEND) {
if (end < start) if (end < start)
end = text().length()-1; end = text().length() - 1;
if (text().length() > 0) if (text().length() > 0)
addBlock(start, end); addBlock(start, end);
} }
@ -111,10 +116,10 @@ void TagWidget::highlight() {
void TagWidget::reparse() void TagWidget::reparse()
{ {
highlight(); highlight();
QPair<int,int> pos = getCursorTagPosition(); QPair<int, int> pos = getCursorTagPosition();
QString currentText; QString currentText;
if (pos.first >= 0 && pos.second > 0) if (pos.first >= 0 && pos.second > 0)
currentText = text().mid(pos.first, pos.second-pos.first).trimmed(); currentText = text().mid(pos.first, pos.second - pos.first).trimmed();
else else
currentText = ""; currentText = "";
if (m_completer) { if (m_completer) {
@ -133,12 +138,13 @@ void TagWidget::reparse()
} }
} }
void TagWidget::completionSelected(QString completion) { void TagWidget::completionSelected(QString completion)
QPair <int,int> pos; {
QPair<int, int> pos;
pos = getCursorTagPosition(); pos = getCursorTagPosition();
if (pos.first >= 0 && pos.second > 0) { if (pos.first >= 0 && pos.second > 0) {
setText(text().remove(pos.first, pos.second-pos.first).insert(pos.first, completion)); setText(text().remove(pos.first, pos.second - pos.first).insert(pos.first, completion));
setCursorPosition(pos.first+completion.length()); setCursorPosition(pos.first + completion.length());
} else { } else {
setText(completion.append(", ")); setText(completion.append(", "));
setCursorPosition(text().length()); setCursorPosition(text().length());
@ -146,26 +152,30 @@ void TagWidget::completionSelected(QString completion) {
emit(textChanged()); emit(textChanged());
} }
void TagWidget::setCursorPosition(int position) { void TagWidget::setCursorPosition(int position)
{
blockSignals(true); blockSignals(true);
GroupedLineEdit::setCursorPosition(position); GroupedLineEdit::setCursorPosition(position);
blockSignals(false); blockSignals(false);
} }
void TagWidget::setText(QString text) { void TagWidget::setText(QString text)
{
blockSignals(true); blockSignals(true);
GroupedLineEdit::setText(text); GroupedLineEdit::setText(text);
blockSignals(false); blockSignals(false);
highlight(); highlight();
} }
void TagWidget::clear() { void TagWidget::clear()
{
blockSignals(true); blockSignals(true);
GroupedLineEdit::clear(); GroupedLineEdit::clear();
blockSignals(false); blockSignals(false);
} }
void TagWidget::keyPressEvent(QKeyEvent *e) { void TagWidget::keyPressEvent(QKeyEvent *e)
{
switch (e->key()) { switch (e->key()) {
case Qt::Key_Return: case Qt::Key_Return:
case Qt::Key_Enter: case Qt::Key_Enter:
@ -188,7 +198,8 @@ void TagWidget::keyPressEvent(QKeyEvent *e) {
} }
} }
void TagWidget::wheelEvent(QWheelEvent *event) { void TagWidget::wheelEvent(QWheelEvent *event)
{
if (hasFocus()) { if (hasFocus()) {
GroupedLineEdit::wheelEvent(event); GroupedLineEdit::wheelEvent(event);
} }

View file

@ -5,11 +5,10 @@
#include <QCompleter> #include <QCompleter>
#include <QPair> #include <QPair>
class TagWidget : public GroupedLineEdit class TagWidget : public GroupedLineEdit {
{ Q_OBJECT
Q_OBJECT
public: public:
explicit TagWidget(QWidget *parent = 0); explicit TagWidget(QWidget *parent = 0);
void setCompleter(QCompleter *completer); void setCompleter(QCompleter *completer);
QPair<int, int> getCursorTagPosition(); QPair<int, int> getCursorTagPosition();
void highlight(); void highlight();
@ -17,11 +16,14 @@ public:
void clear(); void clear();
void setCursorPosition(int position); void setCursorPosition(int position);
void wheelEvent(QWheelEvent *event); void wheelEvent(QWheelEvent *event);
public slots: public
slots:
void reparse(); void reparse();
void completionSelected(QString); void completionSelected(QString);
protected: protected:
void keyPressEvent(QKeyEvent *e); void keyPressEvent(QKeyEvent *e);
private: private:
QCompleter *m_completer; QCompleter *m_completer;
}; };

View file

@ -5,8 +5,7 @@
#include "../helpers.h" #include "../helpers.h"
UserManual::UserManual(QWidget *parent) : UserManual::UserManual(QWidget *parent) : QMainWindow(parent),
QMainWindow(parent),
ui(new Ui::UserManual) ui(new Ui::UserManual)
{ {
ui->setupUi(this); ui->setupUi(this);
@ -56,14 +55,15 @@ void UserManual::hideSearchPanel()
void UserManual::search(QString text, QWebPage::FindFlags flags = 0) void UserManual::search(QString text, QWebPage::FindFlags flags = 0)
{ {
if (ui->webView->findText(text, QWebPage::FindWrapsAroundDocument|flags) || text.length() == 0) { if (ui->webView->findText(text, QWebPage::FindWrapsAroundDocument | flags) || text.length() == 0) {
ui->searchEdit->setStyleSheet(""); ui->searchEdit->setStyleSheet("");
} else { } else {
ui->searchEdit->setStyleSheet("QLineEdit{background: red;}"); ui->searchEdit->setStyleSheet("QLineEdit{background: red;}");
} }
} }
void UserManual::searchTextChanged(QString text) { void UserManual::searchTextChanged(QString text)
{
bool hasText = text.length() > 0; bool hasText = text.length() > 0;
ui->findPrev->setEnabled(hasText); ui->findPrev->setEnabled(hasText);

Some files were not shown because too many files have changed in this diff Show more