XPlane sub directory check (model dirs in XPlane dir), unified with settings is valid

This commit is contained in:
Klaus Basan
2019-07-13 03:41:17 +02:00
committed by Mat Sutcliffe
parent ac2d665c6b
commit 5799e31d27
4 changed files with 99 additions and 33 deletions

View File

@@ -63,8 +63,8 @@ namespace BlackMisc
void CSimulatorSettings::setModelDirectories(const QStringList &modelDirectories)
{
m_modelDirectories = modelDirectories;
m_modelDirectories.removeAll({});
m_modelDirectories.removeDuplicates();
m_modelDirectories.removeAll({}); // empty values
m_modelDirectories.removeDuplicates(); // duplicates
}
void CSimulatorSettings::clearModelDirectories()
@@ -256,6 +256,32 @@ namespace BlackMisc
return this->setSettings(s, simulator);
}
CStatusMessageList CMultiSimulatorSettings::setAndValidateSettings(const CSimulatorSettings &settings, const CSimulatorInfo &simulator)
{
this->setSettings(settings, simulator);
CStatusMessageList msgs;
switch (simulator.getSimulator())
{
case CSimulatorInfo::FG: break;
case CSimulatorInfo::FS9: break;
case CSimulatorInfo::FSX: break;
case CSimulatorInfo::P3D: break;
case CSimulatorInfo::XPLANE:
{
if (settings.hasModelDirectories())
{
const QString simDir = this->getSimulatorDirectoryOrDefault(simulator);
msgs = CXPlaneUtil::validateModelDirectories(simDir, settings.getModelDirectories());
}
}
break;
default:
Q_ASSERT_X(simulator.isSingleSimulator(), Q_FUNC_INFO, "No single simulator");
break;
}
return msgs;
}
CStatusMessage CMultiSimulatorSettings::setAndSaveSettings(const CSimulatorSettings &settings, const CSimulatorInfo &simulator)
{
Q_ASSERT_X(simulator.isSingleSimulator(), Q_FUNC_INFO, "No single simulator");
@@ -445,7 +471,7 @@ namespace BlackMisc
bool CSimulatorMessagesSettings::relayThisStatusMessage(const CStatusMessage &message) const
{
if (message.isEmpty()) { return false; }
if (!this->isGloballyEnabled()) { return false; }
if (!this->isRelayGloballyEnabled()) { return false; }
if (!this->isRelayTechnicalMessages()) { return false; }
const int s = static_cast<int>(message.getSeverity());
return (s >= m_technicalLogLevel);
@@ -454,7 +480,7 @@ namespace BlackMisc
bool CSimulatorMessagesSettings::relayThisTextMessage(const Network::CTextMessage &msg, const BlackMisc::Simulation::CSimulatedAircraft &aircraft) const
{
if (msg.isEmpty()) { return false; }
if (!this->isGloballyEnabled()) { return false; }
if (!this->isRelayGloballyEnabled()) { return false; }
if (m_messageType == NoTextMessages) { return false; }
const TextMessageType mt = static_cast<TextMessageType>(m_messageType);
@@ -495,7 +521,7 @@ namespace BlackMisc
{
severity = CStatusMessage::severityToString(static_cast<CStatusMessage::StatusSeverity>(m_technicalLogLevel));
}
return s.arg(boolToOnOff(m_globallyEnabled)).arg(m_messageType).arg(severity);
return s.arg(boolToOnOff(m_relayGloballyEnabled)).arg(m_messageType).arg(severity);
}
CVariant CSimulatorMessagesSettings::propertyByIndex(const CPropertyIndex &index) const
@@ -505,8 +531,8 @@ namespace BlackMisc
switch (i)
{
case IndexTechnicalLogSeverity: return CVariant::fromValue(m_technicalLogLevel);
case IndexTextMessageRelay: return CVariant::from(m_messageType);
case IndexGloballyEnabled: return CVariant::from(m_globallyEnabled);
case IndexRelayTextMessage: return CVariant::from(m_messageType);
case IndexRelayGloballyEnabled: return CVariant::from(m_relayGloballyEnabled);
default: return CValueObject::propertyByIndex(index);
}
}
@@ -518,8 +544,8 @@ namespace BlackMisc
switch (i)
{
case IndexTechnicalLogSeverity: this->setTechnicalLogSeverity(static_cast<CStatusMessage::StatusSeverity>(variant.toInt())); break;
case IndexTextMessageRelay: this->setRelayTextMessages(static_cast<CSimulatorMessagesSettings::TextMessageType>(variant.toInt())); break;
case IndexGloballyEnabled: this->setGloballyEnabled(variant.toBool()); break;
case IndexRelayTextMessage: this->setRelayTextMessages(static_cast<CSimulatorMessagesSettings::TextMessageType>(variant.toInt())); break;
case IndexRelayGloballyEnabled: this->setRelayGloballyEnabled(variant.toBool()); break;
default: CValueObject::setPropertyByIndex(index, variant); break;
}
}
@@ -747,6 +773,17 @@ namespace BlackMisc
if (simulator == CSimulatorInfo::p3d()) { return m_simP3D.setAndSave(settings); }
return m_simFsx.setAndSave(settings);
}
bool TSimulatorXP::isValid(const CSimulatorSettings &value, QString &reason)
{
const QString simDir = value.hasSimulatorDirectory() ? value.getSimulatorDirectory()
: CSpecializedSimulatorSettings::defaultSimulatorDirectory(CSimulatorInfo::XPLANE);
const CStatusMessageList msgs = CXPlaneUtil::validateModelDirectories(simDir, value.getModelDirectories());
if (msgs.isSuccess()) { return true; }
reason = msgs.getErrorMessages().toSingleMessage().toQString(true);
return false;
}
} // ns
} // ns
} // ns

