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  {
60  // void
61  }
62 
64  {
65  if (!livery.hasCombinedCode())
66  {
67  ui->le_Livery->clear();
68  return;
69  }
70 
71  if (livery != m_currentLivery)
72  {
73  ui->le_Livery->setText(livery.getCombinedCodePlusId());
74  m_currentLivery = livery;
75  emit changedLivery(livery);
76  }
77  }
78 
79  void CDbLiverySelectorComponent::setLivery(const QString &code)
80  {
81  if (!sGui || sGui->isShuttingDown() || !sGui->hasWebDataServices()) { return; }
82  const int dbKey = CDatastoreUtility::extractIntegerKey(code);
83  CLivery livery;
84 
85  if (dbKey >= 0) { livery = sGui->getWebDataServices()->getLiveryForDbKey(dbKey); }
86 
87  if (!livery.hasValidDbKey())
88  {
89  const QString liveryCode = this->stripExtraInfo(code.toUpper().trimmed());
90  if (m_currentLivery.matchesCombinedCode(liveryCode)) { return; }
91  livery = sGui->getWebDataServices()->getLiveries().findByCombinedCode(liveryCode);
92  }
93 
94  if (livery.hasCompleteData()) { this->setLivery(livery); }
95  else
96  {
97  ui->lbl_Description->setText("");
98  ui->le_Livery->setText(code);
99  }
100  }
101 
103  {
104  if (!sGui || sGui->isShuttingDown()) { return CLivery(); }
105 
106  const QString raw = ui->le_Livery->text();
107  const int dbKey = CDatastoreUtility::extractIntegerKey(raw);
108 
109  CLivery livery;
110  if (dbKey >= 0) { livery = sGui->getWebDataServices()->getLiveryForDbKey(dbKey); }
111  else
112  {
113  const QString liveryCode(this->stripExtraInfo(ui->le_Livery->text()));
114  livery = sGui->getWebDataServices()->getLiveries().findByCombinedCode(liveryCode);
115  }
116 
117  if (livery.hasCompleteData() && livery.hasValidDbKey())
118  {
119  // full data fetched
120  return livery;
121  }
122 
123  return m_currentLivery;
124  }
125 
127  {
128  const QString cc(ui->le_Livery->text().trimmed().toUpper());
130  }
131 
132  void CDbLiverySelectorComponent::setReadOnly(bool readOnly) { ui->le_Livery->setReadOnly(readOnly); }
133 
135  {
136  ui->lbl_Description->setVisible(description);
137  }
138 
140 
141  void CDbLiverySelectorComponent::clear() { ui->le_Livery->clear(); }
142 
143  void CDbLiverySelectorComponent::dragEnterEvent(QDragEnterEvent *event)
144  {
145  if (!event || !acceptDrop(event->mimeData())) { return; }
146  this->setBackgroundRole(QPalette::Highlight);
147  event->acceptProposedAction();
148  }
149 
150  void CDbLiverySelectorComponent::dragMoveEvent(QDragMoveEvent *event)
151  {
152  if (!event || !acceptDrop(event->mimeData())) { return; }
153  event->acceptProposedAction();
154  }
155 
156  void CDbLiverySelectorComponent::dragLeaveEvent(QDragLeaveEvent *event)
157  {
158  if (!event) { return; }
159  event->accept();
160  }
161 
163  {
164  if (!event || !acceptDrop(event->mimeData())) { return; }
165  const CVariant valueVariant(toCVariant(event->mimeData()));
166  if (valueVariant.isValid())
167  {
168  if (valueVariant.canConvert<CLivery>())
169  {
170  const CLivery livery(valueVariant.value<CLivery>());
171  if (!livery.hasValidDbKey()) { return; }
172  this->setLivery(livery);
173  }
174  else if (valueVariant.canConvert<CLiveryList>())
175  {
176  const CLiveryList liveries(valueVariant.value<CLiveryList>());
177  if (liveries.isEmpty()) { return; }
178  this->setLivery(liveries.front());
179  }
180  }
181  }
182 
183  void CDbLiverySelectorComponent::onLiveriesRead(CEntityFlags::Entity entity, CEntityFlags::ReadState readState,
184  int count, const QUrl &url)
185  {
186  Q_UNUSED(url)
187 
188  if (!sGui || sGui->isShuttingDown() || !sGui->hasWebDataServices()) { return; }
189  if (entity.testFlag(CEntityFlags::LiveryEntity) && CEntityFlags::isFinishedReadState(readState))
190  {
191  if (count > 0)
192  {
193  const QStringList codes(sGui->getWebDataServices()->getLiveries().getCombinedCodesPlusInfoAndId(true));
194  QCompleter *c = new QCompleter(codes, this);
195  c->setCaseSensitivity(Qt::CaseInsensitive);
196  c->setCompletionMode(QCompleter::PopupCompletion);
197  c->setMaxVisibleItems(10);
198  connect(c, qOverload<const QString &>(&QCompleter::activated), this,
199  &CDbLiverySelectorComponent::onCompleterActivated);
200 
201  ui->le_Livery->setCompleter(c);
202  m_completerLiveries.reset(c); // deletes any old completer
203  }
204  else { m_completerLiveries.reset(nullptr); }
205  }
206  }
207 
208  void CDbLiverySelectorComponent::onDataChanged()
209  {
210  if (!sGui || sGui->isShuttingDown() || !sGui->hasWebDataServices()) { return; }
211  const QString raw = ui->le_Livery->text();
212  this->setLivery(raw);
213  }
214 
215  void CDbLiverySelectorComponent::onCompleterActivated(const QString &liveryCode) { this->setLivery(liveryCode); }
216 
217  QString CDbLiverySelectorComponent::stripExtraInfo(const QString &liveryCode) const
218  {
219  if (liveryCode.isEmpty()) { return {}; }
220  const QString l(liveryCode.trimmed().toUpper());
221  int is = l.indexOf(' ');
222  int ib = l.indexOf('(');
223  int i = qMin(is, ib);
224  if (i < 0) { return l; }
225  return l.left(i);
226  }
227 } // 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:24
swift::misc::CVariant toCVariant(const QMimeData *mime) const
Mime data to CVariant (normally encapsulating a value object)
Definition: dropbase.cpp:43
void setAcceptedMetaTypeIds(const QList< int > &ids)
Accepted ids.
Definition: dropbase.cpp:20
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.
reference front()
Access the first element.
Definition: sequence.h:225
bool isEmpty() const
Synonym for empty.
Definition: sequence.h:285
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:169
bool isValid() const
True if this variant is valid.
Definition: variant.h:252
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:101
bool hasCompleteData() const
Complete data?
Definition: livery.cpp:126
QString getCombinedCodePlusId() const
Combined code plus id.
Definition: livery.cpp:66
bool hasCombinedCode() const
Livery combined code available?
Definition: livery.cpp:161
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:129
CLivery findByCombinedCode(const QString &combinedCode) const
Find livery by combined code.
Definition: liverylist.cpp:106
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:13
GUI related classes.
Free functions in swift::misc.
SWIFT_MISC_EXPORT QString stripDesignatorFromCompleterString(const QString &candidate)
Strip a designator from a combined string.