[PATCH] Show statistics of selected dives

Miika Turkia miika.turkia at gmail.com
Fri Mar 16 01:15:24 PDT 2012


The dive.h looked way too scary to be touched at all...

If the process_selected_dives function is to be included in the dive.h
then gtk/gtk.h must be also included. This means that GTK2CFLAGS must
be included for compilation of all object files that use dive.h. If
this is ok I can easily change it..

miika

On Thu, Mar 15, 2012 at 7:45 PM, Dirk Hohndel <dirk at hohndel.org> wrote:
>
> MUCH better. My only question is "why do we need the new .h file for
> just that one function?"
> We have other functions in dive.h. So either put process_selected_dives
> in there as well - or put them ALL into statistics.h
>
> I guess I could have fixed that up myself, couldn't I? :-)
>
> /D
>
>
> On Wed, 14 Mar 2012 19:01:34 +0200, Miika Turkia <miika.turkia at gmail.com> wrote:
>> If at least 2 dives are selected, show statistics of these dives on
>> Overall Stats. Otherwise, show the statistics of all dives. Temperature
>> is also added to the shown statistics.
>>
>> Signed-off-by: Miika Turkia <miika.turkia at gmail.com>
>> ---
>>  Makefile     |    4 +-
>>  divelist.c   |    5 ++
>>  statistics.c |  144 ++++++++++++++++++++++++++++++++++++++++++++--------------
>>  statistics.h |    6 ++
>>  4 files changed, 122 insertions(+), 37 deletions(-)
>>  create mode 100644 statistics.h
>>
>> diff --git a/Makefile b/Makefile
>> index 20dff4c..19fccfc 100644
>> --- a/Makefile
>> +++ b/Makefile
>> @@ -179,10 +179,10 @@ info.o: info.c dive.h display.h display-gtk.h divelist.h
>>  equipment.o: equipment.c dive.h display.h divelist.h
>>       $(CC) $(CFLAGS) $(GTK2CFLAGS) $(GLIB2CFLAGS) $(XML2CFLAGS) -c equipment.c
>>
>> -statistics.o: statistics.c dive.h display.h divelist.h
>> +statistics.o: statistics.c dive.h display.h divelist.h statistics.h
>>       $(CC) $(CFLAGS) $(GTK2CFLAGS) $(GLIB2CFLAGS) $(XML2CFLAGS) -c statistics.c
>>
>> -divelist.o: divelist.c dive.h display.h divelist.h
>> +divelist.o: divelist.c dive.h display.h divelist.h statistics.h
>>       $(CC) $(CFLAGS) $(GTK2CFLAGS) $(GLIB2CFLAGS) $(XML2CFLAGS) -c divelist.c
>>
>>  print.o: print.c dive.h display.h display-gtk.h
>> diff --git a/divelist.c b/divelist.c
>> index b9388f8..2083cf4 100644
>> --- a/divelist.c
>> +++ b/divelist.c
>> @@ -20,6 +20,7 @@
>>  #include "dive.h"
>>  #include "display.h"
>>  #include "display-gtk.h"
>> +#include "statistics.h"
>>
>>  struct DiveList {
>>       GtkWidget    *tree_view;
>> @@ -73,6 +74,7 @@ static void selection_cb(GtkTreeSelection *selection, GtkTreeModel *model)
>>               return;
>>       case 1:
>>               /* just pick that dive as selected */
>> +             amount_selected = 1;
>>               path = g_list_nth_data(selected_dives, 0);
>>               if (gtk_tree_model_get_iter(model, &iter, path)) {
>>                       gtk_tree_model_get_value(model, &iter, DIVE_INDEX, &value);
>> @@ -86,6 +88,9 @@ static void selection_cb(GtkTreeSelection *selection, GtkTreeModel *model)
>>                 * is the most intuitive solution.
>>                 * I do however want to keep around which dives have
>>                 * been selected */
>> +             amount_selected = g_list_length(selected_dives);
>> +             process_selected_dives(selected_dives, model);
>> +             repaint_dive();
>>               return;
>>       }
>>  }
>> diff --git a/statistics.c b/statistics.c
>> index 2669d53..9277aa5 100644
>> --- a/statistics.c
>> +++ b/statistics.c
>> @@ -18,6 +18,7 @@
>>  #include "display.h"
>>  #include "display-gtk.h"
>>  #include "divelist.h"
>> +#include "statistics.h"
>>
>>  typedef struct {
>>       GtkWidget *date,
>> @@ -44,7 +45,11 @@ typedef struct {
>>               *avg_overall_depth,
>>               *min_sac,
>>               *avg_sac,
>> -             *max_sac;
>> +             *max_sac,
>> +             *selection_size,
>> +             *max_temp,
>> +             *avg_temp,
>> +             *min_temp;
>>  } total_stats_widget_t;
>>
>>  static total_stats_widget_t stats_w;
>> @@ -60,21 +65,65 @@ typedef struct {
>>       volume_t max_sac;
>>       volume_t min_sac;
>>       volume_t avg_sac;
>> +     int max_temp;
>> +     int min_temp;
>> +     unsigned int combined_temp;
>> +     unsigned int combined_count;
>> +     unsigned int selection_size;
>>  } stats_t;
>>
>>  static stats_t stats;
>> +static stats_t stats_selection;
>> +
>> +
>> +static void process_dive(struct dive *dp, stats_t *stats)
>> +{
>> +     int old_tt, sac_time = 0;
>> +     const char *unit;
>> +
>> +     old_tt = stats->total_time.seconds;
>> +     stats->total_time.seconds += dp->duration.seconds;
>> +     if (dp->duration.seconds > stats->longest_time.seconds)
>> +             stats->longest_time.seconds = dp->duration.seconds;
>> +     if (stats->shortest_time.seconds == 0 || dp->duration.seconds < stats->shortest_time.seconds)
>> +             stats->shortest_time.seconds = dp->duration.seconds;
>> +     if (dp->maxdepth.mm > stats->max_depth.mm)
>> +             stats->max_depth.mm = dp->maxdepth.mm;
>> +     if (stats->min_depth.mm == 0 || dp->maxdepth.mm < stats->min_depth.mm)
>> +             stats->min_depth.mm = dp->maxdepth.mm;
>> +     stats->avg_depth.mm = (1.0 * old_tt * stats->avg_depth.mm +
>> +                     dp->duration.seconds * dp->meandepth.mm) / stats->total_time.seconds;
>> +     if (dp->sac > 2800) { /* less than .1 cuft/min (2800ml/min) is bogus */
>> +             int old_sac_time = sac_time;
>> +             sac_time += dp->duration.seconds;
>> +             stats->avg_sac.mliter = (1.0 * old_sac_time * stats->avg_sac.mliter +
>> +                             dp->duration.seconds * dp->sac) / sac_time ;
>> +             if (dp->sac > stats->max_sac.mliter)
>> +                     stats->max_sac.mliter = dp->sac;
>> +             if (stats->min_sac.mliter == 0 || dp->sac < stats->min_sac.mliter)
>> +                     stats->min_sac.mliter = dp->sac;
>> +     }
>> +     if (dp->watertemp.mkelvin) {
>> +             if (stats->min_temp == 0 || dp->watertemp.mkelvin < stats->min_temp)
>> +                     stats->min_temp = dp->watertemp.mkelvin;
>> +             if (dp->watertemp.mkelvin > stats->max_temp)
>> +                     stats->max_temp = dp->watertemp.mkelvin;
>> +             stats->combined_temp += get_temp_units(dp->watertemp.mkelvin, &unit);
>> +             stats->combined_count++;
>> +     }
>> +}
>>
>>  static void process_all_dives(struct dive *dive, struct dive **prev_dive)
>>  {
>>       int idx;
>>       struct dive *dp;
>> -     int old_tt, sac_time = 0;
>>
>>       *prev_dive = NULL;
>>       memset(&stats, 0, sizeof(stats));
>>       if (dive_table.nr > 0) {
>>               stats.shortest_time.seconds = dive_table.dives[0]->duration.seconds;
>>               stats.min_depth.mm = dive_table.dives[0]->maxdepth.mm;
>> +             stats.selection_size = dive_table.nr;
>>       }
>>       /* this relies on the fact that the dives in the dive_table
>>        * are in chronological order */
>> @@ -85,28 +134,28 @@ static void process_all_dives(struct dive *dive, struct dive **prev_dive)
>>                       if (idx > 0)
>>                               *prev_dive = dive_table.dives[idx-1];
>>               }
>> -             old_tt = stats.total_time.seconds;
>> -             stats.total_time.seconds += dp->duration.seconds;
>> -             if (dp->duration.seconds > stats.longest_time.seconds)
>> -                     stats.longest_time.seconds = dp->duration.seconds;
>> -             if (dp->duration.seconds < stats.shortest_time.seconds)
>> -                     stats.shortest_time.seconds = dp->duration.seconds;
>> -             if (dp->maxdepth.mm > stats.max_depth.mm)
>> -                     stats.max_depth.mm = dp->maxdepth.mm;
>> -             if (dp->maxdepth.mm < stats.min_depth.mm)
>> -                     stats.min_depth.mm = dp->maxdepth.mm;
>> -             stats.avg_depth.mm = (1.0 * old_tt * stats.avg_depth.mm +
>> -                             dp->duration.seconds * dp->meandepth.mm) / stats.total_time.seconds;
>> -             if (dp->sac > 2800) { /* less than .1 cuft/min (2800ml/min) is bogus */
>> -                     int old_sac_time = sac_time;
>> -                     sac_time += dp->duration.seconds;
>> -                     stats.avg_sac.mliter = (1.0 * old_sac_time * stats.avg_sac.mliter +
>> -                                             dp->duration.seconds * dp->sac) / sac_time ;
>> -                     if (dp->sac > stats.max_sac.mliter)
>> -                             stats.max_sac.mliter = dp->sac;
>> -                     if (stats.min_sac.mliter == 0 || dp->sac < stats.min_sac.mliter)
>> -                             stats.min_sac.mliter = dp->sac;
>> +             process_dive(dp, &stats);
>> +     }
>> +}
>> +
>> +void process_selected_dives(GList *selected_dives, GtkTreeModel *model)
>> +{
>> +     struct dive *dp;
>> +     unsigned int i;
>> +     GtkTreeIter iter;
>> +     GtkTreePath *path;
>> +
>> +     memset(&stats_selection, 0, sizeof(stats_selection));
>> +     stats_selection.selection_size = amount_selected;
>> +
>> +     for (i = 0; i < amount_selected; ++i) {
>> +             GValue value = {0, };
>> +             path = g_list_nth_data(selected_dives, i);
>> +             if (gtk_tree_model_get_iter(model, &iter, path)) {
>> +                     gtk_tree_model_get_value(model, &iter, 0, &value);
>> +                     dp = get_dive(g_value_get_int(&value));
>>               }
>> +             process_dive(dp, &stats_selection);
>>       }
>>  }
>>
>> @@ -219,22 +268,39 @@ static void show_total_dive_stats(struct dive *dive)
>>       double value;
>>       int decimals;
>>       const char *unit;
>> +     stats_t *stats_ptr;
>> +
>> +     if (amount_selected < 2)
>> +             stats_ptr = &stats;
>> +     else
>> +             stats_ptr = &stats_selection;
>>
>> -     set_label(stats_w.total_time, get_time_string(stats.total_time.seconds, 0));
>> -     set_label(stats_w.avg_time, get_time_string(stats.total_time.seconds / dive_table.nr, 0));
>> -     set_label(stats_w.longest_time, get_time_string(stats.longest_time.seconds, 0));
>> -     set_label(stats_w.shortest_time, get_time_string(stats.shortest_time.seconds, 0));
>> -     value = get_depth_units(stats.max_depth.mm, &decimals, &unit);
>> +     set_label(stats_w.selection_size, "%d", stats_ptr->selection_size);
>> +     if (stats_ptr->min_temp) {
>> +             value = get_temp_units(stats_ptr->min_temp, &unit);
>> +             set_label(stats_w.min_temp, "%.1f %s", value, unit);
>> +     }
>> +     if (stats_ptr->combined_temp && stats_ptr->combined_count)
>> +             set_label(stats_w.avg_temp, "%.1f %s", stats_ptr->combined_temp / (stats_ptr->combined_count * 1.0), unit);
>> +     if (stats_ptr->max_temp) {
>> +             value = get_temp_units(stats_ptr->max_temp, &unit);
>> +             set_label(stats_w.max_temp, "%.1f %s", value, unit);
>> +     }
>> +     set_label(stats_w.total_time, get_time_string(stats_ptr->total_time.seconds, 0));
>> +     set_label(stats_w.avg_time, get_time_string(stats_ptr->total_time.seconds / stats_ptr->selection_size, 0));
>> +     set_label(stats_w.longest_time, get_time_string(stats_ptr->longest_time.seconds, 0));
>> +     set_label(stats_w.shortest_time, get_time_string(stats_ptr->shortest_time.seconds, 0));
>> +     value = get_depth_units(stats_ptr->max_depth.mm, &decimals, &unit);
>>       set_label(stats_w.max_overall_depth, "%.*f %s", decimals, value, unit);
>> -     value = get_depth_units(stats.min_depth.mm, &decimals, &unit);
>> +     value = get_depth_units(stats_ptr->min_depth.mm, &decimals, &unit);
>>       set_label(stats_w.min_overall_depth, "%.*f %s", decimals, value, unit);
>> -     value = get_depth_units(stats.avg_depth.mm, &decimals, &unit);
>> +     value = get_depth_units(stats_ptr->avg_depth.mm, &decimals, &unit);
>>       set_label(stats_w.avg_overall_depth, "%.*f %s", decimals, value, unit);
>> -     value = get_volume_units(stats.max_sac.mliter, &decimals, &unit);
>> +     value = get_volume_units(stats_ptr->max_sac.mliter, &decimals, &unit);
>>       set_label(stats_w.max_sac, "%.*f %s/min", decimals, value, unit);
>> -     value = get_volume_units(stats.min_sac.mliter, &decimals, &unit);
>> +     value = get_volume_units(stats_ptr->min_sac.mliter, &decimals, &unit);
>>       set_label(stats_w.min_sac, "%.*f %s/min", decimals, value, unit);
>> -     value = get_volume_units(stats.avg_sac.mliter, &decimals, &unit);
>> +     value = get_volume_units(stats_ptr->avg_sac.mliter, &decimals, &unit);
>>       set_label(stats_w.avg_sac, "%.*f %s/min", decimals, value, unit);
>>  }
>>
>> @@ -278,13 +344,21 @@ GtkWidget *total_stats_widget(void)
>>       /* first row */
>>       hbox = gtk_hbox_new(FALSE, 3);
>>       gtk_box_pack_start(GTK_BOX(framebox), hbox, TRUE, FALSE, 3);
>> +     stats_w.selection_size = new_info_label_in_frame(hbox, "Dives");
>> +     stats_w.max_temp = new_info_label_in_frame(hbox, "Max Temp");
>> +     stats_w.min_temp = new_info_label_in_frame(hbox, "Min Temp");
>> +     stats_w.avg_temp = new_info_label_in_frame(hbox, "Avg Temp");
>> +
>> +     /* second row */
>> +     hbox = gtk_hbox_new(FALSE, 3);
>> +     gtk_box_pack_start(GTK_BOX(framebox), hbox, TRUE, FALSE, 3);
>>
>>       stats_w.total_time = new_info_label_in_frame(hbox, "Total Time");
>>       stats_w.avg_time = new_info_label_in_frame(hbox, "Avg Time");
>>       stats_w.longest_time = new_info_label_in_frame(hbox, "Longest Dive");
>>       stats_w.shortest_time = new_info_label_in_frame(hbox, "Shortest Dive");
>>
>> -     /* second row */
>> +     /* third row */
>>       hbox = gtk_hbox_new(FALSE, 3);
>>       gtk_box_pack_start(GTK_BOX(framebox), hbox, TRUE, FALSE, 3);
>>
>> @@ -292,7 +366,7 @@ GtkWidget *total_stats_widget(void)
>>       stats_w.min_overall_depth = new_info_label_in_frame(hbox, "Min Depth");
>>       stats_w.avg_overall_depth = new_info_label_in_frame(hbox, "Avg Depth");
>>
>> -     /* third row */
>> +     /* fourth row */
>>       hbox = gtk_hbox_new(FALSE, 3);
>>       gtk_box_pack_start(GTK_BOX(framebox), hbox, TRUE, FALSE, 3);
>>
>> diff --git a/statistics.h b/statistics.h
>> new file mode 100644
>> index 0000000..1293224
>> --- /dev/null
>> +++ b/statistics.h
>> @@ -0,0 +1,6 @@
>> +#ifndef STATISTICS_H
>> +#define STATISTICS_H
>> +unsigned int amount_selected;
>> +
>> +extern void process_selected_dives(GList *, GtkTreeModel *);
>> +#endif
>> --
>> 1.7.5.4
>>
>> _______________________________________________
>> subsurface mailing list
>> subsurface at hohndel.org
>> http://lists.hohndel.org/cgi-bin/mailman/listinfo/subsurface
>
> --
> Dirk Hohndel
> Intel Open Source Technology Center


More information about the subsurface mailing list