mirror of
https://github.com/subsurface/subsurface.git
synced 2024-11-27 20:58:47 +00:00
Merge e039615c3d
into 7a74a6c426
This commit is contained in:
commit
2424de3cd2
16 changed files with 179 additions and 120 deletions
|
@ -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 \
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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();
|
||||
|
|
18
core/event.c
18
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 <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;
|
||||
}
|
||||
}
|
||||
|
|
12
core/event.h
12
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.
|
||||
|
@ -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
|
||||
|
|
|
@ -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; });
|
||||
}
|
|
@ -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
|
67
core/eventtype.cpp
Normal file
67
core/eventtype.cpp
Normal file
|
@ -0,0 +1,67 @@
|
|||
// 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 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" bool any_event_types_hidden()
|
||||
{
|
||||
return std::any_of(event_types.begin(), event_types.end(),
|
||||
[] (const event_type &e) { return !e.plot; });
|
||||
}
|
21
core/eventtype.h
Normal file
21
core/eventtype.h
Normal file
|
@ -0,0 +1,21 @@
|
|||
// 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 bool any_event_types_hidden();
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -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"
|
||||
|
@ -327,3 +328,26 @@ QString formatTripTitleWithDives(const dive_trip *trip)
|
|||
return formatTripTitle(trip) + " " +
|
||||
gettextFromC::tr("(%n dive(s))", "", nr);
|
||||
}
|
||||
|
||||
|
||||
static QString formatEventSeverity(const event *ev)
|
||||
{
|
||||
switch(get_event_severity(ev)) {
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
||||
QString formatEventType(const event *ev)
|
||||
{
|
||||
if (!ev || empty_string(ev->name))
|
||||
return QString();
|
||||
|
||||
QString eventName = QString::fromUtf8(ev->name);
|
||||
QString severity = formatEventSeverity(ev);
|
||||
if (severity.isEmpty())
|
||||
return eventName;
|
||||
return QStringLiteral("%1 (%2)").arg(eventName, severity);
|
||||
}
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
|
||||
struct dive;
|
||||
struct dive_trip;
|
||||
struct event;
|
||||
|
||||
QString formatSac(const dive *d);
|
||||
QString formatNotes(const dive *d);
|
||||
|
@ -31,5 +32,6 @@ QString formatDayOfWeek(int day);
|
|||
QString formatMinutes(int seconds);
|
||||
QString formatTripTitle(const dive_trip *trip);
|
||||
QString formatTripTitleWithDives(const dive_trip *trip);
|
||||
QString formatEventType(const event *ev);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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>;
|
||||
|
|
|
@ -3,10 +3,11 @@
|
|||
#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"
|
||||
#include "core/string-format.h"
|
||||
#include "core/settings/qPrefTechnicalDetails.h"
|
||||
#include "core/settings/qPrefPartialPressureGas.h"
|
||||
#include "profile-widget/diveeventitem.h"
|
||||
|
@ -608,10 +609,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(formatEventType(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 +658,11 @@ 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())
|
||||
m.addAction(tr("Unhide 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 +699,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 +716,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)
|
||||
|
|
|
@ -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();
|
||||
|
|
Loading…
Reference in a new issue