7 #include <QDesktopServices>
13 #include <QPushButton>
15 #include <QStringBuilder>
20 #include "ui_dbownmodelsetcomponent.h"
29 #include "gui/menus/aircraftmodelmenus.h"
30 #include "gui/menus/menuaction.h"
45 using namespace swift::misc::simulation;
47 using namespace swift::gui::menus;
52 CDbOwnModelSetComponent::CDbOwnModelSetComponent(QWidget *parent)
56 ui->tvp_OwnModelSet->setAircraftModelMode(CAircraftModelListModel::OwnModelSet);
57 ui->tvp_OwnModelSet->menuAddItems(CAircraftModelView::MenuStashing);
58 ui->tvp_OwnModelSet->menuRemoveItems(CAircraftModelView::MenuDisplayAutomaticallyAndRefresh |
59 CAircraftModelView::MenuBackend);
60 ui->tvp_OwnModelSet->menuAddItems(CAircraftModelView::MenuRemoveSelectedRows | CAircraftModelView::MenuClear |
61 CAircraftModelView::MenuMaterializeFilter);
62 ui->tvp_OwnModelSet->addFilterDialog();
63 ui->tvp_OwnModelSet->setCustomMenu(
new CLoadModelSetMenu(
this));
66 ui->tvp_OwnModelSet->menuAddItems(CAircraftModelView::MenuLoadAndSave | CAircraftModelView::MenuRefresh |
67 CAircraftModelView::MenuOrderable);
68 ui->tvp_OwnModelSet->setSorting(CAircraftModel::IndexOrderString);
69 ui->tvp_OwnModelSet->initAsOrderable();
74 ui->comp_SimulatorSelector->setRememberSelectionAndSetToLastSelection();
75 const CSimulatorInfo simulator = ui->comp_SimulatorSelector->getValue();
76 ui->le_Simulator->setText(simulator.
toQString(
true));
79 ui->pb_SaveAsSetForSimulator->setStyleSheet(
"padding-left: 3px; padding-right: 3px;");
81 connect(ui->pb_CreateNewSet, &QPushButton::clicked,
this, &CDbOwnModelSetComponent::buttonClicked,
82 Qt::QueuedConnection);
83 connect(ui->pb_LoadExistingSet, &QPushButton::clicked,
this, &CDbOwnModelSetComponent::buttonClicked,
84 Qt::QueuedConnection);
85 connect(ui->pb_ShowStatistics, &QPushButton::clicked,
this, &CDbOwnModelSetComponent::buttonClicked,
86 Qt::QueuedConnection);
87 connect(ui->pb_FirstSet, &QPushButton::clicked,
this, &CDbOwnModelSetComponent::buttonClicked,
88 Qt::QueuedConnection);
89 connect(ui->pb_Clear, &QPushButton::clicked,
this, &CDbOwnModelSetComponent::buttonClicked,
90 Qt::QueuedConnection);
91 connect(ui->pb_CopyFromAnotherSwift, &QPushButton::clicked,
this, &CDbOwnModelSetComponent::buttonClicked,
92 Qt::QueuedConnection);
93 connect(ui->pb_SaveAsSetForSimulator, &QPushButton::clicked,
this, &CDbOwnModelSetComponent::buttonClicked,
94 Qt::QueuedConnection);
97 Qt::QueuedConnection);
98 connect(ui->tvp_OwnModelSet, &CAircraftModelView::modelDataChanged,
this,
99 &CDbOwnModelSetComponent::onRowCountChanged, Qt::QueuedConnection);
100 connect(ui->tvp_OwnModelSet, &CAircraftModelView::modelChanged,
this,
101 &CDbOwnModelSetComponent::viewModelChanged, Qt::QueuedConnection);
102 connect(ui->tvp_OwnModelSet, &CAircraftModelView::requestUpdate,
this,
103 &CDbOwnModelSetComponent::updateViewToCurrentModels, Qt::QueuedConnection);
104 connect(ui->tvp_OwnModelSet, &CAircraftModelView::jsonModelsForSimulatorLoaded,
this,
105 &CDbOwnModelSetComponent::onJsonDataLoaded, Qt::QueuedConnection);
119 using namespace std::chrono_literals;
125 ui->tvp_OwnModelSet->clear();
131 const int diff = models.
size() - cleanModelList.
size();
140 ui->tvp_OwnModelSet->updateContainerMaybeAsync(cleanModelList);
145 using namespace std::chrono_literals;
148 if (models.
isEmpty()) {
return 0; }
151 const int diff = models.
size() - cleanModelList.
size();
159 if (cleanModelList.
isEmpty()) {
return 0; }
163 ui->tvp_OwnModelSet->updateContainerMaybeAsync(updatedModels);
169 return ui->tvp_OwnModelSet->container();
183 if (models.
isEmpty()) {
return CStatusMessage(
this, CStatusMessage::SeverityInfo, u
"No data",
true); }
193 u
"Cannot add data for " % simulator.
toQString(
true) % u
" to " %
194 this->getModelSetSimulator().toQString(
true),
198 const bool allowExcludedModels = m_modelSettings.
get().getAllowExcludedModels();
200 int d =
updateModels.replaceOrAddModelsWithString(models, Qt::CaseInsensitive);
203 if (!allowExcludedModels) {
updateModels.removeIfExcluded(); }
205 ui->tvp_OwnModelSet->updateContainerMaybeAsync(
updateModels);
207 u
"Modified " % QString::number(d) % u
" entries in model set " %
211 else {
return CStatusMessage(
this, CStatusMessage::SeverityInfo, u
"No data modified in model set",
true); }
220 &CDbOwnModelSetComponent::tabIndexChanged);
226 ui->pb_FirstSet->setEnabled(firstSet);
227 ui->pb_CreateNewSet->setEnabled(newSet);
230 void CDbOwnModelSetComponent::tabIndexChanged(
int index) { Q_UNUSED(index) }
232 void CDbOwnModelSetComponent::buttonClicked()
234 using namespace std::chrono_literals;
236 const QObject *sender = QObject::sender();
237 if (!sender) {
return; }
239 if (sender == ui->pb_CreateNewSet)
241 this->createNewSet();
245 if (sender == ui->pb_LoadExistingSet)
247 ui->tvp_OwnModelSet->showFileLoadDialog();
251 if (sender == ui->pb_SaveAsSetForSimulator)
254 if (!ownModelSet.isEmpty())
258 CLogMessage::preformatted(m);
261 const QString msg = QStringLiteral(
"Saved model set for '%1'").arg(sim.
toQString(
true));
266 ui->tvp_OwnModelSet->showOverlayHTMLMessage(msg, 5s);
277 if (sender == ui->pb_ShowStatistics)
279 this->showModelStatistics();
283 if (sender == ui->pb_FirstSet)
289 if (sender == ui->pb_CopyFromAnotherSwift)
291 this->copyFromAnotherSwift();
295 if (sender == ui->pb_Clear)
297 ui->tvp_OwnModelSet->clear();
302 void CDbOwnModelSetComponent::onRowCountChanged(
int count,
bool withFilter)
307 const int realUnfilteredCount = ui->tvp_OwnModelSet->container().size();
309 ui->pb_SaveAsSetForSimulator->setEnabled(canSave);
313 ui->pb_SaveAsSetForSimulator->setText(
316 else { ui->pb_SaveAsSetForSimulator->setText(
"save"); }
319 void CDbOwnModelSetComponent::onJsonDataLoaded(
const CSimulatorInfo &simulator)
324 void CDbOwnModelSetComponent::distributorPreferencesChanged()
328 if (simuulator.
isSingleSimulator()) { this->updateDistributorOrder(simuulator); }
331 void CDbOwnModelSetComponent::reduceModels()
333 if (!m_reduceModelsDialog) { m_reduceModelsDialog.reset(
new CDbReduceModelDuplicates(
this)); }
337 m_reduceModelsDialog->setModels(models, simulator);
338 const QDialog::DialogCode ret =
static_cast<QDialog::DialogCode
>(m_reduceModelsDialog->exec());
339 if (ret != QDialog::Accepted) {
return; }
341 const CSimulatorInfo removeSimulator = m_reduceModelsDialog->getSimulator();
342 if (removeModels.
isEmpty()) {
return; }
348 void CDbOwnModelSetComponent::removeExcludedModels()
353 if (r < 1) {
return; }
357 void CDbOwnModelSetComponent::removeNonDBModels()
362 if (r < 1) {
return; }
366 void CDbOwnModelSetComponent::viewModelChanged()
368 const bool hasData = ui->tvp_OwnModelSet->rowCount() > 0;
369 ui->pb_SaveAsSetForSimulator->setEnabled(hasData);
372 void CDbOwnModelSetComponent::setSaveFileName(
const CSimulatorInfo &simulator)
375 const QString name(
"modelset" + simulator.
toQString(
true));
376 ui->tvp_OwnModelSet->setSaveFileName(name);
379 void CDbOwnModelSetComponent::updateViewToCurrentModels()
382 ui->tvp_OwnModelSet->updateContainerMaybeAsync(models);
385 void CDbOwnModelSetComponent::createNewSet()
404 mc->setOwnModelsSimulator(simulator);
405 if (!m_modelSetFormDialog)
407 m_modelSetFormDialog.reset(
new CDbOwnModelSetFormDialog(
this));
411 if (mc->getOwnModelsCount() > 0)
413 m_modelSetFormDialog->setModal(
true);
414 m_modelSetFormDialog->reloadData();
415 const QDialog::DialogCode rc =
static_cast<QDialog::DialogCode
>(m_modelSetFormDialog->exec());
416 if (rc == QDialog::Accepted)
418 this->
setModelSet(m_modelSetFormDialog->getModelSet(), m_modelSetFormDialog->getSimulatorInfo());
424 mc->showOverlayMessage(m);
428 void CDbOwnModelSetComponent::firstSet()
430 if (!m_firstModelSetDialog) { m_firstModelSetDialog.reset(
new CFirstModelSetDialog(
this)); }
431 m_firstModelSetDialog->show();
434 void CDbOwnModelSetComponent::copyFromAnotherSwift()
436 if (!m_copyFromAnotherSwiftDialog)
438 m_copyFromAnotherSwiftDialog.reset(
new CCopyModelsFromOtherSwiftVersionsDialog(
this));
440 m_copyFromAnotherSwiftDialog->show();
445 if (m_simulator == simulator) {
return; }
449 m_simulator = simulator;
450 ui->comp_SimulatorSelector->setValue(simulator);
451 ui->tvp_OwnModelSet->setCorrespondingSimulator(simulator,
453 ui->le_Simulator->setText(simulator.
toQString(
true));
455 this->updateViewToCurrentModels();
460 ui->comp_SimulatorSelector->setMode(mode);
467 QPointer<CDbOwnModelSetComponent> myself(
this);
470 if (!myself) {
return; }
475 void CDbOwnModelSetComponent::showModelStatistics()
479 m_modelStatisticsDialog->analyzeModels(set);
480 m_modelStatisticsDialog->show();
483 void CDbOwnModelSetComponent::updateDistributorOrder(
const CSimulatorInfo &simulator)
486 if (modelSet.
isEmpty()) {
return; }
489 if (distributors.
isEmpty()) {
return; }
495 if (simulator == currentSimulator) { ui->tvp_OwnModelSet->updateContainerAsync(modelSet); }
500 void CDbOwnModelSetComponent::CLoadModelSetMenu::customMenu(
CMenuActions &menuActions)
508 Q_ASSERT_X(ownModelSetComp, Q_FUNC_INFO,
"Cannot access parent");
509 if (m_setActions.isEmpty())
513 QAction *a =
new QAction(CIcons::appModels16(),
"FSX models",
this);
514 connect(a, &QAction::triggered, ownModelSetComp, [ownModelSetComp](
bool checked) {
516 ownModelSetComp->setSimulator(
CSimulatorInfo(CSimulatorInfo::FSX));
518 m_setActions.append(a);
520 a =
new QAction(CIcons::appModels16(),
"New set FSX models",
this);
521 connect(a, &QAction::triggered, ownModelSetComp, [ownModelSetComp](
bool checked) {
525 m_setNewActions.append(a);
529 QAction *a =
new QAction(CIcons::appModels16(),
"P3D models",
this);
530 connect(a, &QAction::triggered, ownModelSetComp, [ownModelSetComp](
bool checked) {
532 ownModelSetComp->setSimulator(
CSimulatorInfo(CSimulatorInfo::P3D));
534 m_setActions.append(a);
536 a =
new QAction(CIcons::appModels16(),
"New set P3D models",
this);
537 connect(a, &QAction::triggered, ownModelSetComp, [ownModelSetComp](
bool checked) {
541 m_setNewActions.append(a);
545 QAction *a =
new QAction(CIcons::appModels16(),
"FS9 models",
this);
546 connect(a, &QAction::triggered, ownModelSetComp, [ownModelSetComp](
bool checked) {
548 ownModelSetComp->setSimulator(
CSimulatorInfo(CSimulatorInfo::FS9));
550 m_setActions.append(a);
552 a =
new QAction(CIcons::appModels16(),
"New set FS9 models",
this);
553 connect(a, &QAction::triggered, ownModelSetComp, [ownModelSetComp](
bool checked) {
557 m_setNewActions.append(a);
561 QAction *a =
new QAction(CIcons::appModels16(),
"XPlane models",
this);
562 connect(a, &QAction::triggered, ownModelSetComp, [ownModelSetComp](
bool checked) {
564 ownModelSetComp->setSimulator(
CSimulatorInfo(CSimulatorInfo::XPLANE));
566 m_setActions.append(a);
568 a =
new QAction(CIcons::appModels16(),
"New set XPlane models",
this);
569 connect(a, &QAction::triggered, ownModelSetComp, [ownModelSetComp](
bool checked) {
573 m_setNewActions.append(a);
577 QAction *a =
new QAction(CIcons::appModels16(),
"FG models",
this);
578 connect(a, &QAction::triggered, ownModelSetComp, [ownModelSetComp](
bool checked) {
580 ownModelSetComp->setSimulator(
CSimulatorInfo(CSimulatorInfo::FG));
582 m_setActions.append(a);
584 a =
new QAction(CIcons::appModels16(),
"New set FG models",
this);
585 connect(a, &QAction::triggered, ownModelSetComp, [ownModelSetComp](
bool checked) {
589 m_setNewActions.append(a);
593 QAction *a =
new QAction(CIcons::appModels16(),
"MSFS models",
this);
594 connect(a, &QAction::triggered, ownModelSetComp, [ownModelSetComp](
bool checked) {
596 ownModelSetComp->setSimulator(
CSimulatorInfo(CSimulatorInfo::MSFS));
598 m_setActions.append(a);
600 a =
new QAction(CIcons::appModels16(),
"New set MSFS models",
this);
601 connect(a, &QAction::triggered, ownModelSetComp, [ownModelSetComp](
bool checked) {
605 m_setNewActions.append(a);
609 QAction *a =
new QAction(CIcons::appModels16(),
"MSFS2024 models",
this);
610 connect(a, &QAction::triggered, ownModelSetComp, [ownModelSetComp](
bool checked) {
612 ownModelSetComp->setSimulator(
CSimulatorInfo(CSimulatorInfo::MSFS2024));
614 m_setActions.append(a);
616 a =
new QAction(CIcons::appModels16(),
"New set MSFS2024 models",
this);
617 connect(a, &QAction::triggered, ownModelSetComp, [ownModelSetComp](
bool checked) {
621 m_setNewActions.append(a);
624 QAction *a =
new QAction(CIcons::appDistributors16(),
"Apply distributor preferences",
this);
625 connect(a, &QAction::triggered, ownModelSetComp,
626 &CDbOwnModelSetComponent::distributorPreferencesChanged, Qt::QueuedConnection);
627 m_setActions.append(a);
629 a =
new QAction(CIcons::delete16(),
"Reduce models (remove duplicates)",
this);
630 connect(a, &QAction::triggered, ownModelSetComp, &CDbOwnModelSetComponent::reduceModels,
631 Qt::QueuedConnection);
632 m_setActions.append(a);
634 a =
new QAction(CIcons::delete16(),
"Remove excluded models",
this);
635 connect(a, &QAction::triggered, ownModelSetComp, &CDbOwnModelSetComponent::removeExcludedModels,
636 Qt::QueuedConnection);
637 m_setActions.append(a);
639 a =
new QAction(CIcons::delete16(),
"Remove non DB models",
this);
640 connect(a, &QAction::triggered, ownModelSetComp, &CDbOwnModelSetComponent::removeNonDBModels,
641 Qt::QueuedConnection);
642 m_setActions.append(a);
645 menuActions.
addActions(m_setActions, CMenuAction::pathModelSet());
646 menuActions.
addActions(m_setNewActions, CMenuAction::pathModelSetNew());
648 this->nestedCustomMenu(menuActions);
SWIFT_CORE_EXPORT swift::core::CApplication * sApp
Single instance of application object.
bool isShuttingDown() const
Is application shutting down?
static QDialog * findParentDialog(QWidget *widget)
Find parent dialog if there is any, otherwise null.
Allows subcomponents to gain access to model component.
bool showMappingComponentOverlayMessage(const swift::misc::CStatusMessage &message, std::chrono::milliseconds timeout=std::chrono::milliseconds(0))
Overlay messages.
bool showMappingComponentOverlayHtmlMessage(const swift::misc::CStatusMessage &message, std::chrono::milliseconds timeout=std::chrono::milliseconds(0))
Overlay messages.
CDbMappingComponent * getMappingComponent() const
Get the mapping component.
virtual void setMappingComponent(CDbMappingComponent *component)
Set the corresponding component.
void tabIndexChanged(int index)
Tab index has been changed.
Handling of the own model set.
const swift::misc::simulation::CAircraftModelList & getModelSetFromView() const
Current model set for simulator CDbOwnModelSetComponent::getModelSetSimulator.
swift::misc::simulation::CAircraftModelList getModelSet() const
Cached models for current simulator.
int getModelSetCountFromView() const
Current sount of model set for simulator CDbOwnModelSetComponent::getModelSetSimulator.
int replaceOrAddModelSet(const swift::misc::simulation::CAircraftModelList &models, const swift::misc::simulation::CSimulatorInfo &simulator)
Replace or add models provided for a given simulator.
void setSimulator(const swift::misc::simulation::CSimulatorInfo &simulator)
Simulator.
swift::misc::CStatusMessage addToModelSet(const swift::misc::simulation::CAircraftModelList &models, const swift::misc::simulation::CSimulatorInfo &simulator)
Add to model set.
virtual ~CDbOwnModelSetComponent()
Destructor.
views::CAircraftModelView * view() const
Corresponding view.
void setSimulatorSelectorMode(CSimulatorSelector::Mode mode)
How to display.
swift::misc::simulation::CSimulatorInfo getModelSetSimulator() const
Model set is for simulator.
virtual void setMappingComponent(CDbMappingComponent *component)
Set the corresponding component.
void triggerSetSimulatorDeferred(const swift::misc::simulation::CSimulatorInfo &simulator)
Deferred init of simulator.
CDbOwnModelSetComponent(QWidget *parent=nullptr)
Constructor.
void setModelSet(const swift::misc::simulation::CAircraftModelList &models, const swift::misc::simulation::CSimulatorInfo &simulator)
Set the model set for a given simulator.
virtual swift::misc::simulation::CSimulatorInfo getSelectedSimulator() const
Simulator.
virtual int updateModels(const swift::misc::simulation::CAircraftModelList &models)
Update models.
void enableButtons(bool firstSet, bool newSet)
Enable buttons.
void changed(const swift::misc::simulation::CSimulatorInfo &simulator)
Value has been changed.
const T & getThreadLocal() const
Read the current value.
T get() const
Get a copy of the current value.
Class for emitting a log message.
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.
size_type size() const
Returns number of elements in the sequence.
bool isEmpty() const
Synonym for empty.
Streamable status message, e.g.
bool isSuccess() const
Operation considered successful.
void resetOrder(int offset=0)
Set order member to current order.
int removeObjectsWithoutDbKey()
Remove objects without key.
QString toQString(bool i18n=false) const
Cast as QString.
Aircraft model (used by another pilot, my models on disk)
Value object encapsulating a list of aircraft models.
QStringList getModelStringList(bool sort=true) const
Model strings.
int replaceOrAddModelsWithString(const CAircraftModelList &addOrReplaceList, Qt::CaseSensitivity sensitivity)
Replace or add based on model string.
int removeIfExcluded()
Remove if excluded CAircraftModel::Exclude.
int removeModelsWithString(const CAircraftModelList &models, Qt::CaseSensitivity sensitivity)
Remove those models with given model strings.
CAircraftModelList matchesSimulator(const CSimulatorInfo &simulator) const
Find for given simulator.
int updateDistributorOrder(const CDistributorList &distributors)
From given CDistributorList update the model`s distributor order.
Value object encapsulating a list of distributors.
Preferences for distributors.
const CSimulatorInfo & getLastUpdatedSimulator() const
Last updated simulator.
const CDistributorList & getDistributors(const CSimulatorInfo &simulator) const
Get distributors.
Simple hardcoded info about the corresponding simulator.
bool isMSFS2024() const
MSFS2024?
bool isSingleSimulator() const
Single simulator selected.
bool isNoSimulator() const
No simulator?
bool isUnspecified() const
Unspecified simulator.
bool isXPlane() const
XPlane.
void admitCache(const CSimulatorInfo &simulator)
Look like IMultiSimulatorModelCaches interface.
CAircraftModelList getCachedModels(const CSimulatorInfo &simulator) const
Look like IMultiSimulatorModelCaches interface.
CStatusMessage setCachedModels(const CAircraftModelList &models, const CSimulatorInfo &simulator)
Look like IMultiSimulatorModelCaches interface.
void synchronizeCache(const CSimulatorInfo &simulator)
Look like IMultiSimulatorModelCaches interface.
QString getSimulatorDirectoryOrDefault(const CSimulatorInfo &simulator) const
Simulator directory or default model path per simulator.
High level reusable GUI components.
Models to be used with views, mainly QTableView.
Views, mainly QTableView.
Free functions in swift::misc.
auto singleShot(int msec, QObject *target, F &&task)
Starts a single-shot timer which will call a task in the thread of the given object when it times out...