Implement account list and account list dialog

This commit is contained in:
Andrew 2013-11-18 12:05:35 -06:00
parent ad8aeb0b2b
commit cdca530139
12 changed files with 520 additions and 9 deletions

View File

@ -215,6 +215,8 @@ gui/dialogs/EditNotesDialog.h
gui/dialogs/EditNotesDialog.cpp gui/dialogs/EditNotesDialog.cpp
gui/dialogs/CustomMessageBox.h gui/dialogs/CustomMessageBox.h
gui/dialogs/CustomMessageBox.cpp gui/dialogs/CustomMessageBox.cpp
gui/dialogs/AccountListDialog.h
gui/dialogs/AccountListDialog.cpp
# GUI - widgets # GUI - widgets
gui/widgets/InstanceDelegate.h gui/widgets/InstanceDelegate.h
@ -323,6 +325,8 @@ logic/lists/ForgeVersionList.h
logic/lists/ForgeVersionList.cpp logic/lists/ForgeVersionList.cpp
logic/lists/JavaVersionList.h logic/lists/JavaVersionList.h
logic/lists/JavaVersionList.cpp logic/lists/JavaVersionList.cpp
logic/lists/MojangAccountList.h
logic/lists/MojangAccountList.cpp
# misc model/view # misc model/view
logic/EnabledItemFilter.h logic/EnabledItemFilter.h
@ -363,6 +367,7 @@ gui/dialogs/IconPickerDialog.ui
gui/dialogs/LegacyModEditDialog.ui gui/dialogs/LegacyModEditDialog.ui
gui/dialogs/OneSixModEditDialog.ui gui/dialogs/OneSixModEditDialog.ui
gui/dialogs/EditNotesDialog.ui gui/dialogs/EditNotesDialog.ui
gui/dialogs/AccountListDialog.ui
# Widgets/other # Widgets/other
gui/widgets/MCModInfoFrame.ui gui/widgets/MCModInfoFrame.ui

View File

@ -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.
*/
#include "AccountListDialog.h"
#include "ui_AccountListDialog.h"
#include <logger/QsLog.h>
#include <logic/auth/AuthenticateTask.h>
#include <gui/dialogs/LoginDialog.h>
#include <gui/dialogs/ProgressDialog.h>
AccountListDialog::AccountListDialog(QWidget *parent) :
QDialog(parent),
ui(new Ui::AccountListDialog)
{
ui->setupUi(this);
ui->listView->setModel(&m_accounts);
}
AccountListDialog::~AccountListDialog()
{
delete ui;
}
void AccountListDialog::on_addAccountBtn_clicked()
{
doLogin("Please log in to add your account.");
}
void AccountListDialog::on_rmAccountBtn_clicked()
{
// TODO
}
void AccountListDialog::on_editAccountBtn_clicked()
{
// TODO
}
void AccountListDialog::on_closedBtnBox_rejected()
{
close();
}
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.
LoginDialog loginDialog(this);
loginDialog.exec();
if (loginDialog.result() == QDialog::Accepted)
{
QString username(loginDialog.getUsername());
QString password(loginDialog.getPassword());
MojangAccountPtr account = MojangAccountPtr(new MojangAccount(username));
ProgressDialog* progDialog = new ProgressDialog(this);
m_authTask = new AuthenticateTask(account, password, progDialog);
connect(m_authTask, SIGNAL(succeeded()), SLOT(onLoginComplete()), Qt::QueuedConnection);
connect(m_authTask, SIGNAL(failed(QString)), SLOT(doLogin(QString)), Qt::QueuedConnection);
progDialog->exec(m_authTask);
//delete m_authTask;
}
}
void AccountListDialog::onLoginComplete()
{
// Add the authenticated account to the accounts list.
MojangAccountPtr account = m_authTask->getMojangAccount();
m_accounts.addAccount(account);
//ui->listView->update();
}

View File

