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.
openmw-35
dteviot 10 years ago
parent a62e15d93d
commit dfbd470613

@ -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
{
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)
{
foreach (const QString &file, fileList)
mLoadOrderErrors.clear();
int previousPosition = -1;
foreach (const QString &filepath, fileList)
{
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)
{
setCheckState (file, isChecked);
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;

@ -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));
}

@ -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…
Cancel
Save