swift
aircraftpartshistory.cpp
1 // SPDX-FileCopyrightText: Copyright (C) 2016 swift Project Community / Contributors
2 // SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-swift-pilot-client-1
3 
4 #include "aircraftpartshistory.h"
5 
6 #include <QCompleter>
7 #include <QHash>
8 #include <QStringBuilder>
9 #include <QStringListModel>
10 
11 #include "ui_aircraftpartshistory.h"
12 
15 #include "gui/guiapplication.h"
16 #include "gui/uppercasevalidator.h"
17 #include "misc/htmlutils.h"
18 #include "misc/propertyindexlist.h"
19 
20 using namespace swift::misc;
21 using namespace swift::misc::aviation;
22 using namespace swift::misc::network;
23 using namespace swift::core;
24 using namespace swift::core::context;
25 
26 namespace swift::gui::components
27 {
28  CAircraftPartsHistory::CAircraftPartsHistory(QWidget *parent) : QFrame(parent), ui(new Ui::CAircraftPartsHistory)
29  {
30  ui->setupUi(this);
31  ui->cb_PartsHistoryEnabled->setChecked(sApp && sApp->isDeveloperFlagSet()); // default
32 
33  m_timerUpdateHistory.setInterval(2 * 1000);
34  this->initGui();
35  m_text.setDefaultStyleSheet(CStatusMessageList::htmlStyleSheet());
36  connect(ui->comp_CallsignCompleter, &CCallsignCompleter::validChangedCallsignEntered, this,
37  &CAircraftPartsHistory::callsignEntered);
38  connect(ui->cb_PartsHistoryEnabled, &QCheckBox::toggled, this, &CAircraftPartsHistory::toggleHistoryEnabled);
39 
40  if (this->hasContexts())
41  {
42  connect(sGui->getIContextNetwork(), &IContextNetwork::changedLogOrDebugSettings, this,
43  &CAircraftPartsHistory::valuesChanged);
44  connect(sGui->getIContextNetwork(), &IContextNetwork::connectionStatusChanged, this,
45  &CAircraftPartsHistory::connectionStatusChanged);
46  }
47  connect(&m_timerUpdateHistory, &QTimer::timeout, this, &CAircraftPartsHistory::updatePartsHistory);
48  }
49 
51 
52  void CAircraftPartsHistory::initGui()
53  {
54  if (!sGui || sGui->isShuttingDown() || !sGui->getIContextNetwork()) { return; }
55  const bool needCallsigns = this->partsHistoryEnabled();
56  if (needCallsigns && !m_timerUpdateHistory.isActive()) { m_timerUpdateHistory.start(); }
57  else if (!needCallsigns) { m_timerUpdateHistory.stop(); }
58 
59  // avoid signal roundtrip
61  ui->cb_PartsHistoryEnabled->setChecked(c);
62  }
63 
64  bool CAircraftPartsHistory::hasContexts() const
65  {
67  }
68 
69  bool CAircraftPartsHistory::partsHistoryEnabled() const { return this->hasContexts(); }
70 
71  void CAircraftPartsHistory::updatePartsHistory()
72  {
73  if (!this->hasContexts()) { return; }
74  if (!this->isVisible()) { return; }
75  const CCallsign cs(ui->comp_CallsignCompleter->getCallsign());
76  if (cs.isEmpty()) { return; } // no or invalid callsign
77  const auto currentAircraftParts = sGui->getIContextNetwork()->getRemoteAircraftParts(cs).frontOrDefault();
78  const auto aircraftPartsHistory = sGui->getIContextNetwork()->getAircraftPartsHistory(cs);
79 
80  QString html;
81  if (currentAircraftParts == CAircraftParts() && aircraftPartsHistory.isEmpty())
82  {
83  html = cs.toQString() % u" does not support aircraft parts or nothing received yet.";
84  }
85  else
86  {
87  const QString s = u"lights on:"
88  u"<br>"
89  u"&nbsp;&nbsp;&nbsp;&nbsp;" %
90  currentAircraftParts.getLights().toQString() %
91  u"<br>"
92  u"gear down: " %
93  swift::misc::boolToYesNo(currentAircraftParts.isGearDown()) %
94  u"<br>"
95  u"flaps pct: " %
96  QString::number(currentAircraftParts.getFlapsPercent()) %
97  u"<br>"
98  u"spoilers out: " %
99  swift::misc::boolToYesNo(currentAircraftParts.isSpoilersOut()) %
100  u"<br>"
101  u"engines on: "
102  u"<br>"
103  u"&nbsp;&nbsp;&nbsp;&nbsp;" %
104  currentAircraftParts.getEngines().toQString() %
105  u"<br>"
106  u" on ground: " %
107  swift::misc::boolToYesNo(currentAircraftParts.isOnGround());
108  html += s;
109  if (ui->cb_PartsHistoryEnabled->isChecked())
110  {
111  html += u"<hr>" % aircraftPartsHistory.toHtml(CStatusMessageList::timestampHtmlOutput());
112  }
113  }
114 
115  const size_t hash = qHash(html);
116  if (hash == m_htmlHash) { return; } // avoid to always scroll to the end when there is no update
117  m_htmlHash = hash;
118  m_text.setHtml(html);
119  ui->te_Messages->setDocument(&m_text);
120 
121  if (ui->cb_AutoScrollEnabled->isChecked())
122  {
123  QTextCursor c = ui->te_Messages->textCursor();
124  c.movePosition(QTextCursor::End);
125  ui->te_Messages->setTextCursor(c);
126  }
127  }
128 
129  void CAircraftPartsHistory::callsignEntered()
130  {
131  this->updatePartsHistory();
132  m_timerUpdateHistory.start();
133  }
134 
135  void CAircraftPartsHistory::valuesChanged() { this->initGui(); }
136 
137  void CAircraftPartsHistory::toggleHistoryEnabled(bool enabled)
138  {
139  if (!sGui || !sGui->getIContextNetwork() || !sGui->getIContextSimulator()) { return; }
140  const QObject *sender = QObject::sender();
141  if (sender == ui->cb_PartsHistoryEnabled) { sGui->getIContextNetwork()->enableAircraftPartsHistory(enabled); }
142  }
143 
144  void CAircraftPartsHistory::connectionStatusChanged(const CConnectionStatus &from, const CConnectionStatus &to)
145  {
146  Q_UNUSED(from);
147  if (to.isConnected() || to.isDisconnected()) { this->initGui(); }
148  }
149 } // namespace swift::gui::components
SWIFT_CORE_EXPORT swift::core::CApplication * sApp
Single instance of application object.
Definition: application.cpp:71
bool isDeveloperFlagSet() const
Running with dev.flag?
Definition: application.h:173
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 isAircraftPartsHistoryEnabled() const =0
Is storing the aircraft parts history enabled?
virtual swift::misc::CStatusMessageList getAircraftPartsHistory(const swift::misc::aviation::CCallsign &callsign) const =0
Get aircraft parts history.
virtual swift::misc::aviation::CAircraftPartsList getRemoteAircraftParts(const swift::misc::aviation::CCallsign &callsign) const =0
Get remote aircraft parts.
virtual void enableAircraftPartsHistory(bool enabled)=0
Enable storing of aircraft parts.
History frame for received aircraft parts.
void validChangedCallsignEntered()
Changed callsign entered.
const_reference frontOrDefault() const
Access the first element, or a default-initialized value if the sequence is empty.
Definition: sequence.h:239
Value object encapsulating information of aircraft's parts.
Definition: aircraftparts.h:26
Value object encapsulating information of a callsign.
Definition: callsign.h:30
QString toQString(bool i18n=false) const
Cast as QString.
Definition: mixinstring.h:76
Value object encapsulating information about a connection status.
bool isConnected() const
Query status.
bool isDisconnected() const
Query status.
SWIFT_GUI_EXPORT swift::gui::CGuiApplication * sGui
Single instance of GUI application object.
size_t qHash(const std::string &key, uint seed)
std::string qHash
Definition: metaclass.h:86
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.
SWIFT_MISC_EXPORT const QString & boolToYesNo(bool v)
Bool to yes/no.