Merge hbonse's UI tweaks, but fixing the compile warnings. Also bringing it up to date with the master (and my own UI improvements)

Signed-off-by: Nathan Samson <nathansamson@gmail.com>
This commit is contained in:
Nathan Samson 2011-09-04 22:15:55 +02:00
commit 6b075e0339
11 changed files with 127 additions and 79 deletions

2
.gitignore vendored
View file

@ -1,2 +1,2 @@
*.o *.o
/parse /divelog

View file

@ -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 OBJS=main.o dive.o profile.o info.o divelist.o parse-xml.o save-xml.o
divelog: $(OBJS) divelog: $(OBJS)
$(CC) $(LDLAGS) -o divelog $(OBJS) \ $(CC) $(LDFLAGS) -o divelog $(OBJS) \
`xml2-config --libs` \ `xml2-config --libs` \
`pkg-config --libs gtk+-2.0` `pkg-config --libs gtk+-2.0`

View file

@ -8,9 +8,9 @@
extern int selected_dive; extern int selected_dive;
#define current_dive (get_dive(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 *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 GtkWidget *create_dive_list(void);
extern void update_dive_info(struct dive *dive); extern void update_dive_info(struct dive *dive);
extern void repaint_dive(void); extern void repaint_dive(void);

22
dive.c
View file

@ -34,9 +34,10 @@ struct dive *fixup_dive(struct dive *dive)
int lasttime = 0; int lasttime = 0;
int start = -1, end = -1; int start = -1, end = -1;
int startpress = 0, endpress = 0; int startpress = 0, endpress = 0;
int starttemp = 0, endtemp = 0;
int maxdepth = 0, mintemp = 0; int maxdepth = 0, mintemp = 0;
int lastdepth = 0; int lastdepth = 0;
int lasttemp = 0;
temperature_t *redundant_temp = NULL;
for (i = 0; i < dive->samples; i++) { for (i = 0; i < dive->samples; i++) {
struct sample *sample = dive->sample + i; struct sample *sample = dive->sample + i;
@ -60,9 +61,21 @@ struct dive *fixup_dive(struct dive *dive)
startpress = press; startpress = press;
} }
if (temp) { if (temp) {
endtemp = temp; /*
if (!starttemp) * If we have consecutive identical
starttemp = temp; * 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;
}
if (!mintemp || temp < mintemp) if (!mintemp || temp < mintemp)
mintemp = temp; mintemp = temp;
} }
@ -240,7 +253,6 @@ struct dive *try_to_merge(struct dive *a, struct dive *b)
memset(res, 0, dive_size(alloc_samples)); memset(res, 0, dive_size(alloc_samples));
res->when = a->when; res->when = a->when;
res->name = merge_text(a->name, b->name);
res->location = merge_text(a->location, b->location); res->location = merge_text(a->location, b->location);
res->notes = merge_text(a->notes, b->notes); res->notes = merge_text(a->notes, b->notes);
MERGE_MAX(res, a, b, maxdepth.mm); MERGE_MAX(res, a, b, maxdepth.mm);

2
dive.h
View file

@ -75,6 +75,7 @@ typedef struct {
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 */
} cylinder_type_t; } cylinder_type_t;
typedef struct { typedef struct {
@ -110,7 +111,6 @@ struct sample {
#define MAX_CYLINDERS (4) #define MAX_CYLINDERS (4)
struct dive { struct dive {
const char *name;
time_t when; time_t when;
char *location; char *location;
char *notes; char *notes;

View file

@ -1,5 +1,6 @@
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h>
#include <time.h> #include <time.h>
#include "dive.h" #include "dive.h"
@ -13,7 +14,7 @@ static void selection_cb(GtkTreeSelection *selection, GtkTreeModel *model)
if (!gtk_tree_selection_get_selected(selection, NULL, &iter)) if (!gtk_tree_selection_get_selected(selection, NULL, &iter))
return; return;
gtk_tree_model_get_value(model, &iter, 1, &value); gtk_tree_model_get_value(model, &iter, 6, &value);
selected_dive = g_value_get_int(&value); selected_dive = g_value_get_int(&value);
repaint_dive(); repaint_dive();
} }
@ -26,10 +27,37 @@ static void fill_dive_list(GtkListStore *store)
for (i = 0; i < dive_table.nr; i++) { for (i = 0; i < dive_table.nr; i++) {
struct dive *dive = dive_table.dives[i]; struct dive *dive = dive_table.dives[i];
int len;
char buffer[256], *datestr, *depth, *duration;
struct tm *tm;
tm = gmtime(&dive->when);
len = snprintf(buffer, sizeof(buffer),
"%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", dive->duration.seconds / 60);
duration = malloc(len + 1);
memcpy(duration, buffer, len+1);
gtk_list_store_append(store, &iter); gtk_list_store_append(store, &iter);
gtk_list_store_set(store, &iter, gtk_list_store_set(store, &iter,
0, dive->name, 0, datestr,
1, i, 1, dive->when,
2, depth,
3, dive->maxdepth,
4, duration,
5, dive->duration.seconds,
6, i,
-1); -1);
} }
} }
@ -43,7 +71,11 @@ GtkWidget *create_dive_list(void)
GtkTreeViewColumn *col; GtkTreeViewColumn *col;
GtkWidget *scroll_window; GtkWidget *scroll_window;
model = gtk_list_store_new(2, G_TYPE_STRING, G_TYPE_INT); 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);
tree_view = gtk_tree_view_new_with_model(GTK_TREE_MODEL(model)); tree_view = gtk_tree_view_new_with_model(GTK_TREE_MODEL(model));
selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(tree_view)); selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(tree_view));
@ -54,11 +86,30 @@ GtkWidget *create_dive_list(void)
renderer = gtk_cell_renderer_text_new(); renderer = gtk_cell_renderer_text_new();
col = gtk_tree_view_column_new(); col = gtk_tree_view_column_new();
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_pack_start(col, renderer, TRUE);
gtk_tree_view_column_add_attribute(col, renderer, "text", 0); gtk_tree_view_column_add_attribute(col, renderer, "text", 0);
gtk_tree_view_append_column(GTK_TREE_VIEW(tree_view), col); 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, "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", 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, "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", 4);
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, "search-column", 0,
"rules-hint", FALSE, "rules-hint", FALSE,
NULL); NULL);

