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 maindialog.cpp
playpage.cpp playpage.cpp
model/pluginsproxymodel.cpp
settings/gamesettings.cpp settings/gamesettings.cpp
settings/graphicssettings.cpp settings/graphicssettings.cpp
settings/launchersettings.cpp settings/launchersettings.cpp
@ -22,6 +24,8 @@ set(LAUNCHER_HEADER
maindialog.hpp maindialog.hpp
playpage.hpp playpage.hpp
model/pluginsproxymodel.hpp
settings/gamesettings.hpp settings/gamesettings.hpp
settings/graphicssettings.hpp settings/graphicssettings.hpp
settings/launchersettings.hpp settings/launchersettings.hpp
@ -39,6 +43,8 @@ set(LAUNCHER_HEADER_MOC
maindialog.hpp maindialog.hpp
playpage.hpp playpage.hpp
model/pluginsproxymodel.hpp
utils/comboboxlineedit.hpp utils/comboboxlineedit.hpp
utils/profilescombobox.hpp utils/profilescombobox.hpp
utils/textinputdialog.hpp utils/textinputdialog.hpp

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

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

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

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

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

@ -229,10 +229,29 @@ bool lessThanEsmFile(const EsmFile *e1, const EsmFile *e2)
return e1->fileName().toLower() < e2->fileName().toLower(); 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) void DataFilesModel::sort(int column, Qt::SortOrder order)
{ {
emit layoutAboutToBeChanged(); 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(); emit layoutChanged();
} }

Loading…
Cancel
Save