achievementlogindialog.cpp (5223B)
1 // SPDX-FileCopyrightText: 2019-2023 Connor McLaughlin <stenzek@gmail.com> 2 // SPDX-License-Identifier: (GPL-3.0 OR CC-BY-NC-ND-4.0) 3 4 #include "achievementlogindialog.h" 5 #include "qthost.h" 6 7 #include "core/achievements.h" 8 9 #include "common/error.h" 10 11 #include <QtWidgets/QMessageBox> 12 13 AchievementLoginDialog::AchievementLoginDialog(QWidget* parent, Achievements::LoginRequestReason reason) 14 : QDialog(parent), m_reason(reason) 15 { 16 m_ui.setupUi(this); 17 setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint); 18 19 // Adjust text if needed based on reason. 20 if (reason == Achievements::LoginRequestReason::TokenInvalid) 21 { 22 m_ui.instructionText->setText(tr("<strong>Your RetroAchievements login token is no longer valid.</strong> You must " 23 "re-enter your credentials for achievements to be tracked. Your password will not " 24 "be saved in DuckStation, an access token will be generated and used instead.")); 25 } 26 27 m_login = m_ui.buttonBox->addButton(tr("&Login"), QDialogButtonBox::AcceptRole); 28 m_login->setEnabled(false); 29 connectUi(); 30 } 31 32 AchievementLoginDialog::~AchievementLoginDialog() = default; 33 34 void AchievementLoginDialog::loginClicked() 35 { 36 const QString username(m_ui.userName->text()); 37 const QString password(m_ui.password->text()); 38 39 // TODO: Make cancellable. 40 m_ui.status->setText(tr("Logging in...")); 41 enableUI(false); 42 43 Host::RunOnCPUThread([this, username, password]() { 44 Error error; 45 const bool result = Achievements::Login(username.toUtf8().constData(), password.toUtf8().constData(), &error); 46 const QString message = QString::fromStdString(error.GetDescription()); 47 QMetaObject::invokeMethod(this, "processLoginResult", Qt::QueuedConnection, Q_ARG(bool, result), 48 Q_ARG(const QString&, message)); 49 }); 50 } 51 52 void AchievementLoginDialog::cancelClicked() 53 { 54 // Disable hardcore mode if we cancelled reauthentication. 55 if (m_reason == Achievements::LoginRequestReason::TokenInvalid && QtHost::IsSystemValid()) 56 { 57 Host::RunOnCPUThread([]() { 58 if (System::IsValid() && !Achievements::HasActiveGame()) 59 Achievements::DisableHardcoreMode(); 60 }); 61 } 62 63 done(1); 64 } 65 66 void AchievementLoginDialog::processLoginResult(bool result, const QString& message) 67 { 68 if (!result) 69 { 70 QMessageBox::critical( 71 this, tr("Login Error"), 72 tr("Login failed.\nError: %1\n\nPlease check your username and password, and try again.").arg(message)); 73 m_ui.status->setText(tr("Login failed.")); 74 enableUI(true); 75 return; 76 } 77 78 if (!Host::GetBaseBoolSettingValue("Cheevos", "Enabled", false) && 79 QMessageBox::question(this, tr("Enable Achievements"), 80 tr("Achievement tracking is not currently enabled. Your login will have no effect until " 81 "after tracking is enabled.\n\nDo you want to enable tracking now?"), 82 QMessageBox::Yes, QMessageBox::No) == QMessageBox::Yes) 83 { 84 Host::SetBaseBoolSettingValue("Cheevos", "Enabled", true); 85 Host::CommitBaseSettingChanges(); 86 g_emu_thread->applySettings(); 87 } 88 89 if (!Host::GetBaseBoolSettingValue("Cheevos", "ChallengeMode", false) && 90 QMessageBox::question( 91 this, tr("Enable Hardcore Mode"), 92 tr("Hardcore mode is not currently enabled. Enabling hardcore mode allows you to set times, scores, and " 93 "participate in game-specific leaderboards.\n\nHowever, hardcore mode also prevents the usage of save " 94 "states, cheats and slowdown functionality.\n\nDo you want to enable hardcore mode?"), 95 QMessageBox::Yes, QMessageBox::No) == QMessageBox::Yes) 96 { 97 Host::SetBaseBoolSettingValue("Cheevos", "ChallengeMode", true); 98 Host::CommitBaseSettingChanges(); 99 g_emu_thread->applySettings(); 100 101 bool has_active_game; 102 { 103 auto lock = Achievements::GetLock(); 104 has_active_game = Achievements::HasActiveGame(); 105 } 106 107 if (has_active_game && 108 QMessageBox::question( 109 QtUtils::GetRootWidget(this), tr("Reset System"), 110 tr("Hardcore mode will not be enabled until the system is reset. Do you want to reset the system now?")) == 111 QMessageBox::Yes) 112 { 113 g_emu_thread->resetSystem(true); 114 } 115 } 116 117 done(0); 118 } 119 120 void AchievementLoginDialog::connectUi() 121 { 122 connect(m_ui.buttonBox, &QDialogButtonBox::accepted, this, &AchievementLoginDialog::loginClicked); 123 connect(m_ui.buttonBox, &QDialogButtonBox::rejected, this, &AchievementLoginDialog::cancelClicked); 124 125 auto enableLoginButton = [this](const QString&) { m_login->setEnabled(canEnableLoginButton()); }; 126 connect(m_ui.userName, &QLineEdit::textChanged, enableLoginButton); 127 connect(m_ui.password, &QLineEdit::textChanged, enableLoginButton); 128 } 129 130 void AchievementLoginDialog::enableUI(bool enabled) 131 { 132 m_ui.userName->setEnabled(enabled); 133 m_ui.password->setEnabled(enabled); 134 m_ui.buttonBox->button(QDialogButtonBox::Cancel)->setEnabled(enabled); 135 m_login->setEnabled(enabled && canEnableLoginButton()); 136 } 137 138 bool AchievementLoginDialog::canEnableLoginButton() const 139 { 140 return !m_ui.userName->text().isEmpty() && !m_ui.password->text().isEmpty(); 141 }