Correct multi-edit equipment update logic

I lied in the commit message for commit 0468535524a3 ("When editing multiple
files, don't override existing equipment entries"); the changes there did
not parallel the logic for the string entries. Now I think it does.

Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
This commit is contained in:
Dirk Hohndel 2012-08-18 08:28:52 -07:00
parent 5487606fda
commit c26c370c2b
3 changed files with 89 additions and 13 deletions

7
dive.h
View file

@ -92,8 +92,11 @@ typedef struct {
const char *description; /* "integrated", "belt", "ankle" */
} weightsystem_t;
extern int cylinder_none(void *_data);
extern int weightsystem_none(void *_data);
extern gboolean cylinder_none(void *_data);
extern gboolean no_cylinders(cylinder_t *cyl);
extern gboolean cylinders_equal(cylinder_t *cyl1, cylinder_t *cyl2);
extern gboolean no_weightsystems(weightsystem_t *ws);
extern gboolean weightsystems_equal(weightsystem_t *ws1, weightsystem_t *ws2);
extern int get_pressure_units(unsigned int mb, const char **units);
extern double get_depth_units(unsigned int mm, int *frac, const char **units);

View file

@ -428,7 +428,7 @@ static void show_weightsystem(weightsystem_t *ws, struct ws_widget *weightsystem
set_weight_weight_spinbutton(weightsystem_widget, ws->weight.grams);
}
int cylinder_none(void *_data)
gboolean cylinder_none(void *_data)
{
cylinder_t *cyl = _data;
return !cyl->type.size.mliter &&
@ -442,12 +442,77 @@ int cylinder_none(void *_data)
!cyl->end.mbar;
}
int weightsystem_none(void *_data)
gboolean no_cylinders(cylinder_t *cyl)
{
int i;
for (i = 0; i < MAX_CYLINDERS; i++)
if (!cylinder_none(cyl + i))
return FALSE;
return TRUE;
}
/* descriptions are equal if they are both NULL or both non-NULL
and the same text */
gboolean description_equal(const char *desc1, const char *desc2)
{
return ((! desc1 && ! desc2) ||
(desc1 && desc2 && strcmp(desc1, desc2) == 0));
}
/* when checking for the same cylinder we want the size and description to match
but don't compare the start and end pressures */
static gboolean one_cylinder_equal(cylinder_t *cyl1, cylinder_t *cyl2)
{
return cyl1->type.size.mliter == cyl2->type.size.mliter &&
cyl1->type.workingpressure.mbar == cyl2->type.workingpressure.mbar &&
cyl1->gasmix.o2.permille == cyl2->gasmix.o2.permille &&
cyl1->gasmix.he.permille == cyl2->gasmix.he.permille &&
description_equal(cyl1->type.description, cyl2->type.description);
}
gboolean cylinders_equal(cylinder_t *cyl1, cylinder_t *cyl2)
{
int i;
for (i = 0; i < MAX_CYLINDERS; i++)
if (!one_cylinder_equal(cyl1 + i, cyl2 + i))
return FALSE;
return TRUE;
}
static gboolean weightsystem_none(void *_data)
{
weightsystem_t *ws = _data;
return !ws->weight.grams && !ws->description;
}
gboolean no_weightsystems(weightsystem_t *ws)
{
int i;
for (i = 0; i < MAX_WEIGHTSYSTEMS; i++)
if (!weightsystem_none(ws + i))
return FALSE;
return TRUE;
}
static gboolean one_weightsystem_equal(weightsystem_t *ws1, weightsystem_t *ws2)
{
return ws1->weight.grams == ws2->weight.grams &&
description_equal(ws1->description, ws2->description);
}
gboolean weightsystems_equal(weightsystem_t *ws1, weightsystem_t *ws2)
{
int i;
for (i = 0; i < MAX_WEIGHTSYSTEMS; i++)
if (!one_weightsystem_equal(ws1 + i, ws2 + i))
return FALSE;
return TRUE;
}
static void set_one_cylinder(void *_data, GtkListStore *model, GtkTreeIter *iter)
{
cylinder_t *cyl = _data;
@ -493,7 +558,7 @@ static void *ws_ptr(struct dive *dive, int idx)
static void show_equipment(struct dive *dive, int max,
struct equipment_list *equipment_list,
void*(*ptr_function)(struct dive*, int),
int(*none_function)(void *),
gboolean(*none_function)(void *),
void(*set_one_function)(void*, GtkListStore*, GtkTreeIter *))
{
int i, used;

24
info.c
View file

@ -460,25 +460,33 @@ static void dive_info_widget(GtkWidget *box, struct dive *dive, struct dive_info
/* 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];
#define CYL_BYTES sizeof(cylinder_t) * MAX_CYLINDERS
#define WS_BYTES sizeof(weightsystem_t) * MAX_WEIGHTSYSTEMS
void save_equipment_data(struct dive *dive)
{
if (dive) {
memcpy(remember_cyl, dive->cylinder, sizeof(cylinder_t) * MAX_CYLINDERS);
memcpy(remember_ws, dive->weightsystem, sizeof(weightsystem_t) * MAX_WEIGHTSYSTEMS);
memcpy(remember_cyl, dive->cylinder, CYL_BYTES);
memcpy(remember_ws, dive->weightsystem, WS_BYTES);
}
}
/* 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 */
void update_equipment_data(struct dive *dive, struct dive *master)
{
if (dive == master)
return;
if (memcmp(remember_cyl, master->cylinder, sizeof(cylinder_t) * MAX_CYLINDERS) &&
cylinder_none(dive->cylinder))
memcpy(dive->cylinder, master->cylinder, sizeof(cylinder_t) * MAX_CYLINDERS);
if (memcmp(remember_ws, master->weightsystem, sizeof(weightsystem_t) * MAX_WEIGHTSYSTEMS) &&
weightsystem_none(dive->weightsystem))
memcpy(dive->weightsystem, master->weightsystem, sizeof(weightsystem_t) * MAX_WEIGHTSYSTEMS);
if ( ! cylinders_equal(remember_cyl, master->cylinder) &&
(no_cylinders(dive->cylinder) ||
cylinders_equal(dive->cylinder, remember_cyl)))
memcpy(dive->cylinder, master->cylinder, CYL_BYTES);
if (! weightsystems_equal(remember_ws, master->weightsystem) &&
(no_weightsystems(dive->weightsystem) ||
weightsystems_equal(dive->weightsystem, remember_ws)))
memcpy(dive->weightsystem, master->weightsystem, WS_BYTES);
}
int edit_multi_dive_info(int nr, int *indices)