#5629 Complete activation support for activation dialog

This commit is contained in:
Andrew Nelless 2016-09-30 15:03:49 +01:00 committed by Andrew Nelless
parent 60a4e62779
commit 0f95c6e941
15 changed files with 375 additions and 150 deletions

View File

@ -11,7 +11,7 @@
</rect>
</property>
<property name="windowTitle">
<string>Dialog</string>
<string>Activate Synergy</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
@ -51,17 +51,11 @@
<item row="0" column="1">
<widget class="QLineEdit" name="m_pLineEditEmail">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>200</width>
<height>20</height>
</size>
</property>
<property name="echoMode">
<enum>QLineEdit::Normal</enum>
</property>
@ -77,17 +71,11 @@
<item row="1" column="1">
<widget class="QLineEdit" name="m_pLineEditPassword">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>200</width>
<height>20</height>
</size>
</property>
<property name="echoMode">
<enum>QLineEdit::Password</enum>
</property>
@ -120,6 +108,9 @@
</item>
<item>
<widget class="QTextEdit" name="m_pTextEditSerialKey">
<property name="enabled">
<bool>false</bool>
</property>
<property name="html">
<string>&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.0//EN&quot; &quot;http://www.w3.org/TR/REC-html40/strict.dtd&quot;&gt;
&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;
@ -127,6 +118,9 @@ p, li { white-space: pre-wrap; }
&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'Sans'; font-size:10pt; font-weight:400; font-style:normal;&quot;&gt;
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="acceptRichText">
<bool>false</bool>
</property>
</widget>
</item>
<item>

View File

@ -7,7 +7,7 @@
<x>0</x>
<y>0</y>
<width>400</width>
<height>156</height>
<height>165</height>
</rect>
</property>
<property name="windowTitle">

View File

