mirror of
				https://github.com/subsurface/subsurface.git
				synced 2025-02-19 22:16:15 +00:00 
			
		
		
		
	core: default initialize units-type objects to 0
Makes the code much nicer to read. Default initialize cylinder_t to the empty cylinder. This produces lots of warnings, because most structure are now not PODs anymore and shouldn't be erased using memset(). These memset()s will be removed one-by-one and replaced by proper constructors. The whole ordeal made it necessary to add a constructor to struct event. To simplify things the whole optimization of the variable-size event names was removed. In upcoming commits this will be replaced by std::string anyway. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
This commit is contained in:
		
							parent
							
								
									b82fdd1d20
								
							
						
					
					
						commit
						408b31b6ce
					
				
					 34 changed files with 128 additions and 148 deletions
				
			
		| 
						 | 
				
			
			@ -1115,8 +1115,7 @@ void EditWeight::undo()
 | 
			
		|||
 | 
			
		||||
// ***** Add Cylinder *****
 | 
			
		||||
AddCylinder::AddCylinder(bool currentDiveOnly) :
 | 
			
		||||
	EditDivesBase(currentDiveOnly),
 | 
			
		||||
	cyl(empty_cylinder)
 | 
			
		||||
	EditDivesBase(currentDiveOnly)
 | 
			
		||||
{
 | 
			
		||||
	if (dives.empty())
 | 
			
		||||
		return;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -186,7 +186,7 @@ bool AddGasSwitch::workToBeDone()
 | 
			
		|||
 | 
			
		||||
void AddGasSwitch::redoit()
 | 
			
		||||
{
 | 
			
		||||
	std::vector<OwningEventPtr> newEventsToAdd;
 | 
			
		||||
	std::vector<std::unique_ptr<event>> newEventsToAdd;
 | 
			
		||||
	std::vector<event *> newEventsToRemove;
 | 
			
		||||
	newEventsToAdd.reserve(eventsToRemove.size());
 | 
			
		||||
	newEventsToRemove.reserve(eventsToAdd.size());
 | 
			
		||||
| 
						 | 
				
			
			@ -196,7 +196,7 @@ void AddGasSwitch::redoit()
 | 
			
		|||
		remove_event_from_dc(dc, ev);
 | 
			
		||||
		newEventsToAdd.emplace_back(ev); // take ownership of event
 | 
			
		||||
	}
 | 
			
		||||
	for (OwningEventPtr &ev: eventsToAdd) {
 | 
			
		||||
	for (auto &ev: eventsToAdd) {
 | 
			
		||||
		newEventsToRemove.push_back(ev.get());
 | 
			
		||||
		add_event_to_dc(dc, ev.release()); // return ownership to backend
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -42,7 +42,7 @@ protected:
 | 
			
		|||
private:
 | 
			
		||||
	bool workToBeDone() override;
 | 
			
		||||
 | 
			
		||||
	OwningEventPtr eventToAdd;	// for redo
 | 
			
		||||
	std::unique_ptr<event> eventToAdd;	// for redo
 | 
			
		||||
	event *eventToRemove;			// for undo
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -73,7 +73,7 @@ private:
 | 
			
		|||
	void undoit() override;
 | 
			
		||||
	void redoit() override;
 | 
			
		||||
 | 
			
		||||
	OwningEventPtr eventToAdd;	// for undo and redo
 | 
			
		||||
	std::unique_ptr<event> eventToAdd;	// for undo and redo
 | 
			
		||||
	event *eventToRemove;			// for undo and redo
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -86,7 +86,7 @@ private:
 | 
			
		|||
	void redoit() override;
 | 
			
		||||
	void post() const; // Called to fix up dives should a gas-change have happened.
 | 
			
		||||
 | 
			
		||||
	OwningEventPtr eventToAdd;	// for undo
 | 
			
		||||
	std::unique_ptr<event> eventToAdd;	// for undo
 | 
			
		||||
	event *eventToRemove;			// for redo
 | 
			
		||||
	int cylinder;				// affected cylinder (if removing gas switch). <0: not a gas switch.
 | 
			
		||||
};
 | 
			
		||||
| 
						 | 
				
			
			@ -100,7 +100,7 @@ private:
 | 
			
		|||
	void redoit() override;
 | 
			
		||||
 | 
			
		||||
	std::vector<int> cylinders; // cylinders that are modified
 | 
			
		||||
	std::vector<OwningEventPtr> eventsToAdd;
 | 
			
		||||
	std::vector<std::unique_ptr<event>> eventsToAdd;
 | 
			
		||||
	std::vector<event *> eventsToRemove;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -676,7 +676,7 @@ static void cochran_parse_dive(const unsigned char *decode, unsigned mod,
 | 
			
		|||
	case TYPE_GEMINI:
 | 
			
		||||
	case TYPE_COMMANDER:
 | 
			
		||||
		if (config.type == TYPE_GEMINI) {
 | 
			
		||||
			cylinder_t cyl = empty_cylinder;
 | 
			
		||||
			cylinder_t cyl;
 | 
			
		||||
			dc->model = "Gemini";
 | 
			
		||||
			dc->deviceid = buf[0x18c] * 256 + buf[0x18d];	// serial no
 | 
			
		||||
			fill_default_cylinder(dive, &cyl);
 | 
			
		||||
| 
						 | 
				
			
			@ -688,7 +688,7 @@ static void cochran_parse_dive(const unsigned char *decode, unsigned mod,
 | 
			
		|||
			dc->model = "Commander";
 | 
			
		||||
			dc->deviceid = array_uint32_le(buf + 0x31e);	// serial no
 | 
			
		||||
			for (g = 0; g < 2; g++) {
 | 
			
		||||
				cylinder_t cyl = empty_cylinder;
 | 
			
		||||
				cylinder_t cyl;
 | 
			
		||||
				fill_default_cylinder(dive, &cyl);
 | 
			
		||||
				cyl.gasmix.o2.permille = (log[CMD_O2_PERCENT + g * 2] / 256
 | 
			
		||||
					+ log[CMD_O2_PERCENT + g * 2 + 1]) * 10;
 | 
			
		||||
| 
						 | 
				
			
			@ -731,7 +731,7 @@ static void cochran_parse_dive(const unsigned char *decode, unsigned mod,
 | 
			
		|||
		dc->model = "EMC";
 | 
			
		||||
		dc->deviceid = array_uint32_le(buf + 0x31e);	// serial no
 | 
			
		||||
		for (g = 0; g < 4; g++) {
 | 
			
		||||
			cylinder_t cyl = empty_cylinder;
 | 
			
		||||
			cylinder_t cyl;
 | 
			
		||||
			fill_default_cylinder(dive, &cyl);
 | 
			
		||||
			cyl.gasmix.o2.permille =
 | 
			
		||||
				(log[EMC_O2_PERCENT + g * 2] / 256
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -334,7 +334,7 @@ static char *dt_dive_parser(unsigned char *runner, struct dive *dt_dive, struct
 | 
			
		|||
	 */
 | 
			
		||||
	read_bytes(2);
 | 
			
		||||
	if (tmp_2bytes != 0x7FFF) {
 | 
			
		||||
		cylinder_t cyl = empty_cylinder;
 | 
			
		||||
		cylinder_t cyl;
 | 
			
		||||
		std::string desc = cyl_type_by_size(tmp_2bytes * 10);
 | 
			
		||||
		cyl.type.size.mliter = tmp_2bytes * 10;
 | 
			
		||||
		cyl.type.description = desc.c_str();
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -915,7 +915,7 @@ static void fixup_dc_events(struct divecomputer *dc)
 | 
			
		|||
	while (event) {
 | 
			
		||||
		if (event->next && event->next->deleted) {
 | 
			
		||||
			struct event *nextnext = event->next->next;
 | 
			
		||||
			free(event->next);
 | 
			
		||||
			delete event->next;
 | 
			
		||||
			event->next = nextnext;
 | 
			
		||||
		} else {
 | 
			
		||||
			event = event->next;
 | 
			
		||||
| 
						 | 
				
			
			@ -2814,7 +2814,7 @@ static int split_dive_at(const struct dive *dive, int a, int b, struct dive **ou
 | 
			
		|||
		*evp = NULL;
 | 
			
		||||
		while (event) {
 | 
			
		||||
			struct event *next = event->next;
 | 
			
		||||
			free(event);
 | 
			
		||||
			delete event;
 | 
			
		||||
			event = next;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -2823,7 +2823,7 @@ static int split_dive_at(const struct dive *dive, int a, int b, struct dive **ou
 | 
			
		|||
		while ((event = *evp) != NULL) {
 | 
			
		||||
			if (event->time.seconds < t) {
 | 
			
		||||
				*evp = event->next;
 | 
			
		||||
				free(event);
 | 
			
		||||
				delete event;
 | 
			
		||||
			} else {
 | 
			
		||||
				event->time.seconds -= t;
 | 
			
		||||
			}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -14,7 +14,7 @@ struct dive_site
 | 
			
		|||
	uint32_t uuid = 0;
 | 
			
		||||
	std::string name;
 | 
			
		||||
	std::vector<dive *> dives;
 | 
			
		||||
	location_t location = { { 9 }, { 0 } };
 | 
			
		||||
	location_t location;
 | 
			
		||||
	std::string description;
 | 
			
		||||
	std::string notes;
 | 
			
		||||
	taxonomy_data taxonomy;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -205,7 +205,7 @@ void add_cylinder(struct cylinder_table *t, int idx, cylinder_t cyl)
 | 
			
		|||
	 * every single cylinder table there is an empty cylinder that can
 | 
			
		||||
	 * be used by the planner as "surface air" cylinder. Fix this.
 | 
			
		||||
	 */
 | 
			
		||||
	add_to_cylinder_table(t, t->nr, empty_cylinder);
 | 
			
		||||
	add_to_cylinder_table(t, t->nr, cylinder_t());
 | 
			
		||||
	t->nr--;
 | 
			
		||||
	t->cylinders[t->nr].cylinder_use = NOT_USED;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -418,7 +418,7 @@ void copy_cylinder_types(const struct dive *s, struct dive *d)
 | 
			
		|||
 | 
			
		||||
cylinder_t *add_empty_cylinder(struct cylinder_table *t)
 | 
			
		||||
{
 | 
			
		||||
	cylinder_t cyl = empty_cylinder;
 | 
			
		||||
	cylinder_t cyl;
 | 
			
		||||
	cyl.type.description = strdup("");
 | 
			
		||||
	add_cylinder(t, t->nr, cyl);
 | 
			
		||||
	return &t->cylinders[t->nr - 1];
 | 
			
		||||
| 
						 | 
				
			
			@ -483,7 +483,7 @@ void fill_default_cylinder(const struct dive *dive, cylinder_t *cyl)
 | 
			
		|||
 | 
			
		||||
cylinder_t create_new_cylinder(const struct dive *d)
 | 
			
		||||
{
 | 
			
		||||
	cylinder_t cyl = empty_cylinder;
 | 
			
		||||
	cylinder_t cyl;
 | 
			
		||||
	fill_default_cylinder(d, &cyl);
 | 
			
		||||
	cyl.start = cyl.type.workingpressure;
 | 
			
		||||
	cyl.cylinder_use = OC_GAS;
 | 
			
		||||
| 
						 | 
				
			
			@ -507,7 +507,6 @@ void add_default_cylinder(struct dive *d)
 | 
			
		|||
	if (!empty_string(prefs.default_cylinder)) {
 | 
			
		||||
		cyl = create_new_cylinder(d);
 | 
			
		||||
	} else {
 | 
			
		||||
		cyl = empty_cylinder;
 | 
			
		||||
		// roughly an AL80
 | 
			
		||||
		cyl.type.description = strdup(translate("gettextFromC", "unknown"));
 | 
			
		||||
		cyl.type.size.mliter = 11100;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -17,25 +17,23 @@ typedef struct
 | 
			
		|||
{
 | 
			
		||||
	volume_t size;
 | 
			
		||||
	pressure_t workingpressure;
 | 
			
		||||
	const char *description; /* "LP85", "AL72", "AL80", "HP100+" or whatever */
 | 
			
		||||
	const char *description = nullptr; /* "LP85", "AL72", "AL80", "HP100+" or whatever */
 | 
			
		||||
} cylinder_type_t;
 | 
			
		||||
 | 
			
		||||
typedef struct
 | 
			
		||||
{
 | 
			
		||||
	cylinder_type_t type;
 | 
			
		||||
	struct gasmix gasmix;
 | 
			
		||||
	struct gasmix gasmix = gasmix_air;
 | 
			
		||||
	pressure_t start, end, sample_start, sample_end;
 | 
			
		||||
	depth_t depth;
 | 
			
		||||
	bool manually_added;
 | 
			
		||||
	bool manually_added = false;
 | 
			
		||||
	volume_t gas_used;
 | 
			
		||||
	volume_t deco_gas_used;
 | 
			
		||||
	enum cylinderuse cylinder_use;
 | 
			
		||||
	bool bestmix_o2;
 | 
			
		||||
	bool bestmix_he;
 | 
			
		||||
	enum cylinderuse cylinder_use = OC_GAS;
 | 
			
		||||
	bool bestmix_o2 = false;
 | 
			
		||||
	bool bestmix_he = false;
 | 
			
		||||
} cylinder_t;
 | 
			
		||||
 | 
			
		||||
static const cylinder_t empty_cylinder = { { { 0 }, { 0 }, (const char *)0}, { { 0 }, { 0 } } , { 0 }, { 0 }, { 0 }, { 0 }, { 0 }, false, { 0 }, { 0 }, OC_GAS, false, false };
 | 
			
		||||
 | 
			
		||||
/* Table of cylinders. Attention: this stores cylinders,
 | 
			
		||||
 * *not* pointers to cylinders. This has two crucial consequences:
 | 
			
		||||
 * 1) Pointers to cylinders are not stable. They may be
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -6,6 +6,19 @@
 | 
			
		|||
#include <string.h>
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
 | 
			
		||||
event::event() : next(nullptr), type(SAMPLE_EVENT_NONE), flags(0), value(0),
 | 
			
		||||
	divemode(OC), deleted(false), hidden(false)
 | 
			
		||||
{
 | 
			
		||||
	memset(name, 0, MAX_EVENT_NAME);
 | 
			
		||||
	/* That overwrites divemode. Is this a smart thing to do? */
 | 
			
		||||
	gas.index = -1;
 | 
			
		||||
	gas.mix = gasmix_air;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
event::~event()
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int event_is_gaschange(const struct event *ev)
 | 
			
		||||
{
 | 
			
		||||
	return ev->type == SAMPLE_EVENT_GASCHANGE ||
 | 
			
		||||
| 
						 | 
				
			
			@ -23,11 +36,8 @@ struct event *clone_event(const struct event *src_ev)
 | 
			
		|||
	if (!src_ev)
 | 
			
		||||
		return NULL;
 | 
			
		||||
 | 
			
		||||
	size_t size = sizeof(*src_ev) + strlen(src_ev->name) + 1;
 | 
			
		||||
	ev = (struct event*) malloc(size);
 | 
			
		||||
	if (!ev)
 | 
			
		||||
		exit(1);
 | 
			
		||||
	memcpy(ev, src_ev, size);
 | 
			
		||||
	ev = new event;
 | 
			
		||||
	*ev = *src_ev;
 | 
			
		||||
	ev->next = NULL;
 | 
			
		||||
 | 
			
		||||
	return ev;
 | 
			
		||||
| 
						 | 
				
			
			@ -37,7 +47,7 @@ void free_events(struct event *ev)
 | 
			
		|||
{
 | 
			
		||||
	while (ev) {
 | 
			
		||||
		struct event *next = ev->next;
 | 
			
		||||
		free(ev);
 | 
			
		||||
		delete ev;
 | 
			
		||||
		ev = next;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -46,14 +56,9 @@ struct event *create_event(unsigned int time, int type, int flags, int value, co
 | 
			
		|||
{
 | 
			
		||||
	int gas_index = -1;
 | 
			
		||||
	struct event *ev;
 | 
			
		||||
	unsigned int size, len = strlen(name);
 | 
			
		||||
 | 
			
		||||
	size = sizeof(*ev) + len + 1;
 | 
			
		||||
	ev = (struct event*) malloc(size);
 | 
			
		||||
	if (!ev)
 | 
			
		||||
		return NULL;
 | 
			
		||||
	memset(ev, 0, size);
 | 
			
		||||
	memcpy(ev->name, name, len);
 | 
			
		||||
	ev = new event;
 | 
			
		||||
	strncpy(ev->name, name, MAX_EVENT_NAME - 1);
 | 
			
		||||
	ev->time.seconds = time;
 | 
			
		||||
	ev->type = type;
 | 
			
		||||
	ev->flags = flags;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -19,6 +19,8 @@ enum event_severity {
 | 
			
		|||
 * Events are currently based straight on what libdivecomputer gives us.
 | 
			
		||||
 *  We need to wrap these into our own events at some point to remove some of the limitations.
 | 
			
		||||
 */
 | 
			
		||||
#define MAX_EVENT_NAME 128
 | 
			
		||||
 | 
			
		||||
struct event {
 | 
			
		||||
	struct event *next;
 | 
			
		||||
	duration_t time;
 | 
			
		||||
| 
						 | 
				
			
			@ -40,7 +42,9 @@ struct event {
 | 
			
		|||
	};
 | 
			
		||||
	bool deleted; // used internally in the parser and in fixup_dive().
 | 
			
		||||
	bool hidden;
 | 
			
		||||
	char name[];
 | 
			
		||||
	char name[MAX_EVENT_NAME];
 | 
			
		||||
	event();
 | 
			
		||||
	~event();
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
extern int event_is_gaschange(const struct event *ev);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -62,7 +62,7 @@ void sanitize_gasmix(struct gasmix *mix)
 | 
			
		|||
	if (o2 <= 1000 && he <= 1000 && o2 + he <= 1000)
 | 
			
		||||
		return;
 | 
			
		||||
	report_info("Odd gasmix: %u O2 %u He", o2, he);
 | 
			
		||||
	memset(mix, 0, sizeof(*mix));
 | 
			
		||||
	*mix = gasmix_air;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int gasmix_distance(struct gasmix a, struct gasmix b)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -96,7 +96,7 @@ Thumbnailer::Thumbnail Thumbnailer::fetchImage(const QString &urlfilename, const
 | 
			
		|||
 | 
			
		||||
		// For io error or video, return early with the appropriate dummy-icon.
 | 
			
		||||
		if (type == MEDIATYPE_IO_ERROR)
 | 
			
		||||
			return { failImage, MEDIATYPE_IO_ERROR, zero_duration };
 | 
			
		||||
			return { failImage, MEDIATYPE_IO_ERROR, duration_t() };
 | 
			
		||||
		else if (type == MEDIATYPE_VIDEO)
 | 
			
		||||
			return fetchVideoThumbnail(filename, originalFilename, md.duration);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -112,7 +112,7 @@ Thumbnailer::Thumbnail Thumbnailer::fetchImage(const QString &urlfilename, const
 | 
			
		|||
		// Try to check for a video-file extension. Since we couldn't parse the video file,
 | 
			
		||||
		// we pass 0 as the duration.
 | 
			
		||||
		if (hasVideoFileExtension(filename))
 | 
			
		||||
			return fetchVideoThumbnail(filename, originalFilename, zero_duration);
 | 
			
		||||
			return fetchVideoThumbnail(filename, originalFilename, duration_t());
 | 
			
		||||
 | 
			
		||||
		// Give up: we simply couldn't determine what this thing is.
 | 
			
		||||
		// But since we managed to read this file, mark this file in the cache as unknown.
 | 
			
		||||
| 
						 | 
				
			
			@ -122,9 +122,9 @@ Thumbnailer::Thumbnail Thumbnailer::fetchImage(const QString &urlfilename, const
 | 
			
		|||
		// to treat requests from other threads. invokeMethod() is Qt's way of calling a
 | 
			
		||||
		// function in a different thread, namely the thread the called object is associated to.
 | 
			
		||||
		QMetaObject::invokeMethod(ImageDownloader::instance(), "load", Qt::AutoConnection, Q_ARG(QUrl, url), Q_ARG(QString, originalFilename));
 | 
			
		||||
		return { QImage(), MEDIATYPE_STILL_LOADING, zero_duration };
 | 
			
		||||
		return { QImage(), MEDIATYPE_STILL_LOADING, duration_t() };
 | 
			
		||||
	}
 | 
			
		||||
	return { QImage(), MEDIATYPE_IO_ERROR, zero_duration };
 | 
			
		||||
	return { QImage(), MEDIATYPE_IO_ERROR, duration_t() };
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Fetch a picture based on its original filename. If there is a translated filename (obtained either
 | 
			
		||||
| 
						 | 
				
			
			@ -140,7 +140,7 @@ Thumbnailer::Thumbnail Thumbnailer::getHashedImage(const QString &filename, bool
 | 
			
		|||
	// If there is a translated filename, try that first.
 | 
			
		||||
	// Note that we set the default type to io-error, so that if we didn't try
 | 
			
		||||
	// the local filename first, we will load the file from the canonical filename.
 | 
			
		||||
	Thumbnail thumbnail { QImage(), MEDIATYPE_IO_ERROR, zero_duration };
 | 
			
		||||
	Thumbnail thumbnail { QImage(), MEDIATYPE_IO_ERROR, duration_t() };
 | 
			
		||||
	if (localFilename != filename)
 | 
			
		||||
		thumbnail = fetchImage(localFilename, filename, tryDownload);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -187,7 +187,7 @@ Thumbnailer::Thumbnail Thumbnailer::getPictureThumbnailFromStream(QDataStream &s
 | 
			
		|||
{
 | 
			
		||||
	QImage res;
 | 
			
		||||
	stream >> res;
 | 
			
		||||
	return { std::move(res), MEDIATYPE_PICTURE, zero_duration };
 | 
			
		||||
	return { std::move(res), MEDIATYPE_PICTURE, duration_t() };
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void Thumbnailer::markVideoThumbnail(QImage &img)
 | 
			
		||||
| 
						 | 
				
			
			@ -210,7 +210,7 @@ Thumbnailer::Thumbnail Thumbnailer::getVideoThumbnailFromStream(QDataStream &str
 | 
			
		|||
	// Likewise test the duration and number of pictures for sanity (no videos longer than 10 h,
 | 
			
		||||
	// no more than 10000 pictures).
 | 
			
		||||
	if (stream.status() != QDataStream::Ok || duration > 36000 || numPics > 10000)
 | 
			
		||||
		return { QImage(), MEDIATYPE_VIDEO, zero_duration };
 | 
			
		||||
		return { QImage(), MEDIATYPE_VIDEO, duration_t() };
 | 
			
		||||
 | 
			
		||||
	// If the file didn't contain an image, but user turned on thumbnail extraction, schedule thumbnail
 | 
			
		||||
	// for extraction. TODO: save failure to extract thumbnails to disk so that thumbnailing
 | 
			
		||||
| 
						 | 
				
			
			@ -240,7 +240,7 @@ Thumbnailer::Thumbnail Thumbnailer::getThumbnailFromCache(const QString &picture
 | 
			
		|||
{
 | 
			
		||||
	QString filename = thumbnailFileName(picture_filename);
 | 
			
		||||
	if (filename.isEmpty())
 | 
			
		||||
		return { QImage(), MEDIATYPE_UNKNOWN, zero_duration };
 | 
			
		||||
		return { QImage(), MEDIATYPE_UNKNOWN, duration_t() };
 | 
			
		||||
	QFile file(filename);
 | 
			
		||||
 | 
			
		||||
	if (prefs.auto_recalculate_thumbnails) {
 | 
			
		||||
| 
						 | 
				
			
			@ -254,13 +254,13 @@ Thumbnailer::Thumbnail Thumbnailer::getThumbnailFromCache(const QString &picture
 | 
			
		|||
			if (pictureTime.isValid() && thumbnailTime.isValid() && thumbnailTime < pictureTime) {
 | 
			
		||||
				// Both files exist, have valid timestamps and thumbnail was calculated before picture.
 | 
			
		||||
				// Return an empty thumbnail to signal recalculation of the thumbnail
 | 
			
		||||
				return { QImage(), MEDIATYPE_UNKNOWN, zero_duration };
 | 
			
		||||
				return { QImage(), MEDIATYPE_UNKNOWN, duration_t() };
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (!file.open(QIODevice::ReadOnly))
 | 
			
		||||
		return { QImage(), MEDIATYPE_UNKNOWN, zero_duration };
 | 
			
		||||
		return { QImage(), MEDIATYPE_UNKNOWN, duration_t() };
 | 
			
		||||
	QDataStream stream(&file);
 | 
			
		||||
 | 
			
		||||
	// Each thumbnail file is composed of a media-type and an image file.
 | 
			
		||||
| 
						 | 
				
			
			@ -271,8 +271,8 @@ Thumbnailer::Thumbnail Thumbnailer::getThumbnailFromCache(const QString &picture
 | 
			
		|||
	switch (type) {
 | 
			
		||||
	case MEDIATYPE_PICTURE:	return getPictureThumbnailFromStream(stream);
 | 
			
		||||
	case MEDIATYPE_VIDEO:	return getVideoThumbnailFromStream(stream, picture_filename);
 | 
			
		||||
	case MEDIATYPE_UNKNOWN:	return { unknownImage, MEDIATYPE_UNKNOWN, zero_duration };
 | 
			
		||||
	default:		return { QImage(), MEDIATYPE_UNKNOWN, zero_duration };
 | 
			
		||||
	case MEDIATYPE_UNKNOWN:	return { unknownImage, MEDIATYPE_UNKNOWN, duration_t() };
 | 
			
		||||
	default:		return { QImage(), MEDIATYPE_UNKNOWN, duration_t() };
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -319,7 +319,7 @@ Thumbnailer::Thumbnail Thumbnailer::fetchVideoThumbnail(const QString &filename,
 | 
			
		|||
		return { videoImage, MEDIATYPE_VIDEO, duration };
 | 
			
		||||
	} else {
 | 
			
		||||
		// Video-thumbnailing is disabled. Write a thumbnail without picture.
 | 
			
		||||
		return addVideoThumbnailToCache(originalFilename, duration, QImage(), zero_duration);
 | 
			
		||||
		return addVideoThumbnailToCache(originalFilename, duration, QImage(), duration_t());
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -337,7 +337,7 @@ Thumbnailer::Thumbnail Thumbnailer::addPictureThumbnailToCache(const QString &pi
 | 
			
		|||
		stream << thumbnail;
 | 
			
		||||
		file.commit();
 | 
			
		||||
	}
 | 
			
		||||
	return { thumbnail, MEDIATYPE_PICTURE, zero_duration };
 | 
			
		||||
	return { thumbnail, MEDIATYPE_PICTURE, duration_t() };
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
Thumbnailer::Thumbnail Thumbnailer::addUnknownThumbnailToCache(const QString &picture_filename)
 | 
			
		||||
| 
						 | 
				
			
			@ -348,7 +348,7 @@ Thumbnailer::Thumbnail Thumbnailer::addUnknownThumbnailToCache(const QString &pi
 | 
			
		|||
		QDataStream stream(&file);
 | 
			
		||||
		stream << (quint32)MEDIATYPE_UNKNOWN;
 | 
			
		||||
	}
 | 
			
		||||
	return { unknownImage, MEDIATYPE_UNKNOWN, zero_duration };
 | 
			
		||||
	return { unknownImage, MEDIATYPE_UNKNOWN, duration_t() };
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void Thumbnailer::frameExtracted(QString filename, QImage thumbnail, duration_t duration, duration_t offset)
 | 
			
		||||
| 
						 | 
				
			
			@ -374,7 +374,7 @@ void Thumbnailer::frameExtractionFailed(QString filename, duration_t duration)
 | 
			
		|||
{
 | 
			
		||||
	// Frame extraction failed, but this was due to ffmpeg not starting
 | 
			
		||||
	// add to the thumbnail cache as a video image with unknown thumbnail.
 | 
			
		||||
	addVideoThumbnailToCache(filename, duration, QImage(), zero_duration);
 | 
			
		||||
	addVideoThumbnailToCache(filename, duration, QImage(), duration_t());
 | 
			
		||||
	QMutexLocker l(&lock);
 | 
			
		||||
	workingOn.remove(filename);
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -435,7 +435,7 @@ void Thumbnailer::imageDownloaded(QString filename)
 | 
			
		|||
 | 
			
		||||
void Thumbnailer::imageDownloadFailed(QString filename)
 | 
			
		||||
{
 | 
			
		||||
	emit thumbnailChanged(filename, failImage, zero_duration);
 | 
			
		||||
	emit thumbnailChanged(filename, failImage, duration_t());
 | 
			
		||||
	QMutexLocker l(&lock);
 | 
			
		||||
	workingOn.remove(filename);
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -497,7 +497,7 @@ int parse_txt_file(const char *filename, const char *csv, struct divelog *log)
 | 
			
		|||
		bool has_depth = false, has_setpoint = false, has_ndl = false;
 | 
			
		||||
		char *lineptr;
 | 
			
		||||
		int prev_time = 0;
 | 
			
		||||
		cylinder_t cyl = empty_cylinder;
 | 
			
		||||
		cylinder_t cyl;
 | 
			
		||||
 | 
			
		||||
		struct dive *dive;
 | 
			
		||||
		struct divecomputer *dc;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -168,7 +168,7 @@ static dc_status_t parse_gasmixes(device_data_t *devdata, struct dive *dive, dc_
 | 
			
		|||
 | 
			
		||||
	clear_cylinder_table(&dive->cylinders);
 | 
			
		||||
	for (i = 0; i < std::max(ngases, ntanks); i++) {
 | 
			
		||||
		cylinder_t cyl = empty_cylinder;
 | 
			
		||||
		cylinder_t cyl;
 | 
			
		||||
		cyl.cylinder_use = NOT_USED;
 | 
			
		||||
 | 
			
		||||
		if (i < ngases) {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -149,7 +149,7 @@ static void parse_dives(int log_version, const unsigned char *buf, unsigned int
 | 
			
		|||
 | 
			
		||||
		/* Just the main cylinder until we can handle the buddy cylinder porperly */
 | 
			
		||||
		for (i = 0; i < 1; i++) {
 | 
			
		||||
			cylinder_t cyl = empty_cylinder;
 | 
			
		||||
			cylinder_t cyl;
 | 
			
		||||
			fill_default_cylinder(dive, &cyl);
 | 
			
		||||
			add_cylinder(&dive->cylinders, i, cyl);
 | 
			
		||||
		}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -434,7 +434,7 @@ static void parse_cylinder_keyvalue(void *_cylinder, const char *key, const std:
 | 
			
		|||
 | 
			
		||||
static void parse_dive_cylinder(char *line, struct git_parser_state *state)
 | 
			
		||||
{
 | 
			
		||||
	cylinder_t cylinder = empty_cylinder;
 | 
			
		||||
	cylinder_t cylinder;
 | 
			
		||||
 | 
			
		||||
	for (;;) {
 | 
			
		||||
		char c;
 | 
			
		||||
| 
						 | 
				
			
			@ -795,7 +795,7 @@ static int get_divemode(const char *divemodestring) {
 | 
			
		|||
struct parse_event {
 | 
			
		||||
	std::string name;
 | 
			
		||||
	int has_divemode = false;
 | 
			
		||||
	struct event ev = { 0 };
 | 
			
		||||
	struct event ev;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static void parse_event_keyvalue(void *_parse, const char *key, const std::string &value)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -24,13 +24,9 @@ struct DiveDeleter {
 | 
			
		|||
struct TripDeleter {
 | 
			
		||||
	void operator()(dive_trip *t) { free_trip(t); }
 | 
			
		||||
};
 | 
			
		||||
struct EventDeleter {
 | 
			
		||||
	void operator()(event *ev) { free(ev); }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
// Owning pointers to dive, dive_trip, dive_site and event objects.
 | 
			
		||||
using OwningDivePtr = std::unique_ptr<dive, DiveDeleter>;
 | 
			
		||||
using OwningTripPtr = std::unique_ptr<dive_trip, TripDeleter>;
 | 
			
		||||
using OwningEventPtr = std::unique_ptr<event, EventDeleter>;
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1000,7 +1000,7 @@ static void divinglog_place(const char *place, struct dive *d, struct parser_sta
 | 
			
		|||
static int divinglog_dive_match(struct dive *dive, const char *name, char *buf, struct parser_state *state)
 | 
			
		||||
{
 | 
			
		||||
	/* For cylinder related fields, we might have to create a cylinder first. */
 | 
			
		||||
	cylinder_t cyl = empty_cylinder;
 | 
			
		||||
	cylinder_t cyl;
 | 
			
		||||
	if (MATCH("tanktype", utf8_string, (char **)&cyl.type.description)) {
 | 
			
		||||
		cylinder_t *cyl0 = get_or_create_cylinder(dive, 0);
 | 
			
		||||
		free((void *)cyl0->type.description);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -63,7 +63,7 @@ void nonmatch(const char *type, const char *name, char *buffer)
 | 
			
		|||
 | 
			
		||||
void event_start(struct parser_state *state)
 | 
			
		||||
{
 | 
			
		||||
	memset(&state->cur_event, 0, sizeof(state->cur_event));
 | 
			
		||||
	state->cur_event = event();
 | 
			
		||||
	state->event_active = true;	/* Active */
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										13
									
								
								core/parse.h
									
										
									
									
									
								
							
							
						
						
									
										13
									
								
								core/parse.h
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -2,8 +2,6 @@
 | 
			
		|||
#ifndef PARSE_H
 | 
			
		||||
#define PARSE_H
 | 
			
		||||
 | 
			
		||||
#define MAX_EVENT_NAME 128
 | 
			
		||||
 | 
			
		||||
#include "event.h"
 | 
			
		||||
#include "equipment.h" // for cylinder_t
 | 
			
		||||
#include "extradata.h"
 | 
			
		||||
| 
						 | 
				
			
			@ -18,11 +16,6 @@
 | 
			
		|||
struct xml_params;
 | 
			
		||||
struct divelog;
 | 
			
		||||
 | 
			
		||||
typedef union {
 | 
			
		||||
	struct event event;
 | 
			
		||||
	char allocation[sizeof(struct event) + MAX_EVENT_NAME];
 | 
			
		||||
} event_allocation_t;
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Dive info as it is being built up..
 | 
			
		||||
 */
 | 
			
		||||
| 
						 | 
				
			
			@ -63,7 +56,7 @@ struct parser_state {
 | 
			
		|||
	struct divecomputer *cur_dc = nullptr;			/* non-owning */
 | 
			
		||||
	struct dive *cur_dive = nullptr;			/* owning */
 | 
			
		||||
	std::unique_ptr<dive_site> cur_dive_site;		/* owning */
 | 
			
		||||
	location_t cur_location { 0 };
 | 
			
		||||
	location_t cur_location;
 | 
			
		||||
	struct dive_trip *cur_trip = nullptr;			/* owning */
 | 
			
		||||
	struct sample *cur_sample = nullptr;			/* non-owning */
 | 
			
		||||
	struct picture cur_picture { 0 };			/* owning */
 | 
			
		||||
| 
						 | 
				
			
			@ -93,13 +86,11 @@ struct parser_state {
 | 
			
		|||
 | 
			
		||||
	sqlite3 *sql_handle = nullptr;				/* for SQL based parsers */
 | 
			
		||||
	bool event_active = false;
 | 
			
		||||
	event_allocation_t event_allocation;
 | 
			
		||||
	event cur_event;
 | 
			
		||||
	parser_state();
 | 
			
		||||
	~parser_state();
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#define cur_event event_allocation.event
 | 
			
		||||
 | 
			
		||||
void event_start(struct parser_state *state);
 | 
			
		||||
void event_end(struct parser_state *state);
 | 
			
		||||
struct divecomputer *get_dc(struct parser_state *state);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -10,8 +10,8 @@ struct dive;
 | 
			
		|||
 | 
			
		||||
struct picture {
 | 
			
		||||
	char *filename = nullptr;
 | 
			
		||||
	offset_t offset = { 0 };
 | 
			
		||||
	location_t location = { { 0 }, { 0 } };
 | 
			
		||||
	offset_t offset;
 | 
			
		||||
	location_t location;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/* loop through all pictures of a dive */
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -234,7 +234,7 @@ static void create_dive_from_plan(struct diveplan *diveplan, struct dive *dive,
 | 
			
		|||
	free_samples(dc);
 | 
			
		||||
	while ((ev = dc->events)) {
 | 
			
		||||
		dc->events = dc->events->next;
 | 
			
		||||
		free(ev);
 | 
			
		||||
		delete ev;
 | 
			
		||||
	}
 | 
			
		||||
	dp = diveplan->dp;
 | 
			
		||||
	/* Create first sample at time = 0, not based on dp because
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -7,6 +7,7 @@
 | 
			
		|||
 | 
			
		||||
#include <memory>
 | 
			
		||||
#include <string>
 | 
			
		||||
#include <array>
 | 
			
		||||
#include <vector>
 | 
			
		||||
 | 
			
		||||
enum velocity_t {
 | 
			
		||||
| 
						 | 
				
			
			@ -32,7 +33,7 @@ struct divecomputer;
 | 
			
		|||
 * sensor data for a given cylinder
 | 
			
		||||
 */
 | 
			
		||||
struct plot_pressure_data {
 | 
			
		||||
	int data[NUM_PLOT_PRESSURES];
 | 
			
		||||
	std::array<int, NUM_PLOT_PRESSURES> data;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct plot_data {
 | 
			
		||||
| 
						 | 
				
			
			@ -42,8 +43,8 @@ struct plot_data {
 | 
			
		|||
	/* Depth info */
 | 
			
		||||
	int depth = 0;
 | 
			
		||||
	int ceiling = 0;
 | 
			
		||||
	int ceilings[16] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
 | 
			
		||||
	int percentages[16] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
 | 
			
		||||
	std::array<int, 16> ceilings;
 | 
			
		||||
	std::array<int, 16> percentages;
 | 
			
		||||
	int ndl = 0;
 | 
			
		||||
	int tts = 0;
 | 
			
		||||
	int rbt = 0;
 | 
			
		||||
| 
						 | 
				
			
			@ -55,10 +56,10 @@ struct plot_data {
 | 
			
		|||
	int running_sum = 0;
 | 
			
		||||
	struct gas_pressures pressures;
 | 
			
		||||
	// TODO: make pressure_t default to 0
 | 
			
		||||
	pressure_t o2pressure = { 0 };  // for rebreathers, this is consensus measured po2, or setpoint otherwise. 0 for OC.
 | 
			
		||||
	pressure_t o2sensor[MAX_O2_SENSORS] = {{ 0 }, { 0 }, { 0 }, { 0 }, { 0 }, { 0 }}; //for rebreathers with several sensors
 | 
			
		||||
	pressure_t o2setpoint = { 0 };
 | 
			
		||||
	pressure_t scr_OC_pO2 = { 0 };
 | 
			
		||||
	pressure_t o2pressure;  // for rebreathers, this is consensus measured po2, or setpoint otherwise. 0 for OC.
 | 
			
		||||
	std::array<pressure_t, MAX_O2_SENSORS> o2sensor; //for rebreathers with several sensors
 | 
			
		||||
	pressure_t o2setpoint;
 | 
			
		||||
	pressure_t scr_OC_pO2;
 | 
			
		||||
	int mod = 0, ead = 0, end = 0, eadd = 0;
 | 
			
		||||
	velocity_t velocity = STABLE;
 | 
			
		||||
	int speed = 0;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -97,13 +97,6 @@ stats_summary calculate_stats_summary(bool selected_only)
 | 
			
		|||
	int current_month = 0;
 | 
			
		||||
	int prev_month = 0, prev_year = 0;
 | 
			
		||||
	dive_trip_t *trip_ptr = nullptr;
 | 
			
		||||
	//stats_t stats = { 0 };
 | 
			
		||||
 | 
			
		||||
	//if (divelog.dives->nr > 0) {
 | 
			
		||||
	//	stats.shortest_time.seconds = divelog.dives->dives[0]->duration.seconds;
 | 
			
		||||
	//	stats.min_depth.mm = divelog.dives->dives[0]->maxdepth.mm;
 | 
			
		||||
	//	stats.selection_size = divelog.dives->nr;
 | 
			
		||||
	//}
 | 
			
		||||
 | 
			
		||||
	stats_summary out;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -318,7 +311,7 @@ bool is_cylinder_prot(const struct dive *dive, int idx)
 | 
			
		|||
/* Returns a vector with dive->cylinders.nr entries */
 | 
			
		||||
std::vector<volume_t> get_gas_used(struct dive *dive)
 | 
			
		||||
{
 | 
			
		||||
	std::vector<volume_t> gases(dive->cylinders.nr, volume_t { 0 });
 | 
			
		||||
	std::vector<volume_t> gases(dive->cylinders.nr);
 | 
			
		||||
	for (int idx = 0; idx < dive->cylinders.nr; idx++) {
 | 
			
		||||
		cylinder_t *cyl = get_cylinder(dive, idx);
 | 
			
		||||
		pressure_t start, end;
 | 
			
		||||
| 
						 | 
				
			
			@ -351,7 +344,7 @@ std::pair<volume_t, volume_t> selected_dives_gas_parts()
 | 
			
		|||
{
 | 
			
		||||
	int i;
 | 
			
		||||
	struct dive *d;
 | 
			
		||||
	volume_t o2_tot = { 0 }, he_tot = { 0 };
 | 
			
		||||
	volume_t o2_tot, he_tot;
 | 
			
		||||
	for_each_dive (i, d) {
 | 
			
		||||
		if (!d->selected || d->invalid)
 | 
			
		||||
			continue;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -24,25 +24,25 @@ struct dive;
 | 
			
		|||
struct stats_t
 | 
			
		||||
{
 | 
			
		||||
	int period = 0;
 | 
			
		||||
	duration_t total_time = { 0 };
 | 
			
		||||
	duration_t total_time ;
 | 
			
		||||
	/* total time of dives with non-zero average depth */
 | 
			
		||||
	duration_t total_average_depth_time = { 0 };
 | 
			
		||||
	duration_t total_average_depth_time;
 | 
			
		||||
	/* avg_time is simply total_time / nr -- let's not keep this */
 | 
			
		||||
	duration_t shortest_time = { 0 };
 | 
			
		||||
	duration_t longest_time = { 0 };
 | 
			
		||||
	depth_t max_depth = { 0 };
 | 
			
		||||
	depth_t min_depth = { 0 };
 | 
			
		||||
	depth_t avg_depth = { 0 };
 | 
			
		||||
	depth_t combined_max_depth = { 0 };
 | 
			
		||||
	volume_t max_sac = { 0 };
 | 
			
		||||
	volume_t min_sac = { 0 };
 | 
			
		||||
	volume_t avg_sac = { 0 };
 | 
			
		||||
	temperature_t max_temp = { 0 };
 | 
			
		||||
	temperature_t min_temp = { 0 };
 | 
			
		||||
	temperature_sum_t combined_temp = { 0 };
 | 
			
		||||
	duration_t shortest_time;
 | 
			
		||||
	duration_t longest_time;
 | 
			
		||||
	depth_t max_depth;
 | 
			
		||||
	depth_t min_depth;
 | 
			
		||||
	depth_t avg_depth;
 | 
			
		||||
	depth_t combined_max_depth;
 | 
			
		||||
	volume_t max_sac;
 | 
			
		||||
	volume_t min_sac;
 | 
			
		||||
	volume_t avg_sac;
 | 
			
		||||
	temperature_t max_temp;
 | 
			
		||||
	temperature_t min_temp;
 | 
			
		||||
	temperature_sum_t combined_temp;
 | 
			
		||||
	unsigned int combined_count = 0;
 | 
			
		||||
	unsigned int selection_size = 0;
 | 
			
		||||
	duration_t total_sac_time = { 0 };
 | 
			
		||||
	duration_t total_sac_time;
 | 
			
		||||
	bool is_year = false;
 | 
			
		||||
	bool is_trip = false;
 | 
			
		||||
	std::string location;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										26
									
								
								core/units.h
									
										
									
									
									
								
							
							
						
						
									
										26
									
								
								core/units.h
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -69,54 +69,52 @@ typedef int64_t timestamp_t;
 | 
			
		|||
 | 
			
		||||
typedef struct
 | 
			
		||||
{
 | 
			
		||||
	int32_t seconds; // durations up to 34 yrs
 | 
			
		||||
	int32_t seconds = 0; // durations up to 34 yrs
 | 
			
		||||
} duration_t;
 | 
			
		||||
 | 
			
		||||
static const duration_t zero_duration = { 0 };
 | 
			
		||||
 | 
			
		||||
typedef struct
 | 
			
		||||
{
 | 
			
		||||
	int32_t seconds; // offsets up to +/- 34 yrs
 | 
			
		||||
	int32_t seconds = 0; // offsets up to +/- 34 yrs
 | 
			
		||||
} offset_t;
 | 
			
		||||
 | 
			
		||||
typedef struct
 | 
			
		||||
{
 | 
			
		||||
	int32_t mm;
 | 
			
		||||
	int32_t mm = 0;
 | 
			
		||||
} depth_t; // depth to 2000 km
 | 
			
		||||
 | 
			
		||||
typedef struct
 | 
			
		||||
{
 | 
			
		||||
	int32_t mbar; // pressure up to 2000 bar
 | 
			
		||||
	int32_t mbar = 0; // pressure up to 2000 bar
 | 
			
		||||
} pressure_t;
 | 
			
		||||
 | 
			
		||||
typedef struct
 | 
			
		||||
{
 | 
			
		||||
	uint16_t mbar;
 | 
			
		||||
	uint16_t mbar = 0;
 | 
			
		||||
} o2pressure_t; // pressure up to 65 bar
 | 
			
		||||
 | 
			
		||||
typedef struct
 | 
			
		||||
{
 | 
			
		||||
	int16_t degrees;
 | 
			
		||||
	int16_t degrees = 0;
 | 
			
		||||
} bearing_t; // compass bearing
 | 
			
		||||
 | 
			
		||||
typedef struct
 | 
			
		||||
{
 | 
			
		||||
	uint32_t mkelvin; // up to 4 MK (temperatures in K are always positive)
 | 
			
		||||
	uint32_t mkelvin = 0; // up to 4 MK (temperatures in K are always positive)
 | 
			
		||||
} temperature_t;
 | 
			
		||||
 | 
			
		||||
typedef struct
 | 
			
		||||
{
 | 
			
		||||
	uint64_t mkelvin; // up to 18446744073 MK (temperatures in K are always positive)
 | 
			
		||||
	uint64_t mkelvin = 0; // up to 18446744073 MK (temperatures in K are always positive)
 | 
			
		||||
} temperature_sum_t;
 | 
			
		||||
 | 
			
		||||
typedef struct
 | 
			
		||||
{
 | 
			
		||||
	int mliter;
 | 
			
		||||
	int mliter = 0;
 | 
			
		||||
} volume_t;
 | 
			
		||||
 | 
			
		||||
typedef struct
 | 
			
		||||
{
 | 
			
		||||
	int permille;
 | 
			
		||||
	int permille = 0;
 | 
			
		||||
} fraction_t;
 | 
			
		||||
 | 
			
		||||
typedef struct
 | 
			
		||||
| 
						 | 
				
			
			@ -126,15 +124,13 @@ typedef struct
 | 
			
		|||
 | 
			
		||||
typedef struct
 | 
			
		||||
{
 | 
			
		||||
	int udeg;
 | 
			
		||||
	int udeg = 0;
 | 
			
		||||
} degrees_t;
 | 
			
		||||
 | 
			
		||||
typedef struct pos {
 | 
			
		||||
	degrees_t lat, lon;
 | 
			
		||||
} location_t;
 | 
			
		||||
 | 
			
		||||
static const location_t zero_location = { { 0 }, { 0 }};
 | 
			
		||||
 | 
			
		||||
extern void parse_location(const char *, location_t *);
 | 
			
		||||
 | 
			
		||||
static inline bool has_location(const location_t *loc)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -70,7 +70,7 @@ void VideoFrameExtractor::processItem(QString originalFilename, QString filename
 | 
			
		|||
 | 
			
		||||
	// Determine the time where we want to extract the image.
 | 
			
		||||
	// If the duration is < 10 sec, just snap the first frame
 | 
			
		||||
	duration_t position = { 0 };
 | 
			
		||||
	duration_t position;
 | 
			
		||||
	if (duration.seconds > 10) {
 | 
			
		||||
		// We round to second-precision. To be sure that we don't attempt reading past the
 | 
			
		||||
		// video's end, round down by one second.
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -217,7 +217,7 @@ static location_t parseGpsText(const QString &text)
 | 
			
		|||
	double lat, lon;
 | 
			
		||||
	if (parseGpsText(text.trimmed(), &lat, &lon))
 | 
			
		||||
		return create_location(lat, lon);
 | 
			
		||||
	return zero_location;
 | 
			
		||||
	return location_t();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Check if GPS text is parseable
 | 
			
		||||
| 
						 | 
				
			
			@ -263,7 +263,7 @@ void LocationInformationWidget::initFields(dive_site *ds)
 | 
			
		|||
		DiveFilter::instance()->startFilterDiveSites(QVector<dive_site *>{ ds });
 | 
			
		||||
		filter_model.invalidate();
 | 
			
		||||
	} else {
 | 
			
		||||
		filter_model.set(0, zero_location);
 | 
			
		||||
		filter_model.set(0, location_t());
 | 
			
		||||
		clearLabels();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -348,7 +348,7 @@ void LocationInformationWidget::reverseGeocode()
 | 
			
		|||
	Command::editDiveSiteTaxonomy(ds, taxonomy);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
DiveLocationFilterProxyModel::DiveLocationFilterProxyModel(QObject *) : currentLocation(zero_location)
 | 
			
		||||
DiveLocationFilterProxyModel::DiveLocationFilterProxyModel(QObject *)
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -669,7 +669,6 @@ void DiveLocationLineEdit::setCurrentDiveSite(struct dive *d)
 | 
			
		|||
		currentLocation = dive_get_gps_location(d);
 | 
			
		||||
	} else {
 | 
			
		||||
		currDs = nullptr;
 | 
			
		||||
		currentLocation = zero_location;
 | 
			
		||||
	}
 | 
			
		||||
	if (!currDs)
 | 
			
		||||
		clear();
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -422,7 +422,7 @@ QWidget *DoubleSpinBoxDelegate::createEditor(QWidget *parent, const QStyleOption
 | 
			
		|||
	return w;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
LocationFilterDelegate::LocationFilterDelegate(QObject *) : currentLocation(zero_location)
 | 
			
		||||
LocationFilterDelegate::LocationFilterDelegate(QObject *)
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -423,7 +423,7 @@ void TabDiveInformation::on_atmPressVal_editingFinished()
 | 
			
		|||
 | 
			
		||||
void TabDiveInformation::updateTextBox(int event) // Either the text box has been edited or the pressure type has changed.
 | 
			
		||||
{                                       // Either way this gets a numeric value and puts it on the text box atmPressVal,
 | 
			
		||||
	pressure_t atmpress = { 0 };    // then stores it in dive->surface_pressure.The undo stack for the text box content is
 | 
			
		||||
	pressure_t atmpress;            // then stores it in dive->surface_pressure.The undo stack for the text box content is
 | 
			
		||||
	double altitudeVal;             // maintained even though two independent events trigger saving the text box contents.
 | 
			
		||||
	dive *currentDive = parent.currentDive;
 | 
			
		||||
	if (currentDive) {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -911,7 +911,7 @@ struct DiveSiteChange {
 | 
			
		|||
	std::unique_ptr<dive_site> createdDs; // not-null if we created a dive site.
 | 
			
		||||
 | 
			
		||||
	dive_site *editDs = nullptr; // not-null if we are supposed to edit an existing dive site.
 | 
			
		||||
	location_t location = zero_location; // new value of the location if we edit an existing dive site.
 | 
			
		||||
	location_t location; // new value of the location if we edit an existing dive site.
 | 
			
		||||
 | 
			
		||||
	bool changed = false; // true if either a dive site or the dive was changed.
 | 
			
		||||
};
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -17,8 +17,7 @@ CylindersModel::CylindersModel(bool planner, QObject *parent) : CleanerTableMode
 | 
			
		|||
	dcNr(-1),
 | 
			
		||||
	inPlanner(planner),
 | 
			
		||||
	numRows(0),
 | 
			
		||||
	tempRow(-1),
 | 
			
		||||
	tempCyl(empty_cylinder)
 | 
			
		||||
	tempRow(-1)
 | 
			
		||||
{
 | 
			
		||||
	//	enum {REMOVE, TYPE, SIZE, WORKINGPRESS, START, END, O2, HE, DEPTH, MOD, MND, USE, WORKINGPRESS_INT, SIZE_INT, SENSORS};
 | 
			
		||||
	setHeaderDataStrings(QStringList() << "" << tr("Type") << tr("Size") << tr("Work press.") << tr("Start press.") << tr("End press.") << tr("O₂%") << tr("He%")
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -122,9 +122,9 @@ void DivePlannerPointsModel::loadFromDive(dive *dIn, int dcNrIn)
 | 
			
		|||
	const struct event *evd = NULL;
 | 
			
		||||
	enum divemode_t current_divemode = UNDEF_COMP_TYPE;
 | 
			
		||||
	cylinders.updateDive(d, dcNr);
 | 
			
		||||
	duration_t lasttime = { 0 };
 | 
			
		||||
	duration_t lastrecordedtime = {};
 | 
			
		||||
	duration_t newtime = {};
 | 
			
		||||
	duration_t lasttime;
 | 
			
		||||
	duration_t lastrecordedtime;
 | 
			
		||||
	duration_t newtime;
 | 
			
		||||
 | 
			
		||||
	clear();
 | 
			
		||||
	removeDeco();
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue