#5657 Make trial expiry notification live
This commit is contained in:
parent
e05ced287c
commit
714b2f6440
|
@ -55,7 +55,7 @@
|
||||||
<item>
|
<item>
|
||||||
<widget class="QLabel" name="m_trialLabel">
|
<widget class="QLabel" name="m_trialLabel">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string><html><head/><body><p><span style=" font-weight:600;">6</span> days of your Synergy Pro trial remain. <a href="http://symless.com/pricing?src=gui"><span style=" text-decoration: underline; color:#0000ff;">Buy now!</span></a></p></body></html></string>
|
<string><html><head/><body><p><span style=" font-weight:600;">%1</span> days of your Synergy Pro trial remain. <a href="http://symless.com/pricing?src=gui"><span style=" text-decoration: underline; color:#0000ff;">Buy now!</span></a></p></body></html></string>
|
||||||
</property>
|
</property>
|
||||||
<property name="openExternalLinks">
|
<property name="openExternalLinks">
|
||||||
<bool>true</bool>
|
<bool>true</bool>
|
||||||
|
|
|
@ -39,7 +39,7 @@ ActivationDialog::~ActivationDialog()
|
||||||
|
|
||||||
void ActivationDialog::reject()
|
void ActivationDialog::reject()
|
||||||
{
|
{
|
||||||
if (m_subscriptionManager->activeLicense() == kUnregistered) {
|
if (m_subscriptionManager->activeEdition() == kUnregistered) {
|
||||||
CancelActivationDialog cancelActivationDialog(this);
|
CancelActivationDialog cancelActivationDialog(this);
|
||||||
if (QDialog::Accepted == cancelActivationDialog.exec()) {
|
if (QDialog::Accepted == cancelActivationDialog.exec()) {
|
||||||
m_subscriptionManager->skipActivation();
|
m_subscriptionManager->skipActivation();
|
||||||
|
@ -53,28 +53,35 @@ void ActivationDialog::reject()
|
||||||
void ActivationDialog::accept()
|
void ActivationDialog::accept()
|
||||||
{
|
{
|
||||||
QMessageBox message;
|
QMessageBox message;
|
||||||
QString error;
|
|
||||||
|
|
||||||
m_appConfig->activationHasRun(true);
|
m_appConfig->activationHasRun(true);
|
||||||
m_appConfig->saveSettings();
|
m_appConfig->saveSettings();
|
||||||
|
|
||||||
|
std::pair<bool, QString> result;
|
||||||
try {
|
try {
|
||||||
QString serialKey = ui->m_pTextEditSerialKey->toPlainText();
|
QString serialKey = ui->m_pTextEditSerialKey->toPlainText();
|
||||||
m_subscriptionManager->setSerialKey(serialKey);
|
result = m_subscriptionManager->setSerialKey(serialKey);
|
||||||
}
|
}
|
||||||
catch (std::exception& e) {
|
catch (std::exception& e) {
|
||||||
message.critical(this, "Unknown Error",
|
message.critical(this, "Unknown Error",
|
||||||
tr("An error occurred while trying to activate Synergy. "
|
tr("An error occurred while trying to activate Synergy. "
|
||||||
"Please contact the helpdesk, and provide the "
|
"Please contact the helpdesk, and provide the "
|
||||||
"following details.\n\n%1").arg(e.what()));
|
"following information:\n\n%1").arg(e.what()));
|
||||||
refreshSerialKey();
|
refreshSerialKey();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_subscriptionManager->activeLicense() != kUnregistered) {
|
if (!result.first) {
|
||||||
|
message.critical(this, "Activation failed",
|
||||||
|
tr("%1").arg(result.second));
|
||||||
|
refreshSerialKey();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_subscriptionManager->activeEdition() != kUnregistered) {
|
||||||
message.information(this, "Activated!",
|
message.information(this, "Activated!",
|
||||||
tr("Thanks for activating %1!").arg
|
tr("Thanks for activating %1!").arg
|
||||||
(getEditionName(m_subscriptionManager->activeLicense())));
|
(m_subscriptionManager->activeEditionName()));
|
||||||
}
|
}
|
||||||
|
|
||||||
QDialog::accept();
|
QDialog::accept();
|
||||||
}
|
}
|
||||||
|
|
|
@ -154,7 +154,7 @@ MainWindow::MainWindow(QSettings& settings, AppConfig& appConfig,
|
||||||
connect (m_AppConfig, SIGNAL(sslToggled(bool)),
|
connect (m_AppConfig, SIGNAL(sslToggled(bool)),
|
||||||
this, SLOT(sslToggled(bool)), Qt::QueuedConnection);
|
this, SLOT(sslToggled(bool)), Qt::QueuedConnection);
|
||||||
|
|
||||||
m_SubscriptionManager->update();
|
m_SubscriptionManager->refresh();
|
||||||
}
|
}
|
||||||
|
|
||||||
MainWindow::~MainWindow()
|
MainWindow::~MainWindow()
|
||||||
|
@ -547,6 +547,10 @@ void MainWindow::startSynergy()
|
||||||
|
|
||||||
args << "--name" << getScreenName();
|
args << "--name" << getScreenName();
|
||||||
|
|
||||||
|
if (!appConfig().serialKey().isEmpty()) {
|
||||||
|
args << "--serial-key " << appConfig().serialKey();
|
||||||
|
}
|
||||||
|
|
||||||
if (desktopMode)
|
if (desktopMode)
|
||||||
{
|
{
|
||||||
setSynergyProcess(new QProcess(this));
|
setSynergyProcess(new QProcess(this));
|
||||||
|
@ -1038,7 +1042,7 @@ void MainWindow::serverDetected(const QString name)
|
||||||
|
|
||||||
void MainWindow::setEdition(Edition edition)
|
void MainWindow::setEdition(Edition edition)
|
||||||
{
|
{
|
||||||
setWindowTitle(getEditionName(edition));
|
setWindowTitle(m_SubscriptionManager->getEditionName (edition));
|
||||||
if (m_AppConfig->getCryptoEnabled()) {
|
if (m_AppConfig->getCryptoEnabled()) {
|
||||||
m_pSslCertificate = new SslCertificate(this);
|
m_pSslCertificate = new SslCertificate(this);
|
||||||
m_pSslCertificate->generateCertificate();
|
m_pSslCertificate->generateCertificate();
|
||||||
|
@ -1050,8 +1054,19 @@ void MainWindow::setEdition(Edition edition)
|
||||||
void MainWindow::beginTrial(bool isExpiring)
|
void MainWindow::beginTrial(bool isExpiring)
|
||||||
{
|
{
|
||||||
if (isExpiring) {
|
if (isExpiring) {
|
||||||
|
QString expiringNotice = "<html><head/><body><p><span style=\""
|
||||||
|
"font-weight:600;\">%1</span> days of "
|
||||||
|
"your Synergy Pro trial remain. <a href="
|
||||||
|
"\"http://symless.com/pricing?src=gui\">"
|
||||||
|
"<span style=\"text-decoration: underline;"
|
||||||
|
" color:#0000ff;\">Buy now!</span></a>"
|
||||||
|
"</p></body></html>";
|
||||||
|
expiringNotice = expiringNotice.arg
|
||||||
|
(m_SubscriptionManager->serialKey().daysLeft(::time(0)));
|
||||||
|
this->m_trialLabel->setText(expiringNotice);
|
||||||
this->m_trialWidget->show();
|
this->m_trialWidget->show();
|
||||||
}
|
}
|
||||||
|
setWindowTitle (m_SubscriptionManager->activeEditionName());
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::endTrial(bool isExpired)
|
void MainWindow::endTrial(bool isExpired)
|
||||||
|
@ -1059,6 +1074,7 @@ void MainWindow::endTrial(bool isExpired)
|
||||||
if (!isExpired) {
|
if (!isExpired) {
|
||||||
this->m_trialWidget->hide();
|
this->m_trialWidget->hide();
|
||||||
}
|
}
|
||||||
|
setWindowTitle (m_SubscriptionManager->activeEditionName());
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::updateLocalFingerprint()
|
void MainWindow::updateLocalFingerprint()
|
||||||
|
|
|
@ -43,19 +43,6 @@ void setIndexFromItemData(QComboBox* comboBox, const QVariant& itemData)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
QString
|
|
||||||
getEditionName (int edition) {
|
|
||||||
if (edition == kBasic) {
|
|
||||||
return "Synergy Basic";
|
|
||||||
}
|
|
||||||
else if (edition == kPro) {
|
|
||||||
return "Synergy Pro";
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return "Synergy (UNREGISTERED)";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
QString hash(const QString& string)
|
QString hash(const QString& string)
|
||||||
{
|
{
|
||||||
QByteArray data = string.toUtf8();
|
QByteArray data = string.toUtf8();
|
||||||
|
|
|
@ -29,4 +29,3 @@ QString hash(const QString& string);
|
||||||
QString getFirstMacAddress();
|
QString getFirstMacAddress();
|
||||||
qProcessorArch getProcessorArch();
|
qProcessorArch getProcessorArch();
|
||||||
QString getOSInformation();
|
QString getOSInformation();
|
||||||
QString getEditionName (int edition);
|
|
||||||
|
|
|
@ -20,6 +20,7 @@
|
||||||
#include "AppConfig.h"
|
#include "AppConfig.h"
|
||||||
#include <ctime>
|
#include <ctime>
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
|
#include <utility>
|
||||||
#include <QThread>
|
#include <QThread>
|
||||||
|
|
||||||
SubscriptionManager::SubscriptionManager(AppConfig* appConfig) :
|
SubscriptionManager::SubscriptionManager(AppConfig* appConfig) :
|
||||||
|
@ -28,18 +29,24 @@ SubscriptionManager::SubscriptionManager(AppConfig* appConfig) :
|
||||||
try {
|
try {
|
||||||
setSerialKey(m_AppConfig->serialKey());
|
setSerialKey(m_AppConfig->serialKey());
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
|
/* Remove garbage serial keys from the registry */
|
||||||
m_AppConfig->setSerialKey("");
|
m_AppConfig->setSerialKey("");
|
||||||
|
m_AppConfig->setEdition(kUnregistered);
|
||||||
m_AppConfig->saveSettings();
|
m_AppConfig->saveSettings();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SerialKey
|
std::pair<bool, QString>
|
||||||
SubscriptionManager::setSerialKey(QString serialKeyString)
|
SubscriptionManager::setSerialKey(QString serialKeyString)
|
||||||
{
|
{
|
||||||
|
std::pair<bool, QString> ret (true, "");
|
||||||
|
|
||||||
SerialKey serialKey (serialKeyString.toStdString());
|
SerialKey serialKey (serialKeyString.toStdString());
|
||||||
if (!serialKey.isValid (::time(0))) {
|
if (serialKey.isExpired(::time(0))) {
|
||||||
throw std::runtime_error ("Invalid serial key");
|
ret.first = false;
|
||||||
}
|
ret.second = "Serial key expired";
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
if (serialKey != m_serialKey) {
|
if (serialKey != m_serialKey) {
|
||||||
using std::swap;
|
using std::swap;
|
||||||
|
@ -65,15 +72,28 @@ SubscriptionManager::setSerialKey(QString serialKeyString)
|
||||||
m_AppConfig->saveSettings();
|
m_AppConfig->saveSettings();
|
||||||
}
|
}
|
||||||
|
|
||||||
return serialKey;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
Edition SubscriptionManager::activeLicense() const
|
Edition
|
||||||
|
SubscriptionManager::activeEdition() const
|
||||||
{
|
{
|
||||||
return m_serialKey.edition();
|
return m_serialKey.edition();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SubscriptionManager::update() const
|
QString
|
||||||
|
SubscriptionManager::activeEditionName() const
|
||||||
|
{
|
||||||
|
return getEditionName(activeEdition(), m_serialKey.isTrial());
|
||||||
|
}
|
||||||
|
|
||||||
|
SerialKey
|
||||||
|
SubscriptionManager::serialKey() const
|
||||||
|
{
|
||||||
|
return m_serialKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SubscriptionManager::refresh() const
|
||||||
{
|
{
|
||||||
emit serialKeyChanged (m_serialKey);
|
emit serialKeyChanged (m_serialKey);
|
||||||
emit editionChanged (m_serialKey.edition());
|
emit editionChanged (m_serialKey.edition());
|
||||||
|
@ -84,7 +104,27 @@ void SubscriptionManager::update() const
|
||||||
|
|
||||||
void SubscriptionManager::skipActivation()
|
void SubscriptionManager::skipActivation()
|
||||||
{
|
{
|
||||||
notifyActivation ("skip:unknown");
|
notifyActivation ("skip:unknown");
|
||||||
|
}
|
||||||
|
|
||||||
|
QString
|
||||||
|
SubscriptionManager::getEditionName(Edition const edition, bool trial)
|
||||||
|
{
|
||||||
|
std::string name ("Synergy ");
|
||||||
|
switch (edition) {
|
||||||
|
case kUnregistered:
|
||||||
|
name += "(UNREGISTERED)";
|
||||||
|
return QString::fromUtf8 (name.c_str(), name.size());
|
||||||
|
case kBasic:
|
||||||
|
name += "Basic";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
name += "Pro";
|
||||||
|
}
|
||||||
|
if (trial) {
|
||||||
|
name += " (Trial)";
|
||||||
|
}
|
||||||
|
return QString::fromUtf8 (name.c_str(), name.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
void SubscriptionManager::notifyActivation(QString identity)
|
void SubscriptionManager::notifyActivation(QString identity)
|
||||||
|
|
|
@ -20,6 +20,7 @@
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
#include <SerialKey.h>
|
#include <SerialKey.h>
|
||||||
#include <ActivationNotifier.h>
|
#include <ActivationNotifier.h>
|
||||||
|
#include <utility>
|
||||||
|
|
||||||
class AppConfig;
|
class AppConfig;
|
||||||
|
|
||||||
|
@ -29,10 +30,13 @@ class SubscriptionManager: public QObject
|
||||||
|
|
||||||
public:
|
public:
|
||||||
SubscriptionManager(AppConfig* appConfig);
|
SubscriptionManager(AppConfig* appConfig);
|
||||||
SerialKey setSerialKey(QString serialKey);
|
std::pair<bool, QString> setSerialKey(QString serialKey);
|
||||||
void update() const;
|
void refresh() const;
|
||||||
Edition activeLicense() const;
|
Edition activeEdition() const;
|
||||||
|
QString activeEditionName() const;
|
||||||
|
SerialKey serialKey() const;
|
||||||
void skipActivation();
|
void skipActivation();
|
||||||
|
static QString getEditionName(Edition edition, bool trial = false);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void notifyActivation(QString identity);
|
void notifyActivation(QString identity);
|
||||||
|
|
|
@ -22,6 +22,9 @@
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <climits>
|
#include <climits>
|
||||||
|
#include <sstream>
|
||||||
|
#include <iomanip>
|
||||||
|
#include <stdexcept>
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
|
@ -47,6 +50,9 @@ SerialKey::SerialKey(std::string serial) :
|
||||||
if (!plainText.empty()) {
|
if (!plainText.empty()) {
|
||||||
parse(plainText);
|
parse(plainText);
|
||||||
}
|
}
|
||||||
|
if (!m_valid) {
|
||||||
|
throw std::runtime_error ("Invalid serial key");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
|
@ -105,7 +111,51 @@ SerialKey::isTrial() const
|
||||||
Edition
|
Edition
|
||||||
SerialKey::edition() const
|
SerialKey::edition() const
|
||||||
{
|
{
|
||||||
return m_edition;
|
return m_edition;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string
|
||||||
|
SerialKey::editionString() const
|
||||||
|
{
|
||||||
|
switch (edition()) {
|
||||||
|
case kBasic:
|
||||||
|
return "basic";
|
||||||
|
case kPro:
|
||||||
|
return "pro";
|
||||||
|
default: {
|
||||||
|
std::ostringstream oss;
|
||||||
|
oss << static_cast<int>(edition());
|
||||||
|
return oss.str();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::string
|
||||||
|
hexEncode (std::string const& str) {
|
||||||
|
std::ostringstream oss;
|
||||||
|
for (size_t i = 0; i < str.size(); ++i) {
|
||||||
|
int c = str[i];
|
||||||
|
oss << std::setfill('0') << std::hex << std::setw(2)
|
||||||
|
<< std::uppercase;
|
||||||
|
oss << c;
|
||||||
|
}
|
||||||
|
return oss.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string
|
||||||
|
SerialKey::toString() const
|
||||||
|
{
|
||||||
|
std::ostringstream oss;
|
||||||
|
oss << "v2;";
|
||||||
|
oss << (isTrial() ? "trial" : "lifetime") << ";";
|
||||||
|
oss << editionString() << ";";
|
||||||
|
oss << m_name << ";";
|
||||||
|
oss << m_userLimit << ";";
|
||||||
|
oss << m_email << ";";
|
||||||
|
oss << m_company << ";";
|
||||||
|
oss << m_warnTime << ";";
|
||||||
|
oss << m_expireTime;
|
||||||
|
return hexEncode(oss.str());
|
||||||
}
|
}
|
||||||
|
|
||||||
time_t
|
time_t
|
||||||
|
@ -118,10 +168,16 @@ SerialKey::daysLeft(time_t currentTime) const
|
||||||
timeLeft = m_expireTime - currentTime;
|
timeLeft = m_expireTime - currentTime;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned long long dayLeft = 0;
|
unsigned long long daysLeft = 0;
|
||||||
dayLeft = timeLeft % day != 0 ? 1 : 0;
|
daysLeft = timeLeft % day != 0 ? 1 : 0;
|
||||||
|
|
||||||
return timeLeft / day + dayLeft;
|
return timeLeft / day + daysLeft;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string
|
||||||
|
SerialKey::email() const
|
||||||
|
{
|
||||||
|
return m_email;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string
|
std::string
|
||||||
|
@ -208,7 +264,7 @@ SerialKey::parse(std::string plainSerial)
|
||||||
}
|
}
|
||||||
|
|
||||||
Edition
|
Edition
|
||||||
SerialKey::parseEdition(std::string editionStr)
|
SerialKey::parseEdition(std::string const& editionStr)
|
||||||
{
|
{
|
||||||
Edition e = kBasic;
|
Edition e = kBasic;
|
||||||
if (editionStr == "pro") {
|
if (editionStr == "pro") {
|
||||||
|
|
|
@ -36,12 +36,15 @@ public:
|
||||||
bool isExpired(time_t currentTime) const;
|
bool isExpired(time_t currentTime) const;
|
||||||
bool isTrial() const;
|
bool isTrial() const;
|
||||||
time_t daysLeft(time_t currentTime) const;
|
time_t daysLeft(time_t currentTime) const;
|
||||||
|
std::string email() const;
|
||||||
Edition edition() const;
|
Edition edition() const;
|
||||||
|
std::string toString() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::string decode(const std::string& serial) const;
|
std::string decode(const std::string& serial) const;
|
||||||
void parse(std::string plainSerial);
|
void parse(std::string plainSerial);
|
||||||
Edition parseEdition(std::string editionStr);
|
Edition parseEdition(const std::string& editionStr);
|
||||||
|
std::string editionString() const;
|
||||||
|
|
||||||
#ifdef TEST_ENV
|
#ifdef TEST_ENV
|
||||||
private:
|
private:
|
||||||
|
|
Loading…
Reference in New Issue