Ref T660, utility functions

* check if model is in path
* addAsValidOrInvalidModel
* set corresponding simulator for validation
* display validation of empty model set
This commit is contained in:
Klaus Basan
2019-06-08 21:41:22 +02:00
committed by Mat Sutcliffe
parent d59e1c3332
commit f3ec7a8a68
12 changed files with 99 additions and 48 deletions

View File

@@ -70,7 +70,7 @@ namespace BlackGui
ui->tvp_OwnModelSet->menuAddItems(CAircraftModelView::MenuLoadAndSave | CAircraftModelView::MenuRefresh | CAircraftModelView::MenuOrderable); ui->tvp_OwnModelSet->menuAddItems(CAircraftModelView::MenuLoadAndSave | CAircraftModelView::MenuRefresh | CAircraftModelView::MenuOrderable);
ui->tvp_OwnModelSet->setSorting(CAircraftModel::IndexOrderString); ui->tvp_OwnModelSet->setSorting(CAircraftModel::IndexOrderString);
ui->tvp_OwnModelSet->initAsOrderable(); ui->tvp_OwnModelSet->initAsOrderable();
ui->tvp_OwnModelSet->setSimulatorForLoading(ui->comp_SimulatorSelector->getValue()); ui->tvp_OwnModelSet->setCorrespondingSimulator(ui->comp_SimulatorSelector->getValue());
ui->comp_SimulatorSelector->setMode(CSimulatorSelector::RadioButtons); ui->comp_SimulatorSelector->setMode(CSimulatorSelector::RadioButtons);
ui->comp_SimulatorSelector->setRememberSelectionAndSetToLastSelection(); ui->comp_SimulatorSelector->setRememberSelectionAndSetToLastSelection();
const CSimulatorInfo simulator = ui->comp_SimulatorSelector->getValue(); const CSimulatorInfo simulator = ui->comp_SimulatorSelector->getValue();
@@ -428,7 +428,7 @@ namespace BlackGui
m_simulator = simulator; m_simulator = simulator;
ui->comp_SimulatorSelector->setValue(simulator); ui->comp_SimulatorSelector->setValue(simulator);
ui->tvp_OwnModelSet->setSimulatorForLoading(simulator); ui->tvp_OwnModelSet->setCorrespondingSimulator(simulator);
ui->le_Simulator->setText(simulator.toQString(true)); ui->le_Simulator->setText(simulator.toQString(true));
this->synchronizeCache(simulator); this->synchronizeCache(simulator);
this->updateViewToCurrentModels(); this->updateViewToCurrentModels();

View File

@@ -36,6 +36,12 @@ namespace BlackGui
CAircraftModelValidationDialog::~CAircraftModelValidationDialog() CAircraftModelValidationDialog::~CAircraftModelValidationDialog()
{ } { }
void CAircraftModelValidationDialog::setModels(const CAircraftModelList &models, const CSimulatorInfo &simulator)
{
m_models = models;
m_simulator = simulator;
}
void CAircraftModelValidationDialog::triggerValidation(int delayMs) void CAircraftModelValidationDialog::triggerValidation(int delayMs)
{ {
QPointer<CAircraftModelValidationDialog> myself(this); QPointer<CAircraftModelValidationDialog> myself(this);
@@ -57,7 +63,7 @@ namespace BlackGui
const bool ignoreEmpty = false; const bool ignoreEmpty = false;
const int maxFailedFiles = 25; const int maxFailedFiles = 25;
bool wasStopped = false; bool wasStopped = false;
const CStatusMessageList msgs = CAircraftModelUtilities::validateModelFiles(m_models, valid, invalid, ignoreEmpty, maxFailedFiles, wasStopped, ""); const CStatusMessageList msgs = CAircraftModelUtilities::validateModelFiles(m_simulator, m_models, valid, invalid, ignoreEmpty, maxFailedFiles, wasStopped, "");
ui->comp_StatusMessage->clear(); ui->comp_StatusMessage->clear();
ui->comp_StatusMessage->setNoSorting(); // we use the pre-sorted list ui->comp_StatusMessage->setNoSorting(); // we use the pre-sorted list
ui->comp_StatusMessage->appendStatusMessagesToList(msgs); ui->comp_StatusMessage->appendStatusMessagesToList(msgs);

View File

@@ -33,10 +33,12 @@ namespace BlackGui
explicit CAircraftModelValidationDialog(QWidget *parent = nullptr); explicit CAircraftModelValidationDialog(QWidget *parent = nullptr);
//! Destructor //! Destructor
virtual ~CAircraftModelValidationDialog(); virtual ~CAircraftModelValidationDialog() override;
//! Models //! Models
void setModels(const BlackMisc::Simulation::CAircraftModelList &models) { m_models = models; } void setModels(
const BlackMisc::Simulation::CAircraftModelList &models,
const BlackMisc::Simulation::CSimulatorInfo &simulator);
//! Trigger a validation //! Trigger a validation
void triggerValidation(int delayMs = 2500); void triggerValidation(int delayMs = 2500);
@@ -47,6 +49,7 @@ namespace BlackGui
QScopedPointer<Ui::CAircraftModelValidationDialog> ui; QScopedPointer<Ui::CAircraftModelValidationDialog> ui;
BlackMisc::Simulation::CAircraftModelList m_models; BlackMisc::Simulation::CAircraftModelList m_models;
BlackMisc::Simulation::CSimulatorInfo m_simulator { BlackMisc::Simulation::CSimulatorInfo::None };
}; };
} // ns } // ns
} // ns } // ns

