From: Linus Torvalds Date: Mon, 27 Aug 2012 22:36:27 +0000 (-0700) Subject: Merge branch 'trips' of git://git.hohndel.org/subsurface X-Git-Url: http://git.tdb.fi/?p=ext%2Fsubsurface.git;a=commitdiff_plain;h=c89f88378a0a19d6b7e0771b6fd8dc31acfaf2f7;hp=9cf961249e197d6d8a3656968ce15dfd19e3ef3b Merge branch 'trips' of git://git.hohndel.org/subsurface Merge the initial 'track trips explicitly' code from Dirk Hohndel. Fix up trivial conflicts in save-xml.c due to the new 'is_attribute' flag. * 'trips' of git://git.hohndel.org/subsurface: Fix an issue with trips that have dives from multiple input files Some simple test dives for the trips code First cut of explicit trip tracking --- diff --git a/display-gtk.h b/display-gtk.h index dd7e2c4..85ebae3 100644 --- a/display-gtk.h +++ b/display-gtk.h @@ -19,6 +19,7 @@ typedef struct { gboolean nitrox; gboolean sac; gboolean otu; + gboolean print_profiles; } visible_cols_t; typedef enum { diff --git a/dive.h b/dive.h index a715ea2..dffe753 100644 --- a/dive.h +++ b/dive.h @@ -95,6 +95,7 @@ typedef struct { extern gboolean cylinder_none(void *_data); extern gboolean no_cylinders(cylinder_t *cyl); extern gboolean cylinders_equal(cylinder_t *cyl1, cylinder_t *cyl2); +extern void copy_cylinders(cylinder_t *cyl1, cylinder_t *cyl2); extern gboolean no_weightsystems(weightsystem_t *ws); extern gboolean weightsystems_equal(weightsystem_t *ws1, weightsystem_t *ws2); @@ -351,6 +352,16 @@ static inline struct dive *get_dive(unsigned int nr) return dive_table.dives[nr]; } +/* + * Iterate over each dive, with the first parameter being the index + * iterator variable, and the second one being the dive one. + * + * 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. + */ +#define for_each_dive(_i,_x) \ + for ((_i) = 0; ((_x) = get_dive(_i)) != NULL; (_i)++) + extern void parse_xml_init(void); extern void parse_xml_buffer(const char *url, const char *buf, int size, GError **error); extern void set_filename(const char *filename); @@ -411,7 +422,7 @@ extern void evn_foreach(void (*callback)(const char *, int *, void *), void *dat extern int add_new_dive(struct dive *dive); extern int edit_dive_info(struct dive *dive); -extern int edit_multi_dive_info(int idx); +extern int edit_multi_dive_info(struct dive *single_dive); extern void dive_list_update_dives(void); extern void flush_divelist(struct dive *dive); diff --git a/divelist.c b/divelist.c index 83161b8..a773b60 100644 --- a/divelist.c +++ b/divelist.c @@ -92,7 +92,7 @@ void dump_selection(void) struct dive *dive; printf("currently selected are %d dives:", amount_selected); - for (i = 0; (dive = get_dive(i)) != NULL; i++) { + for_each_dive(i, dive) { if (dive->selected) printf(" %d", i); } @@ -1139,7 +1139,7 @@ void add_dive_cb(GtkWidget *menuitem, gpointer data) void edit_dive_cb(GtkWidget *menuitem, gpointer data) { - edit_multi_dive_info(-1); + edit_multi_dive_info(NULL); } static void expand_all_cb(GtkWidget *menuitem, GtkTreeView *tree_view) diff --git a/equipment.c b/equipment.c index 43bb29d..d676fc0 100644 --- a/equipment.c +++ b/equipment.c @@ -461,13 +461,11 @@ gboolean description_equal(const char *desc1, const char *desc2) } /* when checking for the same cylinder we want the size and description to match - but don't compare the start and end pressures */ + but don't compare the start and end pressures, nor the Nitrox/He values */ 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); } @@ -481,6 +479,21 @@ gboolean cylinders_equal(cylinder_t *cyl1, cylinder_t *cyl2) return TRUE; } +/* copy size and description of all cylinders from cyl1 to cyl2 */ +void copy_cylinders(cylinder_t *cyl1, cylinder_t *cyl2) +{ + int i; + + for (i = 0; i < MAX_CYLINDERS; i++) { + cyl2[i].type.size.mliter = cyl1[i].type.size.mliter; + cyl2[i].type.workingpressure.mbar = cyl1[i].type.workingpressure.mbar; + if (cyl1[i].type.description) + cyl2[i].type.description = strdup(cyl1[i].type.description); + else + cyl2[i].type.description = NULL; + } +} + static gboolean weightsystem_none(void *_data) { weightsystem_t *ws = _data; diff --git a/file.c b/file.c index e016390..da49899 100644 --- a/file.c +++ b/file.c @@ -8,6 +8,11 @@ #include "dive.h" #include "file.h" +/* Crazy windows sh*t */ +#ifndef O_BINARY +#define O_BINARY 0 +#endif + static int readfile(const char *filename, struct memblock *mem) { int ret, fd; @@ -17,7 +22,7 @@ static int readfile(const char *filename, struct memblock *mem) mem->buffer = NULL; mem->size = 0; - fd = open(filename, O_RDONLY); + fd = open(filename, O_RDONLY | O_BINARY); if (fd < 0) return fd; ret = fstat(fd, &st); diff --git a/gtk-gui.c b/gtk-gui.c index f9cc8e6..bc8e6e0 100644 --- a/gtk-gui.c +++ b/gtk-gui.c @@ -98,7 +98,7 @@ void report_error(GError* error) { return; } - + if (error_info_bar == NULL) { error_count = 1; @@ -108,11 +108,11 @@ void report_error(GError* error) g_signal_connect(error_info_bar, "response", G_CALLBACK(on_info_bar_response), NULL); gtk_info_bar_set_message_type(GTK_INFO_BAR(error_info_bar), GTK_MESSAGE_ERROR); - + error_label = gtk_label_new(error->message); GtkWidget *container = gtk_info_bar_get_content_area(GTK_INFO_BAR(error_info_bar)); gtk_container_add(GTK_CONTAINER(container), error_label); - + gtk_box_pack_start(GTK_BOX(main_vbox), error_info_bar, FALSE, FALSE, 0); gtk_widget_show_all(main_vbox); } @@ -151,7 +151,7 @@ static void file_open(GtkWidget *w, gpointer data) GSList *filenames, *fn_glist; char *filename; filenames = fn_glist = gtk_file_chooser_get_filenames(GTK_FILE_CHOOSER(dialog)); - + GError *error = NULL; while(filenames != NULL) { filename = filenames->data; @@ -162,7 +162,7 @@ static void file_open(GtkWidget *w, gpointer data) g_error_free(error); error = NULL; } - + g_free(filename); filenames = g_slist_next(filenames); } @@ -172,10 +172,43 @@ static void file_open(GtkWidget *w, gpointer data) gtk_widget_destroy(dialog); } +/* return the path and the file component contained in the full path */ +static char *path_and_file(char *pathin, char **fileout) { + char *slash = pathin, *next; + char *result; + size_t len, n; + + if (! pathin) { + *fileout = strdup(""); + return strdup(""); + } + while ((next = strpbrk(slash + 1, "\\/"))) + slash = next; + if (pathin != slash) + slash++; + *fileout = strdup(slash); + + /* strndup(pathin, slash - pathin) */ + n = slash - pathin; + len = strlen(pathin); + if (n < len) + len = n; + + result = (char *)malloc(len + 1); + if (!result) + return 0; + + result[len] = '\0'; + return (char *)memcpy(result, pathin, len); +} + static void file_save_as(GtkWidget *w, gpointer data) { GtkWidget *dialog; char *filename = NULL; + char *current_file; + char *current_dir; + dialog = gtk_file_chooser_dialog_new("Save File As", GTK_WINDOW(main_window), GTK_FILE_CHOOSER_ACTION_SAVE, @@ -184,7 +217,13 @@ static void file_save_as(GtkWidget *w, gpointer data) NULL); gtk_file_chooser_set_do_overwrite_confirmation(GTK_FILE_CHOOSER(dialog), TRUE); - gtk_file_chooser_set_current_name(GTK_FILE_CHOOSER(dialog), existing_filename); + current_dir = path_and_file(existing_filename, ¤t_file); + gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(dialog), current_dir); + gtk_file_chooser_set_current_name(GTK_FILE_CHOOSER(dialog), current_file); + + free(current_dir); + free(current_file); + if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) { filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog)); } diff --git a/info.c b/info.c index 468f357..cccc649 100644 --- a/info.c +++ b/info.c @@ -1,7 +1,7 @@ /* info.c */ -/* creates the UI for the info frame - +/* creates the UI for the info frame - * controlled through the following interfaces: - * + * * void show_dive_info(struct dive *dive) * * called from gtk-ui: @@ -166,7 +166,7 @@ static int delete_dive_info(struct dive *dive) static void info_menu_edit_cb(GtkMenuItem *menuitem, gpointer user_data) { - edit_multi_dive_info(-1); + edit_multi_dive_info(NULL); } static void info_menu_delete_cb(GtkMenuItem *menuitem, gpointer user_data) @@ -482,7 +482,7 @@ void update_equipment_data(struct dive *dive, struct dive *master) if ( ! cylinders_equal(remember_cyl, master->cylinder) && (no_cylinders(dive->cylinder) || cylinders_equal(dive->cylinder, remember_cyl))) - memcpy(dive->cylinder, master->cylinder, CYL_BYTES); + copy_cylinders(master->cylinder, dive->cylinder); if (! weightsystems_equal(remember_ws, master->weightsystem) && (no_weightsystems(dive->weightsystem) || weightsystems_equal(dive->weightsystem, remember_ws))) @@ -490,7 +490,7 @@ void update_equipment_data(struct dive *dive, struct dive *master) } /* A negative index means "all selected" */ -int edit_multi_dive_info(int index) +int edit_multi_dive_info(struct dive *single_dive) { int success; GtkWidget *dialog, *vbox; @@ -505,21 +505,21 @@ int edit_multi_dive_info(int index) NULL); vbox = gtk_dialog_get_content_area(GTK_DIALOG(dialog)); - master = get_dive(index); + master = single_dive; if (!master) master = current_dive; - dive_info_widget(vbox, master, &info, index < 0); + dive_info_widget(vbox, master, &info, !single_dive); show_dive_equipment(master, W_IDX_SECONDARY); save_equipment_data(master); gtk_widget_show_all(dialog); success = gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT; if (success) { /* Update the non-current selected dives first */ - if (index < 0) { + if (!single_dive) { int i; struct dive *dive; - for (i = 0; (dive = get_dive(i)) != NULL; i++) { + for_each_dive(i, dive) { if (dive == master || !dive->selected) continue; /* copy all "info" fields */ @@ -544,12 +544,9 @@ int edit_multi_dive_info(int index) int edit_dive_info(struct dive *dive) { - int idx; - if (!dive) return 0; - idx = dive->number; - return edit_multi_dive_info(idx); + return edit_multi_dive_info(dive); } static GtkWidget *frame_box(GtkWidget *vbox, const char *fmt, ...) diff --git a/libdivecomputer.c b/libdivecomputer.c index e362d1d..d96d276 100644 --- a/libdivecomputer.c +++ b/libdivecomputer.c @@ -305,13 +305,6 @@ static dc_status_t import_device_data(dc_device_t *device, device_data_t *device return dc_device_foreach(device, dive_cb, devicedata); } -static dc_status_t device_open(const char *devname, - dc_descriptor_t *descriptor, - dc_device_t **device) -{ - return dc_device_open(device, descriptor, devname); -} - static void event_cb(dc_device_t *device, dc_event_type_t event, const void *data, void *userdata) { @@ -351,42 +344,53 @@ cancel_cb(void *userdata) return import_thread_cancelled; } -static const char *do_libdivecomputer_import(device_data_t *data) +static const char *do_device_import(device_data_t *data) { - dc_device_t *device = NULL; dc_status_t rc; - - import_dive_number = 0; - rc = device_open(data->devname, data->descriptor, &device); - if (rc != DC_STATUS_SUCCESS) - return "Unable to open %s %s (%s)"; - data->device = device; + dc_device_t *device = data->device; // Register the event handler. int events = DC_EVENT_WAITING | DC_EVENT_PROGRESS | DC_EVENT_DEVINFO | DC_EVENT_CLOCK; rc = dc_device_set_events(device, events, event_cb, data); - if (rc != DC_STATUS_SUCCESS) { - dc_device_close(device); + if (rc != DC_STATUS_SUCCESS) return "Error registering the event handler."; - } // Register the cancellation handler. rc = dc_device_set_cancel(device, cancel_cb, data); - if (rc != DC_STATUS_SUCCESS) { - dc_device_close(device); + if (rc != DC_STATUS_SUCCESS) return "Error registering the cancellation handler."; - } rc = import_device_data(device, data); - if (rc != DC_STATUS_SUCCESS) { - dc_device_close(device); + if (rc != DC_STATUS_SUCCESS) return "Dive data import error"; - } - dc_device_close(device); + /* All good */ return NULL; } +static const char *do_libdivecomputer_import(device_data_t *data) +{ + dc_status_t rc; + const char *err; + + import_dive_number = 0; + data->device = NULL; + data->context = NULL; + + rc = dc_context_new(&data->context); + if (rc != DC_STATUS_SUCCESS) + return "Unable to create libdivecomputer context"; + + err = "Unable to open %s %s (%s)"; + rc = dc_device_open(&data->device, data->context, data->descriptor, data->devname); + if (rc == DC_STATUS_SUCCESS) { + err = do_device_import(data); + dc_device_close(data->device); + } + dc_context_free(data->context); + return err; +} + static void *pthread_wrapper(void *_data) { device_data_t *data = _data; diff --git a/libdivecomputer.h b/libdivecomputer.h index 8d77a25..6b54e9c 100644 --- a/libdivecomputer.h +++ b/libdivecomputer.h @@ -15,6 +15,7 @@ typedef struct device_data_t { dc_descriptor_t *descriptor; const char *vendor, *product, *devname; dc_device_t *device; + dc_context_t *context; progressbar_t progress; int preexisting; } device_data_t; diff --git a/main.c b/main.c index 8e579f8..2489473 100644 --- a/main.c +++ b/main.c @@ -172,7 +172,7 @@ static void parse_argument(const char *arg) if (strncmp(arg, "-psn_", 5) == 0) { return; } - /* fallthrough */ + /* fallthrough */ default: fprintf(stderr, "Bad argument '%s'\n", arg); exit(1); @@ -217,7 +217,7 @@ int main(int argc, char **argv) parse_xml_init(); init_ui(&argc, &argv); - + for (i = 1; i < argc; i++) { const char *a = argv[i]; @@ -227,7 +227,7 @@ int main(int argc, char **argv) } GError *error = NULL; parse_file(a, &error); - + if (error != NULL) { report_error(error); diff --git a/parse-xml.c b/parse-xml.c index b70f154..5159a33 100644 --- a/parse-xml.c +++ b/parse-xml.c @@ -1480,8 +1480,8 @@ void parse_xml_buffer(const char *url, const char *buffer, int size, GError **er } return; } - /* we assume that the last (or only) filename passed as argument is a - * great filename to use as default when saving the dives */ + /* we assume that the last (or only) filename passed as argument is a + * great filename to use as default when saving the dives */ set_filename(url); reset_all(); dive_start(); diff --git a/print.c b/print.c index bdebcfe..d8373e5 100644 --- a/print.c +++ b/print.c @@ -11,6 +11,15 @@ #define FONT_SMALL (FONT_NORMAL / 1.2) #define FONT_LARGE (FONT_NORMAL * 1.2) +#define OPTIONCALLBACK(name, option) \ +static void name(GtkWidget *w, gpointer data) \ +{ \ + option = GTK_TOGGLE_BUTTON(w)->active; \ +} + +OPTIONCALLBACK(print_profiles_toggle, visible_cols.print_profiles) + + static void set_font(PangoLayout *layout, PangoFontDescription *font, double size, int align) { pango_font_description_set_size(font, size * PANGO_SCALE); @@ -165,6 +174,28 @@ static void print(int divenr, cairo_t *cr, double x, double y, double w, double cairo_restore(cr); } +static void print_table(int divenr, cairo_t *cr, double x, double y, double w, double h, PangoFontDescription *font) +{ + struct dive *dive; + + dive = get_dive(divenr); + if (!dive) + return; + cairo_save(cr); + cairo_translate(cr, x, y); + + /* Plus 5% on all sides */ + cairo_translate(cr, w/20, h/20); + w *= 0.9; h *= 0.9; + + /* We actually want to scale the text and the lines now */ + cairo_scale(cr, 0.5, 0.5); + + show_dive_text(dive, cr, w*2, h*2, font); + + cairo_restore(cr); +} + static void draw_page(GtkPrintOperation *operation, GtkPrintContext *context, gint page_nr, @@ -192,8 +223,71 @@ static void draw_page(GtkPrintOperation *operation, pango_font_description_free(font); } +static void draw_page_table(GtkPrintOperation *operation, + GtkPrintContext *context, + gint page_nr, + gpointer user_data) +{ + int nr; + cairo_t *cr; + double w, h; + PangoFontDescription *font; + + cr = gtk_print_context_get_cairo_context(context); + font = pango_font_description_from_string("Sans"); + + w = gtk_print_context_get_width(context); + h = gtk_print_context_get_height(context)/15; + + nr = page_nr*15; + int i; + for (i = 0; i < 15; i++) { + print_table(nr+i, cr, 0, 0+h*i, w, h, font); + } + + pango_font_description_free(font); +} + static void begin_print(GtkPrintOperation *operation, gpointer user_data) { + int pages; + if (visible_cols.print_profiles){ + pages = (dive_table.nr + 5) / 6; + gtk_print_operation_set_n_pages(operation, pages); + } else { + pages = (dive_table.nr + 9) / 15; + gtk_print_operation_set_n_pages(operation, pages); + } +} + +static GtkWidget *print_dialog(GtkPrintOperation *operation, gpointer user_data) +{ + GtkWidget *vbox, *button, *frame, *box; + gtk_print_operation_set_custom_tab_label(operation, "Dive details"); + + vbox = gtk_vbox_new(TRUE, 5); + + frame = gtk_frame_new("Print options"); + gtk_box_pack_start(GTK_BOX(vbox), frame, FALSE, FALSE, 1); + + box = gtk_hbox_new(FALSE, 1); + gtk_container_add(GTK_CONTAINER(frame), box); + button = gtk_check_button_new_with_label("Show profiles"); + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button), visible_cols.print_profiles); + gtk_box_pack_start(GTK_BOX(box), button, FALSE, FALSE, 6); + g_signal_connect(G_OBJECT(button), "toggled", G_CALLBACK(print_profiles_toggle), NULL); + + gtk_widget_show_all(vbox); + return vbox; +} + +static void print_dialog_apply(GtkPrintOperation *operation, GtkWidget *widget, gpointer user_data) +{ + if (visible_cols.print_profiles){ + g_signal_connect(operation, "draw_page", G_CALLBACK(draw_page), NULL); + } else { + g_signal_connect(operation, "draw_page", G_CALLBACK(draw_page_table), NULL); + } } static GtkPrintSettings *settings = NULL; @@ -208,10 +302,9 @@ void do_print(void) print = gtk_print_operation_new(); if (settings != NULL) gtk_print_operation_set_print_settings(print, settings); - pages = (dive_table.nr + 5) / 6; - gtk_print_operation_set_n_pages(print, pages); + g_signal_connect(print, "create-custom-widget", G_CALLBACK(print_dialog), NULL); + g_signal_connect(print, "custom-widget-apply", G_CALLBACK(print_dialog_apply), NULL); g_signal_connect(print, "begin_print", G_CALLBACK(begin_print), NULL); - g_signal_connect(print, "draw_page", G_CALLBACK(draw_page), NULL); res = gtk_print_operation_run(print, GTK_PRINT_OPERATION_ACTION_PRINT_DIALOG, GTK_WINDOW(main_window), NULL); if (res == GTK_PRINT_OPERATION_RESULT_APPLY) { diff --git a/profile.c b/profile.c index 9618c46..6a159cc 100644 --- a/profile.c +++ b/profile.c @@ -1,5 +1,5 @@ /* profile.c */ -/* creates all the necessary data for drawing the dive profile +/* creates all the necessary data for drawing the dive profile * uses cairo to draw it */ #include @@ -873,7 +873,7 @@ static velocity_t velocity(int speed) else if (speed < -25) /* -5ft/min */ v = SLOW; else if (speed < 25) /* very hard to find data, but it appears that the recommendations - for descent are usually about 2x ascent rate; still, we want + for descent are usually about 2x ascent rate; still, we want stable to mean stable */ v = STABLE; else if (speed < 152) /* between 5 and 30ft/min is considered slow */ @@ -929,7 +929,7 @@ static struct plot_info *analyze_plot_info(struct plot_info *pi) int past = -2; while (i+past > 0 && entry[0].sec - entry[past].sec < 15) 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)); } } else @@ -941,7 +941,7 @@ static struct plot_info *analyze_plot_info(struct plot_info *pi) struct plot_data *entry = pi->entry +i; analyze_plot_info_minmax(entry, pi->entry, pi->entry+nr); } - + return pi; } diff --git a/save-xml.c b/save-xml.c index 9ba7a54..b797475 100644 --- a/save-xml.c +++ b/save-xml.c @@ -67,10 +67,9 @@ static void show_pressure(FILE *f, pressure_t pressure, const char *pre, const c * characters, but at least libxml2 doesn't like them. It doesn't even * allow them quoted. So we just skip them and replace them with '?'. * - * Nothing else (and if we ever do this using attributes, we'd need to - * quote the quotes we use too). + * If we do this for attributes, we need to quote the quotes we use too. */ -static void quote(FILE *f, const char *text) +static void quote(FILE *f, const char *text, int is_attribute) { const char *p = text; @@ -98,9 +97,13 @@ static void quote(FILE *f, const char *text) escape = "&"; break; case '\'': + if (!is_attribute) + continue; escape = "'"; break; case '\"': + if (!is_attribute) + continue; escape = """; break; } @@ -112,7 +115,7 @@ static void quote(FILE *f, const char *text) } } -static void show_utf8(FILE *f, const char *text, const char *pre, const char *post) +static void show_utf8(FILE *f, const char *text, const char *pre, const char *post, int is_attribute) { int len; @@ -127,7 +130,7 @@ static void show_utf8(FILE *f, const char *text, const char *pre, const char *po len--; /* FIXME! Quoting! */ fputs(pre, f); - quote(f, text); + quote(f, text, is_attribute); fputs(post, f); } @@ -177,7 +180,7 @@ static void show_location(FILE *f, struct dive *dive) } prefix = buffer; } - show_utf8(f, dive->location, prefix,"\n"); + show_utf8(f, dive->location, prefix,"\n", 0); } static void save_overview(FILE *f, struct dive *dive) @@ -186,10 +189,10 @@ static void save_overview(FILE *f, struct dive *dive) save_temperatures(f, dive); show_duration(f, dive->surfacetime, " ", "\n"); show_location(f, dive); - show_utf8(f, dive->divemaster, " ","\n"); - show_utf8(f, dive->buddy, " ","\n"); - show_utf8(f, dive->notes, " ","\n"); - show_utf8(f, dive->suit, " ","\n"); + show_utf8(f, dive->divemaster, " ","\n", 0); + show_utf8(f, dive->buddy, " ","\n", 0); + show_utf8(f, dive->notes, " ","\n", 0); + show_utf8(f, dive->suit, " ","\n", 0); } static void save_cylinder_info(FILE *f, struct dive *dive) @@ -268,7 +271,7 @@ static void save_one_event(FILE *f, struct event *ev) show_index(f, ev->type, "type='", "'"); show_index(f, ev->flags, "flags='", "'"); show_index(f, ev->value, "value='", "'"); - show_utf8(f, ev->name, " name='", "'"); + show_utf8(f, ev->name, " name='", "'", 1); fprintf(f, " />\n"); } @@ -289,7 +292,7 @@ static void save_trip(FILE *f, struct dive *trip) fprintf(f, " date='%04u-%02u-%02u'", tm->tm_year+1900, tm->tm_mon+1, tm->tm_mday); if (trip->location) - show_utf8(f, trip->location, " location=\'","\'"); + show_utf8(f, trip->location, " location=\'","\'", 1); fprintf(f, " />\n"); } diff --git a/statistics.c b/statistics.c index 0a23f90..a536173 100644 --- a/statistics.c +++ b/statistics.c @@ -151,7 +151,7 @@ void process_selected_dives(void) memset(&stats_selection, 0, sizeof(stats_selection)); nr = 0; - for (i = 0; (dive = get_dive(i)) != NULL; ++i) { + for_each_dive(i, dive) { if (dive->selected) { process_dive(dive, &stats_selection); nr++; @@ -211,7 +211,7 @@ static void show_single_dive_stats(struct dive *dive) set_label(single_w.date, buf); set_label(single_w.dive_time, "%d min", (dive->duration.seconds + 30) / 60); if (prev_dive) - set_label(single_w.surf_intv, + set_label(single_w.surf_intv, get_time_string(dive->when - (prev_dive->when + prev_dive->duration.seconds), 4)); else set_label(single_w.surf_intv, "unknown"); diff --git a/uemis.h b/uemis.h index 29a168f..ba9a234 100644 --- a/uemis.h +++ b/uemis.h @@ -28,7 +28,7 @@ typedef struct { uint16_t consumption; // (units unclear) uint8_t rgt; // (remaining gas time in minutes) uint8_t cns; - uint8_t flags[8]; + uint8_t flags[8]; } __attribute((packed)) uemis_sample_t; #endif /* DIVE_H */