mirror of
https://github.com/subsurface/subsurface.git
synced 2025-02-19 22:16:15 +00:00
core: turn event-list of divecomputer into std::vector<>
This is a rather long commit, because it refactors lots of the event code from pointer to value semantics: pointers to entries in an std::vector<> are not stable, so better use indexes. To step through the event-list at diven time stamps, add *_loop classes, which encapsulate state that had to be manually handled before by the caller. I'm not happy about the interface, but it tries to mirror the one we had before. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
This commit is contained in:
parent
8ddc960fa0
commit
27dbdd35c6
36 changed files with 644 additions and 821 deletions
|
@ -16,14 +16,15 @@
|
|||
|
||||
static int depthAtTime(const plot_info &pi, duration_t time);
|
||||
|
||||
DiveEventItem::DiveEventItem(const struct dive *d, struct event *ev, struct gasmix lastgasmix,
|
||||
DiveEventItem::DiveEventItem(const struct dive *d, int idx, const struct event &ev, struct gasmix lastgasmix,
|
||||
const plot_info &pi, DiveCartesianAxis *hAxis, DiveCartesianAxis *vAxis,
|
||||
int speed, const DivePixmaps &pixmaps, QGraphicsItem *parent) : DivePixmapItem(parent),
|
||||
vAxis(vAxis),
|
||||
hAxis(hAxis),
|
||||
idx(idx),
|
||||
ev(ev),
|
||||
dive(d),
|
||||
depth(depthAtTime(pi, ev->time))
|
||||
depth(depthAtTime(pi, ev.time))
|
||||
{
|
||||
setFlag(ItemIgnoresTransformations);
|
||||
|
||||
|
@ -36,27 +37,17 @@ DiveEventItem::~DiveEventItem()
|
|||
{
|
||||
}
|
||||
|
||||
const struct event *DiveEventItem::getEvent() const
|
||||
{
|
||||
return ev;
|
||||
}
|
||||
|
||||
struct event *DiveEventItem::getEventMutable()
|
||||
{
|
||||
return ev;
|
||||
}
|
||||
|
||||
void DiveEventItem::setupPixmap(struct gasmix lastgasmix, const DivePixmaps &pixmaps)
|
||||
{
|
||||
event_severity severity = get_event_severity(ev);
|
||||
if (ev->name.empty()) {
|
||||
if (ev.name.empty()) {
|
||||
setPixmap(pixmaps.warning);
|
||||
} else if (same_string_caseinsensitive(ev->name.c_str(), "modechange")) {
|
||||
if (ev->value == 0)
|
||||
} else if (same_string_caseinsensitive(ev.name.c_str(), "modechange")) {
|
||||
if (ev.value == 0)
|
||||
setPixmap(pixmaps.bailout);
|
||||
else
|
||||
setPixmap(pixmaps.onCCRLoop);
|
||||
} else if (ev->type == SAMPLE_EVENT_BOOKMARK) {
|
||||
} else if (ev.type == SAMPLE_EVENT_BOOKMARK) {
|
||||
setPixmap(pixmaps.bookmark);
|
||||
setOffset(QPointF(0.0, -pixmap().height()));
|
||||
} else if (event_is_gaschange(ev)) {
|
||||
|
@ -84,10 +75,10 @@ void DiveEventItem::setupPixmap(struct gasmix lastgasmix, const DivePixmaps &pix
|
|||
else
|
||||
setPixmap(pixmaps.gaschangeEAN);
|
||||
}
|
||||
} else if ((((ev->flags & SAMPLE_FLAGS_SEVERITY_MASK) >> SAMPLE_FLAGS_SEVERITY_SHIFT) == 1) ||
|
||||
} else if ((((ev.flags & SAMPLE_FLAGS_SEVERITY_MASK) >> SAMPLE_FLAGS_SEVERITY_SHIFT) == 1) ||
|
||||
// those are useless internals of the dive computer
|
||||
same_string_caseinsensitive(ev->name.c_str(), "heading") ||
|
||||
(same_string_caseinsensitive(ev->name.c_str(), "SP change") && ev->time.seconds == 0)) {
|
||||
same_string_caseinsensitive(ev.name.c_str(), "heading") ||
|
||||
(same_string_caseinsensitive(ev.name.c_str(), "SP change") && ev.time.seconds == 0)) {
|
||||
// 2 cases:
|
||||
// a) some dive computers have heading in every sample
|
||||
// b) at t=0 we might have an "SP change" to indicate dive type
|
||||
|
@ -102,19 +93,19 @@ void DiveEventItem::setupPixmap(struct gasmix lastgasmix, const DivePixmaps &pix
|
|||
setPixmap(pixmaps.warning);
|
||||
} else if (severity == EVENT_SEVERITY_ALARM) {
|
||||
setPixmap(pixmaps.violation);
|
||||
} else if (same_string_caseinsensitive(ev->name.c_str(), "violation") || // generic libdivecomputer
|
||||
same_string_caseinsensitive(ev->name.c_str(), "Safety stop violation") || // the rest are from the Uemis downloader
|
||||
same_string_caseinsensitive(ev->name.c_str(), "pO₂ ascend alarm") ||
|
||||
same_string_caseinsensitive(ev->name.c_str(), "RGT alert") ||
|
||||
same_string_caseinsensitive(ev->name.c_str(), "Dive time alert") ||
|
||||
same_string_caseinsensitive(ev->name.c_str(), "Low battery alert") ||
|
||||
same_string_caseinsensitive(ev->name.c_str(), "Speed alarm")) {
|
||||
} else if (same_string_caseinsensitive(ev.name.c_str(), "violation") || // generic libdivecomputer
|
||||
same_string_caseinsensitive(ev.name.c_str(), "Safety stop violation") || // the rest are from the Uemis downloader
|
||||
same_string_caseinsensitive(ev.name.c_str(), "pO₂ ascend alarm") ||
|
||||
same_string_caseinsensitive(ev.name.c_str(), "RGT alert") ||
|
||||
same_string_caseinsensitive(ev.name.c_str(), "Dive time alert") ||
|
||||
same_string_caseinsensitive(ev.name.c_str(), "Low battery alert") ||
|
||||
same_string_caseinsensitive(ev.name.c_str(), "Speed alarm")) {
|
||||
setPixmap(pixmaps.violation);
|
||||
} else if (same_string_caseinsensitive(ev->name.c_str(), "non stop time") || // generic libdivecomputer
|
||||
same_string_caseinsensitive(ev->name.c_str(), "safety stop") ||
|
||||
same_string_caseinsensitive(ev->name.c_str(), "safety stop (voluntary)") ||
|
||||
same_string_caseinsensitive(ev->name.c_str(), "Tank change suggested") || // Uemis downloader
|
||||
same_string_caseinsensitive(ev->name.c_str(), "Marker")) {
|
||||
} else if (same_string_caseinsensitive(ev.name.c_str(), "non stop time") || // generic libdivecomputer
|
||||
same_string_caseinsensitive(ev.name.c_str(), "safety stop") ||
|
||||
same_string_caseinsensitive(ev.name.c_str(), "safety stop (voluntary)") ||
|
||||
same_string_caseinsensitive(ev.name.c_str(), "Tank change suggested") || // Uemis downloader
|
||||
same_string_caseinsensitive(ev.name.c_str(), "Marker")) {
|
||||
setPixmap(pixmaps.info);
|
||||
} else {
|
||||
// we should do some guessing based on the type / name of the event;
|
||||
|
@ -126,9 +117,9 @@ void DiveEventItem::setupPixmap(struct gasmix lastgasmix, const DivePixmaps &pix
|
|||
void DiveEventItem::setupToolTipString(struct gasmix lastgasmix)
|
||||
{
|
||||
// we display the event on screen - so translate
|
||||
QString name = gettextFromC::tr(ev->name.c_str());
|
||||
int value = ev->value;
|
||||
int type = ev->type;
|
||||
QString name = gettextFromC::tr(ev.name.c_str());
|
||||
int value = ev.value;
|
||||
int type = ev.type;
|
||||
|
||||
if (event_is_gaschange(ev)) {
|
||||
struct icd_data icd_data;
|
||||
|
@ -137,8 +128,8 @@ void DiveEventItem::setupToolTipString(struct gasmix lastgasmix)
|
|||
name += gasname(mix);
|
||||
|
||||
/* Do we have an explicit cylinder index? Show it. */
|
||||
if (ev->gas.index >= 0)
|
||||
name += tr(" (cyl. %1)").arg(ev->gas.index + 1);
|
||||
if (ev.gas.index >= 0)
|
||||
name += tr(" (cyl. %1)").arg(ev.gas.index + 1);
|
||||
bool icd = isobaric_counterdiffusion(lastgasmix, mix, &icd_data);
|
||||
if (icd_data.dHe < 0) {
|
||||
name += qasprintf_loc("\n%s %s:%+.3g%% %s:%+.3g%%%s%+.3g%%",
|
||||
|
@ -147,25 +138,25 @@ void DiveEventItem::setupToolTipString(struct gasmix lastgasmix)
|
|||
qPrintable(tr("ΔN₂")), icd_data.dN2 / 10.0,
|
||||
icd ? ">" : "<", lrint(-icd_data.dHe / 5.0) / 10.0);
|
||||
}
|
||||
} else if (ev->name == "modechange") {
|
||||
name += QString(": %1").arg(gettextFromC::tr(divemode_text_ui[ev->value]));
|
||||
} else if (ev.name == "modechange") {
|
||||
name += QString(": %1").arg(gettextFromC::tr(divemode_text_ui[ev.value]));
|
||||
} else if (value) {
|
||||
if (type == SAMPLE_EVENT_PO2 && ev->name == "SP change") {
|
||||
if (type == SAMPLE_EVENT_PO2 && ev.name == "SP change") {
|
||||
name += QString(": %1bar").arg((double)value / 1000, 0, 'f', 1);
|
||||
} else if (type == SAMPLE_EVENT_CEILING && ev->name == "planned waypoint above ceiling") {
|
||||
} else if (type == SAMPLE_EVENT_CEILING && ev.name == "planned waypoint above ceiling") {
|
||||
const char *depth_unit;
|
||||
double depth_value = get_depth_units(value*1000, NULL, &depth_unit);
|
||||
name += QString(": %1%2").arg((int) round(depth_value)).arg(depth_unit);
|
||||
} else {
|
||||
name += QString(": %1").arg(value);
|
||||
}
|
||||
} else if (type == SAMPLE_EVENT_PO2 && ev->name == "SP change") {
|
||||
} else if (type == SAMPLE_EVENT_PO2 && ev.name == "SP change") {
|
||||
// this is a bad idea - we are abusing an existing event type that is supposed to
|
||||
// warn of high or low pO₂ and are turning it into a setpoint change event
|
||||
name += ":\n" + tr("Manual switch to OC");
|
||||
} else {
|
||||
name += ev->flags & SAMPLE_FLAGS_BEGIN ? tr(" begin", "Starts with space!") :
|
||||
ev->flags & SAMPLE_FLAGS_END ? tr(" end", "Starts with space!") : "";
|
||||
name += ev.flags & SAMPLE_FLAGS_BEGIN ? tr(" begin", "Starts with space!") :
|
||||
ev.flags & SAMPLE_FLAGS_END ? tr(" end", "Starts with space!") : "";
|
||||
}
|
||||
setToolTip(QString("<img height=\"16\" src=\":status-warning-icon\"> ") + name);
|
||||
}
|
||||
|
@ -188,31 +179,31 @@ static int depthAtTime(const plot_info &pi, duration_t time)
|
|||
}
|
||||
|
||||
bool DiveEventItem::isInteresting(const struct dive *d, const struct divecomputer *dc,
|
||||
const struct event *ev, const plot_info &pi,
|
||||
const struct event &ev, const plot_info &pi,
|
||||
int firstSecond, int lastSecond)
|
||||
{
|
||||
/*
|
||||
* Ignore items outside of plot range
|
||||
*/
|
||||
if (ev->time.seconds < firstSecond || ev->time.seconds >= lastSecond)
|
||||
if (ev.time.seconds < firstSecond || ev.time.seconds >= lastSecond)
|
||||
return false;
|
||||
|
||||
/*
|
||||
* Some gas change events are special. Some dive computers just tell us the initial gas this way.
|
||||
* Don't bother showing those
|
||||
*/
|
||||
if (ev->name == "gaschange" &&
|
||||
(ev->time.seconds == 0 ||
|
||||
(!dc->samples.empty() && ev->time.seconds == dc->samples[0].time.seconds) ||
|
||||
depthAtTime(pi, ev->time) < SURFACE_THRESHOLD))
|
||||
if (ev.name == "gaschange" &&
|
||||
(ev.time.seconds == 0 ||
|
||||
(!dc->samples.empty() && ev.time.seconds == dc->samples[0].time.seconds) ||
|
||||
depthAtTime(pi, ev.time) < SURFACE_THRESHOLD))
|
||||
return false;
|
||||
|
||||
/*
|
||||
* Some divecomputers give "surface" events that just aren't interesting.
|
||||
* Like at the beginning or very end of a dive. Well, duh.
|
||||
*/
|
||||
if (ev->name == "surface") {
|
||||
int time = ev->time.seconds;
|
||||
if (ev.name == "surface") {
|
||||
int time = ev.time.seconds;
|
||||
if (time <= 30 || time + 30 >= (int)dc->duration.seconds)
|
||||
return false;
|
||||
}
|
||||
|
@ -221,15 +212,12 @@ bool DiveEventItem::isInteresting(const struct dive *d, const struct divecompute
|
|||
|
||||
void DiveEventItem::recalculatePos()
|
||||
{
|
||||
if (!ev)
|
||||
return;
|
||||
|
||||
if (depth == DEPTH_NOT_FOUND) {
|
||||
hide();
|
||||
return;
|
||||
}
|
||||
setVisible(!ev->hidden && !is_event_type_hidden(ev));
|
||||
double x = hAxis->posAtValue(ev->time.seconds);
|
||||
setVisible(!ev.hidden && !is_event_type_hidden(&ev));
|
||||
double x = hAxis->posAtValue(ev.time.seconds);
|
||||
double y = vAxis->posAtValue(depth);
|
||||
setPos(x, y);
|
||||
}
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
#define DIVEEVENTITEM_H
|
||||
|
||||
#include "divepixmapitem.h"
|
||||
#include "core/event.h"
|
||||
|
||||
class DiveCartesianAxis;
|
||||
class DivePixmaps;
|
||||
|
@ -12,17 +13,15 @@ struct plot_info;
|
|||
class DiveEventItem : public DivePixmapItem {
|
||||
Q_OBJECT
|
||||
public:
|
||||
DiveEventItem(const struct dive *d, struct event *ev, struct gasmix lastgasmix,
|
||||
DiveEventItem(const struct dive *d, int idx, const struct event &ev, struct gasmix lastgasmix,
|
||||
const struct plot_info &pi, DiveCartesianAxis *hAxis, DiveCartesianAxis *vAxis,
|
||||
int speed, const DivePixmaps &pixmaps, QGraphicsItem *parent = nullptr);
|
||||
~DiveEventItem();
|
||||
const struct event *getEvent() const;
|
||||
struct event *getEventMutable();
|
||||
void eventVisibilityChanged(const QString &eventName, bool visible);
|
||||
void setVerticalAxis(DiveCartesianAxis *axis, int speed);
|
||||
void setHorizontalAxis(DiveCartesianAxis *axis);
|
||||
static bool isInteresting(const struct dive *d, const struct divecomputer *dc,
|
||||
const struct event *ev, const struct plot_info &pi,
|
||||
const struct event &ev, const struct plot_info &pi,
|
||||
int firstSecond, int lastSecond);
|
||||
|
||||
private:
|
||||
|
@ -31,7 +30,9 @@ private:
|
|||
void recalculatePos();
|
||||
DiveCartesianAxis *vAxis;
|
||||
DiveCartesianAxis *hAxis;
|
||||
struct event *ev;
|
||||
public:
|
||||
int idx;
|
||||
struct event ev;
|
||||
const struct dive *dive;
|
||||
int depth;
|
||||
};
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
#include "divepercentageitem.h"
|
||||
#include "divecartesianaxis.h"
|
||||
#include "core/dive.h"
|
||||
#include "core/event.h"
|
||||
#include "core/profile.h"
|
||||
|
||||
#include <array>
|
||||
|
@ -105,7 +106,7 @@ void DivePercentageItem::replot(const dive *d, const struct divecomputer *dc, co
|
|||
int x = 0;
|
||||
QRgb *scanline = (QRgb *)img.scanLine(line);
|
||||
QRgb color = 0;
|
||||
const struct event *ev = NULL;
|
||||
gasmix_loop loop(*d, *dc);
|
||||
for (int i = 0; i < pi.nr; i++) {
|
||||
const plot_data &item = pi.entry[i];
|
||||
int sec = item.sec;
|
||||
|
@ -114,7 +115,7 @@ void DivePercentageItem::replot(const dive *d, const struct divecomputer *dc, co
|
|||
continue;
|
||||
|
||||
double value = item.percentages[tissue];
|
||||
struct gasmix gasmix = get_gasmix(d, dc, sec, &ev, gasmix_air);
|
||||
struct gasmix gasmix = loop.next(sec);
|
||||
int inert = get_n2(gasmix) + get_he(gasmix);
|
||||
color = colorScale(value, inert);
|
||||
if (nextX >= width)
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
#include "core/pref.h"
|
||||
#include "core/profile.h"
|
||||
#include "core/qthelper.h" // for decoMode()
|
||||
#include "core/range.h"
|
||||
#include "core/subsurface-float.h"
|
||||
#include "core/subsurface-string.h"
|
||||
#include "core/settings/qPrefDisplay.h"
|
||||
|
@ -550,23 +551,20 @@ void ProfileScene::plotDive(const struct dive *dIn, int dcIn, DivePlannerPointsM
|
|||
// while all other items are up there on the constructor.
|
||||
qDeleteAll(eventItems);
|
||||
eventItems.clear();
|
||||
struct event *event = currentdc->events;
|
||||
struct gasmix lastgasmix = get_gasmix_at_time(d, currentdc, duration_t{1});
|
||||
struct gasmix lastgasmix = get_gasmix_at_time(*d, *currentdc, duration_t{1});
|
||||
|
||||
while (event) {
|
||||
for (auto [idx, event]: enumerated_range(currentdc->events)) {
|
||||
// if print mode is selected only draw headings, SP change, gas events or bookmark event
|
||||
if (printMode) {
|
||||
if (event->name.empty() ||
|
||||
!(event->name == "heading" ||
|
||||
(event->name == "SP change" && event->time.seconds == 0) ||
|
||||
if (event.name.empty() ||
|
||||
!(event.name == "heading" ||
|
||||
(event.name == "SP change" && event.time.seconds == 0) ||
|
||||
event_is_gaschange(event) ||
|
||||
event->type == SAMPLE_EVENT_BOOKMARK)) {
|
||||
event = event->next;
|
||||
event.type == SAMPLE_EVENT_BOOKMARK))
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (DiveEventItem::isInteresting(d, currentdc, event, plotInfo, firstSecond, lastSecond)) {
|
||||
auto item = new DiveEventItem(d, event, lastgasmix, plotInfo,
|
||||
auto item = new DiveEventItem(d, idx, event, lastgasmix, plotInfo,
|
||||
timeAxis, profileYAxis, animSpeed, *pixmaps);
|
||||
item->setZValue(2);
|
||||
addItem(item);
|
||||
|
@ -574,7 +572,6 @@ void ProfileScene::plotDive(const struct dive *dIn, int dcIn, DivePlannerPointsM
|
|||
}
|
||||
if (event_is_gaschange(event))
|
||||
lastgasmix = get_gasmix_from_event(d, event);
|
||||
event = event->next;
|
||||
}
|
||||
|
||||
QString dcText = QString::fromStdString(get_dc_nickname(currentdc));
|
||||
|
|
|
@ -559,8 +559,8 @@ void ProfileWidget2::contextMenuEvent(QContextMenuEvent *event)
|
|||
DiveEventItem *item = dynamic_cast<DiveEventItem *>(sceneItem);
|
||||
|
||||
// Add or edit Gas Change
|
||||
if (d && item && event_is_gaschange(item->getEvent())) {
|
||||
int eventTime = item->getEvent()->time.seconds;
|
||||
if (d && item && event_is_gaschange(item->ev)) {
|
||||
int eventTime = item->ev.time.seconds;
|
||||
QMenu *gasChange = m.addMenu(tr("Edit Gas Change"));
|
||||
for (int i = 0; i < d->cylinders.nr; i++) {
|
||||
const cylinder_t *cylinder = get_cylinder(d, i);
|
||||
|
@ -579,10 +579,9 @@ void ProfileWidget2::contextMenuEvent(QContextMenuEvent *event)
|
|||
m.addAction(tr("Add setpoint change"), [this, seconds]() { ProfileWidget2::addSetpointChange(seconds); });
|
||||
m.addAction(tr("Add bookmark"), [this, seconds]() { addBookmark(seconds); });
|
||||
m.addAction(tr("Split dive into two"), [this, seconds]() { splitDive(seconds); });
|
||||
const struct event *ev = NULL;
|
||||
enum divemode_t divemode = UNDEF_COMP_TYPE;
|
||||
|
||||
get_current_divemode(get_dive_dc_const(d, dc), seconds, &ev, &divemode);
|
||||
divemode_loop loop(*get_dive_dc_const(d, dc));
|
||||
divemode_t divemode = loop.next(seconds);
|
||||
QMenu *changeMode = m.addMenu(tr("Change divemode"));
|
||||
if (divemode != OC)
|
||||
changeMode->addAction(gettextFromC::tr(divemode_text_ui[OC]),
|
||||
|
@ -595,23 +594,22 @@ void ProfileWidget2::contextMenuEvent(QContextMenuEvent *event)
|
|||
[this, seconds](){ addDivemodeSwitch(seconds, PSCR); });
|
||||
|
||||
if (DiveEventItem *item = dynamic_cast<DiveEventItem *>(sceneItem)) {
|
||||
const struct event *dcEvent = item->getEvent();
|
||||
m.addAction(tr("Remove event"), [this,item] { removeEvent(item); });
|
||||
m.addAction(tr("Hide event"), [this, item] { hideEvent(item); });
|
||||
m.addAction(tr("Hide events of type '%1'").arg(event_type_name(dcEvent)),
|
||||
m.addAction(tr("Hide events of type '%1'").arg(event_type_name(item->ev)),
|
||||
[this, item] { hideEventType(item); });
|
||||
if (dcEvent->type == SAMPLE_EVENT_BOOKMARK)
|
||||
if (item->ev.type == SAMPLE_EVENT_BOOKMARK)
|
||||
m.addAction(tr("Edit name"), [this, item] { editName(item); });
|
||||
#if 0 // TODO::: FINISH OR DISABLE
|
||||
QPointF scenePos = mapToScene(event->pos());
|
||||
int idx = getEntryFromPos(scenePos);
|
||||
// this shows how to figure out if we should ask the user if they want adjust interpolated pressures
|
||||
// at either side of a gas change
|
||||
if (dcEvent->type == SAMPLE_EVENT_GASCHANGE || dcEvent->type == SAMPLE_EVENT_GASCHANGE2) {
|
||||
if (item->ev->type == SAMPLE_EVENT_GASCHANGE || item->ev->type == SAMPLE_EVENT_GASCHANGE2) {
|
||||
int gasChangeIdx = idx;
|
||||
while (gasChangeIdx > 0) {
|
||||
--gasChangeIdx;
|
||||
if (plotInfo.entry[gasChangeIdx].sec <= dcEvent->time.seconds)
|
||||
if (plotInfo.entry[gasChangeIdx].sec <= item->ev->time.seconds)
|
||||
break;
|
||||
}
|
||||
const struct plot_data &gasChangeEntry = plotInfo.entry[newGasIdx];
|
||||
|
@ -650,8 +648,9 @@ void ProfileWidget2::contextMenuEvent(QContextMenuEvent *event)
|
|||
}
|
||||
m2->addAction(tr("All event types"), this, &ProfileWidget2::unhideEventTypes);
|
||||
}
|
||||
if (std::any_of(profileScene->eventItems.begin(), profileScene->eventItems.end(),
|
||||
[] (const DiveEventItem *item) { return item->getEvent()->hidden; }))
|
||||
const struct divecomputer *currentdc = get_dive_dc_const(d, dc);
|
||||
if (currentdc && std::any_of(currentdc->events.begin(), currentdc->events.end(),
|
||||
[] (auto &ev) { return ev.hidden; }))
|
||||
m.addAction(tr("Unhide individually hidden events of this dive"), this, &ProfileWidget2::unhideEvents);
|
||||
m.exec(event->globalPos());
|
||||
}
|
||||
|
@ -690,16 +689,18 @@ void ProfileWidget2::renameCurrentDC()
|
|||
|
||||
void ProfileWidget2::hideEvent(DiveEventItem *item)
|
||||
{
|
||||
item->getEventMutable()->hidden = true;
|
||||
struct divecomputer *currentdc = get_dive_dc(mutable_dive(), dc);
|
||||
int idx = item->idx;
|
||||
if (!currentdc || idx < 0 || static_cast<size_t>(idx) >= currentdc->events.size())
|
||||
return;
|
||||
currentdc->events[idx].hidden = true;
|
||||
item->hide();
|
||||
}
|
||||
|
||||
void ProfileWidget2::hideEventType(DiveEventItem *item)
|
||||
{
|
||||
const struct event *event = item->getEvent();
|
||||
|
||||
if (!event->name.empty()) {
|
||||
hide_event_type(event);
|
||||
if (!item->ev.name.empty()) {
|
||||
hide_event_type(&item->ev);
|
||||
|
||||
replot();
|
||||
}
|
||||
|
@ -707,10 +708,13 @@ void ProfileWidget2::hideEventType(DiveEventItem *item)
|
|||
|
||||
void ProfileWidget2::unhideEvents()
|
||||
{
|
||||
for (DiveEventItem *item: profileScene->eventItems) {
|
||||
item->getEventMutable()->hidden = false;
|
||||
struct divecomputer *currentdc = get_dive_dc(mutable_dive(), dc);
|
||||
if (!currentdc)
|
||||
return;
|
||||
for (auto &ev: currentdc->events)
|
||||
ev.hidden = false;
|
||||
for (DiveEventItem *item: profileScene->eventItems)
|
||||
item->show();
|
||||
}
|
||||
}
|
||||
|
||||
void ProfileWidget2::unhideEventTypes()
|
||||
|
@ -722,15 +726,12 @@ void ProfileWidget2::unhideEventTypes()
|
|||
|
||||
void ProfileWidget2::removeEvent(DiveEventItem *item)
|
||||
{
|
||||
struct event *event = item->getEventMutable();
|
||||
if (!event || !d)
|
||||
return;
|
||||
|
||||
const struct event &ev = item->ev;
|
||||
if (QMessageBox::question(this, TITLE_OR_TEXT(
|
||||
tr("Remove the selected event?"),
|
||||
tr("%1 @ %2:%3").arg(QString::fromStdString(event->name)).arg(event->time.seconds / 60).arg(event->time.seconds % 60, 2, 10, QChar('0'))),
|
||||
tr("%1 @ %2:%3").arg(QString::fromStdString(ev.name)).arg(ev.time.seconds / 60).arg(ev.time.seconds % 60, 2, 10, QChar('0'))),
|
||||
QMessageBox::Ok | QMessageBox::Cancel) == QMessageBox::Ok)
|
||||
Command::removeEvent(mutable_dive(), dc, event);
|
||||
Command::removeEvent(mutable_dive(), dc, item->idx);
|
||||
}
|
||||
|
||||
void ProfileWidget2::addBookmark(int seconds)
|
||||
|
@ -781,13 +782,12 @@ void ProfileWidget2::changeGas(int index, int newCylinderId)
|
|||
|
||||
void ProfileWidget2::editName(DiveEventItem *item)
|
||||
{
|
||||
struct event *event = item->getEventMutable();
|
||||
if (!event || !d)
|
||||
if (!d)
|
||||
return;
|
||||
bool ok;
|
||||
QString newName = QInputDialog::getText(this, tr("Edit name of bookmark"),
|
||||
tr("Custom name:"), QLineEdit::Normal,
|
||||
event->name.c_str(), &ok);
|
||||
item->ev.name.c_str(), &ok);
|
||||
if (ok && !newName.isEmpty()) {
|
||||
if (newName.length() > 22) { //longer names will display as garbage.
|
||||
QMessageBox lengthWarning;
|
||||
|
@ -795,7 +795,7 @@ void ProfileWidget2::editName(DiveEventItem *item)
|
|||
lengthWarning.exec();
|
||||
return;
|
||||
}
|
||||
Command::renameEvent(mutable_dive(), dc, event, qPrintable(newName));
|
||||
Command::renameEvent(mutable_dive(), dc, item->idx, newName.toStdString());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -80,17 +80,19 @@ void TankItem::setData(const struct dive *d, const struct divecomputer *dc, int
|
|||
return;
|
||||
|
||||
// start with the first gasmix and at the start of the plotted range
|
||||
const struct event *ev = NULL;
|
||||
struct gasmix gasmix = gasmix_air;
|
||||
gasmix = get_gasmix(d, dc, plotStartTime, &ev, gasmix);
|
||||
event_loop loop("gaschange");
|
||||
struct gasmix gasmix = gasmix_invalid;
|
||||
const struct event *ev;
|
||||
while ((ev = loop.next(*dc)) != nullptr && ev->time.seconds <= plotStartTime)
|
||||
gasmix = get_gasmix_from_event(d, *ev);
|
||||
|
||||
// work through all the gas changes and add the rectangle for each gas while it was used
|
||||
int startTime = plotStartTime;
|
||||
while (ev && (int)ev->time.seconds < plotEndTime) {
|
||||
createBar(startTime, ev->time.seconds, gasmix);
|
||||
startTime = ev->time.seconds;
|
||||
gasmix = get_gasmix_from_event(d, ev);
|
||||
ev = get_next_event(ev->next, "gaschange");
|
||||
gasmix = get_gasmix_from_event(d, *ev);
|
||||
ev = loop.next(*dc);
|
||||
}
|
||||
createBar(startTime, plotEndTime, gasmix);
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue