diff --git a/apps/launcher/CMakeLists.txt b/apps/launcher/CMakeLists.txt index 044a0a0b7..3c721e238 100644 --- a/apps/launcher/CMakeLists.txt +++ b/apps/launcher/CMakeLists.txt @@ -11,7 +11,9 @@ set(LAUNCHER settings/gamesettings.cpp settings/graphicssettings.cpp + settings/launchersettings.cpp + utils/comboboxlineedit.cpp utils/naturalsort.cpp utils/lineedit.cpp utils/profilescombobox.cpp @@ -32,8 +34,10 @@ set(LAUNCHER_HEADER settings/gamesettings.hpp settings/graphicssettings.hpp + settings/launchersettings.hpp settings/settingsbase.hpp + utils/comboboxlineedit.cpp utils/lineedit.hpp utils/naturalsort.hpp utils/profilescombobox.hpp @@ -52,6 +56,7 @@ set(LAUNCHER_HEADER_MOC model/modelitem.hpp model/esm/esmfile.hpp + utils/comboboxlineedit.hpp utils/lineedit.hpp utils/profilescombobox.hpp utils/textinputdialog.hpp @@ -86,6 +91,7 @@ ENDIF(OGRE_STATIC) add_executable(omwlauncher ${GUI_TYPE} ${LAUNCHER} + ${LAUNCHER_HEADER} ${RCC_SRCS} ${MOC_SRCS} ) diff --git a/apps/launcher/datafilespage.cpp b/apps/launcher/datafilespage.cpp index e25300394..12323b1f1 100644 --- a/apps/launcher/datafilespage.cpp +++ b/apps/launcher/datafilespage.cpp @@ -7,6 +7,7 @@ #include "model/esm/esmfile.hpp" #include "settings/gamesettings.hpp" +#include "settings/launchersettings.hpp" #include "utils/profilescombobox.hpp" #include "utils/lineedit.hpp" @@ -47,9 +48,10 @@ bool rowSmallerThan(const QModelIndex &index1, const QModelIndex &index2) return index1.row() <= index2.row(); } -DataFilesPage::DataFilesPage(Files::ConfigurationManager &cfg, GameSettings &gameSettings, QWidget *parent) +DataFilesPage::DataFilesPage(Files::ConfigurationManager &cfg, GameSettings &gameSettings, LauncherSettings &launcherSettings, QWidget *parent) : mCfgMgr(cfg) , mGameSettings(gameSettings) + , mLauncherSettings(launcherSettings) , QWidget(parent) { // Models @@ -129,15 +131,19 @@ DataFilesPage::DataFilesPage(Files::ConfigurationManager &cfg, GameSettings &gam 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); + mSplitter = new QSplitter(this); + mSplitter->setOrientation(Qt::Horizontal); + mSplitter->setChildrenCollapsible(false); // Don't allow the widgets to be hidden + mSplitter->addWidget(mMastersTable); + mSplitter->addWidget(mPluginsTable); // Adjust the default widget widths inside the splitter QList sizeList; - sizeList << 175 << 200; - splitter->setSizes(sizeList); + sizeList << mLauncherSettings.value(QString("General/MastersTable/width"), QString("200")).toInt(); + sizeList << mLauncherSettings.value(QString("General/PluginTable/width"), QString("340")).toInt(); + qDebug() << sizeList; + + mSplitter->setSizes(sizeList); // Bottom part with profile options QLabel *profileLabel = new QLabel(tr("Current Profile: "), this); @@ -158,7 +164,7 @@ DataFilesPage::DataFilesPage(Files::ConfigurationManager &cfg, GameSettings &gam QVBoxLayout *pageLayout = new QVBoxLayout(this); pageLayout->addWidget(filterToolBar); - pageLayout->addWidget(splitter); + pageLayout->addWidget(mSplitter); pageLayout->addWidget(mProfileToolBar); // Create a dialog for the new profile name input @@ -178,8 +184,9 @@ DataFilesPage::DataFilesPage(Files::ConfigurationManager &cfg, GameSettings &gam 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(); - setupConfig(); setupDataFiles(); } @@ -221,126 +228,50 @@ void DataFilesPage::createActions() } -void DataFilesPage::setupConfig() -{ - // Open our config file - QString config = QString::fromStdString((mCfgMgr.getUserPath() / "launcher.cfg").string()); - mLauncherConfig = new QSettings(config, QSettings::IniFormat); - - // Make sure we have no groups open - while (!mLauncherConfig->group().isEmpty()) { - mLauncherConfig->endGroup(); - } - - mLauncherConfig->beginGroup("Profiles"); - QStringList profiles = mLauncherConfig->childGroups(); - - // 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); - } - - // Add a default profile - if (mProfilesComboBox->findText(QString("Default")) == -1) { - mProfilesComboBox->addItem(QString("Default")); - } - - QString currentProfile = mLauncherConfig->value("CurrentProfile").toString(); - - if (currentProfile.isEmpty()) { - // No current profile selected - currentProfile = "Default"; - } - - const int currentIndex = mProfilesComboBox->findText(currentProfile); - if (currentIndex != -1) { - // Profile is found - mProfilesComboBox->setCurrentIndex(currentIndex); - } - - mLauncherConfig->endGroup(); -} - - void DataFilesPage::readConfig() { - // Don't read the config if no masters are found - if (mMastersModel->rowCount() < 1) - return; - - QString profile = mProfilesComboBox->currentText(); - - // Make sure we have no groups open - while (!mLauncherConfig->group().isEmpty()) { - mLauncherConfig->endGroup(); - } - - mLauncherConfig->beginGroup("Profiles"); - mLauncherConfig->beginGroup(profile); - - QStringList childKeys = mLauncherConfig->childKeys(); - QStringList plugins; - - // Sort the child keys numerical instead of alphabetically - // i.e. Plugin1, Plugin2 instead of Plugin1, Plugin10 - qSort(childKeys.begin(), childKeys.end(), naturalSortLessThanCI); - - foreach (const QString &key, childKeys) { - const QString keyValue = mLauncherConfig->value(key).toString(); - - if (key.startsWith("Plugin")) { - //QStringList checked = mPluginsModel->checkedItems(); - EsmFile *file = mPluginsModel->findItem(keyValue); - QModelIndex index = mPluginsModel->indexFromItem(file); - - mPluginsModel->setCheckState(index, Qt::Checked); - // Move the row to the top of te view - //mPluginsModel->moveRow(index.row(), checked.count()); - plugins << keyValue; - } +// // Don't read the config if no masters are found +// if (mMastersModel->rowCount() < 1) +// return; - if (key.startsWith("Master")) { - EsmFile *file = mMastersModel->findItem(keyValue); - mMastersModel->setCheckState(mMastersModel->indexFromItem(file), Qt::Checked); - } - } +// QString profile = mProfilesComboBox->currentText(); - qDebug() << plugins; +// // Make sure we have no groups open +// while (!mLauncherConfig->group().isEmpty()) { +// mLauncherConfig->endGroup(); +// } +// mLauncherConfig->beginGroup("Profiles"); +// mLauncherConfig->beginGroup(profile); -// // Set the checked item positions -// const QStringList checked = mPluginsModel->checkedItems(); -// for (int i = 0; i < plugins.size(); ++i) { -// EsmFile *file = mPluginsModel->findItem(plugins.at(i)); -// QModelIndex index = mPluginsModel->indexFromItem(file); -// mPluginsModel->moveRow(index.row(), i); -// qDebug() << "Moving: " << plugins.at(i) << " from: " << index.row() << " to: " << i << " count: " << checked.count(); +// QStringList childKeys = mLauncherConfig->childKeys(); +// QStringList plugins; -// } +// // Sort the child keys numerical instead of alphabetically +// // i.e. Plugin1, Plugin2 instead of Plugin1, Plugin10 +// qSort(childKeys.begin(), childKeys.end(), naturalSortLessThanCI); - // Iterate over the plugins to set their checkstate and position -// for (int i = 0; i < plugins.size(); ++i) { -// const QString plugin = plugins.at(i); +// foreach (const QString &key, childKeys) { +// const QString keyValue = mLauncherConfig->value(key).toString(); -// const QList pluginList = mPluginsModel->findItems(plugin); +// if (key.startsWith("Plugin")) { +// //QStringList checked = mPluginsModel->checkedItems(); +// EsmFile *file = mPluginsModel->findItem(keyValue); +// QModelIndex index = mPluginsModel->indexFromItem(file); -// if (!pluginList.isEmpty()) -// { -// foreach (const QStandardItem *currentPlugin, pluginList) { -// mPluginsModel->setData(currentPlugin->index(), Qt::Checked, Qt::CheckStateRole); +// mPluginsModel->setCheckState(index, Qt::Checked); +// // Move the row to the top of te view +// //mPluginsModel->moveRow(index.row(), checked.count()); +// plugins << keyValue; +// } -// // Move the plugin to the position specified in the config file -// mPluginsModel->insertRow(i, mPluginsModel->takeRow(currentPlugin->row())); -// } +// if (key.startsWith("Master")) { +// EsmFile *file = mMastersModel->findItem(keyValue); +// mMastersModel->setCheckState(mMastersModel->indexFromItem(file), Qt::Checked); // } // } +// qDebug() << plugins; } void DataFilesPage::setupDataFiles() @@ -362,10 +293,43 @@ void DataFilesPage::setupDataFiles() mPluginsModel->addPlugins(dataLocal); } + loadSettings(); +} + +void DataFilesPage::loadSettings() +{ + qDebug() << "load settings"; +} + +void DataFilesPage::saveSettings() +{ + QString profile = mLauncherSettings.value(QString("Profiles/CurrentProfile")); + qDebug() << "save settings" << profile; + + QStringList items = mMastersModel->checkedItems(); + + foreach(const QString &master, items) { + mLauncherSettings.setMultiValue(QString("Profiles/") + profile + QString("/master"), master); + } + + items.clear(); + items = mPluginsModel->checkedItems(); + + qDebug() << items.size(); + + foreach(const QString &plugin, items) { + qDebug() << "setting " << plugin; + mLauncherSettings.setMultiValue(QString("Profiles/") + profile + QString("/plugin"), plugin); + } + + + } void DataFilesPage::writeConfig(QString profile) { + + // // Don't overwrite the config if no masters are found // if (mMastersModel->rowCount() < 1) // return; @@ -518,21 +482,22 @@ void DataFilesPage::writeConfig(QString profile) void DataFilesPage::newProfile() { - if (mNewProfileDialog->exec() == QDialog::Accepted) { +// 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(); +// const QString text = mNewProfileDialog->lineEdit()->text(); +// mProfilesComboBox->addItem(text); +// mProfilesComboBox->setCurrentIndex(mProfilesComboBox->findText(text)); +// } - mProfilesComboBox->setCurrentIndex(mProfilesComboBox->findText(text)); - } + mDeleteProfileAction->setEnabled(false); + mProfilesComboBox->setCurrentIndex(-1); + mProfilesComboBox->setEditEnabled(true); + mProfilesComboBox->lineEdit()->setFocus(); } void DataFilesPage::updateOkButton(const QString &text) { + // We do this here because we need the profiles combobox text if (text.isEmpty()) { mNewProfileDialog->setOkButtonEnabled(false); return; @@ -543,6 +508,16 @@ void DataFilesPage::updateOkButton(const QString &text) : mNewProfileDialog->setOkButtonEnabled(false); } +void DataFilesPage::updateSplitter() +{ + // Sigh, update the saved splitter size in settings only when moved + // Since getting mSplitter->sizes() if page is hidden returns invalid values + QList sizes = mSplitter->sizes(); + + mLauncherSettings.setValue(QString("General/MastersTable/width"), QString::number(sizes.at(0))); + mLauncherSettings.setValue(QString("General/PluginsTable/width"), QString::number(sizes.at(1))); +} + void DataFilesPage::deleteProfile() { QString profile = mProfilesComboBox->currentText(); @@ -562,18 +537,8 @@ void DataFilesPage::deleteProfile() msgBox.exec(); if (msgBox.clickedButton() == deleteButton) { - // Make sure we have no groups open - while (!mLauncherConfig->group().isEmpty()) { - mLauncherConfig->endGroup(); - } - - mLauncherConfig->beginGroup("Profiles"); - - // Open the profile-name subgroup - mLauncherConfig->beginGroup(profile); - mLauncherConfig->remove(""); // Clear the subgroup - mLauncherConfig->endGroup(); - mLauncherConfig->endGroup(); + mLauncherSettings.remove(QString("Profiles/") + profile + QString("/master")); + mLauncherSettings.remove(QString("Profiles/") + profile + QString("/plugin")); // Remove the profile from the combobox mProfilesComboBox->removeItem(mProfilesComboBox->findText(profile)); @@ -624,11 +589,8 @@ void DataFilesPage::refresh() { mPluginsModel->sort(0); - // Refresh the plugins table mPluginsTable->scrollToTop(); - writeConfig(); - readConfig(); } @@ -679,50 +641,43 @@ void DataFilesPage::profileChanged(const QString &previous, const QString &curre mProfilesComboBox->setEditEnabled(true); } - if (!previous.isEmpty()) { - writeConfig(previous); - mLauncherConfig->sync(); + if (previous.isEmpty()) + return; - if (mProfilesComboBox->currentIndex() == -1) - return; + if (mProfilesComboBox->findText(previous) == -1) + return; // Profile was deleted + + // Store the previous profile + mLauncherSettings.setValue(QString("Profiles/CurrentProfile"), previous); + saveSettings(); + mLauncherSettings.setValue(QString("Profiles/CurrentProfile"), current); - } else { - return; - } mMastersModel->uncheckAll(); mPluginsModel->uncheckAll(); - readConfig(); + loadSettings(); } void DataFilesPage::profileRenamed(const QString &previous, const QString ¤t) { + qDebug() << "rename"; 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"); + mLauncherSettings.setValue(QString("Profiles/CurrentProfile"), current); + saveSettings(); - // Open the profile-name subgroup - mLauncherConfig->beginGroup(previous); - mLauncherConfig->remove(""); // Clear the subgroup - mLauncherConfig->endGroup(); - mLauncherConfig->endGroup(); - mLauncherConfig->sync(); + // Remove the old one + mLauncherSettings.remove(QString("Profiles/") + previous + QString("/master")); + mLauncherSettings.remove(QString("Profiles/") + previous + QString("/plugin")); - // Remove the profile from the combobox - mProfilesComboBox->removeItem(mProfilesComboBox->findText(previous)); + // Remove the profile from the combobox + mProfilesComboBox->removeItem(mProfilesComboBox->findText(previous)); - mMastersModel->uncheckAll(); - mPluginsModel->uncheckAll(); - readConfig(); + mMastersModel->uncheckAll(); + mPluginsModel->uncheckAll(); + loadSettings(); } void DataFilesPage::showContextMenu(const QPoint &point) diff --git a/apps/launcher/datafilespage.hpp b/apps/launcher/datafilespage.hpp index e40d29d60..2dbbdb667 100644 --- a/apps/launcher/datafilespage.hpp +++ b/apps/launcher/datafilespage.hpp @@ -6,16 +6,18 @@ class QTableView; class QSortFilterProxyModel; -class QSettings; class QAction; class QToolBar; +class QSplitter; class QMenu; + class ProfilesComboBox; class DataFilesModel; class TextInputDialog; class ProfilesComboBox; class GameSettings; +class LauncherSettings; namespace Files { struct ConfigurationManager; } @@ -24,11 +26,13 @@ class DataFilesPage : public QWidget Q_OBJECT public: - DataFilesPage(Files::ConfigurationManager &cfg, GameSettings &gameSettings, QWidget *parent = 0); + DataFilesPage(Files::ConfigurationManager &cfg, GameSettings &gameSettings, LauncherSettings &launcherSettings, QWidget *parent = 0); ProfilesComboBox *mProfilesComboBox; void writeConfig(QString profile = QString()); + void saveSettings(); + public slots: void setCheckState(QModelIndex index); @@ -38,6 +42,7 @@ public slots: void profileChanged(const QString &previous, const QString ¤t); void profileRenamed(const QString &previous, const QString ¤t); void updateOkButton(const QString &text); + void updateSplitter(); // Action slots void newProfile(); @@ -61,6 +66,7 @@ private: QToolBar *mProfileToolBar; QMenu *mContextMenu; + QSplitter *mSplitter; QAction *mNewProfileAction; QAction *mDeleteProfileAction; @@ -74,8 +80,8 @@ private: Files::ConfigurationManager &mCfgMgr; - QSettings *mLauncherConfig; GameSettings &mGameSettings; + LauncherSettings &mLauncherSettings; TextInputDialog *mNewProfileDialog; @@ -87,6 +93,8 @@ private: void setupConfig(); void readConfig(); + void loadSettings(); + }; #endif diff --git a/apps/launcher/main.cpp b/apps/launcher/main.cpp index 43bf50fbc..ba84518c1 100644 --- a/apps/launcher/main.cpp +++ b/apps/launcher/main.cpp @@ -16,6 +16,7 @@ #include "maindialog.hpp" #include "settings/gamesettings.hpp" #include "settings/graphicssettings.hpp" +#include "settings/launchersettings.hpp" int main(int argc, char *argv[]) @@ -52,6 +53,7 @@ int main(int argc, char *argv[]) GameSettings gameSettings(cfgMgr); GraphicsSettings graphicsSettings; + LauncherSettings launcherSettings; QStringList paths; paths.append(userPath + QString("openmw.cfg")); @@ -118,8 +120,6 @@ int main(int argc, char *argv[]) } // On to the graphics settings - qDebug() << userPath; - QFile localDefault(QString("settings-default.cfg")); QFile globalDefault(globalPath + QString("settings-default.cfg")); @@ -163,8 +163,36 @@ int main(int argc, char *argv[]) file.close(); } + // Now the launcher settings + paths.clear(); + paths.append(QString("launcher.cfg")); + paths.append(userPath + QString("launcher.cfg")); + + foreach (const QString &path, paths) { + qDebug() << "Loading: " << path; + QFile file(path); + if (file.exists()) { + if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) { + QMessageBox msgBox; + msgBox.setWindowTitle("Error opening OpenMW configuration file"); + msgBox.setIcon(QMessageBox::Critical); + msgBox.setStandardButtons(QMessageBox::Ok); + msgBox.setText(QObject::tr("
Could not open %0 for reading

\ + Please make sure you have the right permissions \ + and try again.
").arg(file.fileName())); + msgBox.exec(); + return 0; + } + QTextStream stream(&file); + stream.setCodec(QTextCodec::codecForName("UTF-8")); + + launcherSettings.readFile(stream); + } + file.close(); + } + - MainDialog mainWin(gameSettings, graphicsSettings); + MainDialog mainWin(gameSettings, graphicsSettings, launcherSettings); if (mainWin.setup()) { mainWin.show(); diff --git a/apps/launcher/maindialog.cpp b/apps/launcher/maindialog.cpp index 4d3d24bd9..f48ea603b 100644 --- a/apps/launcher/maindialog.cpp +++ b/apps/launcher/maindialog.cpp @@ -2,6 +2,7 @@ #include "settings/gamesettings.hpp" #include "settings/graphicssettings.hpp" +#include "settings/launchersettings.hpp" #include "utils/profilescombobox.hpp" @@ -11,9 +12,11 @@ #include "datafilespage.hpp" MainDialog::MainDialog(GameSettings &gameSettings, - GraphicsSettings &graphicsSettings) + GraphicsSettings &graphicsSettings, + LauncherSettings &launcherSettings) : mGameSettings(gameSettings) , mGraphicsSettings(graphicsSettings) + , mLauncherSettings(launcherSettings) { QWidget *centralWidget = new QWidget(this); @@ -132,7 +135,7 @@ void MainDialog::createPages() { mPlayPage = new PlayPage(this); mGraphicsPage = new GraphicsPage(mCfgMgr, mGraphicsSettings, this); - mDataFilesPage = new DataFilesPage(mCfgMgr, mGameSettings, this); + mDataFilesPage = new DataFilesPage(mCfgMgr, mGameSettings, mLauncherSettings, this); // Set the combobox of the play page to imitate the combobox on the datafilespage mPlayPage->mProfilesComboBox->setModel(mDataFilesPage->mProfilesComboBox->model()); @@ -161,18 +164,11 @@ void MainDialog::createPages() bool MainDialog::setup() { - // Setup the Graphics page + // Call this so we can exit on Ogre errors before mainwindow is shown if (!mGraphicsPage->setupOgre()) { return false; } - // Setup the Data Files page - /* - if (!mDataFilesPage->setupDataFiles()) { - return false; - }*/ - - return true; } @@ -184,11 +180,28 @@ void MainDialog::changePage(QListWidgetItem *current, QListWidgetItem *previous) mPagesWidget->setCurrentIndex(mIconWidget->row(current)); } -void MainDialog::closeEvent(QCloseEvent *event) +void MainDialog::loadSettings() +{ + +} + +void MainDialog::saveSettings() +{ + QString width = QString::number(this->width()); + QString height = QString::number(this->height()); + + mLauncherSettings.setValue(QString("General/MainWindow/width"), width); + mLauncherSettings.setValue(QString("General/MainWindow/height"), height); + + qDebug() << "size: " << width << height; +} + +void MainDialog::writeSettings() { // Now write all config files - mDataFilesPage->writeConfig(); + saveSettings(); mGraphicsPage->saveSettings(); + mDataFilesPage->saveSettings(); QString userPath = QString::fromStdString(mCfgMgr.getUserPath().string()); QDir dir(userPath); @@ -203,7 +216,7 @@ void MainDialog::closeEvent(QCloseEvent *event) Please make sure you have the right permissions \ and try again.
").arg(userPath)); msgBox.exec(); - event->accept(); + return; } } @@ -220,7 +233,7 @@ void MainDialog::closeEvent(QCloseEvent *event) Please make sure you have the right permissions \ and try again.
").arg(file.fileName())); msgBox.exec(); - event->accept(); + return; } QTextStream stream(&file); @@ -242,26 +255,52 @@ void MainDialog::closeEvent(QCloseEvent *event) Please make sure you have the right permissions \ and try again.
").arg(file.fileName())); msgBox.exec(); - event->accept(); + return; } stream.setDevice(&file); stream.setCodec(QTextCodec::codecForName("UTF-8")); mGraphicsSettings.writeFile(stream); + file.close(); + + // Launcher settings + file.setFileName(userPath + QString("launcher.cfg")); + + if (!file.open(QIODevice::ReadWrite | QIODevice::Text | QIODevice::Truncate)) { + // File cannot be opened or created + QMessageBox msgBox; + msgBox.setWindowTitle("Error writing Launcher configuration file"); + msgBox.setIcon(QMessageBox::Critical); + msgBox.setStandardButtons(QMessageBox::Ok); + msgBox.setText(tr("
Could not open or create %0 for writing

\ + Please make sure you have the right permissions \ + and try again.
").arg(file.fileName())); + msgBox.exec(); + return; + } + stream.setDevice(&file); + stream.setCodec(QTextCodec::codecForName("UTF-8")); + + mLauncherSettings.writeFile(stream); + file.close(); +} + +void MainDialog::closeEvent(QCloseEvent *event) +{ + saveSettings(); + writeSettings(); event->accept(); } void MainDialog::play() { // First do a write of all the configs, just to be sure - mDataFilesPage->writeConfig(); + //mDataFilesPage->writeConfig(); //mGraphicsPage->writeConfig(); - - // Save user settings - const std::string settingspath = (mCfgMgr.getUserPath() / "settings.cfg").string(); - mSettings.saveUser(settingspath); + saveSettings(); + writeSettings(); #ifdef Q_OS_WIN QString game = "./openmw.exe"; diff --git a/apps/launcher/maindialog.hpp b/apps/launcher/maindialog.hpp index c9654b874..7167d101d 100644 --- a/apps/launcher/maindialog.hpp +++ b/apps/launcher/maindialog.hpp @@ -4,7 +4,6 @@ #include #include -#include class QListWidget; class QListWidgetItem; @@ -19,22 +18,31 @@ class DataFilesPage; class GameSettings; class GraphicsSettings; +class LauncherSettings; class MainDialog : public QMainWindow { Q_OBJECT public: - MainDialog(GameSettings &gameSettings, GraphicsSettings &GraphicsSettings); + MainDialog(GameSettings &gameSettings, + GraphicsSettings &GraphicsSettings, + LauncherSettings &launcherSettings); + + bool setup(); public slots: void changePage(QListWidgetItem *current, QListWidgetItem *previous); void play(); - bool setup(); private: void createIcons(); void createPages(); + + void loadSettings(); + void saveSettings(); + void writeSettings(); + void closeEvent(QCloseEvent *event); QListWidget *mIconWidget; @@ -45,10 +53,10 @@ private: DataFilesPage *mDataFilesPage; Files::ConfigurationManager mCfgMgr; - Settings::Manager mSettings; GameSettings &mGameSettings; GraphicsSettings &mGraphicsSettings; + LauncherSettings &mLauncherSettings; }; diff --git a/apps/launcher/model/datafilesmodel.cpp b/apps/launcher/model/datafilesmodel.cpp index e84dbe0ac..ae59cc3c3 100644 --- a/apps/launcher/model/datafilesmodel.cpp +++ b/apps/launcher/model/datafilesmodel.cpp @@ -334,6 +334,7 @@ void DataFilesModel::addPlugins(const QString &path) QFileInfo info(dir.absoluteFilePath(path)); EsmFile *file = new EsmFile(path); + try { ESM::ESMReader fileReader; ToUTF8::Utf8Encoder encoder (ToUTF8::calculateEncoding(mEncoding.toStdString())); @@ -361,7 +362,8 @@ void DataFilesModel::addPlugins(const QString &path) // Put the file in the table - addFile(file); + if (findItem(path) == 0) + addFile(file); } catch(std::runtime_error &e) { // An error occurred while reading the .esp qWarning() << "Error reading esp: " << e.what(); diff --git a/apps/launcher/settings/gamesettings.cpp b/apps/launcher/settings/gamesettings.cpp index 2420c1e6c..5f0fb77bc 100644 --- a/apps/launcher/settings/gamesettings.cpp +++ b/apps/launcher/settings/gamesettings.cpp @@ -101,7 +101,14 @@ bool GameSettings::readFile(QTextStream &stream) qDebug() << "key: " << key; // There can be multiple data keys if (key == QLatin1String("data")) { - cache.insertMulti(key, value); + // 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; + cache.insertMulti(key, value); + } } else { cache.insert(key, value); } diff --git a/apps/launcher/settings/launchersettings.cpp b/apps/launcher/settings/launchersettings.cpp new file mode 100644 index 000000000..c189c282f --- /dev/null +++ b/apps/launcher/settings/launchersettings.cpp @@ -0,0 +1,45 @@ +#include +#include +#include +#include + +#include "launchersettings.hpp" + +LauncherSettings::LauncherSettings() +{ +} + +LauncherSettings::~LauncherSettings() +{ +} + + +bool LauncherSettings::writeFile(QTextStream &stream) +{ + QString sectionPrefix; + QRegExp sectionRe("([^/]+)/(.+)$"); + QMap settings = SettingsBase::getSettings(); + + QMapIterator i(settings); + while (i.hasNext()) { + i.next(); + + QString prefix; + QString key; + + if (sectionRe.exactMatch(i.key())) { + prefix = sectionRe.cap(1); + key = sectionRe.cap(2); + } + + if (sectionPrefix != prefix) { + sectionPrefix = prefix; + stream << "\n[" << prefix << "]\n"; + } + + stream << key << "=" << i.value() << "\n"; + } + + return true; + +} diff --git a/apps/launcher/settings/launchersettings.hpp b/apps/launcher/settings/launchersettings.hpp new file mode 100644 index 000000000..cf4dd4c9f --- /dev/null +++ b/apps/launcher/settings/launchersettings.hpp @@ -0,0 +1,16 @@ +#ifndef LAUNCHERSETTINGS_HPP +#define LAUNCHERSETTINGS_HPP + +#include "settingsbase.hpp" + +class LauncherSettings : public SettingsBase> +{ +public: + LauncherSettings(); + ~LauncherSettings(); + + bool writeFile(QTextStream &stream); + +}; + +#endif // LAUNCHERSETTINGS_HPP diff --git a/apps/launcher/settings/settingsbase.hpp b/apps/launcher/settings/settingsbase.hpp index 6b8b52762..e09ea6203 100644 --- a/apps/launcher/settings/settingsbase.hpp +++ b/apps/launcher/settings/settingsbase.hpp @@ -2,6 +2,7 @@ #define SETTINGSBASE_HPP #include +#include #include #include #include @@ -26,6 +27,17 @@ public: mSettings.insert(key, value); } + inline void setMultiValue(const QString &key, const QString &value) + { + mSettings.insertMulti(key, value); + } + + + inline void remove(const QString &key) + { + mSettings.remove(key); + } + Map getSettings() {return mSettings;} bool readFile(QTextStream &stream) @@ -56,11 +68,18 @@ public: if (!sectionPrefix.isEmpty()) key.prepend(sectionPrefix); - // QMap will replace the value if key exists, QMultiMap creates a new one - mCache.insert(key, value); + mSettings.remove(key); + + QStringList values = mCache.values(key); + if (!values.contains(value)) { + // QMap will replace the value if key exists, QMultiMap creates a new one + mCache.insert(key, value); + } } } + qDebug() << "HI THERE! " << mCache; + if (mSettings.isEmpty()) { mSettings = mCache; // This is the first time we read a file return true; diff --git a/apps/launcher/utils/lineedit.cpp b/apps/launcher/utils/lineedit.cpp index dac196425..b0f339589 100644 --- a/apps/launcher/utils/lineedit.cpp +++ b/apps/launcher/utils/lineedit.cpp @@ -1,7 +1,8 @@ -#include "lineedit.hpp" #include #include +#include "lineedit.hpp" + LineEdit::LineEdit(QWidget *parent) : QLineEdit(parent) { @@ -13,9 +14,11 @@ LineEdit::LineEdit(QWidget *parent) mClearButton->setStyleSheet("QToolButton { border: none; padding: 0px; }"); mClearButton->hide(); connect(mClearButton, SIGNAL(clicked()), this, SLOT(clear())); - connect(this, SIGNAL(textChanged(const QString&)), this, SLOT(updateCloseButton(const QString&))); + connect(this, SIGNAL(textChanged(const QString&)), this, SLOT(updateClearButton(const QString&))); int frameWidth = style()->pixelMetric(QStyle::PM_DefaultFrameWidth); - setStyleSheet(QString("QLineEdit { padding-right: %1px; } ").arg(mClearButton->sizeHint().width() + frameWidth + 1)); + + setObjectName(QString("LineEdit")); + setStyleSheet(QString("LineEdit { padding-right: %1px; } ").arg(mClearButton->sizeHint().width() + frameWidth + 1)); QSize msz = minimumSizeHint(); setMinimumSize(qMax(msz.width(), mClearButton->sizeHint().height() + frameWidth * 2 + 2), qMax(msz.height(), mClearButton->sizeHint().height() + frameWidth * 2 + 2)); @@ -29,9 +32,7 @@ void LineEdit::resizeEvent(QResizeEvent *) (rect().bottom() + 1 - sz.height())/2); } -void LineEdit::updateCloseButton(const QString& text) +void LineEdit::updateClearButton(const QString& text) { mClearButton->setVisible(!text.isEmpty()); } - - diff --git a/apps/launcher/utils/lineedit.hpp b/apps/launcher/utils/lineedit.hpp index 2ed76d6eb..14bd7b1b4 100644 --- a/apps/launcher/utils/lineedit.hpp +++ b/apps/launcher/utils/lineedit.hpp @@ -25,7 +25,7 @@ protected: void resizeEvent(QResizeEvent *); private slots: - void updateCloseButton(const QString &text); + void updateClearButton(const QString &text); private: QToolButton *mClearButton; diff --git a/apps/launcher/utils/profilescombobox.cpp b/apps/launcher/utils/profilescombobox.cpp index 8354d4a78..3a75ba417 100644 --- a/apps/launcher/utils/profilescombobox.cpp +++ b/apps/launcher/utils/profilescombobox.cpp @@ -1,45 +1,94 @@ #include #include #include +#include +#include #include "profilescombobox.hpp" +#include "comboboxlineedit.hpp" ProfilesComboBox::ProfilesComboBox(QWidget *parent) : QComboBox(parent) { mValidator = new QRegExpValidator(QRegExp("^[a-zA-Z0-9_]*$"), this); // Alpha-numeric + underscore - - setEditable(true); + setEditEnabled(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) + qDebug() << "called"; + if (isEditable() == editable) + return; + + if (!editable) { + disconnect(lineEdit(), SIGNAL(editingFinished()), this, SLOT(slotEditingFinished())); + disconnect(lineEdit(), SIGNAL(textChanged(QString)), this, SLOT(slotTextChanged(QString))); return setEditable(false); + } // Reset the completer and validator setEditable(true); setValidator(mValidator); + + ComboBoxLineEdit *edit = new ComboBoxLineEdit(this); + setLineEdit(edit); setCompleter(0); + + connect(lineEdit(), SIGNAL(editingFinished()), this, + SLOT(slotEditingFinished())); + + connect(lineEdit(), SIGNAL(textChanged(QString)), this, + SLOT(slotTextChanged(QString))); } -void ProfilesComboBox::slotReturnPressed() +void ProfilesComboBox::slotTextChanged(const QString &text) { + QString previous = itemText(currentIndex()); +// lineEdit()->setPalette(QApplication::palette()); + + if (text.isEmpty()) + return; + + if (text == previous) + return; + + qDebug() << "textChanged"; + if (findText(text) != -1) { + QPalette *palette = new QPalette(); + palette->setColor(QPalette::Text,Qt::red); + lineEdit()->setPalette(*palette); + } +} + +void ProfilesComboBox::slotEditingFinished() +{ + qDebug() << "returnpressed"; QString current = currentText(); QString previous = itemText(currentIndex()); + if (current.isEmpty()) + return; + + if (current == previous) + return; + if (findText(current) != -1) return; - setItemText(currentIndex(), current); - emit(profileRenamed(previous, current)); + + if (currentIndex() == -1) { + addItem(currentText()); + } else { + setItemText(currentIndex(), current); + emit(profileRenamed(previous, current)); + } } void ProfilesComboBox::slotIndexChanged(int index) diff --git a/apps/launcher/utils/profilescombobox.hpp b/apps/launcher/utils/profilescombobox.hpp index c7da60d2a..08ead9a7a 100644 --- a/apps/launcher/utils/profilescombobox.hpp +++ b/apps/launcher/utils/profilescombobox.hpp @@ -4,7 +4,6 @@ #include class QString; - class QRegExpValidator; class ProfilesComboBox : public QComboBox @@ -19,8 +18,9 @@ signals: void profileRenamed(const QString &oldName, const QString &newName); private slots: - void slotReturnPressed(); + void slotEditingFinished(); void slotIndexChanged(int index); + void slotTextChanged(const QString &text); private: QString mOldProfile;