diff --git a/Subsurface-mobile.pro b/Subsurface-mobile.pro index 0167be861..5da3c8b30 100644 --- a/Subsurface-mobile.pro +++ b/Subsurface-mobile.pro @@ -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 \ diff --git a/core/CMakeLists.txt b/core/CMakeLists.txt index 6b552c6cb..5b580ea91 100644 --- a/core/CMakeLists.txt +++ b/core/CMakeLists.txt @@ -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 diff --git a/core/divelist.c b/core/divelist.c index ac0af1b18..ee67d77aa 100644 --- a/core/divelist.c +++ b/core/divelist.c @@ -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(); diff --git a/core/event.c b/core/event.c index defdffc34..dd5551761 100644 --- a/core/event.c +++ b/core/event.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0 #include "event.h" -#include "eventname.h" +#include "eventtype.h" #include "subsurface-string.h" #include @@ -80,7 +80,7 @@ struct event *create_event(unsigned int time, int type, int flags, int value, co break; } - remember_event_name(name); + 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; + } +} diff --git a/core/event.h b/core/event.h index 90f36fe54..9e75b074f 100644 --- a/core/event.h +++ b/core/event.h @@ -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. @@ -46,6 +53,7 @@ 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); diff --git a/core/eventname.cpp b/core/eventname.cpp deleted file mode 100644 index 4289d3d83..000000000 --- a/core/eventname.cpp +++ /dev/null @@ -1,52 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -#include "eventname.h" -#include "subsurface-string.h" - -#include -#include -#include - -struct event_name { - std::string name; - bool plot; -}; - -static std::vector event_names; - -// Small helper so that we can compare events to C-strings -static bool operator==(const event_name &en, const char *s) -{ - return en.name == s; -} - -extern "C" void clear_event_names() -{ - event_names.clear(); -} - -extern "C" void remember_event_name(const char *eventname) -{ - if (empty_string(eventname)) - return; - if (std::find(event_names.begin(), event_names.end(), eventname) != event_names.end()) - return; - event_names.push_back({ eventname, true }); -} - -extern "C" bool is_event_hidden(const char *eventname) -{ - auto it = std::find(event_names.begin(), event_names.end(), eventname); - return it != event_names.end() && !it->plot; -} - -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; }); -} diff --git a/core/eventname.h b/core/eventname.h deleted file mode 100644 index beaac5c32..000000000 --- a/core/eventname.h +++ /dev/null @@ -1,20 +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); -extern bool is_event_hidden(const char *eventname); -extern void show_all_events(); -extern bool any_events_hidden(); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/core/eventtype.cpp b/core/eventtype.cpp new file mode 100644 index 000000000..50e9713e9 --- /dev/null +++ b/core/eventtype.cpp @@ -0,0 +1,73 @@ +// SPDX-License-Identifier: GPL-2.0 +#include "eventtype.h" +#include "event.h" +#include "subsurface-string.h" + +#include +#include +#include + +struct event_type { + std::string name; + event_severity severity; + bool hidden; + event_type(const event *ev) + : name(ev->name), severity(get_event_severity(ev)), hidden(false) + { + } + // Waiting for C++20 space ship operator + bool operator<(const event *t2) { + event_severity severity2 = get_event_severity(t2); + return std::tie(name, severity) < std::tie(t2->name, severity2); + } + bool operator!=(const event *t2) { + event_severity severity2 = get_event_severity(t2); + return std::tie(name, severity) != std::tie(t2->name, severity2); + } + bool operator==(const event *t2) { + event_severity severity2 = get_event_severity(t2); + return std::tie(name, severity) == std::tie(t2->name, severity2); + } +}; + +static std::vector event_types; + +extern "C" void clear_event_types() +{ + event_types.clear(); +} + +extern "C" void remember_event_type(const event *ev) +{ + if (empty_string(ev->name)) + return; + // Insert in ordered manner using binary search + auto it = std::lower_bound(event_types.begin(), event_types.end(), ev); + if (it == event_types.end() || *it != ev) + event_types.insert(it, ev); +} + +extern "C" void hide_event_type(const event *ev) +{ + auto it = std::lower_bound(event_types.begin(), event_types.end(), ev); + if (it != event_types.end() && *it == ev) + it->hidden = true; +} + +extern "C" bool is_event_type_hidden(const event *ev) +{ + auto it = std::lower_bound(event_types.begin(), event_types.end(), ev); + return it == event_types.end() || *it != ev ? false : it->hidden; +} + +extern "C" void show_all_event_types() +{ + for (event_type &en: event_types) + en.hidden = false; +} + +extern "C" bool any_event_types_hidden() +{ + return std::any_of(event_types.begin(), event_types.end(), + [] (const event_type &en) { return en.hidden; }); +} diff --git a/core/eventtype.h b/core/eventtype.h new file mode 100644 index 000000000..597aba7bf --- /dev/null +++ b/core/eventtype.h @@ -0,0 +1,22 @@ +// 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 + +struct event; +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 diff --git a/profile-widget/diveeventitem.cpp b/profile-widget/diveeventitem.cpp index 9b701286d..d3b039ed7 100644 --- a/profile-widget/diveeventitem.cpp +++ b/profile-widget/diveeventitem.cpp @@ -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") || @@ -226,7 +221,7 @@ bool DiveEventItem::isInteresting(const struct dive *d, const struct divecompute bool DiveEventItem::shouldBeHidden() { - return is_event_hidden(ev->name); + return is_event_type_hidden(ev); } void DiveEventItem::recalculatePos() diff --git a/profile-widget/profilewidget2.cpp b/profile-widget/profilewidget2.cpp index b90105187..0f73a39c3 100644 --- a/profile-widget/profilewidget2.cpp +++ b/profile-widget/profilewidget2.cpp @@ -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" @@ -656,7 +656,7 @@ void ProfileWidget2::contextMenuEvent(QContextMenuEvent *event) } #endif } - if (any_events_hidden()) + if (any_event_types_hidden()) m.addAction(tr("Unhide all events"), this, &ProfileWidget2::unhideEvents); m.exec(event->globalPos()); } @@ -701,11 +701,13 @@ void ProfileWidget2::hideSimilarEvents(DiveEventItem *item) { const struct event *event = item->getEvent(); + hide_event_type(event); hideEvent(item); if (!empty_string(event->name)) { for (DiveEventItem *evItem: profileScene->eventItems) { - if (same_string(evItem->getEvent()->name, event->name) && evItem->getEvent()->flags == event->flags) + if (same_string(evItem->getEvent()->name, event->name) && + get_event_severity(evItem->getEvent()) == get_event_severity(event)) evItem->hide(); } } @@ -713,7 +715,7 @@ void ProfileWidget2::hideSimilarEvents(DiveEventItem *item) void ProfileWidget2::unhideEvents() { - show_all_events(); + show_all_event_types(); for (DiveEventItem *item: profileScene->eventItems) item->show(); }