/* Copyright (C) 2017 * swift project Community / Contributors * * This file is part of swift Project. It is subject to the license terms in the LICENSE file found in the top-level * directory of this distribution. No part of swift project, including this file, may be copied, modified, propagated, * or distributed except according to the terms contained in the LICENSE file. */ #include "cockpitcomform.h" #include "ui_cockpitcomform.h" #include "blackgui/guiapplication.h" #include "blackcore/context/contextsimulator.h" #include "blackmisc/math/mathutils.h" #include "blackmisc/logmessage.h" #include "blackmisc/icons.h" #include using namespace BlackMisc; using namespace BlackMisc::Aviation; using namespace BlackMisc::Audio; using namespace BlackMisc::PhysicalQuantities; using namespace BlackMisc::Math; using namespace BlackMisc::Simulation; using namespace BlackGui::Components; namespace BlackGui { namespace Editors { CCockpitComForm::CCockpitComForm(QWidget *parent) : CForm(parent), ui(new Ui::CCockpitComForm) { ui->setupUi(this); this->alignUiElementsHeight(); // SELCAL pairs in cockpit ui->frp_ComPanelSelcalSelector->clear(); connect(ui->tb_ComPanelSelcalTest, &QPushButton::clicked, this, &CCockpitComForm::testSelcal); connect(ui->frp_ComPanelSelcalSelector, &CSelcalCodeSelector::valueChanged, this, &CCockpitComForm::onSelcalChanged); // XPDR connect(ui->cbp_ComPanelTransponderMode, &CTransponderModeSelector::transponderModeChanged, this, &CCockpitComForm::transponderModeChanged); connect(ui->cbp_ComPanelTransponderMode, &CTransponderModeSelector::transponderStateIdentEnded, this, &CCockpitComForm::transponderStateIdentEnded); // COM GUI events connect(ui->tb_ComPanelCom1Toggle, &QPushButton::clicked, this, &CCockpitComForm::onGuiChangedCockpitValues); connect(ui->tb_ComPanelCom2Toggle, &QPushButton::clicked, this, &CCockpitComForm::onGuiChangedCockpitValues); connect(ui->ds_ComPanelCom1Active, &QDoubleSpinBox::editingFinished, this, &CCockpitComForm::onGuiChangedCockpitValues); connect(ui->ds_ComPanelCom2Active, &QDoubleSpinBox::editingFinished, this, &CCockpitComForm::onGuiChangedCockpitValues); connect(ui->ds_ComPanelCom1Standby, &QDoubleSpinBox::editingFinished, this, &CCockpitComForm::onGuiChangedCockpitValues); connect(ui->ds_ComPanelCom2Standby, &QDoubleSpinBox::editingFinished, this, &CCockpitComForm::onGuiChangedCockpitValues); connect(ui->sbp_ComPanelTransponder, &QDoubleSpinBox::editingFinished, this, &CCockpitComForm::onGuiChangedCockpitValues); connect(ui->cbp_ComPanelTransponderMode, &CTransponderModeSelector::transponderModeChanged, this, &CCockpitComForm::onGuiChangedCockpitValues); connect(ui->frp_ComPanelSelcalSelector, &CSelcalCodeSelector::valueChanged, this, &CCockpitComForm::onGuiChangedCockpitValues); connect(ui->tb_RequestTextMessageCom1, &QToolButton::released, this, &CCockpitComForm::requestCom1TextMessage); connect(ui->tb_RequestTextMessageCom2, &QToolButton::released, this, &CCockpitComForm::requestCom2TextMessage); ui->tb_RequestTextMessageCom1->setIcon(CIcons::appTextMessages16()); ui->tb_RequestTextMessageCom2->setIcon(CIcons::appTextMessages16()); this->initLeds(); } CCockpitComForm::~CCockpitComForm() { } void CCockpitComForm::setReadOnly(bool readonly) { ui->ds_ComPanelCom1Active->setReadOnly(readonly); ui->ds_ComPanelCom2Active->setReadOnly(readonly); ui->ds_ComPanelCom1Standby->setReadOnly(readonly); ui->ds_ComPanelCom2Standby->setReadOnly(readonly); ui->cbp_ComPanelTransponderMode->setDisabled(!readonly); ui->tb_ComPanelCom1Toggle->setEnabled(!readonly); ui->tb_ComPanelCom2Toggle->setEnabled(!readonly); this->forceStyleSheetUpdate(); } void CCockpitComForm::setSelectOnly() { this->setReadOnly(true); } CStatusMessageList CCockpitComForm::validate(bool nested) const { Q_UNUSED(nested); CStatusMessageList msgs; return msgs; } void CCockpitComForm::setVoiceRoomStatus(const Audio::CVoiceRoomList &selectedVoiceRooms) { Q_ASSERT_X(selectedVoiceRooms.size() == 2, Q_FUNC_INFO, "Expect 2 voice rooms"); const CVoiceRoom room1 = selectedVoiceRooms[0]; const CVoiceRoom room2 = selectedVoiceRooms[1]; ui->led_ComPanelCom1->setOn(room1.isConnected()); ui->led_ComPanelCom2->setOn(room2.isConnected()); } void CCockpitComForm::setSelectedAtcStations(const CAtcStationList &selectedStations) { const CAtcStation com1Station = selectedStations.size() > 0 ? selectedStations[0] : CAtcStation(); const CAtcStation com2Station = selectedStations.size() > 1 ? selectedStations[1] : CAtcStation(); if (com1Station.getCallsign().isEmpty()) { ui->lbl_ComPanelCom1Active->setToolTip(""); ui->led_ComPanelCom1->setOn(false); } else { ui->lbl_ComPanelCom1Active->setToolTip(com1Station.getCallsign().getStringAsSet()); ui->led_ComPanelCom1->setOn(true); } if (com2Station.getCallsign().isEmpty()) { ui->lbl_ComPanelCom2Active->setToolTip(""); ui->led_ComPanelCom2->setOn(false); } else { ui->lbl_ComPanelCom2Active->setToolTip(com2Station.getCallsign().getStringAsSet()); ui->led_ComPanelCom2->setOn(true); } } void CCockpitComForm::setTransponderModeStateIdent() { ui->cbp_ComPanelTransponderMode->setSelectedTransponderModeStateIdent(); } void CCockpitComForm::setValue(const CSimulatedAircraft &aircraft) { this->setFrequencies(aircraft.getCom1System(), aircraft.getCom2System()); this->setSelcal(aircraft.getSelcal()); this->setTransponder(aircraft.getTransponder()); this->alignUiElementsHeight(); } CSelcal CCockpitComForm::getSelcal() const { return ui->frp_ComPanelSelcalSelector->getSelcal(); } void CCockpitComForm::setSelcal(const CSelcal &selcal) { ui->frp_ComPanelSelcalSelector->setSelcal(selcal); } void CCockpitComForm::initLeds() { const CLedWidget::LedShape shape = CLedWidget::Rounded; ui->led_ComPanelCom1->setValues(CLedWidget::Yellow, CLedWidget::Black, shape, "COM1 connected to station", "COM1 disconnected", 14); ui->led_ComPanelCom2->setValues(CLedWidget::Yellow, CLedWidget::Black, shape, "COM2 connected to station", "COM2 disconnected", 14); ui->led_ComPanelCom1R->setValues(CLedWidget::Yellow, CLedWidget::Black, shape, "COM1 receive (sim)", "COM1 not receiving", 14); ui->led_ComPanelCom1S->setValues(CLedWidget::Yellow, CLedWidget::Black, shape, "COM1 trasmit (sim)", "COM1 not transmitting", 14); ui->led_ComPanelCom1R->setTriStateValues(CLedWidget::Blue, "receive not synced"); ui->led_ComPanelCom1S->setTriStateValues(CLedWidget::Blue, "transmit not synced"); ui->led_ComPanelCom2R->setValues(CLedWidget::Yellow, CLedWidget::Black, shape, "COM2 receive (sim)", "COM2 not receiving", 14); ui->led_ComPanelCom2S->setValues(CLedWidget::Yellow, CLedWidget::Black, shape, "COM2 trasmit (sim)", "COM2 not transmitting", 14); ui->led_ComPanelCom2R->setTriStateValues(CLedWidget::Blue, "receive not synced"); ui->led_ComPanelCom2S->setTriStateValues(CLedWidget::Blue, "transmit not synced"); } CSimulatedAircraft CCockpitComForm::cockpitValuesToAircraftObject() { CSimulatedAircraft comAircraft; CTransponder transponder = comAircraft.getTransponder(); CComSystem com1 = comAircraft.getCom1System(); CComSystem com2 = comAircraft.getCom2System(); // // Transponder // const QString transponderCode = QString::number(ui->sbp_ComPanelTransponder->value()); if (CTransponder::isValidTransponderCode(transponderCode)) { transponder.setTransponderCode(transponderCode); } else { CLogMessage(this).validationWarning(u"Wrong transponder code, reset"); ui->sbp_ComPanelTransponder->setValue(transponder.getTransponderCode()); } transponder.setTransponderMode(ui->cbp_ComPanelTransponderMode->getSelectedTransponderMode()); // // COM units // com1.setFrequencyActiveMHz(ui->ds_ComPanelCom1Active->value()); com1.setFrequencyStandbyMHz(ui->ds_ComPanelCom1Standby->value()); com2.setFrequencyActiveMHz(ui->ds_ComPanelCom2Active->value()); com2.setFrequencyStandbyMHz(ui->ds_ComPanelCom2Standby->value()); this->setFrequencies(com1, com2); // back annotation after rounding comAircraft.setCom1System(com1); comAircraft.setCom2System(com2); comAircraft.setTransponder(transponder); return comAircraft; } void CCockpitComForm::setFrequencies(const CComSystem &com1, const CComSystem &com2) { double freq = com1.getFrequencyActive().valueRounded(CFrequencyUnit::MHz(), 3); if (!isFrequenceEqual(freq, ui->ds_ComPanelCom1Active->value())) { ui->ds_ComPanelCom1Active->setValue(freq); } freq = com2.getFrequencyActive().valueRounded(CFrequencyUnit::MHz(), 3); if (!isFrequenceEqual(freq, ui->ds_ComPanelCom2Active->value())) { ui->ds_ComPanelCom2Active->setValue(freq); } freq = com1.getFrequencyStandby().valueRounded(CFrequencyUnit::MHz(), 3); if (!isFrequenceEqual(freq, ui->ds_ComPanelCom1Standby->value())) { ui->ds_ComPanelCom1Standby->setValue(freq); } freq = com2.getFrequencyStandby().valueRounded(CFrequencyUnit::MHz(), 3); if (!isFrequenceEqual(freq, ui->ds_ComPanelCom2Standby->value())) { ui->ds_ComPanelCom2Standby->setValue(freq); } this->updateIntegrateFromSimulatorContext(); this->updateActiveCOMUnitLEDs(m_integratedWithSim, com1.isSendEnabled(), com1.isReceiveEnabled(), com2.isSendEnabled(), com2.isReceiveEnabled()); } void CCockpitComForm::setTransponder(const CTransponder &transponder) { const int tc = transponder.getTransponderCode(); if (tc != ui->sbp_ComPanelTransponder->value()) { ui->sbp_ComPanelTransponder->setValue(tc); } if (transponder.getTransponderMode() != ui->cbp_ComPanelTransponderMode->getSelectedTransponderMode()) { ui->cbp_ComPanelTransponderMode->setSelectedTransponderMode(transponder.getTransponderMode()); ui->comp_TransponderLeds->setMode(transponder.getTransponderMode()); } } void CCockpitComForm::onGuiChangedCockpitValues() { const QObject *sender = QObject::sender(); if (sender == ui->tb_ComPanelCom1Toggle) { if (isFrequenceEqual(ui->ds_ComPanelCom1Standby->value(), ui->ds_ComPanelCom1Active->value())) { return; } const double f = ui->ds_ComPanelCom1Active->value(); ui->ds_ComPanelCom1Active->setValue(ui->ds_ComPanelCom1Standby->value()); ui->ds_ComPanelCom1Standby->setValue(f); } else if (sender == ui->tb_ComPanelCom2Toggle) { if (isFrequenceEqual(ui->ds_ComPanelCom2Standby->value(), ui->ds_ComPanelCom2Active->value())) { return; } const double f = ui->ds_ComPanelCom2Active->value(); ui->ds_ComPanelCom2Active->setValue(ui->ds_ComPanelCom2Standby->value()); ui->ds_ComPanelCom2Standby->setValue(f); } this->alignUiElementsHeight(); const CSimulatedAircraft aircraft = this->cockpitValuesToAircraftObject(); emit this->changedCockpitValues(aircraft); } void CCockpitComForm::onSelcalChanged() { const CSelcal selcal = ui->frp_ComPanelSelcalSelector->getSelcal(); emit this->changedSelcal(selcal); } void CCockpitComForm::alignUiElementsHeight() { const int selcalH = ui->frp_ComPanelSelcalSelector->getComboBoxHeight(); if (selcalH > ui->ds_ComPanelCom1Standby->height()) { ui->ds_ComPanelCom1Standby->setMinimumHeight(selcalH); ui->ds_ComPanelCom2Standby->setMinimumHeight(selcalH); } const int xpdrH = ui->cbp_ComPanelTransponderMode->height(); if (xpdrH > ui->ds_ComPanelCom1Active->height()) { ui->ds_ComPanelCom1Active->setMinimumHeight(xpdrH); ui->ds_ComPanelCom2Active->setMinimumHeight(xpdrH); ui->sbp_ComPanelTransponder->setMinimumHeight(xpdrH); } } void CCockpitComForm::updateActiveCOMUnitLEDs(bool integratedWithSim, bool com1S, bool com1R, bool com2S, bool com2R) { if (!integratedWithSim) { ui->led_ComPanelCom1R->setTriState(); ui->led_ComPanelCom1S->setTriState(); ui->led_ComPanelCom2R->setTriState(); ui->led_ComPanelCom2S->setTriState(); } else { ui->led_ComPanelCom1R->setOn(com1R); ui->led_ComPanelCom1S->setOn(com1S); ui->led_ComPanelCom2R->setOn(com2R); ui->led_ComPanelCom2S->setOn(com2S); } } void CCockpitComForm::updateIntegrateFromSimulatorContext() { if (!sGui || sGui->isShuttingDown() || !sGui->getIContextSimulator()) { m_integratedWithSim = false; return; } const bool integrated = sGui->getIContextSimulator()->getSimulatorSettings().isComIntegrated(); m_integratedWithSim = integrated; } bool CCockpitComForm::isFrequenceEqual(double f1, double f2) { return CMathUtils::epsilonEqual(f1, f2); } } // ns } // ns