@ -0,0 +1,60 @@
/* 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 <QDialog>
#include "logic/lists/MojangAccountList.h"
namespace Ui {
class AccountListDialog;
}
class AuthenticateTask;
class AccountListDialog : public QDialog
{
Q_OBJECT
public:
explicit AccountListDialog(QWidget *parent = 0);
~AccountListDialog();
public
slots:
void on_addAccountBtn_clicked();
void on_rmAccountBtn_clicked();
void on_editAccountBtn_clicked();
// This will be sent when the "close" button is clicked.
void on_closedBtnBox_rejected();
protected:
// Temporarily putting this here...
MojangAccountList m_accounts;
AuthenticateTask* m_authTask;
protected
slots:
void doLogin(const QString& errMsg="");
void onLoginComplete();
private:
Ui::AccountListDialog *ui;
};

View File

@ -0,0 +1,83 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>AccountListDialog</class>
<widget class="QDialog" name="AccountListDialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>400</width>
<height>300</height>
</rect>
</property>
<property name="windowTitle">
<string>Dialog</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<widget class="QLabel" name="welcomeLabel">
<property name="text">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Welcome! If you're new here, you can click the &amp;quot;Add&amp;quot; button to add your Mojang or Minecraft account.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QListView" name="listView"/>
</item>
<item>
<layout class="QVBoxLayout" name="manageAcctsBtnBox">
<item>
<widget class="QPushButton" name="addAccountBtn">
<property name="text">
<string>&amp;Add</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="editAccountBtn">
<property name="text">
<string>&amp;Edit</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="rmAccountBtn">
<property name="text">
<string>&amp;Remove</string>
</property>
</widget>
</item>
<item>
<spacer name="buttonSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
</layout>
</item>
<item>
<widget class="QDialogButtonBox" name="closeBtnBox">
<property name="standardButtons">
<set>QDialogButtonBox::Close</set>
</property>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>

View File

@ -26,7 +26,7 @@
#include "logger/QsLog.h" #include "logger/QsLog.h"
AuthenticateTask::AuthenticateTask(MojangAccount* account, const QString& password, QObject* parent) : AuthenticateTask::AuthenticateTask(MojangAccountPtr account, const QString& password, QObject* parent) :
YggdrasilTask(account, parent), m_password(password) YggdrasilTask(account, parent), m_password(password)
{ {
} }

View File

@ -29,7 +29,7 @@ class AuthenticateTask : public YggdrasilTask
{ {
Q_OBJECT Q_OBJECT
public: public:
AuthenticateTask(MojangAccount* account, const QString& password, QObject* parent=0); AuthenticateTask(MojangAccountPtr account, const QString& password, QObject* parent=0);
protected: protected:
virtual QJsonObject getRequestContent() const; virtual QJsonObject getRequestContent() const;

View File

@ -41,6 +41,16 @@ MojangAccount::MojangAccount(const QString& username, const QString& clientToken
m_currentProfile = -1; m_currentProfile = -1;
} }
MojangAccount::MojangAccount(const MojangAccount& other, QObject* parent)
{
m_username = other.username();
m_clientToken = other.clientToken();
m_accessToken = other.accessToken();
m_profiles = other.m_profiles;
m_currentProfile = other.m_currentProfile;
}
QString MojangAccount::username() const QString MojangAccount::username() const
{ {

View File

@ -19,6 +19,7 @@
#include <QString> #include <QString>
#include <QList> #include <QList>
#include <memory>
/** /**
* Class that represents a profile within someone's Mojang account. * Class that represents a profile within someone's Mojang account.
@ -65,6 +66,11 @@ public:
*/ */
explicit MojangAccount(const QString& username, const QString& clientToken, const QString& accessToken, QObject* parent = 0); explicit MojangAccount(const QString& username, const QString& clientToken, const QString& accessToken, QObject* parent = 0);
/**
* Constructs a new MojangAccount matching the given account.
*/
MojangAccount(const MojangAccount& other, QObject* parent);
/** /**
* This MojangAccount's username. May be an email address if the account is migrated. * This MojangAccount's username. May be an email address if the account is migrated.
@ -124,3 +130,6 @@ protected:
ProfileList m_profiles; // List of available profiles. ProfileList m_profiles; // List of available profiles.
}; };
typedef std::shared_ptr<MojangAccount> MojangAccountPtr;
Q_DECLARE_METATYPE(MojangAccountPtr)

View File

@ -25,7 +25,7 @@
#include <MultiMC.h> #include <MultiMC.h>
#include <logic/auth/MojangAccount.h> #include <logic/auth/MojangAccount.h>
YggdrasilTask::YggdrasilTask(MojangAccount* account, QObject* parent) : Task(parent) YggdrasilTask::YggdrasilTask(MojangAccountPtr account, QObject* parent) : Task(parent)
{ {
m_error = nullptr; m_error = nullptr;
m_account = account; m_account = account;
@ -175,7 +175,7 @@ YggdrasilTask::Error *YggdrasilTask::getError() const
return this->m_error; return this->m_error;
} }
MojangAccount* YggdrasilTask::getMojangAccount() const MojangAccountPtr YggdrasilTask::getMojangAccount() const
{ {
return this->m_account; return this->m_account;
} }

View File

@ -20,8 +20,7 @@
#include <QString> #include <QString>
#include <QJsonObject> #include <QJsonObject>
#include "logic/auth/MojangAccount.h"
class MojangAccount;
class QNetworkReply; class QNetworkReply;
@ -33,7 +32,7 @@ class YggdrasilTask : public Task
{ {
Q_OBJECT Q_OBJECT
public: public:
explicit YggdrasilTask(MojangAccount* account, QObject* parent=0); explicit YggdrasilTask(MojangAccountPtr account, QObject* parent=0);
~YggdrasilTask(); ~YggdrasilTask();
/** /**
@ -61,7 +60,7 @@ public:
/** /**
* Gets the Mojang account that this task is operating on. * Gets the Mojang account that this task is operating on.
*/ */
virtual MojangAccount* getMojangAccount() const; virtual MojangAccountPtr getMojangAccount() const;
/** /**
* Returns a pointer to a YggdrasilTask::Error object if an error has occurred. * Returns a pointer to a YggdrasilTask::Error object if an error has occurred.
@ -117,7 +116,7 @@ protected:
*/ */
virtual QString getStateMessage(const State state) const; virtual QString getStateMessage(const State state) const;
MojangAccount* m_account; MojangAccountPtr m_account;
QNetworkReply* m_netReply; QNetworkReply* m_netReply;

