#include "tln_legend.h" #include "ui_tln_legend.h" #include "detail_data.h" #include "tln_dialog_model.h" #include #include #include #include #include #include #include #include #include namespace Timeline { TimelineLegendDialog::TimelineLegendDialog(QWidget *parent) : LtsWidgets::LtsDialog(parent, LtsWidgets::ButtonCombination::OkApplyCancel) , m_ui(new Ui::TimelineLegendDialog) { m_ui->setupUi(this); m_buttonBox->getButton(LtsWidgets::DialogButton::Ok)->hide(); connect(m_ui->cbCheckAll, &QCheckBox::toggled, this, [this](bool toggled) { const auto cbList = findChildren(); for (QCheckBox *cb : cbList) { if (cb == m_ui->cbCheckAll) continue; cb->setChecked(toggled); } }); } TimelineLegendDialog::~TimelineLegendDialog() { delete m_ui; } void TimelineLegendDialog::retranslate() { translate(m_ui, tr("Timeline Legend")); } void TimelineLegendDialog::setActiveEventTypeIds(const QSet &activeEventTypeIds) { setUnchangeable(); const QList cbs(findChildren()); 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 TimelineLegendDialog::possibleEvents() { QVector ret ({ ProjectDataManagement::PdmEventType::Hit, ProjectDataManagement::PdmEventType::WeaponAssignment, ProjectDataManagement::PdmEventType::BiteMessage, ProjectDataManagement::PdmEventType::FireEvent, ProjectDataManagement::PdmEventType::HitBuilding, ProjectDataManagement::PdmEventType::Manipulation, ProjectDataManagement::PdmEventType::CameraVideo, ProjectDataManagement::PdmEventType::RadioCnr, ProjectDataManagement::PdmEventType::RadioTvc, ProjectDataManagement::PdmEventType::HitEffectSimulation, ProjectDataManagement::PdmEventType::CrossLocalBorderline, ProjectDataManagement::PdmEventType::CrossGlobalBorderline, }); LtsUtils::ProjectSettings *ps = LtsUtils::ProjectSettings::getInstance(); if (ps->value(QStringLiteral("tln"), QStringLiteral("showEffectSimulationEvents")).toBool()) { ret += ProjectDataManagement::PdmEventType::MineArea; ret += ProjectDataManagement::PdmEventType::DangerArea; ret += ProjectDataManagement::PdmEventType::FunctionalArea; ret += ProjectDataManagement::PdmEventType::MineCorridor; ret += ProjectDataManagement::PdmEventType::Borderline; if (ps->value(QStringLiteral("aes"), QStringLiteral("enableNuclearContaminations")).toBool()) ret += ProjectDataManagement::PdmEventType::NContamination; if (ps->value(QStringLiteral("aes"), QStringLiteral("enableNuclearContaminations")).toBool() || ps->value(QStringLiteral("aes"), QStringLiteral("enableNuclearContaminations")).toBool()) ret += ProjectDataManagement::PdmEventType::BCContamination; } if (ps->value(QStringLiteral("tln"), QStringLiteral("showEnterLeaveEvents")).toBool()) { ret += ProjectDataManagement::PdmEventType::EnterDangerArea; ret += ProjectDataManagement::PdmEventType::LeaveDangerArea; ret += ProjectDataManagement::PdmEventType::EnterMineArea; ret += ProjectDataManagement::PdmEventType::LeaveMineArea; ret += ProjectDataManagement::PdmEventType::EnterFunctionalArea; ret += ProjectDataManagement::PdmEventType::LeaveFunctionalArea; if (ps->value(QStringLiteral("aes"), QStringLiteral("enableNuclearContaminations")).toBool()) { ret += ProjectDataManagement::PdmEventType::EnterNuclear; ret += ProjectDataManagement::PdmEventType::LeaveNuclear; } } if (ps->value(QStringLiteral("aes"), QStringLiteral("enableGasPipes")).toBool()) { ret += ProjectDataManagement::PdmEventType::GasPipe; } const bool showPvSan = LtsUtils::ProjectSettings::isFunctionEnabled(QStringLiteral("ParticipantInformation"), QStringLiteral("HasPvSan")); if (showPvSan) ret += ProjectDataManagement::PdmEventType::Sanitation; return ret; } static int categoryFromEventType(ProjectDataManagement::PdmEventType et) { switch (et.underlying()) { case ProjectDataManagement::PdmEventType::Unknown: return 0; case ProjectDataManagement::PdmEventType::Hit: case ProjectDataManagement::PdmEventType::WeaponAssignment: case ProjectDataManagement::PdmEventType::BiteMessage: case ProjectDataManagement::PdmEventType::FireEvent: case ProjectDataManagement::PdmEventType::FriendlyFire: case ProjectDataManagement::PdmEventType::Manipulation: return 1; case ProjectDataManagement::PdmEventType::CameraVideo: case ProjectDataManagement::PdmEventType::RadioCnr: case ProjectDataManagement::PdmEventType::RadioTvc: return 5; case ProjectDataManagement::PdmEventType::HitBuilding: case ProjectDataManagement::PdmEventType::HitEffectSimulation: case ProjectDataManagement::PdmEventType::HitMine: case ProjectDataManagement::PdmEventType::HitN: case ProjectDataManagement::PdmEventType::HitB: case ProjectDataManagement::PdmEventType::HitC: case ProjectDataManagement::PdmEventType::HitGasPipe: return 2; case ProjectDataManagement::PdmEventType::EnterDangerArea: case ProjectDataManagement::PdmEventType::LeaveDangerArea: case ProjectDataManagement::PdmEventType::EnterMineArea: case ProjectDataManagement::PdmEventType::LeaveMineArea: case ProjectDataManagement::PdmEventType::CrossLocalBorderline: case ProjectDataManagement::PdmEventType::EnterFunctionalArea: case ProjectDataManagement::PdmEventType::LeaveFunctionalArea: case ProjectDataManagement::PdmEventType::EnterNuclear: case ProjectDataManagement::PdmEventType::LeaveNuclear: case ProjectDataManagement::PdmEventType::CrossGlobalBorderline: case ProjectDataManagement::PdmEventType::Sanitation: return 3; case ProjectDataManagement::PdmEventType::MineArea: case ProjectDataManagement::PdmEventType::NContamination: case ProjectDataManagement::PdmEventType::BCContamination: case ProjectDataManagement::PdmEventType::DangerArea: case ProjectDataManagement::PdmEventType::FunctionalArea: case ProjectDataManagement::PdmEventType::MineCorridor: case ProjectDataManagement::PdmEventType::Borderline: case ProjectDataManagement::PdmEventType::GasPipe: return 6; case ProjectDataManagement::PdmEventType::TechnicalArea: case ProjectDataManagement::PdmEventType::EquipmentErrorReport: case ProjectDataManagement::PdmEventType::EmergencyCall: return 0; } Q_ASSERT(false); return 0; } bool TimelineLegendDialog::init(DDSTimelineModel *model, const QSet &activeEventTypeIds) { struct WidgetSortHelper { QLabel *lbl = nullptr; QCheckBox *cbx = nullptr; ProjectDataManagement::PdmEventType et = ProjectDataManagement::PdmEventType::Unknown; }; QImage p(16, 24, QImage::Format_ARGB32); QColor c; LtsTimelineClassic::Event::EventPaintFunc paintFunc; WidgetSortHelper wsh; const auto events = possibleEvents(); std::vector helperCont; helperCont.reserve(events.size()); for (const ProjectDataManagement::PdmEventType 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; 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 activeEventTypeIds; const auto events = possibleEvents(); for (const ProjectDataManagement::PdmEventType eventType : events) { if (checkBox(eventType)->isChecked()) activeEventTypeIds.insert(eventType.underlying()); } emit signalEventTypesChanged(activeEventTypeIds); return false; } }