2013-04-14 11:31:26 -07:00
|
|
|
/* info.c
|
2012-08-26 14:41:05 -07:00
|
|
|
*
|
2013-04-14 11:31:26 -07:00
|
|
|
* UI toolkit independent logic used for the info frame
|
2011-09-20 12:40:34 -07:00
|
|
|
*
|
2013-10-05 00:29:09 -07:00
|
|
|
* bool gps_changed(struct dive *dive, struct dive *master, const char *gps_text);
|
2013-04-14 11:31:26 -07:00
|
|
|
* void print_gps_coordinates(char *buffer, int len, int lat, int lon);
|
|
|
|
* void save_equipment_data(struct dive *dive);
|
|
|
|
* void update_equipment_data(struct dive *dive, struct dive *master);
|
|
|
|
* void update_time_depth(struct dive *dive, struct dive *edited);
|
|
|
|
* const char *get_window_title(struct dive *dive);
|
|
|
|
* char *evaluate_string_change(const char *newstring, char **textp, const char *master);
|
|
|
|
* int text_changed(const char *old, const char *new);
|
2013-10-05 00:29:09 -07:00
|
|
|
* bool parse_gps_text(const char *gps_text, double *latitude, double *longitude);
|
2013-04-14 11:31:26 -07:00
|
|
|
* int divename(char *buf, size_t size, struct dive *dive, char *trailer);
|
2011-09-20 12:40:34 -07:00
|
|
|
*/
|
2011-08-31 12:09:19 -07:00
|
|
|
#include <stdio.h>
|
2011-09-02 20:00:10 -07:00
|
|
|
#include <string.h>
|
2011-08-31 12:09:19 -07:00
|
|
|
#include <stdlib.h>
|
|
|
|
#include <time.h>
|
2011-11-02 22:11:31 -07:00
|
|
|
#include <ctype.h>
|
2012-06-27 18:56:41 -07:00
|
|
|
#include <sys/time.h>
|
2013-10-06 08:55:58 -07:00
|
|
|
#include "gettext.h"
|
2011-08-31 12:09:19 -07:00
|
|
|
#include "dive.h"
|
|
|
|
#include "display.h"
|
2011-09-05 21:12:58 +02:00
|
|
|
#include "divelist.h"
|
2011-08-31 12:09:19 -07:00
|
|
|
|
2013-02-08 19:27:54 -08:00
|
|
|
/* take latitude and longitude in udeg and print them in a human readable
|
|
|
|
* form, without losing precision */
|
2013-04-14 11:31:26 -07:00
|
|
|
void print_gps_coordinates(char *buffer, int len, int lat, int lon)
|
2013-01-28 07:54:30 -08:00
|
|
|
{
|
|
|
|
unsigned int latdeg, londeg;
|
2013-10-06 08:55:58 -07:00
|
|
|
const char *lath, *lonh;
|
|
|
|
char dbuf_lat[32], dbuf_lon[32];
|
2013-01-28 07:54:30 -08:00
|
|
|
|
2013-02-03 19:03:36 +11:00
|
|
|
if (!lat && !lon) {
|
|
|
|
*buffer = 0;
|
|
|
|
return;
|
|
|
|
}
|
2013-10-06 08:55:58 -07:00
|
|
|
lath = lat >= 0 ? tr("N") : tr("S");
|
|
|
|
lonh = lon >= 0 ? tr("E") : tr("W");
|
2013-02-08 19:27:54 -08:00
|
|
|
lat = abs(lat);
|
|
|
|
lon = abs(lon);
|
|
|
|
latdeg = lat / 1000000;
|
|
|
|
londeg = lon / 1000000;
|
2013-10-05 00:29:09 -07:00
|
|
|
int ilatmin = (lat % 1000000) * 60;
|
|
|
|
int ilonmin = (lon % 1000000) * 60;
|
|
|
|
snprintf(dbuf_lat, sizeof(dbuf_lat), "%2d.%05d", ilatmin / 1000000, (ilatmin % 1000000) / 10);
|
|
|
|
snprintf(dbuf_lon, sizeof(dbuf_lon), "%2d.%05d", ilonmin / 1000000, (ilonmin % 1000000) / 10);
|
2013-03-10 15:36:00 +02:00
|
|
|
if (!*dbuf_lat || !*dbuf_lon) {
|
|
|
|
*buffer = 0;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
snprintf(buffer, len, "%s%u%s %s\' , %s%u%s %s\'",
|
|
|
|
lath, latdeg, UTF8_DEGREE, dbuf_lat,
|
|
|
|
lonh, londeg, UTF8_DEGREE, dbuf_lon);
|
2013-01-28 07:54:30 -08:00
|
|
|
}
|
|
|
|
|
2012-08-15 15:21:34 -07:00
|
|
|
/* we use these to find out if we edited the cylinder or weightsystem entries */
|
|
|
|
static cylinder_t remember_cyl[MAX_CYLINDERS];
|
|
|
|
static weightsystem_t remember_ws[MAX_WEIGHTSYSTEMS];
|
2012-08-18 08:28:52 -07:00
|
|
|
#define CYL_BYTES sizeof(cylinder_t) * MAX_CYLINDERS
|
|
|
|
#define WS_BYTES sizeof(weightsystem_t) * MAX_WEIGHTSYSTEMS
|
2012-08-15 15:21:34 -07:00
|
|
|
|
2013-04-14 11:31:26 -07:00
|
|
|
void save_equipment_data(struct dive *dive)
|
2011-11-19 10:11:56 -05:00
|
|
|
{
|
2012-08-15 15:21:34 -07:00
|
|
|
if (dive) {
|
2012-08-18 08:28:52 -07:00
|
|
|
memcpy(remember_cyl, dive->cylinder, CYL_BYTES);
|
|
|
|
memcpy(remember_ws, dive->weightsystem, WS_BYTES);
|
2012-08-15 15:21:34 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-09-24 12:03:58 -07:00
|
|
|
/* Empty and NULL compare equal */
|
|
|
|
static int same_string(const char *a, const char *b)
|
|
|
|
{
|
|
|
|
/* Both NULL or same */
|
|
|
|
if (a == b)
|
|
|
|
return 1;
|
|
|
|
/* Both non-NULL: strcmp */
|
|
|
|
if (a && b)
|
|
|
|
return !strcmp(a, b);
|
|
|
|
/* One non-NULL? Is that one empty? */
|
|
|
|
return !*(a ? a : b);
|
|
|
|
}
|
|
|
|
|
|
|
|
static int same_type(cylinder_t *dst, cylinder_t *src)
|
|
|
|
{
|
|
|
|
return dst->type.size.mliter == src->type.size.mliter &&
|
|
|
|
dst->type.workingpressure.mbar == src->type.workingpressure.mbar &&
|
|
|
|
same_string(dst->type.description, src->type.description);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void copy_type(cylinder_t *dst, cylinder_t *src)
|
|
|
|
{
|
|
|
|
dst->type.size = src->type.size;
|
|
|
|
dst->type.workingpressure = src->type.workingpressure;
|
|
|
|
if (dst->type.description)
|
|
|
|
free((void *)dst->type.description);
|
|
|
|
if (!src->type.description || !*src->type.description)
|
|
|
|
dst->type.description = NULL;
|
|
|
|
else
|
|
|
|
dst->type.description = strdup((char *)src->type.description);
|
|
|
|
}
|
|
|
|
|
|
|
|
static int same_gasmix(cylinder_t *dst, cylinder_t *src)
|
|
|
|
{
|
|
|
|
return !memcmp(&dst->gasmix, &src->gasmix, sizeof(dst->gasmix));
|
|
|
|
}
|
|
|
|
|
|
|
|
static void copy_gasmix(cylinder_t *dst, cylinder_t *src)
|
|
|
|
{
|
|
|
|
memcpy(&dst->gasmix, &src->gasmix, sizeof(dst->gasmix));
|
|
|
|
}
|
|
|
|
|
|
|
|
static int same_press(cylinder_t *dst, cylinder_t *src)
|
|
|
|
{
|
|
|
|
return dst->start.mbar == src->start.mbar &&
|
|
|
|
dst->end.mbar == src->end.mbar;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void copy_press(cylinder_t *dst, cylinder_t *src)
|
|
|
|
{
|
|
|
|
dst->start = src->start;
|
|
|
|
dst->end = src->end;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* When we update the cylinder information, we do it individually
|
|
|
|
* by type/gasmix/pressure, so that you can change them separately.
|
|
|
|
*
|
|
|
|
* The rule is: the destination has to be the same as the original
|
|
|
|
* field, and the source has to have changed. If so, we change the
|
|
|
|
* destination field.
|
|
|
|
*/
|
|
|
|
static void update_cylinder(cylinder_t *dst, cylinder_t *src, cylinder_t *orig)
|
|
|
|
{
|
|
|
|
/* Destination type same? Change it */
|
|
|
|
if (same_type(dst, orig) && !same_type(src, orig))
|
|
|
|
copy_type(dst, src);
|
|
|
|
|
|
|
|
/* Destination gasmix same? Change it */
|
|
|
|
if (same_gasmix(dst, orig) && !same_gasmix(src, orig))
|
|
|
|
copy_gasmix(dst, src);
|
|
|
|
|
|
|
|
/* Destination pressures the same? */
|
|
|
|
if (same_press(dst, orig) && !same_press(src, orig))
|
|
|
|
copy_press(dst, src);
|
|
|
|
}
|
|
|
|
|
2012-08-18 08:28:52 -07:00
|
|
|
/* the editing happens on the master dive; we copy the equipment
|
|
|
|
data if it has changed in the master dive and the other dive
|
|
|
|
either has no entries for the equipment or the same entries
|
|
|
|
as the master dive had before it was edited */
|
2013-04-14 11:31:26 -07:00
|
|
|
void update_equipment_data(struct dive *dive, struct dive *master)
|
2012-08-15 15:21:34 -07:00
|
|
|
{
|
2012-09-24 12:03:58 -07:00
|
|
|
int i;
|
|
|
|
|
2012-08-15 15:21:34 -07:00
|
|
|
if (dive == master)
|
|
|
|
return;
|
2012-09-24 12:03:58 -07:00
|
|
|
for (i = 0; i < MAX_CYLINDERS; i++)
|
|
|
|
update_cylinder(dive->cylinder+i, master->cylinder+i, remember_cyl+i);
|
2012-08-18 08:28:52 -07:00
|
|
|
if (! weightsystems_equal(remember_ws, master->weightsystem) &&
|
|
|
|
(no_weightsystems(dive->weightsystem) ||
|
|
|
|
weightsystems_equal(dive->weightsystem, remember_ws)))
|
|
|
|
memcpy(dive->weightsystem, master->weightsystem, WS_BYTES);
|
2012-08-15 15:21:34 -07:00
|
|
|
}
|
|
|
|
|
2013-02-28 14:58:12 -08:00
|
|
|
/* we can simply overwrite these - this only gets called if we edited
|
|
|
|
* a single dive and the dive was first copied into edited - so we can
|
|
|
|
* just take those values */
|
2013-04-14 11:31:26 -07:00
|
|
|
void update_time_depth(struct dive *dive, struct dive *edited)
|
2013-02-28 14:58:12 -08:00
|
|
|
{
|
|
|
|
dive->when = edited->when;
|
|
|
|
dive->dc.duration.seconds = edited->dc.duration.seconds;
|
|
|
|
dive->dc.maxdepth.mm = edited->dc.maxdepth.mm;
|
|
|
|
dive->dc.meandepth.mm = edited->dc.meandepth.mm;
|
|
|
|
}
|
|
|
|
|
2013-05-03 11:04:51 -07:00
|
|
|
void add_people(const char *string)
|
2012-08-15 15:21:34 -07:00
|
|
|
{
|
2013-05-03 11:04:51 -07:00
|
|
|
/* add names to the completion list for people */
|
|
|
|
}
|
|
|
|
void add_location(const char *string)
|
|
|
|
{
|
|
|
|
/* add names to the completion list for locations */
|
|
|
|
}
|
|
|
|
void add_suit(const char *string)
|
|
|
|
{
|
|
|
|
/* add names to the completion list for suits */
|
2012-08-15 15:21:34 -07:00
|
|
|
}
|