View File

@@ -322,7 +322,7 @@ namespace BlackGui
QDialog *parentDialog = CGuiUtility::findParentDialog(this); QDialog *parentDialog = CGuiUtility::findParentDialog(this);
if (!(parentDialog && (qobject_cast<CAircraftModelValidationDialog *>(parentDialog)))) if (!(parentDialog && (qobject_cast<CAircraftModelValidationDialog *>(parentDialog))))
{ {
menuActions.addAction(CIcons::disk16(), "Model validation", CMenuAction::pathModel(), { this, &CAircraftModelView::displayModelValidationDialog }); menuActions.addAction(CIcons::disk16(), "Model validation (selected)", CMenuAction::pathModel(), { this, &CAircraftModelView::displayModelValidationDialog });
} }
} }
if (CAircraftModelList::hasInvalidModelFile()) if (CAircraftModelList::hasInvalidModelFile())
@@ -389,22 +389,22 @@ namespace BlackGui
CStatusMessage CAircraftModelView::modifyLoadedJsonData(CAircraftModelList &models) const CStatusMessage CAircraftModelView::modifyLoadedJsonData(CAircraftModelList &models) const
{ {
if (m_loadingRequiresSimulator.isNoSimulator()) { return {}; } if (m_correspondingSimulator.isNoSimulator()) { return {}; }
if (models.isEmpty()) { return CStatusMessage(this, CStatusMessage::SeverityDebug, u"Empty models", true); } if (models.isEmpty()) { return CStatusMessage(this, CStatusMessage::SeverityDebug, u"Empty models", true); }
// multiple sims with same count // multiple sims with same count
const int removed = models.removeIfNotMatchingSimulator(m_loadingRequiresSimulator); const int removed = models.removeIfNotMatchingSimulator(m_correspondingSimulator);
if (removed < 1) { return {}; } if (removed < 1) { return {}; }
return CStatusMessage(this, CStatusMessage::SeverityWarning, u"Reduced by %1 model(s) to only use %2 models", true) << removed << m_loadingRequiresSimulator.toQString(true); return CStatusMessage(this, CStatusMessage::SeverityWarning, u"Reduced by %1 model(s) to only use %2 models", true) << removed << m_correspondingSimulator.toQString(true);
} }
CStatusMessage CAircraftModelView::validateLoadedJsonData(const CAircraftModelList &models) const CStatusMessage CAircraftModelView::validateLoadedJsonData(const CAircraftModelList &models) const
{ {
if (models.isEmpty()) { return COrderableViewWithDbObjects::validateLoadedJsonData(models); } if (models.isEmpty()) { return COrderableViewWithDbObjects::validateLoadedJsonData(models); }
if (m_loadingRequiresSimulator.isNoSimulator()) { return COrderableViewWithDbObjects::validateLoadedJsonData(models); } if (m_correspondingSimulator.isNoSimulator()) { return COrderableViewWithDbObjects::validateLoadedJsonData(models); }
if (models.containsNotMatchingSimulator(m_loadingRequiresSimulator)) if (models.containsNotMatchingSimulator(m_correspondingSimulator))
{ {
return CStatusMessage(this, CStatusMessage::SeverityError, u"Found entry not matching %1 in model data", true) << m_loadingRequiresSimulator.toQString(); return CStatusMessage(this, CStatusMessage::SeverityError, u"Found entry not matching %1 in model data", true) << m_correspondingSimulator.toQString();
} }
return COrderableViewWithDbObjects::validateLoadedJsonData(models); return COrderableViewWithDbObjects::validateLoadedJsonData(models);
} }
@@ -473,7 +473,7 @@ namespace BlackGui
void CAircraftModelView::displayModelValidationDialog() void CAircraftModelView::displayModelValidationDialog()
{ {
if (!m_fileValidationDialog) { m_fileValidationDialog = new CAircraftModelValidationDialog(this); } if (!m_fileValidationDialog) { m_fileValidationDialog = new CAircraftModelValidationDialog(this); }
m_fileValidationDialog->setModels(this->selectedObjects()); m_fileValidationDialog->setModels(this->selectedObjects(), m_correspondingSimulator);
m_fileValidationDialog->triggerValidation(1000); m_fileValidationDialog->triggerValidation(1000);
m_fileValidationDialog->exec(); m_fileValidationDialog->exec();
} }

