Commit 57467848 authored by Edric Milaret's avatar Edric Milaret Committed by Guillaume Roguez

Implement multi-device

- add a spiner to wizard dialog
- use wizard dialog to migrate and add ring account
- add a device panel in account details configuration
- add "Add device" feature

Change-Id: I30955a4ef2434b1e9e9f75db39478965d6656ca0
Tuleap: #951
parent 28290e35
......@@ -242,10 +242,10 @@ win32 {
$$RUNTIMEDIR/iconv.dll
QTDEPSRUNTIME.path = $$OUT_PWD/release
QTPLATFORMS.files = $$(QTDIR)/plugins/platforms/qwindows.dll
QTPLATFORMS.files = $$[QT_INSTALL_PLUGINS]/platforms/qwindows.dll
QTPLATFORMS.path = $$OUT_PWD/release/platforms
QTPLUGINIMAGE.files = $$(QTDIR)/plugins/imageformats/
QTPLUGINIMAGE.files = $$[QT_INSTALL_PLUGINS]/imageformats/
QTPLUGINIMAGE.path = $$OUT_PWD/release
LIBSTD.files = $$RUNTIMEDIR/libgcc_s_sjlj-1.dll $$RUNTIMEDIR/libstdc++-6.dll \
......
......@@ -210,6 +210,8 @@ AccountDetails::setAccount(Account* currentAccount) {
ui->cipherListView->setVisible(false);
else
ui->cipherListView->setVisible(true);
ui->tableView->setModel((QAbstractItemModel*)currentAccount_->ringDeviceModel());
}
void
......@@ -298,3 +300,63 @@ AccountDetails::getDeleteAccountButton()
{
return ui->deleteAccountButton;
}
void
AccountDetails::on_addDeviceButton_clicked()
{
ui->devicesStackedWidget->setCurrentIndex(1);
}
void
AccountDetails::on_cancelButton_clicked()
{
ui->devicesStackedWidget->setCurrentIndex(0);
}
void
AccountDetails::on_exportOnRingButton_clicked()
{
if (ui->passwordArchiveEdit->text().isEmpty())
return;
connect(currentAccount_, SIGNAL(exportOnRingEnded(Account::ExportOnRingStatus,QString)), this, SLOT(exportOnRingEnded(Account::ExportOnRingStatus,QString)));
currentAccount_->exportOnRing(ui->passwordArchiveEdit->text());
ui->devicesStackedWidget->setCurrentIndex(2);
ui->pinLabel->setText(tr("Please wait while your PIN is generated."));
}
void
AccountDetails::exportOnRingEnded(Account::ExportOnRingStatus state, const QString& pin) {
ui->devicesStackedWidget->setCurrentIndex(2);
ui->pinLabel->clear();
switch (state) {
case Account::ExportOnRingStatus::SUCCESS:
{
ui->pinLabel->setText(pin);
break;
}
case Account::ExportOnRingStatus::NETWORK_ERROR:
{
ui->pinLabel->setText(tr("Network Error. Please try again later."));
break;
}
case Account::ExportOnRingStatus::WRONG_PASSWORD:
ui->pinLabel->setText(tr("Wrong password."));
break;
}
}
void
AccountDetails::on_exportEndedOkButton_clicked()
{
ui->devicesStackedWidget->setCurrentIndex(0);
}
void
AccountDetails::on_cancelAddButton_clicked()
{
ui->devicesStackedWidget->setCurrentIndex(0);
}
......@@ -52,12 +52,18 @@ private slots:
void on_upVideoButton_clicked();
void on_downVideoButton_clicked();
void on_playButton_clicked();
void on_addDeviceButton_clicked();
void on_cancelButton_clicked();
void on_exportOnRingButton_clicked();
void on_exportEndedOkButton_clicked();
void on_cancelAddButton_clicked();
private slots:
void onCertButtonClicked();
void ringtonesBoxCurrentIndexChanged(int index);
void audioCodecSelectionChanged(const QItemSelection& selected, const QItemSelection& deselected);
void videoCodecSelectionChanged(const QItemSelection& selected, const QItemSelection& deselected);
void exportOnRingEnded(Account::ExportOnRingStatus state, const QString& pin);
private:
Ui::AccountDetails* ui;
......
......@@ -92,7 +92,7 @@
<x>0</x>
<y>0</y>
<width>843</width>
<height>859</height>
<height>856</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout_12">
......@@ -1136,8 +1136,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>812</width>
<height>981</height>
<width>370</width>
<height>1057</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout_11">
......@@ -1993,7 +1993,7 @@
<rect>
<x>0</x>
<y>0</y>
<width>830</width>
<width>686</width>
<height>919</height>
</rect>
</property>
......@@ -2386,6 +2386,263 @@
</item>
</layout>
</widget>
<widget class="QWidget" name="devicesTab">
<attribute name="title">
<string>Devices</string>
</attribute>
<layout class="QVBoxLayout" name="verticalLayout_15">
<item>
<widget class="QStackedWidget" name="devicesStackedWidget">
<widget class="QWidget" name="page">
<layout class="QVBoxLayout" name="verticalLayout_16">
<item>
<widget class="QTableView" name="tableView">
<property name="sizeAdjustPolicy">
<enum>QAbstractScrollArea::AdjustToContents</enum>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
<attribute name="horizontalHeaderCascadingSectionResizes">
<bool>false</bool>
</attribute>
<attribute name="horizontalHeaderDefaultSectionSize">
<number>255</number>
</attribute>
<attribute name="horizontalHeaderHighlightSections">
<bool>false</bool>
</attribute>
<attribute name="horizontalHeaderStretchLastSection">
<bool>false</bool>
</attribute>
<attribute name="verticalHeaderVisible">
<bool>false</bool>
</attribute>
</widget>
</item>
<item>
<widget class="QPushButton" name="addDeviceButton">
<property name="minimumSize">
<size>
<width>0</width>
<height>30</height>
</size>
</property>
<property name="text">
<string>Add device</string>
</property>
</widget>
</item>
</layout>
</widget>
<widget class="QWidget" name="page_2">
<layout class="QVBoxLayout" name="verticalLayout_17">
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QLabel" name="label_18">
<property name="lineWidth">
<number>1</number>
</property>
<property name="text">
<string>To add a new device to your Ring account, you export your account on the Ring. This will generate a pin that must be entered on your new device within 5 minutes of its generation.</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="passwordArchiveEdit">
<property name="echoMode">
<enum>QLineEdit::Password</enum>
</property>
<property name="placeholderText">
<string>Password (required)</string>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_4">
<item>
<spacer name="horizontalSpacer_8">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QPushButton" name="cancelAddButton">
<property name="minimumSize">
<size>
<width>80</width>
<height>30</height>
</size>
</property>
<property name="text">
<string>Cancel</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_7">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QPushButton" name="exportOnRingButton">
<property name="minimumSize">
<size>
<width>150</width>
<height>30</height>
</size>
</property>
<property name="text">
<string>Export on the Ring</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_9">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item>
<spacer name="verticalSpacer_9">
<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>
</widget>
<widget class="QWidget" name="page_3">
<layout class="QVBoxLayout" name="verticalLayout_18">
<item>
<spacer name="verticalSpacer_15">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
<item alignment="Qt::AlignHCenter">
<widget class="QLabel" name="label_24">
<property name="text">
<string>Your generated pin:</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="pinLabel">
<property name="font">
<font>
<pointsize>30</pointsize>
<stylestrategy>PreferAntialias</stylestrategy>
</font>
</property>
<property name="text">
<string>PIN</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item alignment="Qt::AlignHCenter">
<widget class="QLabel" name="label_25">
<property name="text">
<string>This pin should be entered on your new device within 5 minutes. You may generate a new one at any moment.</string>
</property>
</widget>
</item>
<item alignment="Qt::AlignHCenter">
<widget class="QPushButton" name="exportEndedOkButton">
<property name="minimumSize">
<size>
<width>40</width>
<height>30</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>200</width>
<height>16777215</height>
</size>
</property>
<property name="text">
<string>OK</string>
</property>
</widget>
</item>
<item>
<spacer name="verticalSpacer_16">
<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>
</widget>
</widget>
</item>
</layout>
</widget>
</widget>
</item>
</layout>
......
......@@ -376,6 +376,8 @@ void CallWidget::setupQRCode()
void
CallWidget::findRingAccount()
{
ui->ringIdLabel->text().clear();
auto a_count = AccountModel::instance().rowCount();
for (int i = 0; i < a_count; ++i) {
auto idx = AccountModel::instance().index(i, 0);
......@@ -384,16 +386,22 @@ CallWidget::findRingAccount()
auto account = AccountModel::instance().getAccountByModelIndex(idx);
if (account->displayName().isEmpty())
account->displayName() = account->alias();
auto username = account->username();
ui->ringIdLabel->setText(username);
setupQRCode();
return;
if (account->needsMigration()) {
WizardDialog dlg(WizardDialog::MIGRATION, account);
dlg.exec();
}
if (ui->ringIdLabel->text().isEmpty()) {
auto username = account->username();
ui->ringIdLabel->setText(username);
setupQRCode();
}
}
}
ui->ringIdLabel->setText(tr("NO RING ACCOUNT FOUND"));
auto wizardDialog = new WizardDialog();
wizardDialog->exec();
delete wizardDialog;
if (ui->ringIdLabel->text().isEmpty()) {
ui->ringIdLabel->setText(tr("NO RING ACCOUNT FOUND"));
WizardDialog wizardDialog;
wizardDialog.exec();
}
}
void
......
......@@ -44,6 +44,7 @@
#include "utils.h"
#include "pathpassworddialog.h"
#include "photoboothdialog.h"
#include "wizarddialog.h"
#include "accountmodel.h"
#include "protocolmodel.h"
......@@ -302,11 +303,15 @@ ConfigurationWidget::accountPropertyChanged(Account* a,
void
ConfigurationWidget::on_addAccountButton_clicked()
{
auto account = accountModel_->add(tr("New Account"),
ui->accountTypeBox->model()->index(
ui->accountTypeBox->currentIndex(), 0));
account->setRingtonePath(Utils::GetRingtonePath());
accountModel_->save();
auto type = ui->accountTypeBox->model()->index(ui->accountTypeBox->currentIndex(), 0);
if (type.data() == "RING") {
WizardDialog dlg(WizardDialog::NEW_ACCOUNT);
dlg.exec();
} else {
auto account = accountModel_->add(tr("New Account"), type);
account->setRingtonePath(Utils::GetRingtonePath());
accountModel_->save();
}
}
void
......
......@@ -39,5 +39,6 @@
<file>images/icons/ic_photo_camera_white_24dp_2x.png</file>
<file>images/qrcode.png</file>
<file>images/icons/ic_share_black_48dp_2x.png</file>
<file>images/loading.gif</file>
</qresource>
</RCC>
......@@ -286,7 +286,9 @@ QWidget#messagingPage{
}
QPushButton#wizardButton, QPushButton#playButton, QPushButton#clearHistoryButton, QPushButton#doTransferButton,
QPushButton#checkUpdateButton, QPushButton#photoButton, QPushButton#takePhotoButton, QPushButton#importButton{
QPushButton#checkUpdateButton, QPushButton#photoButton, QPushButton#takePhotoButton, QPushButton#importButton,
QPushButton#existingPushButton, QPushButton#newAccountButton, QPushButton#previousButton, QPushButton#exportButton,
QPushButton#cancelAddButton, QPushButton#exportOnRingButton, QPushButton#addDeviceButton, QPushButton#exportEndedOkButton{
background-color: #3AC0D2;
border: 0px;
color: white;
......@@ -295,17 +297,23 @@ QPushButton#checkUpdateButton, QPushButton#photoButton, QPushButton#takePhotoBut
QPushButton#wizardButton:hover, QPushButton#playButton:hover, QPushButton#clearHistoryButton:hover,
QPushButton#doTransferButton:hover, QPushButton#photoButton:hover,
QPushButton#takePhotoButton:hover, QPushButton#importButton:hover{
QPushButton#takePhotoButton:hover, QPushButton#importButton:hover,
QPushButton#existingPushButton:hover, QPushButton#newAccountButton:hover, QPushButton#previousButton:hover,
QPushButton#exportButton:hover, QPushButton#cancelAddButton:hover, QPushButton#exportOnRingButton:hover,
QPushButton#addDeviceButton:hover, QPushButton#exportEndedOkButton:hover{
background-color: #4dc6d6;
}
QPushButton#wizardButton:pressed, QPushButton#playButton:pressed, QPushButton#clearHistoryButton:pressed,
QPushButton#doTransferButton:pressed, QPushButton#photoButton:pressed,
QPushButton#takePhotoButton:pressed, QPushButton#importButton:pressed{
QPushButton#takePhotoButton:pressed, QPushButton#importButton:pressed,
QPushButton#existingPushButton:pressed, QPushButton#newAccountButton:pressed, QPushButton#previousButton:pressed,
QPushButton#exportButton:pressed, QPushButton#cancelAddButton:pressed, QPushButton#exportOnRingButton:pressed,
QPushButton#addDeviceButton:pressed, QPushButton#exportEndedOkButton:pressed{
background-color: #34acbd;
}
QLineEdit#usernameEdit:enabled{
QLineEdit#usernameEdit:enabled, QLineEdit#passwordEdit:enabled, QLineEdit#confirmPasswordEdit:enabled, QLineEdit#pinEdit:enabled{
border-color: rgb(0, 192, 212);
border-radius: 5px;
border-width: 1px;
......@@ -313,7 +321,7 @@ QLineEdit#usernameEdit:enabled{
background-color: rgb(255, 255, 255);
}
QLineEdit#usernameEdit:disabled{
QLineEdit#usernameEdit:disabled, QLineEdit#passwordEdit:disabled, QLineEdit#confirmPasswordEdit:disabled, QLineEdit#pinEdit:disabled{
border-color: rgb(159, 157, 154);
border-radius: 5px;
border-width: 1px;
......
......@@ -29,9 +29,11 @@
#include "utils.h"
#include "photoboothdialog.h"
WizardDialog::WizardDialog(QWidget* parent) :
WizardDialog::WizardDialog(WizardMode wizardMode, Account* toBeMigrated, QWidget* parent) :
QDialog(parent),
ui(new Ui::WizardDialog)
ui(new Ui::WizardDialog),
account_(toBeMigrated),
wizardMode_(wizardMode)
{
ui->setupUi(this);
......@@ -44,7 +46,23 @@ WizardDialog::WizardDialog(QWidget* parent) :
ui->ringLogo->setPixmap(logo.scaledToHeight(65, Qt::SmoothTransformation));
ui->ringLogo->setAlignment(Qt::AlignHCenter);
ui->welcomeLogo->setPixmap(logo.scaledToHeight(65, Qt::SmoothTransformation));
ui->welcomeLogo->setAlignment(Qt::AlignHCenter);
ui->usernameEdit->setText(Utils::GetCurrentUserName());
movie_ = new QMovie(":/images/loading.gif");
ui->spinnerLabel->setMovie(movie_);
movie_->start();
if (wizardMode_ == MIGRATION) {
ui->stackedWidget->setCurrentIndex(1);
ui->usernameEdit->hide();
ui->previousButton->hide();
ui->avatarButton->hide();
ui->pinEdit->hide();
ui->label->setText(tr("Your account needs to be migrated. Choose a password."));
}
}
WizardDialog::~WizardDialog()
......@@ -55,9 +73,21 @@ WizardDialog::~WizardDialog()
void
WizardDialog::accept()
{
ui->label->setText(tr("Please wait while we create your account."));
ui->wizardButton->setEnabled(false);
ui->usernameEdit->setEnabled(false);
if (ui->pinEdit->isVisible() && ui->pinEdit->text().isEmpty()) {
ui->pinEdit->setStyleSheet("border-color: rgb(204, 0, 0);");
return;
}
if (ui->passwordEdit->text().isEmpty() || ui->passwordEdit->text() != ui->confirmPasswordEdit->text()) {
ui->passwordEdit->setStyleSheet("border-color: rgb(204, 0, 0);");
ui->confirmPasswordEdit->setStyleSheet("border-color: rgb(204, 0, 0);");
return;
} else {
ui->passwordEdit->setStyleSheet("border-color: rgb(0, 192, 212);");
ui->confirmPasswordEdit->setStyleSheet("border-color: rgb(0, 192, 212);");
ui->pinEdit->setStyleSheet("border-color: rgb(0, 192, 212);");
}
ui->stackedWidget->setCurrentIndex(2);
auto profile = ProfileModel::instance().selectedProfile();
......@@ -65,38 +95,60 @@ WizardDialog::accept()
Utils::CreateStartupLink();
auto account = AccountModel::instance().add(ui->usernameEdit->text(), Account::Protocol::RING);
if (not ui->usernameEdit->text().isEmpty()) {
account->setDisplayName(ui->usernameEdit->text());
profile->person()->setFormattedName(ui->usernameEdit->text());
if (account_ == nullptr) {
account_ = AccountModel::instance().add(ui->usernameEdit->text(), Account::Protocol::RING);
if (not ui->usernameEdit->text().isEmpty()) {
account_->setDisplayName(ui->usernameEdit->text());
profile->person()->setFormattedName(ui->usernameEdit->text());
}
else {
profile->person()->setFormattedName(tr("Unknown"));
}
}
else {
profile->person()->setFormattedName(tr("Unknown"));
account_->setRingtonePath(Utils::GetRingtonePath());
account_->setUpnpEnabled(true);
account_->setArchivePassword(ui->passwordEdit->text());
ui->passwordEdit->setEnabled(false);
ui->confirmPasswordEdit->setEnabled(false);
if (not ui->pinEdit->text().isEmpty()) {
account_->setArchivePin(ui->pinEdit->text());
}
account->setRingtonePath(Utils::GetRingtonePath());
account->setUpnpEnabled(true);
connect(account, SIGNAL(changed(Account*)), this, SLOT(endSetup(Account*)));
connect(account_, SIGNAL(stateChanged(Account::RegistrationState)), this, SLOT(endSetup(Account::RegistrationState)));
account->performAction(Account::EditAction::SAVE);
account_->performAction(Account::EditAction::SAVE);
profile->setAccounts({account});
profile->setAccounts({account_});
profile->save();
}
void
WizardDialog::endSetup(Account* a)
WizardDialog::endSetup(Account::RegistrationState state)
{
Q_UNUSED(a)
QDialog::accept();
switch (state) {
case Account::RegistrationState::READY:
{
account_->performAction(Account::EditAction::RELOAD);
QDialog::accept();
break;
}
case Account::RegistrationState::UNREGISTERED:
case Account::RegistrationState::TRYING:
case Account::RegistrationState::COUNT__:
break;
}
}
void
WizardDialog::closeEvent(QCloseEvent* event)
{
Q_UNUSED(event)
exit(0);
Q_UNUSED(event);
if (wizardMode_ == WIZARD)
exit(0);
else
QDialog::closeEvent(event);
}
void
......@@ -111,3 +163,48 @@ WizardDialog::on_avatarButton_clicked()
ui->avatarButton->setIcon(QPixmap::fromImage(Utils::getCirclePhoto(avatar, ui->avatarButton->width())));
}
}
void
WizardDialog::on_existingPushButton_clicked()
{
changePage(true);
}
void
WizardDialog::on_newAccountButton_clicked()
{
changePage(false);
}
void
WizardDialog::changePage(bool existingAccount)
{
ui->stackedWidget->setCurrentIndex(1);
ui->avatarButton->setHidden(existingAccount);
ui->ringLogo->setHidden(existingAccount);
ui->label->setHidden(existingAccount);
ui->usernameEdit->setHidden(existingAccount);
ui->confirmPasswordEdit->setHidden(existingAccount);
ui->pinEdit->setVisible(existingAccount);
}
void
WizardDialog::on_previousButton_clicked()
{
ui->stackedWidget->setCurrentIndex(0);
ui->passwordEdit->setStyleSheet("border-color: rgb(0, 192, 212);");
ui->confirmPasswordEdit->setStyleSheet("border-color: rgb(0, 192, 212);");
ui->pinEdit->setStyleSheet("border-color: rgb(0, 192, 212);");
}
void
WizardDialog::on_passwordEdit_textChanged(const QString& arg1)
{
Q_UNUSED(arg1)
if (ui->pinEdit->isVisible()) {
ui->confirmPasswordEdit->setText(ui->passwordEdit->text());
}
}
......@@ -33,7 +33,14 @@ class WizardDialog : public QDialog
Q_OBJECT
public:
explicit WizardDialog(QWidget* parent = 0);
enum WizardMode {
WIZARD,
NEW_ACCOUNT,
MIGRATION
};
public:
explicit WizardDialog(WizardMode wizardMode = WIZARD, Account* toBeMigrated = nullptr, QWidget* parent = 0);
~WizardDialog();
// Overrided function
......@@ -44,13 +51,21 @@ protected slots:
//UI Slots
private slots:
void on_avatarButton_clicked();
void on_existingPushButton_clicked();
void on_newAccountButton_clicked();
void on_previousButton_clicked();
void on_passwordEdit_textChanged(const QString& arg1);