#5657 Create a global SubscriptionManager instance

This commit is contained in:
Andrew Nelless 2016-10-14 11:28:37 +01:00
parent 743e96f277
commit 540882056f
14 changed files with 117 additions and 248 deletions

View File

@ -7,7 +7,8 @@ DEFINES += VERSION_REVISION=\\\"$$QMAKE_VERSION_REVISION\\\"
DEPENDPATH += . \
res
INCLUDEPATH += . \
src
src \
../lib/shared/
FORMS += res/MainWindowBase.ui \
res/AboutDialogBase.ui \
res/ServerConfigDialogBase.ui \
@ -102,7 +103,6 @@ HEADERS += src/MainWindow.h \
src/DataDownloader.h \
src/AddClientDialog.h \
src/CommandProcess.h \
src/EditionType.h \
src/ProcessorArch.h \
src/CoreInterface.h \
src/Fingerprint.h \
@ -114,6 +114,7 @@ HEADERS += src/MainWindow.h \
src/ActivationDialog.h \
src/CancelActivationDialog.h \
src/FailedLoginDialog.h \
../lib/shared/EditionType.h \
../lib/shared/SerialKey.h
RESOURCES += res/Synergy.qrc
RC_FILE = res/win/Synergy.rc

View File

@ -14,10 +14,12 @@
#include <QThread>
#include <iostream>
ActivationDialog::ActivationDialog(QWidget* parent, AppConfig& appConfig) :
ActivationDialog::ActivationDialog(QWidget* parent, AppConfig& appConfig,
SubscriptionManager& subscriptionManager) :
QDialog(parent),
ui(new Ui::ActivationDialog),
m_appConfig(&appConfig)
m_appConfig(&appConfig),
m_subscriptionManager (&subscriptionManager)
{
ui->setupUi(this);
ui->m_pTextEditSerialKey->setFocus();
@ -67,17 +69,8 @@ void ActivationDialog::accept()
try {
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;
}
SubscriptionManager subscriptionManager (m_appConfig);
subscriptionManager.setSerialKey (serialKey);
notifyActivation("serial:" + m_appConfig->serialKey());
}

View File

@ -2,6 +2,7 @@
#define ACTIVATIONDIALOG_H
#include <QDialog>
#include <SubscriptionManager.h>
namespace Ui {
class ActivationDialog;
@ -14,7 +15,8 @@ class ActivationDialog : public QDialog
Q_OBJECT
public:
explicit ActivationDialog(QWidget *parent, AppConfig& appConfig);
ActivationDialog(QWidget *parent, AppConfig& appConfig,
SubscriptionManager& subscriptionManager);
~ActivationDialog();
public slots:
@ -27,6 +29,7 @@ protected:
private:
Ui::ActivationDialog *ui;
AppConfig* m_appConfig;
SubscriptionManager* m_subscriptionManager;
};
#endif // ACTIVATIONDIALOG_H

View File