View File

@@ -380,7 +380,7 @@ namespace BlackMisc
};
//! Trait for simulator settings
struct TSimulatorXP : public TSettingTrait<CSimulatorSettings>
struct BLACKMISC_EXPORT TSimulatorXP : public TSettingTrait<CSimulatorSettings>
{
//! \copydoc BlackMisc::TSettingTrait::key
static const char *key() { return "settingssimulatorxplane"; }
@@ -389,20 +389,7 @@ namespace BlackMisc
static const QString &humanReadable() { static const QString name("XPlane settings"); return name; }
//! \copydoc BlackMisc::TSettingTrait::isValid
static bool isValid(const CSimulatorSettings &value, QString &reason)
{
const QString simDir = value.hasSimulatorDirectory() ? value.getSimulatorDirectory()
: CSpecializedSimulatorSettings::defaultSimulatorDirectory(CSimulatorInfo::XPLANE);
for (const QString &modelDir : value.getModelDirectories())
{
if (!CDirectoryUtils::isSubDirectoryOf(modelDir, simDir))
{
reason = QStringLiteral("Model directory must be within the simulator directory structure");
return false;
}
}
return true;
}
static bool isValid(const CSimulatorSettings &value, QString &reason);
};
//! Trait for simulator settings
@@ -457,6 +444,10 @@ namespace BlackMisc
//! Clear the model directory
CStatusMessage clearModelDirectories(const CSimulatorInfo &simulator);
//! Set settings per simulator, but do NOT save yet, but validate
//! \remark can be simulator specific
CStatusMessageList setAndValidateSettings(const CSimulatorSettings &settings, const CSimulatorInfo &simulator);
//! Set settings per simulator
CStatusMessage setAndSaveSettings(const CSimulatorSettings &settings, const CSimulatorInfo &simulator);
@@ -533,8 +524,8 @@ namespace BlackMisc
enum ColumnIndex
{
IndexTechnicalLogSeverity = CPropertyIndex::GlobalIndexCSimulatorMessageSettings,
IndexTextMessageRelay,
IndexGloballyEnabled
IndexRelayTextMessage,
IndexRelayGloballyEnabled
};
//! Enabled matching mode flags
@@ -557,10 +548,10 @@ namespace BlackMisc
void setTechnicalLogSeverity(CStatusMessage::StatusSeverity severity);
//! Globally enable / disable
void setGloballyEnabled(bool enabled) { m_globallyEnabled = enabled; }
void setRelayGloballyEnabled(bool enabled) { m_relayGloballyEnabled = enabled; }
//! Globally enabled?
bool isGloballyEnabled() const { return m_globallyEnabled; }
bool isRelayGloballyEnabled() const { return m_relayGloballyEnabled; }
//! No technical messages
void disableTechnicalMessages();
@@ -614,9 +605,9 @@ namespace BlackMisc
void setPropertyByIndex(const CPropertyIndex &index, const CVariant &variant);
private:
int m_technicalLogLevel = CStatusMessage::SeverityError; //!< Simulator directory
int m_messageType = static_cast<int>(TextMessagePrivate | TextMessageSupervisor);
bool m_globallyEnabled = true; //!< messsage relay enabled to simulator
int m_technicalLogLevel = CStatusMessage::SeverityError; //!< log level
int m_messageType = static_cast<int>(TextMessagePrivate | TextMessageSupervisor);
bool m_relayGloballyEnabled = true; //!< messsage relay enabled to simulator
BLACK_METACLASS(
CSimulatorMessagesSettings,

View File

@@ -17,7 +17,7 @@
#include <QTextStream>
#if defined(Q_OS_WIN)
#include <shlobj.h>
#include <ShlObj.h>
#endif
using namespace BlackMisc;
@@ -28,6 +28,12 @@ namespace BlackMisc
{
namespace XPlane
{
const CLogCategoryList &CXPlaneUtil::getLogCategories()
{
static const CLogCategoryList cats { CLogCategory::matching() };
return cats;
}
// Returns the last path from filePath, which does exist on the file system
QString getLastExistingPathFromFile(const QString &filePath)
{
@@ -277,6 +283,31 @@ namespace BlackMisc
static const QStringList filter({"*.xpl"});
return filter;
}
CStatusMessageList CXPlaneUtil::validateModelDirectories(const QString &simDir, const QStringList &modelDirectories)
{
if (simDir.isEmpty())
{
return CStatusMessage(getLogCategories(), CStatusMessage::SeverityWarning, u"no simulator directory", true);
}
CStatusMessageList msgs;
if (modelDirectories.isEmpty()) { return msgs; }
const QDir sd(simDir);
const bool simDirExists = sd.exists();
for (const QString &modelDir : modelDirectories)
{
const bool exists = simDirExists ?
CDirectoryUtils::isSameOrSubDirectoryOf(modelDir, sd) :
CDirectoryUtils::isSameOrSubDirectoryOfStringBased(modelDir, sd.absolutePath());
const CStatusMessage m = exists ?
CStatusMessage(getLogCategories()).info(u"Model directory '%1' inside '%2'") << modelDir << sd.absolutePath() :
CStatusMessage(getLogCategories()).error(u"Model directory '%1' NOT inside '%2'") << modelDir << sd.absolutePath();
msgs.push_back(m);
}
msgs.addValidationCategory();
return msgs;
}
} // namespace
} // namespace
} // namespace

View File

@@ -11,8 +11,9 @@
#ifndef BLACKMISC_SIMULATION_XPLANE_XPLANEUTIL_H
#define BLACKMISC_SIMULATION_XPLANE_XPLANEUTIL_H
#include "blackmisc/logcategorylist.h"
#include "blackmisc/statusmessagelist.h"
#include "blackmisc/blackmiscexport.h"
#include <QStringList>
namespace BlackMisc
@@ -28,6 +29,9 @@ namespace BlackMisc
//! Constructor
CXPlaneUtil() = delete;
//! Log categories
static const CLogCategoryList &getLogCategories();
//! XPlane 9 directory
static QString xplane9Dir();
@@ -99,6 +103,9 @@ namespace BlackMisc
//! Filter filter for xpl files
static const QStringList &xplFileFilter();
//! Validate the model directories
static CStatusMessageList validateModelDirectories(const QString &simDir, const QStringList &modelDirectories);
private:
//! Concatenates dirs for used OS
static QString xplaneDir(const QString &xplaneInstallFile);