swift
aircraftpartscomponent.cpp
1 // SPDX-FileCopyrightText: Copyright (C) 2020 swift Project Community / Contributors
2 // SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-swift-pilot-client-1
3 
5 
6 #include "ui_aircraftpartscomponent.h"
7 
11 #include "gui/guiapplication.h"
14 
15 using namespace swift::misc;
16 using namespace swift::misc::aviation;
17 using namespace swift::misc::network;
18 using namespace swift::misc::math;
19 using namespace swift::misc::physical_quantities;
20 using namespace swift::misc::simulation;
21 using namespace swift::core;
22 using namespace swift::core::context;
23 
24 namespace swift::gui::components
25 {
26  CAircraftPartsComponent::CAircraftPartsComponent(QWidget *parent)
27  : QFrame(parent), ui(new Ui::CAircraftPartsComponent)
28  {
29  ui->setupUi(this);
30 
31  ui->editor_AircraftParts->showSetButton(false);
32  connect(ui->pb_SendAircraftPartsGui, &QPushButton::released, this, &CAircraftPartsComponent::sendAircraftParts);
33  connect(ui->pb_SendAircraftPartsJson, &QPushButton::released, this,
34  &CAircraftPartsComponent::sendAircraftParts);
35  connect(ui->pb_CurrentParts, &QPushButton::released, this, &CAircraftPartsComponent::setCurrentParts);
36  connect(ui->pb_OwnParts, &QPushButton::released, this, &CAircraftPartsComponent::displayOwnParts);
37  connect(ui->pb_RequestFromNetwork, &QPushButton::released, this,
38  &CAircraftPartsComponent::requestPartsFromNetwork);
39  connect(ui->pb_DisplayLog, &QPushButton::released, this, &CAircraftPartsComponent::displayLogInSimulator);
40  connect(ui->comp_RemoteAircraftCompleter, &CCallsignCompleter::validCallsignEnteredDigest, this,
41  &CAircraftPartsComponent::onCallsignChanged);
42 
43  ui->comp_RemoteAircraftCompleter->addOwnCallsign(true);
44  }
45 
47  {
48  // void
49  }
50 
52  {
53  ui->comp_RemoteAircraftCompleter->setCallsign(callsign);
54  this->onCallsignChanged();
55  }
56 
57  void CAircraftPartsComponent::sendAircraftParts()
58  {
59  if (!sGui || sGui->isShuttingDown()) { return; }
60 
61  Q_ASSERT(sGui->getIContextNetwork());
63  {
64  CLogMessage(this).validationError(u"Cannot send aircraft parts, network not connected");
65  return;
66  }
67  const CCallsign callsign(ui->comp_RemoteAircraftCompleter->getCallsign(true));
68  if (callsign.isEmpty())
69  {
70  CLogMessage(this).validationError(u"No valid callsign selected");
71  return;
72  }
73 
75  if (client.getCallsign().isEmpty() || client.getCallsign() != callsign)
76  {
77  CLogMessage(this).validationError(u"No valid client for '%1'") << callsign.asString();
78  return;
79  }
80 
81  if (!client.hasAircraftPartsCapability())
82  {
83  static const QString question("'%1' does not support parts, enable parts for it?");
84  const QMessageBox::StandardButton reply = QMessageBox::question(
85  this, "No parts supported", question.arg(callsign.asString()), QMessageBox::Yes | QMessageBox::No);
86  if (reply != QMessageBox::Yes) { return; }
87  client.addCapability(CClient::FsdWithAircraftConfig);
88  const bool enabled = sGui->getIContextNetwork()->setOtherClient(client);
89  Q_UNUSED(enabled)
90  }
91 
92  const bool json = (QObject::sender() == ui->pb_SendAircraftPartsJson);
93  const CAircraftParts parts = json ? ui->editor_AircraftParts->getAircraftPartsFromJson() :
94  ui->editor_AircraftParts->getAircraftPartsFromGui();
95  ui->editor_AircraftParts->setAircraftParts(parts); // display in UI as GUI and JSON
96 
97  ui->tb_History->setToolTip("");
98  const bool incremental = ui->cb_AircraftPartsIncremental->isChecked();
99  sGui->getIContextNetwork()->testAddAircraftParts(callsign, parts, incremental);
100  CLogMessage(this).info(u"Added parts for %1") << callsign.toQString();
101  }
102 
103  void CAircraftPartsComponent::setCurrentParts()
104  {
105  if (!sGui->getIContextNetwork()->isConnected()) { return; }
106  const CCallsign callsign(ui->comp_RemoteAircraftCompleter->getCallsign());
107  if (callsign.isEmpty()) { return; }
108 
109  const CAircraftPartsList partsList = sGui->getIContextNetwork()->getRemoteAircraftParts(callsign);
110  if (partsList.isEmpty())
111  {
112  CStatusMessage(this).info(u"No parts for '%1'") << callsign.asString();
113  return;
114  }
115  const CAircraftParts parts = partsList.latestObject();
117  ui->editor_AircraftParts->setAircraftParts(parts);
118  ui->tb_History->setToolTip(history.toHtml());
119  }
120 
121  void CAircraftPartsComponent::requestPartsFromNetwork()
122  {
123  if (!sGui || sGui->isShuttingDown()) { return; }
124  if (!sGui->getIContextNetwork()) { return; }
125 
126  const CCallsign callsign(ui->comp_RemoteAircraftCompleter->getCallsign(true));
127  if (callsign.isEmpty())
128  {
129  CLogMessage(this).validationError(u"No valid callsign selected");
130  return;
131  }
132  ui->pb_RequestFromNetwork->setEnabled(false);
134  CLogMessage(this).info(u"Request aircraft config for '%1'") << callsign.asString();
135 
136  // simple approach to update UI when parts are received
137  const QPointer<CAircraftPartsComponent> myself(this);
138  QTimer::singleShot(3000, this, [=] {
139  if (!myself) { return; }
140  ui->pb_CurrentParts->click();
141  ui->pb_RequestFromNetwork->setEnabled(true);
142  });
143  }
144 
145  void CAircraftPartsComponent::onCallsignChanged()
146  {
147  this->setCurrentParts();
148  emit this->callsignChanged(ui->comp_RemoteAircraftCompleter->getCallsign());
149  }
150 
151  void CAircraftPartsComponent::displayOwnParts()
152  {
153  if (!sGui || sGui->isShuttingDown()) { return; }
154  if (!sGui->getIContextOwnAircraft()) { return; }
155 
157  const CCallsign cs = myAircraft.getCallsign();
158  const CAircraftParts parts = myAircraft.getParts();
159  ui->comp_RemoteAircraftCompleter->setCallsign(cs);
160  ui->editor_AircraftParts->setAircraftParts(parts);
161  }
162 
163  void CAircraftPartsComponent::displayLogInSimulator()
164  {
165  if (!sGui || sGui->isShuttingDown()) { return; }
166  if (!sGui->getIContextSimulator()) { return; }
167  const CCallsign callsign(ui->comp_RemoteAircraftCompleter->getCallsign(true));
168  if (callsign.isEmpty())
169  {
170  CLogMessage(this).validationError(u"No valid callsign selected");
171  return;
172  }
173 
174  const CIdentifier i(this->objectName());
175  const QString dotCmd(".drv pos " + callsign.asString());
177  }
178 
179 } // 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::IContextSimulator * getIContextSimulator() const
Direct access to contexts if a CCoreFacade has been initialized.
virtual bool parseCommandLine(const QString &commandLine, const swift::misc::CIdentifier &originator)=0
Parse a given command line.
virtual swift::misc::CStatusMessageList getAircraftPartsHistory(const swift::misc::aviation::CCallsign &callsign) const =0
Get aircraft parts history.
virtual bool setOtherClient(const swift::misc::network::CClient &client)=0
Set client for given callsign.
virtual swift::misc::aviation::CAircraftPartsList getRemoteAircraftParts(const swift::misc::aviation::CCallsign &callsign) const =0
Get remote aircraft parts.
virtual swift::misc::network::CClientList getClientsForCallsigns(const swift::misc::aviation::CCallsignSet &callsigns) const =0
Clients for given callsign, e.g. to test/fetch direct aircraft model.
virtual void testRequestAircraftConfig(const swift::misc::aviation::CCallsign &callsign)=0
Request parts for callsign (from another client)
virtual void testAddAircraftParts(const swift::misc::aviation::CCallsign &callsign, const swift::misc::aviation::CAircraftParts &parts, bool incremental)=0
Inject aircraft parts for testing.
virtual bool isConnected() const =0
Network connected?
virtual swift::misc::simulation::CSimulatedAircraft getOwnAircraft() const =0
Get own aircraft.
Allows to display and manipulate parts.
void setCallsign(const swift::misc::aviation::CCallsign &callsign)
Set selected callsign.
void callsignChanged(const swift::misc::aviation::CCallsign &callsign)
Currently used callsign.
void validCallsignEnteredDigest()
Changed callsign entered.
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 & validationError(const char16_t(&format)[N])
Set the severity to error, providing a format string, and adding the validation category.
Derived & info(const char16_t(&format)[N])
Set the severity to info, providing a format string.
const_reference frontOrDefault() const
Access the first element, or a default-initialized value if the sequence is empty.
Definition: sequence.h:239
bool isEmpty() const
Synonym for empty.
Definition: sequence.h:285
Streamable status message, e.g.
Status messages, e.g. from Core -> GUI.
QString toHtml(const CPropertyIndexList &indexes=simpleHtmlOutput()) const
Specialized version to convert to HTML.
OBJ latestObject() const
Latest object.
Value object encapsulating information of aircraft's parts.
Definition: aircraftparts.h:26
Value object encapsulating a list of aircraft parts.
Value object encapsulating information of a callsign.
Definition: callsign.h:30
bool isEmpty() const
Is empty?
Definition: callsign.h:63
Another client software.
Definition: client.h:27
bool hasAircraftPartsCapability() const
Supports aircraft parts?
Definition: client.cpp:66
void addCapability(Capability capability)
Add capability.
Definition: client.cpp:33
const aviation::CCallsign & getCallsign() const
Callsign used with other client.
Definition: client.h:68
Comprehensive information of an aircraft.
const aviation::CCallsign & getCallsign() const
Get callsign.
const aviation::CAircraftParts & getParts() const
Get aircraft parts.
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
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