| 
									
										
										
										
											2017-04-27 20:25:32 +02:00
										 |  |  | // SPDX-License-Identifier: GPL-2.0
 | 
					
						
							| 
									
										
										
										
											2016-04-04 22:02:03 -07:00
										 |  |  | #include "qt-models/yearlystatisticsmodel.h"
 | 
					
						
							| 
									
										
										
										
											2018-06-03 22:15:19 +02:00
										 |  |  | #include "core/qthelper.h"
 | 
					
						
							| 
									
										
										
										
											2016-04-04 22:02:03 -07:00
										 |  |  | #include "core/metrics.h"
 | 
					
						
							|  |  |  | #include "core/statistics.h"
 | 
					
						
							| 
									
										
										
										
											2019-06-27 07:42:09 +02:00
										 |  |  | #include "core/dive.h" // For NUM_DIVEMODE
 | 
					
						
							| 
									
										
										
										
											2015-05-28 18:12:11 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | class YearStatisticsItem : public TreeItem { | 
					
						
							| 
									
										
										
										
											2018-09-14 12:25:00 -07:00
										 |  |  | 	Q_DECLARE_TR_FUNCTIONS(YearStatisticsItem) | 
					
						
							| 
									
										
										
										
											2015-05-28 18:12:11 -03:00
										 |  |  | public: | 
					
						
							|  |  |  | 	enum { | 
					
						
							|  |  |  | 		YEAR, | 
					
						
							|  |  |  | 		DIVES, | 
					
						
							|  |  |  | 		TOTAL_TIME, | 
					
						
							|  |  |  | 		AVERAGE_TIME, | 
					
						
							|  |  |  | 		SHORTEST_TIME, | 
					
						
							|  |  |  | 		LONGEST_TIME, | 
					
						
							|  |  |  | 		AVG_DEPTH, | 
					
						
							| 
									
										
										
										
											2018-12-16 20:52:34 +01:00
										 |  |  | 		AVG_MAX_DEPTH, | 
					
						
							| 
									
										
										
										
											2015-05-28 18:12:11 -03:00
										 |  |  | 		MIN_DEPTH, | 
					
						
							|  |  |  | 		MAX_DEPTH, | 
					
						
							|  |  |  | 		AVG_SAC, | 
					
						
							|  |  |  | 		MIN_SAC, | 
					
						
							|  |  |  | 		MAX_SAC, | 
					
						
							|  |  |  | 		AVG_TEMP, | 
					
						
							|  |  |  | 		MIN_TEMP, | 
					
						
							|  |  |  | 		MAX_TEMP, | 
					
						
							|  |  |  | 		COLUMNS | 
					
						
							|  |  |  | 	}; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	QVariant data(int column, int role) const; | 
					
						
							| 
									
										
										
										
											2019-03-19 20:09:33 +01:00
										 |  |  | 	YearStatisticsItem(const stats_t &interval); | 
					
						
							| 
									
										
										
										
											2015-05-28 18:12:11 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | private: | 
					
						
							|  |  |  | 	stats_t stats_interval; | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-19 20:09:33 +01:00
										 |  |  | YearStatisticsItem::YearStatisticsItem(const stats_t &interval) : stats_interval(interval) | 
					
						
							| 
									
										
										
										
											2015-05-28 18:12:11 -03:00
										 |  |  | { | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | QVariant YearStatisticsItem::data(int column, int role) const | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	QVariant ret; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (role == Qt::FontRole) { | 
					
						
							|  |  |  | 		QFont font = defaultModelFont(); | 
					
						
							|  |  |  | 		font.setBold(stats_interval.is_year); | 
					
						
							|  |  |  | 		return font; | 
					
						
							|  |  |  | 	} else if (role != Qt::DisplayRole) { | 
					
						
							|  |  |  | 		return ret; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	switch (column) { | 
					
						
							|  |  |  | 	case YEAR: | 
					
						
							|  |  |  | 		if (stats_interval.is_trip) { | 
					
						
							|  |  |  | 			ret = stats_interval.location; | 
					
						
							|  |  |  | 		} else { | 
					
						
							|  |  |  | 			ret = stats_interval.period; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		break; | 
					
						
							|  |  |  | 	case DIVES: | 
					
						
							|  |  |  | 		ret = stats_interval.selection_size; | 
					
						
							|  |  |  | 		break; | 
					
						
							|  |  |  | 	case TOTAL_TIME: | 
					
						
							| 
									
										
										
										
											2017-05-11 22:43:36 +02:00
										 |  |  | 		ret = get_dive_duration_string(stats_interval.total_time.seconds, tr("h"), tr("min"), tr("sec"), " "); | 
					
						
							| 
									
										
										
										
											2015-05-28 18:12:11 -03:00
										 |  |  | 		break; | 
					
						
							|  |  |  | 	case AVERAGE_TIME: | 
					
						
							|  |  |  | 		ret = get_minutes(stats_interval.total_time.seconds / stats_interval.selection_size); | 
					
						
							|  |  |  | 		break; | 
					
						
							|  |  |  | 	case SHORTEST_TIME: | 
					
						
							|  |  |  | 		ret = get_minutes(stats_interval.shortest_time.seconds); | 
					
						
							|  |  |  | 		break; | 
					
						
							|  |  |  | 	case LONGEST_TIME: | 
					
						
							|  |  |  | 		ret = get_minutes(stats_interval.longest_time.seconds); | 
					
						
							|  |  |  | 		break; | 
					
						
							|  |  |  | 	case AVG_DEPTH: | 
					
						
							|  |  |  | 		ret = get_depth_string(stats_interval.avg_depth); | 
					
						
							|  |  |  | 		break; | 
					
						
							| 
									
										
										
										
											2018-12-16 20:52:34 +01:00
										 |  |  | 	case AVG_MAX_DEPTH: | 
					
						
							|  |  |  | 		if (stats_interval.selection_size) | 
					
						
							|  |  |  | 			ret = get_depth_string(stats_interval.combined_max_depth.mm / stats_interval.selection_size); | 
					
						
							|  |  |  | 		break; | 
					
						
							| 
									
										
										
										
											2015-05-28 18:12:11 -03:00
										 |  |  | 	case MIN_DEPTH: | 
					
						
							|  |  |  | 		ret = get_depth_string(stats_interval.min_depth); | 
					
						
							|  |  |  | 		break; | 
					
						
							|  |  |  | 	case MAX_DEPTH: | 
					
						
							|  |  |  | 		ret = get_depth_string(stats_interval.max_depth); | 
					
						
							|  |  |  | 		break; | 
					
						
							|  |  |  | 	case AVG_SAC: | 
					
						
							|  |  |  | 		ret = get_volume_string(stats_interval.avg_sac); | 
					
						
							|  |  |  | 		break; | 
					
						
							|  |  |  | 	case MIN_SAC: | 
					
						
							|  |  |  | 		ret = get_volume_string(stats_interval.min_sac); | 
					
						
							|  |  |  | 		break; | 
					
						
							|  |  |  | 	case MAX_SAC: | 
					
						
							|  |  |  | 		ret = get_volume_string(stats_interval.max_sac); | 
					
						
							|  |  |  | 		break; | 
					
						
							|  |  |  | 	case AVG_TEMP: | 
					
						
							| 
									
										
										
										
											2018-02-18 21:55:57 +01:00
										 |  |  | 		if (stats_interval.combined_temp.mkelvin && stats_interval.combined_count) { | 
					
						
							|  |  |  | 			temperature_t avg_temp; | 
					
						
							|  |  |  | 			avg_temp.mkelvin = stats_interval.combined_temp.mkelvin / stats_interval.combined_count; | 
					
						
							|  |  |  | 			ret = get_temperature_string(avg_temp); | 
					
						
							| 
									
										
										
										
											2015-05-28 18:12:11 -03:00
										 |  |  | 		} | 
					
						
							|  |  |  | 		break; | 
					
						
							|  |  |  | 	case MIN_TEMP: | 
					
						
							| 
									
										
										
										
											2018-02-18 21:55:57 +01:00
										 |  |  | 		if (stats_interval.min_temp.mkelvin) | 
					
						
							|  |  |  | 			ret = get_temperature_string(stats_interval.min_temp); | 
					
						
							| 
									
										
										
										
											2015-05-28 18:12:11 -03:00
										 |  |  | 		break; | 
					
						
							|  |  |  | 	case MAX_TEMP: | 
					
						
							| 
									
										
										
										
											2018-02-18 21:55:57 +01:00
										 |  |  | 		if (stats_interval.max_temp.mkelvin) | 
					
						
							|  |  |  | 			ret = get_temperature_string(stats_interval.max_temp); | 
					
						
							| 
									
										
										
										
											2015-05-28 18:12:11 -03:00
										 |  |  | 		break; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return ret; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-03-07 03:43:20 -03:00
										 |  |  | YearlyStatisticsModel::YearlyStatisticsModel(QObject *parent) : TreeModel(parent) | 
					
						
							| 
									
										
										
										
											2015-05-28 18:12:11 -03:00
										 |  |  | { | 
					
						
							|  |  |  | 	columns = COLUMNS; | 
					
						
							|  |  |  | 	update_yearly_stats(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | QVariant YearlyStatisticsModel::headerData(int section, Qt::Orientation orientation, int role) const | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	QVariant val; | 
					
						
							|  |  |  | 	if (role == Qt::FontRole) | 
					
						
							|  |  |  | 		val = defaultModelFont(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (role == Qt::DisplayRole && orientation == Qt::Horizontal) { | 
					
						
							|  |  |  | 		switch (section) { | 
					
						
							|  |  |  | 		case YEAR: | 
					
						
							|  |  |  | 			val = tr("Year \n > Month / Trip"); | 
					
						
							|  |  |  | 			break; | 
					
						
							|  |  |  | 		case DIVES: | 
					
						
							|  |  |  | 			val = tr("#"); | 
					
						
							|  |  |  | 			break; | 
					
						
							|  |  |  | 		case TOTAL_TIME: | 
					
						
							|  |  |  | 			val = tr("Duration \n Total"); | 
					
						
							|  |  |  | 			break; | 
					
						
							|  |  |  | 		case AVERAGE_TIME: | 
					
						
							|  |  |  | 			val = tr("\nAverage"); | 
					
						
							|  |  |  | 			break; | 
					
						
							|  |  |  | 		case SHORTEST_TIME: | 
					
						
							|  |  |  | 			val = tr("\nShortest"); | 
					
						
							|  |  |  | 			break; | 
					
						
							|  |  |  | 		case LONGEST_TIME: | 
					
						
							|  |  |  | 			val = tr("\nLongest"); | 
					
						
							|  |  |  | 			break; | 
					
						
							|  |  |  | 		case AVG_DEPTH: | 
					
						
							|  |  |  | 			val = QString(tr("Depth (%1)\n Average")).arg(get_depth_unit()); | 
					
						
							|  |  |  | 			break; | 
					
						
							| 
									
										
										
										
											2018-12-16 20:52:34 +01:00
										 |  |  | 		case AVG_MAX_DEPTH: | 
					
						
							|  |  |  | 			val = tr("\nAverage maximum"); | 
					
						
							|  |  |  | 			break; | 
					
						
							| 
									
										
										
										
											2015-05-28 18:12:11 -03:00
										 |  |  | 		case MIN_DEPTH: | 
					
						
							|  |  |  | 			val = tr("\nMinimum"); | 
					
						
							|  |  |  | 			break; | 
					
						
							|  |  |  | 		case MAX_DEPTH: | 
					
						
							|  |  |  | 			val = tr("\nMaximum"); | 
					
						
							|  |  |  | 			break; | 
					
						
							|  |  |  | 		case AVG_SAC: | 
					
						
							|  |  |  | 			val = QString(tr("SAC (%1)\n Average")).arg(get_volume_unit()); | 
					
						
							|  |  |  | 			break; | 
					
						
							|  |  |  | 		case MIN_SAC: | 
					
						
							|  |  |  | 			val = tr("\nMinimum"); | 
					
						
							|  |  |  | 			break; | 
					
						
							|  |  |  | 		case MAX_SAC: | 
					
						
							|  |  |  | 			val = tr("\nMaximum"); | 
					
						
							|  |  |  | 			break; | 
					
						
							|  |  |  | 		case AVG_TEMP: | 
					
						
							|  |  |  | 			val = QString(tr("Temp. (%1)\n Average").arg(get_temp_unit())); | 
					
						
							|  |  |  | 			break; | 
					
						
							|  |  |  | 		case MIN_TEMP: | 
					
						
							|  |  |  | 			val = tr("\nMinimum"); | 
					
						
							|  |  |  | 			break; | 
					
						
							|  |  |  | 		case MAX_TEMP: | 
					
						
							|  |  |  | 			val = tr("\nMaximum"); | 
					
						
							|  |  |  | 			break; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return val; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void YearlyStatisticsModel::update_yearly_stats() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	int i, month = 0; | 
					
						
							|  |  |  | 	unsigned int j, combined_months; | 
					
						
							| 
									
										
										
										
											2018-10-06 10:58:12 +02:00
										 |  |  | 	stats_summary_auto_free stats; | 
					
						
							| 
									
										
										
										
											2019-03-09 18:27:51 -08:00
										 |  |  | 	QString label; | 
					
						
							|  |  |  | 	temperature_t t_range_min,t_range_max; | 
					
						
							| 
									
										
										
										
											2018-10-06 16:50:46 +02:00
										 |  |  | 	calculate_stats_summary(&stats, false); | 
					
						
							| 
									
										
										
										
											2015-05-28 18:12:11 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-10-06 10:58:12 +02:00
										 |  |  | 	for (i = 0; stats.stats_yearly != NULL && stats.stats_yearly[i].period; ++i) { | 
					
						
							| 
									
										
										
										
											2019-03-19 20:09:33 +01:00
										 |  |  | 		YearStatisticsItem *item = new YearStatisticsItem(stats.stats_yearly[i]); | 
					
						
							| 
									
										
										
										
											2015-05-28 18:12:11 -03:00
										 |  |  | 		combined_months = 0; | 
					
						
							| 
									
										
										
										
											2018-10-06 10:58:12 +02:00
										 |  |  | 		for (j = 0; combined_months < stats.stats_yearly[i].selection_size; ++j) { | 
					
						
							|  |  |  | 			combined_months += stats.stats_monthly[month].selection_size; | 
					
						
							| 
									
										
										
										
											2019-03-19 20:09:33 +01:00
										 |  |  | 			YearStatisticsItem *iChild = new YearStatisticsItem(stats.stats_monthly[month]); | 
					
						
							| 
									
										
										
										
											2015-05-28 18:12:11 -03:00
										 |  |  | 			item->children.append(iChild); | 
					
						
							|  |  |  | 			iChild->parent = item; | 
					
						
							|  |  |  | 			month++; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		rootItem->children.append(item); | 
					
						
							| 
									
										
										
										
											2018-07-25 21:23:19 +02:00
										 |  |  | 		item->parent = rootItem.get(); | 
					
						
							| 
									
										
										
										
											2015-05-28 18:12:11 -03:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-10-06 10:58:12 +02:00
										 |  |  | 	if (stats.stats_by_trip != NULL && stats.stats_by_trip[0].is_trip == true) { | 
					
						
							| 
									
										
										
										
											2019-03-19 20:09:33 +01:00
										 |  |  | 		YearStatisticsItem *item = new YearStatisticsItem(stats.stats_by_trip[0]); | 
					
						
							| 
									
										
										
										
											2018-10-06 10:58:12 +02:00
										 |  |  | 		for (i = 1; stats.stats_by_trip != NULL && stats.stats_by_trip[i].is_trip; ++i) { | 
					
						
							| 
									
										
										
										
											2019-03-19 20:09:33 +01:00
										 |  |  | 			YearStatisticsItem *iChild = new YearStatisticsItem(stats.stats_by_trip[i]); | 
					
						
							| 
									
										
										
										
											2015-05-28 18:12:11 -03:00
										 |  |  | 			item->children.append(iChild); | 
					
						
							|  |  |  | 			iChild->parent = item; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		rootItem->children.append(item); | 
					
						
							| 
									
										
										
										
											2018-07-25 21:23:19 +02:00
										 |  |  | 		item->parent = rootItem.get(); | 
					
						
							| 
									
										
										
										
											2015-05-28 18:12:11 -03:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2016-01-17 21:18:36 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	/* Show the statistic sorted by dive type */ | 
					
						
							| 
									
										
										
										
											2018-10-06 10:58:12 +02:00
										 |  |  | 	if (stats.stats_by_type != NULL && stats.stats_by_type[0].selection_size) { | 
					
						
							| 
									
										
										
										
											2019-03-19 20:09:33 +01:00
										 |  |  | 		YearStatisticsItem *item = new YearStatisticsItem(stats.stats_by_type[0]); | 
					
						
							| 
									
										
										
										
											2018-05-08 16:24:51 +02:00
										 |  |  | 		for (i = 1; i <= NUM_DIVEMODE; ++i) { | 
					
						
							| 
									
										
										
										
											2018-10-06 10:58:12 +02:00
										 |  |  | 			if (stats.stats_by_type[i].selection_size == 0) | 
					
						
							| 
									
										
										
										
											2016-01-17 21:18:36 +02:00
										 |  |  | 				continue; | 
					
						
							| 
									
										
										
										
											2019-03-19 20:09:33 +01:00
										 |  |  | 			YearStatisticsItem *iChild = new YearStatisticsItem(stats.stats_by_type[i]); | 
					
						
							| 
									
										
										
										
											2016-01-17 21:18:36 +02:00
										 |  |  | 			item->children.append(iChild); | 
					
						
							|  |  |  | 			iChild->parent = item; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		rootItem->children.append(item); | 
					
						
							| 
									
										
										
										
											2018-07-25 21:23:19 +02:00
										 |  |  | 		item->parent = rootItem.get(); | 
					
						
							| 
									
										
										
										
											2016-01-17 21:18:36 +02:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2019-03-09 18:27:51 -08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	/* Show the statistic sorted by dive depth */ | 
					
						
							|  |  |  | 	if (stats.stats_by_depth != NULL && stats.stats_by_depth[0].selection_size) { | 
					
						
							| 
									
										
										
										
											2019-03-19 20:09:33 +01:00
										 |  |  | 		YearStatisticsItem *item = new YearStatisticsItem(stats.stats_by_depth[0]); | 
					
						
							| 
									
										
										
										
											2019-03-09 18:27:51 -08:00
										 |  |  | 		for (i = 1; stats.stats_by_depth[i].is_trip; ++i) | 
					
						
							|  |  |  | 			if (stats.stats_by_depth[i].selection_size) { | 
					
						
							|  |  |  | 				label = QString(tr("%1 - %2")).arg(get_depth_string((i - 1) * (STATS_DEPTH_BUCKET * 1000), true, false), | 
					
						
							|  |  |  | 					get_depth_string(i * (STATS_DEPTH_BUCKET * 1000), true, false)); | 
					
						
							|  |  |  | 				stats.stats_by_depth[i].location = strdup(label.toUtf8().data()); | 
					
						
							| 
									
										
										
										
											2019-03-19 20:09:33 +01:00
										 |  |  | 				YearStatisticsItem *iChild = new YearStatisticsItem(stats.stats_by_depth[i]); | 
					
						
							| 
									
										
										
										
											2019-03-09 18:27:51 -08:00
										 |  |  | 				item->children.append(iChild); | 
					
						
							|  |  |  | 				iChild->parent = item; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		rootItem->children.append(item); | 
					
						
							|  |  |  | 		item->parent = rootItem.get(); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* Show the statistic sorted by dive temperature */ | 
					
						
							|  |  |  | 	if (stats.stats_by_temp != NULL && stats.stats_by_temp[0].selection_size) { | 
					
						
							| 
									
										
										
										
											2019-03-19 20:09:33 +01:00
										 |  |  | 		YearStatisticsItem *item = new YearStatisticsItem(stats.stats_by_temp[0]); | 
					
						
							| 
									
										
										
										
											2019-03-09 18:27:51 -08:00
										 |  |  | 		for (i = 1; stats.stats_by_temp[i].is_trip; ++i) | 
					
						
							|  |  |  | 			if (stats.stats_by_temp[i].selection_size) { | 
					
						
							|  |  |  | 				t_range_min.mkelvin = C_to_mkelvin((i - 1) * STATS_TEMP_BUCKET); | 
					
						
							|  |  |  | 				t_range_max.mkelvin = C_to_mkelvin(i * STATS_TEMP_BUCKET); | 
					
						
							|  |  |  | 				label = QString(tr("%1 - %2")).arg(get_temperature_string(t_range_min, true), | 
					
						
							|  |  |  | 					get_temperature_string(t_range_max, true)); | 
					
						
							|  |  |  | 				stats.stats_by_temp[i].location = strdup(label.toUtf8().data()); | 
					
						
							| 
									
										
										
										
											2019-03-19 20:09:33 +01:00
										 |  |  | 				YearStatisticsItem *iChild = new YearStatisticsItem(stats.stats_by_temp[i]); | 
					
						
							| 
									
										
										
										
											2019-03-09 18:27:51 -08:00
										 |  |  | 				item->children.append(iChild); | 
					
						
							|  |  |  | 				iChild->parent = item; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		rootItem->children.append(item); | 
					
						
							|  |  |  | 		item->parent = rootItem.get(); | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2015-05-28 18:12:11 -03:00
										 |  |  | } |