swift
callsigncompleter.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 "callsigncompleter.h"
5 
6 #include <QStringListModel>
7 
8 #include "ui_callsigncompleter.h"
9 
12 #include "gui/guiapplication.h"
13 #include "gui/led.h"
14 #include "gui/uppercasevalidator.h"
16 
17 using namespace swift::misc;
18 using namespace swift::misc::aviation;
19 using namespace swift::misc::network;
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  CCallsignCompleter::CCallsignCompleter(QWidget *parent) : QFrame(parent), ui(new Ui::CCallsignCompleter)
27  {
28  Q_ASSERT_X(sGui, Q_FUNC_INFO, "Need sGui");
29  Q_ASSERT_X(sGui->getIContextNetwork(), Q_FUNC_INFO, "Need network context");
30  ui->setupUi(this);
31  CUpperCaseValidator *ucv = new CUpperCaseValidator(ui->le_Callsign);
32  ui->le_Callsign->setValidator(ucv);
33  ui->le_Callsign->setCompleter(*completer());
34  ui->led_Status->setToolTips("connected", "disconnected");
35  ui->led_Status->setShape(CLedWidget::Rounded);
36  ui->led_Status->setToolTips("network connected", "network disconnected", "data");
37  ui->led_Status->setShape(CLedWidget::Rounded);
38  connect(ui->le_Callsign, &QLineEdit::editingFinished, this, &CCallsignCompleter::onEditingFinished);
39  connect(sGui->getIContextNetwork(), &IContextNetwork::changedAircraftInRange, &m_dsAircraftsInRangeChanged,
40  &CDigestSignal::inputSignal);
41  connect(sGui->getIContextNetwork(), &IContextNetwork::connectionStatusChanged, this,
42  &CCallsignCompleter::onChangedConnectionStatus, Qt::QueuedConnection);
43  m_dsAircraftsInRangeChanged.inputSignal(); // trigger
44  }
45 
47 
48  CCallsign CCallsignCompleter::getCallsign(bool onlyKnownCallsign) const
49  {
50  const QString csString = ui->le_Callsign->text().trimmed().toUpper();
51  const bool valid =
52  onlyKnownCallsign ? this->isValidKnownCallsign(csString) : CCallsign::isValidAircraftCallsign(csString);
53  if (!valid) { return CCallsign(); }
54  return CCallsign(csString, CCallsign::Aircraft);
55  }
56 
57  void CCallsignCompleter::setCallsign(const CCallsign &cs) { ui->le_Callsign->setText(cs.asString()); }
58 
59  QString CCallsignCompleter::getRawCallsignString() const { return ui->le_Callsign->text(); }
60 
62  {
63  const QString csString = ui->le_Callsign->text().trimmed().toUpper();
64  return this->isValidKnownCallsign(csString);
65  }
66 
67  void CCallsignCompleter::setReadOnly(bool readOnly)
68  {
69  if (ui->le_Callsign->isReadOnly() == readOnly) { return; }
70  ui->le_Callsign->setReadOnly(readOnly);
71  this->setStyleSheet(this->styleSheet());
72  }
73 
74  void CCallsignCompleter::updateCallsignsFromContext()
75  {
76  if (!sGui || sGui->isShuttingDown()) { return; }
77  if (!sGui->getIContextNetwork()) { return; }
78  if (completer()->wasUpdatedWithinTime(1500)) { return; } // avoid context call via DBus
79  CCallsignSet validCallsigns;
80  if (m_onlyWithParts)
81  {
84  }
85  else { validCallsigns = sGui->getIContextNetwork()->getAircraftInRangeCallsigns(); }
86 
87  if (m_addOwnCallsign && sGui->getIContextOwnAircraft())
88  {
90  if (!ownCs.isEmpty()) { validCallsigns.insert(ownCs); }
91  }
92 
93  const QStringList modelData = validCallsigns.getCallsignStrings(true);
94  completer()->updateData(modelData, 2000);
95  ui->led_Status->setTriState(500);
96  }
97 
98  void CCallsignCompleter::onEditingFinished()
99  {
100  const CCallsign cs = this->getCallsign();
101  const bool changed = (cs.asString() == m_lastValue);
102  m_lastValue = cs.asString();
103  m_dsEditingFinished.inputSignal();
104  if (cs.isValid())
105  {
106  m_dsValidCallsignEntered.inputSignal();
107  if (changed) { emit this->validChangedCallsignEntered(); }
108  }
109  }
110 
111  void CCallsignCompleter::onChangedAircraftInRange() { this->updateCallsignsFromContext(); }
112 
113  void CCallsignCompleter::onChangedConnectionStatus(const CConnectionStatus &from, const CConnectionStatus &to)
114  {
115  Q_UNUSED(from)
116  const bool connected = to.isConnected();
117  ui->led_Status->setOn(connected);
118  ui->le_Callsign->clear();
119  ui->le_Callsign->setEnabled(connected);
120  if (!connected) { completer()->clearData(); }
121  }
122 
123  bool CCallsignCompleter::isValidKnownCallsign(const QString &callsignString) const
124  {
125  if (!CCallsign::isValidAircraftCallsign(callsignString)) { return false; }
126  if (!completer()) { return false; }
127  return completer()->contains(callsignString);
128  }
129 
130  CSharedStringListCompleter *CCallsignCompleter::completer()
131  {
132  static CSharedStringListCompleter *c = new CSharedStringListCompleter();
133  return c;
134  }
135 } // 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?
virtual swift::misc::aviation::CCallsignSet getAircraftInRangeCallsigns() const =0
Aircraft callsigns.
virtual swift::misc::simulation::CSimulatedAircraftList getAircraftInRange() const =0
Aircraft list.
virtual swift::misc::simulation::CSimulatedAircraft getOwnAircraft() const =0
Get own aircraft.
bool contains(const QString &value, Qt::CaseSensitivity cs=Qt::CaseInsensitive) const
Contains the string completer the given value.
bool updateData(const QStringList &data, int cacheTimeMs)
Update data.
Completer for aircraft callsigns.
void setReadOnly(bool readOnly)
Set read only.
QString getRawCallsignString() const
String as entered.
void setCallsign(const swift::misc::aviation::CCallsign &cs)
Prefill wit callsign.
bool hasValidCallsign() const
Is valid callsign?
swift::misc::aviation::CCallsign getCallsign(bool onlyKnownCallsign=true) const
Get the entered callsign.
void validChangedCallsignEntered()
Changed callsign entered.
iterator insert(const_iterator hint, const T &value)
For compatibility with std::inserter.
Definition: collection.h:199
void inputSignal()
Received input signal, or manually trigger.
Value object encapsulating information of a callsign.
Definition: callsign.h:30
const QString & asString() const
Get callsign (normalized)
Definition: callsign.h:96
bool isEmpty() const
Is empty?
Definition: callsign.h:63
bool isValid() const
Valid callsign?
Definition: callsign.cpp:359
Value object for a set of callsigns.
Definition: callsignset.h:26
QStringList getCallsignStrings(bool sorted=false) const
The callsign strings.
Definition: callsignset.cpp:37
Value object encapsulating information about a connection status.
bool isConnected() const
Query status.
const aviation::CCallsign & getCallsign() const
Get callsign.
aviation::CCallsignSet getCallsignsWithSynchronizedParts() const
Callsigns of aircraft with synchronized 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.