Compare commits

...

1 Commits

Author SHA1 Message Date
Berthold Stoeger
8b923e0e22 profile: restore global hiding of all events
26f20b805d3c made the event hiding mechanism more fine grained
(by considering also the severity). The commit inadvertently
removed the feature that "hide similar events" would hide the
events from all dives.

Restore this. It's a bit complex, because the "eventname" now
has to remember the severity. Therefore, change "eventname"
into "eventtype".

The UI is a bit inconsistent, as "hide similar events" affects
all dives and is remembered across switching dives. In contrast,
"hide event" is not remembered. This needs some rework.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2024-02-12 11:22:41 +01:00
11 changed files with 136 additions and 94 deletions

View File

@ -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);
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.
@ -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);

View File

@ -1,52 +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;
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 &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; });
}

View File

@ -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

73
core/eventtype.cpp Normal file
View File

@ -0,0 +1,73 @@
// 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 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_type> 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; });
}

22
core/eventtype.h Normal file
View File

@ -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

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") ||
@ -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()

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"
@ -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();
}