@ -244,13 +244,10 @@ void AppConfig::setEdition(int e) {
int AppConfig::edition() const { return m_Edition; }
bool AppConfig::setSerialKey(QString serial, QString& errorOut) {
if (serial.isEmpty()) {
errorOut = "Your serial key cannot be blank.";
return false;
}
m_Serialkey = serial;
return true;
QString AppConfig::setSerialKey(QString serial) {
using std::swap;
swap (serial, m_Serialkey);
return serial;
}
void AppConfig::clearSerialKey()

View File

@ -79,7 +79,7 @@ class AppConfig: public QObject
void setAutoConfigPrompted(bool prompted);
void setEdition(int e);
int edition() const;
bool setSerialKey(QString serial, QString& error);
QString setSerialKey(QString serial);
void clearSerialKey();
QString serialKey();
int lastExpiringWarningTime() const;

View File

@ -76,12 +76,14 @@ static const char* synergyIconFiles[] =
":/res/icons/16x16/synergy-transfering.png"
};
MainWindow::MainWindow(QSettings& settings, AppConfig& appConfig) :
MainWindow::MainWindow(QSettings& settings, AppConfig& appConfig,
SubscriptionManager& subscriptionManager) :
m_Settings(settings),
m_AppConfig(appConfig),
m_AppConfig(&appConfig),
m_SubscriptionManager(&subscriptionManager),
m_pSynergy(NULL),
m_SynergyState(synergyDisconnected),
m_ServerConfig(&m_Settings, 5, 3, m_AppConfig.screenName(), this),
m_ServerConfig(&m_Settings, 5, 3, m_AppConfig->screenName(), this),
m_pTempConfigFile(NULL),
m_pTrayIcon(NULL),
m_pTrayIconMenu(NULL),
@ -135,12 +137,12 @@ MainWindow::MainWindow(QSettings& settings, AppConfig& appConfig) :
m_pComboServerList->hide();
setEdition(m_AppConfig.edition());
setEdition(m_AppConfig->edition());
m_pLabelPadlock->hide();
connect (this, SIGNAL(windowShown()), this, SLOT(on_windowShown()), Qt::QueuedConnection);
connect (&m_AppConfig, SIGNAL(editionSet(int)), this, SLOT(setEdition(int)), Qt::QueuedConnection);
connect (&m_AppConfig, SIGNAL(sslToggled(bool)), this, SLOT(sslToggled(bool)), Qt::QueuedConnection);
connect (m_AppConfig, SIGNAL(editionSet(int)), this, SLOT(setEdition(int)), Qt::QueuedConnection);
connect (m_AppConfig, SIGNAL(sslToggled(bool)), this, SLOT(sslToggled(bool)), Qt::QueuedConnection);
}
MainWindow::~MainWindow()
@ -498,7 +500,7 @@ void MainWindow::restartSynergy()
void MainWindow::proofreadInfo()
{
setEdition(m_AppConfig.edition()); // Why is this here?
setEdition(m_AppConfig->edition()); // Why is this here?
int oldState = m_SynergyState;
m_SynergyState = synergyDisconnected;
@ -566,7 +568,7 @@ void MainWindow::startSynergy()
#endif
if (m_AppConfig.getCryptoEnabled()) {
if (m_AppConfig->getCryptoEnabled()) {
args << "--enable-crypto";
}
@ -734,18 +736,6 @@ QString MainWindow::appPath(const QString& name)
bool MainWindow::serverArgs(QStringList& args, QString& app)
{
int edition;
SubscriptionManager subscriptionManager(this, appConfig(), edition);
if (subscriptionManager.fileExists())
{
if (!subscriptionManager.checkSubscription()) {
return false;
}
else {
setEdition(edition);
}
}
app = appPath(appConfig().synergysName());
if (!QFile::exists(app))
@ -894,7 +884,7 @@ void MainWindow::setSynergyState(qSynergyState state)
switch (state)
{
case synergyConnected: {
if (m_AppConfig.getCryptoEnabled()) {
if (m_AppConfig->getCryptoEnabled()) {
m_pLabelPadlock->show();
}
else {
@ -1009,13 +999,13 @@ void MainWindow::updateZeroconfService()
QMutexLocker locker(&m_UpdateZeroconfMutex);
if (isBonjourRunning()) {
if (!m_AppConfig.wizardShouldRun()) {
if (!m_AppConfig->wizardShouldRun()) {
if (m_pZeroconfService) {
delete m_pZeroconfService;
m_pZeroconfService = NULL;
}
if (m_AppConfig.autoConfig() || synergyType() == synergyServer) {
if (m_AppConfig->autoConfig() || synergyType() == synergyServer) {
m_pZeroconfService = new ZeroconfService(this);
}
}
@ -1037,7 +1027,7 @@ void MainWindow::serverDetected(const QString name)
void MainWindow::setEdition(int edition)
{
setWindowTitle(getEditionName(edition));
if (m_AppConfig.getCryptoEnabled()) {
if (m_AppConfig->getCryptoEnabled()) {
m_pSslCertificate = new SslCertificate(this);
m_pSslCertificate->generateCertificate();
}
@ -1047,7 +1037,7 @@ void MainWindow::setEdition(int edition)
void MainWindow::updateLocalFingerprint()
{
if (m_AppConfig.getCryptoEnabled() && Fingerprint::local().fileExists()) {
if (m_AppConfig->getCryptoEnabled() && Fingerprint::local().fileExists()) {
m_pLabelFingerprint->setVisible(true);
m_pLabelLocalFingerprint->setVisible(true);
m_pLabelLocalFingerprint->setText(Fingerprint::local().readFirst());
@ -1058,6 +1048,12 @@ void MainWindow::updateLocalFingerprint()
}
}
SubscriptionManager&
MainWindow::subscriptionManager() const
{
return *m_SubscriptionManager;
}
void MainWindow::on_m_pGroupClient_toggled(bool on)
{
m_pGroupServer->setChecked(!on);
@ -1159,7 +1155,7 @@ void MainWindow::on_m_pButtonConfigureServer_clicked()
void MainWindow::on_m_pActivate_triggered()
{
ActivationDialog activationDialog (this, this->appConfig());
ActivationDialog activationDialog(this, appConfig(), subscriptionManager());
activationDialog.exec();
}
@ -1320,16 +1316,16 @@ void MainWindow::promptAutoConfig()
QMessageBox::Yes | QMessageBox::No);
if (r == QMessageBox::Yes) {
m_AppConfig.setAutoConfig(true);
m_AppConfig->setAutoConfig(true);
downloadBonjour();
}
else {
m_AppConfig.setAutoConfig(false);
m_AppConfig->setAutoConfig(false);
m_pCheckBoxAutoConfig->setChecked(false);
}
}
m_AppConfig.setAutoConfigPrompted(true);
m_AppConfig->setAutoConfigPrompted(true);
}
void MainWindow::on_m_pComboServerList_currentIndexChanged(QString )
@ -1377,8 +1373,8 @@ void MainWindow::bonjourInstallFinished()
void MainWindow::on_windowShown()
{
if (!m_AppConfig.activationHasRun() && (m_AppConfig.edition() == Unregistered)) {
ActivationDialog activationDialog (this, m_AppConfig);
if (!m_AppConfig->activationHasRun() && (m_AppConfig->edition() == Unregistered)) {
ActivationDialog activationDialog (this, appConfig(), subscriptionManager());
activationDialog.exec();
}
}

View File

@ -58,6 +58,7 @@ class ZeroconfService;
class DataDownloader;
class CommandProcess;
class SslCertificate;
class SubscriptionManager;
class MainWindow : public QMainWindow, public Ui::MainWindowBase
{
@ -94,7 +95,8 @@ class MainWindow : public QMainWindow, public Ui::MainWindowBase
};
public:
MainWindow(QSettings& settings, AppConfig& appConfig);
MainWindow(QSettings& settings, AppConfig& appConfig,
SubscriptionManager& subscriptionManager);
~MainWindow();
public:
@ -116,6 +118,7 @@ class MainWindow : public QMainWindow, public Ui::MainWindowBase
void updateZeroconfService();
void serverDetected(const QString name);
void updateLocalFingerprint();
SubscriptionManager& subscriptionManager() const;
public slots:
void setEdition(int edition);
@ -145,7 +148,7 @@ class MainWindow : public QMainWindow, public Ui::MainWindowBase
protected:
QSettings& settings() { return m_Settings; }
AppConfig& appConfig() { return m_AppConfig; }
AppConfig& appConfig() { return *m_AppConfig; }
QProcess* synergyProcess() { return m_pSynergy; }
void setSynergyProcess(QProcess* p) { m_pSynergy = p; }
void initConnections();
@ -188,7 +191,8 @@ class MainWindow : public QMainWindow, public Ui::MainWindowBase
private:
QSettings& m_Settings;
AppConfig& m_AppConfig;
AppConfig* m_AppConfig;
SubscriptionManager* m_SubscriptionManager;
QProcess* m_pSynergy;
int m_SynergyState;
ServerConfig m_ServerConfig;

View File

@ -51,9 +51,6 @@ getEditionName (int edition) {
else if (edition == Pro) {
return "Synergy Pro";
}
else if (edition == Trial) {
return "Synergy Trial";
}
else {
return "Synergy (UNREGISTERED)";
}

View File

@ -16,152 +16,20 @@
*/
#include "SubscriptionManager.h"
#include "CoreInterface.h"
#include "EditionType.h"
#include "AppConfig.h"
#include <ctime>
#include <QMessageBox>
#include <QDir>
#include <QFile>
#include <QDateTime>
#include <QDate>
static const char purchaseURL[] = "https://symless.com/account/";
SubscriptionManager::SubscriptionManager(QWidget* parent, AppConfig& appConfig, int& edition) :
m_pParent(parent),
m_AppConfig(appConfig),
m_Edition(edition)
{
SubscriptionManager::SubscriptionManager(AppConfig* appConfig) :
m_AppConfig(appConfig) {
}
bool SubscriptionManager::activateSerial(const QString& serial)
void
SubscriptionManager::setSerialKey(QString serialKeyString)
{
m_Edition = Unregistered;
persistDirectory();
CoreInterface coreInterface;
QString output;
try
{
output = coreInterface.activateSerial(serial);
}
catch (std::exception& e)
{
m_ErrorMessage = e.what();
checkError(m_ErrorMessage);
return false;
}
checkOutput(output);
return true;
}
bool SubscriptionManager::checkSubscription()
{
m_Edition = Unregistered;
persistDirectory();
CoreInterface coreInterface;
QString output;
try
{
output = coreInterface.checkSubscription();
}
catch (std::exception& e)
{
m_ErrorMessage = e.what();
checkError(m_ErrorMessage);
return false;
}
checkOutput(output);
return true;
}
bool SubscriptionManager::fileExists()
{
CoreInterface coreInterface;
QString serialKeyFilePath = coreInterface.getSerialKeyFilePath();
return QFile::exists(serialKeyFilePath);
}
void SubscriptionManager::checkError(QString& error)
{
if (error.contains("trial has expired")) {
QMessageBox::warning(m_pParent, tr("Subscription warning"),
tr("Your trial has expired. Click <a href='%1'>here</a> to purchase").arg(purchaseURL));
}
else {
QMessageBox::warning(m_pParent, tr("Subscription error"),
tr("An error occurred while trying to activate Synergy using your serial key. "
"Please contact the helpdesk, and provide the "
"following details.\n\n%1").arg(error));
}
}
void SubscriptionManager::checkOutput(QString& output)
{
getEditionType(output);
checkExpiring(output);
}
void SubscriptionManager::getEditionType(QString& output)
{
if (output.contains("pro subscription valid")) {
m_Edition = Pro;
}
else if (output.contains("basic subscription valid")) {
m_Edition = Basic;
}
else if (output.contains("trial subscription valid")) {
m_Edition = Trial;
}
}
void SubscriptionManager::checkExpiring(QString& output)
{
if (output.contains("trial will end in") && shouldWarnExpiring()) {
QRegExp dayLeftRegex(".*trial will end in ([0-9]+) day.*");
if (dayLeftRegex.exactMatch(output)) {
QString dayLeft = dayLeftRegex.cap(1);
QMessageBox::warning(m_pParent, tr("Subscription warning"),
tr("Your trial will end in %1 %2. Click <a href='%3'>here</a> to purchase")
.arg(dayLeft)
.arg(dayLeft == "1" ? "day" : "days")
.arg(purchaseURL));
}
}
}
bool SubscriptionManager::shouldWarnExpiring()
{
// warn users about expiring subscription once a day
int lastExpiringWarningTime = m_AppConfig.lastExpiringWarningTime();
QDateTime currentDateTime = QDateTime::currentDateTime();
int currentTime = currentDateTime.toTime_t();
const int secondPerDay = 60 * 60 * 24;
bool result = false;
if ((currentTime - lastExpiringWarningTime) > secondPerDay) {
result = true;
m_AppConfig.setLastExpiringWarningTime(currentTime);
}
return result;
}
void SubscriptionManager::persistDirectory()
{
CoreInterface coreInterface;
QString profileDir = coreInterface.getProfileDir();
QDir dir(profileDir);
if (!dir.exists()) {
dir.mkpath(".");
SerialKey serialKey (serialKeyString.toStdString());
if (serialKey.isValid (::time(0)) && (serialKey != m_serialKey)) {
m_AppConfig->setSerialKey (serialKeyString);
emit serialKeyChanged (serialKey);
}
}

View File

@ -17,31 +17,23 @@
#pragma once
#include <QWidget>
#include <QObject>
#include <SerialKey.h>
class AppConfig;
class SubscriptionManager : public QWidget
class SubscriptionManager: public QObject
{
Q_OBJECT
public:
SubscriptionManager(QWidget* parent, AppConfig& appConfig, int& edition);
bool activateSerial(const QString& serial);
bool checkSubscription();
bool fileExists();
QString getLastError(){ return m_ErrorMessage; }
SubscriptionManager (AppConfig* appConfig);
void setSerialKey (QString serialKey);
private:
void checkError(QString& error);
void checkOutput(QString& output);
void getEditionType(QString& output);
void checkExpiring(QString& output);
bool shouldWarnExpiring();
void persistDirectory();
AppConfig* m_AppConfig;
SerialKey m_serialKey;
private:
QString m_ErrorMessage;
QWidget* m_pParent;
AppConfig& m_AppConfig;
int& m_Edition;
signals:
void serialKeyChanged (SerialKey);
};

View File

@ -20,6 +20,7 @@
#define TRAY_RETRY_WAIT 2000
#include "QSynergyApplication.h"
#include "SubscriptionManager.h"
#include "MainWindow.h"
#include "AppConfig.h"
#include "SetupWizard.h"
@ -82,11 +83,12 @@ int main(int argc, char* argv[])
#endif
QSettings settings;
AppConfig appConfig(&settings);
AppConfig appConfig (&settings);
SubscriptionManager subscriptionManager (&appConfig);
app.switchTranslator(appConfig.language());
MainWindow mainWindow(settings, appConfig);
MainWindow mainWindow(settings, appConfig, subscriptionManager);
SetupWizard setupWizard(mainWindow, true);
if (appConfig.wizardShouldRun())

View File

@ -20,10 +20,10 @@
/* Do not reorder these! */
enum EditionType {
enum Edition {
Basic,
Pro,
Trial,
Trial_DO_NOT_USE_OR_THERE_WILL_BE_PAIN,
Unregistered
};

View File

@ -24,11 +24,18 @@
using namespace std;
SerialKey::SerialKey():
m_warnTime(1),
m_expireTime(1),
m_trial(true)
{
}
SerialKey::SerialKey(std::string serial) :
m_userLimit(1),
m_warnTime(0),
m_expireTime(0),
m_edition(kBasic),
m_edition(Edition::Basic),
m_trial(true),
m_valid(false)
{
@ -39,7 +46,7 @@ SerialKey::SerialKey(std::string serial) :
}
bool
SerialKey::isValid(unsigned long long currentTime) const
SerialKey::isValid(time_t currentTime) const
{
bool result = false;
@ -58,7 +65,7 @@ SerialKey::isValid(unsigned long long currentTime) const
}
bool
SerialKey::isExpiring(unsigned long long currentTime) const
SerialKey::isExpiring(time_t currentTime) const
{
bool result = false;
@ -72,7 +79,7 @@ SerialKey::isExpiring(unsigned long long currentTime) const
}
bool
SerialKey::isExpired(unsigned long long currentTime) const
SerialKey::isExpired(time_t currentTime) const
{
bool result = false;
@ -91,14 +98,14 @@ SerialKey::isTrial() const
return m_trial;
}
int
Edition
SerialKey::edition() const
{
return m_edition;
}
unsigned long long
SerialKey::dayLeft(unsigned long long currentTime) const
time_t
SerialKey::daysLeft(time_t currentTime) const
{
unsigned long long timeLeft = 0;
if (m_expireTime > currentTime) {
@ -195,9 +202,9 @@ SerialKey::parse(std::string plainSerial)
Edition
SerialKey::getEdition(std::string editionStr)
{
Edition e = kBasic;
Edition e = Edition::Basic;
if (editionStr == "pro") {
e = kPro;
e = Edition::Pro;
}
return e;

View File

@ -18,31 +18,29 @@
#pragma once
#include <string>
#include <ctime>
#include "EditionType.h"
#ifdef TEST_ENV
#include "gtest/gtest_prod.h"
#endif
enum Edition{
kBasic,
kPro
};
class SerialKey {
public:
SerialKey();
SerialKey(std::string serial);
bool isValid(unsigned long long currentTime) const;
bool isExpiring(unsigned long long currentTime) const;
bool isExpired(unsigned long long currentTime) const;
bool isValid(time_t currentTime) const;
bool isExpiring(time_t currentTime) const;
bool isExpired(time_t currentTime) const;
bool isTrial() const;
int edition() const;
unsigned long long dayLeft(unsigned long long currentTime) const;
time_t daysLeft(time_t currentTime) const;
Edition edition() const;
private:
std::string decode(const std::string& serial) const;
void parse(std::string plainSerial);
Edition getEdition(std::string editionStr);
Edition getEdition(std::string editionStr);
#ifdef TEST_ENV
private:
@ -59,10 +57,21 @@ private:
std::string m_name;
std::string m_email;
std::string m_company;
int m_userLimit;
unsigned m_userLimit;
unsigned long long m_warnTime;
unsigned long long m_expireTime;
Edition m_edition;
Edition m_edition;
bool m_trial;
bool m_valid;
};
inline bool
operator== (SerialKey const& lhs, SerialKey const& rhs) {
return (lhs.edition() == rhs.edition());
}
inline bool
operator!= (SerialKey const& lhs, SerialKey const& rhs) {
return !(lhs == rhs);
}