swift
liveryform.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 
4 #include "liveryform.h"
5 
6 #include <QCheckBox>
7 #include <QLineEdit>
8 #include <QMetaType>
9 
10 #include "ui_liveryform.h"
11 
12 #include "core/webdataservices.h"
15 #include "gui/dropsite.h"
17 #include "gui/editors/liveryform.h"
19 #include "gui/guiapplication.h"
20 #include "gui/guiutility.h"
21 #include "gui/labelandicon.h"
23 #include "misc/icons.h"
25 
26 using namespace swift::misc;
27 using namespace swift::misc::aviation;
28 using namespace swift::gui;
29 using namespace swift::gui::components;
30 
31 namespace swift::gui::editors
32 {
33  CLiveryForm::CLiveryForm(QWidget *parent) : CForm(parent), ui(new Ui::CLiveryForm)
34  {
35  ui->setupUi(this);
36  ui->le_Updated->setReadOnly(true);
37  ui->le_Id->setValidator(new QIntValidator(0, 999999, ui->le_Id));
38  ui->lai_Id->set(CIcons::appLiveries16(), "Id:");
39  ui->comp_LiverySelector->withLiveryDescription(false);
40 
41  // Id
42  connect(ui->le_Id, &QLineEdit::returnPressed, this, &CLiveryForm::onIdEntered);
43 
44  // selector
45  connect(ui->comp_LiverySelector, &CDbLiverySelectorComponent::changedLivery, this, &CLiveryForm::setValue,
46  Qt::QueuedConnection);
47 
48  // drag and drop, paste
49  connect(ui->tb_Paste, &QToolButton::clicked, this, &CLiveryForm::pasted);
50  connect(ui->drop_DropData, &CDropSite::droppedValueObject, this, &CLiveryForm::onDroppedLivery);
51  ui->drop_DropData->setInfoText("<drop livery>");
52  ui->drop_DropData->setAcceptedMetaTypeIds({ qMetaTypeId<CLivery>(), qMetaTypeId<CLiveryList>() });
53 
54  // embedded form
55  connect(ui->editor_AirlineIcao, &CAirlineIcaoForm::airlineChangedDigest, this, &CLiveryForm::onAirlineChanged,
56  Qt::QueuedConnection);
57 
58  // Set as temp.livery or search color
59  connect(ui->pb_TempLivery, &QPushButton::pressed, this, &CLiveryForm::setTemporaryLivery);
60  connect(ui->pb_SearchColor, &QPushButton::pressed, this, &CLiveryForm::searchForColor);
61  }
62 
64 
66  {
67  CLivery livery;
68  const QString id = ui->le_Id->text();
69  if (!id.isEmpty() && sGui && !sGui->isShuttingDown() && sGui->hasWebDataServices())
70  {
71  bool ok;
72  const int dbKey = id.toInt(&ok);
73  if (ok) { livery = sGui->getWebDataServices()->getLiveryForDbKey(dbKey); }
74  }
75 
76  // fallback
77  if (!livery.hasValidDbKey()) { livery = ui->comp_LiverySelector->getLivery(); }
78 
79  if (livery.hasCompleteData() && livery.hasValidDbKey())
80  {
81  // already complete data from selector
82  return livery;
83  }
84 
85  CAirlineIcaoCode airline(ui->editor_AirlineIcao->getValue());
86  livery.setAirlineIcaoCode(airline);
87  livery.setDescription(ui->le_Description->text());
88  livery.setMilitary(ui->cb_Military->isChecked());
89  return livery;
90  }
91 
92  CAirlineIcaoCode CLiveryForm::getValueAirlineIcao() const { return ui->editor_AirlineIcao->getValue(); }
93 
94  bool CLiveryForm::setValue(const CLivery &livery)
95  {
96  if (m_originalLivery == livery) { return false; }
97 
98  m_originalLivery = livery;
99  ui->comp_LiverySelector->setLivery(livery);
100  ui->le_Id->setText(livery.getDbKeyAsString());
101  ui->le_Description->setText(livery.getDescription());
102  ui->le_Updated->setText(livery.getFormattedUtcTimestampYmdhms());
103  ui->color_Fuselage->setColor(livery.getColorFuselage());
104  ui->color_Tail->setColor(livery.getColorTail());
105  ui->cb_Military->setChecked(livery.isMilitary());
106 
107  if (livery.isColorLivery()) { ui->editor_AirlineIcao->clear(); }
108  else { ui->editor_AirlineIcao->setValue(livery.getAirlineIcaoCode()); }
109  return true;
110  }
111 
112  void CLiveryForm::jsonPasted(const QString &json)
113  {
114  if (json.isEmpty()) { return; } // avoid unnecessary conversions
115  try
116  {
117  CVariant jsonVariant;
118  jsonVariant.convertFromJson(json::jsonObjectFromString(json));
119  if (!jsonVariant.canConvert<CLiveryList>()) { return; }
120  const CLiveryList liveries = jsonVariant.value<CLiveryList>();
121  if (!liveries.isEmpty()) { this->setValue(liveries.front()); }
122  }
123  catch (const CJsonException &ex)
124  {
125  Q_UNUSED(ex);
126  }
127  }
128 
129  CStatusMessageList CLiveryForm::validate(bool withNestedForms) const
130  {
131  CLivery livery(getValue());
132  CStatusMessageList msgs(livery.validate());
133  if (withNestedForms)
134  {
135  if (!livery.isColorLivery()) { msgs.push_back(ui->editor_AirlineIcao->validate()); }
136  }
137  if (this->isReadOnly())
138  {
139  // in readonly I cannot change the data anyway, so skip warnings
140  msgs.removeWarningsAndBelow();
141  }
142  ui->val_Indicator->setState(msgs);
143  return msgs;
144  }
145 
146  CStatusMessageList CLiveryForm::validateAirlineIcao() const { return ui->editor_AirlineIcao->validate(); }
147 
148  void CLiveryForm::allowDrop(bool allowDrop)
149  {
150  ui->drop_DropData->allowDrop(allowDrop);
151  ui->comp_LiverySelector->allowDrop(allowDrop);
152  ui->editor_AirlineIcao->allowDrop(allowDrop);
153  }
154 
155  bool CLiveryForm::isDropAllowed() const { return ui->drop_DropData->isDropAllowed(); }
156 
157  void CLiveryForm::setReadOnly(bool readOnly)
158  {
159  m_readOnly = readOnly;
160  ui->le_Id->setReadOnly(readOnly);
161  ui->comp_LiverySelector->setReadOnly(readOnly);
162  ui->le_Description->setReadOnly(readOnly);
163  ui->color_Fuselage->setReadOnly(readOnly);
164  ui->color_Tail->setReadOnly(readOnly);
165  ui->editor_AirlineIcao->setReadOnly(readOnly);
166  ui->pb_SearchColor->setVisible(!readOnly);
167  ui->pb_TempLivery->setVisible(!readOnly);
168  ui->drop_DropData->setVisible(!readOnly);
169  ui->tb_Paste->setVisible(!readOnly);
170  CGuiUtility::checkBoxReadOnly(ui->cb_Military, readOnly);
171  this->forceStyleSheetUpdate();
172  }
173 
175  {
176  this->setReadOnly(true);
177  ui->comp_LiverySelector->setReadOnly(false);
178  ui->le_Id->setReadOnly(false);
179  ui->editor_AirlineIcao->setSelectOnly();
180  ui->drop_DropData->setVisible(true);
181  ui->pb_SearchColor->setVisible(true);
182  ui->pb_TempLivery->setVisible(true);
183  ui->tb_Paste->setVisible(true);
184  }
185 
186  void CLiveryForm::clear() { this->setValue(CLivery()); }
187 
188  void CLiveryForm::resetValue() { this->setValue(m_originalLivery); }
189 
190  void CLiveryForm::onDroppedLivery(const swift::misc::CVariant &variantDropped)
191  {
192  CLivery livery;
193  if (variantDropped.canConvert<CLivery>()) { livery = variantDropped.value<CLivery>(); }
194  else if (variantDropped.canConvert<CLiveryList>())
195  {
196  CLiveryList liveryList(variantDropped.value<CLiveryList>());
197  if (liveryList.isEmpty()) { return; }
198  livery = liveryList.front();
199  }
200  else { return; }
201  this->setValue(livery);
202  }
203 
204  void CLiveryForm::onAirlineChanged(const CAirlineIcaoCode &code)
205  {
206  if (!sGui || sGui->isShuttingDown() || !sGui->getWebDataServices()) { return; }
207  if (!code.hasCompleteData()) { return; }
208  if (!code.hasValidDbKey()) { return; }
209 
210  // only replace with STD livery if airline does not match
211  const CLivery currentLivery = this->getValue();
212  if (currentLivery.hasValidDbKey() && currentLivery.getAirlineIcaoCode() == code) { return; }
213 
215  if (stdLivery.hasValidDbKey()) { this->setValue(stdLivery); }
216  }
217 
218  void CLiveryForm::setTemporaryLivery()
219  {
220  if (!sGui || !sGui->hasWebDataServices()) { return; }
222  if (l.isLoadedFromDb()) { this->setValue(l); }
223  }
224 
225  void CLiveryForm::searchForColor()
226  {
227  if (!m_colorSearch)
228  {
229  m_colorSearch = new CDbLiveryColorSearchDialog(this);
230  m_colorSearch->setModal(true);
231  }
232  const QDialog::DialogCode c = static_cast<QDialog::DialogCode>(m_colorSearch->exec());
233  if (c == QDialog::Rejected) { return; }
234  const CLivery found = m_colorSearch->getLivery();
235  if (found.isLoadedFromDb()) { this->setValue(found); }
236  }
237 
238  void CLiveryForm::onIdEntered()
239  {
240  if (!sGui || !sGui->hasWebDataServices())
241  {
242  ui->le_Id->undo();
243  return;
244  }
245 
246  const int id = ui->le_Id->text().toInt();
247  const CLivery livery = sGui->getWebDataServices()->getLiveryForDbKey(id);
248  if (!livery.isLoadedFromDb())
249  {
250  ui->le_Id->undo();
251  return;
252  }
253  this->setValue(livery);
254  }
255 } // namespace swift::gui::editors
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::CLivery getTempLiveryOrDefault() const
The temp. livery if available.
swift::misc::aviation::CLiveryList getLiveries() const
Liveries.
swift::misc::aviation::CLivery getLiveryForDbKey(int id) const
Livery for id.
void droppedValueObject(const swift::misc::CVariant &droppedObject)
Dropped value object.
static void checkBoxReadOnly(QCheckBox *checkBox, bool readOnly)
Pseudo readonly state for checkbox.
Definition: guiutility.cpp:450
const swift::misc::aviation::CLivery & getLivery() const
Found livery if any, otherwise default.
void airlineChangedDigest(const swift::misc::aviation::CAirlineIcaoCode &airlineIcao)
Airline has been changed.
Form base class.
Definition: form.h:27
void forceStyleSheetUpdate()
Forces a stylesheet update.
Definition: form.cpp:47
void pasted()
Pasted from clipboard.
Definition: form.cpp:39
bool m_readOnly
read only
Definition: form.h:67
bool isReadOnly() const
Is read only?
Definition: form.h:54
swift::misc::aviation::CLivery getValue() const
Value.
Definition: liveryform.cpp:65
bool isDropAllowed() const
Is drop allowed?
Definition: liveryform.cpp:155
void resetValue()
Reset value to current value.
Definition: liveryform.cpp:188
swift::misc::aviation::CAirlineIcaoCode getValueAirlineIcao() const
Embedded ariline.
Definition: liveryform.cpp:92
swift::misc::CStatusMessageList validateAirlineIcao() const
Validate airline ICAO code only.
Definition: liveryform.cpp:146
virtual void setReadOnly(bool readonly)
Set editable.
Definition: liveryform.cpp:157
virtual ~CLiveryForm()
Destructor.
Definition: liveryform.cpp:63
void allowDrop(bool allowDrop)
Allow to drop.
Definition: liveryform.cpp:148
virtual void setSelectOnly()
Read only, but entity can be selected (normally used in mapping). Use setReadOnly to reset this very ...
Definition: liveryform.cpp:174
virtual void jsonPasted(const QString &json)
JSON string has been pasted.
Definition: liveryform.cpp:112
virtual swift::misc::CStatusMessageList validate(bool withNestedForms) const
Validate, empty list means OK.
Definition: liveryform.cpp:129
bool setValue(const swift::misc::aviation::CLivery &livery)
Value.
Definition: liveryform.cpp:94
Thrown when a convertFromJson method encounters an unrecoverable error in JSON data.
Definition: jsonexception.h:24
void push_back(const T &value)
Appends an element at the end of the sequence.
Definition: sequence.h:305
reference front()
Access the first element.
Definition: sequence.h:225
bool isEmpty() const
Synonym for empty.
Definition: sequence.h:285
Status messages, e.g. from Core -> GUI.
void removeWarningsAndBelow()
Remove warnings and below.
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
void convertFromJson(const QJsonObject &json)
Assign from JSON object.
bool canConvert(int typeId) const
True if this variant can be converted to the type with the given metatype ID.
QString getFormattedUtcTimestampYmdhms() const
As yyyy MM dd HH mm ss.
Value object for ICAO classification.
bool hasCompleteData() const
Complete data.
Value object encapsulating information about an airpot.
Definition: livery.h:29
bool isMilitary() const
Military livery.
Definition: livery.h:98
const CRgbColor & getColorTail() const
Get tail color.
Definition: livery.h:95
bool setAirlineIcaoCode(const CAirlineIcaoCode &airlineIcao)
Airline ICAO code.
Definition: livery.cpp:81
CStatusMessageList validate() const
Validate data.
Definition: livery.cpp:128
const CAirlineIcaoCode & getAirlineIcaoCode() const
Corresponding airline, if any.
Definition: livery.h:65
void setMilitary(bool isMilitary)
Military aircraft?
Definition: livery.h:128
bool hasCompleteData() const
Complete data?
Definition: livery.cpp:126
const QString & getDescription() const
Get description.
Definition: livery.h:83
bool isColorLivery() const
Color livery?
Definition: livery.cpp:180
void setDescription(const QString &description)
Set description.
Definition: livery.h:125
const CRgbColor & getColorFuselage() const
Get fuselage color.
Definition: livery.h:92
Value object for a list of airports.
Definition: liverylist.h:29
CLivery findStdLiveryByAirlineIcaoVDesignator(const QString &icao) const
Find livery by airline.
Definition: liverylist.cpp:49
QString getDbKeyAsString() const
DB key as string.
Definition: datastore.cpp:30
bool isLoadedFromDb() const
Loaded from DB.
Definition: datastore.cpp:49
bool hasValidDbKey() const
Has valid DB key.
Definition: datastore.h:102
QJsonObject jsonObjectFromString(const QString &json, bool acceptCacheFormat)
JSON Object from string.
Definition: json.cpp:413
SWIFT_GUI_EXPORT swift::gui::CGuiApplication * sGui
Single instance of GUI application object.
High level reusable GUI components.
Definition: aboutdialog.cpp:13
GUI related classes.
Free functions in swift::misc.