From af95b3b8637d28517f69a70f13b901cc7f43d121 Mon Sep 17 00:00:00 2001 From: isanae <14251494+isanae@users.noreply.github.com> Date: Sat, 20 Jul 2019 09:31:38 -0400 Subject: renamed tab classes, clashing with mod info dialog split nexus tab --- src/settingsdialognexus.h | 40 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) create mode 100644 src/settingsdialognexus.h (limited to 'src/settingsdialognexus.h') diff --git a/src/settingsdialognexus.h b/src/settingsdialognexus.h new file mode 100644 index 00000000..5c01f61f --- /dev/null +++ b/src/settingsdialognexus.h @@ -0,0 +1,40 @@ +#ifndef SETTINGSDIALOGNEXUS_H +#define SETTINGSDIALOGNEXUS_H + +#include "settings.h" +#include "settingsdialog.h" + +class NexusSettingsTab : public SettingsTab +{ +public: + NexusSettingsTab(Settings *m_parent, SettingsDialog &m_dialog); + void update(); + +private: + std::unique_ptr m_nexusLogin; + std::unique_ptr m_nexusValidator; + + void on_nexusConnect_clicked(); + void on_nexusManualKey_clicked(); + void on_nexusDisconnect_clicked(); + void on_clearCacheButton_clicked(); + void on_associateButton_clicked(); + + void validateKey(const QString& key); + bool setKey(const QString& key); + bool clearKey(); + + void updateNexusState(); + void updateNexusButtons(); + void updateNexusData(); + + void onSSOKeyChanged(const QString& key); + void onSSOStateChanged(NexusSSOLogin::States s, const QString& e); + + void onValidatorStateChanged(NexusKeyValidator::States s, const QString& e); + void onValidatorFinished(const APIUserAccount& user); + + void addNexusLog(const QString& s); +}; + +#endif // SETTINGSDIALOGNEXUS_H -- cgit v1.3.1 From a05862aaa13b028e2f250347daa7a2e0f64c2380 Mon Sep 17 00:00:00 2001 From: isanae <14251494+isanae@users.noreply.github.com> Date: Sat, 20 Jul 2019 11:20:27 -0400 Subject: cleaned up includes removed commented out code reordered member functions in Settings --- src/settings.cpp | 44 ------------------------------------------- src/settings.h | 36 +++++++---------------------------- src/settingsdialog.cpp | 26 ------------------------- src/settingsdialog.h | 4 +--- src/settingsdialoggeneral.cpp | 24 ----------------------- src/settingsdialognexus.cpp | 11 ----------- src/settingsdialognexus.h | 1 + 7 files changed, 9 insertions(+), 137 deletions(-) (limited to 'src/settingsdialognexus.h') diff --git a/src/settings.cpp b/src/settings.cpp index dc07e107..e7a853a2 100644 --- a/src/settings.cpp +++ b/src/settings.cpp @@ -18,58 +18,16 @@ along with Mod Organizer. If not, see . */ #include "settings.h" - -#include "pluginsetting.h" #include "serverinfo.h" -#include "versioninfo.h" #include "appconfig.h" -#include "organizercore.h" #include -#include #include -#include #include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include // for Qt::UserRole, etc - -#include // For ShellExecuteW, HINSTANCE, etc -#include // For storage - -#include // for sort -#include -#include // for runtime_error -#include -#include // for pair, make_pair - - using namespace MOBase; - Settings *Settings::s_Instance = nullptr; - Settings::Settings(const QSettings &settingsSource) : m_Settings(settingsSource.fileName(), settingsSource.format()) { @@ -80,13 +38,11 @@ Settings::Settings(const QSettings &settingsSource) } } - Settings::~Settings() { s_Instance = nullptr; } - Settings &Settings::instance() { if (s_Instance == nullptr) { diff --git a/src/settings.h b/src/settings.h index 899baaa3..b20e78d0 100644 --- a/src/settings.h +++ b/src/settings.h @@ -23,17 +23,6 @@ along with Mod Organizer. If not, see . #include "loadmechanism.h" #include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - namespace MOBase { class IPlugin; class IPluginGame; @@ -376,6 +365,8 @@ public: */ bool colorSeparatorScrollbar() const; + static QColor getIdealTextColor(const QColor& rBackgroundColor); + // temp QSettings& settingsRef() { return m_Settings; } MOBase::IPluginGame const *gamePlugin() { return m_GamePlugin; } @@ -386,37 +377,24 @@ public: const LoadMechanism& loadMechanism() const { return m_LoadMechanism; } public slots: - void managedGameChanged(MOBase::IPluginGame const *gamePlugin); -public: - static QColor getIdealTextColor(const QColor& rBackgroundColor); -private: - - static bool obfuscate(const QString key, const QString data); - static QString deObfuscate(const QString key); - - void readPluginBlacklist(); - QString getConfigurablePath(const QString &key, const QString &def, bool resolve) const; - -private slots: signals: - void languageChanged(const QString &newLanguage); void styleChanged(const QString &newStyle); private: - static Settings *s_Instance; - MOBase::IPluginGame const *m_GamePlugin; - QSettings m_Settings; - LoadMechanism m_LoadMechanism; - std::vector m_Plugins; + static bool obfuscate(const QString key, const QString data); + static QString deObfuscate(const QString key); + + void readPluginBlacklist(); + QString getConfigurablePath(const QString &key, const QString &def, bool resolve) const; }; #endif // SETTINGS_H diff --git a/src/settingsdialog.cpp b/src/settingsdialog.cpp index 8c5b2678..e008086a 100644 --- a/src/settingsdialog.cpp +++ b/src/settingsdialog.cpp @@ -18,17 +18,7 @@ along with Mod Organizer. If not, see . */ #include "settingsdialog.h" - #include "ui_settingsdialog.h" -#include "categoriesdialog.h" -#include "helper.h" -#include "noeditdelegate.h" -#include "iplugingame.h" -#include "settings.h" -#include "instancemanager.h" -#include "nexusinterface.h" -#include "plugincontainer.h" - #include "settingsdialogdiagnostics.h" #include "settingsdialoggeneral.h" #include "settingsdialognexus.h" @@ -37,22 +27,6 @@ along with Mod Organizer. If not, see . #include "settingsdialogsteam.h" #include "settingsdialogworkarounds.h" -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -#define WIN32_LEAN_AND_MEAN -#include - - using namespace MOBase; SettingsDialog::SettingsDialog(PluginContainer *pluginContainer, Settings* settings, QWidget *parent) diff --git a/src/settingsdialog.h b/src/settingsdialog.h index f2367315..03bba7cf 100644 --- a/src/settingsdialog.h +++ b/src/settingsdialog.h @@ -21,15 +21,13 @@ along with Mod Organizer. If not, see . #define SETTINGSDIALOG_H #include "tutorabledialog.h" -#include "nxmaccessmanager.h" -#include -#include class PluginContainer; class Settings; class SettingsDialog; namespace Ui { class SettingsDialog; } + class SettingsTab { public: diff --git a/src/settingsdialoggeneral.cpp b/src/settingsdialoggeneral.cpp index cd98dfdc..324dc4f4 100644 --- a/src/settingsdialoggeneral.cpp +++ b/src/settingsdialoggeneral.cpp @@ -33,28 +33,6 @@ GeneralSettingsTab::GeneralSettingsTab(Settings *m_parent, SettingsDialog &m_dia ui->styleBox->setCurrentIndex(currentID); } } - /* verision using palette only works with fusion theme for some stupid reason... - m_overwritingBtn->setAutoFillBackground(true); - m_overwrittenBtn->setAutoFillBackground(true); - m_containsBtn->setAutoFillBackground(true); - m_containedBtn->setAutoFillBackground(true); - m_overwritingBtn->setPalette(QPalette(m_parent->modlistOverwritingLooseColor())); - m_overwrittenBtn->setPalette(QPalette(m_parent->modlistOverwrittenLooseColor())); - m_containsBtn->setPalette(QPalette(m_parent->modlistContainsPluginColor())); - m_containedBtn->setPalette(QPalette(m_parent->pluginListContainedColor())); - QPalette palette1 = m_overwritingBtn->palette(); - QPalette palette2 = m_overwrittenBtn->palette(); - QPalette palette3 = m_containsBtn->palette(); - QPalette palette4 = m_containedBtn->palette(); - palette1.setColor(QPalette::Background, m_parent->modlistOverwritingLooseColor()); - palette2.setColor(QPalette::Background, m_parent->modlistOverwrittenLooseColor()); - palette3.setColor(QPalette::Background, m_parent->modlistContainsPluginColor()); - palette4.setColor(QPalette::Background, m_parent->pluginListContainedColor()); - m_overwritingBtn->setPalette(palette1); - m_overwrittenBtn->setPalette(palette2); - m_containsBtn->setPalette(palette3); - m_containedBtn->setPalette(palette4); - */ //version with stylesheet setButtonColor(ui->overwritingBtn, m_parent->modlistOverwritingLooseColor()); @@ -137,12 +115,10 @@ void GeneralSettingsTab::addLanguages() } } languages.push_back(std::make_pair(QString("%1").arg(languageString), exp.cap(1))); - //languageBox->addItem(QString("%1").arg(languageString), exp.cap(1)); } } if (!ui->languageBox->findText("English")) { languages.push_back(std::make_pair(QString("English"), QString("en_US"))); - //languageBox->addItem("English", "en_US"); } std::sort(languages.begin(), languages.end()); for (const auto &lang : languages) { diff --git a/src/settingsdialognexus.cpp b/src/settingsdialognexus.cpp index 7d4414fd..575f54d0 100644 --- a/src/settingsdialognexus.cpp +++ b/src/settingsdialognexus.cpp @@ -114,17 +114,6 @@ NexusSettingsTab::NexusSettingsTab(Settings *parent, SettingsDialog &dialog) void NexusSettingsTab::update() { - /* - if (m_loginCheckBox->isChecked()) { - m_Settings.setValue("Settings/nexus_login", true); - m_Settings.setValue("Settings/nexus_username", m_usernameEdit->text()); - m_Settings.setValue("Settings/nexus_password", obfuscate(m_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", ui->offlineBox->isChecked()); m_Settings.setValue("Settings/use_proxy", ui->proxyBox->isChecked()); m_Settings.setValue("Settings/endorsement_integration", ui->endorsementBox->isChecked()); diff --git a/src/settingsdialognexus.h b/src/settingsdialognexus.h index 5c01f61f..cca2e1b5 100644 --- a/src/settingsdialognexus.h +++ b/src/settingsdialognexus.h @@ -3,6 +3,7 @@ #include "settings.h" #include "settingsdialog.h" +#include "nxmaccessmanager.h" class NexusSettingsTab : public SettingsTab { -- cgit v1.3.1 From 2ffad7edf2946e66585a67c4ab58c0522cd8e412 Mon Sep 17 00:00:00 2001 From: isanae <14251494+isanae@users.noreply.github.com> Date: Sat, 17 Aug 2019 13:20:53 -0400 Subject: made member variables in SettingsTab private, added accessors SettingsDialog now uses GeometrySaver --- src/loglist.h | 2 + src/mainwindow.cpp | 2 +- src/organizercore.cpp | 9 +--- src/settingsdialog.cpp | 40 ++++++++-------- src/settingsdialog.h | 18 ++++--- src/settingsdialogdiagnostics.cpp | 16 +++---- src/settingsdialogdiagnostics.h | 2 +- src/settingsdialoggeneral.cpp | 98 +++++++++++++++++++-------------------- src/settingsdialoggeneral.h | 2 +- src/settingsdialognexus.cpp | 66 +++++++++++++------------- src/settingsdialognexus.h | 2 +- src/settingsdialogpaths.cpp | 48 +++++++++---------- src/settingsdialogpaths.h | 3 +- src/settingsdialogplugins.cpp | 26 +++++------ src/settingsdialogplugins.h | 2 +- src/settingsdialogsteam.cpp | 8 ++-- src/settingsdialogsteam.h | 5 +- src/settingsdialogworkarounds.cpp | 46 +++++++++--------- src/settingsdialogworkarounds.h | 3 +- 19 files changed, 196 insertions(+), 202 deletions(-) (limited to 'src/settingsdialognexus.h') diff --git a/src/loglist.h b/src/loglist.h index 0b25dfd1..36671be4 100644 --- a/src/loglist.h +++ b/src/loglist.h @@ -61,6 +61,8 @@ private: class LogList : public QTreeView { + Q_OBJECT; + public: LogList(QWidget* parent=nullptr); diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index 2ce6f9d9..f1a2047f 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -5018,7 +5018,7 @@ void MainWindow::on_actionSettings_triggered() DownloadManager *dlManager = m_OrganizerCore.downloadManager(); - SettingsDialog dialog(&m_PluginContainer, &settings, this); + SettingsDialog dialog(&m_PluginContainer, settings, this); dialog.exec(); if (oldManagedGameDirectory != settings.getManagedGameDirectory()) { diff --git a/src/organizercore.cpp b/src/organizercore.cpp index 233a631e..73d0abac 100644 --- a/src/organizercore.cpp +++ b/src/organizercore.cpp @@ -745,16 +745,11 @@ void OrganizerCore::setCurrentProfile(const QString &profileName) m_CurrentProfile->deactivateInvalidation(); } + m_Settings.setSelectedProfileName(m_CurrentProfile->name()); + connect(m_CurrentProfile, SIGNAL(modStatusChanged(uint)), this, SLOT(modStatusChanged(uint))); connect(m_CurrentProfile, SIGNAL(modStatusChanged(QList)), this, SLOT(modStatusChanged(QList))); refreshDirectoryStructure(); - - //This line is not actually needed and was only added to allow some - //outside detection of Mo2 profile change. (like BaobobMiller utility) - if (m_CurrentProfile != nullptr) { - settings().directInterface().setValue("selected_profile", - m_CurrentProfile->name().toUtf8().constData()); - } } MOBase::IModRepositoryBridge *OrganizerCore::createNexusBridge() const diff --git a/src/settingsdialog.cpp b/src/settingsdialog.cpp index d74507c9..097dafc8 100644 --- a/src/settingsdialog.cpp +++ b/src/settingsdialog.cpp @@ -29,7 +29,7 @@ along with Mod Organizer. If not, see . using namespace MOBase; -SettingsDialog::SettingsDialog(PluginContainer *pluginContainer, Settings* settings, QWidget *parent) +SettingsDialog::SettingsDialog(PluginContainer *pluginContainer, Settings& settings, QWidget *parent) : TutorableDialog("SettingsDialog", parent) , ui(new Ui::SettingsDialog) , m_settings(settings) @@ -45,18 +45,13 @@ SettingsDialog::SettingsDialog(PluginContainer *pluginContainer, Settings* setti m_tabs.push_back(std::unique_ptr(new SteamSettingsTab(settings, *this))); m_tabs.push_back(std::unique_ptr(new PluginsSettingsTab(settings, *this))); m_tabs.push_back(std::unique_ptr(new WorkaroundsSettingsTab(settings, *this))); - - auto& qsettings = settings->directInterface(); - - QString key = QString("geometry/%1").arg(objectName()); - if (qsettings.contains(key)) { - restoreGeometry(qsettings.value(key).toByteArray()); - } } int SettingsDialog::exec() { - auto& qsettings = m_settings->directInterface(); + GeometrySaver gs(m_settings, this); + + auto& qsettings = m_settings.directInterface(); auto ret = TutorableDialog::exec(); if (ret == QDialog::Accepted) { @@ -92,9 +87,6 @@ int SettingsDialog::exec() qsettings.endGroup(); } - QString key = QString("geometry/%1").arg(objectName()); - qsettings.setValue(key, saveGeometry()); - // These changes happen regardless of accepted or rejected bool restartNeeded = false; if (getApiKeyChanged()) { @@ -158,18 +150,24 @@ bool SettingsDialog::getApiKeyChanged() } -SettingsTab::SettingsTab(Settings *m_parent, SettingsDialog &m_dialog) - : m_parent(m_parent) - , m_Settings(m_parent->directInterface()) - , m_dialog(m_dialog) - , ui(m_dialog.ui) +SettingsTab::SettingsTab(Settings& s, SettingsDialog& d) + : ui(d.ui), m_settings(s), m_qsettings(s.directInterface()), m_dialog(d) { } -SettingsTab::~SettingsTab() -{} +SettingsTab::~SettingsTab() = default; + +Settings& SettingsTab::settings() +{ + return m_settings; +} + +QSettings& SettingsTab::qsettings() +{ + return m_qsettings; +} -QWidget* SettingsTab::parentWidget() +SettingsDialog& SettingsTab::dialog() { - return &m_dialog; + return m_dialog; } diff --git a/src/settingsdialog.h b/src/settingsdialog.h index efc4a095..0aad8863 100644 --- a/src/settingsdialog.h +++ b/src/settingsdialog.h @@ -31,19 +31,23 @@ namespace Ui { class SettingsDialog; } class SettingsTab { public: - SettingsTab(Settings *m_parent, SettingsDialog &m_dialog); + SettingsTab(Settings& settings, SettingsDialog& m_dialog); virtual ~SettingsTab(); virtual void update() = 0; virtual void closing() {} protected: - Settings *m_parent; - QSettings &m_Settings; - SettingsDialog &m_dialog; Ui::SettingsDialog* ui; - QWidget* parentWidget(); + Settings& settings(); + QSettings& qsettings(); + SettingsDialog& dialog(); + +private: + Settings& m_settings; + QSettings& m_qsettings; + SettingsDialog& m_dialog; }; @@ -58,7 +62,7 @@ class SettingsDialog : public MOBase::TutorableDialog public: explicit SettingsDialog( - PluginContainer *pluginContainer, Settings* settings, QWidget *parent = 0); + PluginContainer *pluginContainer, Settings& settings, QWidget *parent = 0); ~SettingsDialog(); @@ -82,7 +86,7 @@ public: bool getApiKeyChanged(); private: - Settings* m_settings; + Settings& m_settings; std::vector> m_tabs; }; diff --git a/src/settingsdialogdiagnostics.cpp b/src/settingsdialogdiagnostics.cpp index daf81d5c..227d1dfa 100644 --- a/src/settingsdialogdiagnostics.cpp +++ b/src/settingsdialogdiagnostics.cpp @@ -6,12 +6,12 @@ using namespace MOBase; -DiagnosticsSettingsTab::DiagnosticsSettingsTab(Settings *m_parent, SettingsDialog &m_dialog) - : SettingsTab(m_parent, m_dialog) +DiagnosticsSettingsTab::DiagnosticsSettingsTab(Settings& s, SettingsDialog& d) + : SettingsTab(s, d) { setLevelsBox(); - ui->dumpsTypeBox->setCurrentIndex(m_parent->crashDumpsType()); - ui->dumpsMaxEdit->setValue(m_parent->crashDumpsMax()); + ui->dumpsTypeBox->setCurrentIndex(settings().crashDumpsType()); + ui->dumpsMaxEdit->setValue(settings().crashDumpsMax()); QString logsPath = qApp->property("dataPath").toString() + "/" + QString::fromStdWString(AppConfig::logPath()); ui->diagnosticsExplainedLabel->setText( @@ -33,7 +33,7 @@ void DiagnosticsSettingsTab::setLevelsBox() ui->logLevelBox->addItem(QObject::tr("Error"), log::Error); for (int i=0; ilogLevelBox->count(); ++i) { - if (ui->logLevelBox->itemData(i) == m_parent->logLevel()) { + if (ui->logLevelBox->itemData(i) == settings().logLevel()) { ui->logLevelBox->setCurrentIndex(i); break; } @@ -42,7 +42,7 @@ void DiagnosticsSettingsTab::setLevelsBox() void DiagnosticsSettingsTab::update() { - m_Settings.setValue("Settings/log_level", ui->logLevelBox->currentData().toInt()); - m_Settings.setValue("Settings/crash_dumps_type", ui->dumpsTypeBox->currentIndex()); - m_Settings.setValue("Settings/crash_dumps_max", ui->dumpsMaxEdit->value()); + qsettings().setValue("Settings/log_level", ui->logLevelBox->currentData().toInt()); + qsettings().setValue("Settings/crash_dumps_type", ui->dumpsTypeBox->currentIndex()); + qsettings().setValue("Settings/crash_dumps_max", ui->dumpsMaxEdit->value()); } diff --git a/src/settingsdialogdiagnostics.h b/src/settingsdialogdiagnostics.h index 4c1805e2..f20413f8 100644 --- a/src/settingsdialogdiagnostics.h +++ b/src/settingsdialogdiagnostics.h @@ -7,7 +7,7 @@ class DiagnosticsSettingsTab : public SettingsTab { public: - DiagnosticsSettingsTab(Settings *parent, SettingsDialog &dialog); + DiagnosticsSettingsTab(Settings& settings, SettingsDialog& dialog); void update(); diff --git a/src/settingsdialoggeneral.cpp b/src/settingsdialoggeneral.cpp index fda50220..35012db7 100644 --- a/src/settingsdialoggeneral.cpp +++ b/src/settingsdialoggeneral.cpp @@ -6,12 +6,12 @@ using MOBase::QuestionBoxMemory; -GeneralSettingsTab::GeneralSettingsTab(Settings *m_parent, SettingsDialog &m_dialog) - : SettingsTab(m_parent, m_dialog) +GeneralSettingsTab::GeneralSettingsTab(Settings& s, SettingsDialog& d) + : SettingsTab(s, d) { addLanguages(); { - QString languageCode = m_parent->language(); + QString languageCode = settings().language(); int currentID = ui->languageBox->findData(languageCode); // I made a mess. :( Most languages are stored with only the iso country // code (2 characters like "de") but chinese @@ -28,31 +28,31 @@ GeneralSettingsTab::GeneralSettingsTab(Settings *m_parent, SettingsDialog &m_dia addStyles(); { int currentID = ui->styleBox->findData( - m_Settings.value("Settings/style", "").toString()); + qsettings().value("Settings/style", "").toString()); if (currentID != -1) { ui->styleBox->setCurrentIndex(currentID); } } //version with stylesheet - setButtonColor(ui->overwritingBtn, m_parent->modlistOverwritingLooseColor()); - setButtonColor(ui->overwrittenBtn, m_parent->modlistOverwrittenLooseColor()); - setButtonColor(ui->overwritingArchiveBtn, m_parent->modlistOverwritingArchiveColor()); - setButtonColor(ui->overwrittenArchiveBtn, m_parent->modlistOverwrittenArchiveColor()); - setButtonColor(ui->containsBtn, m_parent->modlistContainsPluginColor()); - setButtonColor(ui->containedBtn, m_parent->pluginListContainedColor()); - - setOverwritingColor(m_parent->modlistOverwritingLooseColor()); - setOverwrittenColor(m_parent->modlistOverwrittenLooseColor()); - setOverwritingArchiveColor(m_parent->modlistOverwritingArchiveColor()); - setOverwrittenArchiveColor(m_parent->modlistOverwrittenArchiveColor()); - setContainsColor(m_parent->modlistContainsPluginColor()); - setContainedColor(m_parent->pluginListContainedColor()); - - ui->compactBox->setChecked(m_parent->compactDownloads()); - ui->showMetaBox->setChecked(m_parent->metaDownloads()); - ui->usePrereleaseBox->setChecked(m_parent->usePrereleases()); - ui->colorSeparatorsBox->setChecked(m_parent->colorSeparatorScrollbar()); + setButtonColor(ui->overwritingBtn, settings().modlistOverwritingLooseColor()); + setButtonColor(ui->overwrittenBtn, settings().modlistOverwrittenLooseColor()); + setButtonColor(ui->overwritingArchiveBtn, settings().modlistOverwritingArchiveColor()); + setButtonColor(ui->overwrittenArchiveBtn, settings().modlistOverwrittenArchiveColor()); + setButtonColor(ui->containsBtn, settings().modlistContainsPluginColor()); + setButtonColor(ui->containedBtn, settings().pluginListContainedColor()); + + setOverwritingColor(settings().modlistOverwritingLooseColor()); + setOverwrittenColor(settings().modlistOverwrittenLooseColor()); + setOverwritingArchiveColor(settings().modlistOverwritingArchiveColor()); + setOverwrittenArchiveColor(settings().modlistOverwrittenArchiveColor()); + setContainsColor(settings().modlistContainsPluginColor()); + setContainedColor(settings().pluginListContainedColor()); + + ui->compactBox->setChecked(settings().compactDownloads()); + ui->showMetaBox->setChecked(settings().metaDownloads()); + ui->usePrereleaseBox->setChecked(settings().usePrereleases()); + ui->colorSeparatorsBox->setChecked(settings().colorSeparatorScrollbar()); QObject::connect(ui->overwritingArchiveBtn, &QPushButton::clicked, [&]{ on_overwritingArchiveBtn_clicked(); }); QObject::connect(ui->overwritingBtn, &QPushButton::clicked, [&]{ on_overwritingBtn_clicked(); }); @@ -67,30 +67,30 @@ GeneralSettingsTab::GeneralSettingsTab(Settings *m_parent, SettingsDialog &m_dia void GeneralSettingsTab::update() { - QString oldLanguage = m_parent->language(); + QString oldLanguage = settings().language(); QString newLanguage = ui->languageBox->itemData(ui->languageBox->currentIndex()).toString(); if (newLanguage != oldLanguage) { - m_Settings.setValue("Settings/language", newLanguage); - emit m_parent->languageChanged(newLanguage); + qsettings().setValue("Settings/language", newLanguage); + emit settings().languageChanged(newLanguage); } - QString oldStyle = m_Settings.value("Settings/style", "").toString(); + QString oldStyle = qsettings().value("Settings/style", "").toString(); QString newStyle = ui->styleBox->itemData(ui->styleBox->currentIndex()).toString(); if (oldStyle != newStyle) { - m_Settings.setValue("Settings/style", newStyle); - emit m_parent->styleChanged(newStyle); - } - - m_Settings.setValue("Settings/overwritingLooseFilesColor", getOverwritingColor()); - m_Settings.setValue("Settings/overwrittenLooseFilesColor", getOverwrittenColor()); - m_Settings.setValue("Settings/overwritingArchiveFilesColor", getOverwritingArchiveColor()); - m_Settings.setValue("Settings/overwrittenArchiveFilesColor", getOverwrittenArchiveColor()); - m_Settings.setValue("Settings/containsPluginColor", getContainsColor()); - m_Settings.setValue("Settings/containedColor", getContainedColor()); - m_Settings.setValue("Settings/compact_downloads", ui->compactBox->isChecked()); - m_Settings.setValue("Settings/meta_downloads", ui->showMetaBox->isChecked()); - m_Settings.setValue("Settings/use_prereleases", ui->usePrereleaseBox->isChecked()); - m_Settings.setValue("Settings/colorSeparatorScrollbars", ui->colorSeparatorsBox->isChecked()); + qsettings().setValue("Settings/style", newStyle); + emit settings().styleChanged(newStyle); + } + + qsettings().setValue("Settings/overwritingLooseFilesColor", getOverwritingColor()); + qsettings().setValue("Settings/overwrittenLooseFilesColor", getOverwrittenColor()); + qsettings().setValue("Settings/overwritingArchiveFilesColor", getOverwritingArchiveColor()); + qsettings().setValue("Settings/overwrittenArchiveFilesColor", getOverwrittenArchiveColor()); + qsettings().setValue("Settings/containsPluginColor", getContainsColor()); + qsettings().setValue("Settings/containedColor", getContainedColor()); + qsettings().setValue("Settings/compact_downloads", ui->compactBox->isChecked()); + qsettings().setValue("Settings/meta_downloads", ui->showMetaBox->isChecked()); + qsettings().setValue("Settings/use_prereleases", ui->usePrereleaseBox->isChecked()); + qsettings().setValue("Settings/colorSeparatorScrollbars", ui->colorSeparatorsBox->isChecked()); } void GeneralSettingsTab::addLanguages() @@ -141,7 +141,7 @@ void GeneralSettingsTab::addStyles() void GeneralSettingsTab::resetDialogs() { - m_parent->resetQuestionButtons(); + settings().resetQuestionButtons(); } void GeneralSettingsTab::setButtonColor(QPushButton *button, const QColor &color) @@ -163,7 +163,7 @@ void GeneralSettingsTab::setButtonColor(QPushButton *button, const QColor &color void GeneralSettingsTab::on_containsBtn_clicked() { - QColor result = QColorDialog::getColor(m_ContainsColor, parentWidget(), "Color Picker: Mod contains selected plugin", QColorDialog::ShowAlphaChannel); + QColor result = QColorDialog::getColor(m_ContainsColor, &dialog(), "Color Picker: Mod contains selected plugin", QColorDialog::ShowAlphaChannel); if (result.isValid()) { m_ContainsColor = result; setButtonColor(ui->containsBtn, result); @@ -172,7 +172,7 @@ void GeneralSettingsTab::on_containsBtn_clicked() void GeneralSettingsTab::on_containedBtn_clicked() { - QColor result = QColorDialog::getColor(m_ContainedColor, parentWidget(), "ColorPicker: Plugin is Contained in selected Mod", QColorDialog::ShowAlphaChannel); + QColor result = QColorDialog::getColor(m_ContainedColor, &dialog(), "ColorPicker: Plugin is Contained in selected Mod", QColorDialog::ShowAlphaChannel); if (result.isValid()) { m_ContainedColor = result; setButtonColor(ui->containedBtn, result); @@ -181,7 +181,7 @@ void GeneralSettingsTab::on_containedBtn_clicked() void GeneralSettingsTab::on_overwrittenBtn_clicked() { - QColor result = QColorDialog::getColor(m_OverwrittenColor, parentWidget(), "ColorPicker: Is overwritten (loose files)", QColorDialog::ShowAlphaChannel); + QColor result = QColorDialog::getColor(m_OverwrittenColor, &dialog(), "ColorPicker: Is overwritten (loose files)", QColorDialog::ShowAlphaChannel); if (result.isValid()) { m_OverwrittenColor = result; setButtonColor(ui->overwrittenBtn, result); @@ -190,7 +190,7 @@ void GeneralSettingsTab::on_overwrittenBtn_clicked() void GeneralSettingsTab::on_overwritingBtn_clicked() { - QColor result = QColorDialog::getColor(m_OverwritingColor, parentWidget(), "ColorPicker: Is overwriting (loose files)", QColorDialog::ShowAlphaChannel); + QColor result = QColorDialog::getColor(m_OverwritingColor, &dialog(), "ColorPicker: Is overwriting (loose files)", QColorDialog::ShowAlphaChannel); if (result.isValid()) { m_OverwritingColor = result; setButtonColor(ui->overwritingBtn, result); @@ -199,7 +199,7 @@ void GeneralSettingsTab::on_overwritingBtn_clicked() void GeneralSettingsTab::on_overwrittenArchiveBtn_clicked() { - QColor result = QColorDialog::getColor(m_OverwrittenArchiveColor, parentWidget(), "ColorPicker: Is overwritten (archive files)", QColorDialog::ShowAlphaChannel); + QColor result = QColorDialog::getColor(m_OverwrittenArchiveColor, &dialog(), "ColorPicker: Is overwritten (archive files)", QColorDialog::ShowAlphaChannel); if (result.isValid()) { m_OverwrittenArchiveColor = result; setButtonColor(ui->overwrittenArchiveBtn, result); @@ -208,7 +208,7 @@ void GeneralSettingsTab::on_overwrittenArchiveBtn_clicked() void GeneralSettingsTab::on_overwritingArchiveBtn_clicked() { - QColor result = QColorDialog::getColor(m_OverwritingArchiveColor, parentWidget(), "ColorPicker: Is overwriting (archive files)", QColorDialog::ShowAlphaChannel); + QColor result = QColorDialog::getColor(m_OverwritingArchiveColor, &dialog(), "ColorPicker: Is overwriting (archive files)", QColorDialog::ShowAlphaChannel); if (result.isValid()) { m_OverwritingArchiveColor = result; setButtonColor(ui->overwritingArchiveBtn, result); @@ -234,7 +234,7 @@ void GeneralSettingsTab::on_resetColorsBtn_clicked() void GeneralSettingsTab::on_resetDialogsButton_clicked() { - if (QMessageBox::question(parentWidget(), QObject::tr("Confirm?"), + if (QMessageBox::question(&dialog(), QObject::tr("Confirm?"), QObject::tr("This will make all dialogs show up again where you checked the \"Remember selection\"-box. Continue?"), QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes) { resetDialogs(); @@ -243,7 +243,7 @@ void GeneralSettingsTab::on_resetDialogsButton_clicked() void GeneralSettingsTab::on_categoriesBtn_clicked() { - CategoriesDialog dialog(parentWidget()); + CategoriesDialog dialog(&dialog()); if (dialog.exec() == QDialog::Accepted) { dialog.commitChanges(); } diff --git a/src/settingsdialoggeneral.h b/src/settingsdialoggeneral.h index c7fcae36..2038ba31 100644 --- a/src/settingsdialoggeneral.h +++ b/src/settingsdialoggeneral.h @@ -7,7 +7,7 @@ class GeneralSettingsTab : public SettingsTab { public: - GeneralSettingsTab(Settings *m_parent, SettingsDialog &m_dialog); + GeneralSettingsTab(Settings& settings, SettingsDialog& dialog); void update(); diff --git a/src/settingsdialognexus.cpp b/src/settingsdialognexus.cpp index 575f54d0..b1964069 100644 --- a/src/settingsdialognexus.cpp +++ b/src/settingsdialognexus.cpp @@ -69,18 +69,18 @@ private: }; -NexusSettingsTab::NexusSettingsTab(Settings *parent, SettingsDialog &dialog) - : SettingsTab(parent, dialog) +NexusSettingsTab::NexusSettingsTab(Settings& s, SettingsDialog& d) + : SettingsTab(s, d) { - ui->offlineBox->setChecked(parent->offlineMode()); - ui->proxyBox->setChecked(parent->useProxy()); - ui->endorsementBox->setChecked(parent->endorsementIntegration()); - ui->hideAPICounterBox->setChecked(parent->hideAPICounter()); + ui->offlineBox->setChecked(settings().offlineMode()); + ui->proxyBox->setChecked(settings().useProxy()); + ui->endorsementBox->setChecked(settings().endorsementIntegration()); + ui->hideAPICounterBox->setChecked(settings().hideAPICounter()); // display server preferences - m_Settings.beginGroup("Servers"); - for (const QString &key : m_Settings.childKeys()) { - QVariantMap val = m_Settings.value(key).toMap(); + qsettings().beginGroup("Servers"); + for (const QString &key : qsettings().childKeys()) { + QVariantMap val = qsettings().value(key).toMap(); QString descriptor = key; if (!descriptor.compare("CDN", Qt::CaseInsensitive)) { descriptor += QStringLiteral(" (automatic)"); @@ -101,7 +101,7 @@ NexusSettingsTab::NexusSettingsTab(Settings *parent, SettingsDialog &dialog) } ui->preferredServersList->sortItems(Qt::DescendingOrder); } - m_Settings.endGroup(); + qsettings().endGroup(); QObject::connect(ui->nexusConnect, &QPushButton::clicked, [&]{ on_nexusConnect_clicked(); }); QObject::connect(ui->nexusManualKey, &QPushButton::clicked, [&]{ on_nexusManualKey_clicked(); }); @@ -114,27 +114,27 @@ NexusSettingsTab::NexusSettingsTab(Settings *parent, SettingsDialog &dialog) void NexusSettingsTab::update() { - m_Settings.setValue("Settings/offline_mode", ui->offlineBox->isChecked()); - m_Settings.setValue("Settings/use_proxy", ui->proxyBox->isChecked()); - m_Settings.setValue("Settings/endorsement_integration", ui->endorsementBox->isChecked()); - m_Settings.setValue("Settings/hide_api_counter", ui->hideAPICounterBox->isChecked()); + qsettings().setValue("Settings/offline_mode", ui->offlineBox->isChecked()); + qsettings().setValue("Settings/use_proxy", ui->proxyBox->isChecked()); + qsettings().setValue("Settings/endorsement_integration", ui->endorsementBox->isChecked()); + qsettings().setValue("Settings/hide_api_counter", ui->hideAPICounterBox->isChecked()); // store server preference - m_Settings.beginGroup("Servers"); + qsettings().beginGroup("Servers"); for (int i = 0; i < ui->knownServersList->count(); ++i) { QString key = ui->knownServersList->item(i)->data(Qt::UserRole).toString(); - QVariantMap val = m_Settings.value(key).toMap(); + QVariantMap val = qsettings().value(key).toMap(); val["preferred"] = 0; - m_Settings.setValue(key, val); + qsettings().setValue(key, val); } int count = ui->preferredServersList->count(); for (int i = 0; i < count; ++i) { QString key = ui->preferredServersList->item(i)->data(Qt::UserRole).toString(); - QVariantMap val = m_Settings.value(key).toMap(); + QVariantMap val = qsettings().value(key).toMap(); val["preferred"] = count - i; - m_Settings.setValue(key, val); + qsettings().setValue(key, val); } - m_Settings.endGroup(); + qsettings().endGroup(); } void NexusSettingsTab::on_nexusConnect_clicked() @@ -168,12 +168,12 @@ void NexusSettingsTab::on_nexusManualKey_clicked() return; } - NexusManualKeyDialog dialog(parentWidget()); - if (dialog.exec() != QDialog::Accepted) { + NexusManualKeyDialog d(&dialog()); + if (d.exec() != QDialog::Accepted) { return; } - const auto key = dialog.key(); + const auto key = d.key(); if (key.isEmpty()) { clearKey(); return; @@ -193,7 +193,7 @@ void NexusSettingsTab::on_nexusDisconnect_clicked() void NexusSettingsTab::on_clearCacheButton_clicked() { QDir(Settings::instance().getCacheDirectory()).removeRecursively(); - NexusInterface::instance(m_dialog.m_PluginContainer)->clearCache(); + NexusInterface::instance(dialog().m_PluginContainer)->clearCache(); } void NexusSettingsTab::on_associateButton_clicked() @@ -205,7 +205,7 @@ void NexusSettingsTab::validateKey(const QString& key) { if (!m_nexusValidator) { m_nexusValidator.reset(new NexusKeyValidator( - *NexusInterface::instance(m_dialog.m_PluginContainer)->getAccessManager())); + *NexusInterface::instance(dialog().m_PluginContainer)->getAccessManager())); m_nexusValidator->stateChanged = [&](auto&& s, auto&& e){ onValidatorStateChanged(s, e); @@ -261,7 +261,7 @@ void NexusSettingsTab::onValidatorStateChanged( void NexusSettingsTab::onValidatorFinished(const APIUserAccount& user) { - NexusInterface::instance(m_dialog.m_PluginContainer)->setUserAccount(user); + NexusInterface::instance(dialog().m_PluginContainer)->setUserAccount(user); if (!user.apiKey().isEmpty()) { if (setKey(user.apiKey())) { @@ -278,18 +278,18 @@ void NexusSettingsTab::addNexusLog(const QString& s) bool NexusSettingsTab::setKey(const QString& key) { - m_dialog.m_keyChanged = true; - const bool ret = m_parent->setNexusApiKey(key); + dialog().m_keyChanged = true; + const bool ret = settings().setNexusApiKey(key); updateNexusState(); return ret; } bool NexusSettingsTab::clearKey() { - m_dialog.m_keyChanged = true; - const auto ret = m_parent->clearNexusApiKey(); + dialog().m_keyChanged = true; + const auto ret = settings().clearNexusApiKey(); - NexusInterface::instance(m_dialog.m_PluginContainer)->getAccessManager()->clearApiKey(); + NexusInterface::instance(dialog().m_PluginContainer)->getAccessManager()->clearApiKey(); updateNexusState(); return ret; @@ -319,7 +319,7 @@ void NexusSettingsTab::updateNexusButtons() ui->nexusManualKey->setText(QObject::tr("Cancel")); ui->nexusManualKey->setEnabled(true); } - else if (m_parent->hasNexusApiKey()) { + else if (settings().hasNexusApiKey()) { // api key is present ui->nexusConnect->setText(QObject::tr("Connect to Nexus")); ui->nexusConnect->setEnabled(false); @@ -338,7 +338,7 @@ void NexusSettingsTab::updateNexusButtons() void NexusSettingsTab::updateNexusData() { - const auto user = NexusInterface::instance(m_dialog.m_PluginContainer) + const auto user = NexusInterface::instance(dialog().m_PluginContainer) ->getAPIUserAccount(); if (user.isValid()) { diff --git a/src/settingsdialognexus.h b/src/settingsdialognexus.h index cca2e1b5..89a6618f 100644 --- a/src/settingsdialognexus.h +++ b/src/settingsdialognexus.h @@ -8,7 +8,7 @@ class NexusSettingsTab : public SettingsTab { public: - NexusSettingsTab(Settings *m_parent, SettingsDialog &m_dialog); + NexusSettingsTab(Settings& settings, SettingsDialog& dialog); void update(); private: diff --git a/src/settingsdialogpaths.cpp b/src/settingsdialogpaths.cpp index 6e8fe994..290ceeb3 100644 --- a/src/settingsdialogpaths.cpp +++ b/src/settingsdialogpaths.cpp @@ -3,19 +3,19 @@ #include "appconfig.h" #include -PathsSettingsTab::PathsSettingsTab(Settings *parent, SettingsDialog &dialog) - : SettingsTab(parent, dialog) +PathsSettingsTab::PathsSettingsTab(Settings& s, SettingsDialog& d) + : SettingsTab(s, d) { - ui->baseDirEdit->setText(m_parent->getBaseDirectory()); - ui->managedGameDirEdit->setText(m_parent->gamePlugin()->gameDirectory().absoluteFilePath(m_parent->gamePlugin()->binaryName())); - QString basePath = parent->getBaseDirectory(); + ui->baseDirEdit->setText(settings().getBaseDirectory()); + ui->managedGameDirEdit->setText(settings().gamePlugin()->gameDirectory().absoluteFilePath(settings().gamePlugin()->binaryName())); + QString basePath = settings().getBaseDirectory(); QDir baseDir(basePath); for (const auto &dir : { - std::make_pair(ui->downloadDirEdit, m_parent->getDownloadDirectory(false)), - std::make_pair(ui->modDirEdit, m_parent->getModDirectory(false)), - std::make_pair(ui->cacheDirEdit, m_parent->getCacheDirectory(false)), - std::make_pair(ui->profilesDirEdit, m_parent->getProfileDirectory(false)), - std::make_pair(ui->overwriteDirEdit, m_parent->getOverwriteDirectory(false)) + std::make_pair(ui->downloadDirEdit, settings().getDownloadDirectory(false)), + std::make_pair(ui->modDirEdit, settings().getModDirectory(false)), + std::make_pair(ui->cacheDirEdit, settings().getCacheDirectory(false)), + std::make_pair(ui->profilesDirEdit, settings().getProfileDirectory(false)), + std::make_pair(ui->overwriteDirEdit, settings().getOverwriteDirectory(false)) }) { QString storePath = baseDir.relativeFilePath(dir.second); storePath = dir.second; @@ -42,7 +42,7 @@ void PathsSettingsTab::update() { typedef std::tuple Directory; - QString basePath = m_parent->getBaseDirectory(); + QString basePath = settings().getBaseDirectory(); for (const Directory &dir :{ Directory{ui->downloadDirEdit->text(), "download_directory", AppConfig::downloadPath()}, @@ -71,30 +71,30 @@ void PathsSettingsTab::update() if (QFileInfo(realPath) != QFileInfo(basePath + "/" + QString::fromStdWString(defaultName))) { - m_Settings.setValue(settingsKey, path); + qsettings().setValue(settingsKey, path); } else { - m_Settings.remove(settingsKey); + qsettings().remove(settingsKey); } } if (QFileInfo(ui->baseDirEdit->text()) != QFileInfo(qApp->property("dataPath").toString())) { - m_Settings.setValue("Settings/base_directory", ui->baseDirEdit->text()); + qsettings().setValue("Settings/base_directory", ui->baseDirEdit->text()); } else { - m_Settings.remove("Settings/base_directory"); + qsettings().remove("Settings/base_directory"); } - QFileInfo oldGameExe(m_parent->gamePlugin()->gameDirectory().absoluteFilePath(m_parent->gamePlugin()->binaryName())); + QFileInfo oldGameExe(settings().gamePlugin()->gameDirectory().absoluteFilePath(settings().gamePlugin()->binaryName())); QFileInfo newGameExe(ui->managedGameDirEdit->text()); if (oldGameExe != newGameExe) { - m_Settings.setValue("gamePath", newGameExe.absolutePath()); + qsettings().setValue("gamePath", newGameExe.absolutePath()); } } void PathsSettingsTab::on_browseBaseDirBtn_clicked() { QString temp = QFileDialog::getExistingDirectory( - parentWidget(), QObject::tr("Select base directory"), ui->baseDirEdit->text()); + &dialog(), QObject::tr("Select base directory"), ui->baseDirEdit->text()); if (!temp.isEmpty()) { ui->baseDirEdit->setText(temp); } @@ -105,7 +105,7 @@ void PathsSettingsTab::on_browseDownloadDirBtn_clicked() QString searchPath = ui->downloadDirEdit->text(); searchPath.replace("%BASE_DIR%", ui->baseDirEdit->text()); - QString temp = QFileDialog::getExistingDirectory(parentWidget(), QObject::tr("Select download directory"), searchPath); + QString temp = QFileDialog::getExistingDirectory(&dialog(), QObject::tr("Select download directory"), searchPath); if (!temp.isEmpty()) { ui->downloadDirEdit->setText(temp); } @@ -116,7 +116,7 @@ void PathsSettingsTab::on_browseModDirBtn_clicked() QString searchPath = ui->modDirEdit->text(); searchPath.replace("%BASE_DIR%", ui->baseDirEdit->text()); - QString temp = QFileDialog::getExistingDirectory(parentWidget(), QObject::tr("Select mod directory"), searchPath); + QString temp = QFileDialog::getExistingDirectory(&dialog(), QObject::tr("Select mod directory"), searchPath); if (!temp.isEmpty()) { ui->modDirEdit->setText(temp); } @@ -127,7 +127,7 @@ void PathsSettingsTab::on_browseCacheDirBtn_clicked() QString searchPath = ui->cacheDirEdit->text(); searchPath.replace("%BASE_DIR%", ui->baseDirEdit->text()); - QString temp = QFileDialog::getExistingDirectory(parentWidget(), QObject::tr("Select cache directory"), searchPath); + QString temp = QFileDialog::getExistingDirectory(&dialog(), QObject::tr("Select cache directory"), searchPath); if (!temp.isEmpty()) { ui->cacheDirEdit->setText(temp); } @@ -138,7 +138,7 @@ void PathsSettingsTab::on_browseProfilesDirBtn_clicked() QString searchPath = ui->profilesDirEdit->text(); searchPath.replace("%BASE_DIR%", ui->baseDirEdit->text()); - QString temp = QFileDialog::getExistingDirectory(parentWidget(), QObject::tr("Select profiles directory"), searchPath); + QString temp = QFileDialog::getExistingDirectory(&dialog(), QObject::tr("Select profiles directory"), searchPath); if (!temp.isEmpty()) { ui->profilesDirEdit->setText(temp); } @@ -149,7 +149,7 @@ void PathsSettingsTab::on_browseOverwriteDirBtn_clicked() QString searchPath = ui->overwriteDirEdit->text(); searchPath.replace("%BASE_DIR%", ui->baseDirEdit->text()); - QString temp = QFileDialog::getExistingDirectory(parentWidget(), QObject::tr("Select overwrite directory"), searchPath); + QString temp = QFileDialog::getExistingDirectory(&dialog(), QObject::tr("Select overwrite directory"), searchPath); if (!temp.isEmpty()) { ui->overwriteDirEdit->setText(temp); } @@ -159,7 +159,7 @@ void PathsSettingsTab::on_browseGameDirBtn_clicked() { QFileInfo oldGameExe(ui->managedGameDirEdit->text()); - QString temp = QFileDialog::getOpenFileName(parentWidget(), QObject::tr("Select game executable"), oldGameExe.absolutePath(), oldGameExe.fileName()); + QString temp = QFileDialog::getOpenFileName(&dialog(), QObject::tr("Select game executable"), oldGameExe.absolutePath(), oldGameExe.fileName()); if (!temp.isEmpty()) { ui->managedGameDirEdit->setText(temp); } diff --git a/src/settingsdialogpaths.h b/src/settingsdialogpaths.h index f661b624..a2073188 100644 --- a/src/settingsdialogpaths.h +++ b/src/settingsdialogpaths.h @@ -7,8 +7,7 @@ class PathsSettingsTab : public SettingsTab { public: - PathsSettingsTab(Settings *parent, SettingsDialog &dialog); - + PathsSettingsTab(Settings& settings, SettingsDialog& dialog); void update(); private: diff --git a/src/settingsdialogplugins.cpp b/src/settingsdialogplugins.cpp index 53b28fcc..329ba301 100644 --- a/src/settingsdialogplugins.cpp +++ b/src/settingsdialogplugins.cpp @@ -5,26 +5,26 @@ using MOBase::IPlugin; -PluginsSettingsTab::PluginsSettingsTab(Settings *m_parent, SettingsDialog &m_dialog) - : SettingsTab(m_parent, m_dialog) +PluginsSettingsTab::PluginsSettingsTab(Settings& s, SettingsDialog& d) + : SettingsTab(s, d) { ui->pluginSettingsList->setStyleSheet("QTreeWidget::item {padding-right: 10px;}"); // display plugin settings QSet handledNames; - for (IPlugin *plugin : m_parent->plugins()) { + for (IPlugin *plugin : settings().plugins()) { if (handledNames.contains(plugin->name())) continue; QListWidgetItem *listItem = new QListWidgetItem(plugin->name(), ui->pluginsList); listItem->setData(Qt::UserRole, QVariant::fromValue((void*)plugin)); - listItem->setData(Qt::UserRole + 1, m_parent->m_PluginSettings[plugin->name()]); - listItem->setData(Qt::UserRole + 2, m_parent->m_PluginDescriptions[plugin->name()]); + listItem->setData(Qt::UserRole + 1, settings().m_PluginSettings[plugin->name()]); + listItem->setData(Qt::UserRole + 2, settings().m_PluginDescriptions[plugin->name()]); ui->pluginsList->addItem(listItem); handledNames.insert(plugin->name()); } // display plugin blacklist - for (const QString &pluginName : m_parent->m_PluginBlacklist) { + for (const QString &pluginName : settings().m_PluginBlacklist) { ui->pluginBlacklist->addItem(pluginName); } @@ -34,7 +34,7 @@ PluginsSettingsTab::PluginsSettingsTab(Settings *m_parent, SettingsDialog &m_dia QShortcut *delShortcut = new QShortcut( QKeySequence(Qt::Key_Delete), ui->pluginBlacklist); - QObject::connect(delShortcut, &QShortcut::activated, parentWidget(), [&]{ deleteBlacklistItem(); }); + QObject::connect(delShortcut, &QShortcut::activated, &dialog(), [&]{ deleteBlacklistItem(); }); } void PluginsSettingsTab::update() @@ -42,21 +42,21 @@ void PluginsSettingsTab::update() // transfer plugin settings to in-memory structure for (int i = 0; i < ui->pluginsList->count(); ++i) { QListWidgetItem *item = ui->pluginsList->item(i); - m_parent->m_PluginSettings[item->text()] = item->data(Qt::UserRole + 1).toMap(); + settings().m_PluginSettings[item->text()] = item->data(Qt::UserRole + 1).toMap(); } // store plugin settings on disc - for (auto iterPlugins = m_parent->m_PluginSettings.begin(); iterPlugins != m_parent->m_PluginSettings.end(); ++iterPlugins) { + for (auto iterPlugins = settings().m_PluginSettings.begin(); iterPlugins != settings().m_PluginSettings.end(); ++iterPlugins) { for (auto iterSettings = iterPlugins->begin(); iterSettings != iterPlugins->end(); ++iterSettings) { - m_Settings.setValue("Plugins/" + iterPlugins.key() + "/" + iterSettings.key(), iterSettings.value()); + qsettings().setValue("Plugins/" + iterPlugins.key() + "/" + iterSettings.key(), iterSettings.value()); } } // store plugin blacklist - m_parent->m_PluginBlacklist.clear(); + settings().m_PluginBlacklist.clear(); for (QListWidgetItem *item : ui->pluginBlacklist->findItems("*", Qt::MatchWildcard)) { - m_parent->m_PluginBlacklist.insert(item->text()); + settings().m_PluginBlacklist.insert(item->text()); } - m_parent->writePluginBlacklist(); + settings().writePluginBlacklist(); } void PluginsSettingsTab::closing() diff --git a/src/settingsdialogplugins.h b/src/settingsdialogplugins.h index 9d21daa6..8e2dae2a 100644 --- a/src/settingsdialogplugins.h +++ b/src/settingsdialogplugins.h @@ -7,7 +7,7 @@ class PluginsSettingsTab : public SettingsTab { public: - PluginsSettingsTab(Settings *m_parent, SettingsDialog &m_dialog); + PluginsSettingsTab(Settings& settings, SettingsDialog& dialog); void update(); void closing() override; diff --git a/src/settingsdialogsteam.cpp b/src/settingsdialogsteam.cpp index 34c2d76b..9ed93e47 100644 --- a/src/settingsdialogsteam.cpp +++ b/src/settingsdialogsteam.cpp @@ -1,11 +1,11 @@ #include "settingsdialogsteam.h" #include "ui_settingsdialog.h" -SteamSettingsTab::SteamSettingsTab(Settings *m_parent, SettingsDialog &m_dialog) - : SettingsTab(m_parent, m_dialog) +SteamSettingsTab::SteamSettingsTab(Settings& s, SettingsDialog& d) + : SettingsTab(s, d) { QString username, password; - m_parent->getSteamLogin(username, password); + settings().getSteamLogin(username, password); ui->steamUserEdit->setText(username); ui->steamPassEdit->setText(password); @@ -13,5 +13,5 @@ SteamSettingsTab::SteamSettingsTab(Settings *m_parent, SettingsDialog &m_dialog) void SteamSettingsTab::update() { - m_parent->setSteamLogin(ui->steamUserEdit->text(), ui->steamPassEdit->text()); + settings().setSteamLogin(ui->steamUserEdit->text(), ui->steamPassEdit->text()); } diff --git a/src/settingsdialogsteam.h b/src/settingsdialogsteam.h index dbd85151..6a3d75f4 100644 --- a/src/settingsdialogsteam.h +++ b/src/settingsdialogsteam.h @@ -7,11 +7,8 @@ class SteamSettingsTab : public SettingsTab { public: - SteamSettingsTab(Settings *m_parent, SettingsDialog &m_dialog); - + SteamSettingsTab(Settings& settings, SettingsDialog& dialog); void update(); - -private: }; #endif // SETTINGSDIALOGSTEAM_H diff --git a/src/settingsdialogworkarounds.cpp b/src/settingsdialogworkarounds.cpp index fc859289..443ba54e 100644 --- a/src/settingsdialogworkarounds.cpp +++ b/src/settingsdialogworkarounds.cpp @@ -3,15 +3,15 @@ #include "helper.h" #include -WorkaroundsSettingsTab::WorkaroundsSettingsTab(Settings *m_parent, SettingsDialog &m_dialog) - : SettingsTab(m_parent, m_dialog) +WorkaroundsSettingsTab::WorkaroundsSettingsTab(Settings& s, SettingsDialog& d) + : SettingsTab(s, d) { - ui->appIDEdit->setText(m_parent->getSteamAppID()); + ui->appIDEdit->setText(settings().getSteamAppID()); - LoadMechanism::EMechanism mechanismID = m_parent->getLoadMechanism(); + LoadMechanism::EMechanism mechanismID = settings().getLoadMechanism(); int index = 0; - if (m_parent->loadMechanism().isDirectLoadingSupported()) { + if (settings().loadMechanism().isDirectLoadingSupported()) { ui->mechanismBox->addItem(QObject::tr("Mod Organizer"), LoadMechanism::LOAD_MODORGANIZER); if (mechanismID == LoadMechanism::LOAD_MODORGANIZER) { index = ui->mechanismBox->count() - 1; @@ -20,13 +20,13 @@ WorkaroundsSettingsTab::WorkaroundsSettingsTab(Settings *m_parent, SettingsDialo ui->mechanismBox->setCurrentIndex(index); - ui->hideUncheckedBox->setChecked(m_parent->hideUncheckedPlugins()); - ui->forceEnableBox->setChecked(m_parent->forceEnableCoreFiles()); - ui->displayForeignBox->setChecked(m_parent->displayForeign()); - ui->lockGUIBox->setChecked(m_parent->lockGUI()); - ui->enableArchiveParsingBox->setChecked(m_parent->archiveParsing()); + ui->hideUncheckedBox->setChecked(settings().hideUncheckedPlugins()); + ui->forceEnableBox->setChecked(settings().forceEnableCoreFiles()); + ui->displayForeignBox->setChecked(settings().displayForeign()); + ui->lockGUIBox->setChecked(settings().lockGUI()); + ui->enableArchiveParsingBox->setChecked(settings().archiveParsing()); - setExecutableBlacklist(m_parent->executablesBlacklist()); + setExecutableBlacklist(settings().executablesBlacklist()); QObject::connect(ui->bsaDateBtn, &QPushButton::clicked, [&]{ on_bsaDateBtn_clicked(); }); QObject::connect(ui->execBlacklistBtn, &QPushButton::clicked, [&]{ on_execBlacklistBtn_clicked(); }); @@ -35,26 +35,26 @@ WorkaroundsSettingsTab::WorkaroundsSettingsTab(Settings *m_parent, SettingsDialo void WorkaroundsSettingsTab::update() { - if (ui->appIDEdit->text() != m_parent->gamePlugin()->steamAPPId()) { - m_Settings.setValue("Settings/app_id", ui->appIDEdit->text()); + if (ui->appIDEdit->text() != settings().gamePlugin()->steamAPPId()) { + qsettings().setValue("Settings/app_id", ui->appIDEdit->text()); } else { - m_Settings.remove("Settings/app_id"); + qsettings().remove("Settings/app_id"); } - m_Settings.setValue("Settings/load_mechanism", ui->mechanismBox->itemData(ui->mechanismBox->currentIndex()).toInt()); - m_Settings.setValue("Settings/hide_unchecked_plugins", ui->hideUncheckedBox->isChecked()); - m_Settings.setValue("Settings/force_enable_core_files", ui->forceEnableBox->isChecked()); - m_Settings.setValue("Settings/display_foreign", ui->displayForeignBox->isChecked()); - m_Settings.setValue("Settings/lock_gui", ui->lockGUIBox->isChecked()); - m_Settings.setValue("Settings/archive_parsing_experimental", ui->enableArchiveParsingBox->isChecked()); + qsettings().setValue("Settings/load_mechanism", ui->mechanismBox->itemData(ui->mechanismBox->currentIndex()).toInt()); + qsettings().setValue("Settings/hide_unchecked_plugins", ui->hideUncheckedBox->isChecked()); + qsettings().setValue("Settings/force_enable_core_files", ui->forceEnableBox->isChecked()); + qsettings().setValue("Settings/display_foreign", ui->displayForeignBox->isChecked()); + qsettings().setValue("Settings/lock_gui", ui->lockGUIBox->isChecked()); + qsettings().setValue("Settings/archive_parsing_experimental", ui->enableArchiveParsingBox->isChecked()); - m_Settings.setValue("Settings/executable_blacklist", getExecutableBlacklist()); + qsettings().setValue("Settings/executable_blacklist", getExecutableBlacklist()); } void WorkaroundsSettingsTab::on_execBlacklistBtn_clicked() { bool ok = false; QString result = QInputDialog::getMultiLineText( - parentWidget(), + &dialog(), QObject::tr("Executables Blacklist"), QObject::tr("Enter one executable per line to be blacklisted from the virtual file system.\n" "Mods and other virtualized files will not be visible to these executables and\n" @@ -96,7 +96,7 @@ void WorkaroundsSettingsTab::on_resetGeometryBtn_clicked() nullptr, caption, text, QMessageBox::Yes | QMessageBox::Cancel); if (res == QMessageBox::Yes) { - m_parent->geometry().requestReset(); + settings().geometry().requestReset(); qApp->exit(INT_MAX); } } diff --git a/src/settingsdialogworkarounds.h b/src/settingsdialogworkarounds.h index 1687624b..d5d6815f 100644 --- a/src/settingsdialogworkarounds.h +++ b/src/settingsdialogworkarounds.h @@ -7,8 +7,7 @@ class WorkaroundsSettingsTab : public SettingsTab { public: - WorkaroundsSettingsTab(Settings *m_parent, SettingsDialog &m_dialog); - + WorkaroundsSettingsTab(Settings& settings, SettingsDialog& dialog); void update(); private: -- cgit v1.3.1 From 8269ac1b489d30ca6065ec2b97542ddbb22298b3 Mon Sep 17 00:00:00 2001 From: isanae <14251494+isanae@users.noreply.github.com> Date: Sat, 5 Oct 2019 13:36:27 -0400 Subject: rework of the nexus key validator to allow multiple attempts before failing --- src/nxmaccessmanager.cpp | 495 ++++++++++++++++++++++++++++++-------------- src/nxmaccessmanager.h | 100 ++++++--- src/settingsdialognexus.cpp | 45 ++-- src/settingsdialognexus.h | 5 +- 4 files changed, 428 insertions(+), 217 deletions(-) (limited to 'src/settingsdialognexus.h') diff --git a/src/nxmaccessmanager.cpp b/src/nxmaccessmanager.cpp index 036b22ff..99b93048 100644 --- a/src/nxmaccessmanager.cpp +++ b/src/nxmaccessmanager.cpp @@ -44,7 +44,6 @@ using namespace MOBase; using namespace std::chrono_literals; const QString NexusBaseUrl("https://api.nexusmods.com/v1"); -const std::chrono::seconds NXMAccessManager::ValidationTimeout = 10s; const QString NexusSSO("wss://sso.nexusmods.com"); const QString NexusSSOPage("https://www.nexusmods.com/sso?id=%1&application=modorganizer2"); @@ -69,6 +68,7 @@ void ValidationProgressDialog::setParentWidget(QWidget* w) if (w && wasVisible) { setVisible(true); + raise(); } } @@ -80,9 +80,7 @@ void ValidationProgressDialog::start() m_updateTimer->setInterval(100ms); } - ui->progress->setRange(0, m_validator.timeout().count()); - ui->progress->setValue(0); - + updateProgress(); m_updateTimer->start(); show(); @@ -123,14 +121,35 @@ void ValidationProgressDialog::onCancel() void ValidationProgressDialog::onTimer() { - ui->progress->setValue(m_validator.elapsed().elapsed() / 1000); + updateProgress(); +} + +void ValidationProgressDialog::updateProgress() +{ + const auto* current = m_validator.currentAttempt(); + + if (current) { + ui->progress->setRange(0, current->timeout().count()); + ui->progress->setValue(current->elapsed().elapsed() / 1000); + } else { + // indeterminate + ui->progress->setRange(0, 0); + } + + if (const auto* a=m_validator.lastAttempt()) { + ui->label->setText(a->message() + ". " + tr("Trying again...")); + } else if (current) { + ui->label->setText(tr("Connecting to Nexus...")); + } else { + ui->label->setText("?"); + } } NexusSSOLogin::NexusSSOLogin() : m_keyReceived(false), m_active(false) { - m_timeout.setInterval(NXMAccessManager::ValidationTimeout); + m_timeout.setInterval(10s); m_timeout.setSingleShot(true); QObject::connect( @@ -167,20 +186,22 @@ QString NexusSSOLogin::stateToString(States s, const QString& e) return QObject::tr("Waiting for Nexus..."); case WaitingForBrowser: - return QObject::tr( - "Opened Nexus in browser.\n" - "Switch to your browser and accept the request."); + return + QObject::tr("Opened Nexus in browser.") + "\n" + + QObject::tr("Switch to your browser and accept the request."); case Finished: return QObject::tr("Finished."); case Timeout: - return QObject::tr( - "No answer from Nexus.\n" - "A firewall might be blocking Mod Organizer."); + return + QObject::tr("No answer from Nexus.") + "\n" + + QObject::tr("A firewall might be blocking Mod Organizer."); case ClosedByRemote: - return QObject::tr("Nexus closed the connection."); + return + QObject::tr("Nexus closed the connection.") + "\n" + + QObject::tr("A firewall might be blocking Mod Organizer."); case Cancelled: return QObject::tr("Cancelled."); @@ -300,10 +321,11 @@ void NexusSSOLogin::onMessage(const QString& s) void NexusSSOLogin::onDisconnected() { if (m_active) { - m_active = false; - if (!m_keyReceived) { + close(); setState(ClosedByRemote); + } else { + m_active = false; } } } @@ -332,84 +354,48 @@ void NexusSSOLogin::onTimeout() } -NexusKeyValidator::NexusKeyValidator(NXMAccessManager& am) - : m_manager(am), m_reply(nullptr), m_active(false) +ValidationAttempt::ValidationAttempt(std::chrono::seconds timeout) + : m_reply(nullptr), m_result(None) { - m_timeout.setInterval(NXMAccessManager::ValidationTimeout); m_timeout.setSingleShot(true); + m_timeout.setInterval(timeout); QObject::connect(&m_timeout, &QTimer::timeout, [&]{ onTimeout(); }); } -NexusKeyValidator::~NexusKeyValidator() -{ - abort(); -} - -QString NexusKeyValidator::stateToString(States s, const QString& e) -{ - switch (s) - { - case NexusKeyValidator::Connecting: - return QObject::tr("Connecting to Nexus..."); - - case NexusKeyValidator::Finished: - return QObject::tr("Finished."); - - case NexusKeyValidator::InvalidJson: - return QObject::tr("Invalid JSON"); - - case NexusKeyValidator::BadResponse: - return QObject::tr("Bad response"); - - case NexusKeyValidator::Timeout: - return QObject::tr("There was a timeout during the request"); - - case NexusKeyValidator::Cancelled: - return QObject::tr("Cancelled"); - - case NexusKeyValidator::Error: // fall-through - default: - { - if (e.isEmpty()) { - return QString("%1").arg(s); - } else { - return e; - } - } - } -} - -void NexusKeyValidator::start(const QString& key) +void ValidationAttempt::start(NXMAccessManager& m, const QString& key) { - if (m_reply) { - abort(); + if (!sendRequest(m, key)) { return; } - m_active = true; - setState(Connecting); m_elapsed.start(); + m_timeout.start(); + + log::debug( + "validator: attempt started with timeout of {} seconds", timeout().count()); +} +bool ValidationAttempt::sendRequest( + NXMAccessManager& m, const QString& key) +{ const QString requestUrl(NexusBaseUrl + "/users/validate"); QNetworkRequest request(requestUrl); request.setRawHeader("APIKEY", key.toUtf8()); - request.setHeader(QNetworkRequest::KnownHeaders::UserAgentHeader, m_manager.userAgent().toUtf8()); + request.setHeader(QNetworkRequest::KnownHeaders::UserAgentHeader, m.userAgent().toUtf8()); request.setHeader(QNetworkRequest::KnownHeaders::ContentTypeHeader, "application/json"); request.setRawHeader("Protocol-Version", "1.0.0"); request.setRawHeader("Application-Name", "MO2"); - request.setRawHeader("Application-Version", m_manager.MOVersion().toUtf8()); + request.setRawHeader("Application-Version", m.MOVersion().toUtf8()); + + m_reply = m.get(request); - m_reply = m_manager.get(request); if (!m_reply) { - close(); - setState(Error, QObject::tr("Failed to request %1").arg(requestUrl)); - return; + setFailure(SoftError, QObject::tr("Failed to request %1").arg(requestUrl)); + return false; } - m_timeout.start(NXMAccessManager::ValidationTimeout); - QObject::connect( m_reply, &QNetworkReply::finished, [&]{ onFinished(); }); @@ -417,93 +403,114 @@ void NexusKeyValidator::start(const QString& key) QObject::connect( m_reply, &QNetworkReply::sslErrors, [&](auto&& errors){ onSslErrors(errors); }); + + return true; } -void NexusKeyValidator::cancel() +void ValidationAttempt::cancel() { - if (m_active) { - abort(); - setState(Cancelled); + if (!m_reply || m_result != None) { + // not running + return; } + + setFailure(Cancelled, QObject::tr("Cancelled")); + + if (m_reply) { + m_reply->abort(); + } + + cleanup(); } -bool NexusKeyValidator::isActive() const +bool ValidationAttempt::done() const { - return m_active; + return (m_result != None); } -QElapsedTimer NexusKeyValidator::elapsed() const +ValidationAttempt::Result ValidationAttempt::result() const { - return m_elapsed; + return m_result; } -std::chrono::seconds NexusKeyValidator::timeout() const +const QString& ValidationAttempt::message() const { - return NXMAccessManager::ValidationTimeout; + return m_message; } -void NexusKeyValidator::close() +std::chrono::seconds ValidationAttempt::timeout() const { - m_active = false; - m_timeout.stop(); - - if (m_reply) { - m_reply->disconnect(); - m_reply->deleteLater(); - m_reply = nullptr; - } + return std::chrono::duration_cast( + m_timeout.intervalAsDuration()); } -void NexusKeyValidator::abort() +QElapsedTimer ValidationAttempt::elapsed() const { - m_active = false; - m_timeout.stop(); - - if (m_reply) { - m_reply->disconnect(); - m_reply->abort(); - m_reply->deleteLater(); - m_reply = nullptr; - } + return m_elapsed; } -void NexusKeyValidator::setState(States s, const QString& error) +void ValidationAttempt::onFinished() { - if (stateChanged) { - stateChanged(s, error); + if (m_result == Cancelled) { + return; } -} -void NexusKeyValidator::onFinished() -{ + log::debug("validator attempt: request has finished"); + if (!m_reply) { // shouldn't happen + log::error("validator attempt: reply is null"); + setFailure(HardError, QObject::tr("Internal error")); return; } - m_timeout.stop(); + const auto code = m_reply->attribute( + QNetworkRequest::HttpStatusCodeAttribute).toInt(); + + if (code == 0) { + // request wasn't even sent + log::error("validator attempt: code is 0"); + setFailure(SoftError, m_reply->errorString()); + return; + } - const auto code = m_reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(); const auto doc = QJsonDocument::fromJson(m_reply->readAll()); const auto headers = m_reply->rawHeaderPairs(); - const auto error = m_reply->errorString(); - - close(); + const auto httpError = m_reply->errorString(); const QJsonObject data = doc.object(); if (code != 200) { - handleError(code, data.value("message").toString(), error); + // http request failed + + QString s = m_reply->errorString(); + + const auto nexusMessage = data.value("message").toString(); + if (!nexusMessage.isEmpty()) { + if (!s.isEmpty()) { + s += ", "; + } + + s += nexusMessage; + } + + if (s.isEmpty()) { + s = QObject::tr("HTTP code %1").arg(code); + } else { + s += QString(" (%1)").arg(code); + } + + setFailure(SoftError, s); return; } if (doc.isNull()) { - setState(InvalidJson); + setFailure(HardError, QObject::tr("Invalid JSON")); return; } if (!data.contains("user_id")) { - setState(BadResponse); + setFailure(HardError, QObject::tr("Bad response")); return; } @@ -512,6 +519,11 @@ void NexusKeyValidator::onFinished() const QString name = data.value("name").toString(); const bool premium = data.value("is_premium").toBool(); + if (key.isEmpty()) { + setFailure(HardError, QObject::tr("API key is empty")); + return; + } + const auto user = APIUserAccount() .apiKey(key) .id(QString("%1").arg(id)) @@ -519,51 +531,218 @@ void NexusKeyValidator::onFinished() .type(premium ? APIUserAccountTypes::Premium : APIUserAccountTypes::Regular) .limits(NexusInterface::parseLimits(headers)); - if (finished) { - setState(Finished); - finished(user); + setSuccess(user); +} + +void ValidationAttempt::onSslErrors(const QList& errors) +{ + log::error("validator attempt: ssl errors"); + + for (auto& e : errors) { + log::error(" . {}", e.errorString()); } + + setFailure(HardError, QObject::tr("SSL error")); } -void NexusKeyValidator::onSslErrors(const QList& errors) +void ValidationAttempt::onTimeout() { - if (m_active) { - for (const auto& e : errors) { - setState(Error, e.errorString()); - } + setFailure(SoftError, QObject::tr("Timed out")); +} + +void ValidationAttempt::setFailure(Result r, const QString& error) +{ + if (r != Cancelled) { + // don't spam the log + log::error("validator attempt: {}", error); + } + + cleanup(); + + m_result = r; + m_message = error; + + if (failure) { + failure(); } } -void NexusKeyValidator::onTimeout() +void ValidationAttempt::setSuccess(const APIUserAccount& user) +{ + log::debug("validator attempt successful"); + cleanup(); + + m_result = Success; + m_message = ""; + + if (success) { + success(user); + } +} + +void ValidationAttempt::cleanup() +{ + m_timeout.stop(); + + if (m_reply) { + m_reply->disconnect(); + m_reply->deleteLater(); + m_reply = nullptr; + } +} + + +NexusKeyValidator::NexusKeyValidator(NXMAccessManager& am) + : m_manager(am) { - abort(); - setState(Timeout); } -void NexusKeyValidator::handleError( - int code, const QString& nexusMessage, const QString& httpError) +NexusKeyValidator::~NexusKeyValidator() { - QString s = httpError; + cancel(); +} - if (!nexusMessage.isEmpty()) { - if (!s.isEmpty()) { - s += ", "; +void NexusKeyValidator::start(const QString& key, Behaviour b) +{ + if (isActive()) { + log::debug("validator: trying to start while ongoing; ignoring"); + return; + } + + m_key = key; + + switch (b) + { + case OneShot: + { + createAttempts({10s}); + break; } - s += nexusMessage; + case Retry: + { + createAttempts({5s, 5s, 10s}); + break; + } } - if (code != 0) { - if (s.isEmpty()) { - s = QString("HTTP code %1").arg(code); + nextTry(); +} + +void NexusKeyValidator::createAttempts( + const std::vector& timeouts) +{ + m_attempts.clear(); + + for (auto&& t : timeouts) { + m_attempts.push_back(std::make_unique(t)); + } +} + +void NexusKeyValidator::cancel() +{ + log::debug("validator: cancelled"); + + for (auto&& a : m_attempts) { + a->cancel(); + } +} + +bool NexusKeyValidator::isActive() const +{ + for (auto&& a : m_attempts) { + if (!a->done()) { + return true; + } + } + + return false; +} + +const ValidationAttempt* NexusKeyValidator::lastAttempt() const +{ + const ValidationAttempt* last = nullptr; + + for (auto&& a : m_attempts) { + if (a->done()) { + last = a.get(); } else { - s += QString(" (%1)").arg(code); + break; } } - setState(Error, s); + return last; } +const ValidationAttempt* NexusKeyValidator::currentAttempt() const +{ + for (auto&& a : m_attempts) { + if (!a->done()) { + return a.get(); + } + } + + return nullptr; +} + +bool NexusKeyValidator::nextTry() +{ + for (auto&& a : m_attempts) { + if (!a->done()) { + a->success = [&](auto&& user){ onAttemptSuccess(*a, user); }; + a->failure = [&]{ onAttemptFailure(*a); }; + + a->start(m_manager, m_key); + return true; + } + } + + // no more + return false; +} + +void NexusKeyValidator::onAttemptSuccess( + const ValidationAttempt&, const APIUserAccount& u) +{ + setFinished(ValidationAttempt::Success, "", u); +} + +void NexusKeyValidator::onAttemptFailure(const ValidationAttempt& a) +{ + switch (a.result()) + { + case ValidationAttempt::SoftError: + { + if (!nextTry()) { + setFinished(a.result(), a.message(), {}); + } + + break; + } + + case ValidationAttempt::HardError: + { + cancel(); + setFinished(a.result(), a.message(), {}); + break; + } + + case ValidationAttempt::Cancelled: + { + setFinished(ValidationAttempt::Cancelled, QObject::tr("Cancelled"), {}); + break; + } + } +} + +void NexusKeyValidator::setFinished( + ValidationAttempt::Result r, const QString& message, + std::optional user) +{ + if (finished) { + finished(r, message, user); + } +} NXMAccessManager::NXMAccessManager(QObject *parent, const QString &moVersion) @@ -572,8 +751,9 @@ NXMAccessManager::NXMAccessManager(QObject *parent, const QString &moVersion) , m_validator(*this) , m_validationState(NotChecked) { - m_validator.stateChanged = [&](auto&& s, auto&& e){ onValidatorState(s, e); }; - m_validator.finished = [&](auto&& user){ onValidatorFinished(user); }; + m_validator.finished = [&](auto&& r, auto&& m, auto&& u) { + onValidatorFinished(r, m, u); + }; setCookieJar(new PersistentCookieJar(QDir::fromNativeSeparators( Settings::instance().paths().cache() + "/nexus_cookies.dat"))); @@ -587,7 +767,9 @@ NXMAccessManager::NXMAccessManager(QObject *parent, const QString &moVersion) void NXMAccessManager::setTopLevelWidget(QWidget* w) { if (w) { - m_ProgressDialog->setParentWidget(w); + if (m_ProgressDialog) { + m_ProgressDialog->setParentWidget(w); + } } else { m_ProgressDialog.reset(); m_validator.cancel(); @@ -637,37 +819,30 @@ void NXMAccessManager::clearCookies() void NXMAccessManager::startValidationCheck(const QString& key) { m_validationState = NotChecked; - m_validator.start(key); + m_validator.start(key, NexusKeyValidator::Retry); startProgress(); } -void NXMAccessManager::onValidatorState( - NexusKeyValidator::States s, const QString& e) +void NXMAccessManager::onValidatorFinished( + ValidationAttempt::Result r, const QString& message, + std::optional user) { - if (s == NexusKeyValidator::Connecting || s == NexusKeyValidator::Finished) { - // no-op, success is handled in onValidatorFinished() - return; - } - stopProgress(); - if (s == NexusKeyValidator::Cancelled) { - m_validationState = NotChecked; + if (user) { + m_validationState = Valid; + emit credentialsReceived(*user); + emit validateSuccessful(true); } else { - m_validationState = Invalid; - emit validateFailed(NexusKeyValidator::stateToString(s, e)); + if (r == ValidationAttempt::Cancelled) { + m_validationState = NotChecked; + } else { + m_validationState = Invalid; + emit validateFailed(message); + } } } -void NXMAccessManager::onValidatorFinished(const APIUserAccount& user) -{ - stopProgress(); - - m_validationState = Valid; - emit credentialsReceived(user); - emit validateSuccessful(true); -} - bool NXMAccessManager::validated() const { if (m_validator.isActive()) { diff --git a/src/nxmaccessmanager.h b/src/nxmaccessmanager.h index f0bdd8a6..b0ea45e7 100644 --- a/src/nxmaccessmanager.h +++ b/src/nxmaccessmanager.h @@ -82,53 +82,93 @@ private: }; -class NexusKeyValidator +class ValidationAttempt { public: - enum States + enum Result { - Connecting, - Finished, - InvalidJson, - BadResponse, - Timeout, - Cancelled, - Error + None, + Success, + SoftError, + HardError, + Cancelled }; - std::function finished; - std::function stateChanged; - - static QString stateToString(States s, const QString& e); + std::function success; + std::function failure; - NexusKeyValidator(NXMAccessManager& am); - ~NexusKeyValidator(); + ValidationAttempt(std::chrono::seconds timeout); + ValidationAttempt(const ValidationAttempt&) = delete; + ValidationAttempt& operator=(const ValidationAttempt&) = delete; - void start(const QString& key); + void start(NXMAccessManager& m, const QString& key); void cancel(); - bool isActive() const; - QElapsedTimer elapsed() const; + bool done() const; + Result result() const; + const QString& message() const; std::chrono::seconds timeout() const; + QElapsedTimer elapsed() const; private: - NXMAccessManager& m_manager; QNetworkReply* m_reply; + Result m_result; + QString m_message; QTimer m_timeout; - bool m_active; QElapsedTimer m_elapsed; - void setState(States s, const QString& error={}); - - void close(); - void abort(); + bool sendRequest(NXMAccessManager& m, const QString& key); void onFinished(); void onSslErrors(const QList& errors); void onTimeout(); - void handleError( - int code, const QString& nexusMessage, const QString& httpError); + void setFailure(Result r, const QString& error); + void setSuccess(const APIUserAccount& user); + + void cleanup(); +}; + + +class NexusKeyValidator +{ +public: + enum Behaviour + { + OneShot = 0, + Retry + }; + + using FinishedCallback = void ( + ValidationAttempt::Result, const QString&, + std::optional); + + std::function finished; + + NexusKeyValidator(NXMAccessManager& am); + ~NexusKeyValidator(); + + void start(const QString& key, Behaviour b); + void cancel(); + + bool isActive() const; + const ValidationAttempt* lastAttempt() const; + const ValidationAttempt* currentAttempt() const; + +private: + NXMAccessManager& m_manager; + QString m_key; + std::vector> m_attempts; + + void createAttempts(const std::vector& timeouts); + + bool nextTry(); + void onAttemptSuccess(const ValidationAttempt& a, const APIUserAccount& u); + void onAttemptFailure(const ValidationAttempt& a); + + void setFinished( + ValidationAttempt::Result r, const QString& message, + std::optional user); }; @@ -157,6 +197,7 @@ private: void onHide(); void onCancel(); void onTimer(); + void updateProgress(); }; @@ -167,8 +208,6 @@ class NXMAccessManager : public QNetworkAccessManager { Q_OBJECT public: - static const std::chrono::seconds ValidationTimeout; - NXMAccessManager(QObject *parent, const QString &moVersion); void setTopLevelWidget(QWidget* w); @@ -230,8 +269,9 @@ private: States m_validationState; void startValidationCheck(const QString& key); - void onValidatorState(NexusKeyValidator::States s, const QString& e); - void onValidatorFinished(const APIUserAccount& user); + void onValidatorFinished( + ValidationAttempt::Result r, const QString& message, + std::optional); void startProgress(); void stopProgress(); diff --git a/src/settingsdialognexus.cpp b/src/settingsdialognexus.cpp index 2021bdc1..209ed661 100644 --- a/src/settingsdialognexus.cpp +++ b/src/settingsdialognexus.cpp @@ -240,17 +240,13 @@ void NexusSettingsTab::validateKey(const QString& key) m_nexusValidator.reset(new NexusKeyValidator( *NexusInterface::instance(dialog().pluginContainer())->getAccessManager())); - m_nexusValidator->stateChanged = [&](auto&& s, auto&& e){ - onValidatorStateChanged(s, e); - }; - - m_nexusValidator->finished = [&](auto&& user) { - onValidatorFinished(user); + m_nexusValidator->finished = [&](auto&& r, auto&& m, auto&& u) { + onValidatorFinished(r, m, u); }; } addNexusLog(QObject::tr("Checking API key...")); - m_nexusValidator->start(key); + m_nexusValidator->start(key, NexusKeyValidator::OneShot); } void NexusSettingsTab::onSSOKeyChanged(const QString& key) @@ -277,32 +273,31 @@ void NexusSettingsTab::onSSOStateChanged(NexusSSOLogin::States s, const QString& updateNexusState(); } -void NexusSettingsTab::onValidatorStateChanged( - NexusKeyValidator::States s, const QString& e) +void NexusSettingsTab::onValidatorFinished( + ValidationAttempt::Result r, const QString& message, + std::optional user) { - if (s != NexusKeyValidator::Finished) { - // finished state is handled in onValidatorFinished() - const auto log = NexusKeyValidator::stateToString(s, e); + if (user) { + NexusInterface::instance(dialog().pluginContainer())->setUserAccount(*user); + addNexusLog(QObject::tr("Received user acount information")); - for (auto&& line : log.split("\n")) { - addNexusLog(line); + if (setKey(user->apiKey())) { + addNexusLog(QObject::tr("Linked with Nexus successfully.")); + } else { + addNexusLog(QObject::tr("Failed to set API key")); + } + } else { + if (message.isEmpty()) { + // shouldn't happen + addNexusLog("Unknown error"); + } else { + addNexusLog(message); } } updateNexusState(); } -void NexusSettingsTab::onValidatorFinished(const APIUserAccount& user) -{ - NexusInterface::instance(dialog().pluginContainer())->setUserAccount(user); - - if (!user.apiKey().isEmpty()) { - if (setKey(user.apiKey())) { - addNexusLog(QObject::tr("Linked with Nexus successfully.")); - } - } -} - void NexusSettingsTab::addNexusLog(const QString& s) { ui->nexusLog->addItem(s); diff --git a/src/settingsdialognexus.h b/src/settingsdialognexus.h index 89a6618f..2cb1cc1e 100644 --- a/src/settingsdialognexus.h +++ b/src/settingsdialognexus.h @@ -32,8 +32,9 @@ private: void onSSOKeyChanged(const QString& key); void onSSOStateChanged(NexusSSOLogin::States s, const QString& e); - void onValidatorStateChanged(NexusKeyValidator::States s, const QString& e); - void onValidatorFinished(const APIUserAccount& user); + void onValidatorFinished( + ValidationAttempt::Result r, const QString& message, + std::optional useR); void addNexusLog(const QString& s); }; -- cgit v1.3.1