mirror of
https://github.com/OpenMW/openmw.git
synced 2025-04-01 21:36:42 +00:00
Merge remote-tracking branch 'mike-sc/sel_widget' into settings_selwidget
Conflicts: apps/launcher/datafilespage.cpp components/fileorderlist/datafileslist.cpp
This commit is contained in:
commit
fd430dc5a9
6 changed files with 104 additions and 262 deletions
|
@ -742,6 +742,8 @@ void DataFilesPage::showContextMenu(const QPoint &point)
|
||||||
: mCheckAction->setEnabled(true);
|
: mCheckAction->setEnabled(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Show menu
|
// Show menu
|
||||||
mContextMenu->exec(globalPos);
|
mContextMenu->exec(globalPos);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,7 +7,6 @@
|
||||||
#include "model/esm/esmfile.hpp"
|
#include "model/esm/esmfile.hpp"
|
||||||
|
|
||||||
#include "utils/lineedit.hpp"
|
#include "utils/lineedit.hpp"
|
||||||
#include "utils/naturalsort.hpp"
|
|
||||||
|
|
||||||
#include "datafileslist.hpp"
|
#include "datafileslist.hpp"
|
||||||
|
|
||||||
|
@ -47,13 +46,12 @@ DataFilesList::DataFilesList(Files::ConfigurationManager &cfg, QWidget *parent)
|
||||||
: QWidget(parent)
|
: QWidget(parent)
|
||||||
, mCfgMgr(cfg)
|
, mCfgMgr(cfg)
|
||||||
{
|
{
|
||||||
// Models
|
// Model
|
||||||
mMastersModel = new DataFilesModel(this);
|
mFilesModel = new DataFilesModel(this);
|
||||||
mPluginsModel = new DataFilesModel(this);
|
|
||||||
|
|
||||||
mPluginsProxyModel = new QSortFilterProxyModel();
|
mFilesProxyModel = new QSortFilterProxyModel();
|
||||||
mPluginsProxyModel->setDynamicSortFilter(true);
|
mFilesProxyModel->setDynamicSortFilter(true);
|
||||||
mPluginsProxyModel->setSourceModel(mPluginsModel);
|
mFilesProxyModel->setSourceModel(mFilesModel);
|
||||||
|
|
||||||
// Filter toolbar
|
// Filter toolbar
|
||||||
QLabel *filterLabel = new QLabel(tr("&Filter:"), this);
|
QLabel *filterLabel = new QLabel(tr("&Filter:"), this);
|
||||||
|
@ -77,76 +75,41 @@ DataFilesList::DataFilesList(Files::ConfigurationManager &cfg, QWidget *parent)
|
||||||
QCheckBox checkBox;
|
QCheckBox checkBox;
|
||||||
unsigned int height = checkBox.sizeHint().height() + 4;
|
unsigned int height = checkBox.sizeHint().height() + 4;
|
||||||
|
|
||||||
mMastersTable = new QTableView(this);
|
mFilesTable = new QTableView(this);
|
||||||
mMastersTable->setModel(mMastersModel);
|
mFilesTable->setModel(mFilesProxyModel);
|
||||||
mMastersTable->setObjectName("MastersTable");
|
mFilesTable->setObjectName("PluginsTable");
|
||||||
mMastersTable->setSelectionBehavior(QAbstractItemView::SelectRows);
|
mFilesTable->setContextMenuPolicy(Qt::CustomContextMenu);
|
||||||
mMastersTable->setSelectionMode(QAbstractItemView::SingleSelection);
|
mFilesTable->setSelectionBehavior(QAbstractItemView::SelectRows);
|
||||||
mMastersTable->setEditTriggers(QAbstractItemView::NoEditTriggers);
|
mFilesTable->setSelectionMode(QAbstractItemView::SingleSelection);
|
||||||
mMastersTable->setAlternatingRowColors(true);
|
mFilesTable->setEditTriggers(QAbstractItemView::NoEditTriggers);
|
||||||
mMastersTable->horizontalHeader()->setStretchLastSection(true);
|
mFilesTable->setAlternatingRowColors(true);
|
||||||
mMastersTable->horizontalHeader()->hide();
|
mFilesTable->setVerticalScrollMode(QAbstractItemView::ScrollPerItem);
|
||||||
|
mFilesTable->horizontalHeader()->setStretchLastSection(true);
|
||||||
|
mFilesTable->horizontalHeader()->hide();
|
||||||
|
|
||||||
// Set the row height to the size of the checkboxes
|
mFilesTable->verticalHeader()->setDefaultSectionSize(height);
|
||||||
mMastersTable->verticalHeader()->setDefaultSectionSize(height);
|
mFilesTable->verticalHeader()->setResizeMode(QHeaderView::Fixed);
|
||||||
mMastersTable->verticalHeader()->setResizeMode(QHeaderView::Fixed);
|
mFilesTable->setColumnHidden(1, true);
|
||||||
mMastersTable->verticalHeader()->hide();
|
mFilesTable->setColumnHidden(2, true);
|
||||||
mMastersTable->setColumnHidden(1, true);
|
mFilesTable->setColumnHidden(3, true);
|
||||||
mMastersTable->setColumnHidden(2, true);
|
mFilesTable->setColumnHidden(4, true);
|
||||||
mMastersTable->setColumnHidden(3, true);
|
mFilesTable->setColumnHidden(5, true);
|
||||||
mMastersTable->setColumnHidden(4, true);
|
mFilesTable->setColumnHidden(6, true);
|
||||||
mMastersTable->setColumnHidden(5, true);
|
mFilesTable->setColumnHidden(7, true);
|
||||||
mMastersTable->setColumnHidden(6, true);
|
mFilesTable->setColumnHidden(8, true);
|
||||||
mMastersTable->setColumnHidden(7, true);
|
|
||||||
mMastersTable->setColumnHidden(8, true);
|
|
||||||
|
|
||||||
mPluginsTable = new QTableView(this);
|
|
||||||
mPluginsTable->setModel(mPluginsProxyModel);
|
|
||||||
mPluginsTable->setObjectName("PluginsTable");
|
|
||||||
mPluginsTable->setContextMenuPolicy(Qt::CustomContextMenu);
|
|
||||||
mPluginsTable->setSelectionBehavior(QAbstractItemView::SelectRows);
|
|
||||||
mPluginsTable->setSelectionMode(QAbstractItemView::SingleSelection);
|
|
||||||
mPluginsTable->setEditTriggers(QAbstractItemView::NoEditTriggers);
|
|
||||||
mPluginsTable->setAlternatingRowColors(true);
|
|
||||||
mPluginsTable->setVerticalScrollMode(QAbstractItemView::ScrollPerItem);
|
|
||||||
mPluginsTable->horizontalHeader()->setStretchLastSection(true);
|
|
||||||
mPluginsTable->horizontalHeader()->hide();
|
|
||||||
|
|
||||||
mPluginsTable->verticalHeader()->setDefaultSectionSize(height);
|
|
||||||
mPluginsTable->verticalHeader()->setResizeMode(QHeaderView::Fixed);
|
|
||||||
mPluginsTable->setColumnHidden(1, true);
|
|
||||||
mPluginsTable->setColumnHidden(2, true);
|
|
||||||
mPluginsTable->setColumnHidden(3, true);
|
|
||||||
mPluginsTable->setColumnHidden(4, true);
|
|
||||||
mPluginsTable->setColumnHidden(5, true);
|
|
||||||
mPluginsTable->setColumnHidden(6, true);
|
|
||||||
mPluginsTable->setColumnHidden(7, true);
|
|
||||||
mPluginsTable->setColumnHidden(8, true);
|
|
||||||
|
|
||||||
// Add both tables to a splitter
|
|
||||||
QSplitter *splitter = new QSplitter(this);
|
|
||||||
splitter->setOrientation(Qt::Horizontal);
|
|
||||||
splitter->addWidget(mMastersTable);
|
|
||||||
splitter->addWidget(mPluginsTable);
|
|
||||||
|
|
||||||
// Adjust the default widget widths inside the splitter
|
|
||||||
QList<int> sizeList;
|
|
||||||
sizeList << 175 << 200;
|
|
||||||
splitter->setSizes(sizeList);
|
|
||||||
|
|
||||||
QVBoxLayout *pageLayout = new QVBoxLayout(this);
|
QVBoxLayout *pageLayout = new QVBoxLayout(this);
|
||||||
|
|
||||||
pageLayout->addWidget(filterToolBar);
|
pageLayout->addWidget(filterToolBar);
|
||||||
pageLayout->addWidget(splitter);
|
pageLayout->addWidget(mFilesTable);
|
||||||
|
|
||||||
connect(mPluginsTable, SIGNAL(doubleClicked(QModelIndex)), this, SLOT(setCheckState(QModelIndex)));
|
connect(mFilesTable, SIGNAL(doubleClicked(QModelIndex)), this, SLOT(setCheckState(QModelIndex)));
|
||||||
connect(mMastersTable, SIGNAL(doubleClicked(QModelIndex)), this, SLOT(setCheckState(QModelIndex)));
|
|
||||||
|
connect(mFilesModel, SIGNAL(checkedItemsChanged(QStringList,QStringList)), mFilesModel, SLOT(slotcheckedItemsChanged(QStringList,QStringList)));
|
||||||
connect(mMastersModel, SIGNAL(checkedItemsChanged(QStringList,QStringList)), mPluginsModel, SLOT(slotcheckedItemsChanged(QStringList,QStringList)));
|
|
||||||
|
|
||||||
connect(filterLineEdit, SIGNAL(textChanged(QString)), this, SLOT(filterChanged(QString)));
|
connect(filterLineEdit, SIGNAL(textChanged(QString)), this, SLOT(filterChanged(QString)));
|
||||||
|
|
||||||
connect(mPluginsTable, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(showContextMenu(QPoint)));
|
connect(mFilesTable, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(showContextMenu(QPoint)));
|
||||||
|
|
||||||
createActions();
|
createActions();
|
||||||
}
|
}
|
||||||
|
@ -177,20 +140,17 @@ bool DataFilesList::setupDataFiles(Files::PathContainer dataDirs, const QString
|
||||||
{
|
{
|
||||||
// Set the charset for reading the esm/esp files
|
// Set the charset for reading the esm/esp files
|
||||||
if (!encoding.isEmpty() && encoding != QLatin1String("win1252")) {
|
if (!encoding.isEmpty() && encoding != QLatin1String("win1252")) {
|
||||||
mMastersModel->setEncoding(encoding);
|
mFilesModel->setEncoding(encoding);
|
||||||
mPluginsModel->setEncoding(encoding);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add the paths to the respective models
|
// Add the paths to the respective models
|
||||||
for (Files::PathContainer::iterator it = dataDirs.begin(); it != dataDirs.end(); ++it) {
|
for (Files::PathContainer::iterator it = dataDirs.begin(); it != dataDirs.end(); ++it) {
|
||||||
QString path = QString::fromStdString(it->string());
|
QString path = QString::fromStdString(it->string());
|
||||||
path.remove(QChar('\"'));
|
path.remove(QChar('\"'));
|
||||||
mMastersModel->addMasters(path);
|
mFilesModel->addFiles(path);
|
||||||
mPluginsModel->addPlugins(path);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
mMastersModel->sort(0);
|
mFilesModel->sort(0);
|
||||||
mPluginsModel->sort(0);
|
|
||||||
// mMastersTable->sortByColumn(3, Qt::AscendingOrder);
|
// mMastersTable->sortByColumn(3, Qt::AscendingOrder);
|
||||||
// mPluginsTable->sortByColumn(3, Qt::AscendingOrder);
|
// mPluginsTable->sortByColumn(3, Qt::AscendingOrder);
|
||||||
|
|
||||||
|
@ -199,12 +159,7 @@ bool DataFilesList::setupDataFiles(Files::PathContainer dataDirs, const QString
|
||||||
|
|
||||||
void DataFilesList::selectedFiles(std::vector<boost::filesystem::path>& paths)
|
void DataFilesList::selectedFiles(std::vector<boost::filesystem::path>& paths)
|
||||||
{
|
{
|
||||||
QStringList masterPaths = mMastersModel->checkedItemsPaths();
|
QStringList pluginPaths = mFilesModel->checkedItemsPaths();
|
||||||
foreach (const QString &path, masterPaths)
|
|
||||||
{
|
|
||||||
paths.push_back(path.toStdString());
|
|
||||||
}
|
|
||||||
QStringList pluginPaths = mPluginsModel->checkedItemsPaths();
|
|
||||||
foreach (const QString &path, pluginPaths)
|
foreach (const QString &path, pluginPaths)
|
||||||
{
|
{
|
||||||
paths.push_back(path.toStdString());
|
paths.push_back(path.toStdString());
|
||||||
|
@ -214,11 +169,11 @@ void DataFilesList::selectedFiles(std::vector<boost::filesystem::path>& paths)
|
||||||
void DataFilesList::check()
|
void DataFilesList::check()
|
||||||
{
|
{
|
||||||
// Check the current selection
|
// Check the current selection
|
||||||
if (!mPluginsTable->selectionModel()->hasSelection()) {
|
if (!mFilesTable->selectionModel()->hasSelection()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
QModelIndexList indexes = mPluginsTable->selectionModel()->selectedIndexes();
|
QModelIndexList indexes = mFilesTable->selectionModel()->selectedIndexes();
|
||||||
|
|
||||||
//sort selection ascending because selectedIndexes returns an unsorted list
|
//sort selection ascending because selectedIndexes returns an unsorted list
|
||||||
//qSort(indexes.begin(), indexes.end(), rowSmallerThan);
|
//qSort(indexes.begin(), indexes.end(), rowSmallerThan);
|
||||||
|
@ -227,18 +182,18 @@ void DataFilesList::check()
|
||||||
if (!index.isValid())
|
if (!index.isValid())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
mPluginsModel->setCheckState(index, Qt::Checked);
|
mFilesModel->setCheckState(index, Qt::Checked);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void DataFilesList::uncheck()
|
void DataFilesList::uncheck()
|
||||||
{
|
{
|
||||||
// uncheck the current selection
|
// uncheck the current selection
|
||||||
if (!mPluginsTable->selectionModel()->hasSelection()) {
|
if (!mFilesTable->selectionModel()->hasSelection()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
QModelIndexList indexes = mPluginsTable->selectionModel()->selectedIndexes();
|
QModelIndexList indexes = mFilesTable->selectionModel()->selectedIndexes();
|
||||||
|
|
||||||
//sort selection ascending because selectedIndexes returns an unsorted list
|
//sort selection ascending because selectedIndexes returns an unsorted list
|
||||||
//qSort(indexes.begin(), indexes.end(), rowSmallerThan);
|
//qSort(indexes.begin(), indexes.end(), rowSmallerThan);
|
||||||
|
@ -247,17 +202,17 @@ void DataFilesList::uncheck()
|
||||||
if (!index.isValid())
|
if (!index.isValid())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
mPluginsModel->setCheckState(index, Qt::Unchecked);
|
mFilesModel->setCheckState(index, Qt::Unchecked);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void DataFilesList::refresh()
|
void DataFilesList::refresh()
|
||||||
{
|
{
|
||||||
mPluginsModel->sort(0);
|
mFilesModel->sort(0);
|
||||||
|
|
||||||
|
|
||||||
// Refresh the plugins table
|
// Refresh the plugins table
|
||||||
mPluginsTable->scrollToTop();
|
mFilesTable->scrollToTop();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -273,17 +228,11 @@ void DataFilesList::setCheckState(QModelIndex index)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (object->objectName() == QLatin1String("PluginsTable")) {
|
if (object->objectName() == QLatin1String("PluginsTable")) {
|
||||||
QModelIndex sourceIndex = mPluginsProxyModel->mapToSource(index);
|
QModelIndex sourceIndex = mFilesProxyModel->mapToSource(index);
|
||||||
|
|
||||||
(mPluginsModel->checkState(sourceIndex) == Qt::Checked)
|
(mFilesModel->checkState(sourceIndex) == Qt::Checked)
|
||||||
? mPluginsModel->setCheckState(sourceIndex, Qt::Unchecked)
|
? mFilesModel->setCheckState(sourceIndex, Qt::Unchecked)
|
||||||
: mPluginsModel->setCheckState(sourceIndex, Qt::Checked);
|
: mFilesModel->setCheckState(sourceIndex, Qt::Checked);
|
||||||
}
|
|
||||||
|
|
||||||
if (object->objectName() == QLatin1String("MastersTable")) {
|
|
||||||
(mMastersModel->checkState(index) == Qt::Checked)
|
|
||||||
? mMastersModel->setCheckState(index, Qt::Unchecked)
|
|
||||||
: mMastersModel->setCheckState(index, Qt::Checked);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
|
@ -292,26 +241,25 @@ void DataFilesList::setCheckState(QModelIndex index)
|
||||||
|
|
||||||
void DataFilesList::uncheckAll()
|
void DataFilesList::uncheckAll()
|
||||||
{
|
{
|
||||||
mMastersModel->uncheckAll();
|
mFilesModel->uncheckAll();
|
||||||
mPluginsModel->uncheckAll();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void DataFilesList::filterChanged(const QString filter)
|
void DataFilesList::filterChanged(const QString filter)
|
||||||
{
|
{
|
||||||
QRegExp regExp(filter, Qt::CaseInsensitive, QRegExp::FixedString);
|
QRegExp regExp(filter, Qt::CaseInsensitive, QRegExp::FixedString);
|
||||||
mPluginsProxyModel->setFilterRegExp(regExp);
|
mFilesProxyModel->setFilterRegExp(regExp);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DataFilesList::showContextMenu(const QPoint &point)
|
void DataFilesList::showContextMenu(const QPoint &point)
|
||||||
{
|
{
|
||||||
// Make sure there are plugins in the view
|
// Make sure there are plugins in the view
|
||||||
if (!mPluginsTable->selectionModel()->hasSelection()) {
|
if (!mFilesTable->selectionModel()->hasSelection()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
QPoint globalPos = mPluginsTable->mapToGlobal(point);
|
QPoint globalPos = mFilesTable->mapToGlobal(point);
|
||||||
|
|
||||||
QModelIndexList indexes = mPluginsTable->selectionModel()->selectedIndexes();
|
QModelIndexList indexes = mFilesTable->selectionModel()->selectedIndexes();
|
||||||
|
|
||||||
// Show the check/uncheck actions depending on the state of the selected items
|
// Show the check/uncheck actions depending on the state of the selected items
|
||||||
mUncheckAction->setEnabled(false);
|
mUncheckAction->setEnabled(false);
|
||||||
|
@ -321,7 +269,7 @@ void DataFilesList::showContextMenu(const QPoint &point)
|
||||||
if (!index.isValid())
|
if (!index.isValid())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
(mPluginsModel->checkState(index) == Qt::Checked)
|
(mFilesModel->checkState(index) == Qt::Checked)
|
||||||
? mUncheckAction->setEnabled(true)
|
? mUncheckAction->setEnabled(true)
|
||||||
: mCheckAction->setEnabled(true);
|
: mCheckAction->setEnabled(true);
|
||||||
}
|
}
|
||||||
|
@ -332,19 +280,14 @@ void DataFilesList::showContextMenu(const QPoint &point)
|
||||||
|
|
||||||
void DataFilesList::setCheckState(const QString& element, Qt::CheckState state)
|
void DataFilesList::setCheckState(const QString& element, Qt::CheckState state)
|
||||||
{
|
{
|
||||||
EsmFile *file = mPluginsModel->findItem(element);
|
EsmFile *file = mFilesModel->findItem(element);
|
||||||
if (file)
|
if (file)
|
||||||
{
|
{
|
||||||
mPluginsModel->setCheckState(mPluginsModel->indexFromItem(file), Qt::Checked);
|
mFilesModel->setCheckState(mFilesModel->indexFromItem(file), Qt::Checked);
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
file = mMastersModel->findItem(element);
|
|
||||||
mMastersModel->setCheckState(mMastersModel->indexFromItem(file), Qt::Checked);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
QStringList DataFilesList::checkedFiles()
|
QStringList DataFilesList::checkedFiles()
|
||||||
{
|
{
|
||||||
return mMastersModel->checkedItems() + mPluginsModel->checkedItems();
|
return mFilesModel->checkedItems();
|
||||||
}
|
}
|
||||||
|
|
|
@ -49,13 +49,11 @@ public slots:
|
||||||
void refresh();
|
void refresh();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
DataFilesModel *mMastersModel;
|
DataFilesModel *mFilesModel;
|
||||||
DataFilesModel *mPluginsModel;
|
|
||||||
|
|
||||||
QSortFilterProxyModel *mPluginsProxyModel;
|
QSortFilterProxyModel *mFilesProxyModel;
|
||||||
|
|
||||||
QTableView *mMastersTable;
|
QTableView *mFilesTable;
|
||||||
QTableView *mPluginsTable;
|
|
||||||
|
|
||||||
QMenu *mContextMenu;
|
QMenu *mContextMenu;
|
||||||
|
|
||||||
|
|
|
@ -8,8 +8,6 @@
|
||||||
|
|
||||||
#include "esm/esmfile.hpp"
|
#include "esm/esmfile.hpp"
|
||||||
|
|
||||||
#include "../utils/naturalsort.hpp"
|
|
||||||
|
|
||||||
#include "datafilesmodel.hpp"
|
#include "datafilesmodel.hpp"
|
||||||
|
|
||||||
DataFilesModel::DataFilesModel(QObject *parent) :
|
DataFilesModel::DataFilesModel(QObject *parent) :
|
||||||
|
@ -159,7 +157,7 @@ Qt::ItemFlags DataFilesModel::flags(const QModelIndex &index) const
|
||||||
if (!file)
|
if (!file)
|
||||||
return Qt::NoItemFlags;
|
return Qt::NoItemFlags;
|
||||||
|
|
||||||
if (mAvailableFiles.contains(file->fileName())) {
|
if (canBeChecked(file)) {
|
||||||
if (index.column() == 0) {
|
if (index.column() == 0) {
|
||||||
return Qt::ItemIsUserCheckable | Qt::ItemIsEnabled | Qt::ItemIsSelectable;
|
return Qt::ItemIsUserCheckable | Qt::ItemIsEnabled | Qt::ItemIsSelectable;
|
||||||
} else {
|
} else {
|
||||||
|
@ -212,7 +210,6 @@ bool DataFilesModel::setData(const QModelIndex &index, const QVariant &value, in
|
||||||
QString name = item(index.row())->fileName();
|
QString name = item(index.row())->fileName();
|
||||||
mCheckStates[name] = static_cast<Qt::CheckState>(value.toInt());
|
mCheckStates[name] = static_cast<Qt::CheckState>(value.toInt());
|
||||||
|
|
||||||
emit checkedItemsChanged(checkedItems(), uncheckedItems());
|
|
||||||
emit layoutChanged();
|
emit layoutChanged();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -220,39 +217,21 @@ bool DataFilesModel::setData(const QModelIndex &index, const QVariant &value, in
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool lessThanEsmFile(const EsmFile *e1, const EsmFile *e2)
|
||||||
|
{
|
||||||
|
//Masters first then alphabetically
|
||||||
|
if (e1->fileName().endsWith(".esm") && !e2->fileName().endsWith(".esm"))
|
||||||
|
return true;
|
||||||
|
if (!e1->fileName().endsWith(".esm") && e2->fileName().endsWith(".esm"))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return e1->fileName().toLower() < e2->fileName().toLower();
|
||||||
|
}
|
||||||
|
|
||||||
void DataFilesModel::sort(int column, Qt::SortOrder order)
|
void DataFilesModel::sort(int column, Qt::SortOrder order)
|
||||||
{
|
{
|
||||||
// TODO: Make this more efficient
|
|
||||||
emit layoutAboutToBeChanged();
|
emit layoutAboutToBeChanged();
|
||||||
|
qSort(mFiles.begin(), mFiles.end(), lessThanEsmFile);
|
||||||
QList<EsmFile *> sortedFiles;
|
|
||||||
|
|
||||||
QMultiMap<QString, QString> timestamps;
|
|
||||||
|
|
||||||
foreach (EsmFile *file, mFiles)
|
|
||||||
timestamps.insert(file->modified().toString(Qt::ISODate), file->fileName());
|
|
||||||
|
|
||||||
QMapIterator<QString, QString> ti(timestamps);
|
|
||||||
|
|
||||||
while (ti.hasNext()) {
|
|
||||||
ti.next();
|
|
||||||
|
|
||||||
QModelIndex index = indexFromItem(findItem(ti.value()));
|
|
||||||
|
|
||||||
if (!index.isValid())
|
|
||||||
continue;
|
|
||||||
|
|
||||||
EsmFile *file = item(index.row());
|
|
||||||
|
|
||||||
if (!file)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
sortedFiles.append(file);
|
|
||||||
}
|
|
||||||
|
|
||||||
mFiles.clear();
|
|
||||||
mFiles = sortedFiles;
|
|
||||||
|
|
||||||
emit layoutChanged();
|
emit layoutChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -263,73 +242,12 @@ void DataFilesModel::addFile(EsmFile *file)
|
||||||
emit endInsertRows();
|
emit endInsertRows();
|
||||||
}
|
}
|
||||||
|
|
||||||
void DataFilesModel::addMasters(const QString &path)
|
void DataFilesModel::addFiles(const QString &path)
|
||||||
{
|
{
|
||||||
QDir dir(path);
|
QDir dir(path);
|
||||||
dir.setNameFilters(QStringList(QLatin1String("*.esp")));
|
QStringList filters;
|
||||||
|
filters << "*.esp" << "*.esm";
|
||||||
// Read the dependencies from the plugins
|
dir.setNameFilters(filters);
|
||||||
foreach (const QString &path, dir.entryList()) {
|
|
||||||
try {
|
|
||||||
ESM::ESMReader fileReader;
|
|
||||||
ToUTF8::Utf8Encoder encoder (ToUTF8::calculateEncoding(mEncoding.toStdString()));
|
|
||||||
fileReader.setEncoder(&encoder);
|
|
||||||
fileReader.open(dir.absoluteFilePath(path).toStdString());
|
|
||||||
|
|
||||||
ESM::ESMReader::MasterList mlist = fileReader.getMasters();
|
|
||||||
|
|
||||||
for (unsigned int i = 0; i < mlist.size(); ++i) {
|
|
||||||
QString master = QString::fromStdString(mlist[i].name);
|
|
||||||
|
|
||||||
// Add the plugin to the internal dependency map
|
|
||||||
mDependencies[master].append(path);
|
|
||||||
|
|
||||||
// Don't add esps
|
|
||||||
if (master.endsWith(".esp", Qt::CaseInsensitive))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
QFileInfo info(dir.absoluteFilePath(master));
|
|
||||||
|
|
||||||
EsmFile *file = new EsmFile(master);
|
|
||||||
file->setDates(info.lastModified(), info.lastRead());
|
|
||||||
file->setPath(info.absoluteFilePath());
|
|
||||||
|
|
||||||
// Add the master to the table
|
|
||||||
if (findItem(master) == 0)
|
|
||||||
addFile(file);
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
} catch(std::runtime_error &e) {
|
|
||||||
// An error occurred while reading the .esp
|
|
||||||
qWarning() << "Error reading esp: " << e.what();
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// See if the masters actually exist in the filesystem
|
|
||||||
dir.setNameFilters(QStringList(QLatin1String("*.esm")));
|
|
||||||
|
|
||||||
foreach (const QString &path, dir.entryList()) {
|
|
||||||
QFileInfo info(dir.absoluteFilePath(path));
|
|
||||||
|
|
||||||
if (findItem(path) == 0) {
|
|
||||||
EsmFile *file = new EsmFile(path);
|
|
||||||
file->setDates(info.lastModified(), info.lastRead());
|
|
||||||
|
|
||||||
addFile(file);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Make the master selectable
|
|
||||||
mAvailableFiles.append(path);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void DataFilesModel::addPlugins(const QString &path)
|
|
||||||
{
|
|
||||||
QDir dir(path);
|
|
||||||
dir.setNameFilters(QStringList(QLatin1String("*.esp")));
|
|
||||||
|
|
||||||
foreach (const QString &path, dir.entryList()) {
|
foreach (const QString &path, dir.entryList()) {
|
||||||
QFileInfo info(dir.absoluteFilePath(path));
|
QFileInfo info(dir.absoluteFilePath(path));
|
||||||
|
@ -348,9 +266,6 @@ void DataFilesModel::addPlugins(const QString &path)
|
||||||
for (unsigned int i = 0; i < mlist.size(); ++i) {
|
for (unsigned int i = 0; i < mlist.size(); ++i) {
|
||||||
QString master = QString::fromStdString(mlist[i].name);
|
QString master = QString::fromStdString(mlist[i].name);
|
||||||
masters.append(master);
|
masters.append(master);
|
||||||
|
|
||||||
// Add the plugin to the internal dependency map
|
|
||||||
mDependencies[master].append(path);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
file->setAuthor(QString::fromStdString(fileReader.getAuthor()));
|
file->setAuthor(QString::fromStdString(fileReader.getAuthor()));
|
||||||
|
@ -423,7 +338,7 @@ QStringList DataFilesModel::checkedItems()
|
||||||
QString name = file->fileName();
|
QString name = file->fileName();
|
||||||
|
|
||||||
// Only add the items that are in the checked list and available
|
// Only add the items that are in the checked list and available
|
||||||
if (mCheckStates[name] == Qt::Checked && mAvailableFiles.contains(name))
|
if (mCheckStates[name] == Qt::Checked && canBeChecked(file))
|
||||||
list << name;
|
list << name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -441,8 +356,8 @@ QStringList DataFilesModel::checkedItemsPaths()
|
||||||
for (it = mFiles.constBegin(); it != itEnd; ++it) {
|
for (it = mFiles.constBegin(); it != itEnd; ++it) {
|
||||||
EsmFile *file = item(i);
|
EsmFile *file = item(i);
|
||||||
++i;
|
++i;
|
||||||
|
|
||||||
if (mCheckStates[file->fileName()] == Qt::Checked && mAvailableFiles.contains(file->fileName()))
|
if (mCheckStates[file->fileName()] == Qt::Checked && canBeChecked(file))
|
||||||
list << file->path();
|
list << file->path();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -477,24 +392,17 @@ QStringList DataFilesModel::uncheckedItems()
|
||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DataFilesModel::slotcheckedItemsChanged(const QStringList &checkedItems, const QStringList &unCheckedItems)
|
bool DataFilesModel::canBeChecked(EsmFile *file) const
|
||||||
{
|
{
|
||||||
emit layoutAboutToBeChanged();
|
//element can be checked if all its dependencies are
|
||||||
|
bool canBeChecked = true;
|
||||||
QStringList list;
|
foreach (const QString &master, file->masters())
|
||||||
|
{
|
||||||
foreach (const QString &file, checkedItems) {
|
if (!mCheckStates.contains(master) || mCheckStates[master] != Qt::Checked)
|
||||||
list << mDependencies[file];
|
{
|
||||||
}
|
canBeChecked = false;
|
||||||
|
break;
|
||||||
foreach (const QString &file, unCheckedItems) {
|
|
||||||
foreach (const QString &remove, mDependencies[file]) {
|
|
||||||
list.removeAll(remove);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return canBeChecked;
|
||||||
mAvailableFiles.clear();
|
|
||||||
mAvailableFiles.append(list);
|
|
||||||
|
|
||||||
emit layoutChanged();
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,10 +34,7 @@ public:
|
||||||
|
|
||||||
void setEncoding(const QString &encoding);
|
void setEncoding(const QString &encoding);
|
||||||
|
|
||||||
void addFile(EsmFile *file);
|
void addFiles(const QString &path);
|
||||||
|
|
||||||
void addMasters(const QString &path);
|
|
||||||
void addPlugins(const QString &path);
|
|
||||||
|
|
||||||
void uncheckAll();
|
void uncheckAll();
|
||||||
|
|
||||||
|
@ -51,18 +48,12 @@ public:
|
||||||
QModelIndex indexFromItem(EsmFile *item) const;
|
QModelIndex indexFromItem(EsmFile *item) const;
|
||||||
EsmFile* findItem(const QString &name);
|
EsmFile* findItem(const QString &name);
|
||||||
EsmFile* item(int row) const;
|
EsmFile* item(int row) const;
|
||||||
|
|
||||||
signals:
|
|
||||||
void checkedItemsChanged(const QStringList checkedItems, const QStringList unCheckedItems);
|
|
||||||
|
|
||||||
public slots:
|
|
||||||
void slotcheckedItemsChanged(const QStringList &checkedItems, const QStringList &unCheckedItems);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
bool canBeChecked(EsmFile *file) const;
|
||||||
|
void addFile(EsmFile *file);
|
||||||
|
|
||||||
QList<EsmFile *> mFiles;
|
QList<EsmFile *> mFiles;
|
||||||
QStringList mAvailableFiles;
|
|
||||||
|
|
||||||
QHash<QString, QStringList> mDependencies;
|
|
||||||
QHash<QString, Qt::CheckState> mCheckStates;
|
QHash<QString, Qt::CheckState> mCheckStates;
|
||||||
|
|
||||||
QString mEncoding;
|
QString mEncoding;
|
||||||
|
|
|
@ -26,15 +26,15 @@ public:
|
||||||
void setMasters(const QStringList &masters);
|
void setMasters(const QStringList &masters);
|
||||||
void setDescription(const QString &description);
|
void setDescription(const QString &description);
|
||||||
|
|
||||||
inline QString fileName() { return mFileName; }
|
inline QString fileName() const { return mFileName; }
|
||||||
inline QString author() { return mAuthor; }
|
inline QString author() const { return mAuthor; }
|
||||||
inline int size() { return mSize; }
|
inline int size() const { return mSize; }
|
||||||
inline QDateTime modified() { return mModified; }
|
inline QDateTime modified() const { return mModified; }
|
||||||
inline QDateTime accessed() { return mAccessed; }
|
inline QDateTime accessed() const { return mAccessed; }
|
||||||
inline float version() { return mVersion; }
|
inline float version() const { return mVersion; }
|
||||||
inline QString path() { return mPath; }
|
inline QString path() const { return mPath; }
|
||||||
inline QStringList masters() { return mMasters; }
|
inline QStringList masters() const { return mMasters; }
|
||||||
inline QString description() { return mDescription; }
|
inline QString description() const { return mDescription; }
|
||||||
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
Loading…
Reference in a new issue