1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150
|
#ifndef GAMESETTINGS_HPP
#define GAMESETTINGS_HPP
#include <QFile>
#include <QMultiMap>
#include <QString>
#include <QStringList>
#include <QTextStream>
#include <filesystem>
namespace Files
{
typedef std::vector<std::filesystem::path> PathContainer;
struct ConfigurationManager;
}
namespace Config
{
struct SettingValue
{
QString value = "";
// value as found in openmw.cfg, e.g. relative path with ?slug?
QString originalRepresentation = value;
// path of openmw.cfg, e.g. to resolve relative paths
QString context = "";
friend std::strong_ordering operator<=>(const SettingValue&, const SettingValue&) = default;
};
class GameSettings
{
public:
explicit GameSettings(const Files::ConfigurationManager& cfg);
inline SettingValue value(const QString& key, const SettingValue& defaultValue = {})
{
return mSettings.contains(key) ? mSettings.value(key) : defaultValue;
}
inline void setValue(const QString& key, const SettingValue& value)
{
remove(key);
mSettings.insert(key, value);
if (isUserSetting(value))
mUserSettings.insert(key, value);
}
inline void setMultiValue(const QString& key, const SettingValue& value)
{
QList<SettingValue> values = mSettings.values(key);
if (!values.contains(value))
mSettings.insert(key, value);
if (isUserSetting(value))
{
values = mUserSettings.values(key);
if (!values.contains(value))
mUserSettings.insert(key, value);
}
}
inline void remove(const QString& key)
{
// simplify to removeIf when Qt5 goes
for (auto itr = mSettings.lowerBound(key); itr != mSettings.upperBound(key);)
{
if (isUserSetting(*itr))
itr = mSettings.erase(itr);
else
++itr;
}
mUserSettings.remove(key);
}
QList<SettingValue> getDataDirs() const;
QString getResourcesVfs() const;
inline void removeDataDir(const QString& existingDir)
{
if (!existingDir.isEmpty())
{
// non-user settings can't be removed as we can't edit the openmw.cfg they're in
mDataDirs.erase(
std::remove_if(mDataDirs.begin(), mDataDirs.end(),
[&](const SettingValue& dir) { return isUserSetting(dir) && dir.value == existingDir; }),
mDataDirs.end());
}
}
inline void addDataDir(const SettingValue& dir)
{
if (!dir.value.isEmpty())
mDataDirs.append(dir);
}
inline QString getDataLocal() const { return mDataLocal; }
bool hasMaster();
QList<SettingValue> values(const QString& key, const QList<SettingValue>& defaultValues = {}) const;
bool containsValue(const QString& key, const QString& value) const;
bool readFile(QTextStream& stream, const QString& context, bool ignoreContent = false);
bool readFile(QTextStream& stream, QMultiMap<QString, SettingValue>& settings, const QString& context,
bool ignoreContent = false);
bool readUserFile(QTextStream& stream, const QString& context, bool ignoreContent = false);
bool writeFile(QTextStream& stream);
bool writeFileWithComments(QFile& file);
QList<SettingValue> getArchiveList() const;
void setContentList(
const QList<SettingValue>& dirNames, const QList<SettingValue>& archiveNames, const QStringList& fileNames);
QList<SettingValue> getContentList() const;
const QString& getUserContext() const { return mContexts.back(); }
bool isUserSetting(const SettingValue& settingValue) const;
SettingValue processPathSettingValue(const SettingValue& value);
void clear();
private:
const Files::ConfigurationManager& mCfgMgr;
void validatePaths();
QMultiMap<QString, SettingValue> mSettings;
QMultiMap<QString, SettingValue> mUserSettings;
QStringList mContexts;
QList<SettingValue> mDataDirs;
QString mDataLocal;
static const char sArchiveKey[];
static const char sContentKey[];
static const char sDirectoryKey[];
static bool isOrderedLine(const QString& line);
};
QDataStream& operator<<(QDataStream& out, const SettingValue& settingValue);
QDataStream& operator>>(QDataStream& in, SettingValue& settingValue);
}
Q_DECLARE_METATYPE(Config::SettingValue)
#endif // GAMESETTINGS_HPP
|