swift
dbliveryselectorcomponent.cpp
1 // SPDX-FileCopyrightText: Copyright (C) 2015 swift Project Community / Contributors
2 // SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-swift-pilot-client-1
3 
5 
6 #include <QCompleter>
7 #include <QDragEnterEvent>
8 #include <QDragLeaveEvent>
9 #include <QDragMoveEvent>
10 #include <QDropEvent>
11 #include <QLabel>
12 #include <QLineEdit>
13 #include <QMetaType>
14 #include <QPalette>
15 #include <QStringList>
16 #include <Qt>
17 #include <QtGlobal>
18 
19 #include "ui_dbliveryselectorcomponent.h"
20 
21 #include "core/application.h"
22 #include "core/webdataservices.h"
23 #include "gui/guiapplication.h"
24 #include "gui/uppercasevalidator.h"
28 #include "misc/stringutils.h"
29 #include "misc/variant.h"
30 
31 using namespace swift::gui;
32 using namespace swift::core;
33 using namespace swift::misc;
34 using namespace swift::misc::aviation;
35 using namespace swift::misc::db;
36 using namespace swift::misc::network;
37 
38 namespace swift::gui::components
39 {
40  CDbLiverySelectorComponent::CDbLiverySelectorComponent(QWidget *parent)
41  : QFrame(parent), ui(new Ui::CDbLiverySelectorComponent)
42  {
43  ui->setupUi(this);
44  this->setAcceptDrops(true);
45  this->setAcceptedMetaTypeIds({ qMetaTypeId<CLivery>(), qMetaTypeId<CLiveryList>() });
46 
47  ui->le_Livery->setValidator(new CUpperCaseValidator(this));
48 
49  connect(ui->le_Livery, &QLineEdit::returnPressed, this, &CDbLiverySelectorComponent::onDataChanged);
50  connect(ui->le_Livery, &QLineEdit::editingFinished, this, &CDbLiverySelectorComponent::onDataChanged);
51 
52  connect(sGui->getWebDataServices(), &CWebDataServices::dataRead, this,
53  &CDbLiverySelectorComponent::onLiveriesRead, Qt::QueuedConnection);
54  this->onLiveriesRead(CEntityFlags::LiveryEntity, CEntityFlags::ReadFinished,
56  }
57 
59 
61  {
62  if (!livery.hasCombinedCode())
63  {
64  ui->le_Livery->clear();
65  return;
66  }
67 
68  if (livery != m_currentLivery)
69  {
70  ui->le_Livery->setText(livery.getCombinedCodePlusId());
71  m_currentLivery = livery;
72  emit changedLivery(livery);
73  }
74  }
75 
77  {
78  if (!sGui || sGui->isShuttingDown() || !sGui->hasWebDataServices()) { return; }
79  const int dbKey = CDatastoreUtility::extractIntegerKey(code);
80  CLivery livery;
81 
82  if (dbKey >= 0) { livery = sGui->getWebDataServices()->getLiveryForDbKey(dbKey); }
83 
84  if (!livery.hasValidDbKey())
85  {
86  const QString liveryCode = this->stripExtraInfo(code.toUpper().trimmed());
87  if (m_currentLivery.matchesCombinedCode(liveryCode)) { return; }
88  livery = sGui->getWebDataServices()->getLiveries().findByCombinedCode(liveryCode);
89  }
90 
91  if (livery.hasCompleteData()) { this->setLivery(livery); }
92  else
93  {
94  ui->lbl_Description->setText("");
95  ui->le_Livery->setText(code);
96  }
97  }
98 
100  {
101  if (!sGui || sGui->isShuttingDown()) { return {}; }
102 
103  const QString raw = ui->le_Livery->text();
104  const int dbKey = CDatastoreUtility::extractIntegerKey(raw);
105 
106  CLivery livery;
107  if (dbKey >= 0) { livery = sGui->getWebDataServices()->getLiveryForDbKey(dbKey); }
108  else
109  {
110  const QString liveryCode(this->stripExtraInfo(ui->le_Livery->text()));
111  livery = sGui->getWebDataServices()->getLiveries().findByCombinedCode(liveryCode);
112  }
113 
114  if (livery.hasCompleteData() && livery.hasValidDbKey())
115  {
116  // full data fetched
117  return livery;
118  }
119 
120  return m_currentLivery;
121  }
122 
124  {
125  const QString cc(ui->le_Livery->text().trimmed().toUpper());
127  }
128 
129  void CDbLiverySelectorComponent::setReadOnly(bool readOnly) { ui->le_Livery->setReadOnly(readOnly); }
130 
132  {
133  ui->lbl_Description->setVisible(description);
134  }
135 
137 
138  void CDbLiverySelectorComponent::clear() { ui->le_Livery->clear(); }
139 
141  {
142  if (!event || !acceptDrop(event->mimeData())) { return; }
144  event->acceptProposedAction();
145  }
146 
148  {
149  if (!event || !acceptDrop(event->mimeData())) { return; }
150  event->acceptProposedAction();
151  }
152 
154  {
155  if (!event) { return; }
156  event->accept();
157  }
158 
160  {
161  if (!event || !acceptDrop(event->mimeData())) { return; }
162  const CVariant valueVariant(toCVariant(event->mimeData()));
163  if (valueVariant.isValid())
164  {
165  if (valueVariant.canConvert<CLivery>())
166  {
167  const auto livery(valueVariant.value<CLivery>());
168  if (!livery.hasValidDbKey()) { return; }
169  this->setLivery(livery);
170  }
171  else if (valueVariant.canConvert<CLiveryList>())
172  {
173  const auto liveries(valueVariant.value<CLiveryList>());
174  if (liveries.isEmpty()) { return; }
175  this->setLivery(liveries.front());
176  }
177  }
178  }
179 
180  void CDbLiverySelectorComponent::onLiveriesRead(CEntityFlags::Entity entity, CEntityFlags::ReadState readState,
181  int count, const QUrl &url)
182  {
183  Q_UNUSED(url)
184 
185  if (!sGui || sGui->isShuttingDown() || !sGui->hasWebDataServices()) { return; }
186  if (entity.testFlag(CEntityFlags::LiveryEntity) && CEntityFlags::isFinishedReadState(readState))
187  {
188  if (count > 0)
189  {
191  auto *c = new QCompleter(codes, this);
192  c->setCaseSensitivity(Qt::CaseInsensitive);
193  c->setCompletionMode(QCompleter::PopupCompletion);
194  c->setMaxVisibleItems(10);
195  connect(c, qOverload<const QString &>(&QCompleter::activated), this,
196  &CDbLiverySelectorComponent::onCompleterActivated);
197 
198  ui->le_Livery->setCompleter(c);
199  m_completerLiveries.reset(c); // deletes any old completer
200  }
201  else { m_completerLiveries.reset(nullptr); }
202  }
203  }
204 
205  void CDbLiverySelectorComponent::onDataChanged()
206  {
207  if (!sGui || sGui->isShuttingDown() || !sGui->hasWebDataServices()) { return; }
208  const QString raw = ui->le_Livery->text();
209  this->setLivery(raw);
210  }
211 
212  void CDbLiverySelectorComponent::onCompleterActivated(const QString &liveryCode) { this->setLivery(liveryCode); }
213 
214  QString CDbLiverySelectorComponent::stripExtraInfo(const QString &liveryCode) const
215  {
216  if (liveryCode.isEmpty()) { return {}; }
217  const QString l(liveryCode.trimmed().toUpper());
218  int is = l.indexOf(' ');
219  int ib = l.indexOf('(');
220  int i = qMin(is, ib);
221  if (i < 0) { return l; }
222  return l.left(i);
223  }
224 } // namespace swift::gui::components
bool hasWebDataServices() const
Web data services available?
bool isShuttingDown() const
Is application shutting down?
CWebDataServices * getWebDataServices() const
Get the web data services.
swift::misc::aviation::CLiveryList getLiveries() const
Liveries.
swift::misc::aviation::CLivery getLiveryForDbKey(int id) const
Livery for id.
int getLiveriesCount() const
Liveries count.
bool acceptDrop(const QMimeData *mime) const
Accept drop?
Definition: dropbase.cpp:20
swift::misc::CVariant toCVariant(const QMimeData *mime) const
Mime data to CVariant (normally encapsulating a value object)
Definition: dropbase.cpp:39
void setAcceptedMetaTypeIds(const QList< int > &ids)
Accepted ids.
Definition: dropbase.cpp:16
void setLivery(const swift::misc::aviation::CLivery &livery)
Current livery.
swift::misc::aviation::CLivery getLivery() const
Livery.
void withLiveryDescription(bool description)
Show description.
void changedLivery(const swift::misc::aviation::CLivery &livery)
Distributor was changed.
Wrapper around QVariant which provides transparent access to CValueObject methods of the contained ob...
Definition: variant.h:66
T value() const
Return the value converted to the type T.
Definition: variant.h:166
bool isValid() const
True if this variant is valid.
Definition: variant.h:249
bool canConvert(int typeId) const
True if this variant can be converted to the type with the given metatype ID.
Value object encapsulating information about an airpot.
Definition: livery.h:29
bool matchesCombinedCode(const QString &candidate) const
Matches combined code.
Definition: livery.cpp:99
bool hasCompleteData() const
Complete data?
Definition: livery.cpp:124
QString getCombinedCodePlusId() const
Combined code plus id.
Definition: livery.cpp:64
bool hasCombinedCode() const
Livery combined code available?
Definition: livery.cpp:159
Value object for a list of airports.
Definition: liverylist.h:29
QStringList getCombinedCodesPlusInfoAndId(bool sort=false) const
All combined codes plus more info.
Definition: liverylist.cpp:127
CLivery findByCombinedCode(const QString &combinedCode) const
Find livery by combined code.
Definition: liverylist.cpp:104
bool hasValidDbKey() const
Has valid DB key.
Definition: datastore.h:102
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
GUI related classes.
Free functions in swift::misc.
SWIFT_MISC_EXPORT QString stripDesignatorFromCompleterString(const QString &candidate)
Strip a designator from a combined string.
void activated(const QModelIndex &index)
virtual bool event(QEvent *e) override
void editingFinished()
void returnPressed()
QMetaObject::Connection connect(const QObject *sender, PointerToMemberFunction signal, Functor functor)
void reset(T *other)
bool isEmpty() const const
QString toUpper() const const
QString trimmed() const const
CaseInsensitive
QueuedConnection
void setAcceptDrops(bool on)
void setBackgroundRole(QPalette::ColorRole role)