View File

@ -0,0 +1,146 @@
/* 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 "logic/lists/MojangAccountList.h"
#include "logic/auth/MojangAccount.h"
MojangAccountList::MojangAccountList(QObject *parent) : QAbstractListModel(parent)
{
}
MojangAccountPtr MojangAccountList::findAccount(const QString &username)
{
for (int i = 0; i < count(); i++)
{
MojangAccountPtr account = at(i);
if (account->username() == username)
return account;
}
return MojangAccountPtr();
}
const MojangAccountPtr MojangAccountList::at(int i) const
{
return MojangAccountPtr(m_accounts.at(i));
}
void MojangAccountList::addAccount(const MojangAccountPtr account)
{
beginResetModel();
m_accounts.append(account);
endResetModel();
}
void MojangAccountList::removeAccount(const QString& username)
{
beginResetModel();
for (auto account : m_accounts)
{
if (account->username() == username)
{
m_accounts.removeOne(account);
return;
}
}
endResetModel();
}
int MojangAccountList::count() const
{
return m_accounts.count();
}
QVariant MojangAccountList::data(const QModelIndex &index, int role) const
{
if (!index.isValid())
return QVariant();
if (index.row() > count())
return QVariant();
MojangAccountPtr account = at(index.row());
switch (role)
{
case Qt::DisplayRole:
switch (index.column())
{
case NameColumn:
return account->username();
default:
return QVariant();
}
case Qt::ToolTipRole:
return account->username();
case PointerRole:
return qVariantFromValue(account);
default:
return QVariant();
}
}
QVariant MojangAccountList::headerData(int section, Qt::Orientation orientation, int role) const
{
switch (role)
{
case Qt::DisplayRole:
switch (section)
{
case NameColumn:
return "Name";
default:
return QVariant();
}
case Qt::ToolTipRole:
switch (section)
{
case NameColumn:
return "The name of the version.";
default:
return QVariant();
}
default:
return QVariant();
}
}
int MojangAccountList::rowCount(const QModelIndex &parent) const
{
// Return count
return count();
}
int MojangAccountList::columnCount(const QModelIndex &parent) const
{
return 1;
}
void MojangAccountList::updateListData(QList<MojangAccountPtr> versions)
{
beginResetModel();
m_accounts = versions;
endResetModel();
}

View File

@ -0,0 +1,109 @@
/* 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 <QObject>
#include <QVariant>
#include <QAbstractListModel>
#include <QSharedPointer>
#include "logic/auth/MojangAccount.h"
/*!
* \brief List of available Mojang accounts.
* This should be loaded in the background by MultiMC on startup.
*
* This class also inherits from QAbstractListModel. Methods from that
* class determine how this list shows up in a list view. Said methods
* all have a default implementation, but they can be overridden by subclasses to
* change the behavior of the list.
*/
class MojangAccountList : public QAbstractListModel
{
Q_OBJECT
public:
enum ModelRoles
{
PointerRole = 0x34B1CB48
};
enum VListColumns
{
// TODO: Add icon column.
// First column - Name
NameColumn = 0,
};
explicit MojangAccountList(QObject *parent = 0);
//! Gets the account at the given index.
virtual const MojangAccountPtr at(int i) const;
//! Returns the number of accounts in the list.
virtual int count() const;
//////// List Model Functions ////////
virtual QVariant data(const QModelIndex &index, int role) const;
virtual QVariant headerData(int section, Qt::Orientation orientation, int role) const;
virtual int rowCount(const QModelIndex &parent) const;
virtual int columnCount(const QModelIndex &parent) const;
/*!
* Adds a the given Mojang account to the account list.
*/
virtual void addAccount(const MojangAccountPtr account);
/*!
* Removes the mojang account with the given username from the account list.
*/
virtual void removeAccount(const QString& username);
/*!
* \brief Finds an account by its username.
* \param The username of the account to find.
* \return A const pointer to the account with the given username. NULL if
* one doesn't exist.
*/
virtual MojangAccountPtr findAccount(const QString &username);
signals:
/*!
* Signal emitted to indicate that the account list has changed.
* This will also fire if the value of an element in the list changes (will be implemented later).
*/
void listChanged();
protected:
QList<MojangAccountPtr> m_accounts;
protected
slots:
/*!
* Updates this list with the given list of accounts.
* This is done by copying each account in the given list and inserting it
* into this one.
* We need to do this so that we can set the parents of the accounts are set to this
* account list. This can't be done in the load task, because the accounts the load
* task creates are on the load task's thread and Qt won't allow their parents
* to be set to something created on another thread.
* To get around that problem, we invoke this method on the GUI thread, which
* then copies the accounts and sets their parents correctly.
* \param accounts List of accounts whose parents should be set.
*/
virtual void updateListData(QList<MojangAccountPtr> versions);
};