@ -1,12 +1,44 @@
#include "ActivationDialog.h"
#include "ui_ActivationDialog.h"
#include "CancelActivationDialog.h"
#include "AppConfig.h"
#include "WebClient.h"
#include "EditionType.h"
#include "ActivationNotifier.h"
#include "MainWindow.h"
#include "QUtility.h"
#include "SubscriptionManager.h"
ActivationDialog::ActivationDialog(QWidget *parent) :
#include <QMessageBox>
#include <QThread>
#include <iostream>
ActivationDialog::ActivationDialog(QWidget* parent, AppConfig& appConfig) :
QDialog(parent),
ui(new Ui::ActivationDialog)
ui(new Ui::ActivationDialog),
m_appConfig (&appConfig)
{
ui->setupUi(this);
ui->m_pLineEditEmail->setText(appConfig.activateEmail());
ui->m_pTextEditSerialKey->setText(appConfig.serialKey());
if (!appConfig.serialKey().isEmpty()) {
ui->m_pRadioButtonActivate->setAutoExclusive(false);
ui->m_pRadioButtonSubscription->setAutoExclusive(false);
ui->m_pRadioButtonActivate->setChecked(false);
ui->m_pRadioButtonSubscription->setChecked(true);
ui->m_pRadioButtonActivate->setAutoExclusive(true);
ui->m_pRadioButtonSubscription->setAutoExclusive(true);
ui->m_pTextEditSerialKey->setFocus();
ui->m_pTextEditSerialKey->moveCursor(QTextCursor::End);
} else {
if (ui->m_pLineEditEmail->text().isEmpty()) {
ui->m_pLineEditEmail->setFocus();
} else {
ui->m_pLineEditPassword->setFocus();
}
}
}
ActivationDialog::~ActivationDialog()
@ -14,10 +46,121 @@ ActivationDialog::~ActivationDialog()
delete ui;
}
void ActivationDialog::notifyActivation(QString identity)
{
ActivationNotifier* notifier = new ActivationNotifier();
notifier->setIdentity(identity);
QThread* thread = new QThread();
connect(notifier, SIGNAL(finished()), thread, SLOT(quit()));
connect(notifier, SIGNAL(finished()), notifier, SLOT(deleteLater()));
connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater()));
notifier->moveToThread(thread);
thread->start();
QMetaObject::invokeMethod(notifier, "notify", Qt::QueuedConnection);
}
void ActivationDialog::reject()
{
CancelActivationDialog cancelActivationDialog(this);
if (QDialog::Accepted == cancelActivationDialog.exec()) {
notifyActivation("skip:unknown");
QDialog::reject();
}
}
void ActivationDialog::on_m_pRadioButtonSubscription_toggled(bool checked)
{
if (checked) {
ui->m_pLineEditEmail->setEnabled(false);
ui->m_pLineEditPassword->setEnabled(false);
ui->m_pTextEditSerialKey->setEnabled(true);
ui->m_pTextEditSerialKey->setFocus();
}
}
void ActivationDialog::on_m_pRadioButtonActivate_toggled(bool checked)
{
if (checked) {
ui->m_pLineEditEmail->setEnabled(true);
ui->m_pLineEditPassword->setEnabled(true);
ui->m_pTextEditSerialKey->setEnabled(false);
if (ui->m_pLineEditEmail->text().isEmpty()) {
ui->m_pLineEditEmail->setFocus();
} else {
ui->m_pLineEditPassword->setFocus();
}
}
}
void ActivationDialog::accept()
{
QMessageBox message;
QString error;
int edition = Unregistered;
try {
if (ui->m_pRadioButtonActivate->isChecked()) {
WebClient webClient;
QString email = ui->m_pLineEditEmail->text();
QString password = ui->m_pLineEditPassword->text();
if (!webClient.setEmail (email, error)) {
message.critical (this, "Invalid Email Address", tr("%1").arg(error));
return;
}
else if (!webClient.setPassword (password, error)) {
message.critical (this, "Invalid Password", tr("%1").arg(error));
return;
}
else if (!webClient.getEdition (edition, error)) {
message.critical (this, "Activation Error",
tr("An error occurred while trying to activate Synergy. "
"The Symless server returned the following error:\n\n%1").arg(error));
return;
}
m_appConfig->setActivateEmail (email);
m_appConfig->clearSerialKey();
ui->m_pTextEditSerialKey->clear();
notifyActivation ("login:" + m_appConfig->activateEmail());
}
else {
QString serialKey = ui->m_pTextEditSerialKey->toPlainText();
if (!m_appConfig->setSerialKey (serialKey, error)) {
message.critical (this, "Invalid Serial Key", tr("%1").arg(error));
return;
}
SubscriptionManager subscriptionManager (this, *m_appConfig, edition);
if (!subscriptionManager.activateSerial (serialKey)) {
return;
}
m_appConfig->setActivateEmail("");
notifyActivation ("serial:" + m_appConfig->serialKey());
}
}
catch (std::exception& e) {
message.critical (this, "Unknown Error",
tr("An error occurred while trying to activate Synergy. "
"Please contact the helpdesk, and provide the "
"following details.\n\n%1").arg(e.what()));
return;
}
m_appConfig->setEdition(edition);
m_appConfig->saveSettings();
message.information (this, "Activated!",
tr("Thanks for activating %1!").arg
(getEditionName (edition)));
MainWindow& mainWindow = dynamic_cast<MainWindow&>(*this->parent());
mainWindow.setEdition(edition);
mainWindow.updateLocalFingerprint();
mainWindow.settings().sync();
QDialog::accept();
}

View File

@ -7,19 +7,30 @@ namespace Ui {
class ActivationDialog;
}
class AppConfig;
class ActivationDialog : public QDialog
{
Q_OBJECT
public:
explicit ActivationDialog(QWidget *parent = 0);
explicit ActivationDialog(QWidget *parent, AppConfig& appConfig);
~ActivationDialog();
public slots:
void reject();
void accept();
protected:
void notifyActivation (QString identity);
private:
Ui::ActivationDialog *ui;
AppConfig* m_appConfig;
private slots:
void on_m_pRadioButtonSubscription_toggled(bool checked);
void on_m_pRadioButtonActivate_toggled(bool checked);
};
#endif // ACTIVATIONDIALOG_H

View File

