From a4c5f0135ef8e3671f54cf56b1aa8766ee4b4a20 Mon Sep 17 00:00:00 2001 From: Andrew Date: Wed, 27 Nov 2013 16:14:18 -0600 Subject: [PATCH] Allow setting no default account This allows the user to select an account to use every time they launch an instance. --- CMakeLists.txt | 3 + gui/MainWindow.cpp | 25 ++++---- gui/dialogs/AccountListDialog.cpp | 28 ++++++++- gui/dialogs/AccountListDialog.h | 7 ++- gui/dialogs/AccountListDialog.ui | 14 ++++- gui/dialogs/AccountSelectDialog.cpp | 89 ++++++++++++++++++++++++++++ gui/dialogs/AccountSelectDialog.h | 90 +++++++++++++++++++++++++++++ gui/dialogs/AccountSelectDialog.ui | 56 ++++++++++++++++++ logic/lists/MojangAccountList.cpp | 13 ++++- logic/lists/MojangAccountList.h | 1 + 10 files changed, 308 insertions(+), 18 deletions(-) create mode 100644 gui/dialogs/AccountSelectDialog.cpp create mode 100644 gui/dialogs/AccountSelectDialog.h create mode 100644 gui/dialogs/AccountSelectDialog.ui diff --git a/CMakeLists.txt b/CMakeLists.txt index c831205b..e5f9dcf0 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -219,6 +219,8 @@ gui/dialogs/CustomMessageBox.h gui/dialogs/CustomMessageBox.cpp gui/dialogs/AccountListDialog.h gui/dialogs/AccountListDialog.cpp +gui/dialogs/AccountSelectDialog.h +gui/dialogs/AccountSelectDialog.cpp # GUI - widgets gui/widgets/InstanceDelegate.h @@ -374,6 +376,7 @@ gui/dialogs/LegacyModEditDialog.ui gui/dialogs/OneSixModEditDialog.ui gui/dialogs/EditNotesDialog.ui gui/dialogs/AccountListDialog.ui +gui/dialogs/AccountSelectDialog.ui # Widgets/other gui/widgets/MCModInfoFrame.ui diff --git a/gui/MainWindow.cpp b/gui/MainWindow.cpp index 3fdbed44..e817d50d 100644 --- a/gui/MainWindow.cpp +++ b/gui/MainWindow.cpp @@ -58,6 +58,7 @@ #include "gui/dialogs/EditNotesDialog.h" #include "gui/dialogs/CopyInstanceDialog.h" #include "gui/dialogs/AccountListDialog.h" +#include "gui/dialogs/AccountSelectDialog.h" #include "gui/ConsoleWindow.h" @@ -627,19 +628,21 @@ void MainWindow::doLogin(const QString &errorMsg) } else if (account.get() == nullptr) { - // Tell the user they need to log in at least one account in order to play. - auto reply = CustomMessageBox::selectable(this, tr("No Account Selected"), - tr("You don't have an account selected as an active account." - "Would you like to open the account manager to select one now?"), - QMessageBox::Information, QMessageBox::Yes | QMessageBox::No)->exec(); + // If no default account is set, ask the user which one to use. + AccountSelectDialog selectDialog(tr("Which account would you like to use?"), + AccountSelectDialog::GlobalDefaultCheckbox, this); - if (reply == QMessageBox::Yes) - { - // Open the account manager. - on_actionManageAccounts_triggered(); - } + selectDialog.exec(); + + // Launch the instance with the selected account. + account = selectDialog.selectedAccount(); + + // If the user said to use the account as default, do that. + if (selectDialog.useAsGlobalDefault() && account.get() != nullptr) + accounts->setActiveAccount(account->username()); } - else + + if (account.get() != nullptr) { // We'll need to validate the access token to make sure the account is still logged in. // TODO: Do that ^ diff --git a/gui/dialogs/AccountListDialog.cpp b/gui/dialogs/AccountListDialog.cpp index ea6861c6..5feed13d 100644 --- a/gui/dialogs/AccountListDialog.cpp +++ b/gui/dialogs/AccountListDialog.cpp @@ -25,6 +25,7 @@ #include #include +#include #include @@ -37,6 +38,14 @@ AccountListDialog::AccountListDialog(QWidget *parent) : m_accounts = MMC->accounts(); // TODO: Make the "Active?" column show checkboxes or radio buttons. ui->listView->setModel(m_accounts.get()); + + QItemSelectionModel* selectionModel = ui->listView->selectionModel(); + connect(selectionModel, &QItemSelectionModel::selectionChanged, + [this] (const QItemSelection& sel, const QItemSelection& dsel) { updateButtonStates(); }); + connect(m_accounts.get(), &MojangAccountList::listChanged, + [this] () { updateButtonStates(); }); + + updateButtonStates(); } AccountListDialog::~AccountListDialog() @@ -67,7 +76,7 @@ void AccountListDialog::on_editAccountBtn_clicked() // TODO } -void AccountListDialog::on_setActiveBtn_clicked() +void AccountListDialog::on_setDefaultBtn_clicked() { QModelIndexList selection = ui->listView->selectionModel()->selectedIndexes(); if (selection.size() > 0) @@ -80,11 +89,28 @@ void AccountListDialog::on_setActiveBtn_clicked() } } +void AccountListDialog::on_noDefaultBtn_clicked() +{ + m_accounts->setActiveAccount(""); +} + void AccountListDialog::on_closeBtnBox_rejected() { close(); } +void AccountListDialog::updateButtonStates() +{ + // If there is no selection, disable buttons that require something selected. + QModelIndexList selection = ui->listView->selectionModel()->selectedIndexes(); + + ui->rmAccountBtn->setEnabled(selection.size() > 0); + ui->editAccountBtn->setEnabled(selection.size() > 0); + ui->setDefaultBtn->setEnabled(selection.size() > 0); + + ui->noDefaultBtn->setDown(m_accounts->activeAccount().get() == nullptr); +} + void AccountListDialog::doLogin(const QString& errMsg) { // TODO: We can use the login dialog for this for now, but we'll have to make something better for it eventually. diff --git a/gui/dialogs/AccountListDialog.h b/gui/dialogs/AccountListDialog.h index 52666e3b..63720f58 100644 --- a/gui/dialogs/AccountListDialog.h +++ b/gui/dialogs/AccountListDialog.h @@ -42,11 +42,16 @@ slots: void on_editAccountBtn_clicked(); - void on_setActiveBtn_clicked(); + void on_setDefaultBtn_clicked(); + + void on_noDefaultBtn_clicked(); // This will be sent when the "close" button is clicked. void on_closeBtnBox_rejected(); + //! Updates the states of the dialog's buttons. + void updateButtonStates(); + signals: void activeAccountChanged(); diff --git a/gui/dialogs/AccountListDialog.ui b/gui/dialogs/AccountListDialog.ui index 2872b368..b4baf3f9 100644 --- a/gui/dialogs/AccountListDialog.ui +++ b/gui/dialogs/AccountListDialog.ui @@ -66,12 +66,22 @@ - + <html><head/><body><p>Set the currently selected account as the active account. The active account is the account that is used to log in (unless it is overridden in an instance-specific setting).</p></body></html> - &Set Active + &Set Default + + + + + + + Set no default account. This will cause MultiMC to prompt you to select an account every time you launch an instance that doesn't have its own default set. + + + &No Default diff --git a/gui/dialogs/AccountSelectDialog.cpp b/gui/dialogs/AccountSelectDialog.cpp new file mode 100644 index 00000000..1da6d84f --- /dev/null +++ b/gui/dialogs/AccountSelectDialog.cpp @@ -0,0 +1,89 @@ +/* Copyright 2013 MultiMC Contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "AccountSelectDialog.h" +#include "ui_AccountSelectDialog.h" + +#include + +#include + +#include + +#include +#include + +#include + +AccountSelectDialog::AccountSelectDialog(const QString& message, int flags, QWidget *parent) : + QDialog(parent), + ui(new Ui::AccountSelectDialog) +{ + ui->setupUi(this); + + m_accounts = MMC->accounts(); + ui->listView->setModel(m_accounts.get()); + ui->listView->hideColumn(MojangAccountList::ActiveColumn); + + // Set the message label. + ui->msgLabel->setVisible(!message.isEmpty()); + ui->msgLabel->setText(message); + + // Flags... + ui->globalDefaultCheck->setVisible(flags & GlobalDefaultCheckbox); + ui->instDefaultCheck->setVisible(flags & InstanceDefaultCheckbox); + QLOG_DEBUG() << flags; + + // Select the first entry in the list. + ui->listView->setCurrentIndex(ui->listView->model()->index(0, 0)); +} + +AccountSelectDialog::~AccountSelectDialog() +{ + delete ui; +} + +MojangAccountPtr AccountSelectDialog::selectedAccount() const +{ + return m_selected; +} + +bool AccountSelectDialog::useAsGlobalDefault() const +{ + return ui->globalDefaultCheck->isChecked(); +} + +bool AccountSelectDialog::useAsInstDefaullt() const +{ + return ui->instDefaultCheck->isChecked(); +} + +void AccountSelectDialog::on_buttonBox_accepted() +{ + QModelIndexList selection = ui->listView->selectionModel()->selectedIndexes(); + if (selection.size() > 0) + { + QModelIndex selected = selection.first(); + MojangAccountPtr account = selected.data(MojangAccountList::PointerRole).value(); + m_selected = account; + } + close(); +} + +void AccountSelectDialog::on_buttonBox_rejected() +{ + close(); +} + diff --git a/gui/dialogs/AccountSelectDialog.h b/gui/dialogs/AccountSelectDialog.h new file mode 100644 index 00000000..41af4f7c --- /dev/null +++ b/gui/dialogs/AccountSelectDialog.h @@ -0,0 +1,90 @@ +/* Copyright 2013 MultiMC Contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include + +#include + +#include "logic/lists/MojangAccountList.h" + +namespace Ui { +class AccountSelectDialog; +} + +class AccountSelectDialog : public QDialog +{ +Q_OBJECT +public: + enum Flags + { + NoFlags=0, + + /*! + * Shows a check box on the dialog that allows the user to specify that the account + * they've selected should be used as the global default for all instances. + */ + GlobalDefaultCheckbox, + + /*! + * Shows a check box on the dialog that allows the user to specify that the account + * they've selected should be used as the default for the instance they are currently launching. + * This is not currently implemented. + */ + InstanceDefaultCheckbox, + }; + + /*! + * Constructs a new account select dialog with the given parent and message. + * The message will be shown at the top of the dialog. It is an empty string by default. + */ + explicit AccountSelectDialog(const QString& message="", int flags=0, QWidget *parent = 0); + ~AccountSelectDialog(); + + /*! + * Gets a pointer to the account that the user selected. + * This is null if the user clicked cancel or hasn't clicked OK yet. + */ + MojangAccountPtr selectedAccount() const; + + /*! + * Returns true if the user checked the "use as global default" checkbox. + * If the checkbox wasn't shown, this function returns false. + */ + bool useAsGlobalDefault() const; + + /*! + * Returns true if the user checked the "use as instance default" checkbox. + * If the checkbox wasn't shown, this function returns false. + */ + bool useAsInstDefaullt() const; + +public +slots: + void on_buttonBox_accepted(); + + void on_buttonBox_rejected(); + +protected: + std::shared_ptr m_accounts; + + //! The account that was selected when the user clicked OK. + MojangAccountPtr m_selected; + +private: + Ui::AccountSelectDialog *ui; +}; + diff --git a/gui/dialogs/AccountSelectDialog.ui b/gui/dialogs/AccountSelectDialog.ui new file mode 100644 index 00000000..7af1512a --- /dev/null +++ b/gui/dialogs/AccountSelectDialog.ui @@ -0,0 +1,56 @@ + + + AccountSelectDialog + + + + 0 + 0 + 413 + 300 + + + + Select an Account + + + + + + Select an account. + + + + + + + + + + + + Use as default? + + + + + + + Use as default for this instance only? + + + + + + + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + + + + + diff --git a/logic/lists/MojangAccountList.cpp b/logic/lists/MojangAccountList.cpp index 1d67c70f..a30ef4ab 100644 --- a/logic/lists/MojangAccountList.cpp +++ b/logic/lists/MojangAccountList.cpp @@ -93,9 +93,16 @@ MojangAccountPtr MojangAccountList::activeAccount() const void MojangAccountList::setActiveAccount(const QString& username) { beginResetModel(); - for (MojangAccountPtr account : m_accounts) - if (account->username() == username) - m_activeAccount = username; + if (username.isEmpty()) + { + m_activeAccount = ""; + } + else + { + for (MojangAccountPtr account : m_accounts) + if (account->username() == username) + m_activeAccount = username; + } endResetModel(); onListChanged(); } diff --git a/logic/lists/MojangAccountList.h b/logic/lists/MojangAccountList.h index 71f472f7..cfe96c11 100644 --- a/logic/lists/MojangAccountList.h +++ b/logic/lists/MojangAccountList.h @@ -122,6 +122,7 @@ public: /*! * Sets the given account as the current active account. + * If the username given is an empty string, sets the active account to nothing. */ virtual void setActiveAccount(const QString& username);