From 5ea6b229f88aa5dacb80fedf9d316c31584c429d Mon Sep 17 00:00:00 2001 From: Nathan Samson Date: Sun, 4 Sep 2011 14:38:01 +0200 Subject: [PATCH 01/13] Change location to a text entry instead of text view. Signed-off-by: Nathan Samson --- info.c | 27 +++++++++++++++++++++------ 1 file changed, 21 insertions(+), 6 deletions(-) diff --git a/info.c b/info.c index 55708bedf..99bf3f041 100644 --- a/info.c +++ b/info.c @@ -7,7 +7,8 @@ #include "display.h" static GtkWidget *divedate, *divetime, *depth, *duration, *temperature, *locationnote; -static GtkTextBuffer *location, *notes; +static GtkEntry *location; +static GtkTextBuffer *notes; static int location_changed = 1, notes_changed = 1; static struct dive *buffered_dive; @@ -38,7 +39,7 @@ void flush_dive_info_changes(void) if (location_changed) { g_free(dive->location); - dive->location = get_text(location); + dive->location = gtk_editable_get_chars(GTK_EDITABLE(location), 0, -1); } if (notes_changed) { @@ -94,7 +95,7 @@ void update_dive_info(struct dive *dive) gtk_label_set_text(GTK_LABEL(temperature), buffer); text = dive->location ? : ""; - gtk_text_buffer_set_text(location, text, -1); + gtk_entry_set_text(location, text); gtk_label_set_text(GTK_LABEL(locationnote), text); text = dive->notes ? : ""; @@ -142,7 +143,21 @@ GtkWidget *dive_info_frame(void) return frame; } -static GtkTextBuffer *text_entry(GtkWidget *box, const char *label, gboolean expand) +static GtkEntry *text_entry(GtkWidget *box, const char *label) +{ + GtkWidget *entry; + + GtkWidget *frame = gtk_frame_new(label); + + gtk_box_pack_start(GTK_BOX(box), frame, FALSE, TRUE, 0); + + entry = gtk_entry_new (); + gtk_container_add(GTK_CONTAINER(frame), entry); + + return GTK_ENTRY(entry); +} + +static GtkTextBuffer *text_view(GtkWidget *box, const char *label, gboolean expand) { GtkWidget *view; GtkTextBuffer *buffer; @@ -175,8 +190,8 @@ GtkWidget *extended_dive_info_frame(void) vbox = gtk_vbox_new(FALSE, 5); gtk_container_add(GTK_CONTAINER(frame), vbox); - location = text_entry(vbox, "Location", FALSE); - notes = text_entry(vbox, "Notes", TRUE); + location = text_entry(vbox, "Location"); + notes = text_view(vbox, "Notes", TRUE); /* Add extended info here: name, description, yadda yadda */ update_dive_info(current_dive); From 14547d8ca26fb91b145c6051e541863fb89b76b5 Mon Sep 17 00:00:00 2001 From: Nathan Samson Date: Sun, 4 Sep 2011 15:08:01 +0200 Subject: [PATCH 02/13] Word wrap the info textview. Also do not show the scrollbars if not necessary. Signed-off-by: Nathan Samson --- info.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/info.c b/info.c index 99bf3f041..9abbbec40 100644 --- a/info.c +++ b/info.c @@ -167,10 +167,12 @@ static GtkTextBuffer *text_view(GtkWidget *box, const char *label, gboolean expa gtk_box_pack_start(GTK_BOX(box), frame, expand, expand, 0); GtkWidget* scrolled_window = gtk_scrolled_window_new (0, 0); + gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled_window), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(scrolled_window), GTK_SHADOW_IN); gtk_widget_show(scrolled_window); view = gtk_text_view_new (); + gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(view), GTK_WRAP_WORD); gtk_container_add(GTK_CONTAINER(scrolled_window), view); buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (view)); From f12382c66f2b3deddf38f7d51fda3a2c75a0c5fa Mon Sep 17 00:00:00 2001 From: Nathan Samson Date: Sun, 4 Sep 2011 12:59:54 +0200 Subject: [PATCH 03/13] Removed the unused startemp and enttemp calculations. This fixes a compiler warning too. Signed-off-by: Nathan Samson --- dive.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/dive.c b/dive.c index 8c81a3d51..f758785d9 100644 --- a/dive.c +++ b/dive.c @@ -34,7 +34,6 @@ struct dive *fixup_dive(struct dive *dive) int lasttime = 0; int start = -1, end = -1; int startpress = 0, endpress = 0; - int starttemp = 0, endtemp = 0; int maxdepth = 0, mintemp = 0; int lastdepth = 0; @@ -60,9 +59,6 @@ struct dive *fixup_dive(struct dive *dive) startpress = press; } if (temp) { - endtemp = temp; - if (!starttemp) - starttemp = temp; if (!mintemp || temp < mintemp) mintemp = temp; } From a57668127eb0e00bc467ae0fc487592e95c17227 Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Sun, 4 Sep 2011 09:50:31 -0700 Subject: [PATCH 04/13] Oops. I forgot to 'fclose()' the file after saving the xml It never actually triggered anything for me, but any buffered data might be lost, especially if you force-exit the application after saving a dive log. This probably explains a corrupted (truncated) dive file report from Nathan Samson. Reported-by: Nathan Samson Signed-off-by: Linus Torvalds --- save-xml.c | 1 + 1 file changed, 1 insertion(+) diff --git a/save-xml.c b/save-xml.c index 9e3640cad..5c05723b7 100644 --- a/save-xml.c +++ b/save-xml.c @@ -193,4 +193,5 @@ void save_dives(const char *filename) for (i = 0; i < dive_table.nr; i++) save_dive(f, get_dive(i)); fprintf(f, "\n"); + fclose(f); } From 797343bf8ac6105f9566ce0d662f4289d5d9d410 Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Sun, 4 Sep 2011 09:52:40 -0700 Subject: [PATCH 05/13] Update gitignore for the name-change of the executable It's not called 'parse' any more. And I think I should rename 'divelog' too to something more unique. Right now the working name for the project is 'diveclog' (kind of like 'jdivelog') , but I'm not convinced that the "C implementation" part is really important enough to make a point of long-term. "subsurface"? I don't know. Maybe I should follow the "name all projects after myself" mantra. "divenut"? Signed-off-by: Linus Torvalds --- .gitignore | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 295ea6b17..aeb949b3d 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,2 @@ *.o -/parse +/divelog From 1117cd37d71e294069a670bdf0851041575e0d5f Mon Sep 17 00:00:00 2001 From: Nathan Samson Date: Sun, 4 Sep 2011 18:54:12 +0200 Subject: [PATCH 06/13] Use a pane so the dive list can be made wider or smaller to the users wishes Signed-off-by: Nathan Samson --- main.c | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/main.c b/main.c index c9cda2b47..b748f693b 100644 --- a/main.c +++ b/main.c @@ -174,7 +174,8 @@ int main(int argc, char **argv) int i; GtkWidget *win; GtkWidget *divelist; - GtkWidget *table; + GtkWidget *paned; + GtkWidget *info_box; GtkWidget *notebook; GtkWidget *frame; GtkWidget *menubar; @@ -206,25 +207,25 @@ int main(int argc, char **argv) menubar = get_menubar_menu(win); gtk_box_pack_start(GTK_BOX(vbox), menubar, FALSE, FALSE, 0); - /* Table for the list of dives, cairo window, and dive info */ - table = gtk_table_new(2, 2, FALSE); - gtk_container_set_border_width(GTK_CONTAINER(table), 5); - gtk_box_pack_end(GTK_BOX(vbox), table, TRUE, TRUE, 0); - gtk_widget_show(table); + /* HPane for left the dive list, and right the dive info */ + paned = gtk_hpaned_new(); + gtk_box_pack_end(GTK_BOX(vbox), paned, TRUE, TRUE, 0); /* Create the atual divelist */ divelist = create_dive_list(); - gtk_table_attach(GTK_TABLE(table), divelist, 0, 1, 0, 2, - 0, GTK_FILL | GTK_SHRINK | GTK_EXPAND, 0, 0); + gtk_paned_add1(GTK_PANED(paned), divelist); + + /* VBox for dive info, and tabs */ + info_box = gtk_vbox_new(FALSE, 5); + gtk_paned_add2(GTK_PANED(paned), info_box); /* Frame for minimal dive info */ frame = dive_info_frame(); - gtk_table_attach(GTK_TABLE(table), frame, 1, 2, 0, 1, - GTK_FILL | GTK_SHRINK | GTK_EXPAND, 0, 0, 0); + gtk_box_pack_start(GTK_BOX(info_box), frame, FALSE, TRUE, 5); /* Notebook for dive info vs profile vs .. */ notebook = gtk_notebook_new(); - gtk_table_attach_defaults(GTK_TABLE(table), notebook, 1, 2, 1, 2); + gtk_box_pack_start(GTK_BOX(info_box), notebook, TRUE, TRUE, 5); /* Frame for dive profile */ frame = dive_profile_frame(); From 6138d151e9156bdf15843b1b54104428c5124e38 Mon Sep 17 00:00:00 2001 From: Nathan Samson Date: Sun, 4 Sep 2011 19:01:30 +0200 Subject: [PATCH 07/13] Remove the redundant frames in the notebook. Closes #9 Signed-off-by: Nathan Samson --- display.h | 4 ++-- info.c | 9 ++------- main.c | 10 +++++----- profile.c | 8 ++------ 4 files changed, 11 insertions(+), 20 deletions(-) diff --git a/display.h b/display.h index f336bd5ec..96fa29a5d 100644 --- a/display.h +++ b/display.h @@ -8,9 +8,9 @@ extern int selected_dive; #define current_dive (get_dive(selected_dive)) -extern GtkWidget *dive_profile_frame(void); +extern GtkWidget *dive_profile_widget(void); extern GtkWidget *dive_info_frame(void); -extern GtkWidget *extended_dive_info_frame(void); +extern GtkWidget *extended_dive_info_widget(void); extern GtkWidget *create_dive_list(void); extern void update_dive_info(struct dive *dive); extern void repaint_dive(void); diff --git a/info.c b/info.c index 55708bedf..4275ad6ff 100644 --- a/info.c +++ b/info.c @@ -164,21 +164,16 @@ static GtkTextBuffer *text_entry(GtkWidget *box, const char *label, gboolean exp return buffer; } -GtkWidget *extended_dive_info_frame(void) +GtkWidget *extended_dive_info_widget(void) { - GtkWidget *frame; GtkWidget *vbox; - frame = gtk_frame_new("Extended dive info"); - gtk_widget_show(frame); - vbox = gtk_vbox_new(FALSE, 5); - gtk_container_add(GTK_CONTAINER(frame), vbox); location = text_entry(vbox, "Location", FALSE); notes = text_entry(vbox, "Notes", TRUE); /* Add extended info here: name, description, yadda yadda */ update_dive_info(current_dive); - return frame; + return vbox; } diff --git a/main.c b/main.c index b748f693b..57c8f70e6 100644 --- a/main.c +++ b/main.c @@ -178,6 +178,7 @@ int main(int argc, char **argv) GtkWidget *info_box; GtkWidget *notebook; GtkWidget *frame; + GtkWidget *dive_info; GtkWidget *menubar; GtkWidget *vbox; @@ -228,13 +229,12 @@ int main(int argc, char **argv) gtk_box_pack_start(GTK_BOX(info_box), notebook, TRUE, TRUE, 5); /* Frame for dive profile */ - frame = dive_profile_frame(); - gtk_notebook_append_page(GTK_NOTEBOOK(notebook), frame, gtk_label_new("Dive Profile")); - dive_profile = frame; + dive_profile = dive_profile_widget(); + gtk_notebook_append_page(GTK_NOTEBOOK(notebook), dive_profile, gtk_label_new("Dive Profile")); /* Frame for extended dive info */ - frame = extended_dive_info_frame(); - gtk_notebook_append_page(GTK_NOTEBOOK(notebook), frame, gtk_label_new("Extended dive Info")); + dive_info = extended_dive_info_widget(); + gtk_notebook_append_page(GTK_NOTEBOOK(notebook), dive_info, gtk_label_new("Extended dive Info")); gtk_widget_set_app_paintable(win, TRUE); gtk_widget_show_all(win); diff --git a/profile.c b/profile.c index 7a0a20828..070e6fa70 100644 --- a/profile.c +++ b/profile.c @@ -195,17 +195,13 @@ static gboolean expose_event(GtkWidget *widget, GdkEventExpose *event, gpointer return FALSE; } -GtkWidget *dive_profile_frame(void) +GtkWidget *dive_profile_widget(void) { - GtkWidget *frame; GtkWidget *da; - frame = gtk_frame_new("Dive profile"); - gtk_widget_show(frame); da = gtk_drawing_area_new(); gtk_widget_set_size_request(da, 450, 350); g_signal_connect(da, "expose_event", G_CALLBACK(expose_event), NULL); - gtk_container_add(GTK_CONTAINER(frame), da); - return frame; + return da; } From 23a6607ae7ce9335be736c3400e4b8d77744af16 Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Sun, 4 Sep 2011 10:01:37 -0700 Subject: [PATCH 08/13] Fix typo in Makefile (LDLAGS -> LDFLAGS) Reported-by: Konrad Delong Signed-off-by: Linus Torvalds --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index b16d38c7a..8b5fd220f 100644 --- a/Makefile +++ b/Makefile @@ -4,7 +4,7 @@ CFLAGS=-Wall -Wno-pointer-sign -g OBJS=main.o dive.o profile.o info.o divelist.o parse-xml.o save-xml.o divelog: $(OBJS) - $(CC) $(LDLAGS) -o divelog $(OBJS) \ + $(CC) $(LDFLAGS) -o divelog $(OBJS) \ `xml2-config --libs` \ `pkg-config --libs gtk+-2.0` From 31123f63af0a2b6a9756b8496f56359d1c68a645 Mon Sep 17 00:00:00 2001 From: Nathan Samson Date: Sun, 4 Sep 2011 20:14:33 +0200 Subject: [PATCH 09/13] Split the dive list in columns. Columns are sortable now (name = date, depth, duration) Signed-off-by: Nathan Samson --- divelist.c | 48 ++++++++++++++++++++++++++++++++++++++++++++---- parse-xml.c | 6 ++---- 2 files changed, 46 insertions(+), 8 deletions(-) diff --git a/divelist.c b/divelist.c index ba426588a..5baf589d3 100644 --- a/divelist.c +++ b/divelist.c @@ -1,5 +1,6 @@ #include #include +#include #include #include "dive.h" @@ -13,7 +14,7 @@ static void selection_cb(GtkTreeSelection *selection, GtkTreeModel *model) if (!gtk_tree_selection_get_selected(selection, NULL, &iter)) return; - gtk_tree_model_get_value(model, &iter, 1, &value); + gtk_tree_model_get_value(model, &iter, 5, &value); selected_dive = g_value_get_int(&value); repaint_dive(); } @@ -26,10 +27,27 @@ static void fill_dive_list(GtkListStore *store) for (i = 0; i < dive_table.nr; i++) { struct dive *dive = dive_table.dives[i]; + int len; + char buffer[256], *depth, *duration; + + len = snprintf(buffer, sizeof(buffer), + "%d ft", to_feet(dive->maxdepth)); + depth = malloc(len + 1); + memcpy(depth, buffer, len+1); + + len = snprintf(buffer, sizeof(buffer), + "%d min", dive->duration.seconds / 60); + duration = malloc(len + 1); + memcpy(duration, buffer, len+1); + gtk_list_store_append(store, &iter); gtk_list_store_set(store, &iter, 0, dive->name, - 1, i, + 1, depth, + 2, dive->maxdepth, + 3, duration, + 4, dive->duration.seconds, + 5, i, -1); } } @@ -43,7 +61,10 @@ GtkWidget *create_dive_list(void) GtkTreeViewColumn *col; GtkWidget *scroll_window; - model = gtk_list_store_new(2, G_TYPE_STRING, G_TYPE_INT); + model = gtk_list_store_new(6, G_TYPE_STRING, + G_TYPE_STRING, G_TYPE_INT, + G_TYPE_STRING, G_TYPE_INT, + G_TYPE_INT); tree_view = gtk_tree_view_new_with_model(GTK_TREE_MODEL(model)); selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(tree_view)); @@ -54,11 +75,30 @@ GtkWidget *create_dive_list(void) renderer = gtk_cell_renderer_text_new(); col = gtk_tree_view_column_new(); + gtk_tree_view_column_set_title(col, "Name"); + gtk_tree_view_column_set_sort_column_id(col, 0); + gtk_tree_view_column_set_resizable (col, TRUE); gtk_tree_view_column_pack_start(col, renderer, TRUE); gtk_tree_view_column_add_attribute(col, renderer, "text", 0); gtk_tree_view_append_column(GTK_TREE_VIEW(tree_view), col); + + renderer = gtk_cell_renderer_text_new(); + col = gtk_tree_view_column_new(); + gtk_tree_view_column_set_title(col, "Depth"); + gtk_tree_view_column_set_sort_column_id(col, 2); + gtk_tree_view_column_pack_start(col, renderer, TRUE); + gtk_tree_view_column_add_attribute(col, renderer, "text", 1); + gtk_tree_view_append_column(GTK_TREE_VIEW(tree_view), col); + + renderer = gtk_cell_renderer_text_new(); + col = gtk_tree_view_column_new(); + gtk_tree_view_column_set_title(col, "Duration"); + gtk_tree_view_column_set_sort_column_id(col, 4); + gtk_tree_view_column_pack_start(col, renderer, TRUE); + gtk_tree_view_column_add_attribute(col, renderer, "text", 3); + gtk_tree_view_append_column(GTK_TREE_VIEW(tree_view), col); - g_object_set(G_OBJECT(tree_view), "headers-visible", FALSE, + g_object_set(G_OBJECT(tree_view), "headers-visible", TRUE, "search-column", 0, "rules-hint", FALSE, NULL); diff --git a/parse-xml.c b/parse-xml.c index 635bf56f2..a2c685ed5 100644 --- a/parse-xml.c +++ b/parse-xml.c @@ -693,11 +693,9 @@ static char *generate_name(struct dive *dive) len = snprintf(buffer, sizeof(buffer), "%04d-%02d-%02d " - "%02d:%02d:%02d " - "(%d ft, %d min)", + "%02d:%02d:%02d", tm->tm_year+1900, tm->tm_mon+1, tm->tm_mday, - tm->tm_hour, tm->tm_min, tm->tm_sec, - to_feet(dive->maxdepth), dive->duration.seconds / 60); + tm->tm_hour, tm->tm_min, tm->tm_sec); p = malloc(len+1); if (!p) exit(1); From 9961c7f89ce6353609383b16b9fbf3a30e4d8604 Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Sun, 4 Sep 2011 11:20:27 -0700 Subject: [PATCH 10/13] Remove redundant temperature readings I'm aiming to really differentiate in dive log software by making my XML export files be *clean*, dammit. That means that we don't have random names, we don't have crazy random units, and we don't have redundant information. So when the temperature doesn't change, just don't report it. That's already what "no sample" means, just clean things up. Signed-off-by: Linus Torvalds --- dive.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/dive.c b/dive.c index 8c81a3d51..9bac25eee 100644 --- a/dive.c +++ b/dive.c @@ -37,6 +37,8 @@ struct dive *fixup_dive(struct dive *dive) int starttemp = 0, endtemp = 0; int maxdepth = 0, mintemp = 0; int lastdepth = 0; + int lasttemp = 0; + temperature_t *redundant_temp = NULL; for (i = 0; i < dive->samples; i++) { struct sample *sample = dive->sample + i; @@ -60,6 +62,21 @@ struct dive *fixup_dive(struct dive *dive) startpress = press; } if (temp) { + /* + * If we have consecutive identical + * temperature readings, throw away + * the redundant ones. We care about + * the "edges" only. + */ + if (lasttemp == temp) { + if (redundant_temp) + redundant_temp->mkelvin = 0; + redundant_temp = &sample->temperature; + } else { + redundant_temp = NULL; + lasttemp = temp; + } + endtemp = temp; if (!starttemp) starttemp = temp; From ecff0922d43edeb361769755d49e84d1b02caa90 Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Sun, 4 Sep 2011 11:23:41 -0700 Subject: [PATCH 11/13] Don't save cylinder working pressure It was a mistake to save it - and I did it just because other dive managers did. It's a totally nonsensical measure, and nobody cares. The only thing that matters is the size of the cylinder, and the *actual* pressures. Those give actual air consumption numbers, and are meaningful and unambiguous. So the "working pressure" for a cylinder is pointless except for two things: - if you don't know the actual physical size, you need the "working pressure" along with the air size (eg "85 cuft") in order to compute the physical size. So we do use the working pressure on *input* from systems that report cylinder sizes that way. - People may well want to know what kind of cylinder they were diving, and again, you can make a good guess about this from the working pressure. So saving information like "HP100+" for the cylinder would be a good thing. But notice how in neither case do we actually want to save the working pressure itself. And in fact saving it actually makes the output format ambiguous: if we give both size and working pressure, what does 'size' mean? Is it physical size in liters, or air size in cu ft? So saving working pressure is just wrong. Get rid of it. I'm going to add some kind of "cylinder description" thing, which we can save instead (and perhaps guess standard cylinders from input like the working pressure from dive logs that don't do this sanely - which is all of them, as far as I can tell). Signed-off-by: Linus Torvalds --- save-xml.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/save-xml.c b/save-xml.c index 5c05723b7..c33cbb0dd 100644 --- a/save-xml.c +++ b/save-xml.c @@ -127,7 +127,6 @@ static void save_cylinder_info(FILE *f, struct dive *dive) for (i = 0; i < MAX_CYLINDERS; i++) { cylinder_t *cylinder = dive->cylinder+i; int volume = cylinder->type.size.mliter; - int pressure = cylinder->type.workingpressure.mbar; int o2 = cylinder->gasmix.o2.permille; int he = cylinder->gasmix.he.permille; @@ -140,11 +139,8 @@ static void save_cylinder_info(FILE *f, struct dive *dive) if (he) fprintf(f, " he='%u.%u%%'", FRACTION(he, 10)); } - if (volume) { + if (volume) fprintf(f, " size='%u.%03u l'", FRACTION(volume, 1000)); - if (pressure) - fprintf(f, " workpressure='%u.%03u bar'", FRACTION(pressure, 1000)); - } fprintf(f, " />\n"); } } From 09174367294c399265954a9e2770427e5ee251ba Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Sun, 4 Sep 2011 11:32:30 -0700 Subject: [PATCH 12/13] Add placeholder for cylinder type description So we don't want to save working pressure, but cylinder type knowledge would be lovely and useful. And we can probably make a good initial guess, or at least let people fill it in later. Signed-off-by: Linus Torvalds --- dive.h | 1 + 1 file changed, 1 insertion(+) diff --git a/dive.h b/dive.h index c6c545dcc..2d03ee7cd 100644 --- a/dive.h +++ b/dive.h @@ -75,6 +75,7 @@ typedef struct { typedef struct { volume_t size; pressure_t workingpressure; + const char *description; /* "LP85", "AL72", "AL80", "HP100+" or whatever */ } cylinder_type_t; typedef struct { From aab4d593bdbffef8442282318778a9833cbc7a43 Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Sun, 4 Sep 2011 12:09:48 -0700 Subject: [PATCH 13/13] Generate date string for the dive list dynamically .. and sort based on the 'time_t' value itself. This allows us to use a more compact date format that doesn't need to sort alphabetically, because sorting by date is always based on the date value. So we can use just a two-digit year, and skip the seconds, to keep the column narrow, while still sorting correctly. Also, "Depth" is a nice header string, but it is wider than the column itself, which makes the whole column wider than necessary. So put the units in the header instead of in the string, keeping things narrow. Signed-off-by: Linus Torvalds --- dive.c | 1 - dive.h | 1 - divelist.c | 49 ++++++++++++++++++++++++++++++------------------- parse-xml.c | 22 ---------------------- 4 files changed, 30 insertions(+), 43 deletions(-) diff --git a/dive.c b/dive.c index 757622fe7..5ddb6bc80 100644 --- a/dive.c +++ b/dive.c @@ -253,7 +253,6 @@ struct dive *try_to_merge(struct dive *a, struct dive *b) memset(res, 0, dive_size(alloc_samples)); res->when = a->when; - res->name = merge_text(a->name, b->name); res->location = merge_text(a->location, b->location); res->notes = merge_text(a->notes, b->notes); MERGE_MAX(res, a, b, maxdepth.mm); diff --git a/dive.h b/dive.h index 2d03ee7cd..1386a3bf8 100644 --- a/dive.h +++ b/dive.h @@ -111,7 +111,6 @@ struct sample { #define MAX_CYLINDERS (4) struct dive { - const char *name; time_t when; char *location; char *notes; diff --git a/divelist.c b/divelist.c index 5baf589d3..1970b38ab 100644 --- a/divelist.c +++ b/divelist.c @@ -14,7 +14,7 @@ static void selection_cb(GtkTreeSelection *selection, GtkTreeModel *model) if (!gtk_tree_selection_get_selected(selection, NULL, &iter)) return; - gtk_tree_model_get_value(model, &iter, 5, &value); + gtk_tree_model_get_value(model, &iter, 6, &value); selected_dive = g_value_get_int(&value); repaint_dive(); } @@ -28,26 +28,36 @@ static void fill_dive_list(GtkListStore *store) struct dive *dive = dive_table.dives[i]; int len; - char buffer[256], *depth, *duration; + char buffer[256], *datestr, *depth, *duration; + struct tm *tm; + tm = gmtime(&dive->when); len = snprintf(buffer, sizeof(buffer), - "%d ft", to_feet(dive->maxdepth)); + "%02d.%02d.%02d %02d:%02d", + tm->tm_mday, tm->tm_mon+1, tm->tm_year % 100, + tm->tm_hour, tm->tm_min); + datestr = malloc(len+1); + memcpy(datestr, buffer, len+1); + + len = snprintf(buffer, sizeof(buffer), + "%d", to_feet(dive->maxdepth)); depth = malloc(len + 1); memcpy(depth, buffer, len+1); len = snprintf(buffer, sizeof(buffer), - "%d min", dive->duration.seconds / 60); + "%d", dive->duration.seconds / 60); duration = malloc(len + 1); memcpy(duration, buffer, len+1); gtk_list_store_append(store, &iter); gtk_list_store_set(store, &iter, - 0, dive->name, - 1, depth, - 2, dive->maxdepth, - 3, duration, - 4, dive->duration.seconds, - 5, i, + 0, datestr, + 1, dive->when, + 2, depth, + 3, dive->maxdepth, + 4, duration, + 5, dive->duration.seconds, + 6, i, -1); } } @@ -61,7 +71,8 @@ GtkWidget *create_dive_list(void) GtkTreeViewColumn *col; GtkWidget *scroll_window; - model = gtk_list_store_new(6, G_TYPE_STRING, + model = gtk_list_store_new(7, + G_TYPE_STRING, G_TYPE_INT, G_TYPE_STRING, G_TYPE_INT, G_TYPE_STRING, G_TYPE_INT, G_TYPE_INT); @@ -75,8 +86,8 @@ GtkWidget *create_dive_list(void) renderer = gtk_cell_renderer_text_new(); col = gtk_tree_view_column_new(); - gtk_tree_view_column_set_title(col, "Name"); - gtk_tree_view_column_set_sort_column_id(col, 0); + gtk_tree_view_column_set_title(col, "Date"); + gtk_tree_view_column_set_sort_column_id(col, 1); gtk_tree_view_column_set_resizable (col, TRUE); gtk_tree_view_column_pack_start(col, renderer, TRUE); gtk_tree_view_column_add_attribute(col, renderer, "text", 0); @@ -84,18 +95,18 @@ GtkWidget *create_dive_list(void) renderer = gtk_cell_renderer_text_new(); col = gtk_tree_view_column_new(); - gtk_tree_view_column_set_title(col, "Depth"); - gtk_tree_view_column_set_sort_column_id(col, 2); + gtk_tree_view_column_set_title(col, "ft"); + gtk_tree_view_column_set_sort_column_id(col, 3); gtk_tree_view_column_pack_start(col, renderer, TRUE); - gtk_tree_view_column_add_attribute(col, renderer, "text", 1); + gtk_tree_view_column_add_attribute(col, renderer, "text", 2); gtk_tree_view_append_column(GTK_TREE_VIEW(tree_view), col); renderer = gtk_cell_renderer_text_new(); col = gtk_tree_view_column_new(); - gtk_tree_view_column_set_title(col, "Duration"); - gtk_tree_view_column_set_sort_column_id(col, 4); + gtk_tree_view_column_set_title(col, "min"); + gtk_tree_view_column_set_sort_column_id(col, 5); gtk_tree_view_column_pack_start(col, renderer, TRUE); - gtk_tree_view_column_add_attribute(col, renderer, "text", 3); + gtk_tree_view_column_add_attribute(col, renderer, "text", 4); gtk_tree_view_append_column(GTK_TREE_VIEW(tree_view), col); g_object_set(G_OBJECT(tree_view), "headers-visible", TRUE, diff --git a/parse-xml.c b/parse-xml.c index a2c685ed5..3221111c7 100644 --- a/parse-xml.c +++ b/parse-xml.c @@ -683,26 +683,6 @@ static void dive_start(void) memset(&tm, 0, sizeof(tm)); } -static char *generate_name(struct dive *dive) -{ - int len; - struct tm *tm; - char buffer[256], *p; - - tm = gmtime(&dive->when); - - len = snprintf(buffer, sizeof(buffer), - "%04d-%02d-%02d " - "%02d:%02d:%02d", - tm->tm_year+1900, tm->tm_mon+1, tm->tm_mday, - tm->tm_hour, tm->tm_min, tm->tm_sec); - p = malloc(len+1); - if (!p) - exit(1); - memcpy(p, buffer, len+1); - return p; -} - static void sanitize_gasmix(gasmix_t *mix) { unsigned int o2, he; @@ -770,8 +750,6 @@ static void dive_end(void) { if (!dive) return; - if (!dive->name) - dive->name = generate_name(dive); sanitize_cylinder_info(dive); record_dive(dive); dive = NULL;