diff --git a/src/blackmisc/blackmisc.pro b/src/blackmisc/blackmisc.pro index 499522bbd..34d3c747b 100644 --- a/src/blackmisc/blackmisc.pro +++ b/src/blackmisc/blackmisc.pro @@ -38,6 +38,7 @@ HEADERS += *.h \ $$PWD/pq/*.h \ $$PWD/simulation/*.h \ $$PWD/simulation/data/*.h \ + $$PWD/simulation/settings/*.h \ $$PWD/simulation/fscommon/*.h \ $$PWD/simulation/fsx/*.h \ $$PWD/simulation/xplane/*.h \ @@ -54,6 +55,7 @@ SOURCES += *.cpp \ $$PWD/network/*.cpp \ $$PWD/pq/*.cpp \ $$PWD/simulation/*.cpp \ + $$PWD/simulation/settings/*.cpp \ $$PWD/simulation/data/*.cpp \ $$PWD/simulation/fscommon/*.cpp \ $$PWD/simulation/fsx/*.cpp \ diff --git a/src/blackmisc/propertyindex.h b/src/blackmisc/propertyindex.h index fd6a454bd..d048d9110 100644 --- a/src/blackmisc/propertyindex.h +++ b/src/blackmisc/propertyindex.h @@ -91,8 +91,9 @@ namespace BlackMisc GlobalIndexCSimulatedAircraft = 6700, GlobalIndexCTextMessage = 6800, GlobalIndexCSimulatorSetup = 6900, - GlobalIndexCAircraftCfgEntries = 7000, - GlobalIndexCDistributor = 7100, + GlobalIndexCSimulatorSettings = 7000, + GlobalIndexCAircraftCfgEntries = 7100, + GlobalIndexCDistributor = 7200, GlobalIndexCVPilotModelRule = 8000, GlobalIndexCVoiceRoom = 9000, GlobalIndexCSettingKeyboardHotkey = 10000, diff --git a/src/blackmisc/simulation/registermetadatasimulation.cpp b/src/blackmisc/simulation/registermetadatasimulation.cpp index 10af397e8..2edd1d0d6 100644 --- a/src/blackmisc/simulation/registermetadatasimulation.cpp +++ b/src/blackmisc/simulation/registermetadatasimulation.cpp @@ -9,10 +9,12 @@ #include "registermetadatasimulation.h" #include "simulation.h" +#include "blackmisc/simulation/settings/settingssimulator.h" #include "blackmisc/valueobject.h" #include "blackmisc/variant.h" using namespace BlackMisc::Simulation; +using namespace BlackMisc::Simulation::Settings; using namespace BlackMisc::Simulation::Fsx; using namespace BlackMisc::Simulation::FsCommon; @@ -40,6 +42,7 @@ namespace BlackMisc CSimulatorSetup::registerMetadata(); CVPilotModelRule::registerMetadata(); CVPilotModelRuleSet::registerMetadata(); + CSettingsSimulator::registerMetadata(); } } // ns } // ns diff --git a/src/blackmisc/simulation/settings/settingssimulator.cpp b/src/blackmisc/simulation/settings/settingssimulator.cpp new file mode 100644 index 000000000..805c7dea6 --- /dev/null +++ b/src/blackmisc/simulation/settings/settingssimulator.cpp @@ -0,0 +1,283 @@ +/* Copyright (C) 2016 + * swift project community / contributors + * + * This file is part of swift project. It is subject to the license terms in the LICENSE file found in the top-level + * directory of this distribution and at http://www.swift-project.org/license.html. No part of swift project, + * including this file, may be copied, modified, propagated, or distributed except according to the terms + * contained in the LICENSE file. + */ + +#include "settingssimulator.h" +#include "blackmisc/simulation/fscommon/fscommonutil.h" +#include "blackmisc/simulation/xplane/xplaneutil.h" +#include "blackmisc/stringutils.h" + + +using namespace BlackMisc; +using namespace BlackMisc::Simulation::FsCommon; +using namespace BlackMisc::Simulation::XPlane; + +namespace BlackMisc +{ + namespace Simulation + { + namespace Settings + { + CSettingsSimulator::CSettingsSimulator() + { } + + void CSettingsSimulator::setSimulatorDirectory(const QString &simulatorDirectory) + { + this->m_simulatorDirectory = simulatorDirectory.trimmed(); + } + + const QString &CSettingsSimulator::getSimulatorDirectory() const + { + return this->m_simulatorDirectory; + } + + void CSettingsSimulator::setModelDirectory(const QString &modelDirectory) + { + this->m_modelDirectory = modelDirectory.trimmed(); + } + + const QString &CSettingsSimulator::getModelDirectory() const + { + return this->m_modelDirectory; + } + + void CSettingsSimulator::setModelExcludeDirectories(const QStringList &excludeDirectories) + { + this->m_excludeDirectoryPatterns = excludeDirectories; + } + + const QStringList &CSettingsSimulator::getModelExcludeDirectoryPatterns() const + { + return m_excludeDirectoryPatterns; + } + + QStringList CSettingsSimulator::getRelativeModelExcludeDirectoryPatterns(const QString &modelDirectory) const + { + const QStringList excludes(this->getModelExcludeDirectoryPatterns()); + return CFileUtils::makeDirectoriesRelative(excludes, modelDirectory); + } + + void CSettingsSimulator::resetPaths() + { + this->m_excludeDirectoryPatterns.clear(); + this->m_modelDirectory.clear(); + this->m_simulatorDirectory.clear(); + } + + QString CSettingsSimulator::convertToQString(bool i18n) const + { + return convertToQString(", ", i18n); + } + + QString CSettingsSimulator::convertToQString(const QString &separator, bool i18n) const + { + Q_UNUSED(i18n); + QString s("model directory: "); + s.append(this->m_modelDirectory); + s.append(separator); + s.append("exclude directories: "); + s.append(this->m_excludeDirectoryPatterns.join(',')); + return s; + } + + CVariant CSettingsSimulator::propertyByIndex(const CPropertyIndex &index) const + { + if (index.isMyself()) { return CVariant::from(*this); } + ColumnIndex i = index.frontCasted(); + switch (i) + { + case IndexSimulatorDirectory: + return CVariant::fromValue(this->m_simulatorDirectory); + case IndexModelDirectory: + return CVariant::fromValue(this->m_modelDirectory); + case IndexModelExcludeDirectoryPatterns: + return CVariant::fromValue(this->m_excludeDirectoryPatterns); + default: + return CValueObject::propertyByIndex(index); + } + } + + void CSettingsSimulator::setPropertyByIndex(const CPropertyIndex &index, const CVariant &variant) + { + if (index.isMyself()) { (*this) = variant.to(); return; } + + ColumnIndex i = index.frontCasted(); + switch (i) + { + case IndexSimulatorDirectory: + this->setSimulatorDirectory(variant.toQString()); + break; + case IndexModelDirectory: + this->setSimulatorDirectory(variant.toQString()); + break; + case IndexModelExcludeDirectoryPatterns: + this->m_excludeDirectoryPatterns = variant.value(); + break; + default: + CValueObject::setPropertyByIndex(index, variant); + break; + } + } + + CMultiSimulatorSimulatorSettings::CMultiSimulatorSimulatorSettings(QObject *parent) : QObject(parent) + { + // void + } + + CSettingsSimulator CMultiSimulatorSimulatorSettings::getSettings(const CSimulatorInfo &simulator) const + { + Q_ASSERT_X(simulator.isSingleSimulator(), Q_FUNC_INFO, "No single simulator"); + switch (simulator.getSimulator()) + { + case CSimulatorInfo::FS9: return this->m_simSettingsFs9.get(); + case CSimulatorInfo::FSX: return this->m_simSettingsFsx.get(); + case CSimulatorInfo::P3D: return this->m_simSettingsP3D.get(); + case CSimulatorInfo::XPLANE: return this->m_simSettingsXP.get(); + default: + Q_ASSERT_X(simulator.isSingleSimulator(), Q_FUNC_INFO, "No single simulator"); + break; + } + return CSettingsSimulator(); + } + + CStatusMessage CMultiSimulatorSimulatorSettings::setSettings(const CSettingsSimulator &settings, const CSimulatorInfo &simulator) + { + Q_ASSERT_X(simulator.isSingleSimulator(), Q_FUNC_INFO, "No single simulator"); + switch (simulator.getSimulator()) + { + case CSimulatorInfo::FS9: return this->m_simSettingsFs9.set(settings); + case CSimulatorInfo::FSX: return this->m_simSettingsFsx.set(settings); + case CSimulatorInfo::P3D: return this->m_simSettingsP3D.set(settings); + case CSimulatorInfo::XPLANE: return this->m_simSettingsXP.set(settings); + default: + Q_ASSERT_X(simulator.isSingleSimulator(), Q_FUNC_INFO, "No single simulator"); + break; + } + return CStatusMessage({ CLogCategory::settings() }, CStatusMessage::SeverityError, "wrong simulator"); + } + + CStatusMessage CMultiSimulatorSimulatorSettings::setAndSaveSettings(const CSettingsSimulator &settings, const CSimulatorInfo &simulator) + { + Q_ASSERT_X(simulator.isSingleSimulator(), Q_FUNC_INFO, "No single simulator"); + switch (simulator.getSimulator()) + { + case CSimulatorInfo::FS9: return this->m_simSettingsFs9.setAndSave(settings); + case CSimulatorInfo::FSX: return this->m_simSettingsFsx.setAndSave(settings); + case CSimulatorInfo::P3D: return this->m_simSettingsP3D.setAndSave(settings); + case CSimulatorInfo::XPLANE: return this->m_simSettingsXP.setAndSave(settings); + default: + Q_ASSERT_X(simulator.isSingleSimulator(), Q_FUNC_INFO, "No single simulator"); + break; + } + return CStatusMessage({ CLogCategory::settings() }, CStatusMessage::SeverityError, "wrong simulator"); + } + + CStatusMessage CMultiSimulatorSimulatorSettings::saveSettings(const CSimulatorInfo &simulator) + { + Q_ASSERT_X(simulator.isSingleSimulator(), Q_FUNC_INFO, "No single simulator"); + switch (simulator.getSimulator()) + { + case CSimulatorInfo::FS9: return this->m_simSettingsFs9.save(); + case CSimulatorInfo::FSX: return this->m_simSettingsFsx.save(); + case CSimulatorInfo::P3D: return this->m_simSettingsP3D.save(); + case CSimulatorInfo::XPLANE: return this->m_simSettingsXP.save(); + default: + Q_ASSERT_X(simulator.isSingleSimulator(), Q_FUNC_INFO, "No single simulator"); + break; + } + return CStatusMessage({ CLogCategory::settings() }, CStatusMessage::SeverityError, "wrong simulator"); + } + + QString CMultiSimulatorSimulatorSettings::getSimulatorDirectoryOrDefault(const CSimulatorInfo &simulator) const + { + const CSettingsSimulator s = this->getSettings(simulator); + if (s.getSimulatorDirectory().isEmpty()) + { + return this->getDefaultSimulatorDirectory(simulator); + } + return s.getSimulatorDirectory(); + } + + QString CMultiSimulatorSimulatorSettings::getDefaultSimulatorDirectory(const CSimulatorInfo &simulator) const + { + Q_ASSERT_X(simulator.isSingleSimulator(), Q_FUNC_INFO, "No single simulator"); + switch (simulator.getSimulator()) + { + case CSimulatorInfo::FS9: return CFsCommonUtil::fs9Dir(); + case CSimulatorInfo::FSX: return CFsCommonUtil::fsxDir(); + case CSimulatorInfo::P3D: return CFsCommonUtil::p3dDir(); + case CSimulatorInfo::XPLANE: return CXPlaneUtil::xplaneRootDir(); //! check XP + default: + Q_ASSERT_X(simulator.isSingleSimulator(), Q_FUNC_INFO, "No single simulator"); + break; + } + return ""; + } + + QString CMultiSimulatorSimulatorSettings::getModelDirectoryOrDefault(const CSimulatorInfo &simulator) const + { + const CSettingsSimulator s = this->getSettings(simulator); + if (s.getModelDirectory().isEmpty()) + { + return this->getDefaultModelDirectory(simulator); + } + return s.getModelDirectory(); + } + + QString CMultiSimulatorSimulatorSettings::getDefaultModelDirectory(const CSimulatorInfo &simulator) const + { + Q_ASSERT_X(simulator.isSingleSimulator(), Q_FUNC_INFO, "No single simulator"); + switch (simulator.getSimulator()) + { + case CSimulatorInfo::FS9: return CFsCommonUtil::fs9AircraftDir(); + case CSimulatorInfo::FSX: return CFsCommonUtil::fsxSimObjectsDir(); + case CSimulatorInfo::P3D: return CFsCommonUtil::p3dSimObjectsDir(); + case CSimulatorInfo::XPLANE: return CXPlaneUtil::xplaneModelDirectory(); + default: + Q_ASSERT_X(simulator.isSingleSimulator(), Q_FUNC_INFO, "No single simulator"); + break; + } + return ""; + } + + QStringList CMultiSimulatorSimulatorSettings::getModelExcludeDirectoryPatternsOrDefault(const CSimulatorInfo &simulator, bool relative) const + { + const CSettingsSimulator s = this->getSettings(simulator); + const QString md = getModelDirectoryOrDefault(simulator); + QStringList exclude = relative ? s.getRelativeModelExcludeDirectoryPatterns(md) : s.getModelExcludeDirectoryPatterns(); + if (!exclude.isEmpty()) { return exclude; } + exclude = this->getDefaultModelExcludeDirectoryPatterns(simulator); + if (!relative || exclude.isEmpty()) { return exclude; } + return CFileUtils::makeDirectoriesRelative(exclude, md); + } + + QStringList CMultiSimulatorSimulatorSettings::getDefaultModelExcludeDirectoryPatterns(const CSimulatorInfo &simulator) const + { + Q_ASSERT_X(simulator.isSingleSimulator(), Q_FUNC_INFO, "No single simulator"); + switch (simulator.getSimulator()) + { + case CSimulatorInfo::FS9: return CFsCommonUtil::fs9AircraftObjectsExcludeDirectoryPatterns(); + case CSimulatorInfo::FSX: return CFsCommonUtil::fsxSimObjectsExcludeDirectoryPatterns(); + case CSimulatorInfo::P3D: return CFsCommonUtil::p3dSimObjectsExcludeDirectoryPatterns(); + case CSimulatorInfo::XPLANE: return CXPlaneUtil::xplaneModelExcludeDirectoryPatterns(); + default: + Q_ASSERT_X(simulator.isSingleSimulator(), Q_FUNC_INFO, "No single simulator"); + break; + } + return QStringList(); + } + + void CMultiSimulatorSimulatorSettings::resetToDefaults(const CSimulatorInfo &simulator) + { + CSettingsSimulator s = this->getSettings(simulator); + s.resetPaths(); + this->setAndSaveSettings(s, simulator); + } + } // ns + } // ns +} // ns diff --git a/src/blackmisc/simulation/settings/settingssimulator.h b/src/blackmisc/simulation/settings/settingssimulator.h new file mode 100644 index 000000000..1301a9445 --- /dev/null +++ b/src/blackmisc/simulation/settings/settingssimulator.h @@ -0,0 +1,182 @@ +/* Copyright (C) 2016 + * swift project community / contributors + * + * This file is part of swift project. It is subject to the license terms in the LICENSE file found in the top-level + * directory of this distribution and at http://www.swift-project.org/license.html. No part of swift project, + * including this file, may be copied, modified, propagated, or distributed except according to the terms + * contained in the LICENSE file. + */ + +//! \file + +#ifndef BLACKMISC_SIMULATION_SETTINGS_SETTINGSSIMULATOR_H +#define BLACKMISC_SIMULATION_SETTINGS_SETTINGSSIMULATOR_H + +#include "blackmisc/settingscache.h" +#include "blackmisc/blackmiscexport.h" +#include "blackmisc/simulation/simulatorinfo.h" +#include "blackmisc/propertyindex.h" + +#include +#include + +namespace BlackMisc +{ + namespace Simulation + { + namespace Settings + { + //! Settings for simulator + //! Driver independent part also used in loaders (such as directories) + class BLACKMISC_EXPORT CSettingsSimulator : + public BlackMisc::CValueObject + { + public: + //! Properties by index + enum ColumnIndex + { + IndexSimulatorDirectory = BlackMisc::CPropertyIndex::GlobalIndexCSimulatorSettings, + IndexModelDirectory, + IndexModelExcludeDirectoryPatterns + }; + + //! Default constructor + CSettingsSimulator(); + + //! Destructor. + ~CSettingsSimulator() {} + + //! Set simulator directory + void setSimulatorDirectory(const QString &simulatorDirectory); + + //! Simulator directory + const QString &getSimulatorDirectory() const; + + //! Set model directory + void setModelDirectory(const QString &modelDirectory); + + //! Model directory + const QString &getModelDirectory() const; + + //! Set exclude directories + void setModelExcludeDirectories(const QStringList &excludeDirectories); + + //! Margins for given dock widget + const QStringList &getModelExcludeDirectoryPatterns() const; + + //! Relative exclude directory patterns + QStringList getRelativeModelExcludeDirectoryPatterns(const QString &modelDirectory) const; + + //! Reset the paths + void resetPaths(); + + //! \copydoc BlackMisc::Mixin::String::toQString + QString convertToQString(bool i18n = false) const; + + //! To string + QString convertToQString(const QString &separator, bool i18n = false) const; + + //! \copydoc BlackMisc::Mixin::Index::propertyByIndex + BlackMisc::CVariant propertyByIndex(const BlackMisc::CPropertyIndex &index) const; + + //! \copydoc BlackMisc::Mixin::Index::setPropertyByIndex + void setPropertyByIndex(const BlackMisc::CPropertyIndex &index, const BlackMisc::CVariant &variant); + + private: + QString m_simulatorDirectory; //! Simulator directory + QString m_modelDirectory; //!< Model directory + QStringList m_excludeDirectoryPatterns; //!< Exclude model directory + + BLACK_METACLASS( + CSettingsSimulator, + BLACK_METAMEMBER(simulatorDirectory), + BLACK_METAMEMBER(modelDirectory), + BLACK_METAMEMBER(excludeDirectoryPatterns) + ); + }; + + //! Trait for simulator settings + struct SettingsSimulatorFsx : public BlackMisc::CSettingTrait + { + //! Key in data cache + static const char *key() { return "settingssimulatorfsx"; } + }; + + //! Trait for simulator settings + struct SettingsSimulatorFs9 : public BlackMisc::CSettingTrait + { + //! Key in data cache + static const char *key() { return "settingssimulatorfs9"; } + }; + + //! Trait for simulator settings + struct SettingsSimulatorP3D : public BlackMisc::CSettingTrait + { + //! Key in data cache + static const char *key() { return "settingssimulatorp3d"; } + }; + + //! Trait for simulator settings + struct SettingsSimulatorXP : public BlackMisc::CSettingTrait + { + //! Key in data cache + static const char *key() { return "settingssimulatorxplane"; } + }; + + //! Bundle of settings for all simulators + class BLACKMISC_EXPORT CMultiSimulatorSimulatorSettings : public QObject + { + Q_OBJECT + + public: + //! Construtor + CMultiSimulatorSimulatorSettings(QObject *parent = nullptr); + + //! Settings per simulator + CSettingsSimulator getSettings(const BlackMisc::Simulation::CSimulatorInfo &simulator) const; + + //! Set settings per simulator + BlackMisc::CStatusMessage setSettings(const BlackMisc::Simulation::Settings::CSettingsSimulator &settings, const BlackMisc::Simulation::CSimulatorInfo &simulator); + + //! Set settings per simulator + BlackMisc::CStatusMessage setAndSaveSettings(const BlackMisc::Simulation::Settings::CSettingsSimulator &settings, const BlackMisc::Simulation::CSimulatorInfo &simulator); + + //! Set settings per simulator + BlackMisc::CStatusMessage saveSettings(const BlackMisc::Simulation::CSimulatorInfo &simulator); + + //! Simulator directory or default model path per simulator + QString getSimulatorDirectoryOrDefault(const BlackMisc::Simulation::CSimulatorInfo &simulator) const; + + //! Default simulator path per simulator + QString getDefaultSimulatorDirectory(const BlackMisc::Simulation::CSimulatorInfo &simulator) const; + + //! Model directory or default model path per simulator + QString getModelDirectoryOrDefault(const BlackMisc::Simulation::CSimulatorInfo &simulator) const; + + //! Default model path per simulator + QString getDefaultModelDirectory(const BlackMisc::Simulation::CSimulatorInfo &simulator) const; + + //! Model exclude paths per simulator + QStringList getModelExcludeDirectoryPatternsOrDefault(const BlackMisc::Simulation::CSimulatorInfo &simulator, bool relative) const; + + //! Default model exclude paths per simulator + QStringList getDefaultModelExcludeDirectoryPatterns(const BlackMisc::Simulation::CSimulatorInfo &simulator) const; + + //! Reset to defaults + void resetToDefaults(const BlackMisc::Simulation::CSimulatorInfo &simulator); + + private: + BlackMisc::CSetting m_simSettingsFsx {this}; //!< FSX cache + BlackMisc::CSetting m_simSettingsFs9 {this}; //!< FS9 cache + BlackMisc::CSetting m_simSettingsP3D {this}; //!< P3D cache + BlackMisc::CSetting m_simSettingsXP {this}; //!< XP cache + }; + } // ns + } // ns +} // ns + +Q_DECLARE_METATYPE(BlackMisc::Simulation::Settings::CSettingsSimulator) +Q_DECLARE_METATYPE(BlackMisc::CCollection) +Q_DECLARE_METATYPE(BlackMisc::CSequence) + +#endif // guard