swift
cockpitcomcomponent.cpp
1 // SPDX-FileCopyrightText: Copyright (C) 2013 swift Project Community / Contributors
2 // SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-swift-pilot-client-1
3 
5 
6 #include <QDoubleSpinBox>
7 #include <QLabel>
8 #include <QPushButton>
9 #include <QString>
10 #include <QtGlobal>
11 
12 #include "ui_cockpitcomcomponent.h"
13 
21 #include "gui/guiapplication.h"
22 #include "gui/led.h"
23 #include "gui/stylesheetutility.h"
26 #include "misc/aviation/callsign.h"
28 #include "misc/logmessage.h"
29 #include "misc/pq/frequency.h"
30 #include "misc/pq/units.h"
31 #include "misc/sequence.h"
32 #include "misc/verify.h"
33 
34 using namespace swift::gui;
35 using namespace swift::gui::editors;
36 using namespace swift::core;
37 using namespace swift::core::context;
38 using namespace swift::misc;
39 using namespace swift::misc::audio;
40 using namespace swift::misc::aviation;
41 using namespace swift::misc::simulation;
42 using namespace swift::misc::physical_quantities;
43 
44 namespace swift::gui::components
45 {
46  CCockpitComComponent::CCockpitComComponent(QWidget *parent)
47  : QFrame(parent), CIdentifiable(this), ui(new Ui::CCockpitComComponent)
48  {
49  ui->setupUi(this);
50 
51  // init from aircraft
52  this->forceCockpitUpdateFromOwnAircraftContext();
53 
54  // COM form
55  connect(ui->editor_Com, &CCockpitComForm::testSelcal, this, &CCockpitComComponent::testSelcal);
56  connect(ui->editor_Com, &CCockpitComForm::changedCockpitValues, this,
57  &CCockpitComComponent::updateOwnCockpitInContext);
58  connect(ui->editor_Com, &CCockpitComForm::changedSelcal, this, &CCockpitComComponent::updateSelcalInContext);
59  connect(ui->editor_Com, &CCockpitComForm::requestCom1TextMessage, this,
61  connect(ui->editor_Com, &CCockpitComForm::requestCom2TextMessage, this,
63 
64  // Relay COM form signals
65  connect(ui->editor_Com, &CCockpitComForm::transponderModeChanged, this,
67  connect(ui->editor_Com, &CCockpitComForm::transponderStateIdentEnded, this,
69 
70  // hook up with changes from own aircraft context
71  if (sGui)
72  {
73  // own aircraft
74  connect(sGui->getIContextOwnAircraft(), &IContextOwnAircraft::changedAircraftCockpit, this,
75  &CCockpitComComponent::updateCockpitFromContext, Qt::QueuedConnection);
76  connect(sGui->getIContextOwnAircraft(), &IContextOwnAircraft::changedSelcal, this,
77  &CCockpitComComponent::updateSelcalFromContext, Qt::QueuedConnection);
78 
79  // hook up with audio context
80  // connect(sGui->getIContextAudio(), &IContextAudio::changedVoiceRooms, this,
81  // &CCockpitComComponent::updateVoiceRoomStatusFromContext, Qt::QueuedConnection);
82 
83  // network
84  connect(sGui->getIContextNetwork(), &IContextNetwork::changedAtcStationsOnlineDigest, this,
85  &CCockpitComComponent::onAtcStationsChanged, Qt::QueuedConnection);
86 
87  QPointer<CCockpitComComponent> myself(this);
88  QTimer::singleShot(10 * 1000, this, [=] {
89  if (!sGui || sGui->isShuttingDown() || !myself) { return; }
91  this->updateCockpitFromContext(aircraft, CIdentifier::fake());
92  });
93  }
94  }
95 
97 
98  void CCockpitComComponent::setTransponderModeStateIdent() { ui->editor_Com->setTransponderModeStateIdent(); }
99 
100  void CCockpitComComponent::paintEvent(QPaintEvent *event)
101  {
102  Q_UNUSED(event)
104  }
105 
106  void CCockpitComComponent::updateCockpitFromContext(const CSimulatedAircraft &ownAircraft,
107  const CIdentifier &originator)
108  {
109  if (isMyIdentifier(originator)) { return; } // comes from myself
110 
111  // update GUI elements
112  // avoid unnecessary change events as far as possible
113  const CComSystem com1 = ownAircraft.getCom1System(); // aircraft just updated or set from context
114  const CComSystem com2 = ownAircraft.getCom2System();
115  const CTransponder transponder = ownAircraft.getTransponder();
116 
117  // update the frequencies
118  ui->editor_Com->setFrequencies(com1, com2);
119 
120  // update transponder
121  ui->editor_Com->setTransponder(transponder);
122  }
123 
124  void CCockpitComComponent::testSelcal()
125  {
126  Q_ASSERT_X(sGui, Q_FUNC_INFO, "Need sGui");
127  const CSelcal selcal = ui->editor_Com->getSelcal();
128  if (!selcal.isValid()) { CLogMessage().validationWarning(u"Invalid SELCAL code"); }
130  else { CLogMessage().validationWarning(u"No audio available"); }
131  }
132 
133  void CCockpitComComponent::updateSelcalFromContext(const CSelcal &selcal, const CIdentifier &originator)
134  {
135  if (isMyIdentifier(originator)) { return; } // comes from myself
136  ui->editor_Com->setSelcal(selcal);
137  }
138 
139  CSimulatedAircraft CCockpitComComponent::getOwnAircraft() const
140  {
141  // unavailable context during shutdown possible
142  // mostly when client runs with DBus, but DBus is down
143  if (!sGui || sGui->isShuttingDown() || !sGui->getIContextOwnAircraft()) { return CSimulatedAircraft(); }
145  }
146 
147  bool CCockpitComComponent::updateOwnCockpitInContext(const CSimulatedAircraft &ownAircraft)
148  {
149  // unavailable context during shutdown possible
150  // mostly when client runs with DBus, but DBus is down
151  if (!sGui || sGui->isShuttingDown() || !sGui->getIContextOwnAircraft()) { return false; }
152  return sGui->getIContextOwnAircraft()->updateCockpit(ownAircraft.getCom1System(), ownAircraft.getCom2System(),
153  ownAircraft.getTransponder(), identifier());
154  }
155 
156  void CCockpitComComponent::forceCockpitUpdateFromOwnAircraftContext()
157  {
158  if (!sGui || sGui->isShuttingDown()) { return; }
159  const CSimulatedAircraft ownAircraft = this->getOwnAircraft();
160  this->updateCockpitFromContext(ownAircraft,
161  CIdentifier("dummyInitialValues")); // intentionally different name here
162  }
163 
164  void CCockpitComComponent::onAtcStationsChanged()
165  {
166  // void
167  }
168 
169  void CCockpitComComponent::updateSelcalInContext(const CSelcal &selcal)
170  {
171  if (!sGui || sGui->isShuttingDown() || !sGui->getIContextOwnAircraft()) { return; }
173  }
174 } // namespace swift::gui::components
const context::IContextOwnAircraft * getIContextOwnAircraft() const
Direct access to contexts if a CCoreFacade has been initialized.
const context::IContextNetwork * getIContextNetwork() const
Direct access to contexts if a CCoreFacade has been initialized.
bool isShuttingDown() const
Is application shutting down?
const context::CContextAudioBase * getCContextAudioBase() const
Direct access to contexts if a CCoreFacade has been initialized.
void playSelcalTone(const swift::misc::aviation::CSelcal &selcal)
SELCAL.
virtual bool updateSelcal(const swift::misc::aviation::CSelcal &selcal, const swift::misc::CIdentifier &originator)=0
Own SELCAL code.
virtual swift::misc::simulation::CSimulatedAircraft getOwnAircraft() const =0
Get own aircraft.
virtual bool updateCockpit(const swift::misc::aviation::CComSystem &com1, const swift::misc::aviation::CComSystem &com2, const swift::misc::aviation::CTransponder &transponder, const swift::misc::CIdentifier &originator)=0
Update own cockpit.
static bool useStyleSheetInDerivedWidget(QWidget *derivedWidget, QStyle::PrimitiveElement element=QStyle::PE_Widget)
Use style sheets in derived widgets.
void requestCom1TextMessage()
Request COM text messages.
void transponderModeChanged(swift::misc::aviation::CTransponder::TransponderMode newMode)
Mode / state has been changed.
void setTransponderModeStateIdent()
Set to swift::misc::aviation::CTransponder::StateIdent.
void requestCom2TextMessage()
Request COM text messages.
void transponderStateIdentEnded()
Ident phase ended.
Base class with a member CIdentifier to be inherited by a class which has an identity in the environm...
Definition: identifiable.h:24
bool isMyIdentifier(const CIdentifier &otherIdentifier) const
My identifier?
Definition: identifiable.h:33
const CIdentifier & identifier() const
Get identifier.
Definition: identifiable.h:27
Value object encapsulating information identifying a component of a modular distributed swift process...
Definition: identifier.h:29
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.
COM system (aka "radio")
Definition: comsystem.h:37
Value object for SELCAL.
Definition: selcal.h:31
bool isValid() const
Is valid?
Definition: selcal.h:43
Comprehensive information of an aircraft.
const aviation::CComSystem & getCom2System() const
Get COM2 system.
const aviation::CTransponder & getTransponder() const
Get transponder.
const aviation::CComSystem & getCom1System() const
Get COM1 system.
SWIFT_GUI_EXPORT swift::gui::CGuiApplication * sGui
Single instance of GUI application object.
Backend services of the swift project, like dealing with the network or the simulators.
Definition: actionbind.cpp:7
High level reusable GUI components.
Definition: aboutdialog.cpp:13
GUI related classes.
Free functions in swift::misc.
auto singleShot(int msec, QObject *target, F &&task)
Starts a single-shot timer which will call a task in the thread of the given object when it times out...
Definition: threadutils.h:30