]> git.tdb.fi Git - ext/subsurface.git/blobdiff - divelist.c
Merge branch 'tree2' of git://git.hohndel.org/subsurface
[ext/subsurface.git] / divelist.c
index 112307a1c28fbc89d7d96f8899b99f0767d7fdfc..a85ac7c5ef3ac05eeb0e7bbe2277ff70c82acdf7 100644 (file)
@@ -26,7 +26,7 @@ struct DiveList {
        GtkWidget    *container_widget;
        GtkTreeStore *model, *listmodel, *treemodel;
        GtkTreeViewColumn *nr, *date, *stars, *depth, *duration, *location;
-       GtkTreeViewColumn *temperature, *cylinder, *nitrox, *sac, *otu;
+       GtkTreeViewColumn *temperature, *cylinder, *totalweight, *suit, *nitrox, *sac, *otu;
        int changed;
 };
 
@@ -44,6 +44,8 @@ enum {
        DIVE_DEPTH,             /* int: dive->maxdepth in mm */
        DIVE_DURATION,          /* int: in seconds */
        DIVE_TEMPERATURE,       /* int: in mkelvin */
+       DIVE_TOTALWEIGHT,       /* int: in grams */
+       DIVE_SUIT,              /* "wet, 3mm" */
        DIVE_CYLINDER,
        DIVE_NITROX,            /* int: dummy */
        DIVE_SAC,               /* int: in ml/min */
@@ -53,10 +55,8 @@ enum {
 };
 
 /* magic numbers that indicate (as negative values) model entries that
- * are summary entries for day / month / year */
-#define NEW_DAY 1
-#define NEW_MON 2
-#define NEW_YR  3
+ * are summary entries for a divetrip */
+#define NEW_TRIP 1
 
 #ifdef DEBUG_MODEL
 static gboolean dump_model_entry(GtkTreeModel *model, GtkTreePath *path,
@@ -240,23 +240,13 @@ static void date_data_func(GtkTreeViewColumn *col,
 
        tm = gmtime(&when);
        switch(idx) {
-       case -NEW_DAY:
+       case -NEW_TRIP:
                snprintf(buffer, sizeof(buffer),
-                       "%s, %s %d, %d",
+                       "Trip %s, %s %d, %d",
                        weekday(tm->tm_wday),
                        monthname(tm->tm_mon),
                        tm->tm_mday, tm->tm_year + 1900);
                break;
-       case -NEW_MON:
-               snprintf(buffer, sizeof(buffer),
-                       "%s %d",
-                       monthname(tm->tm_mon),
-                       tm->tm_year + 1900);
-               break;
-       case -NEW_YR:
-               snprintf(buffer, sizeof(buffer),
-                       "%d", tm->tm_year + 1900);
-               break;
        default:
                snprintf(buffer, sizeof(buffer),
                        "%s, %s %d, %d %02d:%02d",
@@ -416,6 +406,38 @@ newmax:
        *o2low_p = mino2;
 }
 
+static int total_weight(struct dive *dive)
+{
+       int i, total_grams = 0;
+
+       if (dive)
+               for (i=0; i< MAX_WEIGHTSYSTEMS; i++)
+                       total_grams += dive->weightsystem[i].weight.grams;
+       return total_grams;
+}
+
+static void weight_data_func(GtkTreeViewColumn *col,
+                            GtkCellRenderer *renderer,
+                            GtkTreeModel *model,
+                            GtkTreeIter *iter,
+                            gpointer data)
+{
+       int indx, decimals;
+       double value;
+       char buffer[80];
+       struct dive *dive;
+
+       gtk_tree_model_get(model, iter, DIVE_INDEX, &indx, -1);
+       dive = get_dive(indx);
+       value = get_weight_units(total_weight(dive), &decimals, NULL);
+       if (value == 0.0)
+               *buffer = '\0';
+       else
+               snprintf(buffer, sizeof(buffer), "%.*f", decimals, value);
+
+       g_object_set(renderer, "text", buffer, NULL);
+}
+
 static gint nitrox_sort_func(GtkTreeModel *model,
        GtkTreeIter *iter_a,
        GtkTreeIter *iter_b,
@@ -650,6 +672,11 @@ static void get_cylinder(struct dive *dive, char **str)
        get_string(str, dive->cylinder[0].type.description);
 }
 
+static void get_suit(struct dive *dive, char **str)
+{
+       get_string(str, dive->suit);
+}
+
 /*
  * Set up anything that could have changed due to editing
  * of dive information; we need to do this for both models,
@@ -665,11 +692,12 @@ static void fill_one_dive(struct dive *dive,
                          GtkTreeModel *model,
                          GtkTreeIter *iter)
 {
-       char *location, *cylinder;
+       char *location, *cylinder, *suit;
        GtkTreeStore *othermodel;
 
        get_cylinder(dive, &cylinder);
        get_location(dive, &location);
+       get_suit(dive, &suit);
 
        gtk_tree_store_set(GTK_TREE_STORE(model), iter,
                DIVE_NR, dive->number,
@@ -678,7 +706,14 @@ static void fill_one_dive(struct dive *dive,
                DIVE_RATING, dive->rating,
                DIVE_SAC, dive->sac,
                DIVE_OTU, dive->otu,
+               DIVE_TOTALWEIGHT, total_weight(dive),
+               DIVE_SUIT, suit,
                -1);
+
+       free(location);
+       free(cylinder);
+       free(suit);
+
        if (model == GTK_TREE_MODEL(dive_list.treemodel))
                othermodel = dive_list.listmodel;
        else
@@ -735,6 +770,9 @@ void update_dive_list_units(void)
        (void) get_temp_units(0, &unit);
        gtk_tree_view_column_set_title(dive_list.temperature, unit);
 
+       (void) get_weight_units(0, NULL, &unit);
+       gtk_tree_view_column_set_title(dive_list.totalweight, unit);
+
        gtk_tree_model_foreach(model, set_one_dive, NULL);
 }
 
@@ -742,28 +780,28 @@ void update_dive_list_col_visibility(void)
 {
        gtk_tree_view_column_set_visible(dive_list.cylinder, visible_cols.cylinder);
        gtk_tree_view_column_set_visible(dive_list.temperature, visible_cols.temperature);
+       gtk_tree_view_column_set_visible(dive_list.totalweight, visible_cols.totalweight);
+       gtk_tree_view_column_set_visible(dive_list.suit, visible_cols.suit);
        gtk_tree_view_column_set_visible(dive_list.nitrox, visible_cols.nitrox);
        gtk_tree_view_column_set_visible(dive_list.sac, visible_cols.sac);
        gtk_tree_view_column_set_visible(dive_list.otu, visible_cols.otu);
        return;
 }
 
-static int new_date(struct dive *dive, struct dive **last_dive, const int flag, time_t *tm_date)
+/* random heuristic - not diving in three days implies new dive trip */
+#define TRIP_THRESHOLD 3600*24*3
+static int new_group(struct dive *dive, struct dive **last_dive, time_t *tm_date)
 {
        if (!last_dive)
                return TRUE;
        if (*last_dive) {
                struct dive *ldive = *last_dive;
-               struct tm tm1, tm2;
-               (void) gmtime_r(&dive->when, &tm1);
-               (void) gmtime_r(&ldive->when, &tm2);
-               if (tm1.tm_year == tm2.tm_year &&
-                       (tm1.tm_mon == tm2.tm_mon || flag > NEW_MON) &&
-                       (tm1.tm_mday == tm2.tm_mday || flag > NEW_DAY))
+               if (abs(dive->when - ldive->when) < TRIP_THRESHOLD) {
+                       *last_dive = dive;
                        return FALSE;
+               }
        }
-       if (flag == NEW_DAY)
-               *last_dive = dive;
+       *last_dive = dive;
        if (tm_date) {
                struct tm *tm1 = gmtime(&dive->when);
                tm1->tm_sec = 0;
@@ -776,10 +814,12 @@ static int new_date(struct dive *dive, struct dive **last_dive, const int flag,
 
 static void fill_dive_list(void)
 {
-       int i, j;
-       GtkTreeIter iter, parent_iter[NEW_YR + 2], *parents[NEW_YR + 2] = {NULL, };
+       int i;
+       GtkTreeIter iter, parent_iter;
        GtkTreeStore *liststore, *treestore;
        struct dive *last_dive = NULL;
+       struct dive *first_trip_dive = NULL;
+       struct dive *last_trip_dive = NULL;
        time_t dive_date;
 
        treestore = GTK_TREE_STORE(dive_list.treemodel);
@@ -789,23 +829,29 @@ static void fill_dive_list(void)
        while (--i >= 0) {
                struct dive *dive = dive_table.dives[i];
 
-               for (j = NEW_YR; j >= NEW_DAY; j--) {
-                       if (new_date(dive, &last_dive, j, &dive_date))
-                       {
-                               gtk_tree_store_append(treestore, &parent_iter[j], parents[j+1]);
-                               parents[j] = &parent_iter[j];
-                               gtk_tree_store_set(treestore, parents[j],
-                                               DIVE_INDEX, -j,
-                                               DIVE_NR, -j,
-                                               DIVE_DATE, dive_date,
-                                               DIVE_LOCATION, "",
-                                               DIVE_TEMPERATURE, 0,
-                                               DIVE_SAC, 0,
+               if (new_group(dive, &last_dive, &dive_date))
+               {
+                       /* make sure we display the first date of the trip in previous summary */
+                       if (first_trip_dive && last_trip_dive && last_trip_dive->when < first_trip_dive->when)
+                               gtk_tree_store_set(treestore, &parent_iter,
+                                               DIVE_DATE, last_trip_dive->when,
+                                               DIVE_LOCATION, last_trip_dive->location,
                                                -1);
-                       }
+                       first_trip_dive = dive;
+
+                       gtk_tree_store_append(treestore, &parent_iter, NULL);
+                       gtk_tree_store_set(treestore, &parent_iter,
+                                       DIVE_INDEX, -NEW_TRIP,
+                                       DIVE_NR, -NEW_TRIP,
+                                       DIVE_DATE, dive_date,
+                                       DIVE_LOCATION, dive->location,
+                                       DIVE_TEMPERATURE, 0,
+                                       DIVE_SAC, 0,
+                                       -1);
                }
+               last_trip_dive = dive;
                update_cylinder_related_info(dive);
-               gtk_tree_store_append(treestore, &iter, parents[NEW_DAY]);
+               gtk_tree_store_append(treestore, &iter, &parent_iter);
                gtk_tree_store_set(treestore, &iter,
                        DIVE_INDEX, i,
                        DIVE_NR, dive->number,
@@ -827,6 +873,8 @@ static void fill_dive_list(void)
                        DIVE_LOCATION, dive->location,
                        DIVE_RATING, dive->rating,
                        DIVE_TEMPERATURE, dive->watertemp.mkelvin,
+                       DIVE_TOTALWEIGHT, 0,
+                       DIVE_SUIT, dive->suit,
                        DIVE_SAC, 0,
                        -1);
        }
@@ -866,6 +914,8 @@ static struct divelist_column {
        [DIVE_DEPTH] = { "ft", depth_data_func, NULL, ALIGN_RIGHT },
        [DIVE_DURATION] = { "min", duration_data_func, NULL, ALIGN_RIGHT },
        [DIVE_TEMPERATURE] = { UTF8_DEGREE "F", temperature_data_func, NULL, ALIGN_RIGHT, &visible_cols.temperature },
+       [DIVE_TOTALWEIGHT] = { "lbs", weight_data_func, NULL, ALIGN_RIGHT, &visible_cols.totalweight },
+       [DIVE_SUIT] = { "Suit", NULL, NULL, ALIGN_LEFT, &visible_cols.suit },
        [DIVE_CYLINDER] = { "Cyl", NULL, NULL, 0, &visible_cols.cylinder },
        [DIVE_NITROX] = { "O" UTF8_SUBSCRIPT_2 "%", nitrox_data_func, nitrox_sort_func, 0, &visible_cols.nitrox },
        [DIVE_SAC] = { "SAC", sac_data_func, NULL, 0, &visible_cols.sac },
@@ -938,14 +988,27 @@ void add_dive_cb(GtkWidget *menuitem, gpointer data)
        free(dive);
 }
 
+void edit_dive_cb(GtkWidget *menuitem, gpointer data)
+{
+       edit_multi_dive_info(amount_selected, selectiontracker);
+}
+
 static void popup_divelist_menu(GtkTreeView *tree_view, GtkTreeModel *model, int button)
 {
        GtkWidget *menu, *menuitem;
+       char editlabel[] = "Edit dives";
 
        menu = gtk_menu_new();
        menuitem = gtk_menu_item_new_with_label("Add dive");
        g_signal_connect(menuitem, "activate", G_CALLBACK(add_dive_cb), NULL);
        gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem);
+       if (amount_selected) {
+               if (amount_selected == 1)
+                       editlabel[strlen(editlabel) - 1] = '\0';
+               menuitem = gtk_menu_item_new_with_label(editlabel);
+               g_signal_connect(menuitem, "activate", G_CALLBACK(edit_dive_cb), model);
+               gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem);
+       }
        gtk_widget_show_all(menu);
 
        gtk_menu_popup(GTK_MENU(menu), NULL, NULL, NULL, NULL,
@@ -1080,6 +1143,8 @@ GtkWidget *dive_list_create(void)
                                G_TYPE_INT,                     /* Depth */
                                G_TYPE_INT,                     /* Duration */
                                G_TYPE_INT,                     /* Temperature */
+                               G_TYPE_INT,                     /* Total weight */
+                               G_TYPE_STRING,                  /* Suit */
                                G_TYPE_STRING,                  /* Cylinder */
                                G_TYPE_INT,                     /* Nitrox */
                                G_TYPE_INT,                     /* SAC */
@@ -1094,6 +1159,8 @@ GtkWidget *dive_list_create(void)
                                G_TYPE_INT,                     /* Depth */
                                G_TYPE_INT,                     /* Duration */
                                G_TYPE_INT,                     /* Temperature */
+                               G_TYPE_INT,                     /* Total weight */
+                               G_TYPE_STRING,                  /* Suit */
                                G_TYPE_STRING,                  /* Cylinder */
                                G_TYPE_INT,                     /* Nitrox */
                                G_TYPE_INT,                     /* SAC */
@@ -1115,6 +1182,8 @@ GtkWidget *dive_list_create(void)
        dive_list.depth = divelist_column(&dive_list, dl_column + DIVE_DEPTH);
        dive_list.duration = divelist_column(&dive_list, dl_column + DIVE_DURATION);
        dive_list.temperature = divelist_column(&dive_list, dl_column + DIVE_TEMPERATURE);
+       dive_list.totalweight = divelist_column(&dive_list, dl_column + DIVE_TOTALWEIGHT);
+       dive_list.suit = divelist_column(&dive_list, dl_column + DIVE_SUIT);
        dive_list.cylinder = divelist_column(&dive_list, dl_column + DIVE_CYLINDER);
        dive_list.nitrox = divelist_column(&dive_list, dl_column + DIVE_NITROX);
        dive_list.sac = divelist_column(&dive_list, dl_column + DIVE_SAC);