diff --git a/core/event.h b/core/event.h index 31eca87fc..fc8a03d64 100644 --- a/core/event.h +++ b/core/event.h @@ -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[]; }; diff --git a/core/eventtype.cpp b/core/eventtype.cpp index dbe0157bc..5e88480a1 100644 --- a/core/eventtype.cpp +++ b/core/eventtype.cpp @@ -1,6 +1,7 @@ // SPDX-License-Identifier: GPL-2.0 #include "eventtype.h" #include "event.h" +#include "gettextfromc.h" #include "subsurface-string.h" #include @@ -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 hidden_event_types() +{ + std::vector 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); +} diff --git a/core/eventtype.h b/core/eventtype.h index 2ccba1c20..8f5a8f5ac 100644 --- a/core/eventtype.h +++ b/core/eventtype.h @@ -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 +#include +extern std::vector hidden_event_types(); +QString event_type_name(const event *ev); +QString event_type_name(int idx); + #endif #endif diff --git a/core/string-format.cpp b/core/string-format.cpp index dc2f3fad5..8bf32fbab 100644 --- a/core/string-format.cpp +++ b/core/string-format.cpp @@ -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" diff --git a/core/string-format.h b/core/string-format.h index 404e7f9cc..c83ff8e70 100644 --- a/core/string-format.h +++ b/core/string-format.h @@ -7,6 +7,7 @@ struct dive; struct dive_trip; +struct event; QString formatSac(const dive *d); QString formatNotes(const dive *d); diff --git a/profile-widget/diveeventitem.cpp b/profile-widget/diveeventitem.cpp index 0de81c454..c5fc5f975 100644 --- a/profile-widget/diveeventitem.cpp +++ b/profile-widget/diveeventitem.cpp @@ -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); diff --git a/profile-widget/profilewidget2.cpp b/profile-widget/profilewidget2.cpp index 400e0eec8..f051f06d7 100644 --- a/profile-widget/profilewidget2.cpp +++ b/profile-widget/profilewidget2.cpp @@ -608,10 +608,11 @@ void ProfileWidget2::contextMenuEvent(QContextMenuEvent *event) [this, seconds](){ addDivemodeSwitch(seconds, PSCR); }); if (DiveEventItem *item = dynamic_cast(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) diff --git a/profile-widget/profilewidget2.h b/profile-widget/profilewidget2.h index 1ca9dccfd..1e91aff20 100644 --- a/profile-widget/profilewidget2.h +++ b/profile-widget/profilewidget2.h @@ -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();