swift
cockpitcomform.cpp
1 // SPDX-FileCopyrightText: Copyright (C) 2017 swift Project Community / Contributors
2 // SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-swift-pilot-client-1
3 
4 #include "cockpitcomform.h"
5 
6 #include <QPushButton>
7 
8 #include "ui_cockpitcomform.h"
9 
11 #include "gui/guiapplication.h"
12 #include "misc/icons.h"
13 #include "misc/logmessage.h"
14 #include "misc/math/mathutils.h"
15 
16 using namespace swift::misc;
17 using namespace swift::misc::aviation;
18 using namespace swift::misc::physical_quantities;
19 using namespace swift::misc::math;
20 using namespace swift::misc::simulation;
21 using namespace swift::core::context;
22 using namespace swift::gui::components;
23 
24 namespace swift::gui::editors
25 {
26  CCockpitComForm::CCockpitComForm(QWidget *parent) : CForm(parent), ui(new Ui::CCockpitComForm)
27  {
28  ui->setupUi(this);
29  this->alignUiElementsHeight();
30 
31  // SELCAL pairs in cockpit
32  ui->frp_ComPanelSelcalSelector->clear();
33  connect(ui->tb_ComPanelSelcalTest, &QPushButton::clicked, this, &CCockpitComForm::testSelcal);
34  connect(ui->frp_ComPanelSelcalSelector, &CSelcalCodeSelector::valueChanged, this,
35  &CCockpitComForm::onSelcalChanged);
36 
37  // XPDR
38  connect(ui->cbp_ComPanelTransponderMode, &CTransponderModeSelector::transponderModeChanged, this,
40  connect(ui->cbp_ComPanelTransponderMode, &CTransponderModeSelector::transponderStateIdentEnded, this,
42 
43  // COM GUI events
44  connect(ui->tb_ComPanelCom1Toggle, &QPushButton::clicked, this, &CCockpitComForm::onGuiChangedCockpitValues);
45  connect(ui->tb_ComPanelCom2Toggle, &QPushButton::clicked, this, &CCockpitComForm::onGuiChangedCockpitValues);
46  connect(ui->ds_ComPanelCom1Active, &QDoubleSpinBox::editingFinished, this,
47  &CCockpitComForm::onGuiChangedCockpitValues);
48  connect(ui->ds_ComPanelCom2Active, &QDoubleSpinBox::editingFinished, this,
49  &CCockpitComForm::onGuiChangedCockpitValues);
50  connect(ui->ds_ComPanelCom1Standby, &QDoubleSpinBox::editingFinished, this,
51  &CCockpitComForm::onGuiChangedCockpitValues);
52  connect(ui->ds_ComPanelCom2Standby, &QDoubleSpinBox::editingFinished, this,
53  &CCockpitComForm::onGuiChangedCockpitValues);
54  connect(ui->sbp_ComPanelTransponder, &QDoubleSpinBox::editingFinished, this,
55  &CCockpitComForm::onGuiChangedCockpitValues);
56  connect(ui->cbp_ComPanelTransponderMode, &CTransponderModeSelector::transponderModeChanged, this,
57  &CCockpitComForm::onGuiChangedCockpitValues);
58  connect(ui->frp_ComPanelSelcalSelector, &CSelcalCodeSelector::valueChanged, this,
59  &CCockpitComForm::onGuiChangedCockpitValues);
60  connect(ui->tb_RequestTextMessageCom1, &QToolButton::released, this, &CCockpitComForm::requestCom1TextMessage);
61  connect(ui->tb_RequestTextMessageCom2, &QToolButton::released, this, &CCockpitComForm::requestCom2TextMessage);
62 
63  ui->tb_RequestTextMessageCom1->setIcon(CIcons::appTextMessages16());
64  ui->tb_RequestTextMessageCom2->setIcon(CIcons::appTextMessages16());
65 
66  this->initLeds();
67  }
68 
70 
71  void CCockpitComForm::setReadOnly(bool readonly)
72  {
73  ui->ds_ComPanelCom1Active->setReadOnly(readonly);
74  ui->ds_ComPanelCom2Active->setReadOnly(readonly);
75  ui->ds_ComPanelCom1Standby->setReadOnly(readonly);
76  ui->ds_ComPanelCom2Standby->setReadOnly(readonly);
77  ui->cbp_ComPanelTransponderMode->setDisabled(!readonly);
78  ui->tb_ComPanelCom1Toggle->setEnabled(!readonly);
79  ui->tb_ComPanelCom2Toggle->setEnabled(!readonly);
80  this->forceStyleSheetUpdate();
81  }
82 
84 
86  {
87  Q_UNUSED(nested)
88  CStatusMessageList msgs;
89  return msgs;
90  }
91 
93  {
94  ui->cbp_ComPanelTransponderMode->setSelectedTransponderModeStateIdent();
95  }
96 
98  {
99  this->setFrequencies(aircraft.getCom1System(), aircraft.getCom2System());
100  this->setSelcal(aircraft.getSelcal());
101  this->setTransponder(aircraft.getTransponder());
102  this->alignUiElementsHeight();
103  this->updateIntegratedFlagFromSimulatorContext();
104  }
105 
106  CSelcal CCockpitComForm::getSelcal() const { return ui->frp_ComPanelSelcalSelector->getSelcal(); }
107 
108  void CCockpitComForm::setSelcal(const CSelcal &selcal) { ui->frp_ComPanelSelcalSelector->setSelcal(selcal); }
109 
110  void CCockpitComForm::initLeds()
111  {
112  const CLedWidget::LedShape shape = CLedWidget::Rounded;
113 
114  ui->led_ComPanelCom1R->setValues(CLedWidget::Yellow, CLedWidget::Black, shape, "COM1 receive (sim)",
115  "COM1 not receiving", 14);
116  ui->led_ComPanelCom1T->setValues(CLedWidget::Yellow, CLedWidget::Black, shape, "COM1 transmit (sim)",
117  "COM1 not transmitting", 14);
118  ui->led_ComPanelCom1R->setTriStateValues(CLedWidget::Blue, "receive not synced");
119  ui->led_ComPanelCom1T->setTriStateValues(CLedWidget::Blue, "transmit not synced");
120 
121  ui->led_ComPanelCom2R->setValues(CLedWidget::Yellow, CLedWidget::Black, shape, "COM2 receive (sim)",
122  "COM2 not receiving", 14);
123  ui->led_ComPanelCom2T->setValues(CLedWidget::Yellow, CLedWidget::Black, shape, "COM2 transmit (sim)",
124  "COM2 not transmitting", 14);
125  ui->led_ComPanelCom2R->setTriStateValues(CLedWidget::Blue, "receive not synced");
126  ui->led_ComPanelCom2T->setTriStateValues(CLedWidget::Blue, "transmit not synced");
127  }
128 
129  CSimulatedAircraft CCockpitComForm::cockpitValuesToAircraftObject()
130  {
131  CSimulatedAircraft comAircraft;
132  CTransponder transponder = comAircraft.getTransponder();
133  CComSystem com1 = comAircraft.getCom1System();
134  CComSystem com2 = comAircraft.getCom2System();
135 
136  //
137  // Transponder
138  //
139  const QString transponderCode = QString::number(ui->sbp_ComPanelTransponder->value());
140  if (CTransponder::isValidTransponderCode(transponderCode)) { transponder.setTransponderCode(transponderCode); }
141  else
142  {
143  CLogMessage(this).validationWarning(u"Wrong transponder code, reset");
144  ui->sbp_ComPanelTransponder->setValue(transponder.getTransponderCode());
145  }
146  transponder.setTransponderMode(ui->cbp_ComPanelTransponderMode->getSelectedTransponderMode());
147 
148  //
149  // COM units
150  //
151  com1.setFrequencyActiveMHz(ui->ds_ComPanelCom1Active->value());
152  com1.setFrequencyStandbyMHz(ui->ds_ComPanelCom1Standby->value());
153  com2.setFrequencyActiveMHz(ui->ds_ComPanelCom2Active->value());
154  com2.setFrequencyStandbyMHz(ui->ds_ComPanelCom2Standby->value());
155  this->setFrequencies(com1, com2); // back annotation after rounding
156 
157  comAircraft.setCom1System(com1);
158  comAircraft.setCom2System(com2);
159  comAircraft.setTransponder(transponder);
160  return comAircraft;
161  }
162 
164  {
165  double freq = com1.getFrequencyActive().valueRounded(CFrequencyUnit::MHz(), 3);
166  if (!isFrequenceEqual(freq, ui->ds_ComPanelCom1Active->value())) { ui->ds_ComPanelCom1Active->setValue(freq); }
167 
168  freq = com2.getFrequencyActive().valueRounded(CFrequencyUnit::MHz(), 3);
169  if (!isFrequenceEqual(freq, ui->ds_ComPanelCom2Active->value())) { ui->ds_ComPanelCom2Active->setValue(freq); }
170 
171  freq = com1.getFrequencyStandby().valueRounded(CFrequencyUnit::MHz(), 3);
172  if (!isFrequenceEqual(freq, ui->ds_ComPanelCom1Standby->value()))
173  {
174  ui->ds_ComPanelCom1Standby->setValue(freq);
175  }
176 
177  freq = com2.getFrequencyStandby().valueRounded(CFrequencyUnit::MHz(), 3);
178  if (!isFrequenceEqual(freq, ui->ds_ComPanelCom2Standby->value()))
179  {
180  ui->ds_ComPanelCom2Standby->setValue(freq);
181  }
182 
183  this->updateIntegratedFlagFromSimulatorContext();
184  this->updateActiveCOMUnitLEDs(m_integratedWithSim, com1.isTransmitEnabled(), com1.isReceiveEnabled(),
185  com2.isTransmitEnabled(), com2.isReceiveEnabled());
186  }
187 
189  {
190  const int tc = transponder.getTransponderCode();
191  if (tc != ui->sbp_ComPanelTransponder->value()) { ui->sbp_ComPanelTransponder->setValue(tc); }
192 
193  if (transponder.getTransponderMode() != ui->cbp_ComPanelTransponderMode->getSelectedTransponderMode())
194  {
195  ui->cbp_ComPanelTransponderMode->setSelectedTransponderMode(transponder.getTransponderMode());
196  ui->comp_TransponderLeds->setMode(transponder.getTransponderMode());
197  }
198  }
199 
200  void CCockpitComForm::onGuiChangedCockpitValues()
201  {
202  const QObject *sender = QObject::sender();
203  if (sender == ui->tb_ComPanelCom1Toggle)
204  {
205  if (isFrequenceEqual(ui->ds_ComPanelCom1Standby->value(), ui->ds_ComPanelCom1Active->value())) { return; }
206  const double f = ui->ds_ComPanelCom1Active->value();
207  ui->ds_ComPanelCom1Active->setValue(ui->ds_ComPanelCom1Standby->value());
208  ui->ds_ComPanelCom1Standby->setValue(f);
209  }
210  else if (sender == ui->tb_ComPanelCom2Toggle)
211  {
212  if (isFrequenceEqual(ui->ds_ComPanelCom2Standby->value(), ui->ds_ComPanelCom2Active->value())) { return; }
213  const double f = ui->ds_ComPanelCom2Active->value();
214  ui->ds_ComPanelCom2Active->setValue(ui->ds_ComPanelCom2Standby->value());
215  ui->ds_ComPanelCom2Standby->setValue(f);
216  }
217 
218  this->alignUiElementsHeight();
219  const CSimulatedAircraft aircraft = this->cockpitValuesToAircraftObject();
220  emit this->changedCockpitValues(aircraft);
221  }
222 
223  void CCockpitComForm::onSelcalChanged()
224  {
225  const CSelcal selcal = ui->frp_ComPanelSelcalSelector->getSelcal();
226  emit this->changedSelcal(selcal);
227  }
228 
229  void CCockpitComForm::alignUiElementsHeight()
230  {
231  const int selcalH = ui->frp_ComPanelSelcalSelector->getComboBoxHeight();
232  if (selcalH > ui->ds_ComPanelCom1Standby->height())
233  {
234  ui->ds_ComPanelCom1Standby->setMinimumHeight(selcalH);
235  ui->ds_ComPanelCom2Standby->setMinimumHeight(selcalH);
236  }
237 
238  const int xpdrH = ui->cbp_ComPanelTransponderMode->height();
239  if (xpdrH > ui->ds_ComPanelCom1Active->height())
240  {
241  ui->ds_ComPanelCom1Active->setMinimumHeight(xpdrH);
242  ui->ds_ComPanelCom2Active->setMinimumHeight(xpdrH);
243  ui->sbp_ComPanelTransponder->setMinimumHeight(xpdrH);
244  }
245  }
246 
247  void CCockpitComForm::updateActiveCOMUnitLEDs(bool integratedWithSim, bool com1T, bool com1R, bool com2T,
248  bool com2R)
249  {
250  if (!integratedWithSim)
251  {
252  ui->led_ComPanelCom1R->setTriState();
253  ui->led_ComPanelCom1T->setTriState();
254  ui->led_ComPanelCom2R->setTriState();
255  ui->led_ComPanelCom2T->setTriState();
256  }
257  else
258  {
259  ui->led_ComPanelCom1R->setOn(com1R);
260  ui->led_ComPanelCom1T->setOn(com1T);
261  ui->led_ComPanelCom2R->setOn(com2R);
262  ui->led_ComPanelCom2T->setOn(com2T);
263  }
264  }
265 
266  void CCockpitComForm::updateIntegratedFlagFromSimulatorContext()
267  {
269  {
270  m_integratedWithSim = false;
271  return;
272  }
273  const bool integrated = sGui->getIContextSimulator()->getSimulatorSettings().isComIntegrated();
274  m_integratedWithSim = integrated;
275  }
276 
277  bool CCockpitComForm::isFrequenceEqual(double f1, double f2) { return CMathUtils::epsilonEqual(f1, f2); }
278 } // namespace swift::gui::editors
bool isShuttingDown() const
Is application shutting down?
const context::IContextSimulator * getIContextSimulator() const
Direct access to contexts if a CCoreFacade has been initialized.
virtual swift::misc::simulation::settings::CSimulatorSettings getSimulatorSettings() const =0
Get the current simulator settings.
LedShape
Shapes.
Definition: led.h:51
void setSelectOnly()
Read only, but entity can be selected (normally used in mapping). Use setReadOnly to reset this very ...
void transponderStateIdentEnded()
Ident phase ended.
swift::misc::aviation::CSelcal getSelcal() const
Get SELCAL.
void setFrequencies(const swift::misc::aviation::CComSystem &com1, const swift::misc::aviation::CComSystem &com2)
COM frequencies displayed.
void requestCom2TextMessage()
Request COM text messages.
void requestCom1TextMessage()
Request COM text messages.
void transponderModeChanged(swift::misc::aviation::CTransponder::TransponderMode newMode)
Mode / state has been changed.
swift::misc::CStatusMessageList validate(bool nested=false) const
Validate, empty list means OK.
void setTransponderModeStateIdent()
Set to swift::misc::aviation::CTransponder::StateIdent.
void changedCockpitValues(const swift::misc::simulation::CSimulatedAircraft &aircraft)
GUI values changed.
void setSelcal(const swift::misc::aviation::CSelcal &selcal)
Set SELCAL.
void setTransponder(const swift::misc::aviation::CTransponder &transponder)
Set the XPDR values.
void testSelcal()
Request to test SELCAL.
void changedSelcal(const swift::misc::aviation::CSelcal &selcal)
SELCAL value changed.
void setReadOnly(bool readonly)
Set editable.
void setValue(const swift::misc::simulation::CSimulatedAircraft &aircraft)
Set all values.
Form base class.
Definition: form.h:27
void forceStyleSheetUpdate()
Forces a stylesheet update.
Definition: form.cpp:47
Class for emitting a log message.
Definition: logmessage.h:27
Derived & validationWarning(const char16_t(&format)[N])
Set the severity to warning, providing a format string, and adding the validation category.
Status messages, e.g. from Core -> GUI.
COM system (aka "radio")
Definition: comsystem.h:37
void setFrequencyActiveMHz(double frequencyMHz)
Set active frequency.
Definition: comsystem.cpp:25
void setFrequencyStandbyMHz(double frequencyMHz)
Set standby frequency.
Definition: comsystem.cpp:31
bool isTransmitEnabled() const
Enabled?
Definition: modulator.cpp:82
swift::misc::physical_quantities::CFrequency getFrequencyStandby() const
Standby frequency.
Definition: modulator.cpp:36
bool isReceiveEnabled() const
Enabled?
Definition: modulator.cpp:88
swift::misc::physical_quantities::CFrequency getFrequencyActive() const
Active frequency.
Definition: modulator.cpp:30
Value object for SELCAL.
Definition: selcal.h:31
void setTransponderCode(int transponderCode)
Set transponder code.
Definition: transponder.h:116
int getTransponderCode() const
Transponder code.
Definition: transponder.h:107
bool setTransponderMode(TransponderMode mode)
Set transponder mode.
Definition: transponder.cpp:97
TransponderMode getTransponderMode() const
Transponder mode.
Definition: transponder.h:95
double valueRounded(MU unit, int digits=-1) const
Rounded value in given unit.
Comprehensive information of an aircraft.
const aviation::CSelcal getSelcal() const
SELCAL.
const aviation::CComSystem & getCom2System() const
Get COM2 system.
const aviation::CTransponder & getTransponder() const
Get transponder.
void setCom1System(const aviation::CComSystem &comSystem)
Set COM1 system.
void setTransponder(const aviation::CTransponder &transponder)
Set transponder.
void setCom2System(const aviation::CComSystem &comSystem)
Set COM2 system.
const aviation::CComSystem & getCom1System() const
Get COM1 system.
SWIFT_GUI_EXPORT swift::gui::CGuiApplication * sGui
Single instance of GUI application object.
High level reusable GUI components.
Definition: aboutdialog.cpp:14
Free functions in swift::misc.
void clicked(bool checked)
void editingFinished()
QMetaObject::Connection connect(const QObject *sender, PointerToMemberFunction signal, Functor functor)
QObject * sender() const const
QString number(double n, char format, int precision)