mirror of
https://github.com/OpenMW/openmw.git
synced 2025-06-25 13:11:37 +00:00
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.
This commit is contained in:
parent
322a378907
commit
d111b4bbd9
3 changed files with 75 additions and 9 deletions
|
@ -109,6 +109,9 @@ Qt::ItemFlags ContentSelectorModel::ContentModel::flags(const QModelIndex& index
|
||||||
if (!file)
|
if (!file)
|
||||||
return Qt::NoItemFlags;
|
return Qt::NoItemFlags;
|
||||||
|
|
||||||
|
if (file->builtIn() || file->fromAnotherConfigFile())
|
||||||
|
return Qt::NoItemFlags;
|
||||||
|
|
||||||
// game files can always be checked
|
// game files can always be checked
|
||||||
if (file == mGameFile)
|
if (file == mGameFile)
|
||||||
return Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsUserCheckable;
|
return Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsUserCheckable;
|
||||||
|
@ -130,7 +133,7 @@ Qt::ItemFlags ContentSelectorModel::ContentModel::flags(const QModelIndex& index
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
noGameFiles = false;
|
noGameFiles = false;
|
||||||
if (mCheckedFiles.contains(depFile))
|
if (depFile->builtIn() || depFile->fromAnotherConfigFile() || mCheckedFiles.contains(depFile))
|
||||||
{
|
{
|
||||||
gamefileChecked = true;
|
gamefileChecked = true;
|
||||||
break;
|
break;
|
||||||
|
@ -217,14 +220,14 @@ QVariant ContentSelectorModel::ContentModel::data(const QModelIndex& index, int
|
||||||
if (file == mGameFile)
|
if (file == mGameFile)
|
||||||
return QVariant();
|
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:
|
case Qt::UserRole:
|
||||||
{
|
{
|
||||||
if (file == mGameFile)
|
if (file == mGameFile)
|
||||||
return ContentType_GameFile;
|
return ContentType_GameFile;
|
||||||
else if (flags(index))
|
else
|
||||||
return ContentType_Addon;
|
return ContentType_Addon;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
@ -279,7 +282,12 @@ bool ContentSelectorModel::ContentModel::setData(const QModelIndex& index, const
|
||||||
{
|
{
|
||||||
int checkValue = value.toInt();
|
int checkValue = value.toInt();
|
||||||
bool setState = false;
|
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;
|
setState = true;
|
||||||
success = true;
|
success = true;
|
||||||
|
@ -374,6 +382,13 @@ bool ContentSelectorModel::ContentModel::dropMimeData(
|
||||||
else if (parent.isValid())
|
else if (parent.isValid())
|
||||||
beginRow = parent.row();
|
beginRow = parent.row();
|
||||||
|
|
||||||
|
int firstModifiable = 0;
|
||||||
|
while (item(firstModifiable)->builtIn() || item(firstModifiable)->fromAnotherConfigFile())
|
||||||
|
++firstModifiable;
|
||||||
|
|
||||||
|
if (beginRow < firstModifiable)
|
||||||
|
return false;
|
||||||
|
|
||||||
QByteArray encodedData = data->data(mMimeType);
|
QByteArray encodedData = data->data(mMimeType);
|
||||||
QDataStream stream(&encodedData, QIODevice::ReadOnly);
|
QDataStream stream(&encodedData, QIODevice::ReadOnly);
|
||||||
|
|
||||||
|
@ -449,6 +464,9 @@ void ContentSelectorModel::ContentModel::addFiles(const QString& path, bool newf
|
||||||
file->setGameFiles({});
|
file->setGameFiles({});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (info.fileName().compare("builtin.omwscripts", Qt::CaseInsensitive) == 0)
|
||||||
|
file->setBuiltIn(true);
|
||||||
|
|
||||||
if (info.fileName().endsWith(".omwscripts", Qt::CaseInsensitive))
|
if (info.fileName().endsWith(".omwscripts", Qt::CaseInsensitive))
|
||||||
{
|
{
|
||||||
file->setDate(info.lastModified());
|
file->setDate(info.lastModified());
|
||||||
|
@ -579,15 +597,20 @@ void ContentSelectorModel::ContentModel::setCurrentGameFile(const EsmFile* file)
|
||||||
void ContentSelectorModel::ContentModel::sortFiles()
|
void ContentSelectorModel::ContentModel::sortFiles()
|
||||||
{
|
{
|
||||||
emit layoutAboutToBeChanged();
|
emit layoutAboutToBeChanged();
|
||||||
|
|
||||||
|
int firstModifiable = 0;
|
||||||
|
while (mFiles.at(firstModifiable)->builtIn() || mFiles.at(firstModifiable)->fromAnotherConfigFile())
|
||||||
|
++firstModifiable;
|
||||||
|
|
||||||
// Dependency sort
|
// Dependency sort
|
||||||
std::unordered_set<const EsmFile*> moved;
|
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);
|
const auto file = mFiles.at(i);
|
||||||
if (moved.find(file) == moved.end())
|
if (moved.find(file) == moved.end())
|
||||||
{
|
{
|
||||||
int index = -1;
|
int index = -1;
|
||||||
for (int j = 0; j < i; ++j)
|
for (int j = firstModifiable; j < i; ++j)
|
||||||
{
|
{
|
||||||
const QStringList& gameFiles = mFiles.at(j)->gameFiles();
|
const QStringList& gameFiles = mFiles.at(j)->gameFiles();
|
||||||
// All addon files are implicitly dependent on the game file
|
// 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))
|
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
|
// as necessary, move plug-ins in visible list to match sequence of supplied filelist
|
||||||
const EsmFile* file = item(filepath);
|
const EsmFile* file = item(filepath);
|
||||||
int filePosition = indexFromItem(file).row();
|
int filePosition = indexFromItem(file).row();
|
||||||
|
@ -747,7 +771,7 @@ bool ContentSelectorModel::ContentModel::setCheckState(const QString& filepath,
|
||||||
|
|
||||||
const EsmFile* file = item(filepath);
|
const EsmFile* file = item(filepath);
|
||||||
|
|
||||||
if (!file)
|
if (!file || file->builtIn() || file->fromAnotherConfigFile())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (checkState)
|
if (checkState)
|
||||||
|
|
|
@ -41,6 +41,16 @@ void ContentSelectorModel::EsmFile::setDescription(const QString& description)
|
||||||
mDescription = description;
|
mDescription = description;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ContentSelectorModel::EsmFile::setBuiltIn(bool builtIn)
|
||||||
|
{
|
||||||
|
mBuiltIn = builtIn;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ContentSelectorModel::EsmFile::setFromAnotherConfigFile(bool fromAnotherConfigFile)
|
||||||
|
{
|
||||||
|
mFromAnotherConfigFile = fromAnotherConfigFile;
|
||||||
|
}
|
||||||
|
|
||||||
bool ContentSelectorModel::EsmFile::isGameFile() const
|
bool ContentSelectorModel::EsmFile::isGameFile() const
|
||||||
{
|
{
|
||||||
return (mGameFiles.size() == 0)
|
return (mGameFiles.size() == 0)
|
||||||
|
@ -76,6 +86,14 @@ QVariant ContentSelectorModel::EsmFile::fileProperty(const FileProperty prop) co
|
||||||
return mDescription;
|
return mDescription;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case FileProperty_BuiltIn:
|
||||||
|
return mBuiltIn;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case FileProperty_FromAnotherConfigFile:
|
||||||
|
return mFromAnotherConfigFile;
|
||||||
|
break;
|
||||||
|
|
||||||
case FileProperty_GameFile:
|
case FileProperty_GameFile:
|
||||||
return mGameFiles;
|
return mGameFiles;
|
||||||
break;
|
break;
|
||||||
|
@ -113,6 +131,15 @@ void ContentSelectorModel::EsmFile::setFileProperty(const FileProperty prop, con
|
||||||
mDescription = value;
|
mDescription = value;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
// todo: check these work
|
||||||
|
case FileProperty_BuiltIn:
|
||||||
|
mBuiltIn = value == "true";
|
||||||
|
break;
|
||||||
|
|
||||||
|
case FileProperty_FromAnotherConfigFile:
|
||||||
|
mFromAnotherConfigFile = value == "true";
|
||||||
|
break;
|
||||||
|
|
||||||
case FileProperty_GameFile:
|
case FileProperty_GameFile:
|
||||||
mGameFiles << value;
|
mGameFiles << value;
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -26,7 +26,9 @@ namespace ContentSelectorModel
|
||||||
FileProperty_DateModified = 3,
|
FileProperty_DateModified = 3,
|
||||||
FileProperty_FilePath = 4,
|
FileProperty_FilePath = 4,
|
||||||
FileProperty_Description = 5,
|
FileProperty_Description = 5,
|
||||||
FileProperty_GameFile = 6
|
FileProperty_BuiltIn = 6,
|
||||||
|
FileProperty_FromAnotherConfigFile = 7,
|
||||||
|
FileProperty_GameFile = 8,
|
||||||
};
|
};
|
||||||
|
|
||||||
EsmFile(const QString& fileName = QString(), ModelItem* parent = nullptr);
|
EsmFile(const QString& fileName = QString(), ModelItem* parent = nullptr);
|
||||||
|
@ -40,6 +42,8 @@ namespace ContentSelectorModel
|
||||||
void setFilePath(const QString& path);
|
void setFilePath(const QString& path);
|
||||||
void setGameFiles(const QStringList& gameFiles);
|
void setGameFiles(const QStringList& gameFiles);
|
||||||
void setDescription(const QString& description);
|
void setDescription(const QString& description);
|
||||||
|
void setBuiltIn(bool builtIn);
|
||||||
|
void setFromAnotherConfigFile(bool fromAnotherConfigFile);
|
||||||
|
|
||||||
void addGameFile(const QString& name) { mGameFiles.append(name); }
|
void addGameFile(const QString& name) { mGameFiles.append(name); }
|
||||||
QVariant fileProperty(const FileProperty prop) const;
|
QVariant fileProperty(const FileProperty prop) const;
|
||||||
|
@ -49,18 +53,27 @@ namespace ContentSelectorModel
|
||||||
QDateTime modified() const { return mModified; }
|
QDateTime modified() const { return mModified; }
|
||||||
QString formatVersion() const { return mVersion; }
|
QString formatVersion() const { return mVersion; }
|
||||||
QString filePath() const { return mPath; }
|
QString filePath() const { return mPath; }
|
||||||
|
bool builtIn() const { return mBuiltIn; }
|
||||||
|
bool fromAnotherConfigFile() const { return mFromAnotherConfigFile; }
|
||||||
|
|
||||||
/// @note Contains file names, not paths.
|
/// @note Contains file names, not paths.
|
||||||
const QStringList& gameFiles() const { return mGameFiles; }
|
const QStringList& gameFiles() const { return mGameFiles; }
|
||||||
QString description() const { return mDescription; }
|
QString description() const { return mDescription; }
|
||||||
QString toolTip() const
|
QString toolTip() const
|
||||||
{
|
{
|
||||||
return mTooltipTemlate.arg(mAuthor)
|
QString tooltip = mTooltipTemlate.arg(mAuthor)
|
||||||
.arg(mVersion)
|
.arg(mVersion)
|
||||||
.arg(mModified.toString(Qt::ISODate))
|
.arg(mModified.toString(Qt::ISODate))
|
||||||
.arg(mPath)
|
.arg(mPath)
|
||||||
.arg(mDescription)
|
.arg(mDescription)
|
||||||
.arg(mGameFiles.join(", "));
|
.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;
|
bool isGameFile() const;
|
||||||
|
@ -82,6 +95,8 @@ namespace ContentSelectorModel
|
||||||
QStringList mGameFiles;
|
QStringList mGameFiles;
|
||||||
QString mDescription;
|
QString mDescription;
|
||||||
QString mToolTip;
|
QString mToolTip;
|
||||||
|
bool mBuiltIn = false;
|
||||||
|
bool mFromAnotherConfigFile = false;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue