diff options
| author | Tannin <devnull@localhost> | 2014-09-10 20:34:31 +0200 |
|---|---|---|
| committer | Tannin <devnull@localhost> | 2014-09-10 20:34:31 +0200 |
| commit | b0a4748da5ffbb5010656d57bbb16912c616ef71 (patch) | |
| tree | 632078b12eda1503c23855963546f55adda2631b | |
| parent | 9daeb9479bd2675d0feef1e1f7bffb3f73361e30 (diff) | |
- descriptions for plugin settings are now displayed
| -rw-r--r-- | src/settings.cpp | 1464 | ||||
| -rw-r--r-- | src/settings.h | 621 | ||||
| -rw-r--r-- | src/settingsdialog.cpp | 355 |
3 files changed, 1227 insertions, 1213 deletions
diff --git a/src/settings.cpp b/src/settings.cpp index 293a06ab..146896db 100644 --- a/src/settings.cpp +++ b/src/settings.cpp @@ -1,730 +1,734 @@ -/*
-Copyright (C) 2012 Sebastian Herbord. All rights reserved.
-
-This file is part of Mod Organizer.
-
-Mod Organizer is free software: you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation, either version 3 of the License, or
-(at your option) any later version.
-
-Mod Organizer is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#include "settings.h"
-
-#include "settingsdialog.h"
-#include "utility.h"
-#include "helper.h"
-#include <gameinfo.h>
-#include <appconfig.h>
-#include <utility.h>
-#include <json.h>
-
-#include <QCheckBox>
-#include <QLineEdit>
-#include <QDirIterator>
-#include <QRegExp>
-#include <QCoreApplication>
-#include <QMessageBox>
-#include <QDesktopServices>
-
-
-using namespace MOBase;
-using namespace MOShared;
-
-
-template <typename T>
-class QListWidgetItemEx : public QListWidgetItem {
-public:
- QListWidgetItemEx(const QString &text, int sortRole = Qt::DisplayRole, QListWidget *parent = 0, int type = Type)
- : QListWidgetItem(text, parent, type), m_SortRole(sortRole) {}
-
- virtual bool operator< ( const QListWidgetItem & other ) const {
- return this->data(m_SortRole).value<T>() < other.data(m_SortRole).value<T>();
- }
-private:
- int m_SortRole;
-};
-
-
-static const unsigned char Key2[20] = { 0x99, 0xb8, 0x76, 0x42, 0x3e, 0xc1, 0x60, 0xa4, 0x5b, 0x01,
- 0xdb, 0xf8, 0x43, 0x3a, 0xb7, 0xb6, 0x98, 0xd4, 0x7d, 0xa2 };
-
-Settings *Settings::s_Instance = NULL;
-
-
-Settings::Settings()
- : m_Settings(ToQString(GameInfo::instance().getIniFilename()), QSettings::IniFormat)
-{
- if (s_Instance != NULL) {
- throw std::runtime_error("second instance of \"Settings\" created");
- } else {
- s_Instance = this;
- }
-}
-
-
-Settings::~Settings()
-{
- s_Instance = NULL;
-}
-
-
-Settings &Settings::instance()
-{
- if (s_Instance == NULL) {
- throw std::runtime_error("no instance of \"Settings\"");
- }
- return *s_Instance;
-}
-
-void Settings::clearPlugins()
-{
- m_Plugins.clear();
- m_PluginSettings.clear();
-
- m_PluginBlacklist.clear();
- int count = m_Settings.beginReadArray("pluginBlacklist");
- for (int i = 0; i < count; ++i) {
- m_Settings.setArrayIndex(i);
- m_PluginBlacklist.insert(m_Settings.value("name").toString());
- }
- m_Settings.endArray();
-}
-
-bool Settings::pluginBlacklisted(const QString &fileName) const
-{
- return m_PluginBlacklist.contains(fileName);
-}
-
-void Settings::registerAsNXMHandler(bool force)
-{
- std::wstring nxmPath = ToWString(QCoreApplication::applicationDirPath() + "/nxmhandler.exe");
- std::wstring executable = ToWString(QCoreApplication::applicationFilePath());
- std::wstring mode = force ? L"forcereg" : L"reg";
- std::wstring parameters = mode + L" " + GameInfo::instance().getGameShortName() + L" \"" + executable + L"\"";
- HINSTANCE res = ::ShellExecuteW(NULL, L"open", nxmPath.c_str(), parameters.c_str(), NULL, SW_SHOWNORMAL);
- if ((int)res <= 32) {
- QMessageBox::critical(NULL, tr("Failed"),
- tr("Sorry, failed to start the helper application"));
- }
-}
-
-void Settings::registerPlugin(IPlugin *plugin)
-{
- m_Plugins.push_back(plugin);
- m_PluginSettings.insert(plugin->name(), QMap<QString, QVariant>());
- foreach (const PluginSetting &setting, plugin->settings()) {
- QVariant temp = m_Settings.value("Plugins/" + plugin->name() + "/" + setting.key, setting.defaultValue);
- if (!temp.convert(setting.defaultValue.type())) {
- qWarning("failed to interpret \"%s\" as correct type for \"%s\" in plugin \"%s\", using default",
- qPrintable(temp.toString()), qPrintable(setting.key), qPrintable(plugin->name()));
- temp = setting.defaultValue;
- }
- m_PluginSettings[plugin->name()][setting.key] = temp;
- }
-}
-
-QString Settings::obfuscate(const QString &password) const
-{
- QByteArray temp = password.toUtf8();
-
- QByteArray buffer;
- for (int i = 0; i < temp.length(); ++i) {
- buffer.append(temp.at(i) ^ Key2[i % 20]);
- }
- return buffer.toBase64();
-}
-
-
-QString Settings::deObfuscate(const QString &password) const
-{
- QByteArray temp(QByteArray::fromBase64(password.toUtf8()));
-
- QByteArray buffer;
- for (int i = 0; i < temp.length(); ++i) {
- buffer.append(temp.at(i) ^ Key2[i % 20]);
- }
- return QString::fromUtf8(buffer.constData());
-}
-
-
-bool Settings::hideUncheckedPlugins() const
-{
- return m_Settings.value("Settings/hide_unchecked_plugins", false).toBool();
-}
-
-bool Settings::forceEnableCoreFiles() const
-{
- return m_Settings.value("Settings/force_enable_core_files", true).toBool();
-}
-
-bool Settings::automaticLoginEnabled() const
-{
- return m_Settings.value("Settings/nexus_login", false).toBool();
-}
-
-QString Settings::getSteamAppID() const
-{
- return m_Settings.value("Settings/app_id", ToQString(GameInfo::instance().getSteamAPPId(m_Settings.value("game_edition", 0).toInt()))).toString();
-}
-
-QString Settings::getDownloadDirectory() const
-{
- return QDir::toNativeSeparators(m_Settings.value("Settings/download_directory", ToQString(GameInfo::instance().getDownloadDir())).toString());
-}
-
-
-void Settings::setDownloadSpeed(const QString &serverName, int bytesPerSecond)
-{
- m_Settings.beginGroup("Servers");
-
- foreach (const QString &serverKey, m_Settings.childKeys()) {
- QVariantMap data = m_Settings.value(serverKey).toMap();
- if (serverKey == serverName) {
- data["downloadCount"] = data["downloadCount"].toInt() + 1;
- data["downloadSpeed"] = data["downloadSpeed"].toDouble() + static_cast<double>(bytesPerSecond);
- m_Settings.setValue(serverKey, data);
- }
- }
-
- m_Settings.endGroup();
- m_Settings.sync();
-}
-
-std::map<QString, int> Settings::getPreferredServers()
-{
- std::map<QString, int> result;
- m_Settings.beginGroup("Servers");
-
- foreach (const QString &serverKey, m_Settings.childKeys()) {
- QVariantMap data = m_Settings.value(serverKey).toMap();
- int preference = data["preferred"].toInt();
- if (preference > 0) {
- result[serverKey] = preference;
- }
- }
- m_Settings.endGroup();
-
- return result;
-}
-
-QString Settings::getCacheDirectory() const
-{
- return QDir::toNativeSeparators(m_Settings.value("Settings/cache_directory", ToQString(GameInfo::instance().getCacheDir())).toString());
-}
-
-QString Settings::getModDirectory() const
-{
- return QDir::toNativeSeparators(m_Settings.value("Settings/mod_directory", ToQString(GameInfo::instance().getModsDir())).toString());
-}
-
-QString Settings::getNMMVersion() const
-{
- static const QString MIN_NMM_VERSION = "0.47.0";
- QString result = m_Settings.value("Settings/nmm_version", MIN_NMM_VERSION).toString();
- if (VersionInfo(result) < VersionInfo(MIN_NMM_VERSION)) {
- result = MIN_NMM_VERSION;
- }
- return result;
-}
-
-bool Settings::getNexusLogin(QString &username, QString &password) const
-{
- if (m_Settings.value("Settings/nexus_login", false).toBool()) {
- username = m_Settings.value("Settings/nexus_username", "").toString();
- password = deObfuscate(m_Settings.value("Settings/nexus_password", "").toString());
- return true;
- } else {
- return false;
- }
-}
-
-bool Settings::compactDownloads() const
-{
- return m_Settings.value("Settings/compact_downloads", false).toBool();
-}
-
-bool Settings::metaDownloads() const
-{
- return m_Settings.value("Settings/meta_downloads", false).toBool();
-}
-
-bool Settings::offlineMode() const
-{
- return m_Settings.value("Settings/offline_mode", false).toBool();
-}
-
-int Settings::logLevel() const
-{
- return m_Settings.value("Settings/log_level", 0).toInt();
-}
-
-
-void Settings::setNexusLogin(QString username, QString password)
-{
- m_Settings.setValue("Settings/nexus_login", true);
- m_Settings.setValue("Settings/nexus_username", username);
- m_Settings.setValue("Settings/nexus_password", obfuscate(password));
-}
-
-
-LoadMechanism::EMechanism Settings::getLoadMechanism() const
-{
- switch (m_Settings.value("Settings/load_mechanism").toInt()) {
- case LoadMechanism::LOAD_MODORGANIZER: return LoadMechanism::LOAD_MODORGANIZER;
- case LoadMechanism::LOAD_SCRIPTEXTENDER: return LoadMechanism::LOAD_SCRIPTEXTENDER;
- case LoadMechanism::LOAD_PROXYDLL: return LoadMechanism::LOAD_PROXYDLL;
- }
- throw std::runtime_error("invalid load mechanism");
-}
-
-
-void Settings::setupLoadMechanism()
-{
- m_LoadMechanism.activate(getLoadMechanism());
-}
-
-
-bool Settings::useProxy()
-{
- return m_Settings.value("Settings/use_proxy", false).toBool();
-}
-
-bool Settings::displayForeign()
-{
- return m_Settings.value("Settings/display_foreign", true).toBool();
-}
-
-void Settings::setMotDHash(uint hash)
-{
- m_Settings.setValue("motd_hash", hash);
-}
-
-uint Settings::getMotDHash() const
-{
- return m_Settings.value("motd_hash", 0).toUInt();
-}
-
-QVariant Settings::pluginSetting(const QString &pluginName, const QString &key) const
-{
- auto iterPlugin = m_PluginSettings.find(pluginName);
- if (iterPlugin == m_PluginSettings.end()) {
- return QVariant();
- }
- auto iterSetting = iterPlugin->find(key);
- if (iterSetting == iterPlugin->end()) {
- return QVariant();
- }
-
- return *iterSetting;
-}
-
-void Settings::setPluginSetting(const QString &pluginName, const QString &key, const QVariant &value)
-{
- auto iterPlugin = m_PluginSettings.find(pluginName);
- if (iterPlugin == m_PluginSettings.end()) {
- throw MyException(tr("attempt to store setting for unknown plugin \"%1\"").arg(pluginName));
- }
-
- // store the new setting both in memory and in the ini
- m_PluginSettings[pluginName][key] = value;
- m_Settings.setValue("Plugins/" + pluginName + "/" + key, value);
-}
-
-QVariant Settings::pluginPersistent(const QString &pluginName, const QString &key, const QVariant &def) const
-{
- if (!m_PluginSettings.contains(pluginName)) {
- return def;
- }
- return m_Settings.value("PluginPersistance/" + pluginName + "/" + key, def);
-}
-
-void Settings::setPluginPersistent(const QString &pluginName, const QString &key, const QVariant &value, bool sync)
-{
- if (!m_PluginSettings.contains(pluginName)) {
- throw MyException(tr("attempt to store setting for unknown plugin \"%1\"").arg(pluginName));
- }
- m_Settings.setValue("PluginPersistance/" + pluginName + "/" + key, value);
- if (sync) {
- m_Settings.sync();
- }
-}
-
-QString Settings::language()
-{
- QString result = m_Settings.value("Settings/language", "").toString();
- if (result.isEmpty()) {
- QStringList languagePreferences = QLocale::system().uiLanguages();
- if (languagePreferences.length() > 0) {
- // the users most favoritest language
- result = languagePreferences.at(0);
- } else {
- // fallback system locale
- result = QLocale::system().name();
- }
- }
- return result;
-}
-
-void Settings::updateServers(const QList<ServerInfo> &servers)
-{
- m_Settings.beginGroup("Servers");
- QStringList oldServerKeys = m_Settings.childKeys();
-
- foreach (const ServerInfo &server, servers) {
- if (!oldServerKeys.contains(server.name)) {
- // not yet known server
- QVariantMap newVal;
- newVal["premium"] = server.premium;
- newVal["preferred"] = server.preferred ? 1 : 0;
- newVal["lastSeen"] = server.lastSeen;
- newVal["downloadCount"] = 0;
- newVal["downloadSpeed"] = 0.0;
-
- m_Settings.setValue(server.name, newVal);
- } else {
- QVariantMap data = m_Settings.value(server.name).toMap();
- data["lastSeen"] = server.lastSeen;
- data["premium"] = server.premium;
-
- m_Settings.setValue(server.name, data);
- }
- }
-
- m_Settings.endGroup();
- m_Settings.sync();
-}
-
-void Settings::addBlacklistPlugin(const QString &fileName)
-{
- m_PluginBlacklist.insert(fileName);
- writePluginBlacklist();
-}
-
-void Settings::writePluginBlacklist()
-{
- m_Settings.beginWriteArray("pluginBlacklist");
- int idx = 0;
- foreach (const QString &plugin, m_PluginBlacklist) {
- m_Settings.setArrayIndex(idx++);
- m_Settings.setValue("name", plugin);
- }
-
- m_Settings.endArray();
-}
-
-void Settings::addLanguages(QComboBox *languageBox)
-{
- languageBox->addItem("English", "en_US");
-
- QDirIterator langIter(QCoreApplication::applicationDirPath() + "/translations", QDir::Files);
- QString pattern = ToQString(AppConfig::translationPrefix()) + "_([a-z]{2,3}(_[A-Z]{2,2})?).qm";
- QRegExp exp(pattern);
- while (langIter.hasNext()) {
- langIter.next();
- QString file = langIter.fileName();
- if (exp.exactMatch(file)) {
- QString languageCode = exp.cap(1);
- QLocale locale(languageCode);
- QString languageString = QLocale::languageToString(locale.language());
- if (locale.language() == QLocale::Chinese) {
- if (languageCode == "zh_TW") {
- languageString = "Chinese (traditional)";
- } else {
- languageString = "Chinese (simplified)";
- }
- }
- languageBox->addItem(QString("%1").arg(languageString), exp.cap(1));
- }
- }
-}
-
-void Settings::addStyles(QComboBox *styleBox)
-{
- styleBox->addItem("None", "");
-#if QT_VERSION >= QT_VERSION_CHECK(5,0,0)
- styleBox->addItem("Fusion", "Fusion");
-#else
- styleBox->addItem("Plastique", "Plastique");
- styleBox->addItem("Cleanlooks", "Cleanlooks");
-#endif
-
- QDirIterator langIter(QCoreApplication::applicationDirPath() + "/" + ToQString(AppConfig::stylesheetsPath()), QStringList("*.qss"), QDir::Files);
- while (langIter.hasNext()) {
- langIter.next();
- QString style = langIter.fileName();
- styleBox->addItem(style, style);
- }
-}
-
-void Settings::resetDialogs()
-{
- m_Settings.beginGroup("DialogChoices");
- QStringList keys = m_Settings.childKeys();
- foreach (QString key, keys) {
- m_Settings.remove(key);
- }
-
- m_Settings.endGroup();
-}
-
-
-void Settings::query(QWidget *parent)
-{
- SettingsDialog dialog(parent);
-
- connect(&dialog, SIGNAL(resetDialogs()), this, SLOT(resetDialogs()));
-
- // General Page
- QComboBox *languageBox = dialog.findChild<QComboBox*>("languageBox");
- QComboBox *styleBox = dialog.findChild<QComboBox*>("styleBox");
- QComboBox *logLevelBox = dialog.findChild<QComboBox*>("logLevelBox");
- QCheckBox *compactBox = dialog.findChild<QCheckBox*>("compactBox");
- QCheckBox *showMetaBox = dialog.findChild<QCheckBox*>("showMetaBox");
-
- QLineEdit *downloadDirEdit = dialog.findChild<QLineEdit*>("downloadDirEdit");
- QLineEdit *modDirEdit = dialog.findChild<QLineEdit*>("modDirEdit");
- QLineEdit *cacheDirEdit = dialog.findChild<QLineEdit*>("cacheDirEdit");
-
- // nexus page
- QCheckBox *loginCheckBox = dialog.findChild<QCheckBox*>("loginCheckBox");
- QLineEdit *usernameEdit = dialog.findChild<QLineEdit*>("usernameEdit");
- QLineEdit *passwordEdit = dialog.findChild<QLineEdit*>("passwordEdit");
- QCheckBox *offlineBox = dialog.findChild<QCheckBox*>("offlineBox");
- QCheckBox *proxyBox = dialog.findChild<QCheckBox*>("proxyBox");
-
- QListWidget *knownServersList = dialog.findChild<QListWidget*>("knownServersList");
- QListWidget *preferredServersList = dialog.findChild<QListWidget*>("preferredServersList");
-
- // plugis page
- QListWidget *pluginsList = dialog.findChild<QListWidget*>("pluginsList");
- QListWidget *pluginBlacklistList = dialog.findChild<QListWidget*>("pluginBlacklist");
-
- // workarounds page
- QCheckBox *forceEnableBox = dialog.findChild<QCheckBox*>("forceEnableBox");
- QComboBox *mechanismBox = dialog.findChild<QComboBox*>("mechanismBox");
- QLineEdit *appIDEdit = dialog.findChild<QLineEdit*>("appIDEdit");
- QLineEdit *nmmVersionEdit = dialog.findChild<QLineEdit*>("nmmVersionEdit");
- QCheckBox *hideUncheckedBox = dialog.findChild<QCheckBox*>("hideUncheckedBox");
- QCheckBox *displayForeignBox = dialog.findChild<QCheckBox*>("displayForeignBox");
-
-
- //
- // set up current settings
- //
- LoadMechanism::EMechanism mechanismID = getLoadMechanism();
- int index = 0;
-
- if (m_LoadMechanism.isDirectLoadingSupported()) {
- mechanismBox->addItem(QObject::tr("Mod Organizer"), LoadMechanism::LOAD_MODORGANIZER);
- if (mechanismID == LoadMechanism::LOAD_MODORGANIZER) {
- index = mechanismBox->count() - 1;
- }
- }
-
- if (m_LoadMechanism.isScriptExtenderSupported()) {
- mechanismBox->addItem(QObject::tr("Script Extender"), LoadMechanism::LOAD_SCRIPTEXTENDER);
- if (mechanismID == LoadMechanism::LOAD_SCRIPTEXTENDER) {
- index = mechanismBox->count() - 1;
- }
- }
-
- if (m_LoadMechanism.isProxyDLLSupported()) {
- mechanismBox->addItem(QObject::tr("Proxy DLL"), LoadMechanism::LOAD_PROXYDLL);
- if (mechanismID == LoadMechanism::LOAD_PROXYDLL) {
- index = mechanismBox->count() - 1;
- }
- }
-
- mechanismBox->setCurrentIndex(index);
-
- {
- addLanguages(languageBox);
- QString languageCode = language();
- int currentID = languageBox->findData(languageCode);
- // I made a mess. :( Most languages are stored with only the iso country code (2 characters like "de") but chinese
- // with the exact language variant (zh_TW) so I have to search for both variants
- if (currentID == -1) {
- currentID = languageBox->findData(languageCode.mid(0, 2));
- }
- if (currentID != -1) {
- languageBox->setCurrentIndex(currentID);
- }
- }
-
- {
- addStyles(styleBox);
- int currentID = styleBox->findData(m_Settings.value("Settings/style", "").toString());
- if (currentID != -1) {
- styleBox->setCurrentIndex(currentID);
- }
- }
-
- compactBox->setChecked(compactDownloads());
- showMetaBox->setChecked(metaDownloads());
-
- hideUncheckedBox->setChecked(hideUncheckedPlugins());
- displayForeignBox->setChecked(displayForeign());
- forceEnableBox->setChecked(forceEnableCoreFiles());
-
- appIDEdit->setText(getSteamAppID());
-
- if (automaticLoginEnabled()) {
- loginCheckBox->setChecked(true);
- usernameEdit->setText(m_Settings.value("Settings/nexus_username", "").toString());
- passwordEdit->setText(deObfuscate(m_Settings.value("Settings/nexus_password", "").toString()));
- }
-
- downloadDirEdit->setText(getDownloadDirectory());
- modDirEdit->setText(getModDirectory());
- cacheDirEdit->setText(getCacheDirectory());
- offlineBox->setChecked(offlineMode());
- proxyBox->setChecked(useProxy());
- nmmVersionEdit->setText(getNMMVersion());
- logLevelBox->setCurrentIndex(logLevel());
-
- // display plugin settings
- foreach (IPlugin *plugin, m_Plugins) {
- QListWidgetItem *listItem = new QListWidgetItem(plugin->name(), pluginsList);
- listItem->setData(Qt::UserRole, QVariant::fromValue((void*)plugin));
- listItem->setData(Qt::UserRole + 1, m_PluginSettings[plugin->name()]);
- pluginsList->addItem(listItem);
- }
-
- // display plugin blacklist
- foreach (const QString &pluginName, m_PluginBlacklist) {
- pluginBlacklistList->addItem(pluginName);
- }
-
- // display server preferences
- m_Settings.beginGroup("Servers");
- foreach (const QString &key, m_Settings.childKeys()) {
- QVariantMap val = m_Settings.value(key).toMap();
- QString type = val["premium"].toBool() ? "(premium)" : "(free)";
-
- QString descriptor = key + " " + type;
- if (val.contains("downloadSpeed") && val.contains("downloadCount") && (val["downloadCount"].toInt() > 0)) {
- int bps = static_cast<int>(val["downloadSpeed"].toDouble() / val["downloadCount"].toInt());
- descriptor += QString(" (%1 kbps)").arg(bps / 1024);
- }
-
- QListWidgetItem *newItem = new QListWidgetItemEx<int>(descriptor, Qt::UserRole + 1);
-
- newItem->setData(Qt::UserRole, key);
- newItem->setData(Qt::UserRole + 1, val["preferred"].toInt());
- if (val["preferred"].toInt() > 0) {
- preferredServersList->addItem(newItem);
- } else {
- knownServersList->addItem(newItem);
- }
- preferredServersList->sortItems(Qt::DescendingOrder);
- }
- m_Settings.endGroup();
-
- if (dialog.exec() == QDialog::Accepted) {
- //
- // transfer modified settings to configuration file
- //
-
- m_Settings.setValue("Settings/hide_unchecked_plugins", hideUncheckedBox->checkState() ? true : false);
- m_Settings.setValue("Settings/force_enable_core_files", forceEnableBox->checkState() ? true : false);
- m_Settings.setValue("Settings/compact_downloads", compactBox->isChecked());
- m_Settings.setValue("Settings/meta_downloads", showMetaBox->isChecked());
- m_Settings.setValue("Settings/load_mechanism", mechanismBox->itemData(mechanismBox->currentIndex()).toInt());
- if (QDir(downloadDirEdit->text()).exists()) {
- m_Settings.setValue("Settings/download_directory", QDir::toNativeSeparators(downloadDirEdit->text()));
- }
- if (!QDir(cacheDirEdit->text()).exists()) {
- QDir().mkpath(cacheDirEdit->text());
- }
- m_Settings.setValue("Settings/cache_directory", QDir::toNativeSeparators(cacheDirEdit->text()));
- if (QDir(modDirEdit->text()).exists()) {
- if ((QDir::fromNativeSeparators(modDirEdit->text()) != QDir::fromNativeSeparators(getModDirectory())) &&
- (QMessageBox::question(NULL, tr("Confirm"), tr("Changing the mod directory affects all your profiles! "
- "Mods not present (or named differently) in the new location will be disabled in all profiles. "
- "There is no way to undo this unless you backed up your profiles manually. Proceed?"),
- QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes)) {
- m_Settings.setValue("Settings/mod_directory", QDir::toNativeSeparators(modDirEdit->text()));
- }
- }
- QString oldLanguage = m_Settings.value("Settings/language", "en_US").toString();
- QString newLanguage = languageBox->itemData(languageBox->currentIndex()).toString();
- if (newLanguage != oldLanguage) {
- m_Settings.setValue("Settings/language", newLanguage);
- emit languageChanged(newLanguage);
- }
-
- QString oldStyle = m_Settings.value("Settings/style", "").toString();
- QString newStyle = styleBox->itemData(styleBox->currentIndex()).toString();
- if (oldStyle != newStyle) {
- m_Settings.setValue("Settings/style", newStyle);
- emit styleChanged(newStyle);
- }
-
- m_Settings.setValue("Settings/log_level", logLevelBox->currentIndex());
-
- if (appIDEdit->text() != ToQString(GameInfo::instance().getSteamAPPId())) {
- m_Settings.setValue("Settings/app_id", appIDEdit->text());
- } else {
- m_Settings.remove("Settings/app_id");
- }
- if (loginCheckBox->isChecked()) {
- m_Settings.setValue("Settings/nexus_login", true);
- m_Settings.setValue("Settings/nexus_username", usernameEdit->text());
- m_Settings.setValue("Settings/nexus_password", obfuscate(passwordEdit->text()));
- } else {
- m_Settings.setValue("Settings/nexus_login", false);
- m_Settings.remove("Settings/nexus_username");
- m_Settings.remove("Settings/nexus_password");
- }
- m_Settings.setValue("Settings/offline_mode", offlineBox->isChecked());
- m_Settings.setValue("Settings/use_proxy", proxyBox->isChecked());
- m_Settings.setValue("Settings/display_foreign", displayForeignBox->isChecked());
-
- m_Settings.setValue("Settings/nmm_version", nmmVersionEdit->text());
-
- // transfer plugin settings to in-memory structure
- for (int i = 0; i < pluginsList->count(); ++i) {
- QListWidgetItem *item = pluginsList->item(i);
- m_PluginSettings[item->text()] = item->data(Qt::UserRole + 1).toMap();
- }
- // store plugin settings on disc
- for (auto iterPlugins = m_PluginSettings.begin(); iterPlugins != m_PluginSettings.end(); ++iterPlugins) {
- for (auto iterSettings = iterPlugins->begin(); iterSettings != iterPlugins->end(); ++iterSettings) {
- m_Settings.setValue("Plugins/" + iterPlugins.key() + "/" + iterSettings.key(), iterSettings.value());
- }
- }
-
- // store plugin blacklist
- m_PluginBlacklist.clear();
- foreach (QListWidgetItem *item, pluginBlacklistList->findItems("*", Qt::MatchWildcard)) {
- m_PluginBlacklist.insert(item->text());
- }
- writePluginBlacklist();
-
- // store server preference
- m_Settings.beginGroup("Servers");
- for (int i = 0; i < knownServersList->count(); ++i) {
- QString key = knownServersList->item(i)->data(Qt::UserRole).toString();
- QVariantMap val = m_Settings.value(key).toMap();
- val["preferred"] = 0;
- m_Settings.setValue(key, val);
- }
- int count = preferredServersList->count();
- for (int i = 0; i < count; ++i) {
- QString key = preferredServersList->item(i)->data(Qt::UserRole).toString();
- QVariantMap val = m_Settings.value(key).toMap();
- val["preferred"] = count - i;
- m_Settings.setValue(key, val);
- }
- m_Settings.endGroup();
- }
-}
+/* +Copyright (C) 2012 Sebastian Herbord. All rights reserved. + +This file is part of Mod Organizer. + +Mod Organizer is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +Mod Organizer is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>. +*/ + +#include "settings.h" + +#include "settingsdialog.h" +#include "utility.h" +#include "helper.h" +#include <gameinfo.h> +#include <appconfig.h> +#include <utility.h> +#include <json.h> + +#include <QCheckBox> +#include <QLineEdit> +#include <QDirIterator> +#include <QRegExp> +#include <QCoreApplication> +#include <QMessageBox> +#include <QDesktopServices> + + +using namespace MOBase; +using namespace MOShared; + + +template <typename T> +class QListWidgetItemEx : public QListWidgetItem { +public: + QListWidgetItemEx(const QString &text, int sortRole = Qt::DisplayRole, QListWidget *parent = 0, int type = Type) + : QListWidgetItem(text, parent, type), m_SortRole(sortRole) {} + + virtual bool operator< ( const QListWidgetItem & other ) const { + return this->data(m_SortRole).value<T>() < other.data(m_SortRole).value<T>(); + } +private: + int m_SortRole; +}; + + +static const unsigned char Key2[20] = { 0x99, 0xb8, 0x76, 0x42, 0x3e, 0xc1, 0x60, 0xa4, 0x5b, 0x01, + 0xdb, 0xf8, 0x43, 0x3a, 0xb7, 0xb6, 0x98, 0xd4, 0x7d, 0xa2 }; + +Settings *Settings::s_Instance = NULL; + + +Settings::Settings() + : m_Settings(ToQString(GameInfo::instance().getIniFilename()), QSettings::IniFormat) +{ + if (s_Instance != NULL) { + throw std::runtime_error("second instance of \"Settings\" created"); + } else { + s_Instance = this; + } +} + + +Settings::~Settings() +{ + s_Instance = NULL; +} + + +Settings &Settings::instance() +{ + if (s_Instance == NULL) { + throw std::runtime_error("no instance of \"Settings\""); + } + return *s_Instance; +} + +void Settings::clearPlugins() +{ + m_Plugins.clear(); + m_PluginSettings.clear(); + + m_PluginBlacklist.clear(); + int count = m_Settings.beginReadArray("pluginBlacklist"); + for (int i = 0; i < count; ++i) { + m_Settings.setArrayIndex(i); + m_PluginBlacklist.insert(m_Settings.value("name").toString()); + } + m_Settings.endArray(); +} + +bool Settings::pluginBlacklisted(const QString &fileName) const +{ + return m_PluginBlacklist.contains(fileName); +} + +void Settings::registerAsNXMHandler(bool force) +{ + std::wstring nxmPath = ToWString(QCoreApplication::applicationDirPath() + "/nxmhandler.exe"); + std::wstring executable = ToWString(QCoreApplication::applicationFilePath()); + std::wstring mode = force ? L"forcereg" : L"reg"; + std::wstring parameters = mode + L" " + GameInfo::instance().getGameShortName() + L" \"" + executable + L"\""; + HINSTANCE res = ::ShellExecuteW(NULL, L"open", nxmPath.c_str(), parameters.c_str(), NULL, SW_SHOWNORMAL); + if ((int)res <= 32) { + QMessageBox::critical(NULL, tr("Failed"), + tr("Sorry, failed to start the helper application")); + } +} + +void Settings::registerPlugin(IPlugin *plugin) +{ + m_Plugins.push_back(plugin); + m_PluginSettings.insert(plugin->name(), QMap<QString, QVariant>()); + m_PluginDescriptions.insert(plugin->name(), QMap<QString, QVariant>()); + foreach (const PluginSetting &setting, plugin->settings()) { + QVariant temp = m_Settings.value("Plugins/" + plugin->name() + "/" + setting.key, setting.defaultValue); + if (!temp.convert(setting.defaultValue.type())) { + qWarning("failed to interpret \"%s\" as correct type for \"%s\" in plugin \"%s\", using default", + qPrintable(temp.toString()), qPrintable(setting.key), qPrintable(plugin->name())); + temp = setting.defaultValue; + } + m_PluginSettings[plugin->name()][setting.key] = temp; + m_PluginDescriptions[plugin->name()][setting.key] = QString("%1 (default: %2)").arg(setting.description).arg(setting.defaultValue.toString()); + } +} + + +QString Settings::obfuscate(const QString &password) const +{ + QByteArray temp = password.toUtf8(); + + QByteArray buffer; + for (int i = 0; i < temp.length(); ++i) { + buffer.append(temp.at(i) ^ Key2[i % 20]); + } + return buffer.toBase64(); +} + + +QString Settings::deObfuscate(const QString &password) const +{ + QByteArray temp(QByteArray::fromBase64(password.toUtf8())); + + QByteArray buffer; + for (int i = 0; i < temp.length(); ++i) { + buffer.append(temp.at(i) ^ Key2[i % 20]); + } + return QString::fromUtf8(buffer.constData()); +} + + +bool Settings::hideUncheckedPlugins() const +{ + return m_Settings.value("Settings/hide_unchecked_plugins", false).toBool(); +} + +bool Settings::forceEnableCoreFiles() const +{ + return m_Settings.value("Settings/force_enable_core_files", true).toBool(); +} + +bool Settings::automaticLoginEnabled() const +{ + return m_Settings.value("Settings/nexus_login", false).toBool(); +} + +QString Settings::getSteamAppID() const +{ + return m_Settings.value("Settings/app_id", ToQString(GameInfo::instance().getSteamAPPId(m_Settings.value("game_edition", 0).toInt()))).toString(); +} + +QString Settings::getDownloadDirectory() const +{ + return QDir::toNativeSeparators(m_Settings.value("Settings/download_directory", ToQString(GameInfo::instance().getDownloadDir())).toString()); +} + + +void Settings::setDownloadSpeed(const QString &serverName, int bytesPerSecond) +{ + m_Settings.beginGroup("Servers"); + + foreach (const QString &serverKey, m_Settings.childKeys()) { + QVariantMap data = m_Settings.value(serverKey).toMap(); + if (serverKey == serverName) { + data["downloadCount"] = data["downloadCount"].toInt() + 1; + data["downloadSpeed"] = data["downloadSpeed"].toDouble() + static_cast<double>(bytesPerSecond); + m_Settings.setValue(serverKey, data); + } + } + + m_Settings.endGroup(); + m_Settings.sync(); +} + +std::map<QString, int> Settings::getPreferredServers() +{ + std::map<QString, int> result; + m_Settings.beginGroup("Servers"); + + foreach (const QString &serverKey, m_Settings.childKeys()) { + QVariantMap data = m_Settings.value(serverKey).toMap(); + int preference = data["preferred"].toInt(); + if (preference > 0) { + result[serverKey] = preference; + } + } + m_Settings.endGroup(); + + return result; +} + +QString Settings::getCacheDirectory() const +{ + return QDir::toNativeSeparators(m_Settings.value("Settings/cache_directory", ToQString(GameInfo::instance().getCacheDir())).toString()); +} + +QString Settings::getModDirectory() const +{ + return QDir::toNativeSeparators(m_Settings.value("Settings/mod_directory", ToQString(GameInfo::instance().getModsDir())).toString()); +} + +QString Settings::getNMMVersion() const +{ + static const QString MIN_NMM_VERSION = "0.47.0"; + QString result = m_Settings.value("Settings/nmm_version", MIN_NMM_VERSION).toString(); + if (VersionInfo(result) < VersionInfo(MIN_NMM_VERSION)) { + result = MIN_NMM_VERSION; + } + return result; +} + +bool Settings::getNexusLogin(QString &username, QString &password) const +{ + if (m_Settings.value("Settings/nexus_login", false).toBool()) { + username = m_Settings.value("Settings/nexus_username", "").toString(); + password = deObfuscate(m_Settings.value("Settings/nexus_password", "").toString()); + return true; + } else { + return false; + } +} + +bool Settings::compactDownloads() const +{ + return m_Settings.value("Settings/compact_downloads", false).toBool(); +} + +bool Settings::metaDownloads() const +{ + return m_Settings.value("Settings/meta_downloads", false).toBool(); +} + +bool Settings::offlineMode() const +{ + return m_Settings.value("Settings/offline_mode", false).toBool(); +} + +int Settings::logLevel() const +{ + return m_Settings.value("Settings/log_level", 0).toInt(); +} + + +void Settings::setNexusLogin(QString username, QString password) +{ + m_Settings.setValue("Settings/nexus_login", true); + m_Settings.setValue("Settings/nexus_username", username); + m_Settings.setValue("Settings/nexus_password", obfuscate(password)); +} + + +LoadMechanism::EMechanism Settings::getLoadMechanism() const +{ + switch (m_Settings.value("Settings/load_mechanism").toInt()) { + case LoadMechanism::LOAD_MODORGANIZER: return LoadMechanism::LOAD_MODORGANIZER; + case LoadMechanism::LOAD_SCRIPTEXTENDER: return LoadMechanism::LOAD_SCRIPTEXTENDER; + case LoadMechanism::LOAD_PROXYDLL: return LoadMechanism::LOAD_PROXYDLL; + } + throw std::runtime_error("invalid load mechanism"); +} + + +void Settings::setupLoadMechanism() +{ + m_LoadMechanism.activate(getLoadMechanism()); +} + + +bool Settings::useProxy() +{ + return m_Settings.value("Settings/use_proxy", false).toBool(); +} + +bool Settings::displayForeign() +{ + return m_Settings.value("Settings/display_foreign", true).toBool(); +} + +void Settings::setMotDHash(uint hash) +{ + m_Settings.setValue("motd_hash", hash); +} + +uint Settings::getMotDHash() const +{ + return m_Settings.value("motd_hash", 0).toUInt(); +} + +QVariant Settings::pluginSetting(const QString &pluginName, const QString &key) const +{ + auto iterPlugin = m_PluginSettings.find(pluginName); + if (iterPlugin == m_PluginSettings.end()) { + return QVariant(); + } + auto iterSetting = iterPlugin->find(key); + if (iterSetting == iterPlugin->end()) { + return QVariant(); + } + + return *iterSetting; +} + +void Settings::setPluginSetting(const QString &pluginName, const QString &key, const QVariant &value) +{ + auto iterPlugin = m_PluginSettings.find(pluginName); + if (iterPlugin == m_PluginSettings.end()) { + throw MyException(tr("attempt to store setting for unknown plugin \"%1\"").arg(pluginName)); + } + + // store the new setting both in memory and in the ini + m_PluginSettings[pluginName][key] = value; + m_Settings.setValue("Plugins/" + pluginName + "/" + key, value); +} + +QVariant Settings::pluginPersistent(const QString &pluginName, const QString &key, const QVariant &def) const +{ + if (!m_PluginSettings.contains(pluginName)) { + return def; + } + return m_Settings.value("PluginPersistance/" + pluginName + "/" + key, def); +} + +void Settings::setPluginPersistent(const QString &pluginName, const QString &key, const QVariant &value, bool sync) +{ + if (!m_PluginSettings.contains(pluginName)) { + throw MyException(tr("attempt to store setting for unknown plugin \"%1\"").arg(pluginName)); + } + m_Settings.setValue("PluginPersistance/" + pluginName + "/" + key, value); + if (sync) { + m_Settings.sync(); + } +} + +QString Settings::language() +{ + QString result = m_Settings.value("Settings/language", "").toString(); + if (result.isEmpty()) { + QStringList languagePreferences = QLocale::system().uiLanguages(); + if (languagePreferences.length() > 0) { + // the users most favoritest language + result = languagePreferences.at(0); + } else { + // fallback system locale + result = QLocale::system().name(); + } + } + return result; +} + +void Settings::updateServers(const QList<ServerInfo> &servers) +{ + m_Settings.beginGroup("Servers"); + QStringList oldServerKeys = m_Settings.childKeys(); + + foreach (const ServerInfo &server, servers) { + if (!oldServerKeys.contains(server.name)) { + // not yet known server + QVariantMap newVal; + newVal["premium"] = server.premium; + newVal["preferred"] = server.preferred ? 1 : 0; + newVal["lastSeen"] = server.lastSeen; + newVal["downloadCount"] = 0; + newVal["downloadSpeed"] = 0.0; + + m_Settings.setValue(server.name, newVal); + } else { + QVariantMap data = m_Settings.value(server.name).toMap(); + data["lastSeen"] = server.lastSeen; + data["premium"] = server.premium; + + m_Settings.setValue(server.name, data); + } + } + + m_Settings.endGroup(); + m_Settings.sync(); +} + +void Settings::addBlacklistPlugin(const QString &fileName) +{ + m_PluginBlacklist.insert(fileName); + writePluginBlacklist(); +} + +void Settings::writePluginBlacklist() +{ + m_Settings.beginWriteArray("pluginBlacklist"); + int idx = 0; + foreach (const QString &plugin, m_PluginBlacklist) { + m_Settings.setArrayIndex(idx++); + m_Settings.setValue("name", plugin); + } + + m_Settings.endArray(); +} + +void Settings::addLanguages(QComboBox *languageBox) +{ + languageBox->addItem("English", "en_US"); + + QDirIterator langIter(QCoreApplication::applicationDirPath() + "/translations", QDir::Files); + QString pattern = ToQString(AppConfig::translationPrefix()) + "_([a-z]{2,3}(_[A-Z]{2,2})?).qm"; + QRegExp exp(pattern); + while (langIter.hasNext()) { + langIter.next(); + QString file = langIter.fileName(); + if (exp.exactMatch(file)) { + QString languageCode = exp.cap(1); + QLocale locale(languageCode); + QString languageString = QLocale::languageToString(locale.language()); + if (locale.language() == QLocale::Chinese) { + if (languageCode == "zh_TW") { + languageString = "Chinese (traditional)"; + } else { + languageString = "Chinese (simplified)"; + } + } + languageBox->addItem(QString("%1").arg(languageString), exp.cap(1)); + } + } +} + +void Settings::addStyles(QComboBox *styleBox) +{ + styleBox->addItem("None", ""); +#if QT_VERSION >= QT_VERSION_CHECK(5,0,0) + styleBox->addItem("Fusion", "Fusion"); +#else + styleBox->addItem("Plastique", "Plastique"); + styleBox->addItem("Cleanlooks", "Cleanlooks"); +#endif + + QDirIterator langIter(QCoreApplication::applicationDirPath() + "/" + ToQString(AppConfig::stylesheetsPath()), QStringList("*.qss"), QDir::Files); + while (langIter.hasNext()) { + langIter.next(); + QString style = langIter.fileName(); + styleBox->addItem(style, style); + } +} + +void Settings::resetDialogs() +{ + m_Settings.beginGroup("DialogChoices"); + QStringList keys = m_Settings.childKeys(); + foreach (QString key, keys) { + m_Settings.remove(key); + } + + m_Settings.endGroup(); +} + + +void Settings::query(QWidget *parent) +{ + SettingsDialog dialog(parent); + + connect(&dialog, SIGNAL(resetDialogs()), this, SLOT(resetDialogs())); + + // General Page + QComboBox *languageBox = dialog.findChild<QComboBox*>("languageBox"); + QComboBox *styleBox = dialog.findChild<QComboBox*>("styleBox"); + QComboBox *logLevelBox = dialog.findChild<QComboBox*>("logLevelBox"); + QCheckBox *compactBox = dialog.findChild<QCheckBox*>("compactBox"); + QCheckBox *showMetaBox = dialog.findChild<QCheckBox*>("showMetaBox"); + + QLineEdit *downloadDirEdit = dialog.findChild<QLineEdit*>("downloadDirEdit"); + QLineEdit *modDirEdit = dialog.findChild<QLineEdit*>("modDirEdit"); + QLineEdit *cacheDirEdit = dialog.findChild<QLineEdit*>("cacheDirEdit"); + + // nexus page + QCheckBox *loginCheckBox = dialog.findChild<QCheckBox*>("loginCheckBox"); + QLineEdit *usernameEdit = dialog.findChild<QLineEdit*>("usernameEdit"); + QLineEdit *passwordEdit = dialog.findChild<QLineEdit*>("passwordEdit"); + QCheckBox *offlineBox = dialog.findChild<QCheckBox*>("offlineBox"); + QCheckBox *proxyBox = dialog.findChild<QCheckBox*>("proxyBox"); + + QListWidget *knownServersList = dialog.findChild<QListWidget*>("knownServersList"); + QListWidget *preferredServersList = dialog.findChild<QListWidget*>("preferredServersList"); + + // plugis page + QListWidget *pluginsList = dialog.findChild<QListWidget*>("pluginsList"); + QListWidget *pluginBlacklistList = dialog.findChild<QListWidget*>("pluginBlacklist"); + + // workarounds page + QCheckBox *forceEnableBox = dialog.findChild<QCheckBox*>("forceEnableBox"); + QComboBox *mechanismBox = dialog.findChild<QComboBox*>("mechanismBox"); + QLineEdit *appIDEdit = dialog.findChild<QLineEdit*>("appIDEdit"); + QLineEdit *nmmVersionEdit = dialog.findChild<QLineEdit*>("nmmVersionEdit"); + QCheckBox *hideUncheckedBox = dialog.findChild<QCheckBox*>("hideUncheckedBox"); + QCheckBox *displayForeignBox = dialog.findChild<QCheckBox*>("displayForeignBox"); + + + // + // set up current settings + // + LoadMechanism::EMechanism mechanismID = getLoadMechanism(); + int index = 0; + + if (m_LoadMechanism.isDirectLoadingSupported()) { + mechanismBox->addItem(QObject::tr("Mod Organizer"), LoadMechanism::LOAD_MODORGANIZER); + if (mechanismID == LoadMechanism::LOAD_MODORGANIZER) { + index = mechanismBox->count() - 1; + } + } + + if (m_LoadMechanism.isScriptExtenderSupported()) { + mechanismBox->addItem(QObject::tr("Script Extender"), LoadMechanism::LOAD_SCRIPTEXTENDER); + if (mechanismID == LoadMechanism::LOAD_SCRIPTEXTENDER) { + index = mechanismBox->count() - 1; + } + } + + if (m_LoadMechanism.isProxyDLLSupported()) { + mechanismBox->addItem(QObject::tr("Proxy DLL"), LoadMechanism::LOAD_PROXYDLL); + if (mechanismID == LoadMechanism::LOAD_PROXYDLL) { + index = mechanismBox->count() - 1; + } + } + + mechanismBox->setCurrentIndex(index); + + { + addLanguages(languageBox); + QString languageCode = language(); + int currentID = languageBox->findData(languageCode); + // I made a mess. :( Most languages are stored with only the iso country code (2 characters like "de") but chinese + // with the exact language variant (zh_TW) so I have to search for both variants + if (currentID == -1) { + currentID = languageBox->findData(languageCode.mid(0, 2)); + } + if (currentID != -1) { + languageBox->setCurrentIndex(currentID); + } + } + + { + addStyles(styleBox); + int currentID = styleBox->findData(m_Settings.value("Settings/style", "").toString()); + if (currentID != -1) { + styleBox->setCurrentIndex(currentID); + } + } + + compactBox->setChecked(compactDownloads()); + showMetaBox->setChecked(metaDownloads()); + + hideUncheckedBox->setChecked(hideUncheckedPlugins()); + displayForeignBox->setChecked(displayForeign()); + forceEnableBox->setChecked(forceEnableCoreFiles()); + + appIDEdit->setText(getSteamAppID()); + + if (automaticLoginEnabled()) { + loginCheckBox->setChecked(true); + usernameEdit->setText(m_Settings.value("Settings/nexus_username", "").toString()); + passwordEdit->setText(deObfuscate(m_Settings.value("Settings/nexus_password", "").toString())); + } + + downloadDirEdit->setText(getDownloadDirectory()); + modDirEdit->setText(getModDirectory()); + cacheDirEdit->setText(getCacheDirectory()); + offlineBox->setChecked(offlineMode()); + proxyBox->setChecked(useProxy()); + nmmVersionEdit->setText(getNMMVersion()); + logLevelBox->setCurrentIndex(logLevel()); + + // display plugin settings + foreach (IPlugin *plugin, m_Plugins) { + QListWidgetItem *listItem = new QListWidgetItem(plugin->name(), pluginsList); + listItem->setData(Qt::UserRole, QVariant::fromValue((void*)plugin)); + listItem->setData(Qt::UserRole + 1, m_PluginSettings[plugin->name()]); + listItem->setData(Qt::UserRole + 2, m_PluginDescriptions[plugin->name()]); + pluginsList->addItem(listItem); + } + + // display plugin blacklist + foreach (const QString &pluginName, m_PluginBlacklist) { + pluginBlacklistList->addItem(pluginName); + } + + // display server preferences + m_Settings.beginGroup("Servers"); + foreach (const QString &key, m_Settings.childKeys()) { + QVariantMap val = m_Settings.value(key).toMap(); + QString type = val["premium"].toBool() ? "(premium)" : "(free)"; + + QString descriptor = key + " " + type; + if (val.contains("downloadSpeed") && val.contains("downloadCount") && (val["downloadCount"].toInt() > 0)) { + int bps = static_cast<int>(val["downloadSpeed"].toDouble() / val["downloadCount"].toInt()); + descriptor += QString(" (%1 kbps)").arg(bps / 1024); + } + + QListWidgetItem *newItem = new QListWidgetItemEx<int>(descriptor, Qt::UserRole + 1); + + newItem->setData(Qt::UserRole, key); + newItem->setData(Qt::UserRole + 1, val["preferred"].toInt()); + if (val["preferred"].toInt() > 0) { + preferredServersList->addItem(newItem); + } else { + knownServersList->addItem(newItem); + } + preferredServersList->sortItems(Qt::DescendingOrder); + } + m_Settings.endGroup(); + + if (dialog.exec() == QDialog::Accepted) { + // + // transfer modified settings to configuration file + // + + m_Settings.setValue("Settings/hide_unchecked_plugins", hideUncheckedBox->checkState() ? true : false); + m_Settings.setValue("Settings/force_enable_core_files", forceEnableBox->checkState() ? true : false); + m_Settings.setValue("Settings/compact_downloads", compactBox->isChecked()); + m_Settings.setValue("Settings/meta_downloads", showMetaBox->isChecked()); + m_Settings.setValue("Settings/load_mechanism", mechanismBox->itemData(mechanismBox->currentIndex()).toInt()); + if (QDir(downloadDirEdit->text()).exists()) { + m_Settings.setValue("Settings/download_directory", QDir::toNativeSeparators(downloadDirEdit->text())); + } + if (!QDir(cacheDirEdit->text()).exists()) { + QDir().mkpath(cacheDirEdit->text()); + } + m_Settings.setValue("Settings/cache_directory", QDir::toNativeSeparators(cacheDirEdit->text())); + if (QDir(modDirEdit->text()).exists()) { + if ((QDir::fromNativeSeparators(modDirEdit->text()) != QDir::fromNativeSeparators(getModDirectory())) && + (QMessageBox::question(NULL, tr("Confirm"), tr("Changing the mod directory affects all your profiles! " + "Mods not present (or named differently) in the new location will be disabled in all profiles. " + "There is no way to undo this unless you backed up your profiles manually. Proceed?"), + QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes)) { + m_Settings.setValue("Settings/mod_directory", QDir::toNativeSeparators(modDirEdit->text())); + } + } + QString oldLanguage = m_Settings.value("Settings/language", "en_US").toString(); + QString newLanguage = languageBox->itemData(languageBox->currentIndex()).toString(); + if (newLanguage != oldLanguage) { + m_Settings.setValue("Settings/language", newLanguage); + emit languageChanged(newLanguage); + } + + QString oldStyle = m_Settings.value("Settings/style", "").toString(); + QString newStyle = styleBox->itemData(styleBox->currentIndex()).toString(); + if (oldStyle != newStyle) { + m_Settings.setValue("Settings/style", newStyle); + emit styleChanged(newStyle); + } + + m_Settings.setValue("Settings/log_level", logLevelBox->currentIndex()); + + if (appIDEdit->text() != ToQString(GameInfo::instance().getSteamAPPId())) { + m_Settings.setValue("Settings/app_id", appIDEdit->text()); + } else { + m_Settings.remove("Settings/app_id"); + } + if (loginCheckBox->isChecked()) { + m_Settings.setValue("Settings/nexus_login", true); + m_Settings.setValue("Settings/nexus_username", usernameEdit->text()); + m_Settings.setValue("Settings/nexus_password", obfuscate(passwordEdit->text())); + } else { + m_Settings.setValue("Settings/nexus_login", false); + m_Settings.remove("Settings/nexus_username"); + m_Settings.remove("Settings/nexus_password"); + } + m_Settings.setValue("Settings/offline_mode", offlineBox->isChecked()); + m_Settings.setValue("Settings/use_proxy", proxyBox->isChecked()); + m_Settings.setValue("Settings/display_foreign", displayForeignBox->isChecked()); + + m_Settings.setValue("Settings/nmm_version", nmmVersionEdit->text()); + + // transfer plugin settings to in-memory structure + for (int i = 0; i < pluginsList->count(); ++i) { + QListWidgetItem *item = pluginsList->item(i); + m_PluginSettings[item->text()] = item->data(Qt::UserRole + 1).toMap(); + } + // store plugin settings on disc + for (auto iterPlugins = m_PluginSettings.begin(); iterPlugins != m_PluginSettings.end(); ++iterPlugins) { + for (auto iterSettings = iterPlugins->begin(); iterSettings != iterPlugins->end(); ++iterSettings) { + m_Settings.setValue("Plugins/" + iterPlugins.key() + "/" + iterSettings.key(), iterSettings.value()); + } + } + + // store plugin blacklist + m_PluginBlacklist.clear(); + foreach (QListWidgetItem *item, pluginBlacklistList->findItems("*", Qt::MatchWildcard)) { + m_PluginBlacklist.insert(item->text()); + } + writePluginBlacklist(); + + // store server preference + m_Settings.beginGroup("Servers"); + for (int i = 0; i < knownServersList->count(); ++i) { + QString key = knownServersList->item(i)->data(Qt::UserRole).toString(); + QVariantMap val = m_Settings.value(key).toMap(); + val["preferred"] = 0; + m_Settings.setValue(key, val); + } + int count = preferredServersList->count(); + for (int i = 0; i < count; ++i) { + QString key = preferredServersList->item(i)->data(Qt::UserRole).toString(); + QVariantMap val = m_Settings.value(key).toMap(); + val["preferred"] = count - i; + m_Settings.setValue(key, val); + } + m_Settings.endGroup(); + } +} diff --git a/src/settings.h b/src/settings.h index 40fd2c5a..5d398f49 100644 --- a/src/settings.h +++ b/src/settings.h @@ -1,310 +1,311 @@ -/*
-Copyright (C) 2012 Sebastian Herbord. All rights reserved.
-
-This file is part of Mod Organizer.
-
-Mod Organizer is free software: you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation, either version 3 of the License, or
-(at your option) any later version.
-
-Mod Organizer is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#ifndef WORKAROUNDS_H
-#define WORKAROUNDS_H
-
-#include "loadmechanism.h"
-#include "serverinfo.h"
-#include <iplugin.h>
-
-#include <QSettings>
-#include <QListWidget>
-#include <QComboBox>
-
-
-/**
- * manages the settings for Mod Organizer. The settings are not cached
- * inside the class but read/written directly from/to disc
- **/
-class Settings : public QObject
-{
-
- Q_OBJECT
-
-public:
-
- /**
- * @brief constructor
- **/
- Settings();
-
- virtual ~Settings();
-
- static Settings &instance();
-
- /**
- * unregister all plugins from settings
- */
- void clearPlugins();
-
- /**
- * @brief register plugin to be configurable
- * @param plugin the plugin to register
- * @return true if the plugin may be registered, false if it is blacklisted
- */
- void registerPlugin(MOBase::IPlugin *plugin);
-
- /**
- * displays a SettingsDialog that allows the user to change settings. If the
- * user accepts the changes, the settings are immediately written
- **/
- void query(QWidget *parent);
-
- /**
- * set up the settings for the specified plugins
- **/
- void addPluginSettings(const std::vector<MOBase::IPlugin*> &plugins);
-
- /**
- * @return true if the user wants unchecked plugins (esp, esm) should be hidden from
- * the virtual dat adirectory
- **/
- bool hideUncheckedPlugins() const;
-
- /**
- * @return true if files of the core game are forced-enabled so the user can't accidentally disable them
- */
- bool forceEnableCoreFiles() const;
-
- /**
- * @brief register download speed
- * @param url complete download url
- * @param bytesPerSecond download size in bytes per second
- */
- void setDownloadSpeed(const QString &serverName, int bytesPerSecond);
-
- /**
- * the steam appid is assigned by the steam platform to each product sold there.
- * The appid may differ between different versions of a game so it may be impossible
- * for Mod Organizer to automatically recognize it, though usually it does
- * @return the steam appid for the game
- **/
- QString getSteamAppID() const;
-
- /**
- * retrieve the directory where downloads are stored (with native separators)
- **/
- QString getDownloadDirectory() const;
-
- /**
- * retrieve a sorted list of preferred servers
- */
- std::map<QString, int> getPreferredServers();
-
- /**
- * retrieve the directory where mods are stored (with native separators)
- **/
- QString getModDirectory() const;
-
- /**
- * returns the version of nmm to impersonate when connecting to nexus
- **/
- QString getNMMVersion() const;
-
- /**
- * retrieve the directory where the web cache is stored (with native separators)
- **/
- QString getCacheDirectory() const;
-
- /**
- * @return true if the user has set up automatic login to nexus
- **/
- bool automaticLoginEnabled() const;
-
- /**
- * @brief retrieve the login information for nexus
- *
- * @param username (out) receives the user name for nexus
- * @param password (out) received the password for nexus
- * @return true if automatic login is active, false otherwise
- **/
- bool getNexusLogin(QString &username, QString &password) const;
-
- /**
- * @return true if the user disabled internet features
- */
- bool offlineMode() const;
-
- /**
- * @return true if the user chose compact downloads
- */
- bool compactDownloads() const;
-
- /**
- * @return true if the user chose meta downloads
- */
- bool metaDownloads() const;
-
- /**
- * @return the configured log level
- */
- int logLevel() const;
-
- /**
- * @brief set the nexus login information
- *
- * @param username username
- * @param password password
- */
- void setNexusLogin(QString username, QString password);
-
- /**
- * @return the load mechanism to be used
- **/
- LoadMechanism::EMechanism getLoadMechanism() const;
-
- /**
- * @brief activate the load mechanism selected by the user
- **/
- void setupLoadMechanism();
-
- /**
- * @return true if the user configured the use of a network proxy
- */
- bool useProxy();
-
- /**
- * @return true if the user wants to see non-official plugins installed outside MO in his mod list
- */
- bool displayForeign();
-
- /**
- * @brief sets the new motd hash
- **/
- void setMotDHash(uint hash);
-
- /**
- * @return hash of the last displayed message of the day
- **/
- uint getMotDHash() const;
-
- /**
- * @brief allows direct access to the wrapped QSettings object
- * @return the wrapped QSettings object
- */
- QSettings &directInterface() { return m_Settings; }
-
- /**
- * @brief retrieve a setting for one of the installed plugins
- * @param pluginName name of the plugin
- * @param key name of the setting to retrieve
- * @return the requested value as a QVariant
- * @note an invalid QVariant is returned if the the plugin/setting is not declared
- */
- QVariant pluginSetting(const QString &pluginName, const QString &key) const;
-
- /**
- * @brief set a setting for one of the installed mods
- * @param pluginName name of the plugin
- * @param key name of the setting to change
- * @param value the new value to set
- * @throw an exception is thrown if pluginName is invalid
- */
- void setPluginSetting(const QString &pluginName, const QString &key, const QVariant &value);
-
- /**
- * @brief retrieve a persistent value for a plugin
- * @param pluginName name of the plugin to store data for
- * @param key id of the value to retrieve
- * @param def default value to return if the value is not set
- * @return the requested value
- */
- QVariant pluginPersistent(const QString &pluginName, const QString &key, const QVariant &def) const;
-
- /**
- * @brief set a persistent value for a plugin
- * @param pluginName name of the plugin to store data for
- * @param key id of the value to retrieve
- * @param value value to set
- * @throw an exception is thrown if pluginName is invalid
- */
- void setPluginPersistent(const QString &pluginName, const QString &key, const QVariant &value, bool sync);
-
- /**
- * @return short code of the configured language (corresponding to the translation files)
- */
- QString language();
-
- /**
- * @brief updates the list of known servers
- * @param list of servers from a recent query
- */
- void updateServers(const QList<ServerInfo> &servers);
-
- /**
- * @brief add a plugin that is to be blacklisted
- * @param fileName name of the plugin to blacklist
- */
- void addBlacklistPlugin(const QString &fileName);
-
- /**
- * @brief test if a plugin is blacklisted and shouldn't be loaded
- * @param fileName name of the plugin
- * @return true if the file is blacklisted
- */
- bool pluginBlacklisted(const QString &fileName) const;
-
- /**
- * @return all loaded MO plugins
- */
- std::vector<MOBase::IPlugin*> plugins() const { return m_Plugins; }
-
- /**
- * @brief register MO as the handler for nxm links
- * @param force set to true to enforce the registration dialog to show up,
- * even if the user said earlier not to
- */
- void registerAsNXMHandler(bool force);
-private:
-
- QString obfuscate(const QString &password) const;
- QString deObfuscate(const QString &password) const;
-
- void addLanguages(QComboBox *languageBox);
- void addStyles(QComboBox *styleBox);
- void readPluginBlacklist();
- void writePluginBlacklist();
-
-private slots:
-
- void resetDialogs();
-
-signals:
-
- void languageChanged(const QString &newLanguage);
- void styleChanged(const QString &newStyle);
-
-private:
-
- static Settings *s_Instance;
-
- QSettings m_Settings;
-
- LoadMechanism m_LoadMechanism;
-
- std::vector<MOBase::IPlugin*> m_Plugins;
-
- QMap<QString, QMap<QString, QVariant> > m_PluginSettings;
-
- QSet<QString> m_PluginBlacklist;
-
-};
-
-#endif // WORKAROUNDS_H
+/* +Copyright (C) 2012 Sebastian Herbord. All rights reserved. + +This file is part of Mod Organizer. + +Mod Organizer is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +Mod Organizer is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>. +*/ + +#ifndef WORKAROUNDS_H +#define WORKAROUNDS_H + +#include "loadmechanism.h" +#include "serverinfo.h" +#include <iplugin.h> + +#include <QSettings> +#include <QListWidget> +#include <QComboBox> + + +/** + * manages the settings for Mod Organizer. The settings are not cached + * inside the class but read/written directly from/to disc + **/ +class Settings : public QObject +{ + + Q_OBJECT + +public: + + /** + * @brief constructor + **/ + Settings(); + + virtual ~Settings(); + + static Settings &instance(); + + /** + * unregister all plugins from settings + */ + void clearPlugins(); + + /** + * @brief register plugin to be configurable + * @param plugin the plugin to register + * @return true if the plugin may be registered, false if it is blacklisted + */ + void registerPlugin(MOBase::IPlugin *plugin); + + /** + * displays a SettingsDialog that allows the user to change settings. If the + * user accepts the changes, the settings are immediately written + **/ + void query(QWidget *parent); + + /** + * set up the settings for the specified plugins + **/ + void addPluginSettings(const std::vector<MOBase::IPlugin*> &plugins); + + /** + * @return true if the user wants unchecked plugins (esp, esm) should be hidden from + * the virtual dat adirectory + **/ + bool hideUncheckedPlugins() const; + + /** + * @return true if files of the core game are forced-enabled so the user can't accidentally disable them + */ + bool forceEnableCoreFiles() const; + + /** + * @brief register download speed + * @param url complete download url + * @param bytesPerSecond download size in bytes per second + */ + void setDownloadSpeed(const QString &serverName, int bytesPerSecond); + + /** + * the steam appid is assigned by the steam platform to each product sold there. + * The appid may differ between different versions of a game so it may be impossible + * for Mod Organizer to automatically recognize it, though usually it does + * @return the steam appid for the game + **/ + QString getSteamAppID() const; + + /** + * retrieve the directory where downloads are stored (with native separators) + **/ + QString getDownloadDirectory() const; + + /** + * retrieve a sorted list of preferred servers + */ + std::map<QString, int> getPreferredServers(); + + /** + * retrieve the directory where mods are stored (with native separators) + **/ + QString getModDirectory() const; + + /** + * returns the version of nmm to impersonate when connecting to nexus + **/ + QString getNMMVersion() const; + + /** + * retrieve the directory where the web cache is stored (with native separators) + **/ + QString getCacheDirectory() const; + + /** + * @return true if the user has set up automatic login to nexus + **/ + bool automaticLoginEnabled() const; + + /** + * @brief retrieve the login information for nexus + * + * @param username (out) receives the user name for nexus + * @param password (out) received the password for nexus + * @return true if automatic login is active, false otherwise + **/ + bool getNexusLogin(QString &username, QString &password) const; + + /** + * @return true if the user disabled internet features + */ + bool offlineMode() const; + + /** + * @return true if the user chose compact downloads + */ + bool compactDownloads() const; + + /** + * @return true if the user chose meta downloads + */ + bool metaDownloads() const; + + /** + * @return the configured log level + */ + int logLevel() const; + + /** + * @brief set the nexus login information + * + * @param username username + * @param password password + */ + void setNexusLogin(QString username, QString password); + + /** + * @return the load mechanism to be used + **/ + LoadMechanism::EMechanism getLoadMechanism() const; + + /** + * @brief activate the load mechanism selected by the user + **/ + void setupLoadMechanism(); + + /** + * @return true if the user configured the use of a network proxy + */ + bool useProxy(); + + /** + * @return true if the user wants to see non-official plugins installed outside MO in his mod list + */ + bool displayForeign(); + + /** + * @brief sets the new motd hash + **/ + void setMotDHash(uint hash); + + /** + * @return hash of the last displayed message of the day + **/ + uint getMotDHash() const; + + /** + * @brief allows direct access to the wrapped QSettings object + * @return the wrapped QSettings object + */ + QSettings &directInterface() { return m_Settings; } + + /** + * @brief retrieve a setting for one of the installed plugins + * @param pluginName name of the plugin + * @param key name of the setting to retrieve + * @return the requested value as a QVariant + * @note an invalid QVariant is returned if the the plugin/setting is not declared + */ + QVariant pluginSetting(const QString &pluginName, const QString &key) const; + + /** + * @brief set a setting for one of the installed mods + * @param pluginName name of the plugin + * @param key name of the setting to change + * @param value the new value to set + * @throw an exception is thrown if pluginName is invalid + */ + void setPluginSetting(const QString &pluginName, const QString &key, const QVariant &value); + + /** + * @brief retrieve a persistent value for a plugin + * @param pluginName name of the plugin to store data for + * @param key id of the value to retrieve + * @param def default value to return if the value is not set + * @return the requested value + */ + QVariant pluginPersistent(const QString &pluginName, const QString &key, const QVariant &def) const; + + /** + * @brief set a persistent value for a plugin + * @param pluginName name of the plugin to store data for + * @param key id of the value to retrieve + * @param value value to set + * @throw an exception is thrown if pluginName is invalid + */ + void setPluginPersistent(const QString &pluginName, const QString &key, const QVariant &value, bool sync); + + /** + * @return short code of the configured language (corresponding to the translation files) + */ + QString language(); + + /** + * @brief updates the list of known servers + * @param list of servers from a recent query + */ + void updateServers(const QList<ServerInfo> &servers); + + /** + * @brief add a plugin that is to be blacklisted + * @param fileName name of the plugin to blacklist + */ + void addBlacklistPlugin(const QString &fileName); + + /** + * @brief test if a plugin is blacklisted and shouldn't be loaded + * @param fileName name of the plugin + * @return true if the file is blacklisted + */ + bool pluginBlacklisted(const QString &fileName) const; + + /** + * @return all loaded MO plugins + */ + std::vector<MOBase::IPlugin*> plugins() const { return m_Plugins; } + + /** + * @brief register MO as the handler for nxm links + * @param force set to true to enforce the registration dialog to show up, + * even if the user said earlier not to + */ + void registerAsNXMHandler(bool force); +private: + + QString obfuscate(const QString &password) const; + QString deObfuscate(const QString &password) const; + + void addLanguages(QComboBox *languageBox); + void addStyles(QComboBox *styleBox); + void readPluginBlacklist(); + void writePluginBlacklist(); + +private slots: + + void resetDialogs(); + +signals: + + void languageChanged(const QString &newLanguage); + void styleChanged(const QString &newStyle); + +private: + + static Settings *s_Instance; + + QSettings m_Settings; + + LoadMechanism m_LoadMechanism; + + std::vector<MOBase::IPlugin*> m_Plugins; + + QMap<QString, QMap<QString, QVariant> > m_PluginSettings; + QMap<QString, QMap<QString, QVariant> > m_PluginDescriptions; + + QSet<QString> m_PluginBlacklist; + +}; + +#endif // WORKAROUNDS_H diff --git a/src/settingsdialog.cpp b/src/settingsdialog.cpp index a7d44d72..d1947b5a 100644 --- a/src/settingsdialog.cpp +++ b/src/settingsdialog.cpp @@ -1,173 +1,182 @@ -/*
-Copyright (C) 2012 Sebastian Herbord. All rights reserved.
-
-This file is part of Mod Organizer.
-
-Mod Organizer is free software: you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation, either version 3 of the License, or
-(at your option) any later version.
-
-Mod Organizer is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#include "settingsdialog.h"
-#include "ui_settingsdialog.h"
-#include "categoriesdialog.h"
-#include "helper.h"
-#include "noeditdelegate.h"
-#include <gameinfo.h>
-#include <QDirIterator>
-#include <QFileDialog>
-#include <QMessageBox>
-#include <QShortcut>
-#define WIN32_LEAN_AND_MEAN
-#include <Windows.h>
-#include "settings.h"
-
-
-using namespace MOBase;
-using namespace MOShared;
-
-
-SettingsDialog::SettingsDialog(QWidget *parent)
- : TutorableDialog("SettingsDialog", parent), ui(new Ui::SettingsDialog)
-{
- ui->setupUi(this);
-
- QShortcut *delShortcut = new QShortcut(QKeySequence(Qt::Key_Delete), ui->pluginBlacklist);
- connect(delShortcut, SIGNAL(activated()), this, SLOT(deleteBlacklistItem()));
-}
-
-SettingsDialog::~SettingsDialog()
-{
- delete ui;
-}
-
-void SettingsDialog::addPlugins(const std::vector<IPlugin*> &plugins)
-{
- foreach (IPlugin *plugin, plugins) {
- ui->pluginsList->addItem(plugin->name());
- }
-}
-
-void SettingsDialog::accept()
-{
- storeSettings(ui->pluginsList->currentItem());
- TutorableDialog::accept();
-}
-
-
-void SettingsDialog::on_loginCheckBox_toggled(bool checked)
-{
- QLineEdit *usernameEdit = findChild<QLineEdit*>("usernameEdit");
- QLineEdit *passwordEdit = findChild<QLineEdit*>("passwordEdit");
- if (checked) {
- passwordEdit->setEnabled(true);
- usernameEdit->setEnabled(true);
- } else {
- passwordEdit->setEnabled(false);
- usernameEdit->setEnabled(false);
- }
-}
-
-void SettingsDialog::on_categoriesBtn_clicked()
-{
- CategoriesDialog dialog(this);
- if (dialog.exec() == QDialog::Accepted) {
- dialog.commitChanges();
- }
-}
-
-void SettingsDialog::on_bsaDateBtn_clicked()
-{
- Helper::backdateBSAs(GameInfo::instance().getOrganizerDirectory(), GameInfo::instance().getGameDirectory().append(L"\\data"));
-}
-
-void SettingsDialog::on_browseDownloadDirBtn_clicked()
-{
- QString temp = QFileDialog::getExistingDirectory(this, tr("Select download directory"), ui->downloadDirEdit->text());
- if (!temp.isEmpty()) {
- ui->downloadDirEdit->setText(temp);
- }
-}
-
-void SettingsDialog::on_browseModDirBtn_clicked()
-{
- QString temp = QFileDialog::getExistingDirectory(this, tr("Select mod directory"), ui->downloadDirEdit->text());
- if (!temp.isEmpty()) {
- ui->modDirEdit->setText(temp);
- }
-}
-
-void SettingsDialog::on_browseCacheDirBtn_clicked()
-{
- QString temp = QFileDialog::getExistingDirectory(this, tr("Select cache directory"), ui->cacheDirEdit->text());
- if (!temp.isEmpty()) {
- ui->cacheDirEdit->setText(temp);
- }
-}
-
-void SettingsDialog::on_resetDialogsButton_clicked()
-{
- if (QMessageBox::question(this, tr("Confirm?"),
- tr("This will make all dialogs show up again where you checked the \"Remember selection\"-box. Continue?"),
- QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes) {
- emit resetDialogs();
- }
-}
-
-void SettingsDialog::storeSettings(QListWidgetItem *pluginItem)
-{
- if (pluginItem != NULL) {
- QMap<QString, QVariant> settings = pluginItem->data(Qt::UserRole + 1).toMap();
-
- for (int i = 0; i < ui->pluginSettingsList->topLevelItemCount(); ++i) {
- const QTreeWidgetItem *item = ui->pluginSettingsList->topLevelItem(i);
- settings[item->text(0)] = item->data(1, Qt::DisplayRole);
- }
-
- pluginItem->setData(Qt::UserRole + 1, settings);
- }
-}
-
-void SettingsDialog::on_pluginsList_currentItemChanged(QListWidgetItem *current, QListWidgetItem *previous)
-{
- storeSettings(previous);
-
- ui->pluginSettingsList->clear();
- IPlugin *plugin = static_cast<IPlugin*>(current->data(Qt::UserRole).value<void*>());
- ui->authorLabel->setText(plugin->author());
- ui->versionLabel->setText(plugin->version().canonicalString());
- ui->descriptionLabel->setText(plugin->description());
-
- QMap<QString, QVariant> settings = current->data(Qt::UserRole + 1).toMap();
- ui->pluginSettingsList->setEnabled(settings.count() != 0);
- for (auto iter = settings.begin(); iter != settings.end(); ++iter) {
- QTreeWidgetItem *newItem = new QTreeWidgetItem(QStringList(iter.key()));
- QVariant value = *iter;
-
- ui->pluginSettingsList->setItemDelegateForColumn(0, new NoEditDelegate());
- newItem->setData(1, Qt::DisplayRole, value);
- newItem->setData(1, Qt::EditRole, value);
-
- newItem->setFlags(newItem->flags() | Qt::ItemIsEditable);
- ui->pluginSettingsList->addTopLevelItem(newItem);
- }
-}
-
-void SettingsDialog::deleteBlacklistItem()
-{
- ui->pluginBlacklist->takeItem(ui->pluginBlacklist->currentIndex().row());
-}
-
-void SettingsDialog::on_associateButton_clicked()
-{
- Settings::instance().registerAsNXMHandler(true);
-}
+/* +Copyright (C) 2012 Sebastian Herbord. All rights reserved. + +This file is part of Mod Organizer. + +Mod Organizer is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +Mod Organizer is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>. +*/ + +#include "settingsdialog.h" +#include "ui_settingsdialog.h" +#include "categoriesdialog.h" +#include "helper.h" +#include "noeditdelegate.h" +#include <gameinfo.h> +#include <QDirIterator> +#include <QFileDialog> +#include <QMessageBox> +#include <QShortcut> +#define WIN32_LEAN_AND_MEAN +#include <Windows.h> +#include "settings.h" + + +using namespace MOBase; +using namespace MOShared; + + +SettingsDialog::SettingsDialog(QWidget *parent) + : TutorableDialog("SettingsDialog", parent), ui(new Ui::SettingsDialog) +{ + ui->setupUi(this); + + QShortcut *delShortcut = new QShortcut(QKeySequence(Qt::Key_Delete), ui->pluginBlacklist); + connect(delShortcut, SIGNAL(activated()), this, SLOT(deleteBlacklistItem())); +} + +SettingsDialog::~SettingsDialog() +{ + delete ui; +} + +void SettingsDialog::addPlugins(const std::vector<IPlugin*> &plugins) +{ + foreach (IPlugin *plugin, plugins) { + ui->pluginsList->addItem(plugin->name()); + } +} + +void SettingsDialog::accept() +{ + storeSettings(ui->pluginsList->currentItem()); + TutorableDialog::accept(); +} + + +void SettingsDialog::on_loginCheckBox_toggled(bool checked) +{ + QLineEdit *usernameEdit = findChild<QLineEdit*>("usernameEdit"); + QLineEdit *passwordEdit = findChild<QLineEdit*>("passwordEdit"); + if (checked) { + passwordEdit->setEnabled(true); + usernameEdit->setEnabled(true); + } else { + passwordEdit->setEnabled(false); + usernameEdit->setEnabled(false); + } +} + +void SettingsDialog::on_categoriesBtn_clicked() +{ + CategoriesDialog dialog(this); + if (dialog.exec() == QDialog::Accepted) { + dialog.commitChanges(); + } +} + +void SettingsDialog::on_bsaDateBtn_clicked() +{ + Helper::backdateBSAs(GameInfo::instance().getOrganizerDirectory(), GameInfo::instance().getGameDirectory().append(L"\\data")); +} + +void SettingsDialog::on_browseDownloadDirBtn_clicked() +{ + QString temp = QFileDialog::getExistingDirectory(this, tr("Select download directory"), ui->downloadDirEdit->text()); + if (!temp.isEmpty()) { + ui->downloadDirEdit->setText(temp); + } +} + +void SettingsDialog::on_browseModDirBtn_clicked() +{ + QString temp = QFileDialog::getExistingDirectory(this, tr("Select mod directory"), ui->downloadDirEdit->text()); + if (!temp.isEmpty()) { + ui->modDirEdit->setText(temp); + } +} + +void SettingsDialog::on_browseCacheDirBtn_clicked() +{ + QString temp = QFileDialog::getExistingDirectory(this, tr("Select cache directory"), ui->cacheDirEdit->text()); + if (!temp.isEmpty()) { + ui->cacheDirEdit->setText(temp); + } +} + +void SettingsDialog::on_resetDialogsButton_clicked() +{ + if (QMessageBox::question(this, tr("Confirm?"), + tr("This will make all dialogs show up again where you checked the \"Remember selection\"-box. Continue?"), + QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes) { + emit resetDialogs(); + } +} + +void SettingsDialog::storeSettings(QListWidgetItem *pluginItem) +{ + if (pluginItem != NULL) { + QMap<QString, QVariant> settings = pluginItem->data(Qt::UserRole + 1).toMap(); + + for (int i = 0; i < ui->pluginSettingsList->topLevelItemCount(); ++i) { + const QTreeWidgetItem *item = ui->pluginSettingsList->topLevelItem(i); + settings[item->text(0)] = item->data(1, Qt::DisplayRole); + } + + pluginItem->setData(Qt::UserRole + 1, settings); + } +} + +void SettingsDialog::on_pluginsList_currentItemChanged(QListWidgetItem *current, QListWidgetItem *previous) +{ + storeSettings(previous); + + ui->pluginSettingsList->clear(); + IPlugin *plugin = static_cast<IPlugin*>(current->data(Qt::UserRole).value<void*>()); + ui->authorLabel->setText(plugin->author()); + ui->versionLabel->setText(plugin->version().canonicalString()); + ui->descriptionLabel->setText(plugin->description()); + + QMap<QString, QVariant> settings = current->data(Qt::UserRole + 1).toMap(); + QMap<QString, QVariant> descriptions = current->data(Qt::UserRole + 2).toMap(); + ui->pluginSettingsList->setEnabled(settings.count() != 0); + for (auto iter = settings.begin(); iter != settings.end(); ++iter) { + QTreeWidgetItem *newItem = new QTreeWidgetItem(QStringList(iter.key())); + QVariant value = *iter; + QString description; + { + auto descriptionIter = descriptions.find(iter.key()); + if (descriptionIter != descriptions.end()) { + description = descriptionIter->toString(); + } + } + + ui->pluginSettingsList->setItemDelegateForColumn(0, new NoEditDelegate()); + newItem->setData(1, Qt::DisplayRole, value); + newItem->setData(1, Qt::EditRole, value); + newItem->setToolTip(1, description); + + newItem->setFlags(newItem->flags() | Qt::ItemIsEditable); + ui->pluginSettingsList->addTopLevelItem(newItem); + } +} + +void SettingsDialog::deleteBlacklistItem() +{ + ui->pluginBlacklist->takeItem(ui->pluginBlacklist->currentIndex().row()); +} + +void SettingsDialog::on_associateButton_clicked() +{ + Settings::instance().registerAsNXMHandler(true); +} |