38
info.c
View file

@ -7,7 +7,8 @@
#include "display.h" #include "display.h"
static GtkWidget *divedate, *divetime, *depth, *duration, *temperature, *locationnote; 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 int location_changed = 1, notes_changed = 1;
static struct dive *buffered_dive; static struct dive *buffered_dive;
@ -38,7 +39,7 @@ void flush_dive_info_changes(void)
if (location_changed) { if (location_changed) {
g_free(dive->location); g_free(dive->location);
dive->location = get_text(location); dive->location = gtk_editable_get_chars(GTK_EDITABLE(location), 0, -1);
} }
if (notes_changed) { if (notes_changed) {
@ -94,7 +95,7 @@ void update_dive_info(struct dive *dive)
gtk_label_set_text(GTK_LABEL(temperature), buffer); gtk_label_set_text(GTK_LABEL(temperature), buffer);
text = dive->location ? : ""; 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); gtk_label_set_text(GTK_LABEL(locationnote), text);
text = dive->notes ? : ""; text = dive->notes ? : "";
@ -118,15 +119,15 @@ GtkWidget *dive_info_frame(void)
frame = gtk_frame_new("Dive info"); frame = gtk_frame_new("Dive info");
gtk_widget_show(frame); gtk_widget_show(frame);
vbox = gtk_vbox_new(TRUE, 5); vbox = gtk_vbox_new(TRUE, 6);
gtk_container_set_border_width(GTK_CONTAINER(vbox), 3); gtk_container_set_border_width(GTK_CONTAINER(vbox), 3);
gtk_container_add(GTK_CONTAINER(frame), vbox); gtk_container_add(GTK_CONTAINER(frame), vbox);
hbox = gtk_hbox_new(TRUE, 5); hbox = gtk_hbox_new(TRUE, 6);
gtk_container_set_border_width(GTK_CONTAINER(hbox), 3); gtk_container_set_border_width(GTK_CONTAINER(hbox), 3);
gtk_container_add(GTK_CONTAINER(vbox), hbox); gtk_container_add(GTK_CONTAINER(vbox), hbox);
hbox2 = gtk_hbox_new(FALSE, 0); hbox2 = gtk_hbox_new(FALSE, 6);
gtk_container_set_border_width(GTK_CONTAINER(hbox2), 3); gtk_container_set_border_width(GTK_CONTAINER(hbox2), 3);
gtk_container_add(GTK_CONTAINER(vbox), hbox2); gtk_container_add(GTK_CONTAINER(vbox), hbox2);
@ -142,7 +143,21 @@ GtkWidget *dive_info_frame(void)
return frame; 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; GtkWidget *view;
GtkTextBuffer *buffer; GtkTextBuffer *buffer;
@ -152,10 +167,12 @@ static GtkTextBuffer *text_entry(GtkWidget *box, const char *label, gboolean exp
gtk_box_pack_start(GTK_BOX(box), frame, expand, expand, 0); gtk_box_pack_start(GTK_BOX(box), frame, expand, expand, 0);
GtkWidget* scrolled_window = gtk_scrolled_window_new (0, 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_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(scrolled_window), GTK_SHADOW_IN);
gtk_widget_show(scrolled_window); gtk_widget_show(scrolled_window);
view = gtk_text_view_new (); 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); gtk_container_add(GTK_CONTAINER(scrolled_window), view);
buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (view)); buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (view));
@ -164,14 +181,15 @@ static GtkTextBuffer *text_entry(GtkWidget *box, const char *label, gboolean exp
return buffer; return buffer;
} }
GtkWidget *extended_dive_info_box(void) GtkWidget *extended_dive_info_widget(void)
{ {
GtkWidget *vbox; GtkWidget *vbox;
vbox = gtk_vbox_new(FALSE, 6); vbox = gtk_vbox_new(FALSE, 6);
location = text_entry(vbox, "Location", FALSE); location = text_entry(vbox, "Location");
gtk_container_set_border_width(GTK_CONTAINER(vbox), 6); gtk_container_set_border_width(GTK_CONTAINER(vbox), 6);
notes = text_entry(vbox, "Notes", TRUE); notes = text_view(vbox, "Notes", TRUE);
/* Add extended info here: name, description, yadda yadda */ /* Add extended info here: name, description, yadda yadda */
update_dive_info(current_dive); update_dive_info(current_dive);

36
main.c
View file

@ -175,10 +175,11 @@ int main(int argc, char **argv)
int i; int i;
GtkWidget *win; GtkWidget *win;
GtkWidget *divelist; GtkWidget *divelist;
GtkWidget *table; GtkWidget *paned;
GtkWidget *info_box;
GtkWidget *notebook; GtkWidget *notebook;
GtkWidget *box;
GtkWidget *frame; GtkWidget *frame;
GtkWidget *dive_info;
GtkWidget *menubar; GtkWidget *menubar;
GtkWidget *vbox; GtkWidget *vbox;
@ -208,36 +209,33 @@ int main(int argc, char **argv)
menubar = get_menubar_menu(win); menubar = get_menubar_menu(win);
gtk_box_pack_start(GTK_BOX(vbox), menubar, FALSE, FALSE, 0); gtk_box_pack_start(GTK_BOX(vbox), menubar, FALSE, FALSE, 0);
/* Table for the list of dives, cairo window, and dive info */ /* HPane for left the dive list, and right the dive info */
table = gtk_table_new(2, 2, FALSE); paned = gtk_hpaned_new();
gtk_container_set_border_width(GTK_CONTAINER(table), 5); gtk_box_pack_end(GTK_BOX(vbox), paned, TRUE, TRUE, 0);
gtk_box_pack_end(GTK_BOX(vbox), table, TRUE, TRUE, 0);
gtk_table_set_col_spacings(GTK_TABLE(table), 6);
gtk_widget_show(table);
/* Create the atual divelist */ /* Create the atual divelist */
divelist = create_dive_list(); divelist = create_dive_list();
gtk_table_attach(GTK_TABLE(table), divelist, 0, 1, 0, 2, gtk_paned_add1(GTK_PANED(paned), divelist);
0, GTK_FILL | GTK_SHRINK | GTK_EXPAND, 0, 0);
/* VBox for dive info, and tabs */
info_box = gtk_vbox_new(FALSE, 6);
gtk_paned_add2(GTK_PANED(paned), info_box);
/* Frame for minimal dive info */ /* Frame for minimal dive info */
frame = dive_info_frame(); frame = dive_info_frame();
gtk_table_attach(GTK_TABLE(table), frame, 1, 2, 0, 1, gtk_box_pack_start(GTK_BOX(info_box), frame, FALSE, TRUE, 6);
GTK_FILL | GTK_SHRINK | GTK_EXPAND, 0, 6, 6);
/* Notebook for dive info vs profile vs .. */ /* Notebook for dive info vs profile vs .. */
notebook = gtk_notebook_new(); notebook = gtk_notebook_new();
gtk_table_attach(GTK_TABLE(table), notebook, 1, 2, 1, 2, gtk_box_pack_start(GTK_BOX(info_box), notebook, TRUE, TRUE, 6);
GTK_FILL | GTK_EXPAND, GTK_FILL | GTK_EXPAND, 6, 6);
/* Frame for dive profile */ /* Frame for dive profile */
frame = dive_profile_frame(); dive_profile = dive_profile_widget();
gtk_notebook_append_page(GTK_NOTEBOOK(notebook), frame, gtk_label_new("Dive Profile")); gtk_notebook_append_page(GTK_NOTEBOOK(notebook), dive_profile, gtk_label_new("Dive Profile"));
dive_profile = frame;
/* Frame for extended dive info */ /* Frame for extended dive info */
box = extended_dive_info_box(); dive_info = extended_dive_info_widget();
gtk_notebook_append_page(GTK_NOTEBOOK(notebook), box, gtk_label_new("Extended Dive Info")); gtk_notebook_append_page(GTK_NOTEBOOK(notebook), dive_info, gtk_label_new("Extended Dive Info"));
gtk_widget_set_app_paintable(win, TRUE); gtk_widget_set_app_paintable(win, TRUE);
gtk_widget_show_all(win); gtk_widget_show_all(win);

View file

@ -683,28 +683,6 @@ static void dive_start(void)
memset(&tm, 0, sizeof(tm)); 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 "
"(%d ft, %d min)",
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);
p = malloc(len+1);
if (!p)
exit(1);
memcpy(p, buffer, len+1);
return p;
}
static void sanitize_gasmix(gasmix_t *mix) static void sanitize_gasmix(gasmix_t *mix)
{ {
unsigned int o2, he; unsigned int o2, he;
@ -772,8 +750,6 @@ static void dive_end(void)
{ {
if (!dive) if (!dive)
return; return;
if (!dive->name)
dive->name = generate_name(dive);
sanitize_cylinder_info(dive); sanitize_cylinder_info(dive);
record_dive(dive); record_dive(dive);
dive = NULL; dive = NULL;

View file

@ -195,17 +195,13 @@ static gboolean expose_event(GtkWidget *widget, GdkEventExpose *event, gpointer
return FALSE; return FALSE;
} }
GtkWidget *dive_profile_frame(void) GtkWidget *dive_profile_widget(void)
{ {
GtkWidget *frame;
GtkWidget *da; GtkWidget *da;
frame = gtk_frame_new("Dive Profile");
gtk_widget_show(frame);
da = gtk_drawing_area_new(); da = gtk_drawing_area_new();
gtk_widget_set_size_request(da, 450, 350); gtk_widget_set_size_request(da, 450, 350);
g_signal_connect(da, "expose_event", G_CALLBACK(expose_event), NULL); g_signal_connect(da, "expose_event", G_CALLBACK(expose_event), NULL);
gtk_container_add(GTK_CONTAINER(frame), da);
return frame; return da;
} }

View file

@ -127,7 +127,6 @@ static void save_cylinder_info(FILE *f, struct dive *dive)
for (i = 0; i < MAX_CYLINDERS; i++) { for (i = 0; i < MAX_CYLINDERS; i++) {
cylinder_t *cylinder = dive->cylinder+i; cylinder_t *cylinder = dive->cylinder+i;
int volume = cylinder->type.size.mliter; int volume = cylinder->type.size.mliter;
int pressure = cylinder->type.workingpressure.mbar;
int o2 = cylinder->gasmix.o2.permille; int o2 = cylinder->gasmix.o2.permille;
int he = cylinder->gasmix.he.permille; int he = cylinder->gasmix.he.permille;
@ -140,11 +139,8 @@ static void save_cylinder_info(FILE *f, struct dive *dive)
if (he) if (he)
fprintf(f, " he='%u.%u%%'", FRACTION(he, 10)); fprintf(f, " he='%u.%u%%'", FRACTION(he, 10));
} }
if (volume) { if (volume)
fprintf(f, " size='%u.%03u l'", FRACTION(volume, 1000)); fprintf(f, " size='%u.%03u l'", FRACTION(volume, 1000));
if (pressure)
fprintf(f, " workpressure='%u.%03u bar'", FRACTION(pressure, 1000));
}
fprintf(f, " />\n"); fprintf(f, " />\n");
} }
} }
@ -193,4 +189,5 @@ void save_dives(const char *filename)
for (i = 0; i < dive_table.nr; i++) for (i = 0; i < dive_table.nr; i++)
save_dive(f, get_dive(i)); save_dive(f, get_dive(i));
fprintf(f, "</dives>\n"); fprintf(f, "</dives>\n");
fclose(f);
} }