This commit is contained in:
bstoeger 2024-02-20 20:14:51 +00:00 committed by GitHub
commit 2424de3cd2
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
16 changed files with 179 additions and 120 deletions

View file

@ -51,7 +51,7 @@ SOURCES += subsurface-mobile-main.cpp \
core/divecomputer.c \
core/divefilter.cpp \
core/event.c \
core/eventname.cpp \
core/eventtype.cpp \
core/filterconstraint.cpp \
core/filterpreset.cpp \
core/divelist.c \
@ -202,7 +202,7 @@ HEADERS += \
core/dive.h \
core/divecomputer.h \
core/event.h \
core/eventname.h \
core/eventtype.h \
core/extradata.h \
core/git-access.h \
core/globals.h \

View file

@ -81,8 +81,8 @@ set(SUBSURFACE_CORE_LIB_SRCS
downloadfromdcthread.h
event.c
event.h
eventname.cpp
eventname.h
eventtype.cpp
eventtype.h
equipment.c
equipment.h
errorhelper.c

View file

@ -9,7 +9,7 @@
#include "divelog.h"
#include "divesite.h"
#include "event.h"
#include "eventname.h"
#include "eventtype.h"
#include "filterpreset.h"
#include "fulltext.h"
#include "interpolate.h"
@ -1319,7 +1319,7 @@ void clear_dive_file_data()
current_dive = NULL;
clear_divelog(&divelog);
clear_event_names();
clear_event_types();
reset_min_datafile_version();
clear_git_id();

View file

@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0
#include "event.h"
#include "eventname.h"
#include "eventtype.h"
#include "subsurface-string.h"
#include <string.h>
@ -80,7 +80,7 @@ struct event *create_event(unsigned int time, int type, int flags, int value, co
break;
}
remember_event_name(name, flags);
remember_event_type(ev);
return ev;
}
@ -102,3 +102,17 @@ bool same_event(const struct event *a, const struct event *b)
return 0;
return !strcmp(a->name, b->name);
}
extern enum event_severity get_event_severity(const struct event *ev)
{
switch (ev->flags & SAMPLE_FLAGS_SEVERITY_MASK) {
case SAMPLE_FLAGS_SEVERITY_INFO:
return EVENT_SEVERITY_INFO;
case SAMPLE_FLAGS_SEVERITY_WARN:
return EVENT_SEVERITY_WARN;
case SAMPLE_FLAGS_SEVERITY_ALARM:
return EVENT_SEVERITY_ALARM;
default:
return EVENT_SEVERITY_NONE;
}
}

View file

@ -12,6 +12,13 @@
extern "C" {
#endif
enum event_severity {
EVENT_SEVERITY_NONE = 0,
EVENT_SEVERITY_INFO,
EVENT_SEVERITY_WARN,
EVENT_SEVERITY_ALARM
};
/*
* 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.
@ -35,7 +42,8 @@ struct event {
struct gasmix mix;
} gas;
};
bool deleted;
bool deleted; // used internally in the parser and in fixup_dive().
bool hidden;
char name[];
};
@ -46,12 +54,12 @@ extern void free_events(struct event *ev);
extern struct event *create_event(unsigned int time, int type, int flags, int value, const char *name);
extern struct event *clone_event_rename(const struct event *ev, const char *name);
extern bool same_event(const struct event *a, const struct event *b);
extern enum event_severity get_event_severity(const struct event *ev);
/* Since C doesn't have parameter-based overloading, two versions of get_next_event. */
extern const struct event *get_next_event(const struct event *event, const char *name);
extern struct event *get_next_event_mutable(struct event *event, const char *name);
#ifdef __cplusplus
}
#endif

View file

@ -1,60 +0,0 @@
// SPDX-License-Identifier: GPL-2.0
#include "eventname.h"
#include "subsurface-string.h"
#include <string>
#include <vector>
#include <algorithm>
struct event_name {
std::string name;
int flags;
bool plot;
};
static std::vector<event_name> event_names;
// Small helper so that we can compare events to C-strings
static bool operator==(const event_name &en1, const event_name &en2)
{
return en1.name == en2.name && en1.flags == en2.flags;
}
extern "C" void clear_event_names()
{
event_names.clear();
}
extern "C" void remember_event_name(const char *eventname, const int flags)
{
if (empty_string(eventname))
return;
if (std::find(event_names.begin(), event_names.end(), event_name{ eventname, flags }) != event_names.end())
return;
event_names.push_back({ eventname, flags, true });
}
extern "C" bool is_event_hidden(const char *eventname, const int flags)
{
auto it = std::find(event_names.begin(), event_names.end(), event_name{ eventname, flags });
return it != event_names.end() && !it->plot;
}
extern "C" void hide_similar_events(const char *eventname, const int flags)
{
auto it = std::find(event_names.begin(), event_names.end(), event_name{ eventname, flags });
if (it != event_names.end())
it->plot = false;
}
extern "C" void show_all_events()
{
for (event_name &en: event_names)
en.plot = true;
}
extern "C" bool any_events_hidden()
{
return std::any_of(event_names.begin(), event_names.end(),
[] (const event_name &en) { return !en.plot; });
}