View File

@@ -112,8 +112,9 @@ namespace BlackGui
//! \copydoc BlackGui::Models::CAircraftModelListModel::highlightModels //! \copydoc BlackGui::Models::CAircraftModelListModel::highlightModels
bool highlightModels() const; bool highlightModels() const;
//! Loading data will be restricted to simulator //! Corresponding simulator
void setSimulatorForLoading(const BlackMisc::Simulation::CSimulatorInfo &simulator) { m_loadingRequiresSimulator = simulator; } //! \remark used for validation or loading data will be restricted to simulator
void setCorrespondingSimulator(const BlackMisc::Simulation::CSimulatorInfo &simulator) { m_correspondingSimulator = simulator; }
//! Enable the validation context menu //! Enable the validation context menu
void setValidationContextMenu(const bool enabled) { m_withValidationContextMenu = enabled; } void setValidationContextMenu(const bool enabled) { m_withValidationContextMenu = enabled; }
@@ -171,9 +172,9 @@ namespace BlackGui
bool m_stashingClearsSelection = true; //!< stashing unselects bool m_stashingClearsSelection = true; //!< stashing unselects
bool m_withValidationContextMenu = true; //!< validation didalog context menu bool m_withValidationContextMenu = true; //!< validation didalog context menu
CAircraftModelStatisticsDialog *m_statisticsDialog = nullptr; CAircraftModelStatisticsDialog *m_statisticsDialog = nullptr;
CAircraftModelValidationDialog *m_fileValidationDialog = nullptr; CAircraftModelValidationDialog *m_fileValidationDialog = nullptr;
BlackMisc::Simulation::CSimulatorInfo m_loadingRequiresSimulator; //!< simulator required when loading BlackMisc::Simulation::CSimulatorInfo m_correspondingSimulator; //!< validation, simulator required when loading
}; };
} // ns } // ns
} // ns } // ns

View File

