#5657 Make trial expiry notification live

This commit is contained in:
Andrew Nelless 2016-10-17 15:26:42 +01:00
parent e05ced287c
commit 714b2f6440
9 changed files with 154 additions and 42 deletions

View File

@ -55,7 +55,7 @@
<item>
<widget class="QLabel" name="m_trialLabel">
<property name="text">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;span style=&quot; font-weight:600;&quot;&gt;6&lt;/span&gt; days of your Synergy Pro trial remain. &lt;a href=&quot;http://symless.com/pricing?src=gui&quot;&gt;&lt;span style=&quot; text-decoration: underline; color:#0000ff;&quot;&gt;Buy now!&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;span style=&quot; font-weight:600;&quot;&gt;%1&lt;/span&gt; days of your Synergy Pro trial remain. &lt;a href=&quot;http://symless.com/pricing?src=gui&quot;&gt;&lt;span style=&quot; text-decoration: underline; color:#0000ff;&quot;&gt;Buy now!&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="openExternalLinks">
<bool>true</bool>

View File

@ -39,7 +39,7 @@ ActivationDialog::~ActivationDialog()
void ActivationDialog::reject()
{
if (m_subscriptionManager->activeLicense() == kUnregistered) {
if (m_subscriptionManager->activeEdition() == kUnregistered) {
CancelActivationDialog cancelActivationDialog(this);
if (QDialog::Accepted == cancelActivationDialog.exec()) {
m_subscriptionManager->skipActivation();
@ -53,28 +53,35 @@ void ActivationDialog::reject()
void ActivationDialog::accept()
{
QMessageBox message;
QString error;
m_appConfig->activationHasRun(true);
m_appConfig->saveSettings();
std::pair<bool, QString> result;
try {
QString serialKey = ui->m_pTextEditSerialKey->toPlainText();
m_subscriptionManager->setSerialKey(serialKey);
result = m_subscriptionManager->setSerialKey(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()));
"following information:\n\n%1").arg(e.what()));
refreshSerialKey();
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!",
tr("Thanks for activating %1!").arg
(getEditionName(m_subscriptionManager->activeLicense())));
(m_subscriptionManager->activeEditionName()));
}
QDialog::accept();
}

View File

@ -154,7 +154,7 @@ MainWindow::MainWindow(QSettings& settings, AppConfig& appConfig,
connect (m_AppConfig, SIGNAL(sslToggled(bool)),
this, SLOT(sslToggled(bool)), Qt::QueuedConnection);
m_SubscriptionManager->update();
m_SubscriptionManager->refresh();
}
MainWindow::~MainWindow()
@ -547,6 +547,10 @@ void MainWindow::startSynergy()
args << "--name" << getScreenName();
if (!appConfig().serialKey().isEmpty()) {
args << "--serial-key " << appConfig().serialKey();
}
if (desktopMode)
{
setSynergyProcess(new QProcess(this));
@ -1038,7 +1042,7 @@ void MainWindow::serverDetected(const QString name)
void MainWindow::setEdition(Edition edition)
{
setWindowTitle(getEditionName(edition));
setWindowTitle(m_SubscriptionManager->getEditionName (edition));
if (m_AppConfig->getCryptoEnabled()) {
m_pSslCertificate = new SslCertificate(this);
m_pSslCertificate->generateCertificate();
@ -1050,8 +1054,19 @@ void MainWindow::setEdition(Edition edition)
void MainWindow::beginTrial(bool 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();
}
setWindowTitle (m_SubscriptionManager->activeEditionName());
}
void MainWindow::endTrial(bool isExpired)
@ -1059,6 +1074,7 @@ void MainWindow::endTrial(bool isExpired)
if (!isExpired) {
this->m_trialWidget->hide();
}
setWindowTitle (m_SubscriptionManager->activeEditionName());
}
void MainWindow::updateLocalFingerprint()

View File

@ -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)
{
QByteArray data = string.toUtf8();

View File

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

View File

@ -20,6 +20,7 @@
#include "AppConfig.h"
#include <ctime>
#include <stdexcept>
#include <utility>
#include <QThread>
SubscriptionManager::SubscriptionManager(AppConfig* appConfig) :
@ -28,18 +29,24 @@ SubscriptionManager::SubscriptionManager(AppConfig* appConfig) :
try {
setSerialKey(m_AppConfig->serialKey());
} catch (...) {
/* Remove garbage serial keys from the registry */
m_AppConfig->setSerialKey("");
m_AppConfig->setEdition(kUnregistered);
m_AppConfig->saveSettings();
}
}
SerialKey
std::pair<bool, QString>
SubscriptionManager::setSerialKey(QString serialKeyString)
{
std::pair<bool, QString> ret (true, "");
SerialKey serialKey (serialKeyString.toStdString());
if (!serialKey.isValid (::time(0))) {
throw std::runtime_error ("Invalid serial key");
}
if (serialKey.isExpired(::time(0))) {
ret.first = false;
ret.second = "Serial key expired";
return ret;
}
if (serialKey != m_serialKey) {
using std::swap;
@ -65,15 +72,28 @@ SubscriptionManager::setSerialKey(QString serialKeyString)
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 editionChanged (m_serialKey.edition());
@ -84,7 +104,27 @@ void SubscriptionManager::update() const
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)

View File

@ -20,6 +20,7 @@
#include <QObject>
#include <SerialKey.h>
#include <ActivationNotifier.h>
#include <utility>
class AppConfig;
@ -29,10 +30,13 @@ class SubscriptionManager: public QObject
public:
SubscriptionManager(AppConfig* appConfig);
SerialKey setSerialKey(QString serialKey);
void update() const;
Edition activeLicense() const;
std::pair<bool, QString> setSerialKey(QString serialKey);
void refresh() const;
Edition activeEdition() const;
QString activeEditionName() const;
SerialKey serialKey() const;
void skipActivation();
static QString getEditionName(Edition edition, bool trial = false);
private:
void notifyActivation(QString identity);

View File

@ -22,6 +22,9 @@
#include <algorithm>
#include <vector>
#include <climits>
#include <sstream>
#include <iomanip>
#include <stdexcept>
using namespace std;
@ -47,6 +50,9 @@ SerialKey::SerialKey(std::string serial) :
if (!plainText.empty()) {
parse(plainText);
}
if (!m_valid) {
throw std::runtime_error ("Invalid serial key");
}
}
bool
@ -105,7 +111,51 @@ SerialKey::isTrial() const
Edition
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
@ -118,10 +168,16 @@ SerialKey::daysLeft(time_t currentTime) const
timeLeft = m_expireTime - currentTime;
}
unsigned long long dayLeft = 0;
dayLeft = timeLeft % day != 0 ? 1 : 0;
unsigned long long daysLeft = 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
@ -208,7 +264,7 @@ SerialKey::parse(std::string plainSerial)
}
Edition
SerialKey::parseEdition(std::string editionStr)
SerialKey::parseEdition(std::string const& editionStr)
{
Edition e = kBasic;
if (editionStr == "pro") {

View File

@ -36,12 +36,15 @@ public:
bool isExpired(time_t currentTime) const;
bool isTrial() const;
time_t daysLeft(time_t currentTime) const;
std::string email() const;
Edition edition() const;
std::string toString() const;
private:
std::string decode(const std::string& serial) const;
void parse(std::string plainSerial);
Edition parseEdition(std::string editionStr);
Edition parseEdition(const std::string& editionStr);
std::string editionString() const;
#ifdef TEST_ENV
private: