コード例 #1
0
void DivePercentageItem::modelDataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight)
{
	int sec = 0;

	// We don't have enougth data to calculate things, quit.
	if (!shouldCalculateStuff(topLeft, bottomRight))
		return;

	// Ignore empty values. a heart rate of 0 would be a bad sign.
	QPolygonF poly;
	for (int i = 0, modelDataCount = dataModel->rowCount(); i < modelDataCount; i++) {
		sec = dataModel->index(i, hDataColumn).data().toInt();
		QPointF point(hAxis->posAtValue(sec), vAxis->posAtValue(64 - 4 * tissueIndex));
		poly.append(point);
	}
	setPolygon(poly);

	if (texts.count())
		texts.last()->setAlignment(Qt::AlignLeft | Qt::AlignBottom);
}
コード例 #2
0
ファイル: diveprofileitem.cpp プロジェクト: ngot/subsurface
void DiveMeanDepthItem::modelDataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight)
{
	double meandepthvalue = 0.0;
	// We don't have enougth data to calculate things, quit.
	if (!shouldCalculateStuff(topLeft, bottomRight))
		return;

	QPolygonF poly;
	plot_data *entry = dataModel->data().entry;
	for (int i = 0, modelDataCount = dataModel->rowCount(); i < modelDataCount; i++, entry++) {
		// Ignore empty values
		if (entry->running_sum == 0 || entry->sec == 0)
			continue;

		meandepthvalue = entry->running_sum / entry->sec;
		QPointF point(hAxis->posAtValue(entry->sec), vAxis->posAtValue(meandepthvalue));
		poly.append(point);
	}
	lastRunningSum = meandepthvalue;
	setPolygon(poly);
	createTextItem();
}
コード例 #3
0
void PartialPressureGasItem::modelDataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight)
{
	//AbstractProfilePolygonItem::modelDataChanged();
	if (!shouldCalculateStuff(topLeft, bottomRight))
		return;

	plot_data *entry = dataModel->data().entry;
	QPolygonF poly;
	QPolygonF alertpoly;
	alertPolygons.clear();
	QSettings s;
	s.beginGroup("TecDetails");
	double threshould = s.value(threshouldKey).toDouble();
	bool inAlertFragment = false;
	for (int i = 0; i < dataModel->rowCount(); i++, entry++) {
		double value = dataModel->index(i, vDataColumn).data().toDouble();
		int time = dataModel->index(i, hDataColumn).data().toInt();
		QPointF point(hAxis->posAtValue(time), vAxis->posAtValue(value));
		poly.push_back(point);
		if (value >= threshould) {
			if (inAlertFragment) {
				alertPolygons.back().push_back(point);
			} else {
				alertpoly.clear();
				alertpoly.push_back(point);
				alertPolygons.append(alertpoly);
				inAlertFragment = true;
			}
		} else {
			inAlertFragment = false;
		}
	}
	setPolygon(poly);
	/*
	createPPLegend(trUtf8("pN" UTF8_SUBSCRIPT_2),getColor(PN2), legendPos);
	*/
}
コード例 #4
0
void DiveProfileItem::modelDataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight)
{
	bool eventAdded = false;
	if (!shouldCalculateStuff(topLeft, bottomRight))
		return;

	AbstractProfilePolygonItem::modelDataChanged(topLeft, bottomRight);
	if (polygon().isEmpty())
		return;

	show_reported_ceiling = prefs.dcceiling;
	reported_ceiling_in_red = prefs.redceiling;
	profileColor = getColor(DEPTH_BOTTOM);

	int currState = qobject_cast<ProfileWidget2 *>(scene()->views().first())->currentState;
	if (currState == ProfileWidget2::PLAN) {
		plot_data *entry = dataModel->data().entry;
		for (int i = 0; i < dataModel->rowCount(); i++, entry++) {
			int max = maxCeiling(i);
			// Don't scream if we violate the ceiling by a few cm
			if (entry->depth < max - 100) {
				profileColor = QColor(Qt::red);
				if (!eventAdded) {
					add_event(&displayed_dive.dc, entry->sec, SAMPLE_EVENT_CEILING, -1, max / 1000, "planned waypoint above ceiling");
					eventAdded = true;
				}
			}
		}
	}

	/* Show any ceiling we may have encountered */
	if (prefs.dcceiling && !prefs.redceiling) {
		QPolygonF p = polygon();
		plot_data *entry = dataModel->data().entry + dataModel->rowCount() - 1;
		for (int i = dataModel->rowCount() - 1; i >= 0; i--, entry--) {
			if (!entry->in_deco) {
				/* not in deco implies this is a safety stop, no ceiling */
				p.append(QPointF(hAxis->posAtValue(entry->sec), vAxis->posAtValue(0)));
			} else {
				p.append(QPointF(hAxis->posAtValue(entry->sec), vAxis->posAtValue(qMin(entry->stopdepth, entry->depth))));
			}
		}
		setPolygon(p);
	}

	// This is the blueish gradient that the Depth Profile should have.
	// It's a simple QLinearGradient with 2 stops, starting from top to bottom.
	QLinearGradient pat(0, polygon().boundingRect().top(), 0, polygon().boundingRect().bottom());
	pat.setColorAt(1, profileColor);
	pat.setColorAt(0, getColor(DEPTH_TOP));
	setBrush(QBrush(pat));

	int last = -1;
	for (int i = 0, count = dataModel->rowCount(); i < count; i++) {

		struct plot_data *entry = dataModel->data().entry + i;
		if (entry->depth < 2000)
			continue;

		if ((entry == entry->max[2]) && entry->depth / 100 != last) {
			plot_depth_sample(entry, Qt::AlignHCenter | Qt::AlignBottom, getColor(SAMPLE_DEEP));
			last = entry->depth / 100;
		}

		if ((entry == entry->min[2]) && entry->depth / 100 != last) {
			plot_depth_sample(entry, Qt::AlignHCenter | Qt::AlignTop, getColor(SAMPLE_SHALLOW));
			last = entry->depth / 100;
		}

		if (entry->depth != last)
			last = -1;
	}
}
コード例 #5
0
ファイル: diveprofileitem.cpp プロジェクト: ngot/subsurface
void DiveGasPressureItem::modelDataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight)
{
	// We don't have enougth data to calculate things, quit.
	if (!shouldCalculateStuff(topLeft, bottomRight))
		return;
	int last_index = -1;
	int o2mbar;
	QPolygonF boundingPoly, o2Poly; // This is the "Whole Item", but a pressure can be divided in N Polygons.
	polygons.clear();
	if (displayed_dive.dc.divemode == CCR)
		polygons.append(o2Poly);

	for (int i = 0, count = dataModel->rowCount(); i < count; i++) {
		o2mbar = 0;
		plot_data *entry = dataModel->data().entry + i;
		int mbar = GET_PRESSURE(entry);
		if (displayed_dive.dc.divemode == CCR)
			o2mbar = GET_O2CYLINDER_PRESSURE(entry);

		if (entry->cylinderindex != last_index) {
			polygons.append(QPolygonF()); // this is the polygon that will be actually drawn on screen.
			last_index = entry->cylinderindex;
		}
		if (!mbar) {
			continue;
		}
		if (o2mbar) {
			QPointF o2point(hAxis->posAtValue(entry->sec), vAxis->posAtValue(o2mbar));
			boundingPoly.push_back(o2point);
			polygons.first().push_back(o2point);
		}

		QPointF point(hAxis->posAtValue(entry->sec), vAxis->posAtValue(mbar));
		boundingPoly.push_back(point);    // The BoundingRect
		polygons.last().push_back(point); // The polygon thta will be plotted.
	}
	setPolygon(boundingPoly);
	qDeleteAll(texts);
	texts.clear();
	int mbar, cyl;
	int seen_cyl[MAX_CYLINDERS] = { false, };
	int last_pressure[MAX_CYLINDERS] = { 0, };
	int last_time[MAX_CYLINDERS] = { 0, };
	struct plot_data *entry;

	cyl = -1;
	o2mbar = 0;

	double print_y_offset[8][2] = { { 0, -0.5 }, { 0, -0.5 }, { 0, -0.5 }, { 0, -0.5 }, { 0, -0.5 } ,{ 0, -0.5 }, { 0, -0.5 }, { 0, -0.5 } };
	// CCR dives: These are offset values used to print the gas lables and pressures on a CCR dive profile at
	// appropriate Y-coordinates: One doublet of values for each of 8 cylinders.
	// Order of offsets within a doublet: gas lable offset; gas pressure offset.
	// The array is initialised with default values that apply to non-CCR dives.

	bool offsets_initialised = false;
	int o2cyl = -1, dilcyl = -1;
	QFlags<Qt::AlignmentFlag> alignVar= Qt::AlignTop, align_dil = Qt::AlignBottom, align_o2 = Qt::AlignTop;
	double axisRange = (vAxis->maximum() - vAxis->minimum())/1000;	// Convert axis pressure range to bar
	double axisLog = log10(log10(axisRange));
	for (int i = 0, count = dataModel->rowCount(); i < count; i++) {
		entry = dataModel->data().entry + i;
		mbar = GET_PRESSURE(entry);
		if (displayed_dive.dc.divemode == CCR && displayed_dive.oxygen_cylinder_index >= 0)
			o2mbar = GET_O2CYLINDER_PRESSURE(entry);

		if (o2mbar) {	// If there is an o2mbar value then this is a CCR dive. Then do:
			// The first time an o2 value is detected, see if the oxygen cyl pressure graph starts above or below the dil graph
			if (!offsets_initialised) {	// Initialise the parameters for placing the text correctly near the graph line:
				o2cyl = displayed_dive.oxygen_cylinder_index;
				dilcyl = displayed_dive.diluent_cylinder_index;
				if ((o2mbar > mbar)) {	// If above, write o2 start cyl pressure above graph and diluent pressure below graph:
					print_y_offset[o2cyl][0] = -7 * axisLog; // y offset for oxygen gas lable (above); pressure offsets=-0.5, already initialised
					print_y_offset[dilcyl][0] = 5 * axisLog; // y offset for diluent gas lable (below)
				} else {				// ... else write o2 start cyl pressure below graph:
					print_y_offset[o2cyl][0]  = 5 * axisLog; // o2 lable & pressure below graph; pressure offsets=-0.5, already initialised
					print_y_offset[dilcyl][0] = -7.8 * axisLog;  // and diluent lable above graph.
					align_dil = Qt::AlignTop;
					align_o2  = Qt::AlignBottom;
				}
				offsets_initialised = true;
			}

			if (!seen_cyl[displayed_dive.oxygen_cylinder_index]) {	//For o2, on the left of profile, write lable and pressure
				plotPressureValue(o2mbar, entry->sec, align_o2, print_y_offset[o2cyl][1]);
				plotGasValue(o2mbar, entry->sec, displayed_dive.cylinder[displayed_dive.oxygen_cylinder_index].gasmix, align_o2, print_y_offset[o2cyl][0]);
				seen_cyl[displayed_dive.oxygen_cylinder_index] = true;
			}
			last_pressure[displayed_dive.oxygen_cylinder_index] = o2mbar;
			last_time[displayed_dive.oxygen_cylinder_index] = entry->sec;
			alignVar = align_dil;
		}

		if (!mbar)
			continue;

		if (cyl != entry->cylinderindex) {	// Pressure value near the left hand edge of the profile - other cylinders:
			cyl = entry->cylinderindex;	// For each other cylinder, write the gas lable and pressure
			if (!seen_cyl[cyl]) {
				plotPressureValue(mbar, entry->sec, alignVar, print_y_offset[cyl][1]);
				plotGasValue(mbar, entry->sec, displayed_dive.cylinder[cyl].gasmix, align_dil, print_y_offset[cyl][0]);
				seen_cyl[cyl] = true;
			}
		}
		last_pressure[cyl] = mbar;
		last_time[cyl] = entry->sec;
	}

	for (cyl = 0; cyl < MAX_CYLINDERS; cyl++) {	// For each cylinder, on right hand side of profile, write cylinder pressure
		alignVar = ((o2cyl >= 0) && (cyl == displayed_dive.oxygen_cylinder_index)) ? align_o2 : align_dil;
		if (last_time[cyl]) {
			plotPressureValue(last_pressure[cyl], last_time[cyl], (alignVar | Qt::AlignLeft), print_y_offset[cyl][1]);
		}
	}
}
コード例 #6
0
void DiveGasPressureItem::modelDataChanged(const QModelIndex& topLeft, const QModelIndex& bottomRight)
{
	// We don't have enougth data to calculate things, quit.
	if (!shouldCalculateStuff(topLeft, bottomRight))
		return;
	int last_index = -1;
	QPolygonF boundingPoly; // This is the "Whole Item", but a pressure can be divided in N Polygons.
	polygons.clear();

	for (int i = 0, count = dataModel->rowCount(); i < count; i++) {
		plot_data* entry = dataModel->data().entry + i;
		int mbar = GET_PRESSURE(entry);

		if (entry->cylinderindex != last_index) {
			polygons.append(QPolygonF()); // this is the polygon that will be actually drawned on screen.
			last_index = entry->cylinderindex;
		}
		if (!mbar) {
			continue;
		}

		QPointF point(hAxis->posAtValue(entry->sec), vAxis->posAtValue(mbar));
		boundingPoly.push_back(point); // The BoundingRect
		polygons.last().push_back(point); // The polygon thta will be plotted.
	}
	setPolygon(boundingPoly);
	qDeleteAll(texts);
	texts.clear();
	int mbar, cyl;
	int seen_cyl[MAX_CYLINDERS] = { false, };
	int last_pressure[MAX_CYLINDERS] = { 0, };
	int last_time[MAX_CYLINDERS] = { 0, };
	struct plot_data *entry;
	struct dive *dive = getDiveById(dataModel->id());
	Q_ASSERT(dive != NULL);

	cyl = -1;
	for (int i = 0, count = dataModel->rowCount(); i < count; i++) {
		entry = dataModel->data().entry + i;
		mbar = GET_PRESSURE(entry);

		if (!mbar)
			continue;
		if (cyl != entry->cylinderindex) {
			cyl = entry->cylinderindex;
			if (!seen_cyl[cyl]) {
				plot_pressure_value(mbar, entry->sec, Qt::AlignRight | Qt::AlignTop);
				plot_gas_value(mbar, entry->sec, Qt::AlignRight | Qt::AlignBottom,
						get_o2(&dive->cylinder[cyl].gasmix),
						get_he(&dive->cylinder[cyl].gasmix));
				seen_cyl[cyl] = true;
			}
		}
		last_pressure[cyl] = mbar;
		last_time[cyl] = entry->sec;
	}

	for (cyl = 0; cyl < MAX_CYLINDERS; cyl++) {
		if (last_time[cyl]) {
			plot_pressure_value(last_pressure[cyl], last_time[cyl], Qt::AlignLeft | Qt::AlignTop);
		}
	}
}
コード例 #7
0
void DiveGasPressureItem::modelDataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight)
{
	// We don't have enougth data to calculate things, quit.
	if (!shouldCalculateStuff(topLeft, bottomRight))
		return;
	int last_index = -1;
	int o2mbar;
	QPolygonF boundingPoly, o2Poly; // This is the "Whole Item", but a pressure can be divided in N Polygons.
	polygons.clear();
	if (displayed_dive.dc.dctype == CCR)
		polygons.append(o2Poly);

	for (int i = 0, count = dataModel->rowCount(); i < count; i++) {
		o2mbar = 0;
		plot_data *entry = dataModel->data().entry + i;
		int mbar = GET_PRESSURE(entry);
		if (displayed_dive.dc.dctype == CCR)
			o2mbar = GET_O2CYLINDER_PRESSURE(entry);

		if (entry->cylinderindex != last_index) {
			polygons.append(QPolygonF()); // this is the polygon that will be actually drawned on screen.
			last_index = entry->cylinderindex;
		}
		if (!mbar) {
			continue;
		}
		if (o2mbar) {
			QPointF o2point(hAxis->posAtValue(entry->sec), vAxis->posAtValue(o2mbar));
			boundingPoly.push_back(o2point);
			polygons.first().push_back(o2point);
		}

		QPointF point(hAxis->posAtValue(entry->sec), vAxis->posAtValue(mbar));
		boundingPoly.push_back(point);    // The BoundingRect
		polygons.last().push_back(point); // The polygon thta will be plotted.
	}
	setPolygon(boundingPoly);
	qDeleteAll(texts);
	texts.clear();
	int mbar, cyl;
	int seen_cyl[MAX_CYLINDERS] = { false, };
	int last_pressure[MAX_CYLINDERS] = { 0, };
	int last_time[MAX_CYLINDERS] = { 0, };
	struct plot_data *entry;

	cyl = -1;
	o2mbar = 0;
	for (int i = 0, count = dataModel->rowCount(); i < count; i++) {
		entry = dataModel->data().entry + i;
		mbar = GET_PRESSURE(entry);
		if (displayed_dive.dc.dctype == CCR && displayed_dive.oxygen_cylinder_index >= 0)
			o2mbar = GET_O2CYLINDER_PRESSURE(entry);

		if (o2mbar) {
			if (!seen_cyl[displayed_dive.oxygen_cylinder_index]) {
				plotPressureValue(o2mbar, entry->sec, Qt::AlignRight | Qt::AlignBottom);
				plotGasValue(o2mbar, entry->sec, Qt::AlignRight | Qt::AlignBottom, displayed_dive.cylinder[displayed_dive.oxygen_cylinder_index].gasmix);
				seen_cyl[displayed_dive.oxygen_cylinder_index] = true;
			}
			last_pressure[displayed_dive.oxygen_cylinder_index] = o2mbar;
			last_time[displayed_dive.oxygen_cylinder_index] = entry->sec;
		}


		if (!mbar)
			continue;
		if (cyl != entry->cylinderindex) {
			cyl = entry->cylinderindex;
			if (!seen_cyl[cyl]) {
				plotPressureValue(mbar, entry->sec, Qt::AlignRight | Qt::AlignTop);
				plotGasValue(mbar, entry->sec, Qt::AlignRight | Qt::AlignBottom,
					       displayed_dive.cylinder[cyl].gasmix);
				seen_cyl[cyl] = true;
			}
		}
		last_pressure[cyl] = mbar;
		last_time[cyl] = entry->sec;
	}

	for (cyl = 0; cyl < MAX_CYLINDERS; cyl++) {
		if (last_time[cyl]) {
			plotPressureValue(last_pressure[cyl], last_time[cyl], Qt::AlignLeft | Qt::AlignTop);
		}
	}
}
コード例 #8
0
void DiveGasPressureItem::modelDataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight)
{
	// We don't have enougth data to calculate things, quit.
	if (!shouldCalculateStuff(topLeft, bottomRight))
		return;

	int plotted_cyl[MAX_CYLINDERS] = { false, };
	int last_plotted[MAX_CYLINDERS] = { 0, };
	QPolygonF poly[MAX_CYLINDERS];
	QPolygonF boundingPoly;
	polygons.clear();

	for (int i = 0, count = dataModel->rowCount(); i < count; i++) {
		struct plot_data *entry = dataModel->data().entry + i;

		for (int cyl = 0; cyl < MAX_CYLINDERS; cyl++) {
			int mbar = GET_PRESSURE(entry, cyl);
			int time = entry->sec;

			if (!mbar)
				continue;

			QPointF point(hAxis->posAtValue(time), vAxis->posAtValue(mbar));
			boundingPoly.push_back(point);

			if (plotted_cyl[cyl]) {
				/* Have we used this culinder in the last two minutes? Continue */
				if (time - last_plotted[cyl] <= 2*60) {
					poly[cyl].push_back(point);
					last_plotted[cyl] = time;
					continue;
				}

				/* Finish the previous one, start a new one */
				polygons.append(poly[cyl]);
				poly[cyl] = QPolygonF();
			}

			plotted_cyl[cyl] = true;
			last_plotted[cyl] = time;
			poly[cyl].push_back(point);
		}
	}

	for (int cyl = 0; cyl < MAX_CYLINDERS; cyl++) {
		if (!plotted_cyl[cyl])
			continue;
		polygons.append(poly[cyl]);
	}

	setPolygon(boundingPoly);
	qDeleteAll(texts);
	texts.clear();

	int seen_cyl[MAX_CYLINDERS] = { false, };
	int last_pressure[MAX_CYLINDERS] = { 0, };
	int last_time[MAX_CYLINDERS] = { 0, };

	// These are offset values used to print the gas lables and pressures on a
	// dive profile at appropriate Y-coordinates. We alternate aligning the
	// label and the gas pressure above and under the pressure line.
	// The values are historical, and we could try to pick the over/under
	// depending on whether this pressure is higher or lower than the average.
	// Right now it's just strictly alternating when you have multiple gas
	// pressures.

	QFlags<Qt::AlignmentFlag> alignVar = Qt::AlignTop;
	QFlags<Qt::AlignmentFlag> align[MAX_CYLINDERS];

	double axisRange = (vAxis->maximum() - vAxis->minimum())/1000;	// Convert axis pressure range to bar
	double axisLog = log10(log10(axisRange));

	for (int i = 0, count = dataModel->rowCount(); i < count; i++) {
		struct plot_data *entry = dataModel->data().entry + i;

		for (int cyl = 0; cyl < MAX_CYLINDERS; cyl++) {
			int mbar = GET_PRESSURE(entry, cyl);

			if (!mbar)
				continue;

			if (!seen_cyl[cyl]) {
				double value_y_offset, label_y_offset;

				// Magic Y offset depending on whether we're aliging
				// the top of the text or the bottom of the text to
				// the pressure line.
				value_y_offset = -0.5;
				if (alignVar & Qt::AlignTop) {
					label_y_offset = 5 * axisLog;
				} else {
					label_y_offset = -7 * axisLog;
				}
				plotPressureValue(mbar, entry->sec, alignVar, value_y_offset);
				plotGasValue(mbar, entry->sec, displayed_dive.cylinder[cyl].gasmix, alignVar, label_y_offset);
				seen_cyl[cyl] = true;

				/* Alternate alignment as we see cylinder use.. */
				align[cyl] = alignVar;
				alignVar ^= Qt::AlignTop | Qt::AlignBottom;
			}
			last_pressure[cyl] = mbar;
			last_time[cyl] = entry->sec;
		}
	}

	// For each cylinder, on right hand side of profile, write cylinder pressure
	for (int cyl = 0; cyl < MAX_CYLINDERS; cyl++) {
		if (last_time[cyl]) {
			double value_y_offset = -0.5;
			plotPressureValue(last_pressure[cyl], last_time[cyl], align[cyl] | Qt::AlignLeft, value_y_offset);
		}
	}
}