Fixed accidental profile deletion and added sorting by date

actorid
Pieter van der Kloet 12 years ago
parent 37fe31e858
commit 35b68a3c40

@ -5,6 +5,8 @@ set(LAUNCHER
maindialog.cpp
playpage.cpp
model/pluginsproxymodel.cpp
settings/gamesettings.cpp
settings/graphicssettings.cpp
settings/launchersettings.cpp
@ -22,6 +24,8 @@ set(LAUNCHER_HEADER
maindialog.hpp
playpage.hpp
model/pluginsproxymodel.hpp
settings/gamesettings.hpp
settings/graphicssettings.hpp
settings/launchersettings.hpp
@ -39,6 +43,8 @@ set(LAUNCHER_HEADER_MOC
maindialog.hpp
playpage.hpp
model/pluginsproxymodel.hpp
utils/comboboxlineedit.hpp
utils/profilescombobox.hpp
utils/textinputdialog.hpp

@ -9,6 +9,8 @@
#include <components/fileorderlist/utils/lineedit.hpp>
#include <components/fileorderlist/utils/naturalsort.hpp>
#include "model/pluginsproxymodel.hpp"
#include "settings/gamesettings.hpp"
#include "settings/launchersettings.hpp"
@ -63,7 +65,7 @@ DataFilesPage::DataFilesPage(Files::ConfigurationManager &cfg, GameSettings &gam
mMastersProxyModel->setFilterCaseSensitivity(Qt::CaseInsensitive);
mMastersProxyModel->setSourceModel(mDataFilesModel);
mPluginsProxyModel = new QSortFilterProxyModel();
mPluginsProxyModel = new PluginsProxyModel();
mPluginsProxyModel->setFilterRegExp(QString("^.*\\.esp"));
mPluginsProxyModel->setFilterCaseSensitivity(Qt::CaseInsensitive);
mPluginsProxyModel->setSourceModel(mDataFilesModel);
@ -97,6 +99,7 @@ DataFilesPage::DataFilesPage(Files::ConfigurationManager &cfg, GameSettings &gam
mMastersTable = new QTableView(this);
mMastersTable->setModel(mMastersProxyModel);
mMastersTable->setObjectName("MastersTable");
mMastersTable->setSortingEnabled(false);
mMastersTable->setSelectionBehavior(QAbstractItemView::SelectRows);
mMastersTable->setSelectionMode(QAbstractItemView::SingleSelection);
mMastersTable->setEditTriggers(QAbstractItemView::NoEditTriggers);
@ -108,19 +111,12 @@ DataFilesPage::DataFilesPage(Files::ConfigurationManager &cfg, GameSettings &gam
mMastersTable->verticalHeader()->setDefaultSectionSize(height);
mMastersTable->verticalHeader()->setResizeMode(QHeaderView::Fixed);
mMastersTable->verticalHeader()->hide();
mMastersTable->setColumnHidden(1, true);
mMastersTable->setColumnHidden(2, true);
mMastersTable->setColumnHidden(3, true);
mMastersTable->setColumnHidden(4, true);
mMastersTable->setColumnHidden(5, true);
mMastersTable->setColumnHidden(6, true);
mMastersTable->setColumnHidden(7, true);
mMastersTable->setColumnHidden(8, true);
mPluginsTable = new QTableView(this);
mPluginsTable->setModel(mFilterProxyModel);
mPluginsTable->setObjectName("PluginsTable");
mPluginsTable->setContextMenuPolicy(Qt::CustomContextMenu);
mPluginsTable->setSortingEnabled(false);
mPluginsTable->setSelectionBehavior(QAbstractItemView::SelectRows);
mPluginsTable->setSelectionMode(QAbstractItemView::SingleSelection);
mPluginsTable->setEditTriggers(QAbstractItemView::NoEditTriggers);
@ -131,14 +127,6 @@ DataFilesPage::DataFilesPage(Files::ConfigurationManager &cfg, GameSettings &gam
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
mSplitter = new QSplitter(this);
@ -185,12 +173,11 @@ DataFilesPage::DataFilesPage(Files::ConfigurationManager &cfg, GameSettings &gam
connect(mMastersTable, SIGNAL(doubleClicked(QModelIndex)), this, SLOT(setCheckState(QModelIndex)));
connect(mPluginsTable, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(showContextMenu(QPoint)));
connect(mDataFilesModel, SIGNAL(layoutChanged()), this, SLOT(updateViews()));
connect(filterLineEdit, SIGNAL(textChanged(QString)), this, SLOT(filterChanged(QString)));
connect(mProfilesComboBox, SIGNAL(profileRenamed(QString,QString)), this, SLOT(profileRenamed(QString,QString)));
connect(mProfilesComboBox, SIGNAL(profileChanged(QString,QString)), this, SLOT(profileChanged(QString,QString)));
connect(mSplitter, SIGNAL(splitterMoved(int,int)), this, SLOT(updateSplitter()));
createActions();
@ -250,9 +237,13 @@ void DataFilesPage::setupDataFiles()
mDataFilesModel->addFiles(dataLocal);
}
// Sort by date accessed for now
mDataFilesModel->sort(3);
QStringList profiles = mLauncherSettings.subKeys(QString("Profiles/"));
QString profile = mLauncherSettings.value(QString("Profiles/CurrentProfile"));
mProfilesComboBox->setCurrentIndex(-1);
mProfilesComboBox->addItems(profiles);
// Add the current profile if empty
@ -262,12 +253,18 @@ void DataFilesPage::setupDataFiles()
if (mProfilesComboBox->findText(QString("Default")) == -1)
mProfilesComboBox->addItem(QString("Default"));
if (profile.isEmpty()) {
if (profile.isEmpty() || profile == QLatin1String("Default")) {
mProfilesComboBox->setCurrentIndex(mProfilesComboBox->findText(QString("Default")));
} else {
mProfilesComboBox->setEditEnabled(true);
mProfilesComboBox->setCurrentIndex(mProfilesComboBox->findText(profile));
}
// We do this here to prevent deletion of profiles when initializing the combobox
connect(mProfilesComboBox, SIGNAL(profileRenamed(QString,QString)), this, SLOT(profileRenamed(QString,QString)));
connect(mProfilesComboBox, SIGNAL(profileChanged(QString,QString)), this, SLOT(profileChanged(QString,QString)));
loadSettings();
}
@ -301,10 +298,8 @@ void DataFilesPage::saveSettings()
{
QString profile = mLauncherSettings.value(QString("Profiles/CurrentProfile"));
if (profile.isEmpty()) {
profile = mProfilesComboBox->currentText();
mLauncherSettings.setValue(QString("Profiles/CurrentProfile"), profile);
}
if (profile.isEmpty())
return;
mLauncherSettings.remove(QString("Profiles/") + profile + QString("/master"));
mLauncherSettings.remove(QString("Profiles/") + profile + QString("/plugin"));
@ -360,6 +355,28 @@ void DataFilesPage::updateSplitter()
mLauncherSettings.setValue(QString("General/PluginsTable/width"), QString::number(sizes.at(1)));
}
void DataFilesPage::updateViews()
{
// Ensure the columns are hidden because sort() re-enables them
mMastersTable->setColumnHidden(1, true);
mMastersTable->setColumnHidden(2, true);
mMastersTable->setColumnHidden(3, true);
mMastersTable->setColumnHidden(4, true);
mMastersTable->setColumnHidden(5, true);
mMastersTable->setColumnHidden(6, true);
mMastersTable->setColumnHidden(7, true);
mMastersTable->setColumnHidden(8, true);
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);
}
void DataFilesPage::deleteProfile()
{
QString profile = mProfilesComboBox->currentText();
@ -441,7 +458,7 @@ void DataFilesPage::uncheck()
void DataFilesPage::refresh()
{
mDataFilesModel->sort(0);
// mDataFilesModel->sort(0);
// Refresh the plugins table
mPluginsTable->scrollToTop();
@ -512,7 +529,6 @@ void DataFilesPage::profileChanged(const QString &previous, const QString &curre
saveSettings();
mLauncherSettings.setValue(QString("Profiles/CurrentProfile"), current);
mDataFilesModel->uncheckAll();
loadSettings();
}
@ -532,7 +548,6 @@ void DataFilesPage::profileRenamed(const QString &previous, const QString &curre
// Remove the profile from the combobox
mProfilesComboBox->removeItem(mProfilesComboBox->findText(previous));
mDataFilesModel->uncheckAll();
loadSettings();
}

@ -18,6 +18,7 @@ class TextInputDialog;
class ProfilesComboBox;
class GameSettings;
class LauncherSettings;
class PluginsProxyModel;
namespace Files { struct ConfigurationManager; }
@ -43,6 +44,7 @@ public slots:
void profileRenamed(const QString &previous, const QString &current);
void updateOkButton(const QString &text);
void updateSplitter();
void updateViews();
// Action slots
void newProfile();
@ -58,7 +60,7 @@ public slots:
private:
DataFilesModel *mDataFilesModel;
QSortFilterProxyModel *mPluginsProxyModel;
PluginsProxyModel *mPluginsProxyModel;
QSortFilterProxyModel *mMastersProxyModel;
QSortFilterProxyModel *mFilterProxyModel;

@ -206,8 +206,6 @@ void MainDialog::saveSettings()
mLauncherSettings.setValue(QString("General/MainWindow/posx"), posX);
mLauncherSettings.setValue(QString("General/MainWindow/posy"), posY);
qDebug() << "size: " << width << height;
}
void MainDialog::writeSettings()

@ -0,0 +1,17 @@
#include "pluginsproxymodel.hpp"
PluginsProxyModel::PluginsProxyModel(QObject *parent) :
QSortFilterProxyModel(parent)
{
}
PluginsProxyModel::~PluginsProxyModel()
{
}
QVariant PluginsProxyModel::headerData(int section, Qt::Orientation orientation, int role) const
{
if (orientation != Qt::Vertical || role != Qt::DisplayRole)
return QSortFilterProxyModel::headerData(section, orientation, role);
return section + 1;
}

@ -0,0 +1,18 @@
#ifndef PLUGINSPROXYMODEL_HPP
#define PLUGINSPROXYMODEL_HPP
#include <QSortFilterProxyModel>
class QVariant;
class PluginsProxyModel : public QSortFilterProxyModel
{
Q_OBJECT
public:
explicit PluginsProxyModel(QObject *parent = 0);
~PluginsProxyModel();
QVariant headerData(int section, Qt::Orientation orientation, int role) const;
};
#endif // PLUGINSPROXYMODEL_HPP

@ -21,8 +21,6 @@ GameSettings::~GameSettings()
void GameSettings::validatePaths()
{
qDebug() << "validate paths!";
if (mSettings.isEmpty())
return;
@ -35,9 +33,6 @@ void GameSettings::validatePaths()
// Parse the data dirs to convert the tokenized paths
mCfgMgr.processPaths(dataDirs);
// // Replace the existing data paths with valid untokenized ones
// mSettings.remove(QString("data"));
mDataDirs.clear();
for (Files::PathContainer::iterator it = dataDirs.begin(); it != dataDirs.end(); ++it) {
@ -59,7 +54,6 @@ void GameSettings::validatePaths()
dataDirs.push_back(Files::PathContainer::value_type(local.toStdString()));
mCfgMgr.processPaths(dataDirs);
// mSettings.remove(QString("data-local"));
if (!dataDirs.empty()) {
QString path = QString::fromStdString(dataDirs.front().string());
@ -92,23 +86,21 @@ bool GameSettings::readFile(QTextStream &stream)
if (line.isEmpty() || line.startsWith("#"))
continue;
qDebug() << "line: " << line;
if (keyRe.indexIn(line) != -1) {
QString key = keyRe.cap(1).simplified();
QString value = keyRe.cap(2).simplified();
qDebug() << "key: " << key;
// There can be multiple data keys
if (key == QLatin1String("data")) {
// There can be multiple keys
if (key == QLatin1String("data") ||
key == QLatin1String("master") ||
key == QLatin1String("plugin"))
{
// Remove keys from previous config and overwrite them
mSettings.remove(key);
QStringList values = cache.values(key);
if (!values.contains(value)) {
// Do not insert duplicate values
qDebug() << "values does not contain: " << value << values;
if (!values.contains(value)) // Do not insert duplicate values
cache.insertMulti(key, value);
}
} else {
cache.insert(key, value);
}
@ -137,23 +129,42 @@ bool GameSettings::readFile(QTextStream &stream)
// Merge the changed keys with those which didn't
mSettings.unite(cache);
validatePaths();
qDebug() << mSettings;
return true;
}
bool GameSettings::writeFile(QTextStream &stream)
{
// Iterate in reverse order to preserve insertion order
QMapIterator<QString, QString> i(mSettings);
while (i.hasNext()) {
i.next();
i.toBack();
// Quote values with spaces
if (i.value().contains(" ")) {
stream << i.key() << "=\"" << i.value() << "\"\n";
} else {
stream << i.key() << "=" << i.value() << "\n";
while (i.hasPrevious()) {
i.previous();
if (i.key() == QLatin1String("master") || i.key() == QLatin1String("plugin"))
continue;
// Quote paths with spaces
if (i.key() == QLatin1String("data") || i.key() == QLatin1String("data")) {
if (i.value().contains(" ")) {
stream << i.key() << "=\"" << i.value() << "\"\n";
continue;
}
}
stream << i.key() << "=" << i.value() << "\n";
}
QStringList masters = mSettings.values(QString("master"));
for (int i = masters.count(); i--;) {
stream << "master=" << masters.at(i) << "\n";
}
QStringList plugins = mSettings.values(QString("plugin"));
for (int i = plugins.count(); i--;) {
stream << "plugin=" << plugins.at(i) << "\n";
}
return true;

@ -26,7 +26,6 @@ QStringList LauncherSettings::values(const QString &key, Qt::MatchFlags flags)
QStringList keys = settings.keys();
foreach (const QString &currentKey, keys) {
qDebug() << "key is: " << currentKey << "value: " << settings.value(currentKey);
if (currentKey.startsWith(key))
result.append(settings.value(currentKey));
}
@ -38,16 +37,15 @@ QStringList LauncherSettings::values(const QString &key, Qt::MatchFlags flags)
QStringList LauncherSettings::subKeys(const QString &key)
{
QMap<QString, QString> settings = SettingsBase::getSettings();
QStringList keys = settings.keys();
QStringList keys = settings.uniqueKeys();
QRegExp keyRe("(.+)/");
QStringList result;
foreach (const QString &currentKey, keys) {
qDebug() << "key is: " << currentKey;
if (keyRe.indexIn(currentKey) != -1) {
qDebug() << "text: " << keyRe.cap(1) << keyRe.cap(2);
QString prefixedKey = keyRe.cap(1);
if(prefixedKey.startsWith(key)) {
@ -55,16 +53,11 @@ QStringList LauncherSettings::subKeys(const QString &key)
QString subKey = prefixedKey.remove(key);
if (!subKey.isEmpty())
result.append(subKey);
//qDebug() << keyRe.cap(2).simplified();
}
} else {
qDebug() << "no match";
}
}
result.removeDuplicates();
qDebug() << result;
return result;
}
@ -75,8 +68,10 @@ bool LauncherSettings::writeFile(QTextStream &stream)
QMap<QString, QString> settings = SettingsBase::getSettings();
QMapIterator<QString, QString> i(settings);
while (i.hasNext()) {
i.next();
i.toBack();
while (i.hasPrevious()) {
i.previous();
QString prefix;
QString key;

@ -75,7 +75,6 @@ public:
QStringList values = mCache.values(key);
if (!values.contains(value)) {
// QMap will replace the value if key exists, QMultiMap creates a new one
mCache.insertMulti(key, value);
}
}
@ -96,7 +95,6 @@ public:
// Merge the changed keys with those which didn't
mSettings.unite(mCache);
qDebug() << mSettings;
return true;
}

@ -229,10 +229,29 @@ bool lessThanEsmFile(const EsmFile *e1, const EsmFile *e2)
return e1->fileName().toLower() < e2->fileName().toLower();
}
bool lessThanDate(const EsmFile *e1, const EsmFile *e2)
{
if (e1->modified().toString(Qt::ISODate) < e2->modified().toString(Qt::ISODate)) {
return true;
} else {
return false;
}
// 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)
{
emit layoutAboutToBeChanged();
qSort(mFiles.begin(), mFiles.end(), lessThanEsmFile);
if (column == 3) {
qSort(mFiles.begin(), mFiles.end(), lessThanDate);
} else {
qSort(mFiles.begin(), mFiles.end(), lessThanEsmFile);
}
emit layoutChanged();
}

Loading…
Cancel
Save