swift
dbstashcomponent.cpp
1 // SPDX-FileCopyrightText: Copyright (C) 2013 swift Project Community / Contributors
2 // SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-swift-pilot-client-1
3 
5 
6 #include <iterator>
7 
8 #include <QCheckBox>
9 #include <QMessageBox>
10 #include <QPushButton>
11 #include <QStringBuilder>
12 #include <QWidget>
13 #include <Qt>
14 #include <QtGlobal>
15 
16 #include "ui_dbstashcomponent.h"
17 
18 #include "core/application.h"
19 #include "core/db/databaseutils.h"
20 #include "core/db/databasewriter.h"
21 #include "core/webdataservices.h"
23 #include "gui/guiapplication.h"
26 #include "gui/views/viewbase.h"
28 #include "misc/aviation/livery.h"
29 #include "misc/logcategories.h"
30 #include "misc/sequence.h"
33 #include "misc/verify.h"
34 
35 using namespace swift::core;
36 using namespace swift::core::db;
37 using namespace swift::misc;
38 using namespace swift::misc::simulation;
39 using namespace swift::misc::aviation;
40 using namespace swift::misc::network;
41 using namespace swift::gui;
42 using namespace swift::gui::models;
43 using namespace swift::gui::views;
44 
45 namespace swift::gui::components
46 {
47  CDbStashComponent::CDbStashComponent(QWidget *parent)
48  : QFrame(parent), CDbMappingComponentAware(parent), ui(new Ui::CDbStashComponent)
49  {
50  ui->setupUi(this);
51 
52  connect(ui->pb_Unstash, &QPushButton::pressed, this, &CDbStashComponent::onUnstashPressed);
53  connect(ui->pb_Validate, &QPushButton::pressed, this, &CDbStashComponent::onValidatePressed);
54  connect(ui->pb_RemoveInvalid, &QPushButton::pressed, this, &CDbStashComponent::onRemoveInvalidPressed);
55  connect(ui->pb_Publish, &QPushButton::pressed, this, &CDbStashComponent::onPublishPressed);
56  connect(ui->tvp_StashAircraftModels, &CAircraftModelView::modelChanged, this,
58  connect(ui->tvp_StashAircraftModels, &CAircraftModelView::modelDataChanged, this,
59  &CDbStashComponent::onRowCountChanged);
60 
61  // copy over buttons
62  connect(ui->pb_AircraftIcao, &QPushButton::pressed, this, &CDbStashComponent::copyOverValuesToSelectedModels);
63  connect(ui->pb_AirlineIcao, &QPushButton::pressed, this, &CDbStashComponent::copyOverValuesToSelectedModels);
64  connect(ui->pb_Livery, &QPushButton::pressed, this, &CDbStashComponent::copyOverValuesToSelectedModels);
65  connect(ui->pb_Distributor, &QPushButton::pressed, this, &CDbStashComponent::copyOverValuesToSelectedModels);
66  connect(ui->pb_Model, &QPushButton::pressed, this, &CDbStashComponent::modifyModelDialog);
67 
68  ui->tvp_StashAircraftModels->setAircraftModelMode(CAircraftModelListModel::StashModel);
69  ui->tvp_StashAircraftModels->allowDragDrop(false, true, true);
70  ui->tvp_StashAircraftModels->setAcceptedMetaTypeIds();
71  ui->tvp_StashAircraftModels->menuAddItems(CAircraftModelView::MenuLoadAndSave);
72  ui->tvp_StashAircraftModels->menuAddItems(CAircraftModelView::MenuRemoveSelectedRows);
73  ui->tvp_StashAircraftModels->setHighlight(true);
74  ui->tvp_StashAircraftModels->setHighlightColor(Qt::red);
75  ui->tvp_StashAircraftModels->setSettingsDirectoryIndex(CDirectories::IndexDirLastModelStashJsonOrDefault);
76  this->enableButtonRow();
77 
78  connect(sApp->getWebDataServices()->getDatabaseWriter(), &CDatabaseWriter::publishedModels, this,
79  &CDbStashComponent::onPublishedModelsResponse, Qt::QueuedConnection);
80  this->onUserChanged();
81  }
82 
84 
86  {
87  if (!allowReplace && ui->tvp_StashAircraftModels->container().containsModelStringOrDbKey(model))
88  {
89  const QString msg("Model '%1' already stashed");
90  return { validationCategories(), CStatusMessage::SeverityError, msg.arg(model.getModelString()) };
91  }
92  return {};
93  }
94 
95  CStatusMessage CDbStashComponent::stashModel(const CAircraftModel &model, bool replace, bool consolidateWithDbData,
96  bool clearHighlighting)
97  {
98  const CAircraftModel stashModel(consolidateWithDbData ? this->consolidateModel(model) : model);
99  const CStatusMessage m(this->validateStashModel(stashModel, replace));
100  if (!m.isWarningOrAbove())
101  {
102  if (clearHighlighting) { this->clearValidationHighlighting(); }
103  if (replace)
104  {
105  ui->tvp_StashAircraftModels->replaceOrAdd(&CAircraftModel::getModelString, stashModel.getModelString(),
106  stashModel);
107  }
108  else { ui->tvp_StashAircraftModels->insert(stashModel); }
109  }
110  return m;
111  }
112 
114  bool consolidateWithDbData, bool clearHighlighting)
115  {
116  if (models.isEmpty()) { return {}; }
117  CStatusMessageList msgs;
118  int successfullyAdded = 0;
119  for (const CAircraftModel &model : models)
120  {
121  const CStatusMessage m(this->stashModel(model, replace, consolidateWithDbData, false));
122  if (m.isWarningOrAbove()) { msgs.push_back(m); }
123  else { successfullyAdded++; }
124  }
125  if (successfullyAdded > 0 && clearHighlighting) { this->clearValidationHighlighting(); }
126  return msgs;
127  }
128 
130  {
131  ui->tvp_StashAircraftModels->updateContainerMaybeAsync(models);
132  }
133 
135  {
136  if (keys.isEmpty()) { return 0; }
137  return ui->tvp_StashAircraftModels->removeDbKeys(keys);
138  }
139 
141  {
142  if (modelStrings.isEmpty()) { return 0; }
143  return ui->tvp_StashAircraftModels->removeModelsWithModelString(modelStrings);
144  }
145 
147  {
148  if (models.isEmpty()) { return 0; }
149  return ui->tvp_StashAircraftModels->removeModelsWithModelString(models);
150  }
151 
152  CAircraftModelView *CDbStashComponent::view() const { return ui->tvp_StashAircraftModels; }
153 
154  bool CDbStashComponent::hasStashedModels() const { return !ui->tvp_StashAircraftModels->isEmpty(); }
155 
156  int CDbStashComponent::getStashedModelsCount() const { return ui->tvp_StashAircraftModels->rowCount(); }
157 
159  {
160  return ui->tvp_StashAircraftModels->derivedModel()->getModelStrings(false);
161  }
162 
164  {
165  return ui->tvp_StashAircraftModels->derivedModel()->container();
166  }
167 
169  {
170  if (modelString.isEmpty() || ui->tvp_StashAircraftModels->isEmpty()) { return {}; }
171  return ui->tvp_StashAircraftModels->container().findFirstByModelStringOrDefault(modelString);
172  }
173 
174  void CDbStashComponent::applyToSelected(const CLivery &livery, bool acceptWarnings)
175  {
176  if (!ui->tvp_StashAircraftModels->hasSelection()) { return; }
177  CStatusMessageList msgs(livery.validate());
178  if (this->showOverlayMessages(msgs, acceptWarnings)) { return; }
179  ui->tvp_StashAircraftModels->applyToSelected(livery);
180  }
181 
182  void CDbStashComponent::applyToSelected(const CAircraftIcaoCode &icao, bool acceptWarnings)
183  {
184  if (!ui->tvp_StashAircraftModels->hasSelection()) { return; }
185  CStatusMessageList msgs(icao.validate());
186  if (this->showOverlayMessages(msgs, acceptWarnings)) { return; }
187  ui->tvp_StashAircraftModels->applyToSelected(icao);
188  }
189 
190  void CDbStashComponent::applyToSelected(const CAirlineIcaoCode &icao, bool acceptWarnings)
191  {
192  if (!icao.hasValidDesignator())
193  {
194  static const CStatusMessage msg(CStatusMessage::SeverityError, u"No valid designator");
195  this->showOverlayMessage(msg);
196  return;
197  }
198 
199  // retrieve the std livery
200  const CLivery stdLivery(sApp->getWebDataServices()->getStdLiveryForAirlineCode(icao));
201  if (!stdLivery.hasValidDbKey())
202  {
203  static const CStatusMessage msg(CStatusMessage::SeverityError,
204  u"No valid standard livery for " % icao.getDesignator());
205  this->showOverlayMessage(msg);
206  return;
207  }
208 
209  applyToSelected(stdLivery, acceptWarnings);
210  }
211 
212  void CDbStashComponent::applyToSelected(const CDistributor &distributor, bool acceptWarnings)
213  {
214  if (!ui->tvp_StashAircraftModels->hasSelection()) { return; }
215  CStatusMessageList msgs(distributor.validate());
216  if (this->showOverlayMessages(msgs, acceptWarnings)) { return; }
217  ui->tvp_StashAircraftModels->applyToSelected(distributor);
218  }
219 
221  {
222  if (vm.isEmpty()) { return; }
223  if (!ui->tvp_StashAircraftModels->hasSelection()) { return; }
224  ui->tvp_StashAircraftModels->applyToSelected(vm);
225  }
226 
227  void CDbStashComponent::onUnstashPressed() { ui->tvp_StashAircraftModels->removeSelectedRows(); }
228 
229  void CDbStashComponent::onValidatePressed()
230  {
231  if (ui->tvp_StashAircraftModels->isEmpty()) { return; }
232  CAircraftModelList validModels;
233  CAircraftModelList invalidModels;
234  this->validateAndDisplay(validModels, invalidModels, true);
235  }
236 
237  void CDbStashComponent::onRemoveInvalidPressed()
238  {
239  if (ui->tvp_StashAircraftModels->isEmpty()) { return; }
240  CAircraftModelList validModels;
241  CAircraftModelList invalidModels;
242  this->validate(validModels, invalidModels);
243  this->unstashModels(invalidModels);
244  }
245 
246  void CDbStashComponent::onPublishPressed()
247  {
248  if (!sGui || sGui->isShuttingDown() || !sGui->hasWebDataServices()) { return; }
249  if (ui->tvp_StashAircraftModels->isEmpty()) { return; }
250  if (!sGui->hasMinimumMappingVersion()) { return; }
251 
252  // get models right here, because later steps might affect selection
253  const CAircraftModelList models(getSelectedOrAllModels());
254  if (models.isEmpty()) { return; }
255 
256  // validate
257  CAircraftModelList validModels;
258  CAircraftModelList invalidModels;
259  if (!this->validateAndDisplay(validModels, invalidModels)) { return; }
260  CStatusMessageList msgs;
261  if (validModels.size() > MaxModelPublished)
262  {
263  validModels.truncate(MaxModelPublished);
264  msgs.push_back(CStatusMessage(validationCategories(), CStatusMessage::SeverityWarning,
265  u"More than %1 values, values skipped")
266  << MaxModelPublished);
267  }
268 
269  msgs.push_back(sGui->getWebDataServices()->asyncPublishModels(validModels));
270  if (msgs.hasWarningOrErrorMessages()) { this->showOverlayMessages(msgs); }
271  else { ui->tvp_StashAircraftModels->showLoadIndicator(); }
272  }
273 
274  void CDbStashComponent::onPublishedModelsResponse(const CAircraftModelList &publishedModels,
275  const CAircraftModelList &skippedModels,
276  const CStatusMessageList &msgs, bool sendingSuccesful,
277  bool directWrite)
278  {
279  Q_UNUSED(skippedModels);
280  ui->tvp_StashAircraftModels->hideLoadIndicator();
281  if (!publishedModels.isEmpty() && sendingSuccesful)
282  {
283  emit this->modelsSuccessfullyPublished(publishedModels, directWrite);
284  }
285 
286  if (!msgs.isEmpty())
287  {
288  if (publishedModels.isEmpty()) { this->showOverlayMessages(msgs, false, false); }
289  else
290  {
291  QPointer<CDbStashComponent> myself(this);
292  const QString confirm("Remove %1 published models from stash?");
293  auto lambda = [=]() {
294  if (!myself) { return; }
295  myself->unstashModels(publishedModels.getModelStringList(false));
296  };
297  this->showOverlayMessagesWithConfirmation(msgs, false, confirm.arg(publishedModels.size()), lambda,
299  }
300  }
301  }
302 
303  CStatusMessageList CDbStashComponent::validate(CAircraftModelList &validModels,
304  CAircraftModelList &invalidModels) const
305  {
306  if (ui->tvp_StashAircraftModels->isEmpty()) { return {}; }
307  Q_ASSERT_X(sGui->getWebDataServices(), Q_FUNC_INFO, "No web services");
308  const CAircraftModelList models(getSelectedOrAllModels());
309  if (models.isEmpty()) { return {}; }
310  const bool ignoreEqual = ui->cb_ChangedOnly->isChecked();
311  const CStatusMessageList msgs(
312  sGui->getWebDataServices()->validateForPublishing(models, ignoreEqual, validModels, invalidModels));
313 
314  // OK?
315  if (msgs.isEmpty())
316  {
317  return CStatusMessageList(
318  { CStatusMessage(validationCategories(), CStatusMessage::SeverityInfo, u"No errors in %1 model(s)")
319  << models.size() });
320  }
321  else { return msgs; }
322  }
323 
324  bool CDbStashComponent::validateAndDisplay(CAircraftModelList &validModels, CAircraftModelList &invalidModels,
325  bool displayInfo)
326  {
327  const CStatusMessageList msgs(this->validate(validModels, invalidModels));
328  if (msgs.hasWarningOrErrorMessages())
329  {
330  this->showOverlayMessages(msgs);
331  ui->tvp_StashAircraftModels->setHighlightModelStrings(invalidModels.getModelStringList(false));
332  }
333  else
334  {
335  // delete highlighting because no errors
336  ui->tvp_StashAircraftModels->clearHighlighting();
337  if (displayInfo)
338  {
339  const QString no = QString::number(this->getStashedModelsCount());
340  const CStatusMessage msg(validationCategories(), CStatusMessage::SeverityInfo,
341  "Validation passed for " + no + " models");
342  this->showOverlayMessage(msg);
343  }
344  }
345  return !validModels.isEmpty(); // at least some valid objects
346  }
347 
348  void CDbStashComponent::enableButtonRow()
349  {
350  const bool e = !ui->tvp_StashAircraftModels->isEmpty();
351  ui->pb_AircraftIcao->setEnabled(e);
352  ui->pb_AirlineIcao->setEnabled(e);
353  ui->pb_Distributor->setEnabled(e);
354  ui->pb_Livery->setEnabled(e);
355  ui->pb_Unstash->setEnabled(e);
356  ui->pb_Validate->setEnabled(e);
357  ui->pb_RemoveInvalid->setEnabled(e);
358  ui->pb_Model->setEnabled(e);
359  ui->pb_Publish->setEnabled(e);
360  this->onUserChanged();
361  }
362 
363  const CLogCategoryList &CDbStashComponent::validationCategories() const
364  {
365  static const CLogCategoryList cats(CLogCategoryList(this).withValidation());
366  return cats;
367  }
368 
369  CAircraftModelList CDbStashComponent::getSelectedOrAllModels() const
370  {
371  const bool selectedOnly = ui->cb_SelectedOnly->isChecked();
372  const CAircraftModelList models(selectedOnly ? ui->tvp_StashAircraftModels->selectedObjects() :
373  ui->tvp_StashAircraftModels->containerOrFilteredContainer());
374  return models;
375  }
376 
377  CAircraftModel CDbStashComponent::consolidateWithDbData(const CAircraftModel &model, bool forced) const
378  {
379  const CAircraftModel consolidatedModel = CDatabaseUtils::consolidateModelWithDbData(model, forced);
380  return consolidatedModel;
381  }
382 
383  CAircraftModel CDbStashComponent::consolidateWithOwnModels(const CAircraftModel &model) const
384  {
385  if (!model.hasModelString()) { return model; }
386  if (model.getModelType() == CAircraftModel::TypeOwnSimulatorModel) { return model; }
387  CAircraftModel ownModel(this->getMappingComponent()->getOwnModelForModelString(model.getModelString()));
388  if (!ownModel.hasModelString()) { return model; }
389  ownModel.updateMissingParts(model);
390  return ownModel;
391  }
392 
393  CAuthenticatedUser CDbStashComponent::getSwiftDbUser() const { return m_swiftDbUser.get(); }
394 
396  {
397  CAircraftModel stashModel(model);
398  const bool ownModel = stashModel.getModelType() == CAircraftModel::TypeOwnSimulatorModel;
399 
400  // merge/update with DB data if any
401  // this is a forced update with DB data, as DB data can change
402  stashModel = this->consolidateWithDbData(stashModel, true);
403 
404  // merge with own models if any
405  if (!ownModel) { stashModel = this->consolidateWithOwnModels(stashModel); }
406 
407  return stashModel;
408  }
409 
411  {
412  if (!sGui || !sGui->hasWebDataServices()) { return; }
413  if (sGui->isShuttingDown()) { return; }
414  const CAircraftModelList models = ui->tvp_StashAircraftModels->selectedObjects();
415  if (models.isEmpty()) { return; }
416 
417  CStatusMessageList msgs;
418  for (const CAircraftModel &model : models)
419  {
420  CStatusMessageList modelMsgs;
421  const bool equal = sGui->getWebDataServices()->isDbModelEqualForPublishing(model, &modelMsgs);
422  if (equal)
423  {
424  msgs.push_back(CStatusMessage(this).info(u"Model '%1' has no change values")
425  << model.getModelStringAndDbKey());
426  }
427  else { msgs.push_back(modelMsgs); }
428  }
429  this->showOverlayMessages(msgs);
430  }
431 
432  void CDbStashComponent::clearValidationHighlighting() { ui->tvp_StashAircraftModels->clearHighlighting(); }
433 
434  void CDbStashComponent::copyOverValuesToSelectedModels()
435  {
436  const QObject *sender = QObject::sender();
437  SWIFT_VERIFY_X(this->getMappingComponent(), Q_FUNC_INFO, "Missing mapping component");
438  if (!this->getMappingComponent()) { return; }
439  if (!ui->tvp_StashAircraftModels->hasSelection()) { return; }
440 
441  const CAircraftModel model(this->getMappingComponent()->getEditorAircraftModel());
442  if (sender == ui->pb_AircraftIcao) { this->applyToSelected(model.getAircraftIcaoCode()); }
443  else if (sender == ui->pb_AirlineIcao) { this->applyToSelected(model.getAirlineIcaoCode()); }
444  else if (sender == ui->pb_Distributor) { this->applyToSelected(model.getDistributor()); }
445  else if (sender == ui->pb_Livery) { this->applyToSelected(model.getLivery()); }
446  }
447 
448  void CDbStashComponent::modifyModelDialog()
449  {
450  if (this->getMappingComponent()) { this->getMappingComponent()->modifyModelDialog(); }
451  }
452 
453  void CDbStashComponent::onRowCountChanged(int number, bool filter)
454  {
455  Q_UNUSED(number);
456  Q_UNUSED(filter);
457  this->enableButtonRow();
458  }
459 
460  void CDbStashComponent::onUserChanged()
461  {
462  const CAuthenticatedUser user(this->getSwiftDbUser());
463  if (!user.isAuthenticated())
464  {
465  ui->pb_Publish->setText(" Publish (login) ");
466  ui->pb_Publish->setToolTip("Login first");
467  ui->pb_Publish->setEnabled(false);
468  }
469  else if (user.canDirectlyWriteModels())
470  {
471  ui->pb_Publish->setText(" Publish (dir.) ");
472  ui->pb_Publish->setToolTip("Models directly released");
473  ui->pb_Publish->setEnabled(true);
474  }
475  else
476  {
477  ui->pb_Publish->setText(" Publish (CR) ");
478  ui->pb_Publish->setToolTip("Models published as change request");
479  ui->pb_Publish->setEnabled(true);
480  }
481  }
482 
483  bool CDbStashComponent::showOverlayMessages(const CStatusMessageList &msgs, bool onlyErrors, bool appendOldMessages,
484  std::chrono::milliseconds timeout)
485  {
486  if (msgs.isEmpty()) { return false; }
487  if (!msgs.hasErrorMessages() && onlyErrors) { return false; }
488  SWIFT_VERIFY_X(this->getMappingComponent(), Q_FUNC_INFO, "missing mapping component");
489  if (!this->getMappingComponent()) { return false; }
490 
491  this->getMappingComponent()->showOverlayMessages(msgs, appendOldMessages, timeout);
492  return true;
493  }
494 
495  bool CDbStashComponent::showOverlayMessagesWithConfirmation(const CStatusMessageList &msgs, bool appendOldMessages,
496  const QString &confirmation,
497  std::function<void()> okLambda,
498  QMessageBox::StandardButton defaultButton,
499  bool onlyErrors, std::chrono::milliseconds timeout)
500  {
501  if (msgs.isEmpty()) { return false; }
502  if (!msgs.hasErrorMessages() && onlyErrors) { return false; }
503  SWIFT_VERIFY_X(this->getMappingComponent(), Q_FUNC_INFO, "missing mapping component");
504  if (!this->getMappingComponent()) { return false; }
505  this->getMappingComponent()->showOverlayMessagesWithConfirmation(msgs, appendOldMessages, confirmation,
506  okLambda, defaultButton, timeout);
507  return true;
508  }
509 
510  bool CDbStashComponent::showOverlayMessage(const CStatusMessage &msg, std::chrono::milliseconds timeout)
511  {
512  if (msg.isEmpty()) { return false; }
513  SWIFT_VERIFY_X(this->getMappingComponent(), Q_FUNC_INFO, "missing mapping component");
514  if (!this->getMappingComponent()) { return false; }
515  this->getMappingComponent()->showOverlayMessage(msg, timeout);
516  return true;
517  }
518 
519  void CDbStashComponent::clearOverlayMessages()
520  {
521  SWIFT_VERIFY_X(this->getMappingComponent(), Q_FUNC_INFO, "missing mapping component");
522  if (!this->getMappingComponent()) { return; }
524  }
525 } // namespace swift::gui::components
SWIFT_CORE_EXPORT swift::core::CApplication * sApp
Single instance of application object.
Definition: application.cpp:71
bool hasWebDataServices() const
Web data services available?
bool isShuttingDown() const
Is application shutting down?
CWebDataServices * getWebDataServices() const
Get the web data services.
swift::misc::CStatusMessageList asyncPublishModels(const swift::misc::simulation::CAircraftModelList &modelsToBePublished) const
Publish models to database.
db::CDatabaseWriter * getDatabaseWriter() const
DB writer class.
swift::misc::aviation::CLivery getStdLiveryForAirlineCode(const swift::misc::aviation::CAirlineIcaoCode &icao) const
Standard livery for airline code.
bool isDbModelEqualForPublishing(const swift::misc::simulation::CAircraftModel &modelToBeChecked, swift::misc::CStatusMessageList *details=nullptr) const
Considered equal for publishing, compares if livery etc. are the same DB values.
swift::misc::CStatusMessageList validateForPublishing(const swift::misc::simulation::CAircraftModelList &modelsToBePublished, bool ignoreEqual, swift::misc::simulation::CAircraftModelList &validModels, swift::misc::simulation::CAircraftModelList &invalidModels) const
Validate for publishing.
bool hasMinimumMappingVersion() const
Minimum mapping version check.
void clearOverlayMessages()
Clear the overlay messages.
bool showOverlayMessage(const swift::misc::CStatusMessage &message, std::chrono::milliseconds timeout=std::chrono::milliseconds(0))
Show single message.
void showOverlayMessages(const swift::misc::CStatusMessageList &messages, bool appendOldMessages=false, std::chrono::milliseconds timeout=std::chrono::milliseconds(0))
Show multiple messages.
void showOverlayMessagesWithConfirmation(const swift::misc::CStatusMessageList &messages, bool appendOldMessages, const QString &confirmationMessage, std::function< void()> okLambda, QMessageBox::StandardButton defaultButton=QMessageBox::Cancel, std::chrono::milliseconds timeout=std::chrono::milliseconds(0))
Show multiple messages with confirmation bar.
Allows subcomponents to gain access to model component.
CDbMappingComponent * getMappingComponent() const
Get the mapping component.
void modifyModelDialog()
Open model modify dialog.
static constexpr int MaxModelPublished
Number of models which can be published at once.
void stashedModelsChanged()
Stashed models have been changed.
void showChangedAttributes()
Show changed attributes of selected models.
int unstashModels(const QSet< int > &keys)
Unstash given models with keys.
int getStashedModelsCount() const
Number of models.
swift::misc::simulation::CAircraftModel getStashedModel(const QString &modelString) const
Model for model string.
swift::gui::views::CAircraftModelView * view() const
The embedded view.
void applyToSelected(const swift::misc::aviation::CLivery &livery, bool acceptWarnings=true)
Apply livery to selected objects.
bool hasStashedModels() const
Has stashed models.
swift::misc::CStatusMessage stashModel(const swift::misc::simulation::CAircraftModel &model, bool replace=false, bool consolidateWithDbData=true, bool clearHighlighting=true)
Stash given model (includes validation and consolidation with DB data)
swift::misc::CStatusMessage validateStashModel(const swift::misc::simulation::CAircraftModel &model, bool allowReplace) const
Test the given model if it can be stashed.
swift::misc::simulation::CAircraftModel consolidateModel(const swift::misc::simulation::CAircraftModel &model) const
Consolidate with other available data.
const swift::misc::simulation::CAircraftModelList & getStashedModels() const
The stashed models.
void modelsSuccessfullyPublished(const swift::misc::simulation::CAircraftModelList &publishedModels, bool directWrite)
Models succesfully published.
swift::misc::CStatusMessageList stashModels(const swift::misc::simulation::CAircraftModelList &models, bool replace=false, bool consolidateWithDbData=true, bool clearHighlighting=true)
Stash given models (includes validation and consolidation with DB data)
void clearValidationHighlighting()
Clear highlighting set by validations.
void replaceModelsUnvalidated(const swift::misc::simulation::CAircraftModelList &models)
Replace models, no validation.
QStringList getStashedModelStrings() const
Stashed model strings.
T get() const
Get a copy of the current value.
Definition: valuecache.h:408
A sequence of log categories.
bool isEmpty() const
Message empty.
Specialized value object compliant map for variants, based on indexes.
size_type size() const
Returns number of elements in the sequence.
Definition: sequence.h:273
void truncate(size_type maxSize)
Changes the size of the sequence, if it is bigger than the given size.
Definition: sequence.h:291
void push_back(const T &value)
Appends an element at the end of the sequence.
Definition: sequence.h:305
bool isEmpty() const
Synonym for empty.
Definition: sequence.h:285
Streamable status message, e.g.
bool isWarningOrAbove() const
Warning or above.
Status messages, e.g. from Core -> GUI.
bool hasWarningOrErrorMessages() const
Warning or error messages.
bool hasErrorMessages() const
Error messages.
Value object for ICAO classification.
CStatusMessageList validate() const
Validate data.
Value object for ICAO classification.
const QString & getDesignator() const
Get airline, e.g. "DLH".
bool hasValidDesignator() const
Airline designator available?
Value object encapsulating information about an airpot.
Definition: livery.h:29
CStatusMessageList validate() const
Validate data.
Definition: livery.cpp:126
bool hasValidDbKey() const
Has valid DB key.
Definition: datastore.h:102
Value object encapsulating information of an authentiated user.
Aircraft model (used by another pilot, my models on disk)
Definition: aircraftmodel.h:71
const aviation::CAirlineIcaoCode & getAirlineIcaoCode() const
Airline ICAO code.
const aviation::CLivery & getLivery() const
Get livery.
const QString & getModelString() const
Model key, either queried or loaded from simulator model.
const CDistributor & getDistributor() const
Get distributor.
const aviation::CAircraftIcaoCode & getAircraftIcaoCode() const
Aircraft ICAO code.
ModelType getModelType() const
Model type.
QString getModelStringAndDbKey() const
Model string and DB key (if available)
bool hasModelString() const
Non empty model string?
void updateMissingParts(const CAircraftModel &otherModel, bool dbModelPriority=true)
Update missing parts from another model.
Value object encapsulating a list of aircraft models.
QStringList getModelStringList(bool sort=true) const
Model strings.
Value object encapsulating information of software distributor.
Definition: distributor.h:33
swift::misc::CStatusMessageList validate() const
Validate data.
SWIFT_GUI_EXPORT swift::gui::CGuiApplication * sGui
Single instance of GUI application object.
Classes interacting with the swift database (aka "datastore").
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
Models to be used with views, mainly QTableView.
Views, mainly QTableView.
GUI related classes.
Free functions in swift::misc.
bool isEmpty() const const
QMetaObject::Connection connect(const QObject *sender, PointerToMemberFunction signal, Functor functor)
QObject * sender() const const
bool isEmpty() const const
QString arg(Args &&... args) const const
bool isEmpty() const const
QString number(double n, char format, int precision)
QueuedConnection
#define SWIFT_VERIFY_X(COND, WHERE, WHAT)
A weaker kind of assert.
Definition: verify.h:26