This commit is contained in:
bstoeger 2024-02-21 20:39:08 +00:00 committed by GitHub
commit 5aa1c44a5b
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
16 changed files with 227 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

122
core/eventtype.cpp Normal file
View file

@ -0,0 +1,122 @@
// SPDX-License-Identifier: GPL-2.0
#include "eventtype.h"
#include "event.h"
#include "gettextfromc.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" void show_event_type(int idx)
{
if (idx < 0 || idx >= (int)event_types.size())
return;
event_types[idx].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; });
}
extern std::vector<int> hidden_event_types()
{
std::vector<int> res;
for (size_t i = 0; i < event_types.size(); ++i) {
if (!event_types[i].plot)
res.push_back(i);
}
return res;
}
static QString event_severity_name(event_severity severity)
{
switch (severity) {
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();
}
}
static QString event_type_name(QString name, event_severity severity)
{
QString severity_name = event_severity_name(severity);
if (severity_name.isEmpty())
return name;
return QStringLiteral("%1 (%2)").arg(name, severity_name);
}
QString event_type_name(const event *ev)
{
if (!ev || empty_string(ev->name))
return QString();
QString name = QString::fromUtf8(ev->name);
return event_type_name(std::move(name), get_event_severity(ev));
}
QString event_type_name(int idx)
{
if (idx < 0 || idx >= (int)event_types.size())
return QString();
const event_type &t = event_types[idx];
QString name = QString::fromUtf8(t.name.c_str());
return event_type_name(std::move(name), t.severity);
}

31
core/eventtype.h Normal file
View file

@ -0,0 +1,31 @@
// 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 void show_event_type(int idx);
extern bool any_event_types_hidden();
#ifdef __cplusplus
}
// C++-only functions
#include <vector>
#include <QString>
extern std::vector<int> hidden_event_types();
QString event_type_name(const event *ev);
QString event_type_name(int idx);
#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"

View file

@ -7,6 +7,7 @@
struct dive;
struct dive_trip;
struct event;
QString formatSac(const dive *d);
QString formatNotes(const dive *d);

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,7 +3,7 @@
#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"
@ -608,10 +608,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(event_type_name(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 +657,19 @@ 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()) {
QMenu *m2 = m.addMenu(tr("Unhide event type"));
for (int i: hidden_event_types()) {
m2->addAction(event_type_name(i), [this, i]() {
show_event_type(i);
replot();
});
}
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; }))
m.addAction(tr("Unhide individually hidden events of this dive"), this, &ProfileWidget2::unhideEvents);
m.exec(event->globalPos());
}
@ -694,15 +706,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 +723,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();