@ -73,6 +73,18 @@ AppConfig::~AppConfig()
saveSettings();
}
const QString &AppConfig::screenName() const { return m_ScreenName; }
int AppConfig::port() const { return m_Port; }
const QString &AppConfig::interface() const { return m_Interface; }
int AppConfig::logLevel() const { return m_LogLevel; }
bool AppConfig::logToFile() const { return m_LogToFile; }
const QString &AppConfig::logFilename() const { return m_LogFilename; }
QString AppConfig::synergyLogDir() const
{
#if defined(Q_OS_WIN)
@ -116,6 +128,16 @@ QString AppConfig::logLevelText() const
return logLevelNames[logLevel()];
}
ProcessMode AppConfig::processMode() const { return m_ProcessMode; }
bool AppConfig::wizardShouldRun() const { return m_WizardLastRun < kWizardVersion; }
const QString &AppConfig::language() const { return m_Language; }
bool AppConfig::startedBefore() const { return m_StartedBefore; }
bool AppConfig::autoConfig() const { return m_AutoConfig; }
void AppConfig::loadSettings()
{
m_ScreenName = settings().value("screenName", QHostInfo::localHostName()).toString();
@ -135,7 +157,7 @@ void AppConfig::loadSettings()
}
m_ElevateMode = static_cast<ElevateMode>(elevateMode.toInt());
m_AutoConfigPrompted = settings().value("autoConfigPrompted", false).toBool();
m_Edition = settings().value("edition", Unknown).toInt();
m_Edition = settings().value("edition", Unregistered).toInt();
m_ActivateEmail = settings().value("activateEmail", "").toString();
m_CryptoEnabled = settings().value("cryptoEnabled", false).toBool();
m_AutoHide = settings().value("autoHide", false).toBool();
@ -168,17 +190,84 @@ void AppConfig::saveSettings()
settings().setValue("lastExpiringWarningTime", m_LastExpiringWarningTime);
}
QSettings &AppConfig::settings() { return *m_pSettings; }
void AppConfig::setScreenName(const QString &s) { m_ScreenName = s; }
void AppConfig::setPort(int i) { m_Port = i; }
void AppConfig::setInterface(const QString &s) { m_Interface = s; }
void AppConfig::setLogLevel(int i) { m_LogLevel = i; }
void AppConfig::setLogToFile(bool b) { m_LogToFile = b; }
void AppConfig::setLogFilename(const QString &s) { m_LogFilename = s; }
void AppConfig::setWizardHasRun() { m_WizardLastRun = kWizardVersion; }
void AppConfig::setLanguage(const QString language) { m_Language = language; }
void AppConfig::setStartedBefore(bool b) { m_StartedBefore = b; }
void AppConfig::setElevateMode(ElevateMode em) { m_ElevateMode = em; }
void AppConfig::setAutoConfig(bool autoConfig)
{
m_AutoConfig = autoConfig;
}
bool AppConfig::autoConfigPrompted() { return m_AutoConfigPrompted; }
void AppConfig::setAutoConfigPrompted(bool prompted)
{
m_AutoConfigPrompted = prompted;
}
void AppConfig::setEdition(int e) { m_Edition = e; }
int AppConfig::edition() { return m_Edition; }
bool AppConfig::setActivateEmail(QString e) {
m_ActivateEmail = e;
return true;
}
QString AppConfig::activateEmail() { return m_ActivateEmail; }
bool AppConfig::setSerialKey(QString serial, QString& errorOut) {
if (serial.isEmpty()) {
errorOut = "Your serial key cannot be blank.";
return false;
}
m_Serialkey = serial;
return true;
}
void AppConfig::clearSerialKey()
{
m_Serialkey.clear();
}
QString AppConfig::serialKey() { return m_Serialkey; }
int AppConfig::lastExpiringWarningTime() const { return m_LastExpiringWarningTime; }
void AppConfig::setLastExpiringWarningTime(int t) { m_LastExpiringWarningTime = t; }
QString AppConfig::synergysName() const { return m_SynergysName; }
QString AppConfig::synergycName() const { return m_SynergycName; }
ElevateMode AppConfig::elevateMode()
{
return m_ElevateMode;
}
void AppConfig::setCryptoEnabled(bool e) { m_CryptoEnabled = e; }
bool AppConfig::getCryptoEnabled() { return m_CryptoEnabled; }
void AppConfig::setAutoHide(bool b) { m_AutoHide = b; }
bool AppConfig::getAutoHide() { return m_AutoHide; }