View file

@ -1,21 +0,0 @@
// collect all event names and whether we display events of that type
// SPDX-License-Identifier: GPL-2.0
#ifndef EVENTNAME_H
#define EVENTNAME_H
#ifdef __cplusplus
extern "C" {
#endif
extern void clear_event_names(void);
extern void remember_event_name(const char *eventname, const int flags);
extern bool is_event_hidden(const char *eventname, const int flags);
extern void hide_similar_events(const char *eventname, const int flags);
extern void show_all_events();
extern bool any_events_hidden();
#ifdef __cplusplus
}
#endif
#endif

67
core/eventtype.cpp Normal file
View file

@ -0,0 +1,67 @@
// SPDX-License-Identifier: GPL-2.0
#include "eventtype.h"
#include "event.h"
#include "subsurface-string.h"
#include <string>
#include <vector>
#include <algorithm>
struct event_type {
std::string name;
event_severity severity;
bool plot;
event_type(const struct event *ev) :
name(ev->name),
severity(get_event_severity(ev)),
plot(true)
{
}
};
static std::vector<event_type> event_types;
static bool operator==(const event_type &en1, const event_type &en2)
{
return en1.name == en2.name && en1.severity == en2.severity;
}
extern "C" void clear_event_types()
{
event_types.clear();
}
extern "C" void remember_event_type(const struct event *ev)
{
if (empty_string(ev->name))
return;
event_type type(ev);
if (std::find(event_types.begin(), event_types.end(), type) != event_types.end())
return;
event_types.push_back(std::move(type));
}
extern "C" bool is_event_type_hidden(const struct event *ev)
{
auto it = std::find(event_types.begin(), event_types.end(), ev);
return it != event_types.end() && !it->plot;
}
extern "C" void hide_event_type(const struct event *ev)
{
auto it = std::find(event_types.begin(), event_types.end(), ev);
if (it != event_types.end())
it->plot = false;
}
extern "C" void show_all_event_types()
{
for (event_type &e: event_types)
e.plot = true;
}
extern "C" bool any_event_types_hidden()
{
return std::any_of(event_types.begin(), event_types.end(),
[] (const event_type &e) { return !e.plot; });
}

21
core/eventtype.h Normal file
View file

@ -0,0 +1,21 @@
// collect all event names and whether we display events of that type
// SPDX-License-Identifier: GPL-2.0
#ifndef EVENTNAME_H
#define EVENTNAME_H
#ifdef __cplusplus
extern "C" {
#endif
extern void clear_event_types(void);
extern void remember_event_type(const struct event *ev);
extern bool is_event_type_hidden(const struct event *ev);
extern void hide_event_type(const struct event *ev);
extern void show_all_event_types();
extern bool any_event_types_hidden();
#ifdef __cplusplus
}
#endif
#endif

View file

@ -1,6 +1,7 @@
#include "string-format.h"
#include "dive.h"
#include "divesite.h"
#include "event.h"
#include "format.h"
#include "qthelper.h"
#include "subsurface-string.h"
@ -327,3 +328,26 @@ QString formatTripTitleWithDives(const dive_trip *trip)
return formatTripTitle(trip) + " " +
gettextFromC::tr("(%n dive(s))", "", nr);
}
static QString formatEventSeverity(const event *ev)
{
switch(get_event_severity(ev)) {
case EVENT_SEVERITY_INFO: return gettextFromC::tr("info");
case EVENT_SEVERITY_WARN: return gettextFromC::tr("warn");
case EVENT_SEVERITY_ALARM: return gettextFromC::tr("alarm");
default: return QString();
}
}
QString formatEventType(const event *ev)
{
if (!ev || empty_string(ev->name))
return QString();
QString eventName = QString::fromUtf8(ev->name);
QString severity = formatEventSeverity(ev);
if (severity.isEmpty())
return eventName;
return QStringLiteral("%1 (%2)").arg(eventName, severity);
}

View file

