328 lines
12 KiB
C++
Executable File
328 lines
12 KiB
C++
Executable File
/**
|
|
* @RDE_HEADER@
|
|
* ExerciseManangement - Exercise Overview Dialog
|
|
* $Id$
|
|
* $HeadURL$
|
|
* $Author$
|
|
*
|
|
* Created by Mike Wille, SLSE, 2017-02-10
|
|
*/
|
|
|
|
#include "tln_legend.h"
|
|
#include "ui_tln_legend.h"
|
|
#include "detail_data.h"
|
|
#include "tln_dialog_model.h"
|
|
|
|
#include <LtsTimelineClassic/Event.h>
|
|
#include <LtsTimelineClassic/EventGraphic.h>
|
|
#include <LtsUtilsSettings/settings.h>
|
|
#include <ProjectDataManagement/pdm_enums.hpp>
|
|
#include <ProjectDataManagement/pdm_translation.h>
|
|
|
|
#include <QLabel>
|
|
#include <QImage>
|
|
#include <QPixmap>
|
|
#include <QPainter>
|
|
|
|
namespace Timeline
|
|
{
|
|
|
|
TimelineLegendDialog::TimelineLegendDialog(QWidget *parent)
|
|
: LtsWidgets::LtsDialog(parent, LtsWidgets::ButtonCombination::OkApplyCancel)
|
|
, m_ui(new Ui::TimelineLegendDialog)
|
|
, m_logger(getLogger("TimelineLegendDialog"))
|
|
{
|
|
m_ui->setupUi(this);
|
|
|
|
m_buttonBox->getButton(LtsWidgets::DialogButton::Ok)->hide(); // apply() always returns false (because it can't be executed with async ops), resulting in the window not closing on OK - only use apply button until apply() can have async ops
|
|
|
|
connect(m_ui->cbCheckAll, &QCheckBox::toggled,
|
|
this, [this](bool toggled)
|
|
{
|
|
const auto cbList = findChildren<QCheckBox *>();
|
|
for (QCheckBox *cb : cbList)
|
|
{
|
|
if (cb == m_ui->cbCheckAll) // needed? maybe recursion?
|
|
continue;
|
|
|
|
cb->setChecked(toggled);
|
|
}
|
|
});
|
|
}
|
|
|
|
|
|
TimelineLegendDialog::~TimelineLegendDialog()
|
|
{
|
|
delete m_ui;
|
|
}
|
|
|
|
|
|
void TimelineLegendDialog::retranslate()
|
|
{
|
|
translate(m_ui, tr("Timeline Legend"));
|
|
}
|
|
|
|
|
|
void TimelineLegendDialog::setActiveEventTypeIds(const QSet<int> &activeEventTypeIds)
|
|
{
|
|
setUnchangeable();
|
|
// first, deactivate all checkboxes, as we can't keep track on WHICH event types are now inactive
|
|
|
|
const QList<QCheckBox *> cbs(findChildren<QCheckBox *>()); // yes, even the "check all" cb
|
|
|
|
for (QCheckBox *cb : cbs)
|
|
cb->setChecked(false);
|
|
|
|
for (int activeEventType : activeEventTypeIds)
|
|
{
|
|
QCheckBox *cb = checkBox(activeEventType);
|
|
|
|
if (cb != nullptr)
|
|
cb->setChecked(true);
|
|
else
|
|
WARNING_LOG(m_logger) << "cb for event type " << activeEventType << " not found!";
|
|
}
|
|
|
|
setUnchangeable(false);
|
|
}
|
|
|
|
QVector<ProjectDataManagement::EventType> TimelineLegendDialog::possibleEvents()
|
|
{
|
|
QVector<ProjectDataManagement::EventType> ret
|
|
({
|
|
// ProjectDataManagement::EventType::Unknown,
|
|
ProjectDataManagement::EventType::Hit,
|
|
ProjectDataManagement::EventType::WeaponAssignment,
|
|
ProjectDataManagement::EventType::BiteMessage,
|
|
ProjectDataManagement::EventType::FireEvent,
|
|
ProjectDataManagement::EventType::HitBuilding,
|
|
ProjectDataManagement::EventType::Manipulation,
|
|
ProjectDataManagement::EventType::CameraVideo,
|
|
ProjectDataManagement::EventType::RadioCnr,
|
|
ProjectDataManagement::EventType::RadioTvc,
|
|
ProjectDataManagement::EventType::HitEffectSimulation,
|
|
// ProjectDataManagement::EventType::HitMine, // HitEffectSimulation
|
|
// ProjectDataManagement::EventType::HitN, // HitEffectSimulation
|
|
// ProjectDataManagement::EventType::HitC, // HitEffectSimulation
|
|
// ProjectDataManagement::EventType::EnterDangerArea, // showEnterLeaveEvents
|
|
// ProjectDataManagement::EventType::LeaveDangerArea, // showEnterLeaveEvents
|
|
// ProjectDataManagement::EventType::EnterMineArea, // showEnterLeaveEvents
|
|
// ProjectDataManagement::EventType::LeaveMineArea, // showEnterLeaveEvents
|
|
ProjectDataManagement::EventType::CrossLocalBorderline,
|
|
// ProjectDataManagement::EventType::EnterFunctionalArea, // showEnterLeaveEvents
|
|
// ProjectDataManagement::EventType::LeaveFunctionalArea, // showEnterLeaveEvents
|
|
// ProjectDataManagement::EventType::EnterNuclear, // showEnterLeaveEvents
|
|
// ProjectDataManagement::EventType::LeaveNuclear, // showEnterLeaveEvents
|
|
ProjectDataManagement::EventType::CrossGlobalBorderline,
|
|
// ProjectDataManagement::EventType::HitB, // HitEffectSimulation
|
|
// ProjectDataManagement::EventType::FriendlyFire, // currently not displayed
|
|
// ProjectDataManagement::EventType::HitGasPipe, // HitEffectSimulation
|
|
// ProjectDataManagement::EventType::MineArea, // showEffectSimulationEvents
|
|
// ProjectDataManagement::EventType::NContamination, // showEffectSimulationEvents
|
|
// ProjectDataManagement::EventType::BCContamination, // showEffectSimulationEvents
|
|
// ProjectDataManagement::EventType::DangerArea, // showEffectSimulationEvents
|
|
// ProjectDataManagement::EventType::FunctionalArea, // showEffectSimulationEvents
|
|
// ProjectDataManagement::EventType::MineCorridor, // showEffectSimulationEvents
|
|
// ProjectDataManagement::EventType::Borderline, // showEffectSimulationEvents
|
|
// ProjectDataManagement::EventType::TechnicalArea,
|
|
// ProjectDataManagement::EventType::GasPipe, // separate
|
|
// ProjectDataManagement::EventType::EquipmentErrorReport,
|
|
// ProjectDataManagement::EventType::EmergencyCall,
|
|
});
|
|
|
|
LtsUtils::ProjectSettings *ps = LtsUtils::ProjectSettings::getInstance();
|
|
|
|
if (ps->value(QStringLiteral("tln"),
|
|
QStringLiteral("showEffectSimulationEvents")).toBool())
|
|
{
|
|
ret += ProjectDataManagement::EventType::MineArea;
|
|
ret += ProjectDataManagement::EventType::DangerArea;
|
|
ret += ProjectDataManagement::EventType::FunctionalArea;
|
|
ret += ProjectDataManagement::EventType::MineCorridor;
|
|
ret += ProjectDataManagement::EventType::Borderline;
|
|
if (ps->value(QStringLiteral("aes"),
|
|
QStringLiteral("enableNuclearContaminations")).toBool())
|
|
ret += ProjectDataManagement::EventType::NContamination;
|
|
if (ps->value(QStringLiteral("aes"),
|
|
QStringLiteral("enableNuclearContaminations")).toBool() ||
|
|
ps->value(QStringLiteral("aes"),
|
|
QStringLiteral("enableNuclearContaminations")).toBool())
|
|
ret += ProjectDataManagement::EventType::BCContamination;
|
|
}
|
|
|
|
|
|
if (ps->value(QStringLiteral("tln"),
|
|
QStringLiteral("showEnterLeaveEvents")).toBool())
|
|
{
|
|
ret += ProjectDataManagement::EventType::EnterDangerArea;
|
|
ret += ProjectDataManagement::EventType::LeaveDangerArea;
|
|
ret += ProjectDataManagement::EventType::EnterMineArea;
|
|
ret += ProjectDataManagement::EventType::LeaveMineArea;
|
|
ret += ProjectDataManagement::EventType::EnterFunctionalArea;
|
|
ret += ProjectDataManagement::EventType::LeaveFunctionalArea;
|
|
|
|
if (ps->value(QStringLiteral("aes"),
|
|
QStringLiteral("enableNuclearContaminations")).toBool())
|
|
{
|
|
ret += ProjectDataManagement::EventType::EnterNuclear;
|
|
ret += ProjectDataManagement::EventType::LeaveNuclear;
|
|
}
|
|
}
|
|
|
|
|
|
if (ps->value(QStringLiteral("aes"),
|
|
QStringLiteral("enableGasPipes")).toBool())
|
|
{
|
|
ret += ProjectDataManagement::EventType::GasPipe;
|
|
//ret += ProjectDataManagement::EventType::HitGasPipe; covered by HitEffectSimulation yes or no ??
|
|
}
|
|
|
|
const bool showPvSan = LtsUtils::ProjectSettings::isFunctionEnabled(QStringLiteral("ParticipantInformation"),
|
|
QStringLiteral("HasPvSan"));
|
|
if (showPvSan)
|
|
ret += ProjectDataManagement::EventType::Sanitation;
|
|
|
|
return ret;
|
|
}
|
|
|
|
// helper for grouped sorting
|
|
static int categoryFromEventType(ProjectDataManagement::EventType et)
|
|
{
|
|
switch (et.underlying())
|
|
{
|
|
case ProjectDataManagement::EventType::Unknown:
|
|
return 0;
|
|
case ProjectDataManagement::EventType::Hit:
|
|
case ProjectDataManagement::EventType::WeaponAssignment:
|
|
case ProjectDataManagement::EventType::BiteMessage:
|
|
case ProjectDataManagement::EventType::FireEvent:
|
|
case ProjectDataManagement::EventType::FriendlyFire:
|
|
case ProjectDataManagement::EventType::Manipulation:
|
|
return 1;
|
|
case ProjectDataManagement::EventType::CameraVideo:
|
|
case ProjectDataManagement::EventType::RadioCnr:
|
|
case ProjectDataManagement::EventType::RadioTvc:
|
|
return 5;
|
|
case ProjectDataManagement::EventType::HitBuilding:
|
|
case ProjectDataManagement::EventType::HitEffectSimulation:
|
|
case ProjectDataManagement::EventType::HitMine:
|
|
case ProjectDataManagement::EventType::HitN:
|
|
case ProjectDataManagement::EventType::HitB:
|
|
case ProjectDataManagement::EventType::HitC:
|
|
case ProjectDataManagement::EventType::HitGasPipe:
|
|
return 2;
|
|
case ProjectDataManagement::EventType::EnterDangerArea:
|
|
case ProjectDataManagement::EventType::LeaveDangerArea:
|
|
case ProjectDataManagement::EventType::EnterMineArea:
|
|
case ProjectDataManagement::EventType::LeaveMineArea:
|
|
case ProjectDataManagement::EventType::CrossLocalBorderline:
|
|
case ProjectDataManagement::EventType::EnterFunctionalArea:
|
|
case ProjectDataManagement::EventType::LeaveFunctionalArea:
|
|
case ProjectDataManagement::EventType::EnterNuclear:
|
|
case ProjectDataManagement::EventType::LeaveNuclear:
|
|
case ProjectDataManagement::EventType::CrossGlobalBorderline:
|
|
case ProjectDataManagement::EventType::Sanitation:
|
|
return 3;
|
|
case ProjectDataManagement::EventType::MineArea:
|
|
case ProjectDataManagement::EventType::NContamination:
|
|
case ProjectDataManagement::EventType::BCContamination:
|
|
case ProjectDataManagement::EventType::DangerArea:
|
|
case ProjectDataManagement::EventType::FunctionalArea:
|
|
case ProjectDataManagement::EventType::MineCorridor:
|
|
case ProjectDataManagement::EventType::Borderline:
|
|
case ProjectDataManagement::EventType::GasPipe:
|
|
return 6;
|
|
case ProjectDataManagement::EventType::TechnicalArea:
|
|
case ProjectDataManagement::EventType::EquipmentErrorReport:
|
|
case ProjectDataManagement::EventType::EmergencyCall:
|
|
return 0;
|
|
}
|
|
Q_ASSERT(false);
|
|
return 0;
|
|
}
|
|
|
|
bool TimelineLegendDialog::init(DDSTimelineModel *model, const QSet<int> &activeEventTypeIds)
|
|
{
|
|
struct WidgetSortHelper
|
|
{
|
|
QLabel *lbl = nullptr;
|
|
QCheckBox *cbx = nullptr;
|
|
ProjectDataManagement::EventType et = ProjectDataManagement::EventType::Unknown;
|
|
};
|
|
QImage p(16, 24, QImage::Format_ARGB32);
|
|
QColor c; // dummy
|
|
LtsTimelineClassic::Event::EventPaintFunc paintFunc;
|
|
WidgetSortHelper wsh;
|
|
|
|
const auto events = possibleEvents();
|
|
std::vector<WidgetSortHelper> helperCont;
|
|
helperCont.reserve(events.size());
|
|
for (const ProjectDataManagement::EventType eventType : events)
|
|
{
|
|
model->setColorPaintFun(paintFunc, c, eventType.underlying());
|
|
|
|
if (paintFunc == nullptr)
|
|
{
|
|
WARNING_LOG(m_logger) << "No draw function for event " << eventType;
|
|
Q_ASSERT(false);
|
|
continue;
|
|
}
|
|
|
|
p.fill(Qt::transparent);
|
|
QPainter pp(&p);
|
|
pp.setRenderHint(QPainter::Antialiasing);
|
|
pp.setBrush(QBrush(c));
|
|
paintFunc(&pp, p.rect().adjusted(0, 0, -1, -1));
|
|
|
|
wsh.lbl = new QLabel(this);
|
|
wsh.lbl->setPixmap(QPixmap::fromImage(p));
|
|
|
|
wsh.et = eventType;
|
|
wsh.cbx = new QCheckBox(ProjectDataManagement::toString(eventType), this);
|
|
wsh.cbx->setObjectName(checkBoxName(eventType));
|
|
wsh.cbx->setChecked(activeEventTypeIds.contains(eventType.underlying()));
|
|
wsh.cbx->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum);
|
|
|
|
helperCont.push_back(wsh);
|
|
}
|
|
|
|
std::sort(helperCont.begin(), helperCont.end(), [](const WidgetSortHelper &a, const WidgetSortHelper &b)
|
|
{
|
|
const auto et1 = categoryFromEventType(a.et);
|
|
const auto et2 = categoryFromEventType(b.et);
|
|
if (et1 != et2)
|
|
return et1 < et2;
|
|
return a.cbx->text() < b.cbx->text();
|
|
});
|
|
|
|
int curGridRow = 1; // 0 is 'Check all'
|
|
for (const auto &ele : helperCont)
|
|
{
|
|
m_ui->gridLayout->addWidget(ele.lbl, curGridRow, 0);
|
|
m_ui->gridLayout->addWidget(ele.cbx, curGridRow, 1);
|
|
m_ui->gridLayout->addItem(new QSpacerItem(0, 0, QSizePolicy::Expanding), curGridRow, 2);
|
|
++curGridRow;
|
|
}
|
|
m_ui->gridLayout->addItem(new QSpacerItem(0, 0, QSizePolicy::Minimum, QSizePolicy::Expanding), curGridRow, 0);
|
|
|
|
return true;
|
|
}
|
|
|
|
|
|
bool TimelineLegendDialog::apply()
|
|
{
|
|
QSet<int> activeEventTypeIds;
|
|
const auto events = possibleEvents();
|
|
for (const ProjectDataManagement::EventType eventType : events)
|
|
{
|
|
if (checkBox(eventType)->isChecked())
|
|
activeEventTypeIds.insert(eventType.underlying());
|
|
}
|
|
emit signalEventTypesChanged(activeEventTypeIds);
|
|
return false; // because this has to happen async.. (reset changes after async ops are (successfully) done)
|
|
}
|
|
|
|
} // namespace Timeline
|
|
|
|
//
|