View File

@ -58,33 +58,34 @@ class AppConfig
~AppConfig();
public:
const QString& screenName() const { return m_ScreenName; }
int port() const { return m_Port; }
const QString& interface() const { return m_Interface; }
int logLevel() const { return m_LogLevel; }
bool logToFile() const { return m_LogToFile; }
const QString& logFilename() const { return m_LogFilename; }
const QString& screenName() const;
int port() const;
const QString& interface() const;
int logLevel() const;
bool logToFile() const;
const QString& logFilename() const;
const QString logFilenameCmd() const;
QString logLevelText() const;
ProcessMode processMode() const { return m_ProcessMode; }
bool wizardShouldRun() const { return m_WizardLastRun < kWizardVersion; }
const QString& language() const { return m_Language; }
bool startedBefore() const { return m_StartedBefore; }
bool autoConfig() const { return m_AutoConfig; }
ProcessMode processMode() const;
bool wizardShouldRun() const;
const QString& language() const;
bool startedBefore() const;
bool autoConfig() const;
void setAutoConfig(bool autoConfig);
bool autoConfigPrompted() { return m_AutoConfigPrompted; }
bool autoConfigPrompted();
void setAutoConfigPrompted(bool prompted);
void setEdition(int e) { m_Edition = e; }
int edition() { return m_Edition; }
void setActivateEmail(QString e) { m_ActivateEmail = e; }
QString activateEmail() { return m_ActivateEmail; }
void setSerialKey(QString serial) { m_Serialkey = serial; }
QString serialKey() { return m_Serialkey; }
int lastExpiringWarningTime() const { return m_LastExpiringWarningTime; }
void setLastExpiringWarningTime(int t) { m_LastExpiringWarningTime = t; }
void setEdition(int e);
int edition();
bool setActivateEmail(QString e);
QString activateEmail();
bool setSerialKey(QString serial, QString& error);
void clearSerialKey();
QString serialKey();
int lastExpiringWarningTime() const;
void setLastExpiringWarningTime(int t);
QString synergysName() const { return m_SynergysName; }
QString synergycName() const { return m_SynergycName; }
QString synergysName() const;
QString synergycName() const;
QString synergyProgramDir() const;
QString synergyLogDir() const;
@ -92,25 +93,25 @@ class AppConfig
void persistLogDir();
ElevateMode elevateMode();
void setCryptoEnabled(bool e) { m_CryptoEnabled = e; }
bool getCryptoEnabled() { return m_CryptoEnabled; }
void setAutoHide(bool b) { m_AutoHide = b; }
bool getAutoHide() { return m_AutoHide; }
void setCryptoEnabled(bool e);
bool getCryptoEnabled();
void setAutoHide(bool b);
bool getAutoHide();
void saveSettings();
protected:
QSettings& settings() { return *m_pSettings; }
void setScreenName(const QString& s) { m_ScreenName = s; }
void setPort(int i) { m_Port = i; }
void setInterface(const QString& s) { m_Interface = s; }
void setLogLevel(int i) { m_LogLevel = i; }
void setLogToFile(bool b) { m_LogToFile = b; }
void setLogFilename(const QString& s) { m_LogFilename = s; }
void setWizardHasRun() { m_WizardLastRun = kWizardVersion; }
void setLanguage(const QString language) { m_Language = language; }
void setStartedBefore(bool b) { m_StartedBefore = b; }
void setElevateMode(ElevateMode em) { m_ElevateMode = em; }
QSettings& settings();
void setScreenName(const QString& s);
void setPort(int i);
void setInterface(const QString& s);
void setLogLevel(int i);
void setLogToFile(bool b);
void setLogFilename(const QString& s);
void setWizardHasRun();
void setLanguage(const QString language);
void setStartedBefore(bool b);
void setElevateMode(ElevateMode em);
void loadSettings();

