profile: make event hiding persistent across change of dive

Currently, the "hide event" status is lost when switching dives.
Save it in the event struct instead to make it persistent.

In the future we might save this information to the log file.
Then this should be integrated in the undo-system.

This commit also makes the "unhide events" menu entry more
fine grained: It now differentiates between individual
events and event types.

Note this adds an additional field to the event structure.
There is a "deleted" field that is used internally for
book-keeping, but probably should be removed. Not touching
this at the moment as long as this is C-only code. When/if
switching to C++ we can make the event linked list a table,
which will make this much simpler.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
This commit is contained in:
Berthold Stoeger 2024-02-19 09:04:14 +01:00 committed by Dirk Hohndel
parent 4783e85b59
commit fac006148f
8 changed files with 100 additions and 10 deletions

View file

@ -42,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[];
};

View file

@ -1,6 +1,7 @@
// SPDX-License-Identifier: GPL-2.0
#include "eventtype.h"
#include "event.h"
#include "gettextfromc.h"
#include "subsurface-string.h"
#include <string>
@ -60,8 +61,62 @@ extern "C" void show_all_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);
}

View file

@ -12,10 +12,20 @@ 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

@ -228,7 +228,7 @@ void DiveEventItem::recalculatePos()
hide();
return;
}
setVisible(!is_event_type_hidden(ev));
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

@ -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_event_types_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,10 +706,11 @@ 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();
@ -710,9 +723,17 @@ void ProfileWidget2::hideSimilarEvents(DiveEventItem *item)
void ProfileWidget2::unhideEvents()
{
show_all_event_types();
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();