diff --git a/apps/launcher/CMakeLists.txt b/apps/launcher/CMakeLists.txt
index 92903b48d..edc3dcf32 100644
--- a/apps/launcher/CMakeLists.txt
+++ b/apps/launcher/CMakeLists.txt
@@ -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})
diff --git a/apps/launcher/datafilespage.cpp b/apps/launcher/datafilespage.cpp
index ce3d6b31d..01b879842 100644
--- a/apps/launcher/datafilespage.cpp
+++ b/apps/launcher/datafilespage.cpp
@@ -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 %0 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 ¤t)
{
+ 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 ¤t)
+{
+ 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
diff --git a/apps/launcher/datafilespage.hpp b/apps/launcher/datafilespage.hpp
index 64f255b57..8b48c1e12 100644
--- a/apps/launcher/datafilespage.hpp
+++ b/apps/launcher/datafilespage.hpp
@@ -3,7 +3,7 @@
#include
#include
-
+#include "utils/profilescombobox.hpp"
#include
@@ -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 ¤t);
+ void profileRenamed(const QString &previous, const QString ¤t);
+ void updateOkButton(const QString &text);
// Action slots
void newProfile();
@@ -77,6 +80,8 @@ private:
QSettings *mLauncherConfig;
+ TextInputDialog *mNewProfileDialog;
+
// const QStringList checkedPlugins();
// const QStringList selectedMasters();
diff --git a/apps/launcher/main.cpp b/apps/launcher/main.cpp
index 4ae09f844..7c4cb5f7e 100644
--- a/apps/launcher/main.cpp
+++ b/apps/launcher/main.cpp
@@ -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();
diff --git a/apps/launcher/maindialog.cpp b/apps/launcher/maindialog.cpp
index d65e51f24..3ce418ddf 100644
--- a/apps/launcher/maindialog.cpp
+++ b/apps/launcher/maindialog.cpp
@@ -1,7 +1,5 @@
#include
-#include "utils/combobox.hpp"
-
#include "maindialog.hpp"
#include "playpage.hpp"
#include "graphicspage.hpp"
diff --git a/apps/launcher/utils/combobox.hpp b/apps/launcher/utils/combobox.hpp
deleted file mode 100644
index bc99575d7..000000000
--- a/apps/launcher/utils/combobox.hpp
+++ /dev/null
@@ -1,28 +0,0 @@
-#ifndef COMBOBOX_H
-#define COMBOBOX_H
-
-#include
-
-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
\ No newline at end of file
diff --git a/apps/launcher/utils/profilescombobox.cpp b/apps/launcher/utils/profilescombobox.cpp
new file mode 100644
index 000000000..8354d4a78
--- /dev/null
+++ b/apps/launcher/utils/profilescombobox.cpp
@@ -0,0 +1,52 @@
+#include
+#include
+#include
+
+#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);
+}
diff --git a/apps/launcher/utils/profilescombobox.hpp b/apps/launcher/utils/profilescombobox.hpp
new file mode 100644
index 000000000..c7da60d2a
--- /dev/null
+++ b/apps/launcher/utils/profilescombobox.hpp
@@ -0,0 +1,30 @@
+#ifndef PROFILESCOMBOBOX_HPP
+#define PROFILESCOMBOBOX_HPP
+
+#include
+
+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 ¤t);
+ void profileRenamed(const QString &oldName, const QString &newName);
+
+private slots:
+ void slotReturnPressed();
+ void slotIndexChanged(int index);
+
+private:
+ QString mOldProfile;
+ QRegExpValidator *mValidator;
+};
+
+#endif // PROFILESCOMBOBOX_HPP
diff --git a/apps/launcher/utils/textinputdialog.cpp b/apps/launcher/utils/textinputdialog.cpp
new file mode 100644
index 000000000..16cadb661
--- /dev/null
+++ b/apps/launcher/utils/textinputdialog.cpp
@@ -0,0 +1,61 @@
+#include
+#include
+#include
+#include
+#include
+#include
+
+#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);
+}
diff --git a/apps/launcher/utils/textinputdialog.hpp b/apps/launcher/utils/textinputdialog.hpp
new file mode 100644
index 000000000..cbb453ac8
--- /dev/null
+++ b/apps/launcher/utils/textinputdialog.hpp
@@ -0,0 +1,28 @@
+#ifndef TEXTINPUTDIALOG_HPP
+#define TEXTINPUTDIALOG_HPP
+
+#include
+//#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