@@ -766,6 +766,19 @@ namespace BlackMisc
return this->getFileDirectory().absolutePath(); return this->getFileDirectory().absolutePath();
} }
bool CAircraftModel::isInPath(const QString &path, Qt::CaseSensitivity cs) const
{
const QString p(this->getFileDirectoryPath());
if (path.isEmpty() || p.isEmpty()) { return false; }
if (path.startsWith('/'))
{
if (path.endsWith('/')) { return p.contains(path.mid(1, path.length() - 2), cs); }
return p.contains(path.mid(1));
}
if (path.endsWith('/')) { return p.contains(path.left(path.length() - 1), cs); }
return (p.contains(path, cs));
}
bool CAircraftModel::hasExistingIconFile() const bool CAircraftModel::hasExistingIconFile() const
{ {
if (m_iconFile.isEmpty()) { return false; } if (m_iconFile.isEmpty()) { return false; }

View File

@@ -457,6 +457,9 @@ namespace BlackMisc
//! Directory path if any //! Directory path if any
QString getFileDirectoryPath() const; QString getFileDirectoryPath() const;
//! Is the file in the give path
bool isInPath(const QString &path, Qt::CaseSensitivity cs) const;
//! File name //! File name
void setFileName(const QString &fileName) { m_fileName = fileName; } void setFileName(const QString &fileName) { m_fileName = fileName; }

View File

@@ -1325,7 +1325,7 @@ namespace BlackMisc
{ {
CAircraftModelList invalidModels; CAircraftModelList invalidModels;
CAircraftModelList validModels; CAircraftModelList validModels;
return validateForPublishing(validModels, invalidModels); return this->validateForPublishing(validModels, invalidModels);
} }
CStatusMessageList CAircraftModelList::validateForPublishing(CAircraftModelList &validModels, CAircraftModelList &invalidModels) const CStatusMessageList CAircraftModelList::validateForPublishing(CAircraftModelList &validModels, CAircraftModelList &invalidModels) const
@@ -1351,7 +1351,7 @@ namespace BlackMisc
CStatusMessage singleMsg(CStatusMessageList({msgModel, msgDb}).toSingleMessage()); CStatusMessage singleMsg(CStatusMessageList({msgModel, msgDb}).toSingleMessage());
if (!singleMsg.isWarningOrAbove()) if (!singleMsg.isWarningOrAbove())
{ {
validModels.push_back(model); CAircraftModelList::addAsValidOrInvalidModel(model, true, validModels, invalidModels);
continue; continue;
} }
if (model.hasModelString()) if (model.hasModelString())
@@ -1359,7 +1359,7 @@ namespace BlackMisc
singleMsg.prependMessage(model.getModelString() % u": "); singleMsg.prependMessage(model.getModelString() % u": ");
} }
msgs.push_back(singleMsg); msgs.push_back(singleMsg);
invalidModels.push_back(model); CAircraftModelList::addAsValidOrInvalidModel(model, false, validModels, invalidModels);
} }
return msgs; return msgs;
} }
@@ -1375,21 +1375,18 @@ namespace BlackMisc
{ {
const CStatusMessage msg = CStatusMessage(this).validationError(u"No DB distributors for validation"); const CStatusMessage msg = CStatusMessage(this).validationError(u"No DB distributors for validation");
msgs.push_back(msg); msgs.push_back(msg);
invalidModels.push_back(*this); CAircraftModelList::addAsValidOrInvalidModels(*this, false, validModels, invalidModels);
return msgs; return msgs;
} }
for (const CAircraftModel &model : *this) for (const CAircraftModel &model : *this)
{ {
if (model.hasDbDistributor() || model.matchesAnyDbDistributor(distributorsFromDb)) const bool valid = (model.hasDbDistributor() || model.matchesAnyDbDistributor(distributorsFromDb));
{ CAircraftModelList::addAsValidOrInvalidModel(model, valid, validModels, invalidModels);
validModels.push_back(model); if (!valid)
}
else
{ {
const CStatusMessage msg = CStatusMessage(this).validationError(u"No valid distributor for '%1', was '%2'") << model.getModelString() << model.getDistributor().getDbKey(); const CStatusMessage msg = CStatusMessage(this).validationError(u"No valid distributor for '%1', was '%2'") << model.getModelString() << model.getDistributor().getDbKey();
msgs.push_back(msg); msgs.push_back(msg);
invalidModels.push_back(model);
} }
} }
return msgs; return msgs;
@@ -1397,8 +1394,6 @@ namespace BlackMisc
CStatusMessageList CAircraftModelList::validateFiles(CAircraftModelList &validModels, CAircraftModelList &invalidModels, bool ignoreEmptyFileNames, int stopAtFailedFiles, bool &stopped, const QString &rootDirectory, bool alreadySortedByFn) const CStatusMessageList CAircraftModelList::validateFiles(CAircraftModelList &validModels, CAircraftModelList &invalidModels, bool ignoreEmptyFileNames, int stopAtFailedFiles, bool &stopped, const QString &rootDirectory, bool alreadySortedByFn) const
{ {
invalidModels.clear();
validModels.clear();
stopped = false; stopped = false;
CStatusMessageList msgs; CStatusMessageList msgs;
@@ -1466,15 +1461,7 @@ namespace BlackMisc
} }
while (false); while (false);
if (ok) CAircraftModelList::addAsValidOrInvalidModel(model, ok, validModels, invalidModels);
{
validModels.push_back(model);
}
else
{
invalidModels.push_back(model);
}
if (stopAtFailedFiles > 0 && failedFilesCount >= stopAtFailedFiles) if (stopAtFailedFiles > 0 && failedFilesCount >= stopAtFailedFiles)
{ {
stopped = true; stopped = true;
@@ -1717,5 +1704,26 @@ namespace BlackMisc
return fi.exists(); return fi.exists();
} }
void CAircraftModelList::addAsValidOrInvalidModel(const CAircraftModel &model, bool valid, CAircraftModelList &validModels, CAircraftModelList &invalidModels)
{
if (valid)
{
validModels.push_back(model);
invalidModels.removeModelWithString(model.getModelString(), Qt::CaseInsensitive);
}
else
{
invalidModels.push_back(model);
validModels.removeModelWithString(model.getModelString(), Qt::CaseInsensitive);
}
}
void CAircraftModelList::addAsValidOrInvalidModels(const CAircraftModelList &models, bool valid, CAircraftModelList &validModels, CAircraftModelList &invalidModels)
{
for (const CAircraftModel &model : models)
{
CAircraftModelList::addAsValidOrInvalidModel(model, valid, validModels, invalidModels);
}
}
} // namespace } // namespace
} // namespace } // namespace

View File

@@ -512,6 +512,11 @@ namespace BlackMisc
static bool hasInvalidModelFile(); static bool hasInvalidModelFile();
//! @} //! @}
//! Add as valid or invalid model (mutual exclusive) @{
static void addAsValidOrInvalidModel(const CAircraftModel &model, bool valid, CAircraftModelList &validModels, CAircraftModelList &invalidModels);
static void addAsValidOrInvalidModels(const CAircraftModelList &models, bool valid, CAircraftModelList &validModels, CAircraftModelList &invalidModels);
//! @}
//! Newer version //! Newer version
static CAircraftModelList fromDatabaseJsonCaching(const QJsonArray &array, static CAircraftModelList fromDatabaseJsonCaching(const QJsonArray &array,
const Aviation::CAircraftIcaoCodeList &aircraftIcaos = {}, const Aviation::CAircraftIcaoCodeList &aircraftIcaos = {},

View File

@@ -140,7 +140,7 @@ namespace BlackMisc
return ok ? dir.absoluteFilePath(fn) : ""; return ok ? dir.absoluteFilePath(fn) : "";
} }
CStatusMessageList CAircraftModelUtilities::validateModelFiles(const CAircraftModelList &models, CAircraftModelList &validModels, CAircraftModelList &invalidModels, bool ignoreEmpty, int stopAtFailedFiles, bool &stopped, const QString &simulatorDir) CStatusMessageList CAircraftModelUtilities::validateModelFiles(const CSimulatorInfo &simulator, const CAircraftModelList &models, CAircraftModelList &validModels, CAircraftModelList &invalidModels, bool ignoreEmpty, int stopAtFailedFiles, bool &stopped, const QString &simulatorDir)
{ {
// some generic tests // some generic tests
CStatusMessageList msgs; CStatusMessageList msgs;
@@ -164,14 +164,23 @@ namespace BlackMisc
// specific checks for FSX/XPlane/FG // specific checks for FSX/XPlane/FG
CStatusMessageList specificTests; CStatusMessageList specificTests;
if (models.isLikelyFsFamilyModelList()) if (simulator.isMicrosoftOrPrepare3DSimulator() || models.isLikelyFsFamilyModelList())
{ {
const CStatusMessageList specificTests1 = FsCommon::CFsCommonUtil::validateConfigFiles(models, validModels, invalidModels, ignoreEmpty, stopAtFailedFiles, stopped); const CStatusMessageList specificTests1 = FsCommon::CFsCommonUtil::validateConfigFiles(models, validModels, invalidModels, ignoreEmpty, stopAtFailedFiles, stopped);
const CStatusMessageList specificTests2 = FsCommon::CFsCommonUtil::validateP3DSimObjectsPath(models, validModels, invalidModels, ignoreEmpty, stopAtFailedFiles, stopped);
specificTests.push_back(specificTests1); specificTests.push_back(specificTests1);
specificTests.push_back(specificTests2);
if (simulator.isP3D())
{
const CStatusMessageList specificTests2 = FsCommon::CFsCommonUtil::validateP3DSimObjectsPath(models, validModels, invalidModels, ignoreEmpty, stopAtFailedFiles, stopped, simulatorDir);
specificTests.push_back(specificTests2);
}
else if (simulator.isFSX())
{
const CStatusMessageList specificTests2 = FsCommon::CFsCommonUtil::validateFSXSimObjectsPath(models, validModels, invalidModels, ignoreEmpty, stopAtFailedFiles, stopped);
specificTests.push_back(specificTests2);
}
} }
else if (models.isLikelyXPlaneModelList()) else if (simulator.isXPlane() || models.isLikelyXPlaneModelList())
{ {
specificTests = models.validateFiles(validModels, invalidModels, ignoreEmpty, stopAtFailedFiles, stopped, simulatorDir); specificTests = models.validateFiles(validModels, invalidModels, ignoreEmpty, stopAtFailedFiles, stopped, simulatorDir);
} }

View File

@@ -36,7 +36,7 @@ namespace BlackMisc
static QString createIcaoAirlineAircraftHtmlMatrixFile(const BlackMisc::Simulation::CAircraftModelList &models, const QString &tempDir); static QString createIcaoAirlineAircraftHtmlMatrixFile(const BlackMisc::Simulation::CAircraftModelList &models, const QString &tempDir);
//! Validate aircraft.cfg entries //! Validate aircraft.cfg entries
static CStatusMessageList validateModelFiles(const CAircraftModelList &models, CAircraftModelList &validModels, CAircraftModelList &invalidModels, bool ignoreEmpty, int stopAtFailedFiles, bool &stopped, const QString &simulatorDir); static CStatusMessageList validateModelFiles(const CSimulatorInfo &simulator, const CAircraftModelList &models, CAircraftModelList &validModels, CAircraftModelList &invalidModels, bool ignoreEmpty, int stopAtFailedFiles, bool &stopped, const QString &simulatorDir);
}; };
} //namespace } //namespace
} // namespace } // namespace

View File

@@ -130,19 +130,22 @@ namespace BlackMisc
onlyErrorsAndWarnings = setup.onlyShowVerificationWarningsAndErrors(); onlyErrorsAndWarnings = setup.onlyShowVerificationWarningsAndErrors();
const CAircraftModelList models = m_modelSets.getCachedModels(simulator); const CAircraftModelList models = m_modelSets.getCachedModels(simulator);
const qint64 now = QDateTime::currentMSecsSinceEpoch();
validated = true;
if (models.isEmpty()) if (models.isEmpty())
{ {
msgs.push_back(CStatusMessage(this, CStatusMessage::SeverityWarning, QStringLiteral("No models in set for '%1'").arg(simulator.toQString(true)))); msgs.push_back(CStatusMessage(this, CStatusMessage::SeverityWarning, QStringLiteral("No models in set for '%1'").arg(simulator.toQString(true))));
break;
} }
msgs = CAircraftModelUtilities::validateModelFiles(models, valid, invalid, false, 25, wasStopped, m_simDirectory); else
{
msgs = CAircraftModelUtilities::validateModelFiles(simulator, models, valid, invalid, false, 25, wasStopped, m_simDirectory);
}
const qint64 now = QDateTime::currentMSecsSinceEpoch();
const qint64 deltaTimeMs = now - started; const qint64 deltaTimeMs = now - started;
msgs.push_back(CStatusMessage(this, CStatusMessage::SeverityInfo, QStringLiteral("Validated in %1ms").arg(deltaTimeMs))); msgs.push_back(CStatusMessage(this, CStatusMessage::SeverityInfo, QStringLiteral("Validated in %1ms").arg(deltaTimeMs)));
msgs.sortBySeverityHighestFirst(); msgs.sortBySeverityHighestFirst();
msgs.freezeOrder(); msgs.freezeOrder();
validated = true;
QWriteLocker l(&m_lock); QWriteLocker l(&m_lock);
m_lastResultValid = valid; m_lastResultValid = valid;