Added support for the profiles and made creation/editing them more user friendly

pull/37/head
Pieter van der Kloet 12 years ago
parent a4855186c5
commit fe9120bcb3

@ -12,6 +12,8 @@ set(LAUNCHER
utils/filedialog.cpp
utils/naturalsort.cpp
utils/lineedit.cpp
utils/profilescombobox.cpp
utils/textinputdialog.cpp
launcher.rc
)
@ -26,10 +28,12 @@ set(LAUNCHER_HEADER
model/modelitem.hpp
model/esm/esmfile.hpp
utils/combobox.hpp
utils/lineedit.hpp
utils/filedialog.hpp
utils/naturalsort.hpp
utils/profilescombobox.hpp
utils/textinputdialog.hpp
)
# Headers that must be pre-processed
@ -43,9 +47,10 @@ set(LAUNCHER_HEADER_MOC
model/modelitem.hpp
model/esm/esmfile.hpp
utils/combobox.hpp
utils/lineedit.hpp
utils/filedialog.hpp
utils/profilescombobox.hpp
utils/textinputdialog.hpp
)
source_group(launcher FILES ${LAUNCHER} ${LAUNCHER_HEADER} ${LAUNCHER_HEADER_MOC})

@ -6,10 +6,11 @@
#include "model/datafilesmodel.hpp"
#include "model/esm/esmfile.hpp"
#include "utils/combobox.hpp"
#include "utils/profilescombobox.hpp"
#include "utils/filedialog.hpp"
#include "utils/lineedit.hpp"
#include "utils/naturalsort.hpp"
#include "utils/textinputdialog.hpp"
#include "datafilespage.hpp"
@ -139,9 +140,11 @@ DataFilesPage::DataFilesPage(Files::ConfigurationManager &cfg, QWidget *parent)
// Bottom part with profile options
QLabel *profileLabel = new QLabel(tr("Current Profile: "), this);
mProfilesComboBox = new ComboBox(this);
mProfilesComboBox = new ProfilesComboBox(this);
mProfilesComboBox->setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Minimum));
mProfilesComboBox->setInsertPolicy(QComboBox::InsertAtBottom);
mProfilesComboBox->setInsertPolicy(QComboBox::NoInsert);
mProfilesComboBox->setDuplicatesEnabled(false);
mProfilesComboBox->setEditEnabled(false);
mProfileToolBar = new QToolBar(this);
mProfileToolBar->setMovable(false);
@ -156,16 +159,22 @@ DataFilesPage::DataFilesPage(Files::ConfigurationManager &cfg, QWidget *parent)
pageLayout->addWidget(splitter);
pageLayout->addWidget(mProfileToolBar);
// Create a dialog for the new profile name input
mNewProfileDialog = new TextInputDialog(tr("New Profile"), tr("Profile name:"), this);
connect(mNewProfileDialog->lineEdit(), SIGNAL(textChanged(QString)), this, SLOT(updateOkButton(QString)));
connect(mPluginsTable, SIGNAL(doubleClicked(QModelIndex)), this, SLOT(setCheckState(QModelIndex)));
connect(mMastersTable, SIGNAL(doubleClicked(QModelIndex)), this, SLOT(setCheckState(QModelIndex)));
connect(mMastersModel, SIGNAL(checkedItemsChanged(QStringList,QStringList)), mPluginsModel, SLOT(slotcheckedItemsChanged(QStringList,QStringList)));
connect(filterLineEdit, SIGNAL(textChanged(QString)), this, SLOT(filterChanged(const QString)));
connect(filterLineEdit, SIGNAL(textChanged(QString)), this, SLOT(filterChanged(QString)));
connect(mPluginsTable, SIGNAL(customContextMenuRequested(const QPoint&)), this, SLOT(showContextMenu(const QPoint&)));
connect(mPluginsTable, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(showContextMenu(QPoint)));
connect(mProfilesComboBox, SIGNAL(textChanged(const QString&, const QString&)), this, SLOT(profileChanged(const QString&, const QString&)));
connect(mProfilesComboBox, SIGNAL(profileRenamed(QString,QString)), this, SLOT(profileRenamed(QString,QString)));
connect(mProfilesComboBox, SIGNAL(profileChanged(QString,QString)), this, SLOT(profileChanged(QString,QString)));
createActions();
setupConfig();
@ -230,12 +239,21 @@ void DataFilesPage::setupConfig()
mLauncherConfig->beginGroup("Profiles");
QStringList profiles = mLauncherConfig->childGroups();
if (profiles.isEmpty()) {
// Add a default profile
profiles.append("Default");
// Add the profiles to the combobox
foreach (const QString &profile, profiles) {
if (profile.contains(QRegExp("[^a-zA-Z0-9_]")))
continue; // Profile name contains garbage
qDebug() << "adding " << profile;
mProfilesComboBox->addItem(profile);
}
mProfilesComboBox->addItems(profiles);
// Add a default profile
if (mProfilesComboBox->count() == 0) {
mProfilesComboBox->addItem(QString("Default"));
}
QString currentProfile = mLauncherConfig->value("CurrentProfile").toString();
@ -572,33 +590,37 @@ void DataFilesPage::writeConfig(QString profile)
void DataFilesPage::newProfile()
{
bool ok;
QString text = QInputDialog::getText(this, tr("New Profile"),
tr("Profile Name:"), QLineEdit::Normal,
tr("New Profile"), &ok);
if (ok && !text.isEmpty()) {
if (mProfilesComboBox->findText(text) != -1) {
QMessageBox::warning(this, tr("Profile already exists"),
tr("the profile <b>%0</b> already exists.").arg(text),
QMessageBox::Ok);
} else {
// Add the new profile to the combobox
mProfilesComboBox->addItem(text);
mProfilesComboBox->setCurrentIndex(mProfilesComboBox->findText(text));
if (mNewProfileDialog->exec() == QDialog::Accepted) {
}
const QString text = mNewProfileDialog->lineEdit()->text();
mProfilesComboBox->addItem(text);
// Copy the currently checked items to cfg
writeConfig(text);
mLauncherConfig->sync();
mProfilesComboBox->setCurrentIndex(mProfilesComboBox->findText(text));
}
}
void DataFilesPage::updateOkButton(const QString &text)
{
if (text.isEmpty()) {
mNewProfileDialog->setOkButtonEnabled(false);
return;
}
(mProfilesComboBox->findText(text) == -1)
? mNewProfileDialog->setOkButtonEnabled(true)
: mNewProfileDialog->setOkButtonEnabled(false);
}
void DataFilesPage::deleteProfile()
{
QString profile = mProfilesComboBox->currentText();
if (profile.isEmpty()) {
if (profile.isEmpty())
return;
}
QMessageBox msgBox(this);
msgBox.setWindowTitle(tr("Delete Profile"));
@ -694,19 +716,17 @@ void DataFilesPage::setCheckState(QModelIndex index)
return;
if (object->objectName() == QLatin1String("PluginsTable")) {
if (mPluginsModel->checkState(index) == Qt::Checked) {
mPluginsModel->setCheckState(index, Qt::Unchecked);
} else {
mPluginsModel->setCheckState(index, Qt::Checked);
}
QModelIndex sourceIndex = mPluginsProxyModel->mapToSource(index);
(mPluginsModel->checkState(sourceIndex) == Qt::Checked)
? mPluginsModel->setCheckState(index, Qt::Unchecked)
: mPluginsModel->setCheckState(index, Qt::Checked);
}
if (object->objectName() == QLatin1String("MastersTable")) {
if (mMastersModel->checkState(index) == Qt::Checked) {
mMastersModel->setCheckState(index, Qt::Unchecked);
} else {
mMastersModel->setCheckState(index, Qt::Checked);
}
(mMastersModel->checkState(index) == Qt::Checked)
? mMastersModel->setCheckState(index, Qt::Unchecked)
: mMastersModel->setCheckState(index, Qt::Checked);
}
return;
@ -721,13 +741,23 @@ void DataFilesPage::filterChanged(const QString filter)
void DataFilesPage::profileChanged(const QString &previous, const QString &current)
{
qDebug() << "Profile is changed from: " << previous << " to " << current;
// Prevent the deletion of the default profile
(current == QLatin1String("Default")) ? mDeleteProfileAction->setEnabled(false)
: mDeleteProfileAction->setEnabled(true);
if (current == QLatin1String("Default")) {
mDeleteProfileAction->setEnabled(false);
mProfilesComboBox->setEditEnabled(false);
} else {
mDeleteProfileAction->setEnabled(true);
mProfilesComboBox->setEditEnabled(true);
}
if (!previous.isEmpty()) {
writeConfig(previous);
mLauncherConfig->sync();
if (mProfilesComboBox->currentIndex() == -1)
return;
} else {
return;
}
@ -737,6 +767,36 @@ void DataFilesPage::profileChanged(const QString &previous, const QString &curre
readConfig();
}
void DataFilesPage::profileRenamed(const QString &previous, const QString &current)
{
if (previous.isEmpty())
return;
// Save the new profile name
writeConfig(current);
// Make sure we have no groups open
while (!mLauncherConfig->group().isEmpty()) {
mLauncherConfig->endGroup();
}
mLauncherConfig->beginGroup("Profiles");
// Open the profile-name subgroup
mLauncherConfig->beginGroup(previous);
mLauncherConfig->remove(""); // Clear the subgroup
mLauncherConfig->endGroup();
mLauncherConfig->endGroup();
mLauncherConfig->sync();
// Remove the profile from the combobox
mProfilesComboBox->removeItem(mProfilesComboBox->findText(previous));
mMastersModel->uncheckAll();
mPluginsModel->uncheckAll();
readConfig();
}
void DataFilesPage::showContextMenu(const QPoint &point)
{
// Make sure there are plugins in the view
@ -756,11 +816,9 @@ void DataFilesPage::showContextMenu(const QPoint &point)
if (!index.isValid())
return;
if (mPluginsModel->checkState(index) == Qt::Checked) {
mUncheckAction->setEnabled(true);
} else {
mCheckAction->setEnabled(true);
}
(mPluginsModel->checkState(index) == Qt::Checked)
? mUncheckAction->setEnabled(true)
: mCheckAction->setEnabled(true);
}
// Show menu

@ -3,7 +3,7 @@
#include <QWidget>
#include <QModelIndex>
#include "utils/profilescombobox.hpp"
#include <components/files/collections.hpp>
@ -13,9 +13,10 @@ class QSettings;
class QAction;
class QToolBar;
class QMenu;
class ComboBox;
class ProfilesComboBox;
class DataFilesModel;
class TextInputDialog;
namespace Files { struct ConfigurationManager; }
@ -26,7 +27,7 @@ class DataFilesPage : public QWidget
public:
DataFilesPage(Files::ConfigurationManager& cfg, QWidget *parent = 0);
ComboBox *mProfilesComboBox;
ProfilesComboBox *mProfilesComboBox;
void writeConfig(QString profile = QString());
bool setupDataFiles();
@ -37,6 +38,8 @@ public slots:
void filterChanged(const QString filter);
void showContextMenu(const QPoint &point);
void profileChanged(const QString &previous, const QString &current);
void profileRenamed(const QString &previous, const QString &current);
void updateOkButton(const QString &text);
// Action slots
void newProfile();
@ -77,6 +80,8 @@ private:
QSettings *mLauncherConfig;
TextInputDialog *mNewProfileDialog;
// const QStringList checkedPlugins();
// const QStringList selectedMasters();

@ -11,7 +11,7 @@ int main(int argc, char *argv[])
// Now we make sure the current dir is set to application path
QDir dir(QCoreApplication::applicationDirPath());
#if defined(Q_OS_MAC)
#ifdef Q_OS_MAC
if (dir.dirName() == "MacOS") {
dir.cdUp();
dir.cdUp();

@ -1,7 +1,5 @@
#include <QtGui>
#include "utils/combobox.hpp"
#include "maindialog.hpp"
#include "playpage.hpp"
#include "graphicspage.hpp"

@ -1,28 +0,0 @@
#ifndef COMBOBOX_H
#define COMBOBOX_H
#include <QComboBox>
class ComboBox : public QComboBox
{
Q_OBJECT
private:
QString oldText;
public:
ComboBox(QWidget *parent=0) : QComboBox(parent), oldText()
{
connect(this,SIGNAL(editTextChanged(const QString&)), this,
SLOT(textChangedSlot(const QString&)));
connect(this,SIGNAL(currentIndexChanged(const QString&)), this,
SLOT(textChangedSlot(const QString&)));
}
private slots:
void textChangedSlot(const QString &newText)
{
emit textChanged(oldText, newText);
oldText = newText;
}
signals:
void textChanged(const QString &oldText, const QString &newText);
};
#endif

@ -0,0 +1,52 @@
#include <QRegExpValidator>
#include <QLineEdit>
#include <QString>
#include "profilescombobox.hpp"
ProfilesComboBox::ProfilesComboBox(QWidget *parent) :
QComboBox(parent)
{
mValidator = new QRegExpValidator(QRegExp("^[a-zA-Z0-9_]*$"), this); // Alpha-numeric + underscore
setEditable(true);
setValidator(mValidator);
setCompleter(0);
connect(this, SIGNAL(currentIndexChanged(int)), this,
SLOT(slotIndexChanged(int)));
connect(lineEdit(), SIGNAL(returnPressed()), this,
SLOT(slotReturnPressed()));
}
void ProfilesComboBox::setEditEnabled(bool editable)
{
if (!editable)
return setEditable(false);
// Reset the completer and validator
setEditable(true);
setValidator(mValidator);
setCompleter(0);
}
void ProfilesComboBox::slotReturnPressed()
{
QString current = currentText();
QString previous = itemText(currentIndex());
if (findText(current) != -1)
return;
setItemText(currentIndex(), current);
emit(profileRenamed(previous, current));
}
void ProfilesComboBox::slotIndexChanged(int index)
{
if (index == -1)
return;
emit(profileChanged(mOldProfile, currentText()));
mOldProfile = itemText(index);
}

@ -0,0 +1,30 @@
#ifndef PROFILESCOMBOBOX_HPP
#define PROFILESCOMBOBOX_HPP
#include <QComboBox>
class QString;
class QRegExpValidator;
class ProfilesComboBox : public QComboBox
{
Q_OBJECT
public:
explicit ProfilesComboBox(QWidget *parent = 0);
void setEditEnabled(bool editable);
signals:
void profileChanged(const QString &previous, const QString &current);
void profileRenamed(const QString &oldName, const QString &newName);
private slots:
void slotReturnPressed();
void slotIndexChanged(int index);
private:
QString mOldProfile;
QRegExpValidator *mValidator;
};
#endif // PROFILESCOMBOBOX_HPP

@ -0,0 +1,61 @@
#include <QDialogButtonBox>
#include <QPushButton>
#include <QDebug>
#include <QLabel>
#include <QVBoxLayout>
#include <QValidator>
#include "lineedit.hpp"
#include "textinputdialog.hpp"
TextInputDialog::TextInputDialog(const QString& title, const QString &text, QWidget *parent) :
QDialog(parent)
{
setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint);
mButtonBox = new QDialogButtonBox(this);
mButtonBox->addButton(QDialogButtonBox::Ok);
mButtonBox->addButton(QDialogButtonBox::Cancel);
setMaximumHeight(height());
setOkButtonEnabled(false);
setModal(true);
// Messageboxes on mac have no title
#ifndef Q_OS_MAC
setWindowTitle(title);
#else
Q_UNUSED(title);
#endif
QLabel *label = new QLabel(this);
label->setText(text);
// Line edit
QValidator *validator = new QRegExpValidator(QRegExp("^[a-zA-Z0-9_]*$"), this); // Alpha-numeric + underscore
mLineEdit = new LineEdit(this);
mLineEdit->setValidator(validator);
mLineEdit->setCompleter(0);
QVBoxLayout *dialogLayout = new QVBoxLayout(this);
dialogLayout->addWidget(label);
dialogLayout->addWidget(mLineEdit);
dialogLayout->addWidget(mButtonBox);
connect(mButtonBox, SIGNAL(accepted()), this, SLOT(accept()));
connect(mButtonBox, SIGNAL(rejected()), this, SLOT(reject()));
}
int TextInputDialog::exec()
{
mLineEdit->clear();
mLineEdit->setFocus();
return QDialog::exec();
}
void TextInputDialog::setOkButtonEnabled(bool enabled)
{
QPushButton *okButton = mButtonBox->button(QDialogButtonBox::Ok);
okButton->setEnabled(enabled);
}

@ -0,0 +1,28 @@
#ifndef TEXTINPUTDIALOG_HPP
#define TEXTINPUTDIALOG_HPP
#include <QDialog>
//#include "lineedit.hpp"
class QDialogButtonBox;
class LineEdit;
class TextInputDialog : public QDialog
{
Q_OBJECT
public:
explicit TextInputDialog(const QString& title, const QString &text, QWidget *parent = 0);
inline LineEdit *lineEdit() { return mLineEdit; }
void setOkButtonEnabled(bool enabled);
LineEdit *mLineEdit;
int exec();
private:
QDialogButtonBox *mButtonBox;
};
#endif // TEXTINPUTDIALOG_HPP
Loading…
Cancel
Save