mirror of
				https://github.com/subsurface/subsurface.git
				synced 2025-02-19 22:16:15 +00:00 
			
		
		
		
	core: convert weightsystem_t and weightsystem_table to C++
As for cylinders, this had to be done simultaneously, Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
This commit is contained in:
		
							parent
							
								
									28520da655
								
							
						
					
					
						commit
						640ecb345b
					
				
					 28 changed files with 137 additions and 247 deletions
				
			
		|  | @ -13,6 +13,7 @@ | |||
| #include "core/divesite.h" | ||||
| #include "core/picture.h" | ||||
| #include "core/pref.h" | ||||
| #include "core/range.h" | ||||
| #include "core/sample.h" | ||||
| #include "core/selection.h" | ||||
| #include "core/taxonomy.h" | ||||
|  | @ -155,11 +156,6 @@ void export_TeX(const char *filename, bool selected_only, bool plain, ExportCall | |||
| 		QString viz = star.repeated(dive->visibility); | ||||
| 		QString rating = star.repeated(dive->rating); | ||||
| 
 | ||||
| 		int i; | ||||
| 		int qty_cyl; | ||||
| 		int qty_weight; | ||||
| 		double total_weight; | ||||
| 
 | ||||
| 		if (need_pagebreak) { | ||||
| 			if (plain) | ||||
| 				put_format(&buf, "\\vfill\\eject\n"); | ||||
|  | @ -204,7 +200,7 @@ void export_TeX(const char *filename, bool selected_only, bool plain, ExportCall | |||
| 
 | ||||
| 		// Print cylinder data
 | ||||
| 		put_format(&buf, "\n%% Gas use information:\n"); | ||||
| 		qty_cyl = 0; | ||||
| 		int qty_cyl = 0; | ||||
| 		for (int i = 0; i < static_cast<int>(dive->cylinders.size()); i++){ | ||||
| 			const cylinder_t &cyl = dive->cylinders[i]; | ||||
| 			if (is_cylinder_used(dive, i) || (prefs.include_unused_tanks && !cyl.type.description.empty())){ | ||||
|  | @ -235,11 +231,10 @@ void export_TeX(const char *filename, bool selected_only, bool plain, ExportCall | |||
| 
 | ||||
| 		//Code block prints all weights listed in dive.
 | ||||
| 		put_format(&buf, "\n%% Weighting information:\n"); | ||||
| 		qty_weight = 0; | ||||
| 		total_weight = 0; | ||||
| 		for (i = 0; i < dive->weightsystems.nr; i++) { | ||||
| 			weightsystem_t w = dive->weightsystems.weightsystems[i]; | ||||
| 			put_format(&buf, "\\def\\%sweight%ctype{%s}\n", ssrf, 'a' + i, w.description); | ||||
| 		int qty_weight = 0; | ||||
| 		double total_weight = 0; | ||||
| 		for (auto [i, w]: enumerated_range(dive->weightsystems)) { | ||||
| 			put_format(&buf, "\\def\\%sweight%ctype{%s}\n", ssrf, 'a' + i, w.description.c_str()); | ||||
| 			put_format(&buf, "\\def\\%sweight%camt{%.3f\\%sweightunit}\n", ssrf, 'a' + i, get_weight_units(w.weight.grams, NULL, &unit), ssrf); | ||||
| 			qty_weight += 1; | ||||
| 			total_weight += get_weight_units(w.weight.grams, NULL, &unit); | ||||
|  |  | |||
|  | @ -6,6 +6,7 @@ | |||
| #include "core/event.h" | ||||
| #include "core/fulltext.h" | ||||
| #include "core/qthelper.h" // for copy_qstring
 | ||||
| #include "core/range.h" | ||||
| #include "core/sample.h" | ||||
| #include "core/selection.h" | ||||
| #include "core/subsurface-string.h" | ||||
|  | @ -629,7 +630,6 @@ static void swapCandQString(QString &q, char *&c) | |||
| PasteState::PasteState(dive *dIn, const dive *data, dive_components what) : d(dIn), | ||||
| 	tags(nullptr) | ||||
| { | ||||
| 	memset(&weightsystems, 0, sizeof(weightsystems)); | ||||
| 	if (what.notes) | ||||
| 		notes = data->notes; | ||||
| 	if (what.diveguide) | ||||
|  | @ -686,7 +686,7 @@ PasteState::PasteState(dive *dIn, const dive *data, dive_components what) : d(dI | |||
| 		} | ||||
| 	} | ||||
| 	if (what.weights) | ||||
| 		copy_weights(&data->weightsystems, &weightsystems); | ||||
| 		weightsystems = data->weightsystems; | ||||
| 	if (what.number) | ||||
| 		number = data->number; | ||||
| 	if (what.when) | ||||
|  | @ -696,8 +696,6 @@ PasteState::PasteState(dive *dIn, const dive *data, dive_components what) : d(dI | |||
| PasteState::~PasteState() | ||||
| { | ||||
| 	taglist_free(tags); | ||||
| 	clear_weightsystem_table(&weightsystems); | ||||
| 	free(weightsystems.weightsystems); | ||||
| } | ||||
| 
 | ||||
| void PasteState::swap(dive_components what) | ||||
|  | @ -952,10 +950,10 @@ bool AddWeight::workToBeDone() | |||
| void AddWeight::undo() | ||||
| { | ||||
| 	for (dive *d: dives) { | ||||
| 		if (d->weightsystems.nr <= 0) | ||||
| 		if (d->weightsystems.empty()) | ||||
| 			continue; | ||||
| 		remove_weightsystem(d, d->weightsystems.nr - 1); | ||||
| 		emit diveListNotifier.weightRemoved(d, d->weightsystems.nr); | ||||
| 		d->weightsystems.pop_back(); | ||||
| 		emit diveListNotifier.weightRemoved(d, d->weightsystems.size()); | ||||
| 		invalidate_dive_cache(d); // Ensure that dive is written in git_save()
 | ||||
| 	} | ||||
| } | ||||
|  | @ -963,31 +961,26 @@ void AddWeight::undo() | |||
| void AddWeight::redo() | ||||
| { | ||||
| 	for (dive *d: dives) { | ||||
| 		add_cloned_weightsystem(&d->weightsystems, empty_weightsystem); | ||||
| 		emit diveListNotifier.weightAdded(d, d->weightsystems.nr - 1); | ||||
| 		d->weightsystems.emplace_back(); | ||||
| 		emit diveListNotifier.weightAdded(d, d->weightsystems.size() - 1); | ||||
| 		invalidate_dive_cache(d); // Ensure that dive is written in git_save()
 | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| static int find_weightsystem_index(const struct dive *d, weightsystem_t ws) | ||||
| static int find_weightsystem_index(const struct dive *d, const weightsystem_t &ws) | ||||
| { | ||||
| 	for (int idx = 0; idx < d->weightsystems.nr; ++idx) { | ||||
| 		if (same_weightsystem(d->weightsystems.weightsystems[idx], ws)) | ||||
| 			return idx; | ||||
| 	} | ||||
| 	return -1; | ||||
| 	return index_of_if(d->weightsystems, [&ws](auto &ws2) { return same_weightsystem(ws2, ws); }); | ||||
| } | ||||
| 
 | ||||
| EditWeightBase::EditWeightBase(int index, bool currentDiveOnly) : | ||||
| 	EditDivesBase(currentDiveOnly), | ||||
| 	ws(empty_weightsystem) | ||||
| 	EditDivesBase(currentDiveOnly) | ||||
| { | ||||
| 	// Get the old weightsystem, bail if index is invalid
 | ||||
| 	if (!current || index < 0 || index >= current->weightsystems.nr) { | ||||
| 	if (!current || index < 0 || static_cast<size_t>(index) >= current->weightsystems.size()) { | ||||
| 		dives.clear(); | ||||
| 		return; | ||||
| 	} | ||||
| 	ws = clone_weightsystem(current->weightsystems.weightsystems[index]); | ||||
| 	ws = current->weightsystems[index]; | ||||
| 
 | ||||
| 	// Deleting a weightsystem from multiple dives is semantically ill-defined.
 | ||||
| 	// What we will do is trying to delete the same weightsystem if it exists.
 | ||||
|  | @ -1013,7 +1006,6 @@ EditWeightBase::EditWeightBase(int index, bool currentDiveOnly) : | |||
| 
 | ||||
| EditWeightBase::~EditWeightBase() | ||||
| { | ||||
| 	free_weightsystem(ws); | ||||
| } | ||||
| 
 | ||||
| bool EditWeightBase::workToBeDone() | ||||
|  | @ -1035,7 +1027,7 @@ RemoveWeight::RemoveWeight(int index, bool currentDiveOnly) : | |||
| void RemoveWeight::undo() | ||||
| { | ||||
| 	for (size_t i = 0; i < dives.size(); ++i) { | ||||
| 		add_to_weightsystem_table(&dives[i]->weightsystems, indices[i], clone_weightsystem(ws)); | ||||
| 		add_to_weightsystem_table(&dives[i]->weightsystems, indices[i], ws); | ||||
| 		emit diveListNotifier.weightAdded(dives[i], indices[i]); | ||||
| 		invalidate_dive_cache(dives[i]); // Ensure that dive is written in git_save()
 | ||||
| 	} | ||||
|  | @ -1052,8 +1044,7 @@ void RemoveWeight::redo() | |||
| 
 | ||||
| // ***** Edit Weight *****
 | ||||
| EditWeight::EditWeight(int index, weightsystem_t wsIn, bool currentDiveOnly) : | ||||
| 	EditWeightBase(index, currentDiveOnly), | ||||
| 	new_ws(empty_weightsystem) | ||||
| 	EditWeightBase(index, currentDiveOnly) | ||||
| { | ||||
| 	if (dives.empty()) | ||||
| 		return; | ||||
|  | @ -1065,15 +1056,13 @@ EditWeight::EditWeight(int index, weightsystem_t wsIn, bool currentDiveOnly) : | |||
| 		setText(QStringLiteral("%1 [%2]").arg(Command::Base::tr("Edit weight (%n dive(s))", "", num_dives)).arg(getListOfDives(dives))); | ||||
| 
 | ||||
| 	// Try to untranslate the weightsystem name
 | ||||
| 	new_ws = clone_weightsystem(wsIn); | ||||
| 	QString vString(new_ws.description); | ||||
| 	new_ws = std::move(wsIn); | ||||
| 	QString vString = QString::fromStdString(new_ws.description); | ||||
| 	auto it = std::find_if(ws_info_table.begin(), ws_info_table.end(), | ||||
| 			       [&vString](const ws_info &info) | ||||
| 			       { return gettextFromC::tr(info.name.c_str()) == vString; }); | ||||
| 	if (it != ws_info_table.end()) { | ||||
| 		free_weightsystem(new_ws); | ||||
| 		new_ws.description = strdup(it->name.c_str()); | ||||
| 	} | ||||
| 	if (it != ws_info_table.end()) | ||||
| 		new_ws.description = it->name; | ||||
| 
 | ||||
| 	// If that doesn't change anything, do nothing
 | ||||
| 	if (same_weightsystem(ws, new_ws)) { | ||||
|  | @ -1084,7 +1073,6 @@ EditWeight::EditWeight(int index, weightsystem_t wsIn, bool currentDiveOnly) : | |||
| 
 | ||||
| EditWeight::~EditWeight() | ||||
| { | ||||
| 	free_weightsystem(new_ws); | ||||
| } | ||||
| 
 | ||||
| void EditWeight::redo() | ||||
|  |  | |||
|  | @ -300,8 +300,8 @@ struct PasteState { | |||
| 	int surge; | ||||
| 	int chill; | ||||
| 	tag_entry *tags; | ||||
| 	struct cylinder_table cylinders; | ||||
| 	struct weightsystem_table weightsystems; | ||||
| 	cylinder_table cylinders; | ||||
| 	weightsystem_table weightsystems; | ||||
| 	int number; | ||||
| 	timestamp_t when; | ||||
| 
 | ||||
|  |  | |||
|  | @ -631,7 +631,7 @@ static void wlog_compl_parser(std::string &wl_mem, struct dive *dt_dive, int dco | |||
| 	tmp = (int) two_bytes_to_int(runner[pos_weight + 1], runner[pos_weight]); | ||||
| 	if (tmp != 0x7fff) { | ||||
| 		weightsystem_t ws = { {tmp * 10}, QT_TRANSLATE_NOOP("gettextFromC", "unknown"), false }; | ||||
| 		add_cloned_weightsystem(&dt_dive->weightsystems, ws); | ||||
| 		dt_dive->weightsystems.push_back(std::move(ws)); | ||||
| 	} | ||||
| 
 | ||||
| 	/*
 | ||||
|  |  | |||
|  | @ -176,8 +176,7 @@ static void free_dive_structures(struct dive *d) | |||
| 	/* free tags, additional dive computers, and pictures */ | ||||
| 	taglist_free(d->tag_list); | ||||
| 	d->cylinders.clear(); | ||||
| 	clear_weightsystem_table(&d->weightsystems); | ||||
| 	free(d->weightsystems.weightsystems); | ||||
| 	d->weightsystems.clear(); | ||||
| 	clear_picture_table(&d->pictures); | ||||
| 	free(d->pictures.pictures); | ||||
| } | ||||
|  | @ -204,7 +203,6 @@ void copy_dive(const struct dive *s, struct dive *d) | |||
| 	 * relevant components that are referenced through pointers, | ||||
| 	 * so all the strings and the structured lists */ | ||||
| 	*d = *s; | ||||
| 	memset(&d->weightsystems, 0, sizeof(d->weightsystems)); | ||||
| 	memset(&d->pictures, 0, sizeof(d->pictures)); | ||||
| 	d->full_text = NULL; | ||||
| 	invalidate_dive_cache(d); | ||||
|  | @ -212,7 +210,6 @@ void copy_dive(const struct dive *s, struct dive *d) | |||
| 	d->diveguide = copy_string(s->diveguide); | ||||
| 	d->notes = copy_string(s->notes); | ||||
| 	d->suit = copy_string(s->suit); | ||||
| 	copy_weights(&s->weightsystems, &d->weightsystems); | ||||
| 	copy_pictures(&s->pictures, &d->pictures); | ||||
| 	d->tag_list = taglist_copy(s->tag_list); | ||||
| } | ||||
|  | @ -260,7 +257,7 @@ void selective_copy_dive(const struct dive *s, struct dive *d, struct dive_compo | |||
| 	if (what.cylinders) | ||||
| 		copy_cylinder_types(s, d); | ||||
| 	if (what.weights) | ||||
| 		copy_weights(&s->weightsystems, &d->weightsystems); | ||||
| 		d->weightsystems = s->weightsystems; | ||||
| 	if (what.number) | ||||
| 		d->number = s->number; | ||||
| 	if (what.when) | ||||
|  | @ -289,11 +286,6 @@ void copy_events_until(const struct dive *sd, struct dive *dd, int dcNr, int tim | |||
| 	} | ||||
| } | ||||
| 
 | ||||
| int nr_weightsystems(const struct dive *dive) | ||||
| { | ||||
| 	return dive->weightsystems.nr; | ||||
| } | ||||
| 
 | ||||
| void copy_used_cylinders(const struct dive *s, struct dive *d, bool used_only) | ||||
| { | ||||
| 	if (!s || !d) | ||||
|  | @ -1116,8 +1108,6 @@ static void fixup_dive_dc(struct dive *dive, struct divecomputer &dc) | |||
| 
 | ||||
| struct dive *fixup_dive(struct dive *dive) | ||||
| { | ||||
| 	int i; | ||||
| 
 | ||||
| 	sanitize_cylinder_info(dive); | ||||
| 	dive->maxcns = dive->cns; | ||||
| 
 | ||||
|  | @ -1146,10 +1136,8 @@ struct dive *fixup_dive(struct dive *dive) | |||
| 			cyl.end.mbar = 0; | ||||
| 	} | ||||
| 	update_cylinder_related_info(dive); | ||||
| 	for (i = 0; i < dive->weightsystems.nr; i++) { | ||||
| 		const weightsystem_t &ws = dive->weightsystems.weightsystems[i]; | ||||
| 	for (auto &ws: dive->weightsystems) | ||||
| 		add_weightsystem_description(ws); | ||||
| 	} | ||||
| 	/* we should always have a uniq ID as that gets assigned during dive creation,
 | ||||
| 	 * but we want to make sure... */ | ||||
| 	if (!dive->id) | ||||
|  | @ -1769,26 +1757,20 @@ static void merge_cylinders(struct dive *res, const struct dive *a, const struct | |||
| } | ||||
| 
 | ||||
| /* Check whether a weightsystem table contains a given weightsystem */ | ||||
| static bool has_weightsystem(const struct weightsystem_table *t, const weightsystem_t w) | ||||
| static bool has_weightsystem(const weightsystem_table &t, const weightsystem_t &w) | ||||
| { | ||||
| 	int i; | ||||
| 	for (i = 0; i < t->nr; i++) { | ||||
| 		if (same_weightsystem(w, t->weightsystems[i])) | ||||
| 			return true; | ||||
| 	} | ||||
| 	return false; | ||||
| 	return any_of(t.begin(), t.end(), [&w] (auto &w2) { return same_weightsystem(w, w2); }); | ||||
| } | ||||
| 
 | ||||
| static void merge_equipment(struct dive *res, const struct dive *a, const struct dive *b) | ||||
| { | ||||
| 	int i; | ||||
| 	for (i = 0; i < a->weightsystems.nr; i++) { | ||||
| 		if (!has_weightsystem(&res->weightsystems, a->weightsystems.weightsystems[i])) | ||||
| 			add_cloned_weightsystem(&res->weightsystems, a->weightsystems.weightsystems[i]); | ||||
| 	for (auto &ws: a->weightsystems) { | ||||
| 		if (!has_weightsystem(res->weightsystems, ws)) | ||||
| 			res->weightsystems.push_back(ws); | ||||
| 	} | ||||
| 	for (i = 0; i < b->weightsystems.nr; i++) { | ||||
| 		if (!has_weightsystem(&res->weightsystems, b->weightsystems.weightsystems[i])) | ||||
| 			add_cloned_weightsystem(&res->weightsystems, b->weightsystems.weightsystems[i]); | ||||
| 	for (auto &ws: b->weightsystems) { | ||||
| 		if (!has_weightsystem(res->weightsystems, ws)) | ||||
| 			res->weightsystems.push_back(ws); | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
|  |  | |||
|  | @ -6,7 +6,7 @@ | |||
| 
 | ||||
| #include "divemode.h" | ||||
| #include "divecomputer.h" | ||||
| #include "equipment.h" // TODO: remove | ||||
| #include "equipment.h" | ||||
| #include "picture.h" // TODO: remove | ||||
| 
 | ||||
| #include <string> | ||||
|  | @ -30,8 +30,8 @@ struct dive { | |||
| 	struct dive_site *dive_site = nullptr; | ||||
| 	char *notes = nullptr; | ||||
| 	char *diveguide = nullptr, *buddy = nullptr; | ||||
| 	struct cylinder_table cylinders; | ||||
| 	struct weightsystem_table weightsystems = { }; | ||||
| 	cylinder_table cylinders; | ||||
| 	weightsystem_table weightsystems; | ||||
| 	char *suit = nullptr; | ||||
| 	int number = 0; | ||||
| 	int rating = 0; | ||||
|  | @ -190,7 +190,6 @@ extern struct event create_gas_switch_event(struct dive *dive, struct divecomput | |||
| extern void per_cylinder_mean_depth(const struct dive *dive, struct divecomputer *dc, int *mean, int *duration); | ||||
| extern int get_cylinder_index(const struct dive *dive, const struct event &ev); | ||||
| extern struct gasmix get_gasmix_from_event(const struct dive *, const struct event &ev); | ||||
| extern int nr_weightsystems(const struct dive *dive); | ||||
| extern bool cylinder_with_sensor_sample(const struct dive *dive, int cylinder_id); | ||||
| 
 | ||||
| /* UI related protopypes */ | ||||
|  |  | |||
|  | @ -64,11 +64,12 @@ void get_dive_gas(const struct dive *dive, int *o2_p, int *he_p, int *o2max_p) | |||
| 
 | ||||
| int total_weight(const struct dive *dive) | ||||
| { | ||||
| 	int i, total_grams = 0; | ||||
| 	int total_grams = 0; | ||||
| 
 | ||||
| 	if (dive) | ||||
| 		for (i = 0; i < dive->weightsystems.nr; i++) | ||||
| 			total_grams += dive->weightsystems.weightsystems[i].weight.grams; | ||||
| 	if (dive) { | ||||
| 		for (auto &ws: dive->weightsystems) | ||||
| 			total_grams += ws.weight.grams; | ||||
| 	} | ||||
| 	return total_grams; | ||||
| } | ||||
| 
 | ||||
|  |  | |||
|  | @ -20,7 +20,6 @@ | |||
| #include "pref.h" | ||||
| #include "range.h" | ||||
| #include "subsurface-string.h" | ||||
| #include "table.h" | ||||
| 
 | ||||
| cylinder_t::cylinder_t() = default; | ||||
| cylinder_t::~cylinder_t() = default; | ||||
|  | @ -55,33 +54,13 @@ const cylinder_t &cylinder_table::operator[](size_t i) const | |||
| 			  : surface_air_cylinder; | ||||
| } | ||||
| 
 | ||||
| /* Warning: this has strange semantics for C-code! Not the weightsystem object
 | ||||
|  * is freed, but the data it references. The object itself is passed in by value. | ||||
|  * This is due to the fact how the table macros work. | ||||
|  */ | ||||
| void free_weightsystem(weightsystem_t ws) | ||||
| weightsystem_t::weightsystem_t() = default; | ||||
| weightsystem_t::~weightsystem_t() = default; | ||||
| weightsystem_t::weightsystem_t(weight_t w, std::string desc, bool auto_filled) | ||||
| 	: weight(w), description(std::move(desc)), auto_filled(auto_filled) | ||||
| { | ||||
| 	free((void *)ws.description); | ||||
| 	ws.description = NULL; | ||||
| } | ||||
| 
 | ||||
| void copy_weights(const struct weightsystem_table *s, struct weightsystem_table *d) | ||||
| { | ||||
| 	clear_weightsystem_table(d); | ||||
| 	for (int i = 0; i < s->nr; i++) | ||||
| 		add_cloned_weightsystem(d, s->weightsystems[i]); | ||||
| } | ||||
| 
 | ||||
| /* weightsystem table functions */ | ||||
| //static MAKE_GET_IDX(weightsystem_table, weightsystem_t, weightsystems)
 | ||||
| static MAKE_GROW_TABLE(weightsystem_table, weightsystem_t, weightsystems) | ||||
| //static MAKE_GET_INSERTION_INDEX(weightsystem_table, weightsystem_t, weightsystems, weightsystem_less_than)
 | ||||
| MAKE_ADD_TO(weightsystem_table, weightsystem_t, weightsystems) | ||||
| static MAKE_REMOVE_FROM(weightsystem_table, weightsystems) | ||||
| //MAKE_SORT(weightsystem_table, weightsystem_t, weightsystems, comp_weightsystems)
 | ||||
| //MAKE_REMOVE(weightsystem_table, weightsystem_t, weightsystem)
 | ||||
| MAKE_CLEAR_TABLE(weightsystem_table, weightsystems, weightsystem) | ||||
| 
 | ||||
| const char *cylinderuse_text[NUM_GAS_USE] = { | ||||
| 	QT_TRANSLATE_NOOP("gettextFromC", "OC-gas"), QT_TRANSLATE_NOOP("gettextFromC", "diluent"), QT_TRANSLATE_NOOP("gettextFromC", "oxygen"), QT_TRANSLATE_NOOP("gettextFromC", "not used") | ||||
| }; | ||||
|  | @ -166,7 +145,7 @@ void add_cylinder_description(const cylinder_type_t &type) | |||
| 
 | ||||
| void add_weightsystem_description(const weightsystem_t &weightsystem) | ||||
| { | ||||
| 	if (empty_string(weightsystem.description)) | ||||
| 	if (weightsystem.description.empty()) | ||||
| 		return; | ||||
| 
 | ||||
| 	auto it = std::find_if(ws_info_table.begin(), ws_info_table.end(), | ||||
|  | @ -188,26 +167,6 @@ weight_t get_weightsystem_weight(const std::string &name) | |||
| 	return it != ws_info_table.end() ? it->weight : weight_t(); | ||||
| } | ||||
| 
 | ||||
| weightsystem_t clone_weightsystem(weightsystem_t ws) | ||||
| { | ||||
| 	weightsystem_t res = { ws.weight, copy_string(ws.description), ws.auto_filled }; | ||||
| 	return res; | ||||
| } | ||||
| 
 | ||||
| /* Add a clone of a weightsystem to the end of a weightsystem table.
 | ||||
|  * Cloned means that the description-string is copied. */ | ||||
| void add_cloned_weightsystem(struct weightsystem_table *t, weightsystem_t ws) | ||||
| { | ||||
| 	add_to_weightsystem_table(t, t->nr, clone_weightsystem(ws)); | ||||
| } | ||||
| 
 | ||||
| /* Add a clone of a weightsystem to the end of a weightsystem table.
 | ||||
|  * Cloned means that the description-string is copied. */ | ||||
| void add_cloned_weightsystem_at(struct weightsystem_table *t, weightsystem_t ws) | ||||
| { | ||||
| 	add_to_weightsystem_table(t, t->nr, clone_weightsystem(ws)); | ||||
| } | ||||
| 
 | ||||
| void add_cylinder(struct cylinder_table *t, int idx, cylinder_t cyl) | ||||
| { | ||||
| 	t->insert(t->begin() + idx, std::move(cyl)); | ||||
|  | @ -216,7 +175,7 @@ void add_cylinder(struct cylinder_table *t, int idx, cylinder_t cyl) | |||
| bool same_weightsystem(weightsystem_t w1, weightsystem_t w2) | ||||
| { | ||||
| 	return w1.weight.grams == w2.weight.grams && | ||||
| 	       same_string(w1.description, w2.description); | ||||
| 	       w1.description == w2.description; | ||||
| } | ||||
| 
 | ||||
| void get_gas_string(struct gasmix gasmix, char *text, int len) | ||||
|  | @ -351,16 +310,20 @@ void remove_cylinder(struct dive *dive, int idx) | |||
| 
 | ||||
| void remove_weightsystem(struct dive *dive, int idx) | ||||
| { | ||||
| 	remove_from_weightsystem_table(&dive->weightsystems, idx); | ||||
| 	dive->weightsystems.erase(dive->weightsystems.begin() + idx); | ||||
| } | ||||
| 
 | ||||
| void add_to_weightsystem_table(weightsystem_table *table, int idx, weightsystem_t ws) | ||||
| { | ||||
| 	idx = std::clamp(idx, 0, static_cast<int>(table->size())); | ||||
| 	table->insert(table->begin() + idx, std::move(ws)); | ||||
| } | ||||
| 
 | ||||
| // ws is cloned.
 | ||||
| void set_weightsystem(struct dive *dive, int idx, weightsystem_t ws) | ||||
| { | ||||
| 	if (idx < 0 || idx >= dive->weightsystems.nr) | ||||
| 	if (idx < 0 || static_cast<size_t>(idx) >= dive->weightsystems.size()) | ||||
| 		return; | ||||
| 	free_weightsystem(dive->weightsystems.weightsystems[idx]); | ||||
| 	dive->weightsystems.weightsystems[idx] = clone_weightsystem(ws); | ||||
| 	dive->weightsystems[idx] = std::move(ws); | ||||
| } | ||||
| 
 | ||||
| /* when planning a dive we need to make sure that all cylinders have a sane depth assigned
 | ||||
|  |  | |||
|  | @ -54,30 +54,22 @@ struct cylinder_table : public std::vector<cylinder_t> { | |||
| struct weightsystem_t | ||||
| { | ||||
| 	weight_t weight; | ||||
| 	const char *description; /* "integrated", "belt", "ankle" */ | ||||
| 	bool auto_filled; /* weight was automatically derived from the type */ | ||||
| }; | ||||
| 	std::string description; /* "integrated", "belt", "ankle" */ | ||||
| 	bool auto_filled = false; /* weight was automatically derived from the type */ | ||||
| 
 | ||||
| static const weightsystem_t empty_weightsystem = { { 0 }, 0, false }; | ||||
| 	weightsystem_t(); | ||||
| 	weightsystem_t(weight_t w, std::string desc, bool auto_filled); | ||||
| 	~weightsystem_t(); | ||||
| }; | ||||
| 
 | ||||
| /* Table of weightsystems. Attention: this stores weightsystems,
 | ||||
|  * *not* pointers * to weightsystems. This has two crucial | ||||
|  * consequences: | ||||
|  * 1) Pointers to weightsystems are not stable. They may be | ||||
|  *    invalidated if the table is reallocated. | ||||
|  * 2) add_to_weightsystem_table(), etc. takes ownership of the | ||||
|  *    weightsystem. Notably of the description string */ | ||||
| struct weightsystem_table { | ||||
| 	int nr, allocated; | ||||
| 	weightsystem_t *weightsystems; | ||||
| }; | ||||
|  * *not* pointers * to weightsystems. Therefore pointers to | ||||
|  * weightsystems are *not* stable. | ||||
|  */ | ||||
| using weightsystem_table = std::vector<weightsystem_t>; | ||||
| 
 | ||||
| extern enum cylinderuse cylinderuse_from_text(const char *text); | ||||
| extern void copy_weights(const struct weightsystem_table *s, struct weightsystem_table *d); | ||||
| extern weightsystem_t clone_weightsystem(weightsystem_t ws); | ||||
| extern void free_weightsystem(weightsystem_t ws); | ||||
| extern void copy_cylinder_types(const struct dive *s, struct dive *d); | ||||
| extern void add_cloned_weightsystem(struct weightsystem_table *t, weightsystem_t ws); | ||||
| extern cylinder_t *add_empty_cylinder(struct cylinder_table *t); | ||||
| extern cylinder_t *get_cylinder(struct dive *d, int idx); | ||||
| extern const cylinder_t *get_cylinder(const struct dive *d, int idx); | ||||
|  | @ -99,8 +91,7 @@ extern void dump_cylinders(struct dive *dive, bool verbose); | |||
| #endif | ||||
| 
 | ||||
| /* Weightsystem table functions */ | ||||
| extern void clear_weightsystem_table(struct weightsystem_table *); | ||||
| extern void add_to_weightsystem_table(struct weightsystem_table *, int idx, weightsystem_t ws); | ||||
| extern void add_to_weightsystem_table(weightsystem_table *, int idx, weightsystem_t ws); | ||||
| 
 | ||||
| /* Cylinder table functions */ | ||||
| extern void add_cylinder(struct cylinder_table *, int idx, cylinder_t cyl); | ||||
|  |  | |||
|  | @ -848,8 +848,8 @@ static bool has_locations(const filter_constraint &c, const struct dive *d) | |||
| static bool has_weight_type(const filter_constraint &c, const struct dive *d) | ||||
| { | ||||
| 	QStringList weightsystemTypes; | ||||
| 	for (int i = 0; i < d->weightsystems.nr; ++i) | ||||
| 		weightsystemTypes.push_back(d->weightsystems.weightsystems[i].description); | ||||
| 	for (auto &ws: d->weightsystems) | ||||
| 		weightsystemTypes.push_back(QString::fromStdString(ws.description)); | ||||
| 
 | ||||
| 	return check(c, weightsystemTypes); | ||||
| } | ||||
|  |  | |||
|  | @ -127,10 +127,8 @@ static std::vector<QString> getWords(const dive *d) | |||
| 		tokenize(QString::fromStdString(tag->tag->name), res); | ||||
| 	for (auto &cyl: d->cylinders) | ||||
| 		tokenize(QString::fromStdString(cyl.type.description), res); | ||||
| 	for (int i = 0; i < d->weightsystems.nr; ++i) { | ||||
| 		const weightsystem_t &ws = d->weightsystems.weightsystems[i]; | ||||
| 		tokenize(QString(ws.description), res); | ||||
| 	} | ||||
| 	for (auto &ws: d->weightsystems) | ||||
| 		tokenize(QString::fromStdString(ws.description), res); | ||||
| 	// TODO: We should tokenize all dive-sites and trips first and then
 | ||||
| 	// take the tokens from a cache.
 | ||||
| 	if (d->dive_site) { | ||||
|  |  | |||
|  | @ -301,7 +301,7 @@ static int divinglog_dive(void *param, int, char **data, char **) | |||
| 
 | ||||
| 	if (data[10]) { | ||||
| 		weightsystem_t ws = { { atoi(data[10]) * 1000 }, translate("gettextFromC", "unknown"), false }; | ||||
| 		add_cloned_weightsystem(&state->cur_dive->weightsystems, ws); | ||||
| 		state->cur_dive->weightsystems.push_back(std::move(ws)); | ||||
| 	} | ||||
| 
 | ||||
| 	if (data[11]) | ||||
|  |  | |||
|  | @ -457,7 +457,7 @@ static void parse_weightsystem_keyvalue(void *_ws, const char *key, const std::s | |||
| 		return; | ||||
| 	} | ||||
| 	if (!strcmp(key, "description")) { | ||||
| 		ws->description = strdup(value.c_str()); | ||||
| 		ws->description = value; | ||||
| 		return; | ||||
| 	} | ||||
| 	report_error("Unknown weightsystem key/value pair (%s/%s)", key, value.c_str()); | ||||
|  | @ -465,7 +465,7 @@ static void parse_weightsystem_keyvalue(void *_ws, const char *key, const std::s | |||
| 
 | ||||
| static void parse_dive_weightsystem(char *line, struct git_parser_state *state) | ||||
| { | ||||
| 	weightsystem_t ws = empty_weightsystem; | ||||
| 	weightsystem_t ws; | ||||
| 
 | ||||
| 	for (;;) { | ||||
| 		char c; | ||||
|  | @ -476,7 +476,7 @@ static void parse_dive_weightsystem(char *line, struct git_parser_state *state) | |||
| 		line = parse_keyvalue_entry(parse_weightsystem_keyvalue, &ws, line, state); | ||||
| 	} | ||||
| 
 | ||||
| 	add_to_weightsystem_table(&state->active_dive->weightsystems, state->active_dive->weightsystems.nr, ws); | ||||
| 	state->active_dive->weightsystems.push_back(std::move(ws)); | ||||
| } | ||||
| 
 | ||||
| static int match_action(char *line, void *data, | ||||
|  | @ -1688,7 +1688,7 @@ static int parse_dive_entry(struct git_parser_state *state, const git_tree_entry | |||
| 		return report_error("Unable to read dive file"); | ||||
| 	if (*suffix) | ||||
| 		state->active_dive->number = atoi(suffix + 1); | ||||
| 	clear_weightsystem_table(&state->active_dive->weightsystems); | ||||
| 	state->active_dive->weightsystems.clear(); | ||||
| 	state->o2pressure_sensor = 1; | ||||
| 	for_each_line(blob, dive_parser, state); | ||||
| 	git_blob_free(blob); | ||||
|  |  | |||
|  | @ -1230,8 +1230,8 @@ static void gps_picture_location(const char *buffer, struct picture *pic) | |||
| static void try_to_fill_dive(struct dive *dive, const char *name, char *buf, struct parser_state *state) | ||||
| { | ||||
| 	cylinder_t *cyl = !dive->cylinders.empty() ? &dive->cylinders.back() : NULL; | ||||
| 	weightsystem_t *ws = dive->weightsystems.nr > 0 ? | ||||
| 		&dive->weightsystems.weightsystems[dive->weightsystems.nr - 1] : NULL; | ||||
| 	weightsystem_t *ws = !dive->weightsystems.empty() > 0 ? | ||||
| 		&dive->weightsystems.back() : NULL; | ||||
| 	pressure_t p; | ||||
| 	weight_t w; | ||||
| 	start_match("dive", name, buf); | ||||
|  | @ -1339,15 +1339,15 @@ static void try_to_fill_dive(struct dive *dive, const char *name, char *buf, str | |||
| 	if (MATCH_STATE("airpressure.dive", pressure, &dive->surface_pressure)) | ||||
| 		return; | ||||
| 	if (ws) { | ||||
| 		if (MATCH("description.weightsystem", utf8_string, (char **)&ws->description)) | ||||
| 		if (MATCH("description.weightsystem", utf8_string_std, &ws->description)) | ||||
| 			return; | ||||
| 		if (MATCH_STATE("weight.weightsystem", weight, &ws->weight)) | ||||
| 			return; | ||||
| 	} | ||||
| 	if (MATCH_STATE("weight", weight, &w)) { | ||||
| 		weightsystem_t ws = empty_weightsystem; | ||||
| 		weightsystem_t ws; | ||||
| 		ws.weight = w; | ||||
| 		add_cloned_weightsystem(&dive->weightsystems, ws); | ||||
| 		dive->weightsystems.push_back(std::move(ws)); | ||||
| 		return; | ||||
| 	} | ||||
| 	if (cyl) { | ||||
|  |  | |||
|  | @ -323,7 +323,7 @@ void cylinder_end(struct parser_state *state) | |||
| 
 | ||||
| void ws_start(struct parser_state *state) | ||||
| { | ||||
| 	add_cloned_weightsystem(&state->cur_dive->weightsystems, empty_weightsystem); | ||||
| 	state->cur_dive->weightsystems.emplace_back(); | ||||
| } | ||||
| 
 | ||||
| void ws_end(struct parser_state *state) | ||||
|  |  | |||
|  | @ -162,19 +162,14 @@ static void save_cylinder_info(struct membuffer *b, struct dive *dive) | |||
| 	} | ||||
| } | ||||
| 
 | ||||
| static void save_weightsystem_info(struct membuffer *b, struct dive *dive) | ||||
| static void save_weightsystem_info(struct membuffer *b, const struct dive *dive) | ||||
| { | ||||
| 	int i, nr; | ||||
| 
 | ||||
| 	nr = nr_weightsystems(dive); | ||||
| 	for (i = 0; i < nr; i++) { | ||||
| 		weightsystem_t ws = dive->weightsystems.weightsystems[i]; | ||||
| 	for (auto &ws: dive->weightsystems) { | ||||
| 		int grams = ws.weight.grams; | ||||
| 		const char *description = ws.description; | ||||
| 
 | ||||
| 		put_string(b, "weightsystem"); | ||||
| 		put_milli(b, " weight=", grams, "kg"); | ||||
| 		show_utf8(b, " description=", description, ""); | ||||
| 		show_utf8(b, " description=", ws.description.c_str(), ""); | ||||
| 		put_string(b, "\n"); | ||||
| 	} | ||||
| } | ||||
|  |  | |||
|  | @ -96,24 +96,18 @@ static void put_HTML_bookmarks(struct membuffer *b, const struct dive *dive) | |||
| 
 | ||||
| static void put_weightsystem_HTML(struct membuffer *b, const struct dive *dive) | ||||
| { | ||||
| 	int i, nr; | ||||
| 
 | ||||
| 	nr = nr_weightsystems(dive); | ||||
| 
 | ||||
| 	put_string(b, "\"Weights\":["); | ||||
| 
 | ||||
| 	const char *separator = ""; | ||||
| 
 | ||||
| 	for (i = 0; i < nr; i++) { | ||||
| 		weightsystem_t ws = dive->weightsystems.weightsystems[i]; | ||||
| 	for (auto &ws: dive->weightsystems) { | ||||
| 		int grams = ws.weight.grams; | ||||
| 		const char *description = ws.description; | ||||
| 
 | ||||
| 		put_string(b, separator); | ||||
| 		separator = ", "; | ||||
| 		put_string(b, "{"); | ||||
| 		put_HTML_weight_units(b, grams, "\"weight\":\"", "\","); | ||||
| 		write_attribute(b, "description", description, " "); | ||||
| 		write_attribute(b, "description", ws.description.c_str(), " "); | ||||
| 		put_string(b, "}"); | ||||
| 	} | ||||
| 	put_string(b, "],"); | ||||
|  |  | |||
|  | @ -197,20 +197,14 @@ static void save_cylinder_info(struct membuffer *b, struct dive *dive) | |||
| 	} | ||||
| } | ||||
| 
 | ||||
| static void save_weightsystem_info(struct membuffer *b, struct dive *dive) | ||||
| static void save_weightsystem_info(struct membuffer *b, const struct dive *dive) | ||||
| { | ||||
| 	int i, nr; | ||||
| 
 | ||||
| 	nr = nr_weightsystems(dive); | ||||
| 
 | ||||
| 	for (i = 0; i < nr; i++) { | ||||
| 		weightsystem_t ws = dive->weightsystems.weightsystems[i]; | ||||
| 	for (auto &ws:  dive->weightsystems) { | ||||
| 		int grams = ws.weight.grams; | ||||
| 		const char *description = ws.description; | ||||
| 
 | ||||
| 		put_format(b, "  <weightsystem"); | ||||
| 		put_milli(b, " weight='", grams, " kg'"); | ||||
| 		show_utf8(b, description, " description='", "'", 1); | ||||
| 		show_utf8(b, ws.description.c_str(), " description='", "'", 1); | ||||
| 		put_format(b, " />\n"); | ||||
| 	} | ||||
| } | ||||
|  |  | |||
|  | @ -195,21 +195,19 @@ QString formatSumWeight(const dive *d) | |||
| 	return get_weight_string(weight_t { total_weight(d) }, true); | ||||
| } | ||||
| 
 | ||||
| static QString getFormattedWeight(const struct dive *dive, int idx) | ||||
| static QString getFormattedWeight(const weightsystem_t &weight) | ||||
| { | ||||
| 	const weightsystem_t *weight = &dive->weightsystems.weightsystems[idx]; | ||||
| 	if (!weight->description) | ||||
| 	if (weight.description.empty()) | ||||
| 		return QString(); | ||||
| 	QString fmt = QString(weight->description); | ||||
| 	fmt += ", " + get_weight_string(weight->weight, true); | ||||
| 	return fmt; | ||||
| 	return QString::fromStdString(weight.description) + | ||||
| 	       ", " + get_weight_string(weight.weight, true); | ||||
| } | ||||
| 
 | ||||
| QString formatWeightList(const dive *d) | ||||
| { | ||||
| 	QString weights; | ||||
| 	for (int i = 0; i < d->weightsystems.nr; i++) { | ||||
| 		QString w = getFormattedWeight(d, i); | ||||
| 	for (auto &ws: d->weightsystems) { | ||||
| 		QString w = getFormattedWeight(ws); | ||||
| 		if (w.isEmpty()) | ||||
| 			continue; | ||||
| 		weights += w + "; "; | ||||
|  | @ -220,8 +218,8 @@ QString formatWeightList(const dive *d) | |||
| QStringList formatWeights(const dive *d) | ||||
| { | ||||
| 	QStringList weights; | ||||
| 	for (int i = 0; i < d->weightsystems.nr; i++) { | ||||
| 		QString w = getFormattedWeight(d, i); | ||||
| 	for (auto &ws: d->weightsystems) { | ||||
| 		QString w = getFormattedWeight(ws); | ||||
| 		if (w.isEmpty()) | ||||
| 			continue; | ||||
| 		weights << w; | ||||
|  |  | |||
|  | @ -745,9 +745,9 @@ static void parse_tag(struct dive *dive, std::string_view tag, std::string_view | |||
| 	} else if (tag == "altitude") { | ||||
| 		uemis_get_index(val, dive->dcs[0].surface_pressure.mbar); | ||||
| 	} else if (tag == "f32Weight") { | ||||
| 		weightsystem_t ws = empty_weightsystem; | ||||
| 		weightsystem_t ws; | ||||
| 		uemis_get_weight(val, ws, dive->dcs[0].diveid); | ||||
| 		add_cloned_weightsystem(&dive->weightsystems, ws); | ||||
| 		dive->weightsystems.push_back(std::move(ws)); | ||||
| 	} else if (tag == "notes") { | ||||
| 		uemis_add_string(val, &dive->notes, " "); | ||||
| 	} else if (tag == "u8DiveSuit") { | ||||
|  |  | |||
|  | @ -335,10 +335,10 @@ void WSInfoDelegate::editorClosed(QWidget *, QAbstractItemDelegate::EndEditHint | |||
| void WSInfoDelegate::setModelData(QWidget *, QAbstractItemModel *, const QModelIndex &) const | ||||
| { | ||||
| 	WeightModel *mymodel = qobject_cast<WeightModel *>(currCombo.model); | ||||
| 	QString weightName = currCombo.activeText; | ||||
| 	weight_t weight = get_weightsystem_weight(qPrintable(weightName)); | ||||
| 	std::string weightName = currCombo.activeText.toStdString(); | ||||
| 	weight_t weight = get_weightsystem_weight(weightName.c_str()); | ||||
| 
 | ||||
| 	mymodel->setTempWS(currCombo.currRow, weightsystem_t{ weight, copy_qstring(weightName), false }); | ||||
| 	mymodel->setTempWS(currCombo.currRow, weightsystem_t( weight, std::move(weightName), false )); | ||||
| } | ||||
| 
 | ||||
| static QAbstractItemModel *createWSInfoModel(QWidget *parent) | ||||
|  |  | |||
|  | @ -356,12 +356,9 @@ void DiveComponentSelection::buttonClicked(QAbstractButton *button) | |||
| 			} | ||||
| 		} | ||||
| 		if (what->weights) { | ||||
| 			int w; | ||||
| 			text << tr("Weights:\n"); | ||||
| 			for (w = 0; w < current_dive->weightsystems.nr; w++) { | ||||
| 				weightsystem_t ws = current_dive->weightsystems.weightsystems[w]; | ||||
| 				text << ws.description << ws.weight.grams / 1000 << "kg\n"; | ||||
| 			} | ||||
| 			for (auto &ws: current_dive->weightsystems) | ||||
| 				text << QString::fromStdString(ws.description) << ws.weight.grams / 1000 << "kg\n"; | ||||
| 		} | ||||
| 		if (what->number) | ||||
| 			text << tr("Dive number: ") << current_dive->number << "\n"; | ||||
|  |  | |||
|  | @ -562,7 +562,7 @@ QVariant TemplateLayout::getValue(QString list, QString property, const State &s | |||
| 		} else if (property == "weights") { | ||||
| 			return formatWeights(d); | ||||
| 		} else if (property == "singleWeight") { | ||||
| 			return d->weightsystems.nr <= 1; | ||||
| 			return d->weightsystems.size() <= 1; | ||||
| 		} else if (property == "suit") { | ||||
| 			return d->suit; | ||||
| 		} else if (property == "cylinderList") { | ||||
|  |  | |||
|  | @ -1228,11 +1228,11 @@ void QMLManager::commitChanges(QString diveId, QString number, QString date, QSt | |||
| 		diveChanged = true; | ||||
| 		// not sure what we'd do if there was more than one weight system
 | ||||
| 		// defined - for now just ignore that case
 | ||||
| 		if (d->weightsystems.nr == 0) { | ||||
| 			weightsystem_t ws = { { parseWeightToGrams(weight) } , strdup(qPrintable(tr("weight"))), false }; | ||||
| 			add_to_weightsystem_table(&d->weightsystems, 0, ws); // takes ownership of the string
 | ||||
| 		} else if (d->weightsystems.nr == 1) { | ||||
| 			d->weightsystems.weightsystems[0].weight.grams = parseWeightToGrams(weight); | ||||
| 		if (d->weightsystems.size() == 0) { | ||||
| 			weightsystem_t ws = { { parseWeightToGrams(weight) } , tr("weight").toStdString(), false }; | ||||
| 			add_to_weightsystem_table(&d->weightsystems, 0, std::move(ws)); | ||||
| 		} else if (d->weightsystems.size() == 1) { | ||||
| 			d->weightsystems[0].weight.grams = parseWeightToGrams(weight); | ||||
| 		} | ||||
| 	} | ||||
| 	// start and end pressures
 | ||||
|  |  | |||
|  | @ -303,7 +303,7 @@ QVariant DiveTripModelBase::diveData(const struct dive *d, int column, int role) | |||
| 	case MobileListModel::CylinderRole: return formatGetCylinder(d).join(", "); | ||||
| 	case MobileListModel::GetCylinderRole: return formatGetCylinder(d); | ||||
| 	case MobileListModel::CylinderListRole: return formatFullCylinderList(); | ||||
| 	case MobileListModel::SingleWeightRole: return d->weightsystems.nr <= 1; | ||||
| 	case MobileListModel::SingleWeightRole: return d->weightsystems.size() <= 1; | ||||
| 	case MobileListModel::StartPressureRole: return formatStartPressure(d); | ||||
| 	case MobileListModel::EndPressureRole: return formatEndPressure(d); | ||||
| 	case MobileListModel::FirstGasRole: return formatFirstGas(d); | ||||
|  |  | |||
|  | @ -12,8 +12,7 @@ | |||
| 
 | ||||
| WeightModel::WeightModel(QObject *parent) : CleanerTableModel(parent), | ||||
| 	d(nullptr), | ||||
| 	tempRow(-1), | ||||
| 	tempWS(empty_weightsystem) | ||||
| 	tempRow(-1) | ||||
| { | ||||
| 	//enum Column {REMOVE, TYPE, WEIGHT};
 | ||||
| 	setHeaderDataStrings(QStringList() << tr("") << tr("Type") << tr("Weight")); | ||||
|  | @ -26,11 +25,11 @@ WeightModel::WeightModel(QObject *parent) : CleanerTableModel(parent), | |||
| weightsystem_t WeightModel::weightSystemAt(const QModelIndex &index) const | ||||
| { | ||||
| 	int row = index.row(); | ||||
| 	if (row < 0 || row >= d->weightsystems.nr) { | ||||
| 		qWarning("WeightModel: Accessing invalid weightsystem %d (of %d)", row, d->weightsystems.nr); | ||||
| 		return empty_weightsystem; | ||||
| 	if (row < 0 || static_cast<size_t>(row) >= d->weightsystems.size()) { | ||||
| 		qWarning("WeightModel: Accessing invalid weightsystem %d (of %d)", row, static_cast<int>(d->weightsystems.size())); | ||||
| 		return weightsystem_t(); | ||||
| 	} | ||||
| 	return d->weightsystems.weightsystems[index.row()]; | ||||
| 	return d->weightsystems[index.row()]; | ||||
| } | ||||
| 
 | ||||
| void WeightModel::clear() | ||||
|  | @ -40,7 +39,7 @@ void WeightModel::clear() | |||
| 
 | ||||
| QVariant WeightModel::data(const QModelIndex &index, int role) const | ||||
| { | ||||
| 	if (!index.isValid() || index.row() >= d->weightsystems.nr) | ||||
| 	if (!index.isValid() || static_cast<size_t>(index.row()) >= d->weightsystems.size()) | ||||
| 		return QVariant(); | ||||
| 
 | ||||
| 	weightsystem_t ws = index.row() == tempRow ? tempWS : weightSystemAt(index); | ||||
|  | @ -54,7 +53,7 @@ QVariant WeightModel::data(const QModelIndex &index, int role) const | |||
| 	case Qt::EditRole: | ||||
| 		switch (index.column()) { | ||||
| 		case TYPE: | ||||
| 			return gettextFromC::tr(ws.description); | ||||
| 			return gettextFromC::tr(ws.description.c_str()); | ||||
| 		case WEIGHT: | ||||
| 			return get_weight_string(ws.weight, true); | ||||
| 		} | ||||
|  | @ -78,20 +77,16 @@ QVariant WeightModel::data(const QModelIndex &index, int role) const | |||
| // Ownership of passed in weight system will be taken. Caller must not use it any longer.
 | ||||
| void WeightModel::setTempWS(int row, weightsystem_t ws) | ||||
| { | ||||
| 	if (!d || row < 0 || row >= d->weightsystems.nr) { // Sanity check: row must exist
 | ||||
| 		free_weightsystem(ws); | ||||
| 	if (!d || row < 0 || static_cast<size_t>(row) >= d->weightsystems.size()) // Sanity check: row must exist
 | ||||
| 		return; | ||||
| 	} | ||||
| 
 | ||||
| 	clearTempWS(); // Shouldn't be necessary, just in case: Reset old temporary row.
 | ||||
| 
 | ||||
| 	// It is really hard to get the editor-close-hints and setModelData calls under
 | ||||
| 	// control. Therefore, if the row is set to the already existing entry, don't
 | ||||
| 	// enter temporary mode.
 | ||||
| 	const weightsystem_t &oldWS = d->weightsystems.weightsystems[row]; | ||||
| 	if (same_string(oldWS.description, ws.description)) { | ||||
| 		free_weightsystem(ws); | ||||
| 	} else { | ||||
| 	const weightsystem_t &oldWS = d->weightsystems[row]; | ||||
| 	if (oldWS.description != ws.description) { | ||||
| 		tempRow = row; | ||||
| 		tempWS = ws; | ||||
| 
 | ||||
|  | @ -110,18 +105,18 @@ void WeightModel::clearTempWS() | |||
| 		return; | ||||
| 	int oldRow = tempRow; | ||||
| 	tempRow = -1; | ||||
| 	free_weightsystem(tempWS); | ||||
| 	tempWS = weightsystem_t(); | ||||
| 	dataChanged(index(oldRow, TYPE), index(oldRow, WEIGHT)); | ||||
| } | ||||
| 
 | ||||
| void WeightModel::commitTempWS() | ||||
| { | ||||
| #ifndef SUBSURFACE_MOBILE | ||||
| 	if (tempRow < 0 || !d || tempRow > d->weightsystems.nr) | ||||
| 	if (tempRow < 0 || !d || static_cast<size_t>(tempRow) > d->weightsystems.size()) | ||||
| 		return; | ||||
| 	// Only submit a command if the type changed
 | ||||
| 	weightsystem_t ws = d->weightsystems.weightsystems[tempRow]; | ||||
| 	if (!same_string(ws.description, tempWS.description) || gettextFromC::tr(ws.description) != QString(tempWS.description)) { | ||||
| 	weightsystem_t ws = d->weightsystems[tempRow]; | ||||
| 	if (ws.description != tempWS.description || gettextFromC::tr(ws.description.c_str()) != QString::fromStdString(tempWS.description)) { | ||||
| 		int count = Command::editWeight(tempRow, tempWS, false); | ||||
| 		emit divesEdited(count); | ||||
| 	} | ||||
|  | @ -155,7 +150,7 @@ Qt::ItemFlags WeightModel::flags(const QModelIndex &index) const | |||
| 
 | ||||
| int WeightModel::rowCount(const QModelIndex&) const | ||||
| { | ||||
| 	return d ? d->weightsystems.nr : 0; | ||||
| 	return d ? static_cast<int>(d->weightsystems.size()) : 0; | ||||
| } | ||||
| 
 | ||||
| void WeightModel::updateDive(dive *dIn) | ||||
|  |  | |||
|  | @ -1021,8 +1021,8 @@ void smartrak_import(const char *file, struct divelog *log) | |||
| 
 | ||||
| 		/* No DC related data */ | ||||
| 		smtkdive->visibility = strtod((char *)col[coln(VISIBILITY)]->bind_ptr, NULL) > 25 ? 5 : lrint(strtod((char *)col[13]->bind_ptr, NULL) / 5); | ||||
| 		weightsystem_t ws = { {(int)lrint(strtod((char *)col[coln(WEIGHT)]->bind_ptr, NULL) * 1000)}, "", false }; | ||||
| 		add_cloned_weightsystem(&smtkdive->weightsystems, ws); | ||||
| 		weightsystem_t ws = { {(int)lrint(strtod((char *)col[coln(WEIGHT)]->bind_ptr, NULL) * 1000)}, std::string(), false }; | ||||
| 		smtkdive->weightsystems.push_back(std::move(ws)); | ||||
| 		smtkdive->suit = strdup(get(suit_list, atoi((char *)col[coln(SUITIDX)]->bind_ptr) - 1).c_str()); | ||||
| 		smtk_build_location(mdb_clon, (char *)col[coln(SITEIDX)]->bind_ptr, &smtkdive->dive_site, log); | ||||
| 		smtkdive->buddy = strdup(smtk_locate_buddy(mdb_clon, (char *)col[0]->bind_ptr, buddy_list).c_str()); | ||||
|  |  | |||
|  | @ -1768,9 +1768,9 @@ struct SuitVariable : public StatsVariableTemplate<StatsVariable::Type::Discrete | |||
| static std::vector<QString> weightsystems(const dive *d) | ||||
| { | ||||
| 	std::vector<QString> res; | ||||
| 	res.reserve(d->weightsystems.nr); | ||||
| 	for (int i = 0; i < d->weightsystems.nr; ++i) | ||||
| 		add_to_vector_unique(res, QString(d->weightsystems.weightsystems[i].description).trimmed()); | ||||
| 	res.reserve(d->weightsystems.size()); | ||||
| 	for (auto &ws: d->weightsystems) | ||||
| 		add_to_vector_unique(res, QString::fromStdString(ws.description).trimmed()); | ||||
| 	return res; | ||||
| } | ||||
| 
 | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue