forked from teamnwah/openmw-tes3coop
Fix broken launcher content file display / selection scheme
Disable selection of content files with missing dependencies (grayed out)
This commit is contained in:
parent
12c06a5615
commit
1d4b5a2425
5 changed files with 93 additions and 54 deletions
|
@ -79,8 +79,7 @@ void Launcher::DataFilesPage::loadSettings()
|
|||
//throw addons error here.
|
||||
}
|
||||
*/
|
||||
if (foundFiles.size() > 0)
|
||||
mSelector->setCheckStates (foundFiles);
|
||||
mSelector->setCheckStates (foundFiles);
|
||||
}
|
||||
|
||||
void Launcher::DataFilesPage::saveSettings(const QString &profile)
|
||||
|
@ -177,7 +176,7 @@ void Launcher::DataFilesPage::setProfile (const QString &previous, const QString
|
|||
if (!previous.isEmpty() && savePrevious)
|
||||
saveSettings (previous);
|
||||
|
||||
ui.profilesComboBox->setCurrentIndex (ui.profilesComboBox->findText (current));
|
||||
ui.profilesComboBox->setCurrentProfile (ui.profilesComboBox->findText (current));
|
||||
|
||||
loadSettings();
|
||||
|
||||
|
@ -232,7 +231,7 @@ void Launcher::DataFilesPage::setupDataFiles()
|
|||
foreach (const QString &item, profiles)
|
||||
addProfile (item, false);
|
||||
|
||||
addProfile (profile, true);
|
||||
setProfile (ui.profilesComboBox->findText(profile), false);
|
||||
|
||||
loadSettings();
|
||||
}
|
||||
|
@ -289,6 +288,10 @@ void Launcher::DataFilesPage::on_deleteProfileAction_triggered()
|
|||
// Remove the profile from the combobox
|
||||
ui.profilesComboBox->removeItem (ui.profilesComboBox->findText (profile));
|
||||
|
||||
removeProfile(profile);
|
||||
|
||||
saveSettings();
|
||||
|
||||
loadSettings();
|
||||
|
||||
checkForDefaultProfile();
|
||||
|
|
|
@ -4,6 +4,8 @@
|
|||
#include "components/contentselector/view/combobox.hpp"
|
||||
#include "lineedit.hpp"
|
||||
|
||||
#include <QDebug>
|
||||
|
||||
class QString;
|
||||
|
||||
class ProfilesComboBox : public ContentSelectorView::ComboBox
|
||||
|
@ -21,6 +23,11 @@ public:
|
|||
|
||||
explicit ProfilesComboBox(QWidget *parent = 0);
|
||||
void setEditEnabled(bool editable);
|
||||
void setCurrentProfile(int index)
|
||||
{
|
||||
ComboBox::setCurrentIndex(index);
|
||||
mOldProfile = currentText();
|
||||
}
|
||||
|
||||
signals:
|
||||
void signalProfileTextChanged(const QString &item);
|
||||
|
|
|
@ -13,7 +13,6 @@ ContentSelectorModel::ContentModel::ContentModel(QObject *parent) :
|
|||
mMimeTypes (QStringList() << mMimeType),
|
||||
mColumnCount (1),
|
||||
mDragDropFlags (Qt::ItemIsDragEnabled | Qt::ItemIsDropEnabled),
|
||||
mDefaultFlags (Qt::ItemIsDropEnabled | Qt::ItemIsSelectable),
|
||||
mDropActions (Qt::CopyAction | Qt::MoveAction)
|
||||
{
|
||||
setEncoding ("win1252");
|
||||
|
@ -102,10 +101,53 @@ Qt::ItemFlags ContentSelectorModel::ContentModel::flags(const QModelIndex &index
|
|||
if (!file)
|
||||
return Qt::NoItemFlags;
|
||||
|
||||
if (canBeChecked(file))
|
||||
return Qt::ItemIsEnabled | mDragDropFlags | mDefaultFlags;
|
||||
//game files can always be checked
|
||||
if (file->isGameFile())
|
||||
return Qt::ItemIsEnabled | Qt::ItemIsSelectable;
|
||||
|
||||
return Qt::NoItemFlags;
|
||||
Qt::ItemFlags returnFlags;
|
||||
bool allDependenciesFound = true;
|
||||
bool gamefileChecked = false;
|
||||
|
||||
//addon can be checked if its gamefile is and all other dependencies exist
|
||||
foreach (const QString &fileName, file->gameFiles())
|
||||
{
|
||||
bool depFound = false;
|
||||
foreach (EsmFile *dependency, mFiles)
|
||||
{
|
||||
//compare filenames only. Multiple instances
|
||||
//of the filename (with different paths) is not relevant here.
|
||||
depFound = (dependency->fileName() == fileName);
|
||||
|
||||
if (!depFound)
|
||||
continue;
|
||||
|
||||
if (!gamefileChecked)
|
||||
{
|
||||
if (isChecked (dependency->filePath()))
|
||||
gamefileChecked = (dependency->isGameFile());
|
||||
}
|
||||
|
||||
// force it to iterate all files in cases where the current
|
||||
// dependency is a game file to ensure that a later duplicate
|
||||
// game file is / is not checked.
|
||||
// (i.e., break only if it's not a gamefile or the game file has been checked previously)
|
||||
if (gamefileChecked || !(dependency->isGameFile()))
|
||||
break;
|
||||
}
|
||||
|
||||
allDependenciesFound = allDependenciesFound && depFound;
|
||||
}
|
||||
|
||||
if (gamefileChecked)
|
||||
{
|
||||
if (allDependenciesFound)
|
||||
returnFlags = returnFlags | Qt::ItemIsEnabled | Qt::ItemIsSelectable | mDragDropFlags;
|
||||
else
|
||||
returnFlags = Qt::ItemIsSelectable;
|
||||
}
|
||||
|
||||
return returnFlags;
|
||||
}
|
||||
|
||||
QVariant ContentSelectorModel::ContentModel::data(const QModelIndex &index, int role) const
|
||||
|
@ -173,7 +215,7 @@ QVariant ContentSelectorModel::ContentModel::data(const QModelIndex &index, int
|
|||
if (file->isGameFile())
|
||||
return ContentType_GameFile;
|
||||
else
|
||||
if (flags(index) & mDefaultFlags)
|
||||
if (flags(index))
|
||||
return ContentType_Addon;
|
||||
|
||||
break;
|
||||
|
@ -215,19 +257,13 @@ bool ContentSelectorModel::ContentModel::setData(const QModelIndex &index, const
|
|||
|
||||
case Qt::UserRole+1:
|
||||
{
|
||||
setCheckState(fileName, value.toBool());
|
||||
success = (flags (index) & Qt::ItemIsEnabled);
|
||||
|
||||
emit dataChanged(index, index);
|
||||
|
||||
foreach (EsmFile *file, mFiles)
|
||||
if (success)
|
||||
{
|
||||
if (file->gameFiles().contains(fileName))
|
||||
{
|
||||
QModelIndex idx = indexFromItem(file);
|
||||
emit dataChanged(idx, idx);
|
||||
}
|
||||
success = setCheckState(fileName, value.toBool());
|
||||
emit dataChanged(index, index);
|
||||
}
|
||||
success = true;
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -377,32 +413,6 @@ bool ContentSelectorModel::ContentModel::dropMimeData(const QMimeData *data, Qt:
|
|||
return true;
|
||||
}
|
||||
|
||||
bool ContentSelectorModel::ContentModel::canBeChecked(const EsmFile *file) const
|
||||
{
|
||||
//game files can always be checked
|
||||
if (file->isGameFile())
|
||||
return true;
|
||||
|
||||
//addon can be checked if its gamefile is
|
||||
foreach (const QString &fileName, file->gameFiles())
|
||||
{
|
||||
foreach (EsmFile *dependency, mFiles)
|
||||
{
|
||||
//compare filenames only. Multiple instances
|
||||
//of the filename (with different paths) is not relevant here.
|
||||
if (!(dependency->fileName() == fileName))
|
||||
continue;
|
||||
|
||||
if (dependency->isGameFile())
|
||||
{
|
||||
if (isChecked(dependency->filePath()))
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void ContentSelectorModel::ContentModel::addFile(EsmFile *file)
|
||||
{
|
||||
beginInsertRows(QModelIndex(), mFiles.count(), mFiles.count());
|
||||
|
@ -510,6 +520,11 @@ bool ContentSelectorModel::ContentModel::isChecked(const QString& name) const
|
|||
return false;
|
||||
}
|
||||
|
||||
bool ContentSelectorModel::ContentModel::isEnabled (QModelIndex index) const
|
||||
{
|
||||
return (flags(index) & Qt::ItemIsEnabled);
|
||||
}
|
||||
|
||||
void ContentSelectorModel::ContentModel::setCheckStates (const QStringList &fileList, bool isChecked)
|
||||
{
|
||||
foreach (const QString &file, fileList)
|
||||
|
@ -518,6 +533,11 @@ void ContentSelectorModel::ContentModel::setCheckStates (const QStringList &file
|
|||
}
|
||||
}
|
||||
|
||||
void ContentSelectorModel::ContentModel::refreshModel()
|
||||
{
|
||||
emit dataChanged (index(0,0), index(rowCount()-1,0));
|
||||
}
|
||||
|
||||
bool ContentSelectorModel::ContentModel::setCheckState(const QString &name, bool checkState)
|
||||
{
|
||||
if (name.isEmpty())
|
||||
|
@ -537,7 +557,7 @@ bool ContentSelectorModel::ContentModel::setCheckState(const QString &name, bool
|
|||
emit dataChanged(indexFromItem(item(name)), indexFromItem(item(name)));
|
||||
|
||||
if (file->isGameFile())
|
||||
emit dataChanged (index(0,0), index(rowCount()-1,0));
|
||||
refreshModel();
|
||||
|
||||
//if we're checking an item, ensure all "upstream" files (dependencies) are checked as well.
|
||||
if (state == Qt::Checked)
|
||||
|
|
|
@ -44,19 +44,21 @@ namespace ContentSelectorModel
|
|||
QModelIndex indexFromItem(const EsmFile *item) const;
|
||||
const EsmFile *item(const QString &name) const;
|
||||
|
||||
bool isEnabled (QModelIndex index) const;
|
||||
bool isChecked(const QString &name) const;
|
||||
bool setCheckState(const QString &name, bool isChecked);
|
||||
void setCheckStates (const QStringList &fileList, bool isChecked);
|
||||
ContentFileList checkedItems() const;
|
||||
void uncheckAll();
|
||||
|
||||
void refreshModel();
|
||||
|
||||
private:
|
||||
|
||||
void addFile(EsmFile *file);
|
||||
const EsmFile *item(int row) const;
|
||||
EsmFile *item(int row);
|
||||
|
||||
bool canBeChecked(const EsmFile *file) const;
|
||||
void sortFiles();
|
||||
|
||||
ContentFileList mFiles;
|
||||
|
@ -69,7 +71,6 @@ namespace ContentSelectorModel
|
|||
QStringList mMimeTypes;
|
||||
int mColumnCount;
|
||||
Qt::ItemFlags mDragDropFlags;
|
||||
Qt::ItemFlags mDefaultFlags;
|
||||
Qt::DropActions mDropActions;
|
||||
};
|
||||
}
|
||||
|
|
|
@ -12,6 +12,8 @@
|
|||
#include <QModelIndex>
|
||||
#include <assert.h>
|
||||
|
||||
#include <QDebug>
|
||||
|
||||
ContentSelectorView::ContentSelector::ContentSelector(QWidget *parent) :
|
||||
QObject(parent)
|
||||
{
|
||||
|
@ -89,9 +91,12 @@ void ContentSelectorView::ContentSelector::clearCheckStates()
|
|||
void ContentSelectorView::ContentSelector::setCheckStates(const QStringList &list)
|
||||
{
|
||||
if (list.isEmpty())
|
||||
return;
|
||||
|
||||
mContentModel->setCheckStates (list, true);
|
||||
{
|
||||
qDebug() << "refreshing model";
|
||||
slotCurrentGameFileIndexChanged (ui.gameFileView->currentIndex());
|
||||
}
|
||||
else
|
||||
mContentModel->setCheckStates (list, true);
|
||||
}
|
||||
|
||||
ContentSelectorModel::ContentFileList
|
||||
|
@ -152,14 +157,17 @@ void ContentSelectorView::ContentSelector::slotCurrentGameFileIndexChanged(int i
|
|||
|
||||
void ContentSelectorView::ContentSelector::slotAddonTableItemClicked(const QModelIndex &index)
|
||||
{
|
||||
QAbstractItemModel *const model = ui.addonView->model();
|
||||
QModelIndex sourceIndex = mAddonProxyModel->mapToSource (index);
|
||||
|
||||
if (!mContentModel->isEnabled (sourceIndex))
|
||||
return;
|
||||
|
||||
Qt::CheckState checkState = Qt::Unchecked;
|
||||
|
||||
if (model->data(index, Qt::CheckStateRole).toInt() == Qt::Unchecked)
|
||||
if (mContentModel->data(sourceIndex, Qt::CheckStateRole).toInt() == Qt::Unchecked)
|
||||
checkState = Qt::Checked;
|
||||
|
||||
model->setData(index, checkState, Qt::CheckStateRole);
|
||||
mContentModel->setData(sourceIndex, checkState, Qt::CheckStateRole);
|
||||
|
||||
if (checkState == Qt::Checked)
|
||||
emit signalAddonFileSelected (index.row());
|
||||
|
|
Loading…
Reference in a new issue