diff options
| author | isanae <14251494+isanae@users.noreply.github.com> | 2019-07-20 09:31:38 -0400 |
|---|---|---|
| committer | isanae <14251494+isanae@users.noreply.github.com> | 2019-08-02 03:06:58 -0400 |
| commit | af95b3b8637d28517f69a70f13b901cc7f43d121 (patch) | |
| tree | 5ff6113611c85b5aabebdf5805d7f93e67a48fb5 /src | |
| parent | 0a5ce34b1a80694fbfe6a4d6b4f032b9c11a5376 (diff) | |
renamed tab classes, clashing with mod info dialog
split nexus tab
Diffstat (limited to 'src')
| -rw-r--r-- | src/CMakeLists.txt | 3 | ||||
| -rw-r--r-- | src/settings.cpp | 114 | ||||
| -rw-r--r-- | src/settings.h | 16 | ||||
| -rw-r--r-- | src/settingsdialog.cpp | 278 | ||||
| -rw-r--r-- | src/settingsdialog.h | 34 | ||||
| -rw-r--r-- | src/settingsdialoggeneral.cpp | 30 | ||||
| -rw-r--r-- | src/settingsdialoggeneral.h | 4 | ||||
| -rw-r--r-- | src/settingsdialognexus.cpp | 374 | ||||
| -rw-r--r-- | src/settingsdialognexus.h | 40 | ||||
| -rw-r--r-- | src/settingsdialogpaths.cpp | 32 | ||||
| -rw-r--r-- | src/settingsdialogpaths.h | 4 |
11 files changed, 460 insertions, 469 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 98d59996..b2407e17 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -38,6 +38,7 @@ SET(organizer_SRCS singleinstance.cpp settingsdialog.cpp settingsdialoggeneral.cpp + settingsdialognexus.cpp settingsdialogpaths.cpp settings.cpp selfupdater.cpp @@ -154,6 +155,7 @@ SET(organizer_HDRS singleinstance.h settingsdialog.h settingsdialoggeneral.h + settingsdialognexus.h settingsdialogpaths.h settings.h selfupdater.h @@ -436,6 +438,7 @@ set(settings settings settingsdialog settingsdialoggeneral + settingsdialognexus settingsdialogpaths ) diff --git a/src/settings.cpp b/src/settings.cpp index bed8e789..bded470c 100644 --- a/src/settings.cpp +++ b/src/settings.cpp @@ -23,6 +23,7 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>. #include "serverinfo.h" #include "settingsdialog.h" #include "settingsdialoggeneral.h" +#include "settingsdialognexus.h" #include "settingsdialogpaths.h" #include "versioninfo.h" #include "appconfig.h" @@ -69,19 +70,6 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>. using namespace MOBase; -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; -}; - SettingsTab::SettingsTab(Settings *m_parent, SettingsDialog &m_dialog) : m_parent(m_parent) @@ -688,10 +676,10 @@ void Settings::query(PluginContainer *pluginContainer, QWidget *parent) std::vector<std::unique_ptr<SettingsTab>> tabs; - tabs.push_back(std::unique_ptr<SettingsTab>(new GeneralTab(this, dialog))); - tabs.push_back(std::unique_ptr<SettingsTab>(new PathsTab(this, dialog))); + tabs.push_back(std::unique_ptr<SettingsTab>(new GeneralSettingsTab(this, dialog))); + tabs.push_back(std::unique_ptr<SettingsTab>(new PathsSettingsTab(this, dialog))); tabs.push_back(std::unique_ptr<SettingsTab>(new DiagnosticsTab(this, dialog))); - tabs.push_back(std::unique_ptr<SettingsTab>(new NexusTab(this, dialog))); + tabs.push_back(std::unique_ptr<SettingsTab>(new NexusSettingsTab(this, dialog))); tabs.push_back(std::unique_ptr<SettingsTab>(new SteamTab(this, dialog))); tabs.push_back(std::unique_ptr<SettingsTab>(new PluginsTab(this, dialog))); tabs.push_back(std::unique_ptr<SettingsTab>(new WorkaroundsTab(this, dialog))); @@ -781,100 +769,6 @@ void Settings::DiagnosticsTab::update() m_Settings.setValue("Settings/crash_dumps_max", m_dumpsMaxEdit->value()); } -void Settings::DiagnosticsTab::setLevelsBox() -{ - m_logLevelBox->clear(); - - m_logLevelBox->addItem(tr("Debug"), log::Debug); - m_logLevelBox->addItem(tr("Info (recommended)"), log::Info); - m_logLevelBox->addItem(tr("Warning"), log::Warning); - m_logLevelBox->addItem(tr("Error"), log::Error); - - for (int i=0; i<m_logLevelBox->count(); ++i) { - if (m_logLevelBox->itemData(i) == m_parent->logLevel()) { - m_logLevelBox->setCurrentIndex(i); - break; - } - } -} - -Settings::NexusTab::NexusTab(Settings *parent, SettingsDialog &dialog) - : SettingsTab(parent, dialog) - , m_offlineBox(dialog.findChild<QCheckBox *>("offlineBox")) - , m_proxyBox(dialog.findChild<QCheckBox *>("proxyBox")) - , m_knownServersList(dialog.findChild<QListWidget *>("knownServersList")) - , m_preferredServersList( - dialog.findChild<QListWidget *>("preferredServersList")) - , m_endorsementBox(dialog.findChild<QCheckBox *>("endorsementBox")) - , m_hideAPICounterBox(dialog.findChild<QCheckBox *>("hideAPICounterBox")) -{ - m_offlineBox->setChecked(parent->offlineMode()); - m_proxyBox->setChecked(parent->useProxy()); - m_endorsementBox->setChecked(parent->endorsementIntegration()); - m_hideAPICounterBox->setChecked(parent->hideAPICounter()); - - // display server preferences - m_Settings.beginGroup("Servers"); - for (const QString &key : m_Settings.childKeys()) { - QVariantMap val = m_Settings.value(key).toMap(); - QString descriptor = key; - if (!descriptor.compare("CDN", Qt::CaseInsensitive)) { - descriptor += QStringLiteral(" (automatic)"); - } - 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) { - m_preferredServersList->addItem(newItem); - } else { - m_knownServersList->addItem(newItem); - } - m_preferredServersList->sortItems(Qt::DescendingOrder); - } - m_Settings.endGroup(); -} - -void Settings::NexusTab::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", m_offlineBox->isChecked()); - m_Settings.setValue("Settings/use_proxy", m_proxyBox->isChecked()); - m_Settings.setValue("Settings/endorsement_integration", m_endorsementBox->isChecked()); - m_Settings.setValue("Settings/hide_api_counter", m_hideAPICounterBox->isChecked()); - - // store server preference - m_Settings.beginGroup("Servers"); - for (int i = 0; i < m_knownServersList->count(); ++i) { - QString key = m_knownServersList->item(i)->data(Qt::UserRole).toString(); - QVariantMap val = m_Settings.value(key).toMap(); - val["preferred"] = 0; - m_Settings.setValue(key, val); - } - int count = m_preferredServersList->count(); - for (int i = 0; i < count; ++i) { - QString key = m_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(); -} Settings::SteamTab::SteamTab(Settings *m_parent, SettingsDialog &m_dialog) : SettingsTab(m_parent, m_dialog) diff --git a/src/settings.h b/src/settings.h index 6f75562b..b9383ce4 100644 --- a/src/settings.h +++ b/src/settings.h @@ -461,22 +461,6 @@ private: void setLevelsBox(); }; - /** Display/store the configuration in the 'nexus' tab of the settings dialogue */ - class NexusTab : public SettingsTab - { - public: - NexusTab(Settings *m_parent, SettingsDialog &m_dialog); - void update(); - - private: - QCheckBox *m_offlineBox; - QCheckBox *m_proxyBox; - QListWidget *m_knownServersList; - QListWidget *m_preferredServersList; - QCheckBox *m_endorsementBox; - QCheckBox *m_hideAPICounterBox; - }; - /** Display/store the configuration in the 'steam' tab of the settings dialogue */ class SteamTab : public SettingsTab { diff --git a/src/settingsdialog.cpp b/src/settingsdialog.cpp index bfa285bf..6d5a8cc0 100644 --- a/src/settingsdialog.cpp +++ b/src/settingsdialog.cpp @@ -20,7 +20,6 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>. #include "settingsdialog.h" #include "ui_settingsdialog.h" -#include "ui_nexusmanualkey.h" #include "categoriesdialog.h" #include "helper.h" #include "noeditdelegate.h" @@ -48,62 +47,14 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>. using namespace MOBase; -class NexusManualKeyDialog : public QDialog -{ -public: - NexusManualKeyDialog(QWidget* parent) - : QDialog(parent), ui(new Ui::NexusManualKeyDialog) - { - ui->setupUi(this); - ui->key->setFont(QFontDatabase::systemFont(QFontDatabase::FixedFont)); - - connect(ui->openBrowser, &QPushButton::clicked, [&]{ openBrowser(); }); - connect(ui->paste, &QPushButton::clicked, [&]{ paste(); }); - connect(ui->clear, &QPushButton::clicked, [&]{ clear(); }); - } - - void accept() override - { - m_key = ui->key->toPlainText(); - QDialog::accept(); - } - - const QString& key() const - { - return m_key; - } - - void openBrowser() - { - shell::OpenLink(QUrl("https://www.nexusmods.com/users/myaccount?tab=api")); - } - - void paste() - { - const auto text = QApplication::clipboard()->text(); - if (!text.isEmpty()) { - ui->key->setPlainText(text); - } - } - - void clear() - { - ui->key->clear(); - } - -private: - std::unique_ptr<Ui::NexusManualKeyDialog> ui; - QString m_key; -}; - SettingsDialog::SettingsDialog(PluginContainer *pluginContainer, Settings* settings, QWidget *parent) : TutorableDialog("SettingsDialog", parent) , ui(new Ui::SettingsDialog) , m_settings(settings) , m_PluginContainer(pluginContainer) - , m_keyChanged(false) , m_GeometriesReset(false) + , m_keyChanged(false) { ui->setupUi(this); ui->pluginSettingsList->setStyleSheet("QTreeWidget::item {padding-right: 10px;}"); @@ -111,8 +62,6 @@ SettingsDialog::SettingsDialog(PluginContainer *pluginContainer, Settings* setti QShortcut *delShortcut = new QShortcut( QKeySequence(Qt::Key_Delete), ui->pluginBlacklist); connect(delShortcut, SIGNAL(activated()), this, SLOT(deleteBlacklistItem())); - - updateNexusState(); } SettingsDialog::~SettingsDialog() @@ -200,220 +149,6 @@ void SettingsDialog::on_bsaDateBtn_clicked() dir.absolutePath().toStdWString()); } -void SettingsDialog::on_nexusConnect_clicked() -{ - if (m_nexusLogin && m_nexusLogin->isActive()) { - m_nexusLogin->cancel(); - return; - } - - if (!m_nexusLogin) { - m_nexusLogin.reset(new NexusSSOLogin); - - m_nexusLogin->keyChanged = [&](auto&& s){ - onSSOKeyChanged(s); - }; - - m_nexusLogin->stateChanged = [&](auto&& s, auto&& e){ - onSSOStateChanged(s, e); - }; - } - - ui->nexusLog->clear(); - m_nexusLogin->start(); - updateNexusState(); -} - -void SettingsDialog::on_nexusManualKey_clicked() -{ - if (m_nexusValidator && m_nexusValidator->isActive()) { - m_nexusValidator->cancel(); - return; - } - - NexusManualKeyDialog dialog(this); - if (dialog.exec() != QDialog::Accepted) { - return; - } - - const auto key = dialog.key(); - if (key.isEmpty()) { - clearKey(); - return; - } - - ui->nexusLog->clear(); - validateKey(key); -} - -void SettingsDialog::on_nexusDisconnect_clicked() -{ - clearKey(); - ui->nexusLog->clear(); - addNexusLog(tr("Disconnected.")); -} - -void SettingsDialog::validateKey(const QString& key) -{ - if (!m_nexusValidator) { - m_nexusValidator.reset(new NexusKeyValidator( - *NexusInterface::instance(m_PluginContainer)->getAccessManager())); - - m_nexusValidator->stateChanged = [&](auto&& s, auto&& e){ - onValidatorStateChanged(s, e); - }; - - m_nexusValidator->finished = [&](auto&& user) { - onValidatorFinished(user); - }; - } - - addNexusLog(tr("Checking API key...")); - m_nexusValidator->start(key); -} - -void SettingsDialog::onSSOKeyChanged(const QString& key) -{ - if (key.isEmpty()) { - clearKey(); - } else { - addNexusLog(tr("Received API key.")); - validateKey(key); - } -} - -void SettingsDialog::onSSOStateChanged(NexusSSOLogin::States s, const QString& e) -{ - if (s != NexusSSOLogin::Finished) { - // finished state is handled in onSSOKeyChanged() - const auto log = NexusSSOLogin::stateToString(s, e); - - for (auto&& line : log.split("\n")) { - addNexusLog(line); - } - } - - updateNexusState(); -} - -void SettingsDialog::onValidatorStateChanged( - NexusKeyValidator::States s, const QString& e) -{ - if (s != NexusKeyValidator::Finished) { - // finished state is handled in onValidatorFinished() - const auto log = NexusKeyValidator::stateToString(s, e); - - for (auto&& line : log.split("\n")) { - addNexusLog(line); - } - } - - updateNexusState(); -} - -void SettingsDialog::onValidatorFinished(const APIUserAccount& user) -{ - NexusInterface::instance(m_PluginContainer)->setUserAccount(user); - - if (!user.apiKey().isEmpty()) { - if (setKey(user.apiKey())) { - addNexusLog(tr("Linked with Nexus successfully.")); - } - } -} - -void SettingsDialog::addNexusLog(const QString& s) -{ - ui->nexusLog->addItem(s); - ui->nexusLog->scrollToBottom(); -} - -bool SettingsDialog::setKey(const QString& key) -{ - m_keyChanged = true; - const bool ret = m_settings->setNexusApiKey(key); - updateNexusState(); - return ret; -} - -bool SettingsDialog::clearKey() -{ - m_keyChanged = true; - const auto ret = m_settings->clearNexusApiKey(); - - NexusInterface::instance(m_PluginContainer)->getAccessManager()->clearApiKey(); - updateNexusState(); - - return ret; -} - -void SettingsDialog::updateNexusState() -{ - updateNexusButtons(); - updateNexusData(); -} - -void SettingsDialog::updateNexusButtons() -{ - if (m_nexusLogin && m_nexusLogin->isActive()) { - // api key is in the process of being retrieved - ui->nexusConnect->setText(tr("Cancel")); - ui->nexusConnect->setEnabled(true); - ui->nexusDisconnect->setEnabled(false); - ui->nexusManualKey->setText(tr("Enter API Key Manually")); - ui->nexusManualKey->setEnabled(false); - } - else if (m_nexusValidator && m_nexusValidator->isActive()) { - // api key is in the process of being tested - ui->nexusConnect->setText(tr("Connect to Nexus")); - ui->nexusConnect->setEnabled(false); - ui->nexusDisconnect->setEnabled(false); - ui->nexusManualKey->setText(tr("Cancel")); - ui->nexusManualKey->setEnabled(true); - } - else if (m_settings->hasNexusApiKey()) { - // api key is present - ui->nexusConnect->setText(tr("Connect to Nexus")); - ui->nexusConnect->setEnabled(false); - ui->nexusDisconnect->setEnabled(true); - ui->nexusManualKey->setText(tr("Enter API Key Manually")); - ui->nexusManualKey->setEnabled(false); - } else { - // api key not present - ui->nexusConnect->setText(tr("Connect to Nexus")); - ui->nexusConnect->setEnabled(true); - ui->nexusDisconnect->setEnabled(false); - ui->nexusManualKey->setText(tr("Enter API Key Manually")); - ui->nexusManualKey->setEnabled(true); - } -} - -void SettingsDialog::updateNexusData() -{ - const auto user = NexusInterface::instance(m_PluginContainer) - ->getAPIUserAccount(); - - if (user.isValid()) { - ui->nexusUserID->setText(user.id()); - ui->nexusName->setText(user.name()); - ui->nexusAccount->setText(localizedUserAccountType(user.type())); - - ui->nexusDailyRequests->setText(QString("%1/%2") - .arg(user.limits().remainingDailyRequests) - .arg(user.limits().maxDailyRequests)); - - ui->nexusHourlyRequests->setText(QString("%1/%2") - .arg(user.limits().remainingHourlyRequests) - .arg(user.limits().maxHourlyRequests)); - } else { - ui->nexusUserID->setText(tr("N/A")); - ui->nexusName->setText(tr("N/A")); - ui->nexusAccount->setText(tr("N/A")); - ui->nexusDailyRequests->setText(tr("N/A")); - ui->nexusHourlyRequests->setText(tr("N/A")); - } -} - void SettingsDialog::storeSettings(QListWidgetItem *pluginItem) { if (pluginItem != nullptr) { @@ -470,17 +205,6 @@ void SettingsDialog::deleteBlacklistItem() ui->pluginBlacklist->takeItem(ui->pluginBlacklist->currentIndex().row()); } -void SettingsDialog::on_associateButton_clicked() -{ - Settings::instance().registerAsNXMHandler(true); -} - -void SettingsDialog::on_clearCacheButton_clicked() -{ - QDir(Settings::instance().getCacheDirectory()).removeRecursively(); - NexusInterface::instance(m_PluginContainer)->clearCache(); -} - void SettingsDialog::on_resetGeometryBtn_clicked() { m_GeometriesReset = true; diff --git a/src/settingsdialog.h b/src/settingsdialog.h index 68e72529..df5d0ad8 100644 --- a/src/settingsdialog.h +++ b/src/settingsdialog.h @@ -54,18 +54,15 @@ public: */ QString getColoredButtonStyleSheet() const; + // temp Ui::SettingsDialog *ui; + bool m_keyChanged; + PluginContainer *m_PluginContainer; public slots: - virtual void accept(); -signals: - - void retryApiConnection(); - private: - void storeSettings(QListWidgetItem *pluginItem); public: @@ -75,13 +72,8 @@ public: bool getApiKeyChanged(); private slots: - void on_associateButton_clicked(); void on_bsaDateBtn_clicked(); - void on_clearCacheButton_clicked(); void on_execBlacklistBtn_clicked(); - void on_nexusConnect_clicked(); - void on_nexusDisconnect_clicked(); - void on_nexusManualKey_clicked(); void on_pluginsList_currentItemChanged(QListWidgetItem *current, QListWidgetItem *previous); void on_resetGeometryBtn_clicked(); @@ -89,30 +81,10 @@ private slots: private: Settings* m_settings; - PluginContainer *m_PluginContainer; bool m_GeometriesReset; - bool m_keyChanged; QString m_ExecutableBlacklist; - std::unique_ptr<NexusSSOLogin> m_nexusLogin; - std::unique_ptr<NexusKeyValidator> m_nexusValidator; - - 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 // SETTINGSDIALOG_H diff --git a/src/settingsdialoggeneral.cpp b/src/settingsdialoggeneral.cpp index b22b04fd..cd98dfdc 100644 --- a/src/settingsdialoggeneral.cpp +++ b/src/settingsdialoggeneral.cpp @@ -6,7 +6,7 @@ using MOBase::QuestionBoxMemory; -GeneralTab::GeneralTab(Settings *m_parent, SettingsDialog &m_dialog) +GeneralSettingsTab::GeneralSettingsTab(Settings *m_parent, SettingsDialog &m_dialog) : SettingsTab(m_parent, m_dialog) { addLanguages(); @@ -87,7 +87,7 @@ GeneralTab::GeneralTab(Settings *m_parent, SettingsDialog &m_dialog) QObject::connect(ui->resetDialogsButton, &QPushButton::clicked, [&]{ on_resetDialogsButton_clicked(); }); } -void GeneralTab::update() +void GeneralSettingsTab::update() { QString oldLanguage = m_parent->language(); QString newLanguage = ui->languageBox->itemData(ui->languageBox->currentIndex()).toString(); @@ -115,7 +115,7 @@ void GeneralTab::update() m_Settings.setValue("Settings/colorSeparatorScrollbars", ui->colorSeparatorsBox->isChecked()); } -void GeneralTab::addLanguages() +void GeneralSettingsTab::addLanguages() { std::vector<std::pair<QString, QString>> languages; @@ -150,7 +150,7 @@ void GeneralTab::addLanguages() } } -void GeneralTab::addStyles() +void GeneralSettingsTab::addStyles() { ui->styleBox->addItem("None", ""); ui->styleBox->addItem("Fusion", "Fusion"); @@ -163,12 +163,12 @@ void GeneralTab::addStyles() } } -void GeneralTab::resetDialogs() +void GeneralSettingsTab::resetDialogs() { QuestionBoxMemory::resetDialogs(); } -void GeneralTab::setButtonColor(QPushButton *button, const QColor &color) +void GeneralSettingsTab::setButtonColor(QPushButton *button, const QColor &color) { button->setStyleSheet( QString("QPushButton {" @@ -185,7 +185,7 @@ void GeneralTab::setButtonColor(QPushButton *button, const QColor &color) ); }; -void GeneralTab::on_containsBtn_clicked() +void GeneralSettingsTab::on_containsBtn_clicked() { QColor result = QColorDialog::getColor(m_ContainsColor, parentWidget(), "Color Picker: Mod contains selected plugin", QColorDialog::ShowAlphaChannel); if (result.isValid()) { @@ -194,7 +194,7 @@ void GeneralTab::on_containsBtn_clicked() } } -void GeneralTab::on_containedBtn_clicked() +void GeneralSettingsTab::on_containedBtn_clicked() { QColor result = QColorDialog::getColor(m_ContainedColor, parentWidget(), "ColorPicker: Plugin is Contained in selected Mod", QColorDialog::ShowAlphaChannel); if (result.isValid()) { @@ -203,7 +203,7 @@ void GeneralTab::on_containedBtn_clicked() } } -void GeneralTab::on_overwrittenBtn_clicked() +void GeneralSettingsTab::on_overwrittenBtn_clicked() { QColor result = QColorDialog::getColor(m_OverwrittenColor, parentWidget(), "ColorPicker: Is overwritten (loose files)", QColorDialog::ShowAlphaChannel); if (result.isValid()) { @@ -212,7 +212,7 @@ void GeneralTab::on_overwrittenBtn_clicked() } } -void GeneralTab::on_overwritingBtn_clicked() +void GeneralSettingsTab::on_overwritingBtn_clicked() { QColor result = QColorDialog::getColor(m_OverwritingColor, parentWidget(), "ColorPicker: Is overwriting (loose files)", QColorDialog::ShowAlphaChannel); if (result.isValid()) { @@ -221,7 +221,7 @@ void GeneralTab::on_overwritingBtn_clicked() } } -void GeneralTab::on_overwrittenArchiveBtn_clicked() +void GeneralSettingsTab::on_overwrittenArchiveBtn_clicked() { QColor result = QColorDialog::getColor(m_OverwrittenArchiveColor, parentWidget(), "ColorPicker: Is overwritten (archive files)", QColorDialog::ShowAlphaChannel); if (result.isValid()) { @@ -230,7 +230,7 @@ void GeneralTab::on_overwrittenArchiveBtn_clicked() } } -void GeneralTab::on_overwritingArchiveBtn_clicked() +void GeneralSettingsTab::on_overwritingArchiveBtn_clicked() { QColor result = QColorDialog::getColor(m_OverwritingArchiveColor, parentWidget(), "ColorPicker: Is overwriting (archive files)", QColorDialog::ShowAlphaChannel); if (result.isValid()) { @@ -239,7 +239,7 @@ void GeneralTab::on_overwritingArchiveBtn_clicked() } } -void GeneralTab::on_resetColorsBtn_clicked() +void GeneralSettingsTab::on_resetColorsBtn_clicked() { m_OverwritingColor = QColor(255, 0, 0, 64); m_OverwrittenColor = QColor(0, 255, 0, 64); @@ -256,7 +256,7 @@ void GeneralTab::on_resetColorsBtn_clicked() setButtonColor(ui->containedBtn, m_ContainedColor); } -void GeneralTab::on_resetDialogsButton_clicked() +void GeneralSettingsTab::on_resetDialogsButton_clicked() { if (QMessageBox::question(parentWidget(), QObject::tr("Confirm?"), QObject::tr("This will make all dialogs show up again where you checked the \"Remember selection\"-box. Continue?"), @@ -265,7 +265,7 @@ void GeneralTab::on_resetDialogsButton_clicked() } } -void GeneralTab::on_categoriesBtn_clicked() +void GeneralSettingsTab::on_categoriesBtn_clicked() { CategoriesDialog dialog(parentWidget()); if (dialog.exec() == QDialog::Accepted) { diff --git a/src/settingsdialoggeneral.h b/src/settingsdialoggeneral.h index 1f1b4637..c7fcae36 100644 --- a/src/settingsdialoggeneral.h +++ b/src/settingsdialoggeneral.h @@ -4,10 +4,10 @@ #include "settingsdialog.h" #include "settings.h" -class GeneralTab : public SettingsTab +class GeneralSettingsTab : public SettingsTab { public: - GeneralTab(Settings *m_parent, SettingsDialog &m_dialog); + GeneralSettingsTab(Settings *m_parent, SettingsDialog &m_dialog); void update(); diff --git a/src/settingsdialognexus.cpp b/src/settingsdialognexus.cpp new file mode 100644 index 00000000..7d4414fd --- /dev/null +++ b/src/settingsdialognexus.cpp @@ -0,0 +1,374 @@ +#include "settingsdialognexus.h" +#include "ui_settingsdialog.h" +#include "ui_nexusmanualkey.h" +#include "nexusinterface.h" +#include <utility.h> + +namespace shell = MOBase::shell; + +template <typename T> +class ServerItem : public QListWidgetItem { +public: + ServerItem(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; +}; + + +class NexusManualKeyDialog : public QDialog +{ +public: + NexusManualKeyDialog(QWidget* parent) + : QDialog(parent), ui(new Ui::NexusManualKeyDialog) + { + ui->setupUi(this); + ui->key->setFont(QFontDatabase::systemFont(QFontDatabase::FixedFont)); + + connect(ui->openBrowser, &QPushButton::clicked, [&]{ openBrowser(); }); + connect(ui->paste, &QPushButton::clicked, [&]{ paste(); }); + connect(ui->clear, &QPushButton::clicked, [&]{ clear(); }); + } + + void accept() override + { + m_key = ui->key->toPlainText(); + QDialog::accept(); + } + + const QString& key() const + { + return m_key; + } + + void openBrowser() + { + shell::OpenLink(QUrl("https://www.nexusmods.com/users/myaccount?tab=api")); + } + + void paste() + { + const auto text = QApplication::clipboard()->text(); + if (!text.isEmpty()) { + ui->key->setPlainText(text); + } + } + + void clear() + { + ui->key->clear(); + } + +private: + std::unique_ptr<Ui::NexusManualKeyDialog> ui; + QString m_key; +}; + + +NexusSettingsTab::NexusSettingsTab(Settings *parent, SettingsDialog &dialog) + : SettingsTab(parent, dialog) +{ + ui->offlineBox->setChecked(parent->offlineMode()); + ui->proxyBox->setChecked(parent->useProxy()); + ui->endorsementBox->setChecked(parent->endorsementIntegration()); + ui->hideAPICounterBox->setChecked(parent->hideAPICounter()); + + // display server preferences + m_Settings.beginGroup("Servers"); + for (const QString &key : m_Settings.childKeys()) { + QVariantMap val = m_Settings.value(key).toMap(); + QString descriptor = key; + if (!descriptor.compare("CDN", Qt::CaseInsensitive)) { + descriptor += QStringLiteral(" (automatic)"); + } + 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 ServerItem<int>(descriptor, Qt::UserRole + 1); + + newItem->setData(Qt::UserRole, key); + newItem->setData(Qt::UserRole + 1, val["preferred"].toInt()); + if (val["preferred"].toInt() > 0) { + ui->preferredServersList->addItem(newItem); + } else { + ui->knownServersList->addItem(newItem); + } + ui->preferredServersList->sortItems(Qt::DescendingOrder); + } + m_Settings.endGroup(); + + QObject::connect(ui->nexusConnect, &QPushButton::clicked, [&]{ on_nexusConnect_clicked(); }); + QObject::connect(ui->nexusManualKey, &QPushButton::clicked, [&]{ on_nexusManualKey_clicked(); }); + QObject::connect(ui->nexusDisconnect, &QPushButton::clicked, [&]{ on_nexusDisconnect_clicked(); }); + QObject::connect(ui->clearCacheButton, &QPushButton::clicked, [&]{ on_clearCacheButton_clicked(); }); + QObject::connect(ui->associateButton, &QPushButton::clicked, [&]{ on_associateButton_clicked(); }); + + updateNexusState(); +} + +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()); + m_Settings.setValue("Settings/hide_api_counter", ui->hideAPICounterBox->isChecked()); + + // store server preference + m_Settings.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(); + val["preferred"] = 0; + m_Settings.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(); + val["preferred"] = count - i; + m_Settings.setValue(key, val); + } + m_Settings.endGroup(); +} + +void NexusSettingsTab::on_nexusConnect_clicked() +{ + if (m_nexusLogin && m_nexusLogin->isActive()) { + m_nexusLogin->cancel(); + return; + } + + if (!m_nexusLogin) { + m_nexusLogin.reset(new NexusSSOLogin); + + m_nexusLogin->keyChanged = [&](auto&& s){ + onSSOKeyChanged(s); + }; + + m_nexusLogin->stateChanged = [&](auto&& s, auto&& e){ + onSSOStateChanged(s, e); + }; + } + + ui->nexusLog->clear(); + m_nexusLogin->start(); + updateNexusState(); +} + +void NexusSettingsTab::on_nexusManualKey_clicked() +{ + if (m_nexusValidator && m_nexusValidator->isActive()) { + m_nexusValidator->cancel(); + return; + } + + NexusManualKeyDialog dialog(parentWidget()); + if (dialog.exec() != QDialog::Accepted) { + return; + } + + const auto key = dialog.key(); + if (key.isEmpty()) { + clearKey(); + return; + } + + ui->nexusLog->clear(); + validateKey(key); +} + +void NexusSettingsTab::on_nexusDisconnect_clicked() +{ + clearKey(); + ui->nexusLog->clear(); + addNexusLog(QObject::tr("Disconnected.")); +} + +void NexusSettingsTab::on_clearCacheButton_clicked() +{ + QDir(Settings::instance().getCacheDirectory()).removeRecursively(); + NexusInterface::instance(m_dialog.m_PluginContainer)->clearCache(); +} + +void NexusSettingsTab::on_associateButton_clicked() +{ + Settings::instance().registerAsNXMHandler(true); +} + +void NexusSettingsTab::validateKey(const QString& key) +{ + if (!m_nexusValidator) { + m_nexusValidator.reset(new NexusKeyValidator( + *NexusInterface::instance(m_dialog.m_PluginContainer)->getAccessManager())); + + m_nexusValidator->stateChanged = [&](auto&& s, auto&& e){ + onValidatorStateChanged(s, e); + }; + + m_nexusValidator->finished = [&](auto&& user) { + onValidatorFinished(user); + }; + } + + addNexusLog(QObject::tr("Checking API key...")); + m_nexusValidator->start(key); +} + +void NexusSettingsTab::onSSOKeyChanged(const QString& key) +{ + if (key.isEmpty()) { + clearKey(); + } else { + addNexusLog(QObject::tr("Received API key.")); + validateKey(key); + } +} + +void NexusSettingsTab::onSSOStateChanged(NexusSSOLogin::States s, const QString& e) +{ + if (s != NexusSSOLogin::Finished) { + // finished state is handled in onSSOKeyChanged() + const auto log = NexusSSOLogin::stateToString(s, e); + + for (auto&& line : log.split("\n")) { + addNexusLog(line); + } + } + + updateNexusState(); +} + +void NexusSettingsTab::onValidatorStateChanged( + NexusKeyValidator::States s, const QString& e) +{ + if (s != NexusKeyValidator::Finished) { + // finished state is handled in onValidatorFinished() + const auto log = NexusKeyValidator::stateToString(s, e); + + for (auto&& line : log.split("\n")) { + addNexusLog(line); + } + } + + updateNexusState(); +} + +void NexusSettingsTab::onValidatorFinished(const APIUserAccount& user) +{ + NexusInterface::instance(m_dialog.m_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); + ui->nexusLog->scrollToBottom(); +} + +bool NexusSettingsTab::setKey(const QString& key) +{ + m_dialog.m_keyChanged = true; + const bool ret = m_parent->setNexusApiKey(key); + updateNexusState(); + return ret; +} + +bool NexusSettingsTab::clearKey() +{ + m_dialog.m_keyChanged = true; + const auto ret = m_parent->clearNexusApiKey(); + + NexusInterface::instance(m_dialog.m_PluginContainer)->getAccessManager()->clearApiKey(); + updateNexusState(); + + return ret; +} + +void NexusSettingsTab::updateNexusState() +{ + updateNexusButtons(); + updateNexusData(); +} + +void NexusSettingsTab::updateNexusButtons() +{ + if (m_nexusLogin && m_nexusLogin->isActive()) { + // api key is in the process of being retrieved + ui->nexusConnect->setText(QObject::tr("Cancel")); + ui->nexusConnect->setEnabled(true); + ui->nexusDisconnect->setEnabled(false); + ui->nexusManualKey->setText(QObject::tr("Enter API Key Manually")); + ui->nexusManualKey->setEnabled(false); + } + else if (m_nexusValidator && m_nexusValidator->isActive()) { + // api key is in the process of being tested + ui->nexusConnect->setText(QObject::tr("Connect to Nexus")); + ui->nexusConnect->setEnabled(false); + ui->nexusDisconnect->setEnabled(false); + ui->nexusManualKey->setText(QObject::tr("Cancel")); + ui->nexusManualKey->setEnabled(true); + } + else if (m_parent->hasNexusApiKey()) { + // api key is present + ui->nexusConnect->setText(QObject::tr("Connect to Nexus")); + ui->nexusConnect->setEnabled(false); + ui->nexusDisconnect->setEnabled(true); + ui->nexusManualKey->setText(QObject::tr("Enter API Key Manually")); + ui->nexusManualKey->setEnabled(false); + } else { + // api key not present + ui->nexusConnect->setText(QObject::tr("Connect to Nexus")); + ui->nexusConnect->setEnabled(true); + ui->nexusDisconnect->setEnabled(false); + ui->nexusManualKey->setText(QObject::tr("Enter API Key Manually")); + ui->nexusManualKey->setEnabled(true); + } +} + +void NexusSettingsTab::updateNexusData() +{ + const auto user = NexusInterface::instance(m_dialog.m_PluginContainer) + ->getAPIUserAccount(); + + if (user.isValid()) { + ui->nexusUserID->setText(user.id()); + ui->nexusName->setText(user.name()); + ui->nexusAccount->setText(localizedUserAccountType(user.type())); + + ui->nexusDailyRequests->setText(QString("%1/%2") + .arg(user.limits().remainingDailyRequests) + .arg(user.limits().maxDailyRequests)); + + ui->nexusHourlyRequests->setText(QString("%1/%2") + .arg(user.limits().remainingHourlyRequests) + .arg(user.limits().maxHourlyRequests)); + } else { + ui->nexusUserID->setText(QObject::tr("N/A")); + ui->nexusName->setText(QObject::tr("N/A")); + ui->nexusAccount->setText(QObject::tr("N/A")); + ui->nexusDailyRequests->setText(QObject::tr("N/A")); + ui->nexusHourlyRequests->setText(QObject::tr("N/A")); + } +} 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<NexusSSOLogin> m_nexusLogin; + std::unique_ptr<NexusKeyValidator> 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 diff --git a/src/settingsdialogpaths.cpp b/src/settingsdialogpaths.cpp index 303d1562..6e8fe994 100644 --- a/src/settingsdialogpaths.cpp +++ b/src/settingsdialogpaths.cpp @@ -3,7 +3,7 @@ #include "appconfig.h" #include <iplugingame.h> -PathsTab::PathsTab(Settings *parent, SettingsDialog &dialog) +PathsSettingsTab::PathsSettingsTab(Settings *parent, SettingsDialog &dialog) : SettingsTab(parent, dialog) { ui->baseDirEdit->setText(m_parent->getBaseDirectory()); @@ -38,7 +38,7 @@ PathsTab::PathsTab(Settings *parent, SettingsDialog &dialog) QObject::connect(ui->profilesDirEdit, &QLineEdit::editingFinished, [&]{ on_profilesDirEdit_editingFinished(); }); } -void PathsTab::update() +void PathsSettingsTab::update() { typedef std::tuple<QString, QString, std::wstring> Directory; @@ -91,7 +91,7 @@ void PathsTab::update() } } -void PathsTab::on_browseBaseDirBtn_clicked() +void PathsSettingsTab::on_browseBaseDirBtn_clicked() { QString temp = QFileDialog::getExistingDirectory( parentWidget(), QObject::tr("Select base directory"), ui->baseDirEdit->text()); @@ -100,7 +100,7 @@ void PathsTab::on_browseBaseDirBtn_clicked() } } -void PathsTab::on_browseDownloadDirBtn_clicked() +void PathsSettingsTab::on_browseDownloadDirBtn_clicked() { QString searchPath = ui->downloadDirEdit->text(); searchPath.replace("%BASE_DIR%", ui->baseDirEdit->text()); @@ -111,7 +111,7 @@ void PathsTab::on_browseDownloadDirBtn_clicked() } } -void PathsTab::on_browseModDirBtn_clicked() +void PathsSettingsTab::on_browseModDirBtn_clicked() { QString searchPath = ui->modDirEdit->text(); searchPath.replace("%BASE_DIR%", ui->baseDirEdit->text()); @@ -122,7 +122,7 @@ void PathsTab::on_browseModDirBtn_clicked() } } -void PathsTab::on_browseCacheDirBtn_clicked() +void PathsSettingsTab::on_browseCacheDirBtn_clicked() { QString searchPath = ui->cacheDirEdit->text(); searchPath.replace("%BASE_DIR%", ui->baseDirEdit->text()); @@ -133,7 +133,7 @@ void PathsTab::on_browseCacheDirBtn_clicked() } } -void PathsTab::on_browseProfilesDirBtn_clicked() +void PathsSettingsTab::on_browseProfilesDirBtn_clicked() { QString searchPath = ui->profilesDirEdit->text(); searchPath.replace("%BASE_DIR%", ui->baseDirEdit->text()); @@ -144,7 +144,7 @@ void PathsTab::on_browseProfilesDirBtn_clicked() } } -void PathsTab::on_browseOverwriteDirBtn_clicked() +void PathsSettingsTab::on_browseOverwriteDirBtn_clicked() { QString searchPath = ui->overwriteDirEdit->text(); searchPath.replace("%BASE_DIR%", ui->baseDirEdit->text()); @@ -155,7 +155,7 @@ void PathsTab::on_browseOverwriteDirBtn_clicked() } } -void PathsTab::on_browseGameDirBtn_clicked() +void PathsSettingsTab::on_browseGameDirBtn_clicked() { QFileInfo oldGameExe(ui->managedGameDirEdit->text()); @@ -165,37 +165,37 @@ void PathsTab::on_browseGameDirBtn_clicked() } } -void PathsTab::on_baseDirEdit_editingFinished() +void PathsSettingsTab::on_baseDirEdit_editingFinished() { normalizePath(ui->baseDirEdit); } -void PathsTab::on_downloadDirEdit_editingFinished() +void PathsSettingsTab::on_downloadDirEdit_editingFinished() { normalizePath(ui->downloadDirEdit); } -void PathsTab::on_modDirEdit_editingFinished() +void PathsSettingsTab::on_modDirEdit_editingFinished() { normalizePath(ui->modDirEdit); } -void PathsTab::on_cacheDirEdit_editingFinished() +void PathsSettingsTab::on_cacheDirEdit_editingFinished() { normalizePath(ui->cacheDirEdit); } -void PathsTab::on_profilesDirEdit_editingFinished() +void PathsSettingsTab::on_profilesDirEdit_editingFinished() { normalizePath(ui->profilesDirEdit); } -void PathsTab::on_overwriteDirEdit_editingFinished() +void PathsSettingsTab::on_overwriteDirEdit_editingFinished() { normalizePath(ui->overwriteDirEdit); } -void PathsTab::normalizePath(QLineEdit *lineEdit) +void PathsSettingsTab::normalizePath(QLineEdit *lineEdit) { QString text = lineEdit->text(); while (text.endsWith('/') || text.endsWith('\\')) { diff --git a/src/settingsdialogpaths.h b/src/settingsdialogpaths.h index dac402b1..f661b624 100644 --- a/src/settingsdialogpaths.h +++ b/src/settingsdialogpaths.h @@ -4,10 +4,10 @@ #include "settings.h" #include "settingsdialog.h" -class PathsTab : public SettingsTab +class PathsSettingsTab : public SettingsTab { public: - PathsTab(Settings *parent, SettingsDialog &dialog); + PathsSettingsTab(Settings *parent, SettingsDialog &dialog); void update(); |
