Handle built-in content files in content model

There's also handling for files declared as originating from a lower-priority openmw.cfg, e.g. anything in the local config or any intermediate ones, as they can't be disabled or reordered.
There's no way to mark such files yet, but the logic's the same as built-in files, so everything will be fine once that's set up.
pull/3235/head
AnyOldName3 10 months ago
parent 322a378907
commit d111b4bbd9

@ -109,6 +109,9 @@ Qt::ItemFlags ContentSelectorModel::ContentModel::flags(const QModelIndex& index
if (!file)
return Qt::NoItemFlags;
if (file->builtIn() || file->fromAnotherConfigFile())
return Qt::NoItemFlags;
// game files can always be checked
if (file == mGameFile)
return Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsUserCheckable;
@ -130,7 +133,7 @@ Qt::ItemFlags ContentSelectorModel::ContentModel::flags(const QModelIndex& index
continue;
noGameFiles = false;
if (mCheckedFiles.contains(depFile))
if (depFile->builtIn() || depFile->fromAnotherConfigFile() || mCheckedFiles.contains(depFile))
{
gamefileChecked = true;
break;
@ -217,14 +220,14 @@ QVariant ContentSelectorModel::ContentModel::data(const QModelIndex& index, int
if (file == mGameFile)
return QVariant();
return mCheckedFiles.contains(file) ? Qt::Checked : Qt::Unchecked;
return (file->builtIn() || file->fromAnotherConfigFile() || mCheckedFiles.contains(file)) ? Qt::Checked : Qt::Unchecked;
}
case Qt::UserRole:
{
if (file == mGameFile)
return ContentType_GameFile;
else if (flags(index))
else
return ContentType_Addon;
break;
@ -279,7 +282,12 @@ bool ContentSelectorModel::ContentModel::setData(const QModelIndex& index, const
{
int checkValue = value.toInt();
bool setState = false;
if (checkValue == Qt::Checked && !mCheckedFiles.contains(file))
if (file->builtIn() || file->fromAnotherConfigFile())
{
setState = false;
success = false;
}
else if (checkValue == Qt::Checked && !mCheckedFiles.contains(file))
{
setState = true;
success = true;
@ -374,6 +382,13 @@ bool ContentSelectorModel::ContentModel::dropMimeData(
else if (parent.isValid())
beginRow = parent.row();
int firstModifiable = 0;
while (item(firstModifiable)->builtIn() || item(firstModifiable)->fromAnotherConfigFile())
++firstModifiable;
if (beginRow < firstModifiable)
return false;
QByteArray encodedData = data->data(mMimeType);
QDataStream stream(&encodedData, QIODevice::ReadOnly);
@ -449,6 +464,9 @@ void ContentSelectorModel::ContentModel::addFiles(const QString& path, bool newf
file->setGameFiles({});
}
if (info.fileName().compare("builtin.omwscripts", Qt::CaseInsensitive) == 0)
file->setBuiltIn(true);
if (info.fileName().endsWith(".omwscripts", Qt::CaseInsensitive))
{
file->setDate(info.lastModified());
@ -579,15 +597,20 @@ void ContentSelectorModel::ContentModel::setCurrentGameFile(const EsmFile* file)
void ContentSelectorModel::ContentModel::sortFiles()
{
emit layoutAboutToBeChanged();
int firstModifiable = 0;
while (mFiles.at(firstModifiable)->builtIn() || mFiles.at(firstModifiable)->fromAnotherConfigFile())
++firstModifiable;
// Dependency sort
std::unordered_set<const EsmFile*> moved;
for (int i = mFiles.size() - 1; i > 0;)
for (int i = mFiles.size() - 1; i > firstModifiable;)
{
const auto file = mFiles.at(i);
if (moved.find(file) == moved.end())
{
int index = -1;
for (int j = 0; j < i; ++j)
for (int j = firstModifiable; j < i; ++j)
{
const QStringList& gameFiles = mFiles.at(j)->gameFiles();
// All addon files are implicitly dependent on the game file
@ -650,6 +673,7 @@ void ContentSelectorModel::ContentModel::setContentList(const QStringList& fileL
{
if (setCheckState(filepath, true))
{
// setCheckState already gracefully handles builtIn and fromAnotherConfigFile
// as necessary, move plug-ins in visible list to match sequence of supplied filelist
const EsmFile* file = item(filepath);
int filePosition = indexFromItem(file).row();
@ -747,7 +771,7 @@ bool ContentSelectorModel::ContentModel::setCheckState(const QString& filepath,
const EsmFile* file = item(filepath);
if (!file)
if (!file || file->builtIn() || file->fromAnotherConfigFile())
return false;
if (checkState)

@ -41,6 +41,16 @@ void ContentSelectorModel::EsmFile::setDescription(const QString& description)
mDescription = description;
}
void ContentSelectorModel::EsmFile::setBuiltIn(bool builtIn)
{
mBuiltIn = builtIn;
}
void ContentSelectorModel::EsmFile::setFromAnotherConfigFile(bool fromAnotherConfigFile)
{
mFromAnotherConfigFile = fromAnotherConfigFile;
}
bool ContentSelectorModel::EsmFile::isGameFile() const
{
return (mGameFiles.size() == 0)
@ -76,6 +86,14 @@ QVariant ContentSelectorModel::EsmFile::fileProperty(const FileProperty prop) co
return mDescription;
break;
case FileProperty_BuiltIn:
return mBuiltIn;
break;
case FileProperty_FromAnotherConfigFile:
return mFromAnotherConfigFile;
break;
case FileProperty_GameFile:
return mGameFiles;
break;
@ -113,6 +131,15 @@ void ContentSelectorModel::EsmFile::setFileProperty(const FileProperty prop, con
mDescription = value;
break;
// todo: check these work
case FileProperty_BuiltIn:
mBuiltIn = value == "true";
break;
case FileProperty_FromAnotherConfigFile:
mFromAnotherConfigFile = value == "true";
break;
case FileProperty_GameFile:
mGameFiles << value;
break;

@ -26,7 +26,9 @@ namespace ContentSelectorModel
FileProperty_DateModified = 3,
FileProperty_FilePath = 4,
FileProperty_Description = 5,
FileProperty_GameFile = 6
FileProperty_BuiltIn = 6,
FileProperty_FromAnotherConfigFile = 7,
FileProperty_GameFile = 8,
};
EsmFile(const QString& fileName = QString(), ModelItem* parent = nullptr);
@ -40,6 +42,8 @@ namespace ContentSelectorModel
void setFilePath(const QString& path);
void setGameFiles(const QStringList& gameFiles);
void setDescription(const QString& description);
void setBuiltIn(bool builtIn);
void setFromAnotherConfigFile(bool fromAnotherConfigFile);
void addGameFile(const QString& name) { mGameFiles.append(name); }
QVariant fileProperty(const FileProperty prop) const;
@ -49,18 +53,27 @@ namespace ContentSelectorModel
QDateTime modified() const { return mModified; }
QString formatVersion() const { return mVersion; }
QString filePath() const { return mPath; }
bool builtIn() const { return mBuiltIn; }
bool fromAnotherConfigFile() const { return mFromAnotherConfigFile; }
/// @note Contains file names, not paths.
const QStringList& gameFiles() const { return mGameFiles; }
QString description() const { return mDescription; }
QString toolTip() const
{
return mTooltipTemlate.arg(mAuthor)
QString tooltip = mTooltipTemlate.arg(mAuthor)
.arg(mVersion)
.arg(mModified.toString(Qt::ISODate))
.arg(mPath)
.arg(mDescription)
.arg(mGameFiles.join(", "));
if (mBuiltIn)
tooltip += tr("<br/><b>This content file cannot be disabled because it is part of OpenMW.</b><br/>");
else if (mFromAnotherConfigFile)
tooltip += tr("<br/><b>This content file cannot be disabled because it is enabled in a config file other than the user one.</b><br/>");
return tooltip;
}
bool isGameFile() const;
@ -82,6 +95,8 @@ namespace ContentSelectorModel
QStringList mGameFiles;
QString mDescription;
QString mToolTip;
bool mBuiltIn = false;
bool mFromAnotherConfigFile = false;
};
}

Loading…
Cancel
Save