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 
49  {
50  ui->comp_RemoteAircraftCompleter->setCallsign(callsign);
51  this->onCallsignChanged();
52  }
53 
54  void CAircraftPartsComponent::sendAircraftParts()
55  {
56  if (!sGui || sGui->isShuttingDown()) { return; }
57 
58  Q_ASSERT(sGui->getIContextNetwork());
60  {
61  CLogMessage(this).validationError(u"Cannot send aircraft parts, network not connected");
62  return;
63  }
64  const CCallsign callsign(ui->comp_RemoteAircraftCompleter->getCallsign(true));
65  if (callsign.isEmpty())
66  {
67  CLogMessage(this).validationError(u"No valid callsign selected");
68  return;
69  }
70 
72  if (client.getCallsign().isEmpty() || client.getCallsign() != callsign)
73  {
74  CLogMessage(this).validationError(u"No valid client for '%1'") << callsign.asString();
75  return;
76  }
77 
78  if (!client.hasAircraftPartsCapability())
79  {
80  static const QString question("'%1' does not support parts, enable parts for it?");
82  this, "No parts supported", question.arg(callsign.asString()), QMessageBox::Yes | QMessageBox::No);
83  if (reply != QMessageBox::Yes) { return; }
84  client.addCapability(CClient::FsdWithAircraftConfig);
85  const bool enabled = sGui->getIContextNetwork()->setOtherClient(client);
86  Q_UNUSED(enabled)
87  }
88 
89  const bool json = (QObject::sender() == ui->pb_SendAircraftPartsJson);
90  const CAircraftParts parts = json ? ui->editor_AircraftParts->getAircraftPartsFromJson() :
91  ui->editor_AircraftParts->getAircraftPartsFromGui();
92  ui->editor_AircraftParts->setAircraftParts(parts); // display in UI as GUI and JSON
93 
94  ui->tb_History->setToolTip("");
95  const bool incremental = ui->cb_AircraftPartsIncremental->isChecked();
96  sGui->getIContextNetwork()->testAddAircraftParts(callsign, parts, incremental);
97  CLogMessage(this).info(u"Added parts for %1") << callsign.toQString();
98  }
99 
100  void CAircraftPartsComponent::setCurrentParts()
101  {
102  if (!sGui->getIContextNetwork()->isConnected()) { return; }
103  const CCallsign callsign(ui->comp_RemoteAircraftCompleter->getCallsign());
104  if (callsign.isEmpty()) { return; }
105 
106  const CAircraftPartsList partsList = sGui->getIContextNetwork()->getRemoteAircraftParts(callsign);
107  if (partsList.isEmpty())
108  {
109  CStatusMessage(this).info(u"No parts for '%1'") << callsign.asString();
110  return;
111  }
112  const CAircraftParts parts = partsList.latestObject();
114  ui->editor_AircraftParts->setAircraftParts(parts);
115  ui->tb_History->setToolTip(history.toHtml());
116  }
117 
118  void CAircraftPartsComponent::requestPartsFromNetwork()
119  {
120  if (!sGui || sGui->isShuttingDown()) { return; }
121  if (!sGui->getIContextNetwork()) { return; }
122 
123  const CCallsign callsign(ui->comp_RemoteAircraftCompleter->getCallsign(true));
124  if (callsign.isEmpty())
125  {
126  CLogMessage(this).validationError(u"No valid callsign selected");
127  return;
128  }
129  ui->pb_RequestFromNetwork->setEnabled(false);
131  CLogMessage(this).info(u"Request aircraft config for '%1'") << callsign.asString();
132 
133  // simple approach to update UI when parts are received
134  const QPointer<CAircraftPartsComponent> myself(this);
135  QTimer::singleShot(3000, this, [=] {
136  if (!myself) { return; }
137  ui->pb_CurrentParts->click();
138  ui->pb_RequestFromNetwork->setEnabled(true);
139  });
140  }
141 
142  void CAircraftPartsComponent::onCallsignChanged()
143  {
144  this->setCurrentParts();
145  emit this->callsignChanged(ui->comp_RemoteAircraftCompleter->getCallsign());
146  }
147 
148  void CAircraftPartsComponent::displayOwnParts()
149  {
150  if (!sGui || sGui->isShuttingDown()) { return; }
151  if (!sGui->getIContextOwnAircraft()) { return; }
152 
154  const CCallsign cs = myAircraft.getCallsign();
155  const CAircraftParts parts = myAircraft.getParts();
156  ui->comp_RemoteAircraftCompleter->setCallsign(cs);
157  ui->editor_AircraftParts->setAircraftParts(parts);
158  }
159 
160  void CAircraftPartsComponent::displayLogInSimulator()
161  {
162  if (!sGui || sGui->isShuttingDown()) { return; }
163  if (!sGui->getIContextSimulator()) { return; }
164  const CCallsign callsign(ui->comp_RemoteAircraftCompleter->getCallsign(true));
165  if (callsign.isEmpty())
166  {
167  CLogMessage(this).validationError(u"No valid callsign selected");
168  return;
169  }
170 
171  const CIdentifier i(this->objectName());
172  const QString dotCmd(".drv pos " + callsign.asString());
174  }
175 
176 } // 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:14
Free functions in swift::misc.
QMessageBox::StandardButton question(QWidget *parent, const QString &title, const QString &text, QMessageBox::StandardButtons buttons, QMessageBox::StandardButton defaultButton)
QMetaObject::Connection connect(const QObject *sender, PointerToMemberFunction signal, Functor functor)
QObject * sender() const const