@ -7,6 +7,7 @@
struct dive;
struct dive_trip;
struct event;
QString formatSac(const dive *d);
QString formatNotes(const dive *d);
@ -31,5 +32,6 @@ QString formatDayOfWeek(int day);
QString formatMinutes(int seconds);
QString formatTripTitle(const dive_trip *trip);
QString formatTripTitleWithDives(const dive_trip *trip);
QString formatEventType(const event *ev);
#endif

View file

@ -4,7 +4,7 @@
#include "profile-widget/divepixmapcache.h"
#include "profile-widget/animationfunctions.h"
#include "core/event.h"
#include "core/eventname.h"
#include "core/eventtype.h"
#include "core/format.h"
#include "core/profile.h"
#include "core/gettextfromc.h"
@ -47,6 +47,7 @@ struct event *DiveEventItem::getEventMutable()
void DiveEventItem::setupPixmap(struct gasmix lastgasmix, const DivePixmaps &pixmaps)
{
event_severity severity = get_event_severity(ev);
if (empty_string(ev->name)) {
setPixmap(pixmaps.warning);
} else if (same_string_caseinsensitive(ev->name, "modechange")) {
@ -82,12 +83,8 @@ void DiveEventItem::setupPixmap(struct gasmix lastgasmix, const DivePixmaps &pix
else
setPixmap(pixmaps.gaschangeEAN);
}
#ifdef SAMPLE_FLAGS_SEVERITY_SHIFT
} else if ((((ev->flags & SAMPLE_FLAGS_SEVERITY_MASK) >> SAMPLE_FLAGS_SEVERITY_SHIFT) == 1) ||
// those are useless internals of the dive computer
#else
} else if (
#endif
same_string_caseinsensitive(ev->name, "heading") ||
(same_string_caseinsensitive(ev->name, "SP change") && ev->time.seconds == 0)) {
// 2 cases:
@ -98,14 +95,12 @@ void DiveEventItem::setupPixmap(struct gasmix lastgasmix, const DivePixmaps &pix
// that allows tooltips to work when we don't want to show a specific
// pixmap for an event, but want to show the event value in the tooltip
setPixmap(pixmaps.transparent);
#ifdef SAMPLE_FLAGS_SEVERITY_SHIFT
} else if (((ev->flags & SAMPLE_FLAGS_SEVERITY_MASK) >> SAMPLE_FLAGS_SEVERITY_SHIFT) == 2) {
} else if (severity == EVENT_SEVERITY_INFO) {
setPixmap(pixmaps.info);
} else if (((ev->flags & SAMPLE_FLAGS_SEVERITY_MASK) >> SAMPLE_FLAGS_SEVERITY_SHIFT) == 3) {
} else if (severity == EVENT_SEVERITY_WARN) {
setPixmap(pixmaps.warning);
} else if (((ev->flags & SAMPLE_FLAGS_SEVERITY_MASK) >> SAMPLE_FLAGS_SEVERITY_SHIFT) == 4) {
} else if (severity == EVENT_SEVERITY_ALARM) {
setPixmap(pixmaps.violation);
#endif
} else if (same_string_caseinsensitive(ev->name, "violation") || // generic libdivecomputer
same_string_caseinsensitive(ev->name, "Safety stop violation") || // the rest are from the Uemis downloader
same_string_caseinsensitive(ev->name, "pO₂ ascend alarm") ||
@ -224,11 +219,6 @@ bool DiveEventItem::isInteresting(const struct dive *d, const struct divecompute
return true;
}
bool DiveEventItem::shouldBeHidden()
{
return is_event_hidden(ev->name, ev->flags);
}
void DiveEventItem::recalculatePos()
{
if (!ev)
@ -238,7 +228,7 @@ void DiveEventItem::recalculatePos()
hide();
return;
}
setVisible(!shouldBeHidden());
setVisible(!ev->hidden && !is_event_type_hidden(ev));
double x = hAxis->posAtValue(ev->time.seconds);
double y = vAxis->posAtValue(depth);
setPos(x, y);

View file

@ -21,7 +21,6 @@ public:
void eventVisibilityChanged(const QString &eventName, bool visible);
void setVerticalAxis(DiveCartesianAxis *axis, int speed);
void setHorizontalAxis(DiveCartesianAxis *axis);
bool shouldBeHidden();
static bool isInteresting(const struct dive *d, const struct divecomputer *dc,
const struct event *ev, const struct plot_info &pi,
int firstSecond, int lastSecond);

View file

@ -40,7 +40,7 @@ DivePixmaps::DivePixmaps(int dpr) : dpr(dpr)
gaschangeEANICD = createPixmap(":gaschange-ean-ICD-icon", sz_bigger);
gaschangeEAN = createPixmap(":gaschange-ean-icon", sz_bigger);
// The transparen pixmap is a very obscure feature to enable tooltips without showing a pixmap.
// The transparent pixmap is a very obscure feature to enable tooltips without showing a pixmap.
// See code in diveeventitem.cpp. This should probably be replaced by a different mechanism.
QPixmap transparentPixmap(lrint(4 * dprf), lrint(20 * dprf));
transparentPixmap.fill(makeColor(1.0, 1.0, 1.0, 0.01));
@ -52,7 +52,7 @@ static std::vector<std::shared_ptr<const DivePixmaps>> cache;
// Note that the idiomatic way would be to store std::weak_ptr<>s.
// That would mean that the pixmaps are destroyed when the last user uses
// them. We want to keep them around at least until the next caller!
// Therefore we also std::shared_ptr<>s.
// Therefore we also store std::shared_ptr<>s.
std::shared_ptr<const DivePixmaps> getDivePixmaps(double dprIn)
{
using ptr = std::shared_ptr<const DivePixmaps>;

View file

@ -3,10 +3,11 @@
#include "profile-widget/profilescene.h"
#include "core/device.h"
#include "core/event.h"
#include "core/eventname.h"
#include "core/eventtype.h"
#include "core/subsurface-string.h"
#include "core/qthelper.h"
#include "core/range.h"
#include "core/string-format.h"
#include "core/settings/qPrefTechnicalDetails.h"
#include "core/settings/qPrefPartialPressureGas.h"
#include "profile-widget/diveeventitem.h"
@ -608,10 +609,11 @@ 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 similar events"), [this, item] { hideSimilarEvents(item); });
const struct event *dcEvent = item->getEvent();
m.addAction(tr("Hide events of type '%1'").arg(formatEventType(dcEvent)),
[this, item] { hideEventType(item); });
if (dcEvent->type == SAMPLE_EVENT_BOOKMARK)
m.addAction(tr("Edit name"), [this, item] { editName(item); });
#if 0 // TODO::: FINISH OR DISABLE
@ -656,8 +658,11 @@ void ProfileWidget2::contextMenuEvent(QContextMenuEvent *event)
}
#endif
}
if (any_events_hidden() || std::any_of(profileScene->eventItems.begin(), profileScene->eventItems.end(), [] (const DiveEventItem *item) { return !item->isVisible(); }))
m.addAction(tr("Unhide all events"), this, &ProfileWidget2::unhideEvents);
if (any_event_types_hidden())
m.addAction(tr("Unhide all event types"), this, &ProfileWidget2::unhideEventTypes);
if (std::any_of(profileScene->eventItems.begin(), profileScene->eventItems.end(),
[] (const DiveEventItem *item) { return item->getEvent()->hidden; }))
m.addAction(tr("Unhide individually hidden events of this dive"), this, &ProfileWidget2::unhideEvents);
m.exec(event->globalPos());
}
@ -694,15 +699,16 @@ void ProfileWidget2::renameCurrentDC()
void ProfileWidget2::hideEvent(DiveEventItem *item)
{
item->getEventMutable()->hidden = true;
item->hide();
}
void ProfileWidget2::hideSimilarEvents(DiveEventItem *item)
void ProfileWidget2::hideEventType(DiveEventItem *item)
{
const struct event *event = item->getEvent();
if (!empty_string(event->name)) {
hide_similar_events(event->name, event->flags);
hide_event_type(event);
replot();
}
@ -710,9 +716,17 @@ void ProfileWidget2::hideSimilarEvents(DiveEventItem *item)
void ProfileWidget2::unhideEvents()
{
show_all_events();
for (DiveEventItem *item: profileScene->eventItems)
for (DiveEventItem *item: profileScene->eventItems) {
item->getEventMutable()->hidden = false;
item->show();
}
}
void ProfileWidget2::unhideEventTypes()
{
show_all_event_types();
replot();
}
void ProfileWidget2::removeEvent(DiveEventItem *item)

View file

@ -126,9 +126,10 @@ private:
void addSetpointChange(int seconds);
void removeEvent(DiveEventItem *item);
void hideEvent(DiveEventItem *item);
void hideSimilarEvents(DiveEventItem *item);
void hideEventType(DiveEventItem *item);
void editName(DiveEventItem *item);
void unhideEvents();
void unhideEventTypes();
void makeFirstDC();
void deleteCurrentDC();
void splitCurrentDC();