forked from mirror/openmw-tes3mp
Adjust plug-in order to match profile loading.
Also marks plug-ins with load order problems in red and changes tool tip to describe error.
This commit is contained in:
parent
a62e15d93d
commit
dfbd470613
7 changed files with 167 additions and 9 deletions
|
@ -116,6 +116,7 @@ if(QT_QTGUI_LIBRARY AND QT_QTCORE_LIBRARY)
|
|||
add_component_qt_dir (contentselector
|
||||
model/modelitem model/esmfile
|
||||
model/naturalsort model/contentmodel
|
||||
model/loadordererror
|
||||
view/combobox view/contentselector
|
||||
)
|
||||
add_component_qt_dir (config
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
#include <QDir>
|
||||
#include <QTextCodec>
|
||||
#include <QDebug>
|
||||
#include <qbrush>
|
||||
|
||||
#include "components/esm/esmreader.hpp"
|
||||
|
||||
|
@ -170,6 +171,16 @@ QVariant ContentSelectorModel::ContentModel::data(const QModelIndex &index, int
|
|||
|
||||
switch (role)
|
||||
{
|
||||
case Qt::ForegroundRole:
|
||||
{
|
||||
if (isLoadOrderError(file->filePath()))
|
||||
{
|
||||
QBrush redBackground(Qt::red, Qt::SolidPattern);
|
||||
return redBackground;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case Qt::EditRole:
|
||||
case Qt::DisplayRole:
|
||||
{
|
||||
|
@ -202,7 +213,7 @@ QVariant ContentSelectorModel::ContentModel::data(const QModelIndex &index, int
|
|||
if (column != 0)
|
||||
return QVariant();
|
||||
|
||||
return file->toolTip();
|
||||
return isLoadOrderError(file->filePath()) ? getLoadOrderError(file->filePath()).toolTip() : file->toolTip();
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -341,6 +352,8 @@ bool ContentSelectorModel::ContentModel::removeRows(int position, int rows, cons
|
|||
|
||||
} endRemoveRows();
|
||||
|
||||
// at this point we know that drag and drop has finished.
|
||||
checkForLoadOrderErrors();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -530,11 +543,83 @@ bool ContentSelectorModel::ContentModel::isEnabled (QModelIndex index) const
|
|||
return (flags(index) & Qt::ItemIsEnabled);
|
||||
}
|
||||
|
||||
void ContentSelectorModel::ContentModel::setCheckStates (const QStringList &fileList, bool isChecked)
|
||||
bool ContentSelectorModel::ContentModel::isLoadOrderError(const QString& filepath) const
|
||||
{
|
||||
foreach (const QString &file, fileList)
|
||||
return !(getLoadOrderError(filepath) == LoadOrderError::sNoError);
|
||||
}
|
||||
|
||||
ContentSelectorModel::LoadOrderError ContentSelectorModel::ContentModel::getLoadOrderError(const QString& filepath) const
|
||||
{
|
||||
return mLoadOrderErrors.contains(filepath) ? mLoadOrderErrors[filepath] : ContentSelectorModel::LoadOrderError::sNoError;
|
||||
}
|
||||
|
||||
void ContentSelectorModel::ContentModel::setLoadOrderError(const QString& filepath, const ContentSelectorModel::LoadOrderError& loadOrderError)
|
||||
{
|
||||
mLoadOrderErrors[filepath] = loadOrderError;
|
||||
int filePosition = indexFromItem(item(filepath)).row();
|
||||
emit dataChanged(index(filePosition, 0, QModelIndex()), index(filePosition, 0, QModelIndex()));
|
||||
}
|
||||
|
||||
void ContentSelectorModel::ContentModel::setContentList(const QStringList &fileList, bool isChecked)
|
||||
{
|
||||
mLoadOrderErrors.clear();
|
||||
int previousPosition = -1;
|
||||
foreach (const QString &filepath, fileList)
|
||||
{
|
||||
setCheckState (file, isChecked);
|
||||
if (setCheckState(filepath, isChecked))
|
||||
{
|
||||
// as necessary, move plug-ins in visible list to match sequence of supplied filelist
|
||||
const EsmFile* file = item(filepath);
|
||||
int filePosition = indexFromItem(file).row();
|
||||
if (filePosition < previousPosition)
|
||||
{
|
||||
mFiles.move(filePosition, previousPosition);
|
||||
emit dataChanged(index(filePosition, 0, QModelIndex()), index(previousPosition, 0, QModelIndex()));
|
||||
}
|
||||
else
|
||||
{
|
||||
previousPosition = filePosition;
|
||||
}
|
||||
}
|
||||
}
|
||||
checkForLoadOrderErrors();
|
||||
}
|
||||
|
||||
void ContentSelectorModel::ContentModel::checkForLoadOrderErrors()
|
||||
{
|
||||
for (int row = 0; row < mFiles.count(); ++row)
|
||||
{
|
||||
EsmFile* file = item(row);
|
||||
bool isRowInError = isLoadOrderError(file->filePath());
|
||||
LoadOrderError::ErrorCode error = LoadOrderError::ErrorCode_None;
|
||||
foreach(QString dependantfileName, file->gameFiles())
|
||||
{
|
||||
const EsmFile* dependentFile = item(dependantfileName);
|
||||
|
||||
if (!dependentFile)
|
||||
{
|
||||
error = LoadOrderError::ErrorCode_MissingDependency;
|
||||
}
|
||||
else if (!isChecked(dependentFile->filePath()))
|
||||
{
|
||||
error = LoadOrderError::ErrorCode_InactiveDependency;
|
||||
}
|
||||
else if (row < indexFromItem(dependentFile).row())
|
||||
{
|
||||
error = LoadOrderError::ErrorCode_LoadOrder;
|
||||
}
|
||||
|
||||
if (!isRowInError && (error != LoadOrderError::ErrorCode_None))
|
||||
{
|
||||
setLoadOrderError(file->filePath(), LoadOrderError(error, dependantfileName));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (isRowInError && (error == LoadOrderError::ErrorCode_None))
|
||||
{
|
||||
setLoadOrderError(file->filePath(), LoadOrderError::sNoError);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -4,6 +4,8 @@
|
|||
#include <QAbstractTableModel>
|
||||
#include <QStringList>
|
||||
|
||||
#include "loadordererror.hpp"
|
||||
|
||||
namespace ContentSelectorModel
|
||||
{
|
||||
class EsmFile;
|
||||
|
@ -47,10 +49,14 @@ namespace ContentSelectorModel
|
|||
bool isEnabled (QModelIndex index) const;
|
||||
bool isChecked(const QString &filepath) const;
|
||||
bool setCheckState(const QString &filepath, bool isChecked);
|
||||
void setCheckStates (const QStringList &fileList, bool isChecked);
|
||||
void setContentList(const QStringList &fileList, bool isChecked);
|
||||
ContentFileList checkedItems() const;
|
||||
void uncheckAll();
|
||||
|
||||
bool isLoadOrderError(const QString& filepath) const;
|
||||
ContentSelectorModel::LoadOrderError ContentSelectorModel::ContentModel::getLoadOrderError(const QString& filepath) const;
|
||||
void ContentSelectorModel::ContentModel::setLoadOrderError(const QString& filepath, const ContentSelectorModel::LoadOrderError& loadOrderError);
|
||||
|
||||
void refreshModel();
|
||||
|
||||
private:
|
||||
|
@ -60,9 +66,12 @@ namespace ContentSelectorModel
|
|||
EsmFile *item(int row);
|
||||
|
||||
void sortFiles();
|
||||
void checkForLoadOrderErrors();
|
||||
|
||||
|
||||
ContentFileList mFiles;
|
||||
QHash<QString, Qt::CheckState> mCheckStates;
|
||||
QHash<QString, LoadOrderError> mLoadOrderErrors;
|
||||
QTextCodec *mCodec;
|
||||
QString mEncoding;
|
||||
|
||||
|
|
22
components/contentselector/model/loadordererror.cpp
Normal file
22
components/contentselector/model/loadordererror.cpp
Normal file
|
@ -0,0 +1,22 @@
|
|||
#include "loadordererror.hpp"
|
||||
#include <assert.h>
|
||||
|
||||
QString ContentSelectorModel::LoadOrderError::sErrorToolTips[ErrorCode_LoadOrder] =
|
||||
{
|
||||
QString("Unable to find dependant file: %1"),
|
||||
QString("Dependent file needs to be active: %1"),
|
||||
QString("This file needs to load after %1"),
|
||||
};
|
||||
|
||||
ContentSelectorModel::LoadOrderError ContentSelectorModel::LoadOrderError::sNoError = ContentSelectorModel::LoadOrderError();
|
||||
|
||||
QString ContentSelectorModel::LoadOrderError::toolTip() const
|
||||
{
|
||||
assert(mErrorCode);
|
||||
return sErrorToolTips[mErrorCode - 1].arg(mFileName);
|
||||
}
|
||||
|
||||
bool ContentSelectorModel::LoadOrderError::operator== (const ContentSelectorModel::LoadOrderError& rhs) const
|
||||
{
|
||||
return (mErrorCode == rhs.mErrorCode) && ((mErrorCode == ErrorCode_None) || (mFileName == rhs.mFileName));
|
||||
}
|
41
components/contentselector/model/loadordererror.hpp
Normal file
41
components/contentselector/model/loadordererror.hpp
Normal file
|
@ -0,0 +1,41 @@
|
|||
#ifndef LOADORDERERROR_HPP
|
||||
#define LOADORDERERROR_HPP
|
||||
|
||||
#include <QString>
|
||||
|
||||
namespace ContentSelectorModel
|
||||
{
|
||||
/// \Details of a suspected Load Order problem a plug-in will have. This is basically a POD
|
||||
class LoadOrderError
|
||||
{
|
||||
public:
|
||||
enum ErrorCode
|
||||
{
|
||||
ErrorCode_None = 0,
|
||||
ErrorCode_MissingDependency = 1,
|
||||
ErrorCode_InactiveDependency = 2,
|
||||
ErrorCode_LoadOrder = 3,
|
||||
};
|
||||
|
||||
inline LoadOrderError() : mErrorCode(ErrorCode_None) {};
|
||||
inline LoadOrderError(ErrorCode errorCode, QString fileName)
|
||||
{
|
||||
mErrorCode = errorCode;
|
||||
mFileName = fileName;
|
||||
}
|
||||
inline ErrorCode errorCode() const { return mErrorCode; }
|
||||
inline QString fileName() const { return mFileName; }
|
||||
bool operator==(const LoadOrderError& rhs) const;
|
||||
QString toolTip() const;
|
||||
|
||||
/// \Sentinal to represent a "No Load Order Error" condition
|
||||
static LoadOrderError sNoError;
|
||||
|
||||
private:
|
||||
ErrorCode mErrorCode;
|
||||
QString mFileName;
|
||||
static QString sErrorToolTips[ErrorCode_LoadOrder];
|
||||
};
|
||||
}
|
||||
|
||||
#endif // LOADORDERERROR_HPP
|
|
@ -75,7 +75,7 @@ void ContentSelectorView::ContentSelector::setProfileContent(const QStringList &
|
|||
}
|
||||
}
|
||||
|
||||
setCheckStates (fileList);
|
||||
setContentList(fileList);
|
||||
}
|
||||
|
||||
void ContentSelectorView::ContentSelector::setGameFile(const QString &filename)
|
||||
|
@ -103,14 +103,14 @@ void ContentSelectorView::ContentSelector::clearCheckStates()
|
|||
mContentModel->uncheckAll();
|
||||
}
|
||||
|
||||
void ContentSelectorView::ContentSelector::setCheckStates(const QStringList &list)
|
||||
void ContentSelectorView::ContentSelector::setContentList(const QStringList &list)
|
||||
{
|
||||
if (list.isEmpty())
|
||||
{
|
||||
slotCurrentGameFileIndexChanged (ui.gameFileView->currentIndex());
|
||||
}
|
||||
else
|
||||
mContentModel->setCheckStates (list, true);
|
||||
mContentModel->setContentList(list, true);
|
||||
}
|
||||
|
||||
ContentSelectorModel::ContentFileList
|
||||
|
|
|
@ -32,7 +32,7 @@ namespace ContentSelectorView
|
|||
void setProfileContent (const QStringList &fileList);
|
||||
|
||||
void clearCheckStates();
|
||||
void setCheckStates (const QStringList &list);
|
||||
void setContentList(const QStringList &list);
|
||||
|
||||
ContentSelectorModel::ContentFileList selectedFiles() const;
|
||||
|
||||
|
|
Loading…
Reference in a new issue