View File

@ -18,11 +18,13 @@
#ifndef EDITIONTYPE_H
#define EDITIONTYPE_H
enum qEditionType {
/* Do not reorder these! */
enum EditionType {
Basic,
Pro,
Trial,
Unknown
Unregistered
};
#endif // EDITIONTYPE_H

View File

@ -1015,23 +1015,9 @@ void MainWindow::serverDetected(const QString name)
}
}
void MainWindow::setEdition(int type)
void MainWindow::setEdition(int edition)
{
QString title;
if (type == Basic) {
title = "Synergy Basic";
}
else if (type == Pro) {
title = "Synergy Pro";
}
else if (type == Trial) {
title = "Synergy Trial";
}
else {
title = "Synergy (UNREGISTERED)";
}
setWindowTitle(title);
setWindowTitle(getEditionName(edition));
}
void MainWindow::updateLocalFingerprint()
@ -1154,7 +1140,7 @@ void MainWindow::on_m_pActionWizard_triggered()
void MainWindow::on_m_pActivate_triggered()
{
ActivationDialog activationDialog (this);
ActivationDialog activationDialog (this, this->appConfig());
activationDialog.exec();
}

View File

@ -33,6 +33,7 @@
#include "VersionChecker.h"
#include "IpcClient.h"
#include "Ipc.h"
#include "ActivationDialog.h"
#include <QMutex>
@ -63,6 +64,7 @@ class MainWindow : public QMainWindow, public Ui::MainWindowBase
friend class QSynergyApplication;
friend class SetupWizard;
friend class ActivationDialog;
public:
enum qSynergyState
@ -111,7 +113,7 @@ class MainWindow : public QMainWindow, public Ui::MainWindowBase
void autoAddScreen(const QString name);
void updateZeroconfService();
void serverDetected(const QString name);
void setEdition(int type);
void setEdition(int edition);
void updateLocalFingerprint();
public slots:
void appendLogRaw(const QString& text);

View File

@ -19,6 +19,7 @@
#include "ProcessorArch.h"
#include "CommandProcess.h"
#include "EditionType.h"
#if defined(Q_OS_LINUX)
#include <QProcess>
@ -42,6 +43,22 @@ void setIndexFromItemData(QComboBox* comboBox, const QVariant& itemData)
}
}
QString
getEditionName (int edition) {
if (edition == Basic) {
return "Synergy Basic";
}
else if (edition == Pro) {
return "Synergy Pro";
}
else if (edition == Trial) {
return "Synergy Trial";
}
else {
return "Synergy (UNREGISTERED)";
}
}
QString hash(const QString& string)
{
QByteArray data = string.toUtf8();

View File

@ -29,3 +29,4 @@ QString hash(const QString& string);
QString getFirstMacAddress();
qProcessorArch getProcessorArch();
QString getOSInformation();
QString getEditionName (int edition);

View File

@ -29,7 +29,7 @@
SetupWizard::SetupWizard(MainWindow& mainWindow, bool startMain) :
m_MainWindow(mainWindow),
m_StartMain(startMain),
m_Edition(Unknown),
m_Edition(Unregistered),
m_LoginAttemps(0)
{
setupUi(this);
@ -76,7 +76,7 @@ bool SetupWizard::validateCurrentPage()
message.setWindowTitle(tr("Setup Synergy"));
message.setIcon(QMessageBox::Information);
if (currentPage() == m_pActivatePage)
/*if (currentPage() == m_pActivatePage)
{
if (m_pRadioButtonActivate->isChecked()) {
if (m_pLineEditEmail->text().isEmpty() ||
@ -136,7 +136,8 @@ bool SetupWizard::validateCurrentPage()
return true;
}
}
else if (currentPage() == m_pNodePage)
else */
if (currentPage() == m_pNodePage)
{
bool result = m_pClientRadioButton->isChecked() ||
m_pServerRadioButton->isChecked();
@ -201,7 +202,7 @@ void SetupWizard::accept()
if (m_pRadioButtonSubscription->isChecked())
{
appConfig.setSerialKey(m_pTextEditSerialKey->toPlainText());
//appConfig.setSerialKey(m_pTextEditSerialKey->toPlainText());
notifyActivation("serial:" + m_pTextEditSerialKey->toPlainText());
}

View File

@ -39,7 +39,7 @@ SubscriptionManager::SubscriptionManager(QWidget* parent, AppConfig& appConfig,
bool SubscriptionManager::activateSerial(const QString& serial)
{
m_Edition = Unknown;
m_Edition = Unregistered;
persistDirectory();
CoreInterface coreInterface;
QString output;
@ -62,7 +62,7 @@ bool SubscriptionManager::activateSerial(const QString& serial)
bool SubscriptionManager::checkSubscription()
{
m_Edition = Unknown;
m_Edition = Unregistered;
persistDirectory();
CoreInterface coreInterface;
QString output;

View File

@ -25,26 +25,13 @@
#include <QCoreApplication>
#include <stdexcept>
int WebClient::getEdition(
const QString& email,
const QString& password,
QMessageBox& message,
QWidget* w)
{
QString responseJson;
int edition = Unknown;
try {
responseJson = request(email, password);
}
catch (std::exception& e)
{
message.critical(
w, "Error",
tr("An error occurred while trying to sign in. "
"Please contact the helpdesk, and provide the "
"following details.\n\n%1").arg(e.what()));
return edition;
}
bool
WebClient::getEdition (int& edition, QString& errorOut) {
QString responseJson = request();
/* TODO: This is horrible and should be ripped out as soon as we move
* to Qt 5. See issue #5630
*/
QRegExp resultRegex(".*\"result\".*:.*(true|false).*");
if (resultRegex.exactMatch (responseJson)) {
@ -54,47 +41,44 @@ int WebClient::getEdition(
if (editionRegex.exactMatch(responseJson)) {
QString e = editionRegex.cap(1);
edition = e.toInt();
return true;
} else {
throw std::runtime_error ("Unrecognised server response.");
}
return edition;
} else {
errorOut = tr("Login failed. Invalid email or password.");
return false;
}
else if (boolString == "false") {
message.critical(
w, "Error",
tr("Login failed, invalid email or password."));
return edition;
}
}
else {
} else {
QRegExp errorRegex(".*\"error\".*:.*\"([^\"]+)\".*");
if (errorRegex.exactMatch (responseJson)) {
// replace "\n" with real new lines.
QString error = errorRegex.cap(1).replace("\\n", "\n");
message.critical(
w, "Error",
tr("Login failed, an error occurred.\n\n%1").arg(error));
return edition;
errorOut = errorRegex.cap(1).replace("\\n", "\n");
return false;
} else {
throw std::runtime_error ("Unrecognised server response.");
}
}
}
message.critical(
w, "Error",
tr("Login failed, an error occurred.\n\nServer response:\n\n%1")
.arg(responseJson));
return edition;
bool
WebClient::setEmail (QString email, QString& errorOut) {
if (email.isEmpty()) {
errorOut = tr("Your email address cannot be left blank.");
return false;
}
m_Email = email;
return true;
}
QString WebClient::request(
const QString& email,
const QString& password)
{
bool
WebClient::setPassword (QString password, QString&) {
m_Password = password;
return true;
}
QString
WebClient::request() {
QStringList args("--login-auth");
// hash password in case it contains interesting chars.
QString credentials(email + ":" + hash(password) + "\n");
QString credentials (m_Email + ":" + hash(m_Password) + "\n");
return m_CoreInterface.run (args, credentials);
}

View File

@ -32,21 +32,15 @@ class WebClient : public QObject
Q_OBJECT
public:
int getEdition(const QString& email,
const QString& password,
QMessageBox& message,
QWidget* w);
void setEmail(QString& e) { m_Email = e; }
void setPassword(QString& p) { m_Password = p; }
bool getEdition (int& edition, QString& errorOut);
bool setEmail (QString email, QString& errorOut);
bool setPassword (QString password, QString& errorOut);
signals:
void error(QString e);
private:
QString request(const QString& email,
const QString& password);
QString request();
private:
QString m_Email;
QString m_Password;
CoreInterface m_CoreInterface;