swift
dbmappingcomponent.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 <QAction>
7 #include <QDialog>
8 #include <QFileDialog>
9 #include <QFrame>
10 #include <QMenu>
11 #include <QModelIndex>
12 #include <QPoint>
13 #include <QShortcut>
14 #include <QSplitter>
15 #include <QTabWidget>
16 #include <QVariant>
17 #include <QWidget>
18 #include <Qt>
19 #include <QtGlobal>
20 
21 #include "ui_dbmappingcomponent.h"
22 
23 #include "core/webdataservices.h"
33 #include "gui/editors/liveryform.h"
35 #include "gui/guiapplication.h"
36 #include "gui/guiutility.h"
37 #include "gui/menus/aircraftmodelmenus.h"
38 #include "gui/menus/menuaction.h"
40 #include "gui/shortcut.h"
42 #include "gui/views/viewbase.h"
44 #include "misc/aviation/livery.h"
45 #include "misc/icons.h"
46 #include "misc/logmessage.h"
50 #include "misc/swiftdirectories.h"
51 
52 using namespace swift::core;
53 using namespace swift::misc;
54 using namespace swift::misc::aviation;
55 using namespace swift::misc::network;
56 using namespace swift::misc::simulation;
57 using namespace swift::misc::simulation::fscommon;
58 using namespace swift::gui;
59 using namespace swift::gui::editors;
60 using namespace swift::gui::views;
61 using namespace swift::gui::models;
62 using namespace swift::gui::menus;
63 
64 namespace swift::gui::components
65 {
66  CDbMappingComponent::CDbMappingComponent(QWidget *parent)
67  : COverlayMessagesFrame(parent), ui(new Ui::CDbMappingComponent),
68  m_autoStashDialog(new CDbAutoStashingComponent(this)),
69  m_autoSimulatorDialog(new CDbAutoSimulatorStashingComponent(this)),
70  m_modelModifyDialog(new CDbModelMappingModifyDialog(this))
71  {
72  ui->setupUi(this);
73  ui->comp_StashAircraft->setMappingComponent(this);
74  ui->comp_OwnModelSet->setMappingComponent(this);
75 
77  ui->tvp_AircraftModelsForVPilot->setAircraftModelMode(CAircraftModelListModel::VPilotRuleModel);
78  ui->tvp_AircraftModelsForVPilot->addFilterDialog();
79 
80  // model menus
81  ui->comp_OwnAircraftModels->view()->setCustomMenu(
82  new CShowSimulatorFileMenu(ui->comp_OwnAircraftModels->view(), this));
83  ui->comp_OwnAircraftModels->view()->setCustomMenu(new CMergeWithVPilotMenu(this));
84  ui->comp_OwnAircraftModels->view()->setCustomMenu(new COwnModelSetMenu(this));
85  ui->comp_OwnAircraftModels->view()->setCustomMenu(new CStashToolsMenu(this));
86 
87  ui->comp_OwnModelSet->view()->setCustomMenu(new CShowSimulatorFileMenu(ui->comp_OwnModelSet->view(), this));
88  ui->comp_OwnModelSet->view()->setCustomMenu(new CStashToolsMenu(this));
89 
90  ui->comp_StashAircraft->view()->setCustomMenu(new CShowSimulatorFileMenu(ui->comp_StashAircraft->view(), this));
91  ui->comp_StashAircraft->view()->setCustomMenu(new CApplyDbDataMenu(this));
92  ui->comp_StashAircraft->view()->setCustomMenu(new COwnModelSetMenu(this));
93  ui->comp_StashAircraft->view()->setCustomMenu(new CStashToolsMenu(this));
94 
95  ui->comp_ModelWorkbench->view()->menuAddItems(CAircraftModelView::MenuClear |
96  CAircraftModelView::MenuRemoveSelectedRows);
97  ui->comp_ModelWorkbench->view()->setCustomMenu(new CApplyDbDataMenu(this));
98  ui->comp_ModelWorkbench->view()->setCustomMenu(new COwnModelSetMenu(this));
99  ui->comp_ModelWorkbench->view()->setCustomMenu(new CStashToolsMenu(this));
100  ui->comp_ModelWorkbench->view()->setCustomMenu(new CRemovedModelsMenu(this));
101 
102  // connects
103  connect(ui->editor_ModelMapping, &CModelMappingForm::requestStash, this,
104  &CDbMappingComponent::stashCurrentModel);
105 
106  connect(ui->comp_OwnAircraftModels, &CDbOwnModelsComponent::ownModelsSimulatorChanged, this,
107  &CDbMappingComponent::onOwnModelsSimulatorChanged, Qt::QueuedConnection);
108  connect(ui->comp_OwnAircraftModels->view(), &CAircraftModelView::doubleClicked, this,
109  &CDbMappingComponent::onModelRowSelected);
110  connect(ui->comp_OwnAircraftModels->view(), &CAircraftModelView::modelDataChangedDigest, this,
111  &CDbMappingComponent::onOwnModelsChangedDigest, Qt::QueuedConnection);
112  connect(ui->comp_OwnAircraftModels->view(), &CAircraftModelView::requestStash, this,
114  connect(ui->comp_OwnAircraftModels->view(), &CAircraftModelView::toggledHighlightStashedModels, this,
115  &CDbMappingComponent::onStashedModelsChangedTriggerDigest);
116 
117  connect(ui->comp_ModelWorkbench->view(), &CAircraftModelView::doubleClicked, this,
118  &CDbMappingComponent::onModelRowSelected);
119  connect(ui->comp_ModelWorkbench->view(), &CAircraftModelView::modelDataChangedDigest, this,
120  &CDbMappingComponent::onWorkbenchDataChanged, Qt::QueuedConnection);
121  connect(ui->comp_ModelWorkbench->view(), &CAircraftModelView::requestStash, this,
123  connect(ui->comp_ModelWorkbench->view(), &CAircraftModelView::toggledHighlightStashedModels, this,
124  &CDbMappingComponent::onStashedModelsChangedTriggerDigest);
125 
126  connect(ui->comp_StashAircraft->view(), &CAircraftModelView::modelDataChangedDigest, this,
127  &CDbMappingComponent::onStashedModelsDataChangedDigest);
128  connect(ui->comp_StashAircraft->view(), &CAircraftModelView::doubleClicked, this,
129  &CDbMappingComponent::onModelRowSelected);
130  connect(ui->comp_StashAircraft->view(), &CAircraftModelView::requestHandlingOfStashDrop, this,
131  &CDbMappingComponent::handleStashDropRequest);
132  connect(ui->comp_StashAircraft, &CDbStashComponent::stashedModelsChanged, this,
133  &CDbMappingComponent::onStashedModelsChangedTriggerDigest);
134  connect(ui->comp_StashAircraft, &CDbStashComponent::modelsSuccessfullyPublished, this,
135  &CDbMappingComponent::onModelsSuccessfullyPublished, Qt::QueuedConnection);
136 
137  connect(ui->comp_OwnModelSet->view(), &CAircraftModelView::modelDataChangedDigest, this,
138  &CDbMappingComponent::onModelSetChangedDigest, Qt::QueuedConnection);
139  connect(ui->comp_OwnModelSet->view(), &CAircraftModelView::requestStash, this,
141 
142  connect(ui->tw_ModelsToBeMapped, &QTabWidget::currentChanged, this, &CDbMappingComponent::onTabIndexChanged);
143  connect(ui->tw_ModelsToBeMapped, &QTabWidget::currentChanged, ui->comp_ModelMatcher,
145 
146  connect(ui->comp_OwnModelSet->view(), &CAircraftModelView::doubleClicked, this,
147  &CDbMappingComponent::onModelRowSelected);
148 
149  // initial values
150  this->onModelSetChangedDigest(ui->comp_OwnModelSet->view()->rowCount(),
151  ui->comp_OwnModelSet->view()->hasFilter());
152  this->onStashedModelsDataChangedDigest(ui->comp_StashAircraft->view()->rowCount(),
153  ui->comp_StashAircraft->view()->hasFilter());
154  this->onOwnModelsChangedDigest(ui->comp_OwnAircraftModels->view()->rowCount(),
155  ui->comp_OwnAircraftModels->view()->hasFilter());
156 
157  // allow to use workbench data
158  ui->comp_ModelMatcher->setWorkbenchView(ui->comp_ModelWorkbench->view());
159 
160  // how to display forms
161  ui->editor_AircraftModel->setSelectOnly();
162 
163  ui->tw_ModelsToBeMapped->setTabIcon(TabStash, CIcons::appDbStash16());
164  ui->tw_ModelsToBeMapped->setTabIcon(TabOwnModels, CIcons::appModels16());
165  ui->tw_ModelsToBeMapped->setTabIcon(TabOwnModelSet, CIcons::appModels16());
166  ui->tw_ModelsToBeMapped->setTabIcon(TabWorkbench, CIcons::wrench16());
167 
168  // custom menu and shortcut
169  this->setContextMenuPolicy(Qt::CustomContextMenu);
170  connect(this, &CDbMappingComponent::customContextMenuRequested, this,
171  &CDbMappingComponent::onCustomContextMenu);
172  new QShortcut(CShortcut::keyAddToModelSet(), this, SLOT(ps_addToOwnModelSet()));
173 
174  // vPilot
175  this->initVPilotLoading();
176  }
177 
179 
180  void CDbMappingComponent::initVPilotLoading()
181  {
182  m_vPilotEnabled = this->vPilotSupport && m_swiftDbUser.get().hasAdminRole();
183  static const QString tabName(ui->tw_ModelsToBeMapped->tabText(TabVPilot));
184 
185  if (m_vPilot1stInit && vPilotSupport)
186  {
187  m_vPilot1stInit = false;
188  connect(ui->tvp_AircraftModelsForVPilot, &CAircraftModelView::doubleClicked, this,
189  &CDbMappingComponent::onModelRowSelected);
190  connect(ui->tvp_AircraftModelsForVPilot, &CAircraftModelView::modelDataChanged, this,
191  &CDbMappingComponent::onVPilotDataChanged);
192  connect(&m_vPilotReader, &CVPilotRulesReader::readFinished, this,
193  &CDbMappingComponent::onLoadVPilotDataFinished);
194  connect(ui->tvp_AircraftModelsForVPilot, &CAircraftModelView::requestStash, this,
196  connect(ui->tvp_AircraftModelsForVPilot, &CAircraftModelView::toggledHighlightStashedModels, this,
197  &CDbMappingComponent::onStashedModelsChangedTriggerDigest);
198  connect(ui->tvp_AircraftModelsForVPilot, &CAircraftModelView::requestUpdate, this,
199  &CDbMappingComponent::requestVPilotDataUpdate);
200 
201  ui->tvp_AircraftModelsForVPilot->setCustomMenu(new CMappingVPilotMenu(this));
202  ui->tvp_AircraftModelsForVPilot->setCustomMenu(new CStashToolsMenu(this));
203  ui->tvp_AircraftModelsForVPilot->setDisplayAutomatically(true);
204 
205  ui->tvp_AircraftModelsForVPilot->addFilterDialog();
206  const CAircraftModelList vPilotModels(m_vPilotReader.getAsModelsFromCache());
207  ui->tvp_AircraftModelsForVPilot->updateContainerMaybeAsync(vPilotModels);
208  const int noModels = vPilotModels.size();
209  CLogMessage(this).info(u"%1 cached vPilot models loaded") << noModels;
210  }
211  ui->tab_VPilot->setEnabled(m_vPilotEnabled);
212  ui->tab_VPilot->setVisible(m_vPilotEnabled);
213  if (m_vPilotEnabled)
214  {
215  // create / restore tab
216  ui->tw_ModelsToBeMapped->addTab(ui->tab_VPilot, tabName);
217  this->onVPilotDataChanged(ui->tvp_AircraftModelsForVPilot->rowCount(),
218  ui->tvp_AircraftModelsForVPilot->hasFilter());
219  }
220  else
221  {
222  m_vPilotFormatted = false;
223  ui->tw_ModelsToBeMapped->removeTab(TabVPilot);
224  }
225  }
226 
227  void CDbMappingComponent::formatVPilotView()
228  {
229  if (!m_vPilotEnabled || m_vPilotFormatted) { return; }
230  m_vPilotFormatted = true;
231  ui->tvp_AircraftModelsForVPilot->presizeOrFullResizeToContents();
232  }
233 
234  CAircraftModel CDbMappingComponent::getModelFromView(const QModelIndex &index) const
235  {
236  if (!index.isValid()) { return CAircraftModel(); }
237  const QObject *sender = QObject::sender();
238 
239  // check if we have an explicit sender
240  if (sender == ui->tvp_AircraftModelsForVPilot) { return ui->tvp_AircraftModelsForVPilot->at(index); }
241  if (sender == ui->comp_OwnAircraftModels->view()) { return ui->comp_OwnAircraftModels->view()->at(index); }
242  if (sender == ui->comp_StashAircraft || sender == ui->comp_StashAircraft->view())
243  {
244  return ui->comp_StashAircraft->view()->at(index);
245  }
246  if (sender == ui->comp_OwnModelSet->view()) { return ui->comp_OwnModelSet->view()->at(index); }
247 
248  // no sender, use current tab
249  const CAircraftModelView *mv = this->currentModelView();
250  if (!mv) { return CAircraftModel(); }
251  return mv->at(index);
252  }
253 
255  {
256  this->disconnect();
257  m_vPilotReader.gracefulShutdown();
258  ui->comp_OwnAircraftModels->gracefulShutdown();
259  }
260 
262  {
263  const CAircraftModelView *mv = this->currentModelView();
264  if (!mv) { return false; }
265  return mv->hasSelectedModelsToStash();
266  }
267 
269  {
270  const TabIndex tab = currentTabIndex();
271  return this->modelView(tab);
272  }
273 
275  {
276  switch (tab)
277  {
278  case TabOwnModels: return ui->comp_OwnAircraftModels->view();
279  case TabVPilot: return ui->tvp_AircraftModelsForVPilot;
280  case TabWorkbench: return ui->comp_ModelWorkbench->view();
281  case TabStash: return ui->comp_StashAircraft->view();
282  case TabOwnModelSet: return ui->comp_OwnModelSet->view();
283  default: return nullptr;
284  }
285  }
286 
287  QString CDbMappingComponent::currentTabText() const
288  {
289  const int i = ui->tw_ModelsToBeMapped->currentIndex();
290  return ui->tw_ModelsToBeMapped->tabText(i);
291  }
292 
293  void CDbMappingComponent::updateEditorsWhenApplicable()
294  {
295  const CAircraftModel currentEditorModel(ui->editor_ModelMapping->getValue());
296  if (!currentEditorModel.hasModelString()) { return; } // no related model
297  const QString modelString(currentEditorModel.getModelString());
298  const CAircraftModel currentStashedModel(ui->comp_StashAircraft->getStashedModel(modelString));
299  if (!currentStashedModel.hasModelString()) { return; }
300 
301  // we have found a model in the stashed models and this is the one currently displayed
302  // in the editors
303  bool updated = false;
304  const CLivery stashedLivery(currentStashedModel.getLivery());
305  if (stashedLivery.hasValidDbKey())
306  {
307  if (ui->editor_AircraftModel->setLivery(stashedLivery)) { updated = true; }
308  }
309 
310  const CDistributor stashedDistributor(currentStashedModel.getDistributor());
311  if (stashedDistributor.hasValidDbKey())
312  {
313  if (ui->editor_AircraftModel->setDistributor(stashedDistributor)) { updated = true; }
314  }
315 
316  const CAircraftIcaoCode stashedIcaoCode(currentStashedModel.getAircraftIcaoCode());
317  if (stashedIcaoCode.hasValidDbKey())
318  {
319  if (ui->editor_AircraftModel->setAircraftIcao(stashedIcaoCode)) { updated = true; }
320  }
321 
322  if (updated) { CLogMessage(this).info(u"Updated editor data for '%1'") << modelString; }
323  }
324 
326  {
327  const CAircraftModelView *mv = this->currentModelView();
328  if (!mv || !mv->hasSelectedModelsToStash()) { return CAircraftModelList(); }
329  return mv->selectedObjects();
330  }
331 
333  {
334  return ui->comp_StashAircraft->getStashedModels();
335  }
336 
338 
340  {
341  return ui->comp_StashAircraft->getStashedModelStrings();
342  }
343 
345  {
346  if (!ui->tw_ModelsToBeMapped) { return CDbMappingComponent::NoValidTab; }
347  const int t = ui->tw_ModelsToBeMapped->currentIndex();
348  return static_cast<TabIndex>(t);
349  }
350 
351  bool CDbMappingComponent::isStashTab() const { return this->currentTabIndex() == TabStash; }
352 
353  bool CDbMappingComponent::isWorkbenchTab() const { return this->currentTabIndex() == TabWorkbench; }
354 
356  {
357  const bool allowed = this->currentTabIndex() == CDbMappingComponent::TabOwnModels ||
358  this->currentTabIndex() == CDbMappingComponent::TabStash;
359  return allowed && this->currentModelView()->hasSelection();
360  }
361 
363  {
364  CStatusMessageList msgs;
365  if (withNestedForms)
366  {
367  // tests the 3 subforms and the model itself lenient
368  msgs.push_back(ui->editor_ModelMapping->validate(false));
369  msgs.push_back(ui->editor_AircraftModel->validate(true));
370  }
371  else
372  {
373  // model lenient
374  msgs.push_back(ui->editor_ModelMapping->validate(false));
375  }
376  return msgs;
377  }
378 
379  void CDbMappingComponent::handleStashDropRequest(const CAirlineIcaoCode &code) const
380  {
381  const CLivery stdLivery(sGui->getWebDataServices()->getStdLiveryForAirlineCode(code));
382  if (!stdLivery.hasValidDbKey()) { return; }
383  ui->comp_StashAircraft->applyToSelected(stdLivery);
384  }
385 
386  void CDbMappingComponent::stashCurrentModel()
387  {
388  const bool nested = this->isStashTab(); // on stash tab, full validation, otherwise not
389  CStatusMessageList msgs(this->validateCurrentModel(nested));
390  if (!msgs.hasErrorMessages())
391  {
392  const CAircraftModel editorModel(getEditorAircraftModel());
393 
394  // from stash, do not consolidate, because we want to keep data as they are from the editor
395  const bool consolidate = !this->isStashTab();
396  msgs.push_back(ui->comp_StashAircraft->stashModel(editorModel, true, consolidate));
397  }
398  if (msgs.hasErrorMessages()) { this->showOverlayMessagesOrHTMLMessage(msgs); }
399  }
400 
401  void CDbMappingComponent::displayAutoStashingDialog() { m_autoStashDialog->exec(); }
402 
403  void CDbMappingComponent::displayAutoSimulatorStashingDialog() { m_autoSimulatorDialog->exec(); }
404 
405  void CDbMappingComponent::removeDbModelsFromView()
406  {
407  const QStringList modelStrings(sGui->getWebDataServices()->getModelStrings());
408  if (modelStrings.isEmpty()) { return; }
409  CAircraftModelView *mv = this->currentModelView();
410  if (mv) { mv->removeModelsWithModelString(modelStrings); }
411  }
412 
413  void CDbMappingComponent::showChangedAttributes()
414  {
415  if (!this->hasStashedModels()) { return; }
416  if (this->currentTabIndex() != TabStash) { return; }
417  ui->comp_StashAircraft->showChangedAttributes();
418  }
419 
420  void CDbMappingComponent::toggleAutoFiltering() { m_autoFilterInDbViews = !m_autoFilterInDbViews; }
421 
422  void CDbMappingComponent::applyFormLiveryData()
423  {
424  if (ui->comp_StashAircraft->view()->selectedRowCount() < 1) { return; }
425  const CStatusMessageList msgs = ui->editor_AircraftModel->validateLivery(true);
426  if (msgs.hasErrorMessages()) { this->showOverlayMessagesOrHTMLMessage(msgs); }
427  else { ui->comp_StashAircraft->applyToSelected(ui->editor_AircraftModel->getLivery()); }
428  }
429 
430  void CDbMappingComponent::applyFormAircraftIcaoData()
431  {
432  if (ui->comp_StashAircraft->view()->selectedRowCount() < 1) { return; }
433  const CStatusMessageList msgs = ui->editor_AircraftModel->validateAircraftIcao(true);
434  if (msgs.hasErrorMessages()) { this->showOverlayMessagesOrHTMLMessage(msgs); }
435  else { ui->comp_StashAircraft->applyToSelected(ui->editor_AircraftModel->getAircraftIcao()); }
436  }
437 
438  void CDbMappingComponent::applyFormDistributorData()
439  {
440  if (ui->comp_StashAircraft->view()->selectedRowCount() < 1) { return; }
441  const CStatusMessageList msgs = ui->editor_AircraftModel->validateDistributor(true);
442  if (msgs.hasErrorMessages()) { this->showOverlayMessagesOrHTMLMessage(msgs); }
443  else { ui->comp_StashAircraft->applyToSelected(ui->editor_AircraftModel->getDistributor()); }
444  }
445 
447  {
448  // only one model selected, use as default
449  if (ui->comp_StashAircraft->view()->hasSingleSelectedRow())
450  {
451  m_modelModifyDialog->setValue(ui->comp_StashAircraft->view()->selectedObject());
452  }
453 
454  const QDialog::DialogCode s = static_cast<QDialog::DialogCode>(m_modelModifyDialog->exec());
455  if (s == QDialog::Rejected) { return; }
456  const CPropertyIndexVariantMap vm = m_modelModifyDialog->getValues();
457  ui->comp_StashAircraft->applyToSelected(vm);
458  }
459 
461 
463  {
464  const int h = this->height(); // total height
465  int h2 = ui->qw_EditorsScrollArea->minimumHeight();
466  h2 = qRound(h2 * 1.10); // desired height of inner widget + some space for scrollarea
467  int currentSize = ui->sp_MappingComponent->sizes().last(); // current size
468  if (h2 <= currentSize) { return; }
469 
470  int h1;
471  if (h * 0.90 > h2)
472  {
473  // enough space to display as whole
474  h1 = h - h2;
475  }
476  else
477  {
478  h1 = h / 3;
479  h2 = h / 3 * 2;
480  }
481  const QList<int> sizes({ h1, h2 });
482  ui->sp_MappingComponent->setSizes(sizes);
483  }
484 
486  {
487  const int h = this->height();
488  const int h1 = h;
489  const int h2 = 0;
490  const QList<int> sizes({ h1, h2 });
491  ui->sp_MappingComponent->setSizes(sizes);
492  }
493 
494  void CDbMappingComponent::loadVPilotData()
495  {
496  if (m_vPilotReader.readInBackground(true))
497  {
498  CLogMessage(this).info(u"Start loading vPilot rulesets");
499  ui->tvp_AircraftModelsForVPilot->showLoadIndicator();
500  }
501  else { CLogMessage(this).warning(u"Loading vPilot rulesets already in progress"); }
502  }
503 
504  void CDbMappingComponent::onLoadVPilotDataFinished(bool success)
505  {
506  if (!m_vPilotEnabled) { return; }
507  if (success)
508  {
509  CLogMessage(this).info(u"Loading vPilot ruleset completed");
510  const CAircraftModelList models(m_vPilotReader.getAsModels());
511  if (ui->tvp_AircraftModelsForVPilot->displayAutomatically())
512  {
513  ui->tvp_AircraftModelsForVPilot->updateContainerMaybeAsync(models);
514  }
515  }
516  else { CLogMessage(this).error(u"Loading vPilot ruleset failed"); }
517  ui->tvp_AircraftModelsForVPilot->hideLoadIndicator();
518  }
519 
520  void CDbMappingComponent::loadRemovedModels()
521  {
522  if (!ui->comp_ModelWorkbench->view()) { return; }
523  const QString logDir = CSwiftDirectories::logDirectory();
524  ui->comp_ModelWorkbench->view()->showFileLoadDialog(logDir);
525  }
526 
527  void CDbMappingComponent::onVPilotCacheChanged()
528  {
529  if (ui->tvp_AircraftModelsForVPilot->displayAutomatically())
530  {
531  ui->tvp_AircraftModelsForVPilot->updateContainerMaybeAsync(m_vPilotReader.getAsModelsFromCache());
532  }
533  else { ui->tvp_AircraftModelsForVPilot->hideLoadIndicator(); }
534  }
535 
536  void CDbMappingComponent::requestVPilotDataUpdate() { this->onVPilotCacheChanged(); }
537 
538  void CDbMappingComponent::onStashedModelsChangedTriggerDigest()
539  {
540  m_dsStashedModelsChanged.inputSignal(); // will call onStashedModelsChangedDigest
541  }
542 
543  void CDbMappingComponent::onStashedModelsChangedDigest()
544  {
545  const bool highlightVPilot = ui->tvp_AircraftModelsForVPilot->derivedModel()->highlightModels();
546  const bool highlightOwnModels = ui->comp_OwnAircraftModels->view()->derivedModel()->highlightModels();
547  const bool highlightModelSet = ui->comp_OwnModelSet->view()->derivedModel()->highlightModels();
548  const bool highlight = highlightOwnModels || highlightModelSet || highlightVPilot;
549  if (!highlight) { return; }
550  const QStringList stashedModels(ui->comp_StashAircraft->getStashedModelStrings());
551  if (highlightVPilot)
552  {
553  ui->tvp_AircraftModelsForVPilot->derivedModel()->setHighlightModelStrings(stashedModels);
554  }
555  if (highlightOwnModels)
556  {
557  ui->comp_OwnAircraftModels->view()->derivedModel()->setHighlightModelStrings(stashedModels);
558  }
559  if (highlightModelSet)
560  {
561  ui->comp_OwnModelSet->view()->derivedModel()->setHighlightModelStrings(stashedModels);
562  }
563  }
564 
565  void CDbMappingComponent::onTabIndexChanged(int index)
566  {
567  const CDbMappingComponent::TabIndex ti = static_cast<CDbMappingComponent::TabIndex>(index);
568  switch (ti)
569  {
570  case CDbMappingComponent::TabOwnModelSet:
571  {
572  ui->frp_Editors->setVisible(true);
573  ui->editor_ModelMapping->setVisible(true);
574  this->resizeForSelect();
575  }
576  break;
577  case CDbMappingComponent::TabModelMatcher:
578  {
579  ui->editor_ModelMapping->setVisible(false);
580  ui->frp_Editors->setVisible(false);
581  this->resizeForSelect();
582  }
583  break;
584  case CDbMappingComponent::TabVPilot:
585  {
586  // fall thru intended
587  this->formatVPilotView();
588  }
589  [[fallthrough]];
590  default:
591  {
592  ui->frp_Editors->setVisible(true);
593  ui->editor_ModelMapping->setVisible(true);
594  }
595  break;
596  }
597  emit this->tabIndexChanged(index);
598  }
599 
600  void CDbMappingComponent::onModelsSuccessfullyPublished(const CAircraftModelList &models, bool directWrite)
601  {
602  if (models.isEmpty()) { return; }
603  if (!directWrite) { return; } // no models wwritten, but CRs
604  emit this->requestUpdatedData(CEntityFlags::ModelEntity);
605  }
606 
607  void CDbMappingComponent::onVPilotDataChanged(int count, bool withFilter)
608  {
609  Q_UNUSED(count)
610  Q_UNUSED(withFilter)
611  ui->tvp_AircraftModelsForVPilot->setTabWidgetViewText(ui->tw_ModelsToBeMapped,
612  ui->tw_ModelsToBeMapped->indexOf(ui->tab_VPilot));
613  }
614 
615  void CDbMappingComponent::onWorkbenchDataChanged(int count, bool withFilter)
616  {
617  Q_UNUSED(count)
618  Q_UNUSED(withFilter)
619  ui->comp_ModelWorkbench->view()->setTabWidgetViewText(ui->tw_ModelsToBeMapped,
620  ui->tw_ModelsToBeMapped->indexOf(ui->tab_Workbench));
621  }
622 
623  void CDbMappingComponent::ps_addToOwnModelSet()
624  {
625  if (!this->canAddToModelSetTab()) { return; }
626  const CAircraftModelList models(this->currentModelView()->selectedObjects());
627  const CStatusMessage m = this->addToOwnModelSet(models, this->getOwnModelsSimulator());
628  CLogMessage::preformatted(m);
629  }
630 
631  void CDbMappingComponent::mergeWithVPilotModels()
632  {
633  if (!ui->comp_OwnAircraftModels->modelLoader()) { return; }
634  if (m_vPilotReader.getModelsCount() < 1) { return; }
635  const CSimulatorInfo sim(ui->comp_OwnAircraftModels->getOwnModelsSimulator());
636  if (!sim.isSingleSimulator() || !sim.isMicrosoftOrPrepare3DSimulator()) { return; }
637  CAircraftModelList ownModels(getOwnModels());
638  if (ownModels.isEmpty()) { return; }
639  ui->comp_OwnAircraftModels->view()->showLoadIndicator();
640  CAircraftModelUtilities::mergeWithVPilotData(ownModels, m_vPilotReader.getAsModelsFromCache(), true);
641  ui->comp_OwnAircraftModels->updateViewAndCache(ownModels);
642  }
643 
644  void CDbMappingComponent::mergeSelectedWithVPilotModels()
645  {
646  if (!ui->comp_OwnAircraftModels->modelLoader()) { return; }
647  if (m_vPilotReader.getModelsCount() < 1) { return; }
648  if (!ui->comp_OwnAircraftModels->view()->hasSelection()) { return; }
649  const CSimulatorInfo sim(ui->comp_OwnAircraftModels->getOwnModelsSimulator());
650  if (!sim.isSingleSimulator() || !sim.isMicrosoftOrPrepare3DSimulator()) { return; }
651  CAircraftModelList ownModels(this->getOwnSelectedModels()); // subset
652  if (ownModels.isEmpty()) { return; }
653  ui->comp_OwnAircraftModels->view()->showLoadIndicator();
654  CAircraftModelUtilities::mergeWithVPilotData(ownModels, m_vPilotReader.getAsModelsFromCache(), true);
655 
656  // full models
657  CAircraftModelList allModels = m_vPilotReader.getAsModelsFromCache();
658  allModels.replaceOrAddModelsWithString(ownModels, Qt::CaseInsensitive);
659  ui->comp_OwnAircraftModels->updateViewAndCache(allModels);
660  }
661 
662  void CDbMappingComponent::onCustomContextMenu(const QPoint &point)
663  {
664  QPoint globalPos = this->mapToGlobal(point);
665  QScopedPointer<QMenu> contextMenu(new QMenu(this));
666 
667  contextMenu->addAction("Max.data area", this, &CDbMappingComponent::resizeForSelect,
668  QKeySequence(static_cast<Qt::Key>(Qt::CTRL) + Qt::Key_M, Qt::Key_D));
669  contextMenu->addAction("Max.mapping area", this, &CDbMappingComponent::resizeForMapping,
670  QKeySequence(static_cast<Qt::Key>(Qt::CTRL) + Qt::Key_M, Qt::Key_M));
671  QAction *selectedItem = contextMenu.data()->exec(globalPos);
672  Q_UNUSED(selectedItem)
673  }
674 
675  void CDbMappingComponent::onStashedModelsDataChangedDigest(int count, bool withFilter)
676  {
677  Q_UNUSED(count)
678  Q_UNUSED(withFilter)
679  ui->comp_StashAircraft->view()->setTabWidgetViewText(
680  ui->tw_ModelsToBeMapped, ui->tw_ModelsToBeMapped->indexOf(ui->tab_StashAircraftModels));
681 
682  // update editors
683  this->updateEditorsWhenApplicable();
684  }
685 
686  void CDbMappingComponent::onModelSetChangedDigest(int count, bool withFilter)
687  {
688  Q_UNUSED(count)
689  Q_UNUSED(withFilter)
690 
691  // none standard with simulator
692  int i = ui->tw_ModelsToBeMapped->indexOf(ui->tab_OwnModelSet);
693  QString o = "Active model set " + ui->comp_OwnModelSet->getModelSetSimulator().toQString(true);
694  const QString f = ui->comp_OwnModelSet->view()->hasFilter() ? "F" : "";
695  o = CGuiUtility::replaceTabCountValue(o, ui->comp_OwnModelSet->view()->rowCount()) + f;
696  ui->tw_ModelsToBeMapped->setTabText(i, o);
697  }
698 
699  void CDbMappingComponent::onOwnModelsChangedDigest(int count, bool withFilter)
700  {
701  Q_UNUSED(count)
702  Q_UNUSED(withFilter)
703 
704  // non standard with sim
705  const int i = ui->tw_ModelsToBeMapped->indexOf(ui->tab_OwnModels);
706  static const QString ot("Stored own models");
707  QString o(ot);
708  const QString sim(ui->comp_OwnAircraftModels->getOwnModelsSimulator().toQString(true));
709  if (!sim.isEmpty()) { o = o.append(" ").append(sim); }
710  const QString f = ui->comp_OwnAircraftModels->view()->hasFilter() ? "F" : "";
711  o = CGuiUtility::replaceTabCountValue(o, ui->comp_OwnAircraftModels->view()->rowCount()) + f;
712  ui->tw_ModelsToBeMapped->setTabText(i, o);
713  }
714 
715  void CDbMappingComponent::onUserChanged() { this->initVPilotLoading(); }
716 
718  {
719  if (!this->hasSelectedModelsToStash()) { return; }
720  CStatusMessageList msgs = ui->comp_StashAircraft->stashModels(this->getSelectedModelsToStash());
722  }
723 
724  void CDbMappingComponent::onModelRowSelected(const QModelIndex &index)
725  {
726  CAircraftModel model(this->getModelFromView(index)); // data from view
727  if (!model.hasModelString()) { return; }
728 
729  // we either use the model, or try to resolve the data to DB data
730  bool dbModel = model.hasValidDbKey();
731  const CLivery livery(dbModel ? model.getLivery() :
732  sGui->getWebDataServices()->smartLiverySelector(model.getLivery()));
733  const CAircraftIcaoCode aircraftIcao(
734  dbModel ? model.getAircraftIcaoCode() :
735  sGui->getWebDataServices()->smartAircraftIcaoSelector(model.getAircraftIcaoCode()));
736  const CDistributor distributor(
737  dbModel ? model.getDistributor() :
738  sGui->getWebDataServices()->smartDistributorSelector(model.getDistributor()));
739 
740  // set model part
741  ui->editor_ModelMapping->setValue(model);
742 
743  // if found, then set in editor
744  if (livery.hasValidDbKey()) { ui->editor_AircraftModel->setLivery(livery); }
745  else { ui->editor_AircraftModel->clearLivery(); }
746  if (aircraftIcao.hasValidDbKey()) { ui->editor_AircraftModel->setAircraftIcao(aircraftIcao); }
747  else { ui->editor_AircraftModel->clearAircraftIcao(); }
748  if (distributor.hasValidDbKey()) { ui->editor_AircraftModel->setDistributor(distributor); }
749  else { ui->editor_AircraftModel->clearDistributor(); }
750 
751  // request filtering
752  if (m_autoFilterInDbViews)
753  {
754  emit filterByLivery(model.getLivery());
755  emit filterByAircraftIcao(model.getAircraftIcaoCode());
756  emit filterByDistributor(model.getDistributor());
757  }
758  }
759 
760  void CDbMappingComponent::onOwnModelsSimulatorChanged(const CSimulatorInfo simulator)
761  {
762  // loading of models can fail, so we clean the tab text
763  Q_UNUSED(simulator)
764 
765  ui->comp_OwnAircraftModels->clearView();
766  this->onOwnModelsChangedDigest(0, false);
767  }
768 
770  {
771  CAircraftModel model(ui->editor_ModelMapping->getValue());
772  model.setDistributor(ui->editor_AircraftModel->getDistributor());
773  model.setAircraftIcaoCode(ui->editor_AircraftModel->getAircraftIcao());
774  model.setLivery(ui->editor_AircraftModel->getLivery());
775  return model;
776  }
777 
778  CAircraftModelList CDbMappingComponent::getOwnModels() const { return ui->comp_OwnAircraftModels->getOwnModels(); }
779 
781  {
782  return ui->comp_OwnAircraftModels->getOwnCachedModels(simulator);
783  }
784 
786  {
787  return ui->comp_OwnAircraftModels->getOwnSelectedModels();
788  }
789 
791  {
792  return ui->comp_OwnAircraftModels->getOwnModelForModelString(modelString);
793  }
794 
796  {
797  return ui->comp_OwnAircraftModels->getOwnModelsSimulator();
798  }
799 
801  {
802  ui->comp_OwnAircraftModels->setSimulator(simulator);
803  }
804 
805  int CDbMappingComponent::getOwnModelsCount() const { return ui->comp_OwnAircraftModels->getOwnModelsCount(); }
806 
807  QString CDbMappingComponent::getOwnModelsInfoString() const { return ui->comp_OwnAircraftModels->getInfoString(); }
808 
810  {
811  return ui->comp_OwnAircraftModels->getInfoStringFsFamily();
812  }
813 
815  {
816  Q_ASSERT_X(simulator.isSingleSimulator(), Q_FUNC_INFO, "Need single simulator");
817  ui->comp_OwnModelSet->setSimulator(simulator);
818  }
819 
821  {
822  return ui->comp_OwnModelSet->getModelSetFromView();
823  }
824 
826  {
827  return ui->comp_StashAircraft->stashModel(model, replace);
828  }
829 
831  {
832  return ui->comp_StashAircraft->stashModels(models);
833  }
834 
836  const CSimulatorInfo &simulator)
837  {
838  return ui->comp_OwnModelSet->addToModelSet(models, simulator);
839  }
840 
842  {
843  return ui->comp_StashAircraft->consolidateModel(model);
844  }
845 
847  {
848  ui->comp_StashAircraft->replaceModelsUnvalidated(models);
849  }
850 
851  void CDbMappingComponent::CMappingVPilotMenu::customMenu(CMenuActions &menuActions)
852  {
853  CDbMappingComponent *mapComp = qobject_cast<CDbMappingComponent *>(this->parent());
854  Q_ASSERT_X(mapComp, Q_FUNC_INFO, "Cannot access mapping component");
855 
856  const bool canUseVPilot = mappingComponent()->withVPilot();
857  if (canUseVPilot)
858  {
859  m_menuAction = menuActions.addAction(m_menuAction, CIcons::appMappings16(), "Load vPilot Rules",
860  CMenuAction::pathVPilot(), this,
861  { mapComp, &CDbMappingComponent::loadVPilotData });
862  }
863  this->nestedCustomMenu(menuActions);
864  }
865 
866  CDbMappingComponent *CDbMappingComponent::CMappingVPilotMenu::mappingComponent() const
867  {
868  return qobject_cast<CDbMappingComponent *>(this->parent());
869  }
870 
871  CDbMappingComponent::CStashToolsMenu::CStashToolsMenu(CDbMappingComponent *mappingComponent)
872  : menus::IMenuDelegate(mappingComponent)
873  {}
874 
875  void CDbMappingComponent::CStashToolsMenu::customMenu(CMenuActions &menuActions)
876  {
877  CDbMappingComponent *mapComp = mappingComponent();
878  Q_ASSERT_X(mapComp, Q_FUNC_INFO, "no mapping component");
879  if (!mapComp->currentModelView()->isEmpty() &&
880  mapComp->currentModelView()->getMenu().testFlag(CViewBaseNonTemplate::MenuCanStashModels))
881  {
882  menuActions.addMenuStash();
883 
884  // auto filter in DB views
885  m_stashFiltering = menuActions.addAction(
886  m_stashFiltering, CIcons::filter16(), "Auto filtering in DB views (on/off)",
887  CMenuAction::pathModelStash(), this, { mapComp, &CDbMappingComponent::toggleAutoFiltering });
888  m_stashFiltering->setCheckable(true);
889  m_stashFiltering->setChecked(mapComp->m_autoFilterInDbViews);
890 
891  m_autoStashing = menuActions.addAction(m_autoStashing, CIcons::appDbStash16(), "Auto stashing",
892  CMenuAction::pathModelStash(), this,
893  { mapComp, &CDbMappingComponent::displayAutoStashingDialog });
894  m_autoSimulatorStashing =
895  menuActions.addAction(m_autoSimulatorStashing, CIcons::appDbStash16(),
896  "Cross simulator updating (FSX-P3D-FS9)", CMenuAction::pathModelStash(), this,
897  { mapComp, &CDbMappingComponent::displayAutoSimulatorStashingDialog });
898  if (mapComp->m_autoStashDialog && mapComp->m_autoStashDialog->isCompleted())
899  {
900  menuActions.addAction(
901  CIcons::appDbStash16(), "Last auto stash run", CMenuAction::pathModelStash(), nullptr,
902  { mapComp->m_autoStashDialog.data(), &CDbAutoStashingComponent::showLastResults });
903  }
904  }
905  else if (mapComp->currentTabIndex() == CDbMappingComponent::TabStash)
906  {
907  this->addStashViewSpecificMenus(menuActions);
908  }
909  this->nestedCustomMenu(menuActions);
910  }
911 
912  void CDbMappingComponent::CStashToolsMenu::addStashViewSpecificMenus(CMenuActions &menuActions)
913  {
914  CDbMappingComponent *mapComp = mappingComponent();
915  Q_ASSERT_X(mapComp, Q_FUNC_INFO, "no mapping component");
916 
917  const int dbModels = sGui->getWebDataServices()->getModelsCount();
918  if (dbModels > 0 && mapComp->hasStashedModels())
919  {
920  menuActions.addMenu(CIcons::appDbStash16(), "Stash", CMenuAction::pathModelStash());
921 
922  // we have keys and data by which we could delete them from view
923  const QString msgDelete("Delete " + QString::number(dbModels) + " DB model(s) from '" +
924  mapComp->currentTabText() + "'");
925  menuActions.addAction(CIcons::delete16(), msgDelete, CMenuAction::pathModelStash(), nullptr,
926  { mapComp, &CDbMappingComponent::removeDbModelsFromView });
927 
928  // attribute info
929  menuActions.addAction(CIcons::info16(), "Show changed attributes", CMenuAction::pathModelStash(), nullptr,
930  { mapComp, &CDbMappingComponent::showChangedAttributes });
931  }
932  }
933 
934  CDbMappingComponent *CDbMappingComponent::CStashToolsMenu::mappingComponent() const
935  {
936  return qobject_cast<CDbMappingComponent *>(this->parent());
937  }
938 
939  void CDbMappingComponent::COwnModelSetMenu::customMenu(CMenuActions &menuActions)
940  {
941  CDbMappingComponent *mapComp = mappingComponent();
942  Q_ASSERT_X(mapComp, Q_FUNC_INFO, "no mapping component");
943  if (mapComp->canAddToModelSetTab())
944  {
945  menuActions.addMenuModelSet();
946  m_menuAction = menuActions.addAction(
947  m_menuAction, CIcons::appModels16(),
948  "Add to own model set " + CShortcut::toParenthesisString(CShortcut::keyAddToModelSet()),
949  CMenuAction::pathModelSet(), this, { mapComp, &CDbMappingComponent::ps_addToOwnModelSet },
951  }
952  this->nestedCustomMenu(menuActions);
953  }
954 
955  CDbMappingComponent *CDbMappingComponent::COwnModelSetMenu::mappingComponent() const
956  {
957  return qobject_cast<CDbMappingComponent *>(this->parent());
958  }
959 
960  void CDbMappingComponent::CApplyDbDataMenu::customMenu(CMenuActions &menuActions)
961  {
962  CDbMappingComponent *mapComp = mappingComponent();
963  Q_ASSERT_X(mapComp, Q_FUNC_INFO, "no mapping component");
964 
965  if (mapComp->currentTabIndex() == CDbMappingComponent::TabStash && mapComp->currentModelView()->hasSelection())
966  {
967  if (m_menuActions.isEmpty()) { m_menuActions = QList<QAction *>({ nullptr, nullptr, nullptr, nullptr }); }
968 
969  // stash view and selection
970  menuActions.addMenuStashEditor();
971 
972  m_menuActions[0] = menuActions.addAction(m_menuActions[0], CIcons::appAircraftIcao16(),
973  "Current aircraft ICAO", CMenuAction::pathModelStashEditor(), this,
974  { mapComp, &CDbMappingComponent::applyFormAircraftIcaoData });
975  m_menuActions[1] = menuActions.addAction(m_menuActions[1], CIcons::appDistributors16(),
976  "Current distributor", CMenuAction::pathModelStashEditor(), this,
977  { mapComp, &CDbMappingComponent::applyFormDistributorData });
978  m_menuActions[2] = menuActions.addAction(m_menuActions[2], CIcons::appLiveries16(), "Current livery",
979  CMenuAction::pathModelStashEditor(), this,
980  { mapComp, &CDbMappingComponent::applyFormLiveryData });
981  m_menuActions[3] = menuActions.addAction(m_menuActions[3], CIcons::databaseTable16(),
982  "Modify DB model data", CMenuAction::pathModelStashEditor(), this,
984  }
985  this->nestedCustomMenu(menuActions);
986  }
987 
988  CDbMappingComponent *CDbMappingComponent::CApplyDbDataMenu::mappingComponent() const
989  {
990  return qobject_cast<CDbMappingComponent *>(this->parent());
991  }
992 
993  CDbMappingComponent::CMergeWithVPilotMenu::CMergeWithVPilotMenu(CDbMappingComponent *mappingComponent)
994  : IMenuDelegate(mappingComponent)
995  {
996  Q_ASSERT_X(mappingComponent, Q_FUNC_INFO, "Missing vPilot reader");
997  }
998 
999  void CDbMappingComponent::CMergeWithVPilotMenu::customMenu(CMenuActions &menuActions)
1000  {
1001  const CAircraftModelView *mv = mappingComponent()->ui->comp_OwnAircraftModels->view();
1002  const CSimulatorInfo sim = mappingComponent()->ui->comp_OwnAircraftModels->getOwnModelsSimulator();
1003  if (!mappingComponent()->withVPilot() || mv->isEmpty() || !sim.isSingleSimulator() ||
1005  {
1006  this->nestedCustomMenu(menuActions);
1007  return;
1008  }
1009 
1010  if (m_menuActions.isEmpty()) { m_menuActions = QList<QAction *>({ nullptr, nullptr }); }
1011  menuActions.addMenu("Merge with vPilot data", CMenuAction::pathVPilot());
1012  m_menuActions[0] = menuActions.addAction(m_menuActions[0], "All", CMenuAction::pathVPilot(), this,
1013  { mappingComponent(), &CDbMappingComponent::mergeWithVPilotModels });
1014  if (mv->hasSelection())
1015  {
1016  m_menuActions[1] =
1017  menuActions.addAction(m_menuActions[1], "Selected only", CMenuAction::pathVPilot(), this,
1018  { mappingComponent(), &CDbMappingComponent::mergeSelectedWithVPilotModels });
1019  }
1020  this->nestedCustomMenu(menuActions);
1021  }
1022 
1023  void CDbMappingComponent::CRemovedModelsMenu::customMenu(CMenuActions &menuActions)
1024  {
1025  CDbMappingComponent *mapComp = mappingComponent();
1026  Q_ASSERT_X(mapComp, Q_FUNC_INFO, "no mapping component");
1027  if (mapComp->isWorkbenchTab())
1028  {
1029  menuActions.addMenuModelSet();
1030  m_menuAction =
1031  menuActions.addAction(m_menuAction, CIcons::appModels16(), "Removed models", CMenuAction::pathModel(),
1032  this, { mapComp, &CDbMappingComponent::loadRemovedModels });
1033  }
1034  this->nestedCustomMenu(menuActions);
1035  }
1036 
1037  CDbMappingComponent *CDbMappingComponent::CRemovedModelsMenu::mappingComponent() const
1038  {
1039  return qobject_cast<CDbMappingComponent *>(this->parent());
1040  }
1041 
1042  CDbMappingComponent *CDbMappingComponent::CMergeWithVPilotMenu::mappingComponent() const
1043  {
1044  return qobject_cast<CDbMappingComponent *>(this->parent());
1045  }
1046 } // namespace swift::gui::components
CWebDataServices * getWebDataServices() const
Get the web data services.
swift::misc::aviation::CAircraftIcaoCode smartAircraftIcaoSelector(const swift::misc::aviation::CAircraftIcaoCode &icao) const
Use an ICAO object to select the best complete ICAO object from DB for it.
int getModelsCount() const
Models count.
swift::misc::aviation::CLivery getStdLiveryForAirlineCode(const swift::misc::aviation::CAirlineIcaoCode &icao) const
Standard livery for airline code.
swift::misc::simulation::CDistributor smartDistributorSelector(const swift::misc::simulation::CDistributor &distributor) const
Use distributor object to select the best complete distributor from DB.
swift::misc::aviation::CLivery smartLiverySelector(const swift::misc::aviation::CLivery &livery) const
Use a livery as template and select the best complete livery from DB for it.
QStringList getModelStrings(bool sort=false) const
Model strings.
static QString replaceTabCountValue(const QString &oldName, int count)
Replace count in name such as "stations (4)".
Definition: guiutility.cpp:522
void showOverlayMessagesOrHTMLMessage(const swift::misc::CStatusMessageList &messages, bool appendOldMessages=false, std::chrono::milliseconds timeout=std::chrono::milliseconds(0))
Show multiple messages or a single message (HTML)
Using this class provides a QFrame with the overlay functionality already integrated.
static const QKeySequence & keyAddToModelSet()
Add to model set.
Definition: shortcut.cpp:18
static QString toParenthesisString(const QKeySequence &sequence)
As string for menus etc. Looks like "(CTRL + R)".
Definition: shortcut.cpp:97
Allows to automatically update models if found in own model set, but already existing for a sibling s...
bool hasSelectedModelsToStash() const
Any models which can be stashed?
TabIndex currentTabIndex() const
Current tab index.
void setOwnModelSetSimulator(const swift::misc::simulation::CSimulatorInfo &simulator)
Set simulator for own models.
void replaceStashedModelsUnvalidated(const swift::misc::simulation::CAircraftModelList &models) const
Replace models, no validation.
void tabIndexChanged(int index)
Tab index has been changed.
swift::misc::CStatusMessageList stashModels(const swift::misc::simulation::CAircraftModelList &models)
Stash given models (includes validation and consolidation with DB data)
swift::misc::simulation::CAircraftModelList getSelectedModelsToStash() const
Models to be stashed from currently activated tab (table view)
void maxTableView()
Max. space for table view.
swift::misc::simulation::CAircraftModelList getOwnSelectedModels() const
Own selected models.
swift::misc::CStatusMessage addToOwnModelSet(const swift::misc::simulation::CAircraftModelList &models, const swift::misc::simulation::CSimulatorInfo &simulator)
Add to model set.
bool canAddToModelSetTab() const
Tab can contribute to model set.
int getOwnModelsCount() const
Number of own models.
swift::misc::simulation::CSimulatorInfo getOwnModelsSimulator() const
Own models for simulator.
void requestUpdatedData(swift::misc::network::CEntityFlags::Entity entities)
Request latest (incremental) data from backend.
swift::misc::simulation::CAircraftModelList getOwnModelSet() const
Own model set.
void resizeForMapping()
Resize so that mapping is easier.
swift::misc::CStatusMessageList validateCurrentModel(bool withNestedForms) const
Validate, empty list means OK.
void filterByAircraftIcao(const swift::misc::aviation::CAircraftIcaoCode &icao)
Request to filter by aircraft ICAO.
swift::misc::simulation::CAircraftModelList getOwnModels() const
Own cached models.
views::CAircraftModelView * currentModelView() const
Current model view.
swift::misc::simulation::CAircraftModel getEditorAircraftModel() const
Unvalidated consolidated aircraft model from the editor subparts (icao, distributor)
QString getOwnModelsInfoString() const
Info string about models in cache.
void setOwnModelsSimulator(const swift::misc::simulation::CSimulatorInfo &simulator)
Set simulator for own models.
void modifyModelDialog()
Open model modify dialog.
views::CAircraftModelView * modelView(TabIndex tab) const
Current model view.
swift::misc::simulation::CAircraftModel getOwnModelForModelString(const QString &modelString) const
Own (installed) model for given model string.
swift::misc::simulation::CAircraftModelList getOwnCachedModels(const swift::misc::simulation::CSimulatorInfo &simulator) const
Own cached models.
void filterByDistributor(const swift::misc::simulation::CDistributor &distributor)
Request to filter by distributor.
swift::misc::CStatusMessage stashModel(const swift::misc::simulation::CAircraftModel &model, bool replace=false)
Stash given model (includes validation and consolidation with DB data)
void filterByLivery(const swift::misc::aviation::CLivery &livery)
Request to filter by livery.
const swift::misc::simulation::CAircraftModelList & getStashedModels() const
Any stashed models?
bool hasStashedModels() const
Any stashed models?
QString getOwnModelsInfoStringFsFamily() const
Info string without XPlane (FSX,P3D, FS9)
QStringList getStashedModelStrings() const
Stashed model strings.
swift::misc::simulation::CAircraftModel consolidateModel(const swift::misc::simulation::CAircraftModel &model) const
Consolidate with other available data.
void resizeForSelect()
Resize so that selection is easy (larger table view)
void ownModelsSimulatorChanged(const swift::misc::simulation::CSimulatorInfo &simulator)
Own models simulator has changed.
void stashedModelsChanged()
Stashed models have been changed.
void modelsSuccessfullyPublished(const swift::misc::simulation::CAircraftModelList &publishedModels, bool directWrite)
Models succesfully published.
void tabIndexChanged(int index)
Tab (where this component is embedded) has been changed.
Bunch of CMenuAction objects.
Definition: menuaction.h:384
CMenuAction addMenuStash()
Stash menu.
Definition: menuaction.cpp:434
CMenuAction addAction(const CMenuAction &menuAction)
Add menu action.
Definition: menuaction.cpp:210
CMenuAction addMenuStashEditor()
Stash menu.
Definition: menuaction.cpp:443
CMenuAction addMenu(const CMenuAction &subdirAction)
Add a sub menu.
Definition: menuaction.cpp:177
CMenuAction addMenuModelSet()
Model set menu.
Definition: menuaction.cpp:461
Open the simulator file (e.g. aircraft.cfg) in the standard text editor.
Interface to implement a custom menu.
Definition: menudelegate.h:21
int removeModelsWithModelString(const QStringList &modelStrings, Qt::CaseSensitivity sensitivity=Qt::CaseInsensitive)
Remove models with model strings.
bool hasSelectedModelsToStash() const
Has any models to stash and it is allowed to stash.
virtual bool isEmpty() const
Empty?
Definition: viewbase.cpp:400
virtual ContainerType selectedObjects() const
Selected objects.
Definition: viewbase.cpp:240
const ObjectType & at(const QModelIndex &index) const
Value object at.
Definition: viewbase.cpp:193
bool hasSelection() const
Selection (selected rows)
T get() const
Get a copy of the current value.
Definition: valuecache.h:408
void inputSignal()
Received input signal, or manually trigger.
Class for emitting a log message.
Definition: logmessage.h:27
Derived & warning(const char16_t(&format)[N])
Set the severity to warning, providing a format string.
Derived & error(const char16_t(&format)[N])
Set the severity to error, providing a format string.
Derived & info(const char16_t(&format)[N])
Set the severity to info, providing a format string.
Specialized value object compliant map for variants, based on indexes.
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.
Status messages, e.g. from Core -> GUI.
bool hasWarningOrErrorMessages() const
Warning or error messages.
bool hasErrorMessages() const
Error messages.
Value object for ICAO classification.
Value object for ICAO classification.
Value object encapsulating information about an airpot.
Definition: livery.h:29
Aircraft model (used by another pilot, my models on disk)
Definition: aircraftmodel.h:71
void setLivery(const aviation::CLivery &livery)
Livery.
void setDistributor(const CDistributor &distributor)
Set distributor.
bool setAircraftIcaoCode(const aviation::CAircraftIcaoCode &aircraftIcaoCode)
Set aircraft ICAO code.
Value object encapsulating a list of aircraft models.
int replaceOrAddModelsWithString(const CAircraftModelList &addOrReplaceList, Qt::CaseSensitivity sensitivity)
Replace or add based on model string.
Value object encapsulating information of software distributor.
Definition: distributor.h:33
Simple hardcoded info about the corresponding simulator.
Definition: simulatorinfo.h:41
bool isSingleSimulator() const
Single simulator selected.
bool isMicrosoftOrPrepare3DSimulator() const
Microsoft Simulator or P3D?
swift::misc::simulation::CAircraftModelList getAsModels()
Get as models.
swift::misc::simulation::CAircraftModelList getAsModelsFromCache() const
Get as models from cache.
swift::misc::CWorker * readInBackground(bool convertToModels)
Load data in background thread.
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
Models to be used with views, mainly QTableView.
Views, mainly QTableView.
GUI related classes.
Free functions in swift::misc.