Improve UI design and reduce over-use of #ifdef (#7413)
* Rename `LicenseManager` to `License` * Rename `LicenseManager` to `License` * Move License class to gui lib * Rename license related classes * Refactor serial key parsing * Don't fail fast on containers * Move licensed product name from config to code * Fixed formatting * Update code coverage generator and fixed args * WIP: Converting license to chrono * WIP: Fixed compile errors, tests failing * Fixed all serial key and license tests * Disable verbose logging * Add missing </p> * Add missing include * Revert code coverage config * Handle parse errors * Move more classes into the new gui lib and improve license/serial object ownership * WIP: Fixing signal/slots in MainWindow * Fixed slot for about to quit * Rename manual slots to solve auto-connection warnings * Fixed logging issue * By default, don't close to tray * Add .env support and furthe refactor license code, also fixed some copyright dates * Remove test code * Fixed memory error in .env parser and refactor more licensing display code * Fixed color inconsistencies * Fixed link colors and made log view expand * Disable server components rather than hiding * Reset years of blind UI layout fiddling * Fixed clean Qt task * Only show notice when time limited * Fixed main window layout * Show connected clients * Set 15 spacing * Auto connect on start * More intentional screen size * Fixed tests related to license * Tests for expiry notifications * Reorg tests and remove death test * Update gtest * Tests for dotenv parser * Test command process * What the heck is that doing there? * Merge constants headers * Fixed magic includes * Remove helper function * Remove comment * Remove extern decl * Update ChangeLog
This commit is contained in:
parent
ce3f8869e7
commit
9315b089c8
143 changed files with 3732 additions and 3680 deletions
10
.env.example
10
.env.example
|
|
@ -2,6 +2,16 @@
|
|||
# Usage: Copy this .env.example file to .env
|
||||
#
|
||||
|
||||
#
|
||||
# App
|
||||
#
|
||||
|
||||
# Serial key value to pre-fill the activation dialog
|
||||
# SYNERGY_TEST_SERIAL_KEY="DEADBEEF"
|
||||
|
||||
# Version checker URL to use (useful for testing)
|
||||
# SYNERGY_VERSION_URL="http://localhost:8787?version=v1"
|
||||
|
||||
#
|
||||
# Build
|
||||
#
|
||||
|
|
|
|||
3
.github/workflows/build-containers.yml
vendored
3
.github/workflows/build-containers.yml
vendored
|
|
@ -21,6 +21,9 @@ jobs:
|
|||
timeout-minutes: 10
|
||||
|
||||
strategy:
|
||||
# Build all images even if some fail.
|
||||
fail-fast: false
|
||||
|
||||
matrix:
|
||||
os:
|
||||
- name: debian-12-amd64
|
||||
|
|
|
|||
4
.vscode/settings.json
vendored
Normal file
4
.vscode/settings.json
vendored
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
{
|
||||
"sonarlint.pathToCompileCommands": "${workspaceFolder}/build/compile_commands.json",
|
||||
"gcovViewer.buildDirectories": ["${workspaceFolder}/build/src/lib"]
|
||||
}
|
||||
58
.vscode/tasks.json
vendored
58
.vscode/tasks.json
vendored
|
|
@ -10,6 +10,13 @@
|
|||
"group": {
|
||||
"kind": "build",
|
||||
"isDefault": true
|
||||
},
|
||||
"problemMatcher": {
|
||||
"base": "$gcc",
|
||||
"fileLocation": ["absolute"]
|
||||
},
|
||||
"presentation": {
|
||||
"revealProblems": "onProblem"
|
||||
}
|
||||
},
|
||||
{
|
||||
|
|
@ -20,6 +27,38 @@
|
|||
"preset": "${command:cmake.activeBuildPresetName}",
|
||||
"group": "build"
|
||||
},
|
||||
{
|
||||
"label": "clean-gcda",
|
||||
"type": "shell",
|
||||
"command": "find . -name '*.gcda' -delete",
|
||||
"windows": {
|
||||
"command": "$null"
|
||||
},
|
||||
"presentation": {
|
||||
"reveal": "silent"
|
||||
}
|
||||
},
|
||||
{
|
||||
"label": "clean-qt",
|
||||
"type": "shell",
|
||||
"command": "rm -r build/src/gui build/src/lib/gui",
|
||||
"windows": {
|
||||
"command": "remove-item -recurse build/src/gui,build/src/lib/gui"
|
||||
}
|
||||
},
|
||||
{
|
||||
"label": "clean-config",
|
||||
"type": "shell",
|
||||
"linux": {
|
||||
"command": "rm -r ~/.config/Synergy/Synergy.conf"
|
||||
},
|
||||
"windows": {
|
||||
"command": "remove-item -recurse $env:APPDATA\\Synergy\\Synergy"
|
||||
},
|
||||
"osx": {
|
||||
"command": "rm -r ~/Library/Application\\ Support/Synergy/Synergy"
|
||||
}
|
||||
},
|
||||
{
|
||||
"label": "tests",
|
||||
"dependsOn": ["integtests", "unittests"],
|
||||
|
|
@ -68,25 +107,6 @@
|
|||
"type": "shell",
|
||||
"command": "python scripts/daemon.py --stop"
|
||||
},
|
||||
{
|
||||
"label": "clean-gcda",
|
||||
"type": "shell",
|
||||
"command": "find . -name '*.gcda' -delete",
|
||||
"windows": {
|
||||
"command": "$null"
|
||||
},
|
||||
"presentation": {
|
||||
"reveal": "silent"
|
||||
}
|
||||
},
|
||||
{
|
||||
"label": "clean-qt",
|
||||
"type": "shell",
|
||||
"command": "rm -r build/src/gui",
|
||||
"windows": {
|
||||
"command": "remove-item -recurse build/src/gui"
|
||||
}
|
||||
},
|
||||
{
|
||||
"label": "unittests (current)",
|
||||
"type": "shell",
|
||||
|
|
|
|||
|
|
@ -59,6 +59,7 @@ Enhancements:
|
|||
- #7406 Migrate scripts from `requirements.txt` to `pyproject.toml`
|
||||
- #7407 Implement safer memory use, improve dev env, fixed GUI bugs
|
||||
- #7412 Reduce GUI compile time by building a GUI library
|
||||
- #7413 Improve UI design and reduce over-use of `#ifdef`
|
||||
|
||||
# 1.14.6
|
||||
|
||||
|
|
|
|||
|
|
@ -53,6 +53,9 @@ macro(configure_definitions)
|
|||
if(NOT "$ENV{SYNERGY_PRODUCT_NAME}" STREQUAL "")
|
||||
set(PRODUCT_NAME $ENV{SYNERGY_PRODUCT_NAME})
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(PRODUCT_NAME)
|
||||
message(STATUS "Product name: ${PRODUCT_NAME}")
|
||||
add_definitions(-DSYNERGY_PRODUCT_NAME="${PRODUCT_NAME}")
|
||||
endif()
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
Subproject commit 18f8200e3079b0e54fa00cb7ac55d4c39dcf6da6
|
||||
Subproject commit e39786088138f2749d64e9e90e0f9902daa77c40
|
||||
|
|
@ -36,7 +36,8 @@ target_link_libraries(
|
|||
net
|
||||
platform
|
||||
synlib
|
||||
shared
|
||||
global
|
||||
license
|
||||
${libs})
|
||||
|
||||
post_config()
|
||||
|
|
|
|||
|
|
@ -28,18 +28,12 @@ file(
|
|||
src/validators/*
|
||||
src/widgets/*)
|
||||
file(GLOB GUI_UI_FILES src/*.ui)
|
||||
file(GLOB ACTIVATION_FILES src/*Activation* src/*License*)
|
||||
|
||||
if(${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
|
||||
file(GLOB GUI_MAC_SOURCE_FILES src/*.mm)
|
||||
list(APPEND GUI_SOURCE_FILES ${GUI_MAC_SOURCE_FILES})
|
||||
endif()
|
||||
|
||||
if(NOT ENABLE_LICENSING)
|
||||
list(REMOVE_ITEM GUI_SOURCE_FILES ${ACTIVATION_FILES})
|
||||
list(REMOVE_ITEM GUI_UI_FILES ${ACTIVATION_FILES})
|
||||
endif()
|
||||
|
||||
if(WIN32)
|
||||
set(GUI_RC_FILES res/win/Synergy.rc ${CMAKE_BINARY_DIR}/src/version.rc)
|
||||
endif()
|
||||
|
|
@ -56,8 +50,9 @@ include_directories(./src)
|
|||
|
||||
target_link_libraries(
|
||||
${target}
|
||||
shared
|
||||
gui
|
||||
global
|
||||
license
|
||||
Qt6::Core
|
||||
Qt6::Widgets
|
||||
Qt6::Network)
|
||||
|
|
|
|||
|
|
@ -18,21 +18,27 @@
|
|||
|
||||
#include "AboutDialog.h"
|
||||
|
||||
#include <QDateTime>
|
||||
|
||||
#if defined(Q_OS_MAC)
|
||||
#include "OSXHelpers.h"
|
||||
#endif
|
||||
|
||||
#ifdef GIT_SHA_SHORT
|
||||
const QString kVersionAppend = GIT_SHA_SHORT;
|
||||
#else
|
||||
const QString kVersionAppend;
|
||||
#endif
|
||||
|
||||
AboutDialog::AboutDialog(MainWindow *parent, const AppConfig &config)
|
||||
: QDialog(parent, Qt::WindowTitleHint | Qt::WindowSystemMenuHint),
|
||||
Ui::AboutDialogBase() {
|
||||
setupUi(this);
|
||||
|
||||
m_versionChecker.setApp(parent->appPath(config.coreClientName()));
|
||||
|
||||
QString version = SYNERGY_VERSION;
|
||||
#ifdef GIT_SHA_SHORT
|
||||
version += " (" GIT_SHA_SHORT ")";
|
||||
#endif
|
||||
QString version(SYNERGY_VERSION);
|
||||
if (!kVersionAppend.isEmpty()) {
|
||||
version.append(QString(" (%1)").arg(kVersionAppend));
|
||||
}
|
||||
|
||||
m_pLabelSynergyVersion->setText(version);
|
||||
|
||||
|
|
@ -84,7 +90,7 @@ QString AboutDialog::getImportantDevelopers() const {
|
|||
|
||||
// Symless employees
|
||||
"Kyle Bloom, Daun Chung, Serhii Hadzhylov, "
|
||||
"Oleksandr Lysytsia, Olena Kutytska, Francisco Magalhães.");
|
||||
"Oleksandr Lysytsia, Olena Kutytska.");
|
||||
}
|
||||
|
||||
QString AboutDialog::getCopyright() const {
|
||||
|
|
|
|||
|
|
@ -16,45 +16,64 @@
|
|||
*/
|
||||
|
||||
#include "ActivationDialog.h"
|
||||
|
||||
#include "gui/license_notices.h"
|
||||
#include "ui_ActivationDialog.h"
|
||||
|
||||
#include "AppConfig.h"
|
||||
#include "CancelActivationDialog.h"
|
||||
#include "LicenseManager.h"
|
||||
#include "MainWindow.h"
|
||||
#include "shared/EditionType.h"
|
||||
#include "ui_ActivationDialog.h"
|
||||
#include "gui/LicenseHandler.h"
|
||||
#include "gui/constants.h"
|
||||
#include "gui/license_notices.h"
|
||||
#include "license/ProductEdition.h"
|
||||
#include "license/parse_serial_key.h"
|
||||
|
||||
#include <QApplication>
|
||||
#include <QMessageBox>
|
||||
#include <QThread>
|
||||
|
||||
using namespace synergy::gui;
|
||||
using namespace synergy::license;
|
||||
|
||||
ActivationDialog::ActivationDialog(
|
||||
QWidget *parent, AppConfig &appConfig, LicenseManager &licenseManager)
|
||||
QWidget *parent, AppConfig &appConfig, LicenseHandler &licenseHandler)
|
||||
: QDialog(parent),
|
||||
ui(new Ui::ActivationDialog),
|
||||
m_appConfig(&appConfig),
|
||||
m_LicenseManager(&licenseManager) {
|
||||
ui->setupUi(this);
|
||||
m_ui(new Ui::ActivationDialog),
|
||||
m_pAppConfig(&appConfig),
|
||||
m_licenseHandler(licenseHandler) {
|
||||
|
||||
m_ui->setupUi(this);
|
||||
refreshSerialKey();
|
||||
time_t currentTime = ::time(0);
|
||||
if (!m_LicenseManager->serialKey().isExpired(currentTime)) {
|
||||
ui->m_trialWidget->hide();
|
||||
|
||||
if (!m_licenseHandler.license().isExpired()) {
|
||||
m_ui->m_widgetNotice->hide();
|
||||
}
|
||||
|
||||
const QString envSerialKey = ::getenv("SYNERGY_TEST_SERIAL_KEY");
|
||||
if (!envSerialKey.isEmpty()) {
|
||||
qDebug() << "using env test serial key:" << envSerialKey;
|
||||
m_ui->m_pTextEditSerialKey->setText(envSerialKey);
|
||||
}
|
||||
}
|
||||
|
||||
void ActivationDialog::refreshSerialKey() {
|
||||
ui->m_pTextEditSerialKey->setText(m_appConfig->serialKey());
|
||||
ui->m_pTextEditSerialKey->setFocus();
|
||||
ui->m_pTextEditSerialKey->moveCursor(QTextCursor::End);
|
||||
ui->m_trialLabel->setText(
|
||||
tr(m_LicenseManager->getLicenseNotice().toStdString().c_str()));
|
||||
m_ui->m_pTextEditSerialKey->setText(m_pAppConfig->serialKey());
|
||||
m_ui->m_pTextEditSerialKey->setFocus();
|
||||
m_ui->m_pTextEditSerialKey->moveCursor(QTextCursor::End);
|
||||
|
||||
const auto &license = m_licenseHandler.license();
|
||||
if (license.isTimeLimited()) {
|
||||
m_ui->m_labelNotice->setText(licenseNotice(license));
|
||||
}
|
||||
}
|
||||
|
||||
ActivationDialog::~ActivationDialog() { delete ui; }
|
||||
ActivationDialog::~ActivationDialog() { delete m_ui; }
|
||||
|
||||
void ActivationDialog::reject() {
|
||||
// don't show the cancel confirmation dialog if they've already registered,
|
||||
// since it's not revent to customers who are changing their serial key.
|
||||
if (m_LicenseManager->activeEdition() != kUnregistered) {
|
||||
if (m_licenseHandler.productEdition() != Edition::kUnregistered) {
|
||||
QDialog::reject();
|
||||
return;
|
||||
}
|
||||
|
|
@ -67,56 +86,105 @@ void ActivationDialog::reject() {
|
|||
}
|
||||
|
||||
void ActivationDialog::accept() {
|
||||
QMessageBox message;
|
||||
m_appConfig->setActivationHasRun(true);
|
||||
using Result = LicenseHandler::ChangeSerialKeyResult;
|
||||
auto serialKey = m_ui->m_pTextEditSerialKey->toPlainText();
|
||||
|
||||
try {
|
||||
SerialKey serialKey(
|
||||
ui->m_pTextEditSerialKey->toPlainText().trimmed().toStdString());
|
||||
m_LicenseManager->setSerialKey(serialKey);
|
||||
} catch (std::exception &e) {
|
||||
message.critical(
|
||||
this, "Activation failed",
|
||||
tr("An error occurred while trying to activate Synergy. "
|
||||
"<a href=\"https://symless.com/synergy/contact-support?source=gui\" "
|
||||
"style=\"text-decoration: none; color: #4285F4;\">"
|
||||
"Please contact the helpdesk</a>, and provide the following "
|
||||
"information:"
|
||||
"<br><br>%1")
|
||||
.arg(e.what()));
|
||||
refreshSerialKey();
|
||||
if (serialKey.isEmpty()) {
|
||||
QMessageBox::information(this, "Activation", "Please enter a serial key.");
|
||||
return;
|
||||
}
|
||||
|
||||
m_LicenseManager->notifyActivation("serial:" + m_appConfig->serialKey());
|
||||
Edition edition = m_LicenseManager->activeEdition();
|
||||
time_t daysLeft = m_LicenseManager->serialKey().daysLeft(::time(0));
|
||||
if (edition != kUnregistered) {
|
||||
QString thanksMessage = tr("Thanks for trying %1! %5\n\n%2 day%3 of "
|
||||
"your trial remain%4")
|
||||
.arg(m_LicenseManager->getEditionName(edition))
|
||||
.arg(daysLeft)
|
||||
.arg((daysLeft == 1) ? "" : "s")
|
||||
.arg((daysLeft == 1) ? "s" : "");
|
||||
|
||||
if (m_appConfig->cryptoAvailable()) {
|
||||
m_appConfig->generateCertificate();
|
||||
thanksMessage =
|
||||
thanksMessage.arg("If you're using SSL, "
|
||||
"remember to activate all of your devices.");
|
||||
} else {
|
||||
thanksMessage = thanksMessage.arg("");
|
||||
try {
|
||||
const auto result = m_licenseHandler.changeSerialKey(serialKey);
|
||||
if (result != Result::kSuccess) {
|
||||
showResultDialog(result);
|
||||
return;
|
||||
}
|
||||
} catch (const SerialKeyParseError &e) {
|
||||
showErrorDialog(e.what());
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_LicenseManager->serialKey().isTrial()) {
|
||||
message.information(this, "Thanks!", thanksMessage);
|
||||
} else {
|
||||
message.information(
|
||||
this, "Activated!",
|
||||
tr("Thanks for activating %1!")
|
||||
.arg(m_LicenseManager->getEditionName(edition)));
|
||||
showSuccessDialog();
|
||||
m_pAppConfig->setActivationHasRun(true);
|
||||
QDialog::accept();
|
||||
}
|
||||
|
||||
void ActivationDialog::showResultDialog(
|
||||
LicenseHandler::ChangeSerialKeyResult result) {
|
||||
const QString title = "Activation result";
|
||||
|
||||
switch (result) {
|
||||
using enum LicenseHandler::ChangeSerialKeyResult;
|
||||
|
||||
case kUnchanged:
|
||||
QMessageBox::information(
|
||||
this, title,
|
||||
"Heads up, the serial key you entered was the same as last time.");
|
||||
break;
|
||||
|
||||
case kInvalid:
|
||||
QMessageBox::critical(
|
||||
this, title,
|
||||
QString("Invalid serial key. "
|
||||
R"(Please <a href="%1" style="%2">contact us</a> for help.)")
|
||||
.arg(kUrlContact)
|
||||
.arg(kLinkStyleSecondary));
|
||||
break;
|
||||
|
||||
case kExpired:
|
||||
QMessageBox::warning(
|
||||
this, title,
|
||||
QString("Sorry, that serial key has expired. "
|
||||
R"(Please <a href="%1" style="%1">renew</a> your license.)")
|
||||
.arg(kUrlPurchase)
|
||||
.arg(kLinkStyleSecondary));
|
||||
break;
|
||||
|
||||
default:
|
||||
qFatal("unexpected change serial key result: %d", static_cast<int>(result));
|
||||
}
|
||||
}
|
||||
|
||||
void ActivationDialog::showSuccessDialog() {
|
||||
const auto &license = m_licenseHandler.license();
|
||||
|
||||
QString title = "Activation successful";
|
||||
QString message = tr("<p>Thanks for activating %1.</p>")
|
||||
.arg(m_licenseHandler.productName());
|
||||
|
||||
TlsUtility tls(*m_pAppConfig, license);
|
||||
if (tls.isAvailableAndEnabled()) {
|
||||
message +=
|
||||
"<p>To ensure that TLS encryption works correctly, "
|
||||
"please activate all of your computers with the same serial key.</p>";
|
||||
}
|
||||
|
||||
if (license.isTimeLimited()) {
|
||||
auto daysLeft = license.daysLeft().count();
|
||||
if (license.isTrial()) {
|
||||
title = "Trial started";
|
||||
message += QString("Your trial will expire in %1 %2.")
|
||||
.arg(daysLeft)
|
||||
.arg((daysLeft == 1) ? "day" : "days");
|
||||
} else if (license.isSubscription()) {
|
||||
message += QString("Your license will expire in %1 %2.")
|
||||
.arg(daysLeft)
|
||||
.arg((daysLeft == 1) ? "day" : "days");
|
||||
}
|
||||
}
|
||||
|
||||
QDialog::accept();
|
||||
QMessageBox::information(this, title, message);
|
||||
}
|
||||
|
||||
void ActivationDialog::showErrorDialog(const QString &message) {
|
||||
QString fullMessage =
|
||||
QString("<p>There was a problem activating Synergy.</p>"
|
||||
R"(<p>Please <a href="%1" style="%2">contact us</a> )"
|
||||
"and provide the following information:</p>"
|
||||
"%3")
|
||||
.arg(kUrlContact)
|
||||
.arg(kLinkStyleSecondary)
|
||||
.arg(message);
|
||||
QMessageBox::critical(this, "Activation failed", fullMessage);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,7 +17,8 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include <LicenseManager.h>
|
||||
#include "gui/LicenseHandler.h"
|
||||
|
||||
#include <QDialog>
|
||||
|
||||
namespace Ui {
|
||||
|
|
@ -31,8 +32,14 @@ class ActivationDialog : public QDialog {
|
|||
|
||||
public:
|
||||
ActivationDialog(
|
||||
QWidget *parent, AppConfig &appConfig, LicenseManager &licenseManager);
|
||||
~ActivationDialog();
|
||||
QWidget *parent, AppConfig &appConfig, LicenseHandler &licenseHandler);
|
||||
~ActivationDialog() override;
|
||||
|
||||
class ActivationMessageError : public std::runtime_error {
|
||||
public:
|
||||
ActivationMessageError()
|
||||
: std::runtime_error("could not show activation message") {}
|
||||
};
|
||||
|
||||
public slots:
|
||||
void reject();
|
||||
|
|
@ -42,7 +49,11 @@ protected:
|
|||
void refreshSerialKey();
|
||||
|
||||
private:
|
||||
Ui::ActivationDialog *ui;
|
||||
AppConfig *m_appConfig;
|
||||
LicenseManager *m_LicenseManager;
|
||||
void showResultDialog(LicenseHandler::ChangeSerialKeyResult result);
|
||||
void showSuccessDialog();
|
||||
void showErrorDialog(const QString &message);
|
||||
|
||||
Ui::ActivationDialog *m_ui;
|
||||
AppConfig *m_pAppConfig;
|
||||
LicenseHandler &m_licenseHandler;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@
|
|||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>477</width>
|
||||
<width>541</width>
|
||||
<height>241</height>
|
||||
</rect>
|
||||
</property>
|
||||
|
|
@ -29,7 +29,7 @@
|
|||
<item>
|
||||
<widget class="QLabel" name="label_5">
|
||||
<property name="text">
|
||||
<string><html><head/><body><p>Your serial key is on your <a href="https://symless.com/synergy/account?source=gui"><span style=" text-decoration: underline; color:#4285f4;">account</span></a> page. Don't have a license? <a href="https://symless.com/synergy/purchase?source=gui"><span style=" text-decoration: underline; color:#007af4;">Purchase Synergy</span></a></p></body></html></string>
|
||||
<string><p>Your serial key is on your <a href="https://symless.com/synergy/account?source=gui" style="color:#4285f4;">account</span></a> page. Don't have a license? <a href="https://symless.com/synergy/purchase?source=gui" style="color:#4285f4;">Purchase Synergy</span></a></p></string>
|
||||
</property>
|
||||
<property name="openExternalLinks">
|
||||
<bool>true</bool>
|
||||
|
|
@ -51,7 +51,7 @@ p, li { white-space: pre-wrap; }
|
|||
hr { height: 1px; border-width: 0; }
|
||||
li.unchecked::marker { content: "\2610"; }
|
||||
li.checked::marker { content: "\2612"; }
|
||||
</style></head><body style=" font-family:'Segoe UI'; font-size:9pt; font-weight:400; font-style:normal;">
|
||||
</style></head><body style=" font-family:'Cantarell'; font-size:11pt; font-weight:400; font-style:normal;">
|
||||
<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans'; font-size:10pt;"><br /></p></body></html></string>
|
||||
</property>
|
||||
<property name="acceptRichText">
|
||||
|
|
@ -60,7 +60,7 @@ li.checked::marker { content: "\2612"; }
|
|||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QWidget" name="m_trialWidget" native="true">
|
||||
<widget class="QWidget" name="m_widgetNotice" native="true">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_5">
|
||||
<property name="leftMargin">
|
||||
<number>2</number>
|
||||
|
|
@ -75,18 +75,16 @@ li.checked::marker { content: "\2612"; }
|
|||
<number>8</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QLabel" name="m_trialLabel">
|
||||
<widget class="QLabel" name="m_labelNotice">
|
||||
<property name="styleSheet">
|
||||
<string notr="true">font-size: 13px;
|
||||
font-weight: 700;
|
||||
padding: 3px 5px;
|
||||
<string notr="true">padding: 3px 5px;
|
||||
border-radius: 3px;
|
||||
background-color: #EC4C47;
|
||||
background-color: #3B67D3;
|
||||
color: #ffffff;
|
||||
top: 3px;</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
<string>m_labelNotice</string>
|
||||
</property>
|
||||
<property name="openExternalLinks">
|
||||
<bool>true</bool>
|
||||
|
|
@ -96,7 +94,7 @@ top: 3px;</string>
|
|||
<item>
|
||||
<spacer name="horizontalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
<enum>Qt::Orientation::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
|
|
@ -112,10 +110,10 @@ top: 3px;</string>
|
|||
<item>
|
||||
<widget class="QDialogButtonBox" name="buttonBox">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
<enum>Qt::Orientation::Horizontal</enum>
|
||||
</property>
|
||||
<property name="standardButtons">
|
||||
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
|
||||
<set>QDialogButtonBox::StandardButton::Cancel|QDialogButtonBox::StandardButton::Ok</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
|
|
|
|||
|
|
@ -19,14 +19,13 @@
|
|||
#include "AppConfig.h"
|
||||
|
||||
#include "Config.h"
|
||||
#include "SslCertificate.h"
|
||||
#include "gui/constants.h"
|
||||
|
||||
#include <QApplication>
|
||||
#include <QMessageBox>
|
||||
#include <QPushButton>
|
||||
#include <QtCore>
|
||||
#include <QtNetwork>
|
||||
#include <QtWidgets/QMessageBox>
|
||||
#include <qapplication.h>
|
||||
|
||||
using synergy::gui::Config;
|
||||
|
||||
|
|
@ -46,6 +45,7 @@ const char AppConfig::m_LogDir[] = "/var/log/";
|
|||
const char AppConfig::m_ConfigFilename[] = "synergy.conf";
|
||||
#endif
|
||||
|
||||
// TODO: instead, use key value pair table, which would be less fragile.
|
||||
const char *const AppConfig::m_SettingsName[] = {
|
||||
"screenName",
|
||||
"port",
|
||||
|
|
@ -57,17 +57,17 @@ const char *const AppConfig::m_SettingsName[] = {
|
|||
"startedBefore",
|
||||
"elevateMode",
|
||||
"elevateModeEnum",
|
||||
"edition",
|
||||
"cryptoEnabled",
|
||||
"", // 10 = edition, obsolete (using serial key instead)
|
||||
"cryptoEnabled", // kTlsEnabled (retain legacy string value)
|
||||
"autoHide",
|
||||
"serialKey",
|
||||
"lastVersion",
|
||||
"lastExpiringWarningTime",
|
||||
"", // 15 = lastExpiringWarningTime, obsolete
|
||||
"activationHasRun",
|
||||
"minimizeToTray",
|
||||
"ActivateEmail",
|
||||
"", // 18 = ActivateEmail, obsolete
|
||||
"loadFromSystemScope",
|
||||
"groupServerChecked",
|
||||
"groupServerChecked", // kServerGroupChecked
|
||||
"useExternalConfig",
|
||||
"configFile",
|
||||
"useInternalConfig",
|
||||
|
|
@ -78,23 +78,20 @@ const char *const AppConfig::m_SettingsName[] = {
|
|||
"preventSleep",
|
||||
"languageSync",
|
||||
"invertScrollDirection",
|
||||
"guid",
|
||||
"licenseRegistryUrl",
|
||||
"", // 31 = guid, obsolete
|
||||
"", // 32 = licenseRegistryUrl, obsolete
|
||||
"licenseNextCheck",
|
||||
"initiateConnectionFromServer",
|
||||
"clientHostMode",
|
||||
"serverClientMode",
|
||||
"initiateConnectionFromServer", // kInvertConnection
|
||||
"", // 35 = clientHostMode, obsolete
|
||||
"", // 36 = serverClientMode, obsolete
|
||||
"serviceEnabled",
|
||||
"closeToTray"};
|
||||
|
||||
static const char *logLevelNames[] = {"INFO", "DEBUG", "DEBUG1", "DEBUG2"};
|
||||
|
||||
AppConfig::AppConfig() {
|
||||
m_Config.registerReceiever(this);
|
||||
load();
|
||||
}
|
||||
AppConfig::AppConfig() { m_Config.registerReceiever(this); }
|
||||
|
||||
void AppConfig::load() {
|
||||
void AppConfig::loadAllScopes() {
|
||||
m_Config.loadAll();
|
||||
|
||||
// User settings exist and the load from system scope variable is true
|
||||
|
|
@ -112,6 +109,8 @@ void AppConfig::load() {
|
|||
void AppConfig::loadSettings() {
|
||||
using enum AppConfig::Setting;
|
||||
|
||||
qDebug("loading settings");
|
||||
|
||||
m_ScreenName =
|
||||
loadSetting(kScreenName, QHostInfo::localHostName()).toString();
|
||||
if (m_ScreenName.isEmpty()) {
|
||||
|
|
@ -119,7 +118,7 @@ void AppConfig::loadSettings() {
|
|||
}
|
||||
|
||||
m_Port = loadSetting(kPort, 24800).toInt();
|
||||
m_Interface = loadSetting(kInterfaceSetting).toString();
|
||||
m_Interface = loadSetting(kInterface).toString();
|
||||
m_LogLevel = loadSetting(kLogLevel, 0).toInt();
|
||||
m_LogToFile = loadSetting(kLogToFile, false).toBool();
|
||||
m_LogFilename =
|
||||
|
|
@ -130,98 +129,74 @@ void AppConfig::loadSettings() {
|
|||
QVariant elevateMode = loadSetting(kElevateModeEnum);
|
||||
if (!elevateMode.isValid()) {
|
||||
elevateMode = loadSetting(
|
||||
kElevateModeSetting, QVariant(static_cast<int>(kDefaultElevateMode)));
|
||||
kElevateMode, QVariant(static_cast<int>(kDefaultElevateMode)));
|
||||
}
|
||||
m_ElevateMode = static_cast<ElevateMode>(elevateMode.toInt());
|
||||
|
||||
m_ActivateEmail = loadSetting(kActivateEmail, "").toString();
|
||||
m_CryptoEnabled = loadSetting(kCryptoEnabled, true).toBool();
|
||||
m_AutoHide = loadSetting(kAutoHide, false).toBool();
|
||||
m_LastVersion = loadSetting(kLastVersion, "Unknown").toString();
|
||||
m_LastExpiringWarningTime = loadSetting(kLastExpireWarningTime, 0).toInt();
|
||||
m_ActivationHasRun = loadSetting(kActivationHasRun, false).toBool();
|
||||
m_MinimizeToTray = loadSetting(kMinimizeToTray, false).toBool();
|
||||
m_LoadFromSystemScope =
|
||||
loadCommonSetting(kLoadSystemSettings, false).toBool();
|
||||
m_ServerGroupChecked = loadSetting(kGroupServerCheck, false).toBool();
|
||||
m_ServerGroupChecked = loadSetting(kServerGroupChecked, false).toBool();
|
||||
m_UseExternalConfig = loadSetting(kUseExternalConfig, false).toBool();
|
||||
m_ConfigFile =
|
||||
loadSetting(kConfigFile, QDir::homePath() + "/" + m_ConfigFilename)
|
||||
.toString();
|
||||
m_UseInternalConfig = loadSetting(kUseInternalConfig, false).toBool();
|
||||
m_ClientGroupChecked = loadSetting(kGroupClientCheck, false).toBool();
|
||||
m_ClientGroupChecked = loadSetting(kClientGroupChecked, false).toBool();
|
||||
m_ServerHostname = loadSetting(kServerHostname).toString();
|
||||
m_PreventSleep = loadSetting(kPreventSleep, false).toBool();
|
||||
m_LanguageSync = loadSetting(kLanguageSync, false).toBool();
|
||||
m_InvertScrollDirection = loadSetting(kInvertScrollDirection, false).toBool();
|
||||
m_Guid = loadCommonSetting(kGuid, QUuid::createUuid()).toString();
|
||||
m_licenseNextCheck = loadCommonSetting(kLicenseNextCheck, 0).toULongLong();
|
||||
m_ClientHostMode = loadSetting(kClientHostMode, true).toBool();
|
||||
m_ServerClientMode = loadSetting(kServerClientMode, true).toBool();
|
||||
m_InitiateConnectionFromServer =
|
||||
loadSetting(kInitiateConnectionFromServer, false).toBool();
|
||||
m_InvertConnection = loadSetting(kInvertConnection, false).toBool();
|
||||
|
||||
// only change the serial key if the settings being loaded contains a key
|
||||
bool updateSerial = m_Config.hasSetting(
|
||||
bool loadSerial = m_Config.hasSetting(
|
||||
settingName(kLoadSystemSettings), Config::Scope::Current);
|
||||
// if the setting exists and is not empty
|
||||
updateSerial = updateSerial &&
|
||||
!loadSetting(kSerialKey, "").toString().trimmed().isEmpty();
|
||||
|
||||
if (updateSerial) {
|
||||
m_Serialkey = loadSetting(kSerialKey, "").toString().trimmed();
|
||||
m_Edition = static_cast<Edition>(
|
||||
loadSetting(kEditionSetting, kUnregistered).toInt());
|
||||
if (loadSerial) {
|
||||
const auto &serialKey = loadSetting(kSerialKey, "").toString().trimmed();
|
||||
if (!serialKey.isEmpty()) {
|
||||
m_SerialKey = serialKey;
|
||||
}
|
||||
}
|
||||
|
||||
m_ServiceEnabled = loadSetting(kServiceEnabled, m_ServiceEnabled).toBool();
|
||||
m_CloseToTray = loadSetting(kCloseToTray, m_CloseToTray).toBool();
|
||||
m_TlsEnabled = loadSetting(kTlsEnabled, m_TlsEnabled).toBool();
|
||||
m_TlsCertPath = loadSetting(kTlsCertPath, defaultTlsCertPath()).toString();
|
||||
m_TlsKeyLength = loadSetting(kTlsKeyLength, m_TlsKeyLength).toString();
|
||||
|
||||
try {
|
||||
// Set the default path of the TLS certificate file in the users DIR
|
||||
QString certificateFilename =
|
||||
QString("%1/%2/%3")
|
||||
.arg(m_CoreInterface.getProfileDir(), "SSL", "Synergy.pem");
|
||||
|
||||
m_TlsCertPath = loadSetting(kTlsCertPath, certificateFilename).toString();
|
||||
m_TlsKeyLength = loadSetting(kTlsKeyLength, "2048").toString();
|
||||
} catch (const std::exception &e) {
|
||||
qDebug() << e.what();
|
||||
qFatal("Failed to get profile dir, unable to configure TLS");
|
||||
}
|
||||
|
||||
if (cryptoEnabled()) {
|
||||
generateCertificate();
|
||||
}
|
||||
|
||||
applyAppSettings();
|
||||
emit loaded();
|
||||
}
|
||||
|
||||
void AppConfig::saveSettings() {
|
||||
using enum Setting;
|
||||
|
||||
qDebug("saving settings");
|
||||
|
||||
setCommonSetting(kWizardLastRun, m_WizardLastRun);
|
||||
setCommonSetting(kLoadSystemSettings, m_LoadFromSystemScope);
|
||||
setCommonSetting(kGroupClientCheck, m_ClientGroupChecked);
|
||||
setCommonSetting(kGroupServerCheck, m_ServerGroupChecked);
|
||||
setCommonSetting(kGuid, m_Guid);
|
||||
setCommonSetting(kClientGroupChecked, m_ClientGroupChecked);
|
||||
setCommonSetting(kServerGroupChecked, m_ServerGroupChecked);
|
||||
setCommonSetting(kLicenseNextCheck, m_licenseNextCheck);
|
||||
|
||||
if (isWritable()) {
|
||||
setSetting(kScreenName, m_ScreenName);
|
||||
setSetting(kPort, m_Port);
|
||||
setSetting(kInterfaceSetting, m_Interface);
|
||||
setSetting(kInterface, m_Interface);
|
||||
setSetting(kLogLevel, m_LogLevel);
|
||||
setSetting(kLogToFile, m_LogToFile);
|
||||
setSetting(kLogFilename, m_LogFilename);
|
||||
setSetting(kStartedBefore, m_StartedBefore);
|
||||
setSetting(kElevateModeEnum, static_cast<int>(m_ElevateMode));
|
||||
setSetting(kEditionSetting, m_Edition);
|
||||
setSetting(kCryptoEnabled, m_CryptoEnabled);
|
||||
setSetting(kTlsEnabled, m_TlsEnabled);
|
||||
setSetting(kAutoHide, m_AutoHide);
|
||||
setSetting(kSerialKey, m_Serialkey);
|
||||
setSetting(kSerialKey, m_SerialKey);
|
||||
setSetting(kLastVersion, m_LastVersion);
|
||||
setSetting(kLastExpireWarningTime, m_LastExpiringWarningTime);
|
||||
setSetting(kActivationHasRun, m_ActivationHasRun);
|
||||
setSetting(kMinimizeToTray, m_MinimizeToTray);
|
||||
setSetting(kUseExternalConfig, m_UseExternalConfig);
|
||||
|
|
@ -231,17 +206,28 @@ void AppConfig::saveSettings() {
|
|||
setSetting(kPreventSleep, m_PreventSleep);
|
||||
setSetting(kLanguageSync, m_LanguageSync);
|
||||
setSetting(kInvertScrollDirection, m_InvertScrollDirection);
|
||||
setSetting(kClientHostMode, m_ClientHostMode);
|
||||
setSetting(kServerClientMode, m_ServerClientMode);
|
||||
setSetting(kInvertConnection, m_InvertConnection);
|
||||
setSetting(kServiceEnabled, m_ServiceEnabled);
|
||||
setSetting(kCloseToTray, m_CloseToTray);
|
||||
|
||||
// See enum ElevateMode declaration to understand why this setting is bool
|
||||
setSetting(kElevateModeSetting, m_ElevateMode == ElevateAlways);
|
||||
setSetting(kElevateMode, m_ElevateMode == ElevateAlways);
|
||||
}
|
||||
|
||||
setModified(false);
|
||||
applyAppSettings();
|
||||
saved();
|
||||
|
||||
if (m_TlsChanged) {
|
||||
m_TlsChanged = false;
|
||||
emit tlsChanged();
|
||||
}
|
||||
}
|
||||
|
||||
QString AppConfig::defaultTlsCertPath() const {
|
||||
QDir path(m_CoreInterface.getProfileDir());
|
||||
path = path.filePath("SSL");
|
||||
path = path.filePath("Synergy.pem");
|
||||
return path.absolutePath();
|
||||
}
|
||||
|
||||
QString AppConfig::settingName(Setting name) {
|
||||
|
|
@ -293,13 +279,15 @@ void AppConfig::loadScope(Config::Scope scope) {
|
|||
}
|
||||
}
|
||||
|
||||
void AppConfig::setDefaultValues() { m_InitiateConnectionFromServer = false; }
|
||||
void AppConfig::setDefaultValues() { m_InvertConnection = false; }
|
||||
|
||||
void AppConfig::setLoadFromSystemScope(bool value) {
|
||||
|
||||
if (value) {
|
||||
qDebug("loading system settings scope");
|
||||
loadScope(Config::Scope::System);
|
||||
} else {
|
||||
qDebug("loading user settings scope");
|
||||
loadScope(Config::Scope::User);
|
||||
}
|
||||
|
||||
|
|
@ -323,59 +311,132 @@ void AppConfig::setSettingModified(T &variable, const T &newValue) {
|
|||
setModified(true);
|
||||
}
|
||||
}
|
||||
QString AppConfig::logDir() const {
|
||||
// by default log to home dir
|
||||
return QDir::home().absolutePath() + "/";
|
||||
}
|
||||
|
||||
void AppConfig::generateCertificate(bool forceGeneration) const {
|
||||
try {
|
||||
SslCertificate sslCertificate;
|
||||
sslCertificate.generateCertificate(
|
||||
tlsCertPath(), tlsKeyLength(), forceGeneration);
|
||||
emit sslToggled();
|
||||
} catch (const std::exception &e) {
|
||||
qDebug() << e.what();
|
||||
qFatal("Failed to configure TLS");
|
||||
void AppConfig::persistLogDir() const {
|
||||
QDir dir = logDir();
|
||||
|
||||
// persist the log directory
|
||||
if (!dir.exists()) {
|
||||
dir.mkpath(dir.path());
|
||||
}
|
||||
}
|
||||
|
||||
void AppConfig::applyAppSettings() const {
|
||||
QApplication::setQuitOnLastWindowClosed(!m_CloseToTray);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Begin getters and setters
|
||||
// Begin getters
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifdef SYNERGY_ENABLE_LICENSING
|
||||
|
||||
bool AppConfig::activationHasRun() const { return m_ActivationHasRun; }
|
||||
|
||||
QString AppConfig::serialKey() const { return m_SerialKey; }
|
||||
|
||||
Config &AppConfig::config() { return m_Config; }
|
||||
|
||||
const QString &AppConfig::screenName() const { return m_ScreenName; }
|
||||
|
||||
int AppConfig::port() const { return m_Port; }
|
||||
|
||||
const QString &AppConfig::networkInterface() 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::logLevelText() const { return logLevelNames[logLevel()]; }
|
||||
|
||||
ProcessMode AppConfig::processMode() const {
|
||||
return m_ServiceEnabled ? ProcessMode::kService : ProcessMode::kDesktop;
|
||||
}
|
||||
|
||||
bool AppConfig::wizardShouldRun() const {
|
||||
return m_WizardLastRun < kWizardVersion;
|
||||
}
|
||||
|
||||
bool AppConfig::startedBefore() const { return m_StartedBefore; }
|
||||
|
||||
QString AppConfig::lastVersion() const { return m_LastVersion; }
|
||||
|
||||
QString AppConfig::coreServerName() const { return m_CoreServerName; }
|
||||
|
||||
QString AppConfig::coreClientName() const { return m_CoreClientName; }
|
||||
|
||||
ElevateMode AppConfig::elevateMode() const { return m_ElevateMode; }
|
||||
|
||||
bool AppConfig::tlsEnabled() const { return m_TlsEnabled; }
|
||||
|
||||
bool AppConfig::autoHide() const { return m_AutoHide; }
|
||||
|
||||
bool AppConfig::invertScrollDirection() const {
|
||||
return m_InvertScrollDirection;
|
||||
}
|
||||
|
||||
unsigned long long AppConfig::licenseNextCheck() const {
|
||||
return m_licenseNextCheck;
|
||||
}
|
||||
|
||||
bool AppConfig::languageSync() const { return m_LanguageSync; }
|
||||
|
||||
bool AppConfig::preventSleep() const { return m_PreventSleep; }
|
||||
|
||||
bool AppConfig::invertConnection() const { return m_InvertConnection; }
|
||||
|
||||
bool AppConfig::minimizeToTray() const { return m_MinimizeToTray; }
|
||||
|
||||
QString AppConfig::tlsCertPath() const { return m_TlsCertPath; }
|
||||
|
||||
QString AppConfig::tlsKeyLength() const { return m_TlsKeyLength; }
|
||||
|
||||
bool AppConfig::serviceEnabled() const { return m_ServiceEnabled; }
|
||||
|
||||
bool AppConfig::closeToTray() const { return m_CloseToTray; }
|
||||
|
||||
bool AppConfig::serverGroupChecked() const { return m_ServerGroupChecked; }
|
||||
|
||||
bool AppConfig::useExternalConfig() const { return m_UseExternalConfig; }
|
||||
|
||||
const QString &AppConfig::configFile() const { return m_ConfigFile; }
|
||||
|
||||
bool AppConfig::useInternalConfig() const { return m_UseInternalConfig; }
|
||||
|
||||
bool AppConfig::clientGroupChecked() const { return m_ClientGroupChecked; }
|
||||
|
||||
QString AppConfig::serverHostname() const { return m_ServerHostname; }
|
||||
|
||||
void AppConfig::setActivationHasRun(bool value) { m_ActivationHasRun = value; }
|
||||
|
||||
void AppConfig::setEdition(Edition e) {
|
||||
setSettingModified(m_Edition, e);
|
||||
setCommonSetting(Setting::kEditionSetting, m_Edition);
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// End getters
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Begin setters
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void AppConfig::clearSerialKey() { m_SerialKey.clear(); }
|
||||
|
||||
void AppConfig::setTlsEnabled(bool value) {
|
||||
setSettingModified(m_TlsEnabled, value);
|
||||
m_TlsChanged = true;
|
||||
}
|
||||
|
||||
Edition AppConfig::edition() const { return m_Edition; }
|
||||
|
||||
void AppConfig::setSerialKey(const QString &serial) {
|
||||
setSettingModified(m_Serialkey, serial);
|
||||
setCommonSetting(Setting::kSerialKey, m_Serialkey);
|
||||
void AppConfig::setTlsCertPath(const QString &value) {
|
||||
setSettingModified(m_TlsCertPath, value);
|
||||
m_TlsChanged = true;
|
||||
}
|
||||
|
||||
void AppConfig::clearSerialKey() { m_Serialkey.clear(); }
|
||||
|
||||
QString AppConfig::serialKey() const { return m_Serialkey; }
|
||||
|
||||
int AppConfig::lastExpiringWarningTime() const {
|
||||
return m_LastExpiringWarningTime;
|
||||
void AppConfig::setTlsKeyLength(const QString &value) {
|
||||
setSettingModified(m_TlsKeyLength, value);
|
||||
m_TlsChanged = true;
|
||||
}
|
||||
|
||||
void AppConfig::setLastExpiringWarningTime(int newValue) {
|
||||
setSettingModified(m_LastExpiringWarningTime, newValue);
|
||||
void AppConfig::setSerialKey(const QString &serialKey) {
|
||||
setSettingModified(m_SerialKey, serialKey);
|
||||
setCommonSetting(Setting::kSerialKey, m_SerialKey);
|
||||
}
|
||||
|
||||
#endif // SYNERGY_ENABLE_LICENSING
|
||||
|
||||
void AppConfig::setServerGroupChecked(bool newValue) {
|
||||
setSettingModified(m_ServerGroupChecked, newValue);
|
||||
}
|
||||
|
|
@ -399,57 +460,6 @@ void AppConfig::setClientGroupChecked(bool newValue) {
|
|||
void AppConfig::setServerHostname(const QString &newValue) {
|
||||
setSettingModified(m_ServerHostname, newValue);
|
||||
}
|
||||
|
||||
void AppConfig::setClientHostMode(bool newValue) {
|
||||
setSettingModified(m_ClientHostMode, newValue);
|
||||
}
|
||||
|
||||
void AppConfig::setServerClientMode(bool newValue) {
|
||||
setSettingModified(m_ServerClientMode, newValue);
|
||||
}
|
||||
|
||||
Config &AppConfig::config() { return m_Config; }
|
||||
|
||||
const QString &AppConfig::screenName() const { return m_ScreenName; }
|
||||
|
||||
int AppConfig::port() const { return m_Port; }
|
||||
|
||||
const QString &AppConfig::networkInterface() 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::logDir() const {
|
||||
// by default log to home dir
|
||||
return QDir::home().absolutePath() + "/";
|
||||
}
|
||||
|
||||
void AppConfig::persistLogDir() const {
|
||||
QDir dir = logDir();
|
||||
|
||||
// persist the log directory
|
||||
if (!dir.exists()) {
|
||||
dir.mkpath(dir.path());
|
||||
}
|
||||
}
|
||||
|
||||
QString AppConfig::logLevelText() const { return logLevelNames[logLevel()]; }
|
||||
|
||||
ProcessMode AppConfig::processMode() const {
|
||||
return m_ServiceEnabled ? ProcessMode::kService : ProcessMode::kDesktop;
|
||||
}
|
||||
|
||||
bool AppConfig::wizardShouldRun() const {
|
||||
return m_WizardLastRun < kWizardVersion;
|
||||
}
|
||||
|
||||
bool AppConfig::startedBefore() const { return m_StartedBefore; }
|
||||
|
||||
QString AppConfig::lastVersion() const { return m_LastVersion; }
|
||||
|
||||
void AppConfig::setLastVersion(const QString &version) {
|
||||
setSettingModified(m_LastVersion, version);
|
||||
}
|
||||
|
|
@ -485,61 +495,16 @@ void AppConfig::setElevateMode(ElevateMode em) {
|
|||
setSettingModified(m_ElevateMode, em);
|
||||
}
|
||||
|
||||
QString AppConfig::coreServerName() const { return m_CoreServerName; }
|
||||
|
||||
QString AppConfig::coreClientName() const { return m_CoreClientName; }
|
||||
|
||||
ElevateMode AppConfig::elevateMode() { return m_ElevateMode; }
|
||||
|
||||
void AppConfig::setCryptoEnabled(bool newValue) {
|
||||
if (m_CryptoEnabled != newValue && newValue) {
|
||||
generateCertificate();
|
||||
} else {
|
||||
emit sslToggled();
|
||||
}
|
||||
setSettingModified(m_CryptoEnabled, newValue);
|
||||
}
|
||||
|
||||
bool AppConfig::cryptoAvailable() const {
|
||||
bool result{true};
|
||||
|
||||
#ifdef SYNERGY_ENABLE_LICENSING
|
||||
result =
|
||||
(edition() == kPro || edition() == kProChina || edition() == kBusiness ||
|
||||
edition() == kUltimate);
|
||||
#endif // SYNERGY_ENABLE_LICENSING
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
bool AppConfig::cryptoEnabled() const {
|
||||
return cryptoAvailable() && m_CryptoEnabled;
|
||||
}
|
||||
|
||||
void AppConfig::setAutoHide(bool b) { setSettingModified(m_AutoHide, b); }
|
||||
|
||||
bool AppConfig::autoHide() const { return m_AutoHide; }
|
||||
|
||||
void AppConfig::setMinimizeToTray(bool newValue) {
|
||||
setSettingModified(m_MinimizeToTray, newValue);
|
||||
}
|
||||
|
||||
bool AppConfig::invertScrollDirection() const {
|
||||
return m_InvertScrollDirection;
|
||||
}
|
||||
|
||||
void AppConfig::setLicenseNextCheck(unsigned long long time) {
|
||||
setSettingModified(m_licenseNextCheck, time);
|
||||
}
|
||||
|
||||
unsigned long long AppConfig::licenseNextCheck() const {
|
||||
return m_licenseNextCheck;
|
||||
}
|
||||
|
||||
const QString &AppConfig::guid() const { return m_Guid; }
|
||||
|
||||
bool AppConfig::languageSync() const { return m_LanguageSync; }
|
||||
|
||||
void AppConfig::setInvertScrollDirection(bool newValue) {
|
||||
setSettingModified(m_InvertScrollDirection, newValue);
|
||||
}
|
||||
|
|
@ -548,63 +513,23 @@ void AppConfig::setLanguageSync(bool newValue) {
|
|||
setSettingModified(m_LanguageSync, newValue);
|
||||
}
|
||||
|
||||
bool AppConfig::preventSleep() const { return m_PreventSleep; }
|
||||
|
||||
bool AppConfig::clientHostMode() const {
|
||||
return (m_ClientHostMode && initiateConnectionFromServer());
|
||||
}
|
||||
|
||||
bool AppConfig::serverClientMode() const {
|
||||
return (m_ServerClientMode && initiateConnectionFromServer());
|
||||
}
|
||||
|
||||
bool AppConfig::initiateConnectionFromServer() const {
|
||||
return m_InitiateConnectionFromServer;
|
||||
}
|
||||
|
||||
void AppConfig::setPreventSleep(bool newValue) {
|
||||
setSettingModified(m_PreventSleep, newValue);
|
||||
}
|
||||
|
||||
bool AppConfig::minimizeToTray() const { return m_MinimizeToTray; }
|
||||
|
||||
void AppConfig::setTlsCertPath(const QString &path) { m_TlsCertPath = path; }
|
||||
|
||||
QString AppConfig::tlsCertPath() const { return m_TlsCertPath; }
|
||||
|
||||
QString AppConfig::tlsKeyLength() const { return m_TlsKeyLength; }
|
||||
|
||||
void AppConfig::setTlsKeyLength(const QString &length) {
|
||||
if (m_TlsKeyLength != length) {
|
||||
m_TlsKeyLength = length;
|
||||
generateCertificate(true);
|
||||
}
|
||||
}
|
||||
|
||||
void AppConfig::setServiceEnabled(bool enabled) {
|
||||
setSettingModified(m_ServiceEnabled, enabled);
|
||||
}
|
||||
|
||||
bool AppConfig::serviceEnabled() const { return m_ServiceEnabled; }
|
||||
|
||||
void AppConfig::setCloseToTray(bool minimize) {
|
||||
setSettingModified(m_CloseToTray, minimize);
|
||||
}
|
||||
|
||||
bool AppConfig::closeToTray() const { return m_CloseToTray; }
|
||||
|
||||
bool AppConfig::serverGroupChecked() const { return m_ServerGroupChecked; }
|
||||
|
||||
bool AppConfig::useExternalConfig() const { return m_UseExternalConfig; }
|
||||
|
||||
const QString &AppConfig::configFile() const { return m_ConfigFile; }
|
||||
|
||||
bool AppConfig::useInternalConfig() const { return m_UseInternalConfig; }
|
||||
|
||||
bool AppConfig::clientGroupChecked() const { return m_ClientGroupChecked; }
|
||||
|
||||
QString AppConfig::serverHostname() const { return m_ServerHostname; }
|
||||
void AppConfig::setInvertConnection(bool value) {
|
||||
setSettingModified(m_InvertConnection, value);
|
||||
emit invertConnectionChanged();
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// End getters and setters
|
||||
// End setters
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
|||
|
|
@ -20,10 +20,9 @@
|
|||
|
||||
#include "CommonConfig.h"
|
||||
#include "Config.h"
|
||||
#include "CoreInterface.h"
|
||||
#include "LicenseManager.h"
|
||||
#include "gui/CoreInterface.h"
|
||||
#include "gui/ElevateMode.h"
|
||||
#include "shared/EditionType.h"
|
||||
#include "gui/IAppConfig.h"
|
||||
|
||||
#include <QObject>
|
||||
#include <QString>
|
||||
|
|
@ -32,11 +31,9 @@
|
|||
|
||||
class QSettings;
|
||||
class SettingsDialog;
|
||||
class LicenseRegister;
|
||||
class ServerConfig;
|
||||
class LicenseManager;
|
||||
class LicenseHandler;
|
||||
class ActivationDialog;
|
||||
class LicenseRegistry;
|
||||
|
||||
enum class ProcessMode { kService, kDesktop };
|
||||
|
||||
|
|
@ -48,17 +45,67 @@ const ProcessMode kDefaultProcessMode = ProcessMode::kService;
|
|||
const ProcessMode kDefaultProcessMode = ProcessMode::kDesktop;
|
||||
#endif
|
||||
|
||||
/// @brief Reads and writes application specific settings
|
||||
class AppConfig : public QObject, public synergy::gui::CommonConfig {
|
||||
/**
|
||||
* @brief Simply reads and writes app settings.
|
||||
*
|
||||
* Important: Maintain a clear separation of concerns and keep it simple.
|
||||
* It is tempting to add logic (e.g. license checks) to this class since it
|
||||
* instance is widely accessible, but that has previously led to this class
|
||||
* becoming a god object.
|
||||
*/
|
||||
class AppConfig : public QObject,
|
||||
public synergy::gui::CommonConfig,
|
||||
public synergy::gui::IAppConfig {
|
||||
Q_OBJECT
|
||||
|
||||
friend class SettingsDialog;
|
||||
friend class MainWindow;
|
||||
friend class SetupWizard;
|
||||
friend class ServerConfig;
|
||||
friend class LicenseManager;
|
||||
friend class ActivationDialog;
|
||||
friend class LicenseRegistry;
|
||||
|
||||
private:
|
||||
enum class Setting {
|
||||
kScreenName = 0,
|
||||
kPort = 1,
|
||||
kInterface = 2,
|
||||
kLogLevel = 3,
|
||||
kLogToFile = 4,
|
||||
kLogFilename = 5,
|
||||
kWizardLastRun = 6,
|
||||
kStartedBefore = 7,
|
||||
kElevateMode = 8,
|
||||
kElevateModeEnum = 9,
|
||||
// 10 = edition, obsolete (using serial key instead)
|
||||
kTlsEnabled = 11,
|
||||
kAutoHide = 12,
|
||||
kSerialKey = 13,
|
||||
kLastVersion = 14,
|
||||
// 15 = last expire time, obsolete
|
||||
kActivationHasRun = 16,
|
||||
kMinimizeToTray = 17,
|
||||
// 18 = activate email, obsolete
|
||||
kLoadSystemSettings = 19,
|
||||
kServerGroupChecked = 20,
|
||||
kUseExternalConfig = 21,
|
||||
kConfigFile = 22,
|
||||
kUseInternalConfig = 23,
|
||||
kClientGroupChecked = 24,
|
||||
kServerHostname = 25,
|
||||
kTlsCertPath = 26,
|
||||
kTlsKeyLength = 27,
|
||||
kPreventSleep = 28,
|
||||
kLanguageSync = 29,
|
||||
kInvertScrollDirection = 30,
|
||||
// 31 = guid, obsolete
|
||||
// 32 = license registry url, obsolete
|
||||
kLicenseNextCheck = 33,
|
||||
kInvertConnection = 34,
|
||||
// 35 = client-host-mode, obsolete
|
||||
// 36 = server-client-mode, obsolete
|
||||
kServiceEnabled = 37,
|
||||
kCloseToTray = 38,
|
||||
};
|
||||
|
||||
public:
|
||||
explicit AppConfig();
|
||||
|
|
@ -66,12 +113,8 @@ public:
|
|||
/// @brief Underlying configuration reader/writer
|
||||
synergy::gui::Config &config();
|
||||
|
||||
/// @brief Saves the setting to the current scope
|
||||
void saveSettings() override;
|
||||
void applyAppSettings() const;
|
||||
|
||||
/// @brief Generates TLS certificate
|
||||
/// @param [in] bool forceGeneration Generate certificate even if it's exists.
|
||||
void generateCertificate(bool forceGeneration = false) const;
|
||||
|
||||
/**
|
||||
* Getters
|
||||
|
|
@ -93,18 +136,13 @@ public:
|
|||
QString coreClientName() const;
|
||||
QString logDir() const;
|
||||
void persistLogDir() const;
|
||||
ElevateMode elevateMode();
|
||||
bool cryptoAvailable() const;
|
||||
bool cryptoEnabled() const;
|
||||
ElevateMode elevateMode() const;
|
||||
bool autoHide() const;
|
||||
bool invertScrollDirection() const;
|
||||
unsigned long long licenseNextCheck() const;
|
||||
const QString &guid() const;
|
||||
bool languageSync() const;
|
||||
bool preventSleep() const;
|
||||
bool clientHostMode() const;
|
||||
bool serverClientMode() const;
|
||||
bool initiateConnectionFromServer() const;
|
||||
bool invertConnection() const;
|
||||
bool serverGroupChecked() const;
|
||||
bool useExternalConfig() const;
|
||||
const QString &configFile() const;
|
||||
|
|
@ -115,70 +153,18 @@ public:
|
|||
bool serviceEnabled() const;
|
||||
bool minimizeToTray() const;
|
||||
bool closeToTray() const;
|
||||
|
||||
/// @brief Gets the current TLS certificate path
|
||||
/// @return QString The path to the cert
|
||||
QString tlsCertPath() const;
|
||||
|
||||
/// @brief Get the key length to be used for the private key of a TLS cert
|
||||
/// @return QString The key length in bits
|
||||
QString tlsKeyLength() const;
|
||||
|
||||
#ifdef SYNERGY_ENABLE_LICENSING
|
||||
Edition edition() const;
|
||||
QString serialKey() const;
|
||||
int lastExpiringWarningTime() const;
|
||||
bool activationHasRun() const;
|
||||
#endif
|
||||
|
||||
protected:
|
||||
enum class Setting {
|
||||
kScreenName,
|
||||
kPort,
|
||||
kInterfaceSetting,
|
||||
kLogLevel,
|
||||
kLogToFile,
|
||||
kLogFilename,
|
||||
kWizardLastRun,
|
||||
kStartedBefore,
|
||||
kElevateModeSetting,
|
||||
kElevateModeEnum,
|
||||
kEditionSetting,
|
||||
kCryptoEnabled,
|
||||
kAutoHide,
|
||||
kSerialKey,
|
||||
kLastVersion,
|
||||
kLastExpireWarningTime,
|
||||
kActivationHasRun,
|
||||
kMinimizeToTray,
|
||||
kActivateEmail,
|
||||
kLoadSystemSettings,
|
||||
kGroupServerCheck,
|
||||
kUseExternalConfig,
|
||||
kConfigFile,
|
||||
kUseInternalConfig,
|
||||
kGroupClientCheck,
|
||||
kServerHostname,
|
||||
kTlsCertPath,
|
||||
kTlsKeyLength,
|
||||
kPreventSleep,
|
||||
kLanguageSync,
|
||||
kInvertScrollDirection,
|
||||
kGuid,
|
||||
kLicenseRegistryUrl,
|
||||
kLicenseNextCheck,
|
||||
kInitiateConnectionFromServer,
|
||||
kClientHostMode,
|
||||
kServerClientMode,
|
||||
kServiceEnabled,
|
||||
kCloseToTray
|
||||
};
|
||||
|
||||
static QString settingName(AppConfig::Setting name);
|
||||
bool tlsEnabled() const override;
|
||||
QString tlsCertPath() const override;
|
||||
QString tlsKeyLength() const override;
|
||||
|
||||
private:
|
||||
/// @brief Loads the setting from the current scope
|
||||
void loadSettings() override;
|
||||
|
||||
static QString settingName(AppConfig::Setting name);
|
||||
|
||||
/**
|
||||
* Setters
|
||||
*/
|
||||
|
|
@ -192,11 +178,9 @@ protected:
|
|||
void setWizardHasRun();
|
||||
void setStartedBefore(bool b);
|
||||
void setElevateMode(ElevateMode em);
|
||||
void setCryptoEnabled(bool e);
|
||||
void setEdition(Edition);
|
||||
void setSerialKey(const QString &serial);
|
||||
void setTlsEnabled(bool e);
|
||||
void setSerialKey(const QString &serialKey);
|
||||
void clearSerialKey();
|
||||
void setLastExpiringWarningTime(int t);
|
||||
void setAutoHide(bool b);
|
||||
void setInvertScrollDirection(bool b);
|
||||
void setLicenseNextCheck(unsigned long long);
|
||||
|
|
@ -208,13 +192,14 @@ protected:
|
|||
void setUseInternalConfig(bool);
|
||||
void setClientGroupChecked(bool);
|
||||
void setServerHostname(const QString &);
|
||||
void setClientHostMode(bool newValue);
|
||||
void setServerClientMode(bool newValue);
|
||||
void setMinimizeToTray(bool b);
|
||||
void setLastVersion(const QString &version);
|
||||
void setServiceEnabled(bool enabled);
|
||||
void setCloseToTray(bool minimize);
|
||||
void setActivationHasRun(bool value);
|
||||
void setTlsCertPath(const QString &path);
|
||||
void setTlsKeyLength(const QString &length);
|
||||
void setInvertConnection(bool value);
|
||||
|
||||
/// @brief Sets the user preference to load from SystemScope.
|
||||
/// @param [in] value
|
||||
|
|
@ -223,17 +208,8 @@ protected:
|
|||
/// scope settings.
|
||||
void setLoadFromSystemScope(bool value);
|
||||
|
||||
/// @brief Set the path to the TLS/SSL certificate file that will be used
|
||||
/// @param [in] path The path to the Certificate
|
||||
void setTlsCertPath(const QString &path);
|
||||
|
||||
/// @brief Sets the key length of the private key to use in a TLS connection
|
||||
/// @param [in] QString length The key length eg: 1024, 2048, 4096
|
||||
void setTlsKeyLength(const QString &length);
|
||||
|
||||
private:
|
||||
/// @brief Loads config from the underlying reader/writer
|
||||
void load();
|
||||
void loadAllScopes();
|
||||
|
||||
/// @brief Sets the value of a setting
|
||||
/// @param [in] name The Setting to be saved
|
||||
|
|
@ -273,6 +249,11 @@ private:
|
|||
/// for settings that shouldn't be copied from between scopes.
|
||||
void setDefaultValues();
|
||||
|
||||
/**
|
||||
* @brief Gets a TLS certificate path based on the user's profile dir.
|
||||
*/
|
||||
QString defaultTlsCertPath() const;
|
||||
|
||||
synergy::gui::Config m_Config;
|
||||
CoreInterface m_CoreInterface;
|
||||
QString m_ScreenName = "";
|
||||
|
|
@ -284,23 +265,18 @@ private:
|
|||
int m_WizardLastRun = 0;
|
||||
bool m_StartedBefore = false;
|
||||
ElevateMode m_ElevateMode = kDefaultElevateMode;
|
||||
Edition m_Edition = Edition::kUnregistered;
|
||||
QString m_ActivateEmail = "";
|
||||
bool m_CryptoEnabled = false;
|
||||
bool m_TlsEnabled = true;
|
||||
bool m_AutoHide = false;
|
||||
QString m_Serialkey = "";
|
||||
QString m_SerialKey = "";
|
||||
QString m_LastVersion = "";
|
||||
QString m_Guid = "";
|
||||
unsigned long long m_licenseNextCheck = 0;
|
||||
int m_LastExpiringWarningTime = 0;
|
||||
bool m_ActivationHasRun = false;
|
||||
bool m_MinimizeToTray = true;
|
||||
bool m_InvertScrollDirection = false;
|
||||
bool m_LanguageSync = true;
|
||||
bool m_PreventSleep = false;
|
||||
bool m_InitiateConnectionFromServer = false;
|
||||
bool m_ClientHostMode = true;
|
||||
bool m_ServerClientMode = true;
|
||||
bool m_InvertConnection = false;
|
||||
bool m_ServerGroupChecked = false;
|
||||
bool m_UseExternalConfig = false;
|
||||
QString m_ConfigFile = "";
|
||||
|
|
@ -308,13 +284,15 @@ private:
|
|||
bool m_ClientGroupChecked = false;
|
||||
QString m_ServerHostname = "";
|
||||
bool m_ServiceEnabled = kDefaultProcessMode == ProcessMode::kService;
|
||||
bool m_CloseToTray = true;
|
||||
|
||||
/// @brief The path to the TLS certificate file
|
||||
bool m_CloseToTray = false;
|
||||
QString m_TlsCertPath = "";
|
||||
QString m_TlsKeyLength = "2048";
|
||||
|
||||
/// @brief The key length of the TLS cert to make
|
||||
QString m_TlsKeyLength = "";
|
||||
/**
|
||||
* @brief Flag is set when any TLS is setting is changed, and is reset
|
||||
* when the TLS changed event is emitted.
|
||||
*/
|
||||
bool m_TlsChanged = false;
|
||||
|
||||
/// @brief should the setting be loaded from
|
||||
/// SystemScope
|
||||
|
|
@ -340,6 +318,9 @@ private:
|
|||
static const char m_ConfigFilename[];
|
||||
|
||||
signals:
|
||||
void sslToggled() const;
|
||||
void screenNameChanged() const;
|
||||
void loaded();
|
||||
void saved();
|
||||
void tlsChanged();
|
||||
void screenNameChanged();
|
||||
void invertConnectionChanged();
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,237 +0,0 @@
|
|||
/*
|
||||
* synergy -- mouse and keyboard sharing utility
|
||||
* Copyright (C) 2015 Synergy Ltd.
|
||||
*
|
||||
* This package is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* found in the file LICENSE that should have accompanied this file.
|
||||
*
|
||||
* This package is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "LicenseManager.h"
|
||||
|
||||
#include "ActivationNotifier.h"
|
||||
#include "AppConfig.h"
|
||||
|
||||
#include <QDateTime>
|
||||
#include <QLocale>
|
||||
#include <QThread>
|
||||
#include <QTimer>
|
||||
#include <ctime>
|
||||
#include <stdexcept>
|
||||
#include <utility>
|
||||
|
||||
namespace {
|
||||
|
||||
std::string getMaintenanceMessage(const SerialKey &serialKey) {
|
||||
auto expiration =
|
||||
QDateTime::fromSecsSinceEpoch(serialKey.getExpiration()).date();
|
||||
QString message =
|
||||
"The license key you used will only work with versions of Synergy "
|
||||
"released before %1."
|
||||
"<p>To use this version, you’ll need to renew your Synergy maintenance "
|
||||
"license. "
|
||||
"<a href=\"https://symless.com/synergy/account?source=gui\""
|
||||
"style=\"text-decoration: none; color: #4285F4;\">Renew today</a>.</p>";
|
||||
auto formatedDate = QLocale("en_US").toString(expiration, "MMM dd yyyy");
|
||||
return message.arg(formatedDate).toStdString();
|
||||
}
|
||||
|
||||
void checkSerialKey(const SerialKey &serialKey, bool acceptExpired) {
|
||||
if (serialKey.isMaintenance()) {
|
||||
auto buildDate =
|
||||
QDateTime::fromString(__TIMESTAMP__, "ddd MMM dd hh:mm:ss yyyy")
|
||||
.toSecsSinceEpoch();
|
||||
|
||||
if (buildDate > serialKey.getExpiration()) {
|
||||
throw std::runtime_error(getMaintenanceMessage(serialKey));
|
||||
}
|
||||
}
|
||||
|
||||
if (!acceptExpired && serialKey.isExpired(::time(nullptr))) {
|
||||
throw std::runtime_error("Serial key expired");
|
||||
}
|
||||
|
||||
#ifdef SYNERGY_ENABLE_LICENSING
|
||||
if (!serialKey.isValid()) {
|
||||
throw std::runtime_error("The serial key is not valid.");
|
||||
}
|
||||
#endif // SYNERGY_ENABLE_LICENSING
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
LicenseManager::LicenseManager(AppConfig *appConfig)
|
||||
: m_pAppConfig(appConfig),
|
||||
m_serialKey(appConfig->edition()),
|
||||
m_registry(*appConfig) {}
|
||||
|
||||
void LicenseManager::setSerialKey(SerialKey serialKey, bool acceptExpired) {
|
||||
checkSerialKey(serialKey, acceptExpired);
|
||||
|
||||
if (serialKey != m_serialKey) {
|
||||
using std::swap;
|
||||
swap(serialKey, m_serialKey);
|
||||
m_pAppConfig->setSerialKey(QString::fromStdString(m_serialKey.toString()));
|
||||
|
||||
emit showLicenseNotice(getLicenseNotice());
|
||||
validateSerialKey();
|
||||
m_registry.scheduleRegistration();
|
||||
|
||||
if (m_serialKey.edition() != serialKey.edition()) {
|
||||
m_pAppConfig->setEdition(m_serialKey.edition());
|
||||
emit editionChanged(m_serialKey.edition());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void LicenseManager::notifyUpdate(
|
||||
QString fromVersion, QString toVersion) const {
|
||||
if ((fromVersion == "Unknown") && (m_serialKey == SerialKey(kUnregistered))) {
|
||||
return;
|
||||
}
|
||||
|
||||
ActivationNotifier *notifier = new ActivationNotifier();
|
||||
notifier->setUpdateInfo(
|
||||
fromVersion, toVersion, QString::fromStdString(m_serialKey.toString()));
|
||||
|
||||
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, "notifyUpdate", Qt::QueuedConnection);
|
||||
}
|
||||
|
||||
Edition LicenseManager::activeEdition() const { return m_serialKey.edition(); }
|
||||
|
||||
QString LicenseManager::activeEditionName() const {
|
||||
return getEditionName(activeEdition(), m_serialKey.isTrial());
|
||||
}
|
||||
|
||||
const SerialKey &LicenseManager::serialKey() const { return m_serialKey; }
|
||||
|
||||
void LicenseManager::refresh() {
|
||||
if (!m_pAppConfig->serialKey().isEmpty()) {
|
||||
try {
|
||||
SerialKey serialKey(m_pAppConfig->serialKey().toStdString());
|
||||
setSerialKey(serialKey, true);
|
||||
} catch (const std::exception &e) {
|
||||
qDebug() << e.what();
|
||||
m_serialKey = SerialKey();
|
||||
m_pAppConfig->clearSerialKey();
|
||||
}
|
||||
}
|
||||
if (!m_serialKey.isValid()) {
|
||||
emit InvalidLicense();
|
||||
}
|
||||
}
|
||||
|
||||
QString LicenseManager::getEditionName(Edition const edition, bool trial) {
|
||||
SerialKeyEdition KeyEdition(edition);
|
||||
std::string name = KeyEdition.getProductName();
|
||||
|
||||
if (trial) {
|
||||
name += " (Trial)";
|
||||
}
|
||||
|
||||
return QString::fromUtf8(name.c_str(), static_cast<int>(name.size()));
|
||||
}
|
||||
|
||||
void LicenseManager::notifyActivation(QString identity) const {
|
||||
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);
|
||||
}
|
||||
|
||||
QString LicenseManager::getLicenseNotice() const {
|
||||
QString Notice;
|
||||
|
||||
if (m_serialKey.isTemporary()) {
|
||||
if (m_serialKey.isTrial()) {
|
||||
Notice = getTrialNotice();
|
||||
} else {
|
||||
Notice = getTemporaryNotice();
|
||||
}
|
||||
}
|
||||
|
||||
return Notice;
|
||||
}
|
||||
|
||||
void LicenseManager::registerLicense() { m_registry.registerLicense(); }
|
||||
|
||||
QString LicenseManager::getTrialNotice() const {
|
||||
QString Notice;
|
||||
|
||||
if (m_serialKey.isExpired(::time(0))) {
|
||||
Notice = "<html><head/><body><p>"
|
||||
"Trial expired - "
|
||||
"<a href=\"https://symless.com/synergy/purchase?source=gui\" "
|
||||
"style=\"color: #FFFFFF;\">Buy now</a>"
|
||||
"</p></body></html>";
|
||||
} else {
|
||||
Notice = "<html><head/><body><p>"
|
||||
"Trial expires in %1 day%2 - "
|
||||
"<a href=\"https://symless.com/synergy/purchase?source=gui\" "
|
||||
"style=\"color: #FFFFFF;\">Buy now</a>"
|
||||
"</p></body></html>";
|
||||
|
||||
time_t daysLeft = m_serialKey.daysLeft(::time(0));
|
||||
Notice = Notice.arg(daysLeft).arg((daysLeft == 1) ? "" : "s");
|
||||
}
|
||||
|
||||
return Notice;
|
||||
}
|
||||
|
||||
QString LicenseManager::getTemporaryNotice() const {
|
||||
QString Notice;
|
||||
|
||||
if (m_serialKey.isExpired(::time(0))) {
|
||||
Notice = "<html><head/><body><p>"
|
||||
"License expired - "
|
||||
"<a href=\"https://symless.com/synergy/purchase?source=gui\" "
|
||||
"style=\"color: #FFFFFF;\">Renew now</a>"
|
||||
"</p></body></html>";
|
||||
} else if (m_serialKey.isExpiring(::time(0))) {
|
||||
Notice = "<html><head/><body><p>"
|
||||
"License expires in %1 day%2 - "
|
||||
"<a href=\"https://symless.com/synergy/purchase?source=gui\" "
|
||||
"style=\"color: #FFFFFF;\">Renew now</a>"
|
||||
"</p></body></html>";
|
||||
|
||||
time_t daysLeft = m_serialKey.daysLeft(::time(0));
|
||||
Notice = Notice.arg(daysLeft).arg((daysLeft == 1) ? "" : "s");
|
||||
}
|
||||
|
||||
return Notice;
|
||||
}
|
||||
|
||||
void LicenseManager::validateSerialKey() const {
|
||||
if (m_serialKey.isValid()) {
|
||||
if (m_serialKey.isTemporary()) {
|
||||
QTimer::singleShot(
|
||||
m_serialKey.getSpanLeft(), this, SLOT(validateSerialKey()));
|
||||
}
|
||||
} else {
|
||||
emit InvalidLicense();
|
||||
}
|
||||
}
|
||||
|
|
@ -1,60 +0,0 @@
|
|||
/*
|
||||
* synergy -- mouse and keyboard sharing utility
|
||||
* Copyright (C) 2015 Synergy Ltd.
|
||||
*
|
||||
* This package is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* found in the file LICENSE that should have accompanied this file.
|
||||
*
|
||||
* This package is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "LicenseRegistry.h"
|
||||
#include "shared/EditionType.h"
|
||||
#include "shared/SerialKey.h"
|
||||
|
||||
#include <QObject>
|
||||
|
||||
class AppConfig;
|
||||
|
||||
class LicenseManager : public QObject {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
LicenseManager(AppConfig *appConfig);
|
||||
void setSerialKey(SerialKey serialKey, bool acceptExpired = false);
|
||||
void refresh();
|
||||
Edition activeEdition() const;
|
||||
QString activeEditionName() const;
|
||||
const SerialKey &serialKey() const;
|
||||
void notifyUpdate(QString fromVersion, QString toVersion) const;
|
||||
static QString getEditionName(Edition edition, bool trial = false);
|
||||
void notifyActivation(QString identity) const;
|
||||
QString getLicenseNotice() const;
|
||||
|
||||
private:
|
||||
AppConfig *m_pAppConfig;
|
||||
SerialKey m_serialKey;
|
||||
LicenseRegistry m_registry;
|
||||
|
||||
public slots:
|
||||
void validateSerialKey() const;
|
||||
void registerLicense();
|
||||
|
||||
signals:
|
||||
void editionChanged(Edition) const;
|
||||
void InvalidLicense() const;
|
||||
void showLicenseNotice(const QString ¬ice) const;
|
||||
|
||||
protected:
|
||||
QString getTrialNotice() const;
|
||||
QString getTemporaryNotice() const;
|
||||
};
|
||||
|
|
@ -1,101 +0,0 @@
|
|||
/*
|
||||
* synergy -- mouse and keyboard sharing utility
|
||||
* Copyright (C) 2022 Synergy Ltd.
|
||||
*
|
||||
* This package is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* found in the file LICENSE that should have accompanied this file.
|
||||
*
|
||||
* This package is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include <QJsonDocument>
|
||||
#include <QJsonObject>
|
||||
#include <QNetworkReply>
|
||||
#include <QTimer>
|
||||
|
||||
#include "AppConfig.h"
|
||||
#include "LicenseRegistry.h"
|
||||
#include <QSysInfo>
|
||||
|
||||
const char *const kLicenseRegistryUrl =
|
||||
"https://api2.prod.symless.com/license/register";
|
||||
|
||||
LicenseRegistry::LicenseRegistry(AppConfig &config) : m_config(config) {
|
||||
connect(&m_timer, SIGNAL(timeout()), this, SLOT(registerLicense()));
|
||||
}
|
||||
|
||||
void LicenseRegistry::registerLicense() {
|
||||
m_timer.stop();
|
||||
if (m_config.edition() == Edition::kBusiness) {
|
||||
const auto url = QUrl(kLicenseRegistryUrl);
|
||||
|
||||
auto request = QNetworkRequest(url);
|
||||
request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");
|
||||
|
||||
m_manager.post(request, getRequestData());
|
||||
connect(
|
||||
&m_manager, SIGNAL(finished(QNetworkReply *)), this,
|
||||
SLOT(handleResponse(QNetworkReply *)));
|
||||
}
|
||||
}
|
||||
|
||||
void LicenseRegistry::handleResponse(QNetworkReply *reply) {
|
||||
if (reply) {
|
||||
const auto HOUR = (60 * 60); // seconds per hour
|
||||
const auto DAY = (24 * HOUR); // seconds per day
|
||||
const auto WEEK = (7 * DAY); // seconds per week
|
||||
const auto currentTimestamp = time(nullptr);
|
||||
|
||||
if (reply->error() == QNetworkReply::NoError) {
|
||||
m_config.setLicenseNextCheck(currentTimestamp + WEEK);
|
||||
} else {
|
||||
m_config.setLicenseNextCheck(currentTimestamp + HOUR);
|
||||
}
|
||||
|
||||
scheduleRegistration();
|
||||
reply->deleteLater();
|
||||
}
|
||||
}
|
||||
|
||||
QByteArray LicenseRegistry::getRequestData() const {
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(5, 11, 0)
|
||||
QString guid(QSysInfo::machineUniqueId());
|
||||
#else
|
||||
QString guid;
|
||||
#endif
|
||||
|
||||
QJsonObject data;
|
||||
if (!guid.isEmpty()) {
|
||||
data["guid"] = guid;
|
||||
data["guid_type"] = "system";
|
||||
} else {
|
||||
data["guid"] = m_config.guid();
|
||||
data["guid_type"] = "synergy";
|
||||
}
|
||||
|
||||
data["key"] = m_config.serialKey();
|
||||
data["is_server"] = m_config.serverGroupChecked();
|
||||
|
||||
return QJsonDocument(data).toJson();
|
||||
}
|
||||
|
||||
void LicenseRegistry::scheduleRegistration() {
|
||||
const auto nextCheck = m_config.licenseNextCheck();
|
||||
const auto currentTimestamp = static_cast<unsigned long long>(time(nullptr));
|
||||
|
||||
if (currentTimestamp >= nextCheck) {
|
||||
registerLicense();
|
||||
} else {
|
||||
const auto interval =
|
||||
(nextCheck - currentTimestamp) * 1000; // interval in milliseconds
|
||||
m_timer.setInterval(static_cast<int>(interval));
|
||||
m_timer.setSingleShot(true);
|
||||
m_timer.start();
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load diff
|
|
@ -35,9 +35,10 @@
|
|||
#include "ServerConfig.h"
|
||||
#include "ServerConnection.h"
|
||||
#include "TrayIcon.h"
|
||||
#include "global/Ipc.h"
|
||||
#include "gui/QIpcClient.h"
|
||||
#include "gui/TlsUtility.h"
|
||||
#include "gui/VersionChecker.h"
|
||||
#include "shared/Ipc.h"
|
||||
|
||||
class QAction;
|
||||
class QMenu;
|
||||
|
|
@ -57,8 +58,7 @@ class QSynergyApplication;
|
|||
class SetupWizard;
|
||||
class DataDownloader;
|
||||
class CommandProcess;
|
||||
class SslCertificate;
|
||||
class LicenseManager;
|
||||
class TlsCertificate;
|
||||
|
||||
class MainWindow : public QMainWindow, public Ui::MainWindowBase {
|
||||
Q_OBJECT
|
||||
|
|
@ -80,60 +80,57 @@ public:
|
|||
};
|
||||
|
||||
enum class CoreMode { Client, Server };
|
||||
|
||||
enum class LogLevel { Error, Info };
|
||||
|
||||
enum class RuningState { Started, Stopped };
|
||||
|
||||
public:
|
||||
#ifdef SYNERGY_ENABLE_LICENSING
|
||||
MainWindow(AppConfig &appConfig, LicenseManager &licenseManager);
|
||||
#else
|
||||
explicit MainWindow(AppConfig &appConfig);
|
||||
#endif
|
||||
~MainWindow() override;
|
||||
|
||||
public:
|
||||
void setVisible(bool visible) override;
|
||||
CoreMode coreMode() const {
|
||||
auto isClient = m_pRadioGroupClient->isChecked();
|
||||
return isClient ? CoreMode::Client : CoreMode::Server;
|
||||
}
|
||||
CoreState coreState() const { return m_CoreState; }
|
||||
QString hostname() const { return m_pLineEditHostname->text(); }
|
||||
QString configFilename();
|
||||
CoreMode coreMode() const;
|
||||
QString address() const;
|
||||
QString appPath(const QString &name);
|
||||
QString appPath(const QString &name) const;
|
||||
void open();
|
||||
void clearLog();
|
||||
VersionChecker &versionChecker() { return m_VersionChecker; }
|
||||
ServerConfig &serverConfig() { return m_ServerConfig; }
|
||||
void showConfigureServer(const QString &message);
|
||||
void showConfigureServer() { showConfigureServer(""); }
|
||||
void autoAddScreen(const QString name);
|
||||
#ifdef SYNERGY_ENABLE_LICENSING
|
||||
LicenseManager &licenseManager() const;
|
||||
int raiseActivationDialog();
|
||||
#endif
|
||||
|
||||
public slots:
|
||||
void setEdition(Edition edition);
|
||||
#ifdef SYNERGY_ENABLE_LICENSING
|
||||
void InvalidLicense();
|
||||
void showLicenseNotice(const QString &message);
|
||||
#endif
|
||||
void appendLogRaw(const QString &text);
|
||||
LicenseHandler &licenseHandler();
|
||||
int showActivationDialog();
|
||||
void appendLogInfo(const QString &text);
|
||||
void appendLogDebug(const QString &text);
|
||||
void appendLogError(const QString &text);
|
||||
void startCore();
|
||||
void retryStart();
|
||||
void actionStart();
|
||||
void handleIdleService(const QString &text);
|
||||
|
||||
protected slots:
|
||||
void updateLocalFingerprint();
|
||||
void updateScreenName();
|
||||
signals:
|
||||
void created();
|
||||
void shown();
|
||||
|
||||
public slots:
|
||||
void onAppAboutToQuit();
|
||||
|
||||
private slots:
|
||||
void onCreated();
|
||||
void onShown();
|
||||
void onAppConfigLoaded();
|
||||
void onAppConfigTlsChanged();
|
||||
void onAppConfigScreenNameChanged();
|
||||
void onAppConfigInvertConnection();
|
||||
void onLicenseHandlerSerialKeyChanged(const QString &serialKey);
|
||||
void onLicenseHandlerInvalidLicense();
|
||||
void onIpcClientReadLogLine(const QString &text);
|
||||
void onIpcClientErrorMessage(const QString &text);
|
||||
void onIpcClientInfoMessage(const QString &text);
|
||||
void onCoreProcessFinished(int exitCode, QProcess::ExitStatus);
|
||||
void onVersionCheckerUpdateFound(const QString &version);
|
||||
void onTrayIconCreate(QSystemTrayIcon::ActivationReason reason);
|
||||
void onActionStartCoreTriggered();
|
||||
void onActionStopCoreTriggered();
|
||||
void onCoreProcessReadyReadStandardOutput();
|
||||
void onCoreProcessReadyReadStandardError();
|
||||
void on_m_pButtonApply_clicked();
|
||||
void on_m_pLabelComputerName_linkActivated(const QString &link);
|
||||
void on_m_pLabelFingerprint_linkActivated(const QString &link);
|
||||
void on_m_pButtonConnect_clicked();
|
||||
void on_m_pButtonConnectToClient_clicked();
|
||||
void on_m_pRadioGroupServer_clicked(bool);
|
||||
void on_m_pRadioGroupClient_clicked(bool);
|
||||
void on_m_pButtonConfigureServer_clicked();
|
||||
|
|
@ -142,24 +139,15 @@ protected slots:
|
|||
void on_m_pActionHelp_triggered();
|
||||
void on_m_pActionSettings_triggered();
|
||||
void on_m_pActivate_triggered();
|
||||
void coreProcessExit(int exitCode, QProcess::ExitStatus);
|
||||
void trayActivated(QSystemTrayIcon::ActivationReason reason);
|
||||
void stopCore();
|
||||
void logOutput();
|
||||
void logError();
|
||||
void updateFound(const QString &version);
|
||||
void saveSettings();
|
||||
|
||||
protected:
|
||||
private:
|
||||
QSettings &settings() { return *appConfig().config().currentSettings(); }
|
||||
AppConfig &appConfig() { return m_AppConfig; }
|
||||
AppConfig const &appConfig() const { return m_AppConfig; }
|
||||
AppConfig *appConfigPtr() { return &m_AppConfig; }
|
||||
void initConnections();
|
||||
void createMenuBar();
|
||||
void createStatusBar();
|
||||
void createTrayIcon();
|
||||
void loadSettings();
|
||||
void applyConfig();
|
||||
void setIcon(CoreState state) const;
|
||||
void setCoreState(CoreState state);
|
||||
bool checkForApp(int which, QString &app);
|
||||
|
|
@ -168,51 +156,45 @@ protected:
|
|||
void setStatus(const QString &status);
|
||||
void sendIpcMessage(IpcMessageType type, const char *buffer, bool showErrors);
|
||||
void updateFromLogLine(const QString &line);
|
||||
QString getIPAddresses();
|
||||
QString getIPAddresses() const;
|
||||
void stopService();
|
||||
void stopDesktop();
|
||||
void enableServer(bool enable);
|
||||
void enableClient(bool enable);
|
||||
|
||||
QString getProfileRootForArg();
|
||||
QString getProfileRootForArg() const;
|
||||
void checkConnected(const QString &line);
|
||||
void checkFingerprint(const QString &line);
|
||||
bool checkSecureSocket(const QString &line);
|
||||
void checkLicense(const QString &line);
|
||||
QString getTimeStamp() const;
|
||||
void restartCore();
|
||||
void showEvent(QShowEvent *) override;
|
||||
void secureSocket(bool secureSocket);
|
||||
void windowStateChanged();
|
||||
void connectSlots() const;
|
||||
void updateWindowTitle();
|
||||
void processCoreLogLine(const QString &line);
|
||||
void startCore();
|
||||
void onCoreProcessRetryStart();
|
||||
void updateLocalFingerprint();
|
||||
void updateScreenName();
|
||||
void saveSettings();
|
||||
QString configFilename();
|
||||
void showConfigureServer(const QString &message);
|
||||
void showConfigureServer() { showConfigureServer(""); }
|
||||
void showLicenseNotice();
|
||||
void stopCore();
|
||||
|
||||
#ifdef Q_OS_MAC
|
||||
void checkOSXNotification(const QString &line);
|
||||
#endif
|
||||
#ifdef SYNERGY_ENABLE_LICENSING
|
||||
void checkLicense(const QString &line);
|
||||
#endif
|
||||
QString getTimeStamp();
|
||||
void restartCore();
|
||||
|
||||
void showEvent(QShowEvent *) override;
|
||||
void secureSocket(bool secureSocket);
|
||||
|
||||
void windowStateChanged();
|
||||
|
||||
private:
|
||||
void updateWindowTitle();
|
||||
|
||||
#ifdef SYNERGY_ENABLE_LICENSING
|
||||
LicenseManager *m_LicenseManager = nullptr;
|
||||
#endif
|
||||
|
||||
AppConfig &m_AppConfig;
|
||||
ServerConfig m_ServerConfig;
|
||||
ServerConnection m_serverConnection;
|
||||
ClientConnection m_clientConnection;
|
||||
VersionChecker m_VersionChecker;
|
||||
QIpcClient m_IpcClient;
|
||||
TrayIcon m_trayIcon;
|
||||
TrayIcon m_TrayIcon;
|
||||
QMutex m_StopDesktopMutex;
|
||||
|
||||
#ifdef SYNERGY_ENABLE_LICENSING
|
||||
bool m_ActivationDialogRunning = false;
|
||||
QStringList m_PendingClientNames;
|
||||
#endif
|
||||
|
||||
RuningState m_ExpectedRunningState = RuningState::Stopped;
|
||||
std::unique_ptr<QProcess> m_pCoreProcess;
|
||||
QMenuBar *m_pMenuBar = nullptr;
|
||||
|
|
@ -226,16 +208,10 @@ private:
|
|||
bool m_SecureSocket = false;
|
||||
QString m_SecureSocketVersion = "";
|
||||
|
||||
private slots:
|
||||
void on_m_pButtonApply_clicked();
|
||||
void on_windowShown();
|
||||
|
||||
void on_m_pLabelComputerName_linkActivated(const QString &link);
|
||||
void on_m_pLabelFingerprint_linkActivated(const QString &link);
|
||||
|
||||
void on_m_pButtonConnect_clicked();
|
||||
void on_m_pButtonConnectToClient_clicked();
|
||||
|
||||
signals:
|
||||
void windowShown();
|
||||
AppConfig &m_AppConfig;
|
||||
LicenseHandler m_LicenseHandler;
|
||||
ServerConfig m_ServerConfig;
|
||||
ServerConnection m_ServerConnection;
|
||||
ClientConnection m_ClientConnection;
|
||||
synergy::gui::TlsUtility m_TlsUtility;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -7,11 +7,11 @@
|
|||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>750</width>
|
||||
<height>650</height>
|
||||
<height>700</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
||||
<sizepolicy hsizetype="Fixed" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
|
|
@ -34,83 +34,45 @@
|
|||
<number>20</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QWidget" name="m_pWidgetUpdate" native="true">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||
<property name="spacing">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<property name="leftMargin">
|
||||
<number>2</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>10</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QLabel" name="m_pIconUpdate">
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="pixmap">
|
||||
<pixmap resource="../res/Synergy.qrc">:/res/icons/16x16/warning.png</pixmap>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="m_pLabelUpdate">
|
||||
<property name="text">
|
||||
<string notr="true">m_pLabelUpdate</string>
|
||||
</property>
|
||||
<property name="openExternalLinks">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="m_pSpacerUpdate">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>469</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="m_pLabelComputerName">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>65535</width>
|
||||
<height>65535</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<family>Arial</family>
|
||||
<kerning>true</kerning>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string notr="true">This computer's name:</string>
|
||||
</property>
|
||||
</widget>
|
||||
<layout class="QHBoxLayout" name="m_layout1">
|
||||
<item>
|
||||
<widget class="QLabel" name="m_pLabelComputerName">
|
||||
<property name="text">
|
||||
<string notr="true">This computer's name:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="m_pSpacerUpdate">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="m_pLabelUpdate">
|
||||
<property name="styleSheet">
|
||||
<string notr="true">padding: 3px 5px;
|
||||
border-radius: 3px;
|
||||
background-color: #3B67D3;
|
||||
color: #ffffff;
|
||||
top: 3px;</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string notr="true">m_pLabelUpdate</string>
|
||||
</property>
|
||||
<property name="openExternalLinks">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="verticalSpacer_5">
|
||||
|
|
@ -138,23 +100,11 @@
|
|||
<item>
|
||||
<widget class="QWidget" name="m_pMainWidgets" native="true">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>220</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>16777215</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_8">
|
||||
<property name="spacing">
|
||||
<number>16</number>
|
||||
|
|
@ -173,17 +123,11 @@
|
|||
</property>
|
||||
<item>
|
||||
<widget class="QFrame" name="m_pGroupServer">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>16777215</width>
|
||||
<height>250</height>
|
||||
</size>
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="styleSheet">
|
||||
<string notr="true">.QFrame{
|
||||
|
|
@ -192,193 +136,162 @@ border-radius: 4px;
|
|||
background-color: rgba(192,192,192, 0.1);
|
||||
}</string>
|
||||
</property>
|
||||
<property name="frameShape">
|
||||
<enum>QFrame::StyledPanel</enum>
|
||||
</property>
|
||||
<property name="frameShadow">
|
||||
<enum>QFrame::Raised</enum>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<property name="topMargin">
|
||||
<number>11</number>
|
||||
<property name="spacing">
|
||||
<number>15</number>
|
||||
</property>
|
||||
<item>
|
||||
<item alignment="Qt::AlignTop">
|
||||
<widget class="QRadioButton" name="m_pRadioGroupServer">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>300</width>
|
||||
<height>30</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>65535</width>
|
||||
<height>30</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="styleSheet">
|
||||
<string notr="true">QRadioButton::indicator{
|
||||
top: -7px;
|
||||
top: -7px;
|
||||
}</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Use this computer's keyboard and mouse
|
||||
(make this computer the server)</string>
|
||||
(make this computer the &server)</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="verticalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeType">
|
||||
<enum>QSizePolicy::Fixed</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>10</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="m_pLabelClientIp">
|
||||
<property name="text">
|
||||
<string>Client IP address or hostname:</string>
|
||||
</property>
|
||||
<property name="indent">
|
||||
<number>20</number>
|
||||
</property>
|
||||
<item alignment="Qt::AlignTop">
|
||||
<widget class="QWidget" name="m_pWidgetServer" native="true">
|
||||
<layout class="QVBoxLayout" name="m_pLayoutServer">
|
||||
<property name="spacing">
|
||||
<number>15</number>
|
||||
</property>
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QWidget" name="m_pWidgetServerInverse" native="true">
|
||||
<layout class="QVBoxLayout" name="m_pLayoutServerInverse">
|
||||
<property name="spacing">
|
||||
<number>15</number>
|
||||
</property>
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QLabel" name="m_pLabelClientIp">
|
||||
<property name="text">
|
||||
<string>Client IP address or hostname:</string>
|
||||
</property>
|
||||
<property name="indent">
|
||||
<number>20</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_3">
|
||||
<property name="leftMargin">
|
||||
<number>20</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QLineEdit" name="m_pLineEditClientIp"/>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="m_pButtonConnectToClient">
|
||||
<property name="text">
|
||||
<string>Connect</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="synergy_widgets::ServerStateLabel" name="m_pLabelServerState">
|
||||
<property name="text">
|
||||
<string>No clients connected</string>
|
||||
</property>
|
||||
<property name="indent">
|
||||
<number>20</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="m_pLabelFingerprint">
|
||||
<property name="text">
|
||||
<string><html><head/><body><p>TLS enabled (<a href="#"><span style=" text-decoration: underline; color:#4285f4;">fingerprint</span></a>)</p></body></html></string>
|
||||
</property>
|
||||
<property name="textFormat">
|
||||
<enum>Qt::RichText</enum>
|
||||
</property>
|
||||
<property name="indent">
|
||||
<number>20</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="verticalSpacer_2">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>10</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_4">
|
||||
<item>
|
||||
<spacer name="spacer_2">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="m_pButtonConfigureServer">
|
||||
<property name="text">
|
||||
<string>&Configure</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_3">
|
||||
<property name="leftMargin">
|
||||
<number>20</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QLineEdit" name="m_pLineEditClienIp"/>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="m_pButtonConnectToClient">
|
||||
<property name="text">
|
||||
<string>Connect</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="synergy_widgets::ServerStateLabel" name="m_pLabelServerState">
|
||||
<property name="text">
|
||||
<string>No clients connected</string>
|
||||
</property>
|
||||
<property name="indent">
|
||||
<number>20</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="m_pLabelFingerprint">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>16777215</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string><html><head/><body><p>TLS enabled (<a href="#"><span style=" text-decoration: underline; color:#4285f4;">fingerprint</span></a>)</p></body></html></string>
|
||||
</property>
|
||||
<property name="textFormat">
|
||||
<enum>Qt::RichText</enum>
|
||||
</property>
|
||||
<property name="indent">
|
||||
<number>20</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="verticalSpacer_2">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>10</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_4">
|
||||
<item>
|
||||
<spacer>
|
||||
<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="m_pButtonConfigureServer">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>16777215</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>&Configure</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QFrame" name="m_pGroupClient">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>16777215</width>
|
||||
<height>250</height>
|
||||
</size>
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="styleSheet">
|
||||
<string notr="true">.QFrame{
|
||||
|
|
@ -387,36 +300,15 @@ border-radius: 4px;
|
|||
background-color: rgba(192,192,192, 0.1);
|
||||
}</string>
|
||||
</property>
|
||||
<property name="frameShape">
|
||||
<enum>QFrame::StyledPanel</enum>
|
||||
</property>
|
||||
<property name="frameShadow">
|
||||
<enum>QFrame::Raised</enum>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_5">
|
||||
<property name="spacing">
|
||||
<number>15</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>11</number>
|
||||
</property>
|
||||
<item>
|
||||
<item alignment="Qt::AlignTop">
|
||||
<widget class="QRadioButton" name="m_pRadioGroupClient">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>30</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>300</width>
|
||||
<height>30</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="styleSheet">
|
||||
<string notr="true">QRadioButton::indicator{
|
||||
top: -7px;
|
||||
|
|
@ -424,18 +316,83 @@ background-color: rgba(192,192,192, 0.1);
|
|||
</property>
|
||||
<property name="text">
|
||||
<string>Use another computer’s mouse and keyboard
|
||||
(make this computer the client)</string>
|
||||
(make this computer the &client)</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item alignment="Qt::AlignTop">
|
||||
<widget class="QWidget" name="m_pWidgetClient" native="true">
|
||||
<layout class="QVBoxLayout" name="m_pLayoutClient">
|
||||
<property name="spacing">
|
||||
<number>15</number>
|
||||
</property>
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QLabel" name="m_pLabelServerName">
|
||||
<property name="text">
|
||||
<string>Server IP address or hostname:</string>
|
||||
</property>
|
||||
<property name="indent">
|
||||
<number>20</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||
<property name="leftMargin">
|
||||
<number>20</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QLineEdit" name="m_pLineEditHostname">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Hostname or IP address of the server computer.</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="m_pButtonConnect">
|
||||
<property name="text">
|
||||
<string>Connect</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="synergy_widgets::ClientStateLabel" name="m_pLabelClientState">
|
||||
<property name="text">
|
||||
<string>Connected to server</string>
|
||||
</property>
|
||||
<property name="indent">
|
||||
<number>20</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="verticalSpacer_4">
|
||||
<spacer name="verticalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeType">
|
||||
<enum>QSizePolicy::Minimum</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
|
|
@ -444,104 +401,6 @@ background-color: rgba(192,192,192, 0.1);
|
|||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_3">
|
||||
<property name="leftMargin">
|
||||
<number>19</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>10</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QLabel" name="m_pLabelServerName">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Maximum">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>&Server IP address or hostname:</string>
|
||||
</property>
|
||||
<property name="buddy">
|
||||
<cstring>m_pLineEditHostname</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLineEdit" name="m_pLineEditHostname">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Maximum" vsizetype="Maximum">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>200</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Hostname or IP address of the server computer.</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="synergy_widgets::ClientStateLabel" name="m_pLabelClientState">
|
||||
<property name="text">
|
||||
<string>Connected to server</string>
|
||||
</property>
|
||||
<property name="indent">
|
||||
<number>20</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="verticalSpacer_3">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeType">
|
||||
<enum>QSizePolicy::Expanding</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>10</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_9">
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_2">
|
||||
<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="m_pButtonConnect">
|
||||
<property name="text">
|
||||
<string>Connect</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
|
|
@ -687,28 +546,19 @@ background-color: rgba(192,192,192, 0.1);
|
|||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="m_trialLabel">
|
||||
<property name="font">
|
||||
<font>
|
||||
<family>Arial</family>
|
||||
<pointsize>-1</pointsize>
|
||||
<bold>true</bold>
|
||||
</font>
|
||||
</property>
|
||||
<widget class="QLabel" name="m_labelNotice">
|
||||
<property name="autoFillBackground">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="styleSheet">
|
||||
<string notr="true">font-size: 13px;
|
||||
font-weight: 700;
|
||||
padding: 3px 5px;
|
||||
<string notr="true">padding: 3px 5px;
|
||||
border-radius: 3px;
|
||||
background-color: #EC4C47;
|
||||
background-color: #3B67D3;
|
||||
color: #ffffff;
|
||||
top: 3px;</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string notr="true"/>
|
||||
<string notr="true">m_labelNotice</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* synergy -- mouse and keyboard sharing utility
|
||||
* Copyright (C) 2013-2016 Symless Ltd.
|
||||
* Copyright (C) 2013 Symless Ltd.
|
||||
*
|
||||
* This package is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
|
|
@ -17,7 +17,6 @@
|
|||
|
||||
#include "QUtility.h"
|
||||
|
||||
#include "CommandProcess.h"
|
||||
#include "ProcessorArch.h"
|
||||
|
||||
#if defined(Q_OS_LINUX)
|
||||
|
|
|
|||
|
|
@ -22,14 +22,13 @@
|
|||
#include "Config.h"
|
||||
#include "Hotkey.h"
|
||||
#include "MainWindow.h"
|
||||
#include "gui/constants.h"
|
||||
|
||||
#include <QAbstractButton>
|
||||
#include <QMessageBox>
|
||||
#include <QPushButton>
|
||||
#include <QtCore>
|
||||
|
||||
using synergy::gui::Config;
|
||||
|
||||
static const struct {
|
||||
int x;
|
||||
int y;
|
||||
|
|
@ -162,9 +161,6 @@ void ServerConfig::saveSettings() {
|
|||
settings().endArray();
|
||||
|
||||
settings().endGroup();
|
||||
|
||||
m_pAppConfig->saveSettings();
|
||||
m_pAppConfig->config().markUnsaved();
|
||||
}
|
||||
|
||||
void ServerConfig::loadSettings() {
|
||||
|
|
@ -541,7 +537,7 @@ size_t ServerConfig::setClipboardSharingSize(size_t size) {
|
|||
}
|
||||
|
||||
void ServerConfig::setClientAddress(const QString &address) {
|
||||
if (m_pAppConfig->serverClientMode()) {
|
||||
if (m_pAppConfig->invertConnection()) {
|
||||
m_ClientAddress = address;
|
||||
}
|
||||
}
|
||||
|
|
@ -549,7 +545,7 @@ void ServerConfig::setClientAddress(const QString &address) {
|
|||
QString ServerConfig::getClientAddress() const {
|
||||
QString clientAddress;
|
||||
|
||||
if (m_pAppConfig->serverClientMode()) {
|
||||
if (m_pAppConfig->invertConnection()) {
|
||||
clientAddress = m_ClientAddress.trimmed();
|
||||
}
|
||||
|
||||
|
|
@ -559,11 +555,3 @@ QString ServerConfig::getClientAddress() const {
|
|||
QSettings &ServerConfig::settings() {
|
||||
return *m_pAppConfig->config().currentSettings();
|
||||
}
|
||||
|
||||
bool ServerConfig::isHotkeysAvailable() const {
|
||||
#ifdef SYNERGY_ENABLE_LICENSING
|
||||
return (m_pAppConfig->edition() != Edition::kLite);
|
||||
#else
|
||||
return true;
|
||||
#endif
|
||||
}
|
||||
|
|
|
|||
|
|
@ -81,7 +81,6 @@ public:
|
|||
bool isFull() const;
|
||||
bool isScreenExists(const QString &screenName) const;
|
||||
void addClient(const QString &clientName);
|
||||
bool isHotkeysAvailable() const;
|
||||
QString getClientAddress() const;
|
||||
void setClientAddress(const QString &address);
|
||||
|
||||
|
|
|
|||
|
|
@ -22,7 +22,8 @@
|
|||
#include "ScreenSettingsDialog.h"
|
||||
#include "ServerConfig.h"
|
||||
#include "UpgradeDialog.h"
|
||||
#include "shared/EditionType.h"
|
||||
#include "gui/constants.h"
|
||||
#include "license/ProductEdition.h"
|
||||
|
||||
#include <QFileDialog>
|
||||
#include <QMessageBox>
|
||||
|
|
@ -273,27 +274,12 @@ void ServerConfigDialog::reject() {
|
|||
}
|
||||
|
||||
void ServerConfigDialog::on_m_pButtonNewHotkey_clicked() {
|
||||
if (serverConfig().isHotkeysAvailable()) {
|
||||
Hotkey hotkey;
|
||||
HotkeyDialog dlg(this, hotkey);
|
||||
if (dlg.exec() == QDialog::Accepted) {
|
||||
serverConfig().hotkeys().append(hotkey);
|
||||
m_pListHotkeys->addItem(hotkey.text());
|
||||
onChange();
|
||||
}
|
||||
} else {
|
||||
#ifdef SYNERGY_ENABLE_LICENSING
|
||||
auto edition = appConfig().edition();
|
||||
if (edition == Edition::kLite || edition == Edition::kBasic) {
|
||||
UpgradeDialog upgradeDialog(this);
|
||||
if (appConfig().edition() == Edition::kLite) {
|
||||
upgradeDialog.showDialog(
|
||||
"Upgrade to Synergy 1 Ultimate to enable hotkeys");
|
||||
} else if (appConfig().edition() == Edition::kBasic) {
|
||||
upgradeDialog.showDialog("Upgrade to Synergy 1 Pro to enable hotkeys");
|
||||
}
|
||||
}
|
||||
#endif // SYNERGY_ENABLE_LICENSING
|
||||
Hotkey hotkey;
|
||||
HotkeyDialog dlg(this, hotkey);
|
||||
if (dlg.exec() == QDialog::Accepted) {
|
||||
serverConfig().hotkeys().append(hotkey);
|
||||
m_pListHotkeys->addItem(hotkey.text());
|
||||
onChange();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -20,11 +20,9 @@
|
|||
|
||||
#include "AppConfig.h"
|
||||
#include "MainWindow.h"
|
||||
#include "SslCertificate.h"
|
||||
|
||||
#ifdef SYNERGY_ENABLE_LICENSING
|
||||
#include "UpgradeDialog.h"
|
||||
#endif // SYNERGY_ENABLE_LICENSING
|
||||
#include "gui/TlsCertificate.h"
|
||||
#include "gui/constants.h"
|
||||
|
||||
#include <QDir>
|
||||
#include <QFileDialog>
|
||||
|
|
@ -33,13 +31,20 @@
|
|||
#include <QtGui>
|
||||
#include <memory>
|
||||
|
||||
SettingsDialog::SettingsDialog(QWidget *parent, AppConfig &config)
|
||||
using namespace synergy::license;
|
||||
|
||||
const char *const kProProductName = "Synergy 1 Pro";
|
||||
|
||||
SettingsDialog::SettingsDialog(
|
||||
QWidget *parent, AppConfig &config, const License &license)
|
||||
: QDialog(parent, Qt::WindowTitleHint | Qt::WindowSystemMenuHint),
|
||||
Ui::SettingsDialogBase(),
|
||||
m_appConfig(config) {
|
||||
m_appConfig(config),
|
||||
m_license(license),
|
||||
m_tlsUtility(config, license) {
|
||||
|
||||
setupUi(this);
|
||||
|
||||
// TODO: maybe just accept MainWindow type in ctor?
|
||||
m_pMainWindow = dynamic_cast<MainWindow *>(parent);
|
||||
|
||||
loadFromConfig();
|
||||
|
|
@ -79,9 +84,6 @@ SettingsDialog::SettingsDialog(QWidget *parent, AppConfig &config)
|
|||
connect(m_pCheckBoxLanguageSync, SIGNAL(clicked()), this, SLOT(onChange()));
|
||||
connect(
|
||||
m_pCheckBoxScrollDirection, SIGNAL(clicked()), this, SLOT(onChange()));
|
||||
connect(m_pCheckBoxClientHostMode, SIGNAL(clicked()), this, SLOT(onChange()));
|
||||
connect(
|
||||
m_pCheckBoxServerClientMode, SIGNAL(clicked()), this, SLOT(onChange()));
|
||||
|
||||
adjustSize();
|
||||
}
|
||||
|
|
@ -106,13 +108,12 @@ void SettingsDialog::accept() {
|
|||
appConfig().setMinimizeToTray(m_pCheckBoxMinimizeToTray->isChecked());
|
||||
appConfig().setTlsCertPath(m_pLineEditCertificatePath->text());
|
||||
appConfig().setTlsKeyLength(m_pComboBoxKeyLength->currentText());
|
||||
appConfig().setCryptoEnabled(m_pCheckBoxEnableCrypto->isChecked());
|
||||
appConfig().setTlsEnabled(m_pCheckBoxEnableCrypto->isChecked());
|
||||
appConfig().setLanguageSync(m_pCheckBoxLanguageSync->isChecked());
|
||||
appConfig().setInvertScrollDirection(m_pCheckBoxScrollDirection->isChecked());
|
||||
appConfig().setClientHostMode(m_pCheckBoxClientHostMode->isChecked());
|
||||
appConfig().setServerClientMode(m_pCheckBoxServerClientMode->isChecked());
|
||||
appConfig().setServiceEnabled(m_pCheckBoxServiceEnabled->isChecked());
|
||||
appConfig().setCloseToTray(m_pCheckBoxCloseToTray->isChecked());
|
||||
appConfig().setInvertConnection(m_pInvertConnection->isChecked());
|
||||
|
||||
appConfig().saveSettings();
|
||||
QDialog::accept();
|
||||
|
|
@ -139,11 +140,9 @@ void SettingsDialog::loadFromConfig() {
|
|||
m_pCheckBoxPreventSleep->setChecked(appConfig().preventSleep());
|
||||
m_pCheckBoxMinimizeToTray->setChecked(appConfig().minimizeToTray());
|
||||
m_pLineEditCertificatePath->setText(appConfig().tlsCertPath());
|
||||
m_pCheckBoxEnableCrypto->setChecked(m_appConfig.cryptoEnabled());
|
||||
m_pCheckBoxEnableCrypto->setChecked(m_appConfig.tlsEnabled());
|
||||
m_pCheckBoxLanguageSync->setChecked(m_appConfig.languageSync());
|
||||
m_pCheckBoxScrollDirection->setChecked(m_appConfig.invertScrollDirection());
|
||||
m_pCheckBoxClientHostMode->setChecked(m_appConfig.clientHostMode());
|
||||
m_pCheckBoxServerClientMode->setChecked(m_appConfig.serverClientMode());
|
||||
m_pCheckBoxServiceEnabled->setChecked(m_appConfig.serviceEnabled());
|
||||
m_pCheckBoxCloseToTray->setChecked(m_appConfig.closeToTray());
|
||||
|
||||
|
|
@ -153,6 +152,10 @@ void SettingsDialog::loadFromConfig() {
|
|||
m_pRadioUserScope->setChecked(true);
|
||||
}
|
||||
|
||||
m_pInvertConnection->setChecked(m_appConfig.invertConnection());
|
||||
m_pInvertConnection->setEnabled(
|
||||
m_license.productEdition() == Edition::kBusiness);
|
||||
|
||||
updateTlsControls();
|
||||
}
|
||||
|
||||
|
|
@ -164,20 +167,20 @@ void SettingsDialog::updateTlsControls() {
|
|||
m_pComboBoxKeyLength->findText(appConfig().tlsKeyLength()));
|
||||
}
|
||||
|
||||
m_pCheckBoxEnableCrypto->setChecked(m_appConfig.cryptoEnabled());
|
||||
m_pCheckBoxEnableCrypto->setChecked(m_appConfig.tlsEnabled());
|
||||
|
||||
updateTlsControlsEnabled();
|
||||
}
|
||||
|
||||
void SettingsDialog::updateTlsControlsEnabled() {
|
||||
auto clientMode = appConfig().clientGroupChecked();
|
||||
auto cryptoAvailable = appConfig().cryptoAvailable();
|
||||
auto tlsAvailable = m_tlsUtility.isAvailableAndEnabled();
|
||||
auto tlsChecked = m_pCheckBoxEnableCrypto->isChecked();
|
||||
auto enabled = !clientMode && cryptoAvailable && tlsChecked;
|
||||
auto enabled = !clientMode && tlsAvailable && tlsChecked;
|
||||
|
||||
qDebug(
|
||||
"TLS controls enabled=%d, client=%d, crypto=%d, checked=%d", enabled,
|
||||
clientMode, cryptoAvailable, tlsChecked);
|
||||
"TLS controls enabled=%d, client=%d, available=%d, checked=%d", enabled,
|
||||
clientMode, tlsAvailable, tlsChecked);
|
||||
|
||||
m_pLabelKeyLength->setEnabled(enabled);
|
||||
m_pComboBoxKeyLength->setEnabled(enabled);
|
||||
|
|
@ -209,24 +212,17 @@ void SettingsDialog::on_m_pButtonBrowseLog_clicked() {
|
|||
}
|
||||
}
|
||||
|
||||
void SettingsDialog::on_m_pCheckBoxEnableCrypto_clicked(bool checked) {
|
||||
void SettingsDialog::on_m_pCheckBoxEnableCrypto_clicked(bool) {
|
||||
updateTlsControlsEnabled();
|
||||
|
||||
if (!appConfig().cryptoAvailable()) {
|
||||
|
||||
#ifdef SYNERGY_ENABLE_LICENSING
|
||||
auto edition = appConfig().edition();
|
||||
if (edition == Edition::kLite || edition == Edition::kBasic) {
|
||||
if (kLicensingEnabled && !m_tlsUtility.isAvailable()) {
|
||||
auto edition = m_license.productEdition();
|
||||
if (edition == Edition::kBasic) {
|
||||
UpgradeDialog upgradeDialog(this);
|
||||
if (appConfig().edition() == Edition::kLite) {
|
||||
upgradeDialog.showDialog(
|
||||
"Upgrade to Synergy Ultimate to enable TLS encryption.");
|
||||
} else if (appConfig().edition() == Edition::kBasic) {
|
||||
upgradeDialog.showDialog(
|
||||
"Upgrade to Synergy Pro to enable TLS encryption.");
|
||||
}
|
||||
upgradeDialog.showDialog(
|
||||
QString("Upgrade to %1 to enable TLS encryption.")
|
||||
.arg(kProProductName));
|
||||
}
|
||||
#endif // SYNERGY_ENABLE_LICENSING
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -271,11 +267,11 @@ void SettingsDialog::updateTlsRegenerateButton() {
|
|||
}
|
||||
|
||||
void SettingsDialog::on_m_pPushButtonRegenCert_clicked() {
|
||||
appConfig().generateCertificate(true);
|
||||
m_tlsUtility.generateCertificate(true);
|
||||
}
|
||||
|
||||
void SettingsDialog::updateKeyLengthOnFile(const QString &path) {
|
||||
SslCertificate ssl;
|
||||
TlsCertificate ssl;
|
||||
auto length = ssl.getCertKeyLength(path);
|
||||
auto index = m_pComboBoxKeyLength->findText(length);
|
||||
m_pComboBoxKeyLength->setCurrentIndex(index);
|
||||
|
|
@ -299,8 +295,6 @@ void SettingsDialog::updateControlsEnabled() {
|
|||
m_pComboBoxKeyLength->setEnabled(writable);
|
||||
m_pPushButtonBrowseCert->setEnabled(writable);
|
||||
m_pCheckBoxEnableCrypto->setEnabled(writable);
|
||||
m_pCheckBoxClientHostMode->setEnabled(writable);
|
||||
m_pCheckBoxServerClientMode->setEnabled(writable);
|
||||
m_pCheckBoxServiceEnabled->setEnabled(writable);
|
||||
m_pCheckBoxCloseToTray->setEnabled(writable);
|
||||
|
||||
|
|
@ -311,12 +305,6 @@ void SettingsDialog::updateControlsEnabled() {
|
|||
m_pCheckBoxServiceEnabled->setEnabled(false);
|
||||
#endif
|
||||
|
||||
m_pCheckBoxClientHostMode->setEnabled(
|
||||
writable && isClientMode() && appConfig().initiateConnectionFromServer());
|
||||
m_pCheckBoxServerClientMode->setEnabled(
|
||||
writable && !isClientMode() &&
|
||||
appConfig().initiateConnectionFromServer());
|
||||
|
||||
m_pLabelLogPath->setEnabled(writable && m_pCheckBoxLogToFile->isChecked());
|
||||
m_pLineEditLogFilename->setEnabled(
|
||||
writable && m_pCheckBoxLogToFile->isChecked());
|
||||
|
|
|
|||
|
|
@ -18,9 +18,11 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include "gui/TlsUtility.h"
|
||||
#include "ui_SettingsDialogBase.h"
|
||||
|
||||
#include "CoreInterface.h"
|
||||
#include "gui/CoreInterface.h"
|
||||
#include "license/License.h"
|
||||
#include "validators/ScreenNameValidator.h"
|
||||
|
||||
#include <QDialog>
|
||||
|
|
@ -33,7 +35,9 @@ class SettingsDialog : public QDialog, public Ui::SettingsDialogBase {
|
|||
Q_OBJECT
|
||||
|
||||
public:
|
||||
SettingsDialog(QWidget *parent, AppConfig &config);
|
||||
SettingsDialog(
|
||||
QWidget *parent, AppConfig &config,
|
||||
const synergy::license::License &license);
|
||||
static QString browseForSynergyc(
|
||||
QWidget *parent, const QString &programDir,
|
||||
const QString &coreClientName);
|
||||
|
|
@ -63,9 +67,12 @@ protected:
|
|||
void updateTlsControlsEnabled();
|
||||
|
||||
private:
|
||||
QString m_nameError = "";
|
||||
MainWindow *m_pMainWindow;
|
||||
AppConfig &m_appConfig;
|
||||
CoreInterface m_CoreInterface;
|
||||
CoreInterface m_coreInterface;
|
||||
const synergy::license::License &m_license;
|
||||
synergy::gui::TlsUtility m_tlsUtility;
|
||||
std::unique_ptr<validators::ScreenNameValidator> m_screenNameValidator;
|
||||
|
||||
/// @brief Stores settings scope at start of settings dialog
|
||||
|
|
@ -73,8 +80,6 @@ private:
|
|||
/// the scope and doesn't save changes
|
||||
bool m_isSystemAtStart = false;
|
||||
|
||||
QString m_nameError = "";
|
||||
|
||||
private slots:
|
||||
void on_m_pCheckBoxEnableCrypto_clicked(bool checked);
|
||||
void on_m_pCheckBoxLogToFile_stateChanged(int);
|
||||
|
|
|
|||
|
|
@ -6,8 +6,8 @@
|
|||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>417</width>
|
||||
<height>786</height>
|
||||
<width>500</width>
|
||||
<height>830</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
|
|
@ -38,195 +38,6 @@
|
|||
<property name="verticalSpacing">
|
||||
<number>5</number>
|
||||
</property>
|
||||
<item row="6" column="0">
|
||||
<widget class="QFrame" name="m_pGroupLog1">
|
||||
<property name="styleSheet">
|
||||
<string notr="true">.QFrame{
|
||||
border: 1px solid rgba(192,192,192, 0.2);
|
||||
border-radius: 4px;
|
||||
background-color: rgba(192,192,192, 0.1);
|
||||
}
|
||||
</string>
|
||||
</property>
|
||||
<property name="frameShape">
|
||||
<enum>QFrame::StyledPanel</enum>
|
||||
</property>
|
||||
<property name="frameShadow">
|
||||
<enum>QFrame::Raised</enum>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<property name="topMargin">
|
||||
<number>15</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>15</number>
|
||||
</property>
|
||||
<property name="verticalSpacing">
|
||||
<number>7</number>
|
||||
</property>
|
||||
<item row="0" column="1">
|
||||
<spacer name="horizontalSpacer_5">
|
||||
<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 row="0" column="0">
|
||||
<widget class="QCheckBox" name="m_pCheckBoxLogToFile">
|
||||
<property name="text">
|
||||
<string>Log to file</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="3">
|
||||
<widget class="QComboBox" name="m_pComboLogLevel">
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Info</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Debug</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Debug1</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Debug2</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="2">
|
||||
<widget class="QLabel" name="m_pLabel_3">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Level</string>
|
||||
</property>
|
||||
<property name="buddy">
|
||||
<cstring>m_pComboLogLevel</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0" colspan="4">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_4">
|
||||
<property name="spacing">
|
||||
<number>3</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QLabel" name="m_pLabelLogPath">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Log path</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_7">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeType">
|
||||
<enum>QSizePolicy::Minimum</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>30</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLineEdit" name="m_pLineEditLogFilename">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="m_pButtonBrowseLog">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="cursor">
|
||||
<cursorShape>PointingHandCursor</cursorShape>
|
||||
</property>
|
||||
<property name="styleSheet">
|
||||
<string notr="true">margin: 0px; padding: 0px;</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../res/Synergy.qrc">
|
||||
<normaloff>:/res/icons/64x64/folder.png</normaloff>:/res/icons/64x64/folder.png</iconset>
|
||||
</property>
|
||||
<property name="iconSize">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>13</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="flat">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="9" column="0">
|
||||
<widget class="QLabel" name="m_pLabelGroupScope">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Use settings profile from</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QFrame" name="m_pGroupBoxCommon">
|
||||
<property name="styleSheet">
|
||||
|
|
@ -238,10 +49,10 @@ background-color: rgba(192,192,192, 0.1);
|
|||
</string>
|
||||
</property>
|
||||
<property name="frameShape">
|
||||
<enum>QFrame::StyledPanel</enum>
|
||||
<enum>QFrame::Shape::StyledPanel</enum>
|
||||
</property>
|
||||
<property name="frameShadow">
|
||||
<enum>QFrame::Raised</enum>
|
||||
<enum>QFrame::Shadow::Raised</enum>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_3">
|
||||
<property name="topMargin">
|
||||
|
|
@ -277,10 +88,10 @@ background-color: rgba(192,192,192, 0.1);
|
|||
<item>
|
||||
<spacer name="horizontalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
<enum>Qt::Orientation::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeType">
|
||||
<enum>QSizePolicy::Maximum</enum>
|
||||
<enum>QSizePolicy::Policy::Maximum</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
|
|
@ -382,7 +193,7 @@ background-color: rgba(192,192,192, 0.1);
|
|||
<item>
|
||||
<spacer name="horizontalSpacer_6">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
<enum>Qt::Orientation::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
|
|
@ -413,7 +224,7 @@ background-color: rgba(192,192,192, 0.1);
|
|||
</size>
|
||||
</property>
|
||||
<property name="layoutDirection">
|
||||
<enum>Qt::LeftToRight</enum>
|
||||
<enum>Qt::LayoutDirection::LeftToRight</enum>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Minimize to system &tray</string>
|
||||
|
|
@ -432,26 +243,13 @@ background-color: rgba(192,192,192, 0.1);
|
|||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="m_pLabelGroupNetwork">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Security</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="8" column="0">
|
||||
<spacer name="verticalSpacer_5">
|
||||
<item row="1" column="0">
|
||||
<spacer name="verticalSpacer_2">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
<enum>Qt::Orientation::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeType">
|
||||
<enum>QSizePolicy::Fixed</enum>
|
||||
<enum>QSizePolicy::Policy::Fixed</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
|
|
@ -461,6 +259,61 @@ background-color: rgba(192,192,192, 0.1);
|
|||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="12" column="0">
|
||||
<widget class="QLabel" name="m_pLabelGroupAdvanced">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Advanced</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="11" column="0">
|
||||
<spacer name="verticalSpacer_3">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Orientation::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeType">
|
||||
<enum>QSizePolicy::Policy::Fixed</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>3</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="15" column="0">
|
||||
<spacer name="verticalSpacer_6">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Orientation::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="5" column="0">
|
||||
<widget class="QLabel" name="m_pLabelGroupLog">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Logs</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="13" column="0">
|
||||
<widget class="QFrame" name="m_pGroupAdvanced">
|
||||
<property name="sizePolicy">
|
||||
|
|
@ -478,34 +331,44 @@ background-color: rgba(192,192,192, 0.1);
|
|||
</string>
|
||||
</property>
|
||||
<property name="frameShape">
|
||||
<enum>QFrame::StyledPanel</enum>
|
||||
<enum>QFrame::Shape::StyledPanel</enum>
|
||||
</property>
|
||||
<property name="frameShadow">
|
||||
<enum>QFrame::Raised</enum>
|
||||
<enum>QFrame::Shadow::Raised</enum>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_3">
|
||||
<item row="7" column="0" colspan="3">
|
||||
<item row="1" column="0">
|
||||
<widget class="QCheckBox" name="m_pCheckBoxPreventSleep">
|
||||
<property name="text">
|
||||
<string>Stop this computer from sleeping</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="7" column="0">
|
||||
<widget class="QCheckBox" name="m_pCheckBoxScrollDirection">
|
||||
<property name="text">
|
||||
<string>Invert scroll direction on this computer (client mode)</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="8" column="0" colspan="3">
|
||||
<item row="9" column="0">
|
||||
<widget class="QCheckBox" name="m_pInvertConnection">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Invert server/client TCP connection (business edition)</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="8" column="0">
|
||||
<widget class="QCheckBox" name="m_pCheckBoxLanguageSync">
|
||||
<property name="text">
|
||||
<string>Use server's keyboard language on this computer (client mode)</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QCheckBox" name="m_pCheckBoxServiceEnabled">
|
||||
<property name="text">
|
||||
<string>Use background service (daemon)</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0" rowspan="3" colspan="2">
|
||||
<item row="4" column="0" rowspan="3" colspan="2">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_9">
|
||||
<item>
|
||||
<widget class="QLabel" name="m_pLabelElevate">
|
||||
|
|
@ -559,46 +422,87 @@ background-color: rgba(192,192,192, 0.1);
|
|||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QCheckBox" name="m_pCheckBoxPreventSleep">
|
||||
<item row="2" column="0">
|
||||
<widget class="QCheckBox" name="m_pCheckBoxServiceEnabled">
|
||||
<property name="text">
|
||||
<string>Stop this computer from sleeping</string>
|
||||
<string>Use background service (daemon)</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="9" column="0" colspan="3">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_8">
|
||||
<property name="sizeConstraint">
|
||||
<enum>QLayout::SetNoConstraint</enum>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="9" column="0">
|
||||
<widget class="QLabel" name="m_pLabelGroupScope">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Use settings profile from</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="0">
|
||||
<spacer name="verticalSpacer_4">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Orientation::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeType">
|
||||
<enum>QSizePolicy::Policy::Fixed</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>3</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="10" column="0">
|
||||
<widget class="QFrame" name="m_pGroupScope">
|
||||
<property name="styleSheet">
|
||||
<string notr="true">.QFrame{
|
||||
border: 1px solid rgba(192,192,192, 0.2);
|
||||
border-radius: 4px;
|
||||
background-color: rgba(192,192,192, 0.1);
|
||||
}
|
||||
</string>
|
||||
</property>
|
||||
<property name="frameShape">
|
||||
<enum>QFrame::Shape::StyledPanel</enum>
|
||||
</property>
|
||||
<property name="frameShadow">
|
||||
<enum>QFrame::Shadow::Raised</enum>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_2">
|
||||
<property name="topMargin">
|
||||
<number>15</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>15</number>
|
||||
</property>
|
||||
<property name="verticalSpacing">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<item row="0" column="1">
|
||||
<widget class="QRadioButton" name="m_pRadioSystemScope">
|
||||
<property name="text">
|
||||
<string>All users</string>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="m_pCheckBoxServerClientMode">
|
||||
<property name="text">
|
||||
<string>Use server as a client</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<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="QCheckBox" name="m_pCheckBoxClientHostMode">
|
||||
<property name="text">
|
||||
<string>Use client in host mode</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
<property name="checked">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QRadioButton" name="m_pRadioUserScope">
|
||||
<property name="text">
|
||||
<string>Current user</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
|
|
@ -614,10 +518,10 @@ background-color: rgba(192,192,192, 0.1);
|
|||
</string>
|
||||
</property>
|
||||
<property name="frameShape">
|
||||
<enum>QFrame::StyledPanel</enum>
|
||||
<enum>QFrame::Shape::StyledPanel</enum>
|
||||
</property>
|
||||
<property name="frameShadow">
|
||||
<enum>QFrame::Raised</enum>
|
||||
<enum>QFrame::Shadow::Raised</enum>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<property name="spacing">
|
||||
|
|
@ -647,7 +551,7 @@ background-color: rgba(192,192,192, 0.1);
|
|||
<item>
|
||||
<spacer name="horizontalSpacer_2">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
<enum>Qt::Orientation::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
|
|
@ -715,10 +619,10 @@ background-color: rgba(192,192,192, 0.1);
|
|||
<item>
|
||||
<spacer name="horizontalSpacer_3">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
<enum>Qt::Orientation::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeType">
|
||||
<enum>QSizePolicy::Minimum</enum>
|
||||
<enum>QSizePolicy::Policy::Minimum</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
|
|
@ -774,7 +678,7 @@ background-color: rgba(192,192,192, 0.1);
|
|||
<item>
|
||||
<spacer name="horizontalSpacer_4">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
<enum>Qt::Orientation::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
|
|
@ -796,63 +700,18 @@ background-color: rgba(192,192,192, 0.1);
|
|||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="12" column="0">
|
||||
<widget class="QLabel" name="m_pLabelGroupAdvanced">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
<item row="19" column="0">
|
||||
<widget class="QDialogButtonBox" name="m_pButtonBox">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Orientation::Horizontal</enum>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Advanced</string>
|
||||
<property name="standardButtons">
|
||||
<set>QDialogButtonBox::StandardButton::Cancel|QDialogButtonBox::StandardButton::Save</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="14" column="0">
|
||||
<spacer name="verticalSpacer_6">
|
||||
<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 row="5" column="0">
|
||||
<widget class="QLabel" name="m_pLabelGroupLog">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Logs</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="0">
|
||||
<spacer name="verticalSpacer_4">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeType">
|
||||
<enum>QSizePolicy::Fixed</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>3</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="10" column="0">
|
||||
<widget class="QFrame" name="m_pGroupScope">
|
||||
<item row="6" column="0">
|
||||
<widget class="QFrame" name="m_pGroupLog1">
|
||||
<property name="styleSheet">
|
||||
<string notr="true">.QFrame{
|
||||
border: 1px solid rgba(192,192,192, 0.2);
|
||||
|
|
@ -862,12 +721,12 @@ background-color: rgba(192,192,192, 0.1);
|
|||
</string>
|
||||
</property>
|
||||
<property name="frameShape">
|
||||
<enum>QFrame::StyledPanel</enum>
|
||||
<enum>QFrame::Shape::StyledPanel</enum>
|
||||
</property>
|
||||
<property name="frameShadow">
|
||||
<enum>QFrame::Raised</enum>
|
||||
<enum>QFrame::Shadow::Raised</enum>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_2">
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<property name="topMargin">
|
||||
<number>15</number>
|
||||
</property>
|
||||
|
|
@ -875,61 +734,178 @@ background-color: rgba(192,192,192, 0.1);
|
|||
<number>15</number>
|
||||
</property>
|
||||
<property name="verticalSpacing">
|
||||
<number>6</number>
|
||||
<number>7</number>
|
||||
</property>
|
||||
<item row="0" column="1">
|
||||
<widget class="QRadioButton" name="m_pRadioSystemScope">
|
||||
<property name="text">
|
||||
<string>All users</string>
|
||||
<spacer name="horizontalSpacer_5">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Orientation::Horizontal</enum>
|
||||
</property>
|
||||
<property name="checked">
|
||||
<bool>true</bool>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QCheckBox" name="m_pCheckBoxLogToFile">
|
||||
<property name="text">
|
||||
<string>Log to file</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QRadioButton" name="m_pRadioUserScope">
|
||||
<item row="0" column="3">
|
||||
<widget class="QComboBox" name="m_pComboLogLevel">
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Info</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Debug</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Debug1</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Debug2</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="2">
|
||||
<widget class="QLabel" name="m_pLabel_3">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Current user</string>
|
||||
<string>Level</string>
|
||||
</property>
|
||||
<property name="buddy">
|
||||
<cstring>m_pComboLogLevel</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0" colspan="4">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_4">
|
||||
<property name="spacing">
|
||||
<number>3</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QLabel" name="m_pLabelLogPath">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Log path</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_7">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Orientation::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeType">
|
||||
<enum>QSizePolicy::Policy::Minimum</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>30</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLineEdit" name="m_pLineEditLogFilename">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="m_pButtonBrowseLog">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="cursor">
|
||||
<cursorShape>PointingHandCursor</cursorShape>
|
||||
</property>
|
||||
<property name="styleSheet">
|
||||
<string notr="true">margin: 0px; padding: 0px;</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../res/Synergy.qrc">
|
||||
<normaloff>:/res/icons/64x64/folder.png</normaloff>:/res/icons/64x64/folder.png</iconset>
|
||||
</property>
|
||||
<property name="iconSize">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>13</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="flat">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="18" column="0">
|
||||
<widget class="QDialogButtonBox" name="m_pButtonBox">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="m_pLabelGroupNetwork">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="standardButtons">
|
||||
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Save</set>
|
||||
<property name="text">
|
||||
<string>Security</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="11" column="0">
|
||||
<spacer name="verticalSpacer_3">
|
||||
<item row="8" column="0">
|
||||
<spacer name="verticalSpacer_5">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
<enum>Qt::Orientation::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeType">
|
||||
<enum>QSizePolicy::Fixed</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>3</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<spacer name="verticalSpacer_2">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeType">
|
||||
<enum>QSizePolicy::Fixed</enum>
|
||||
<enum>QSizePolicy::Policy::Fixed</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
|
|
@ -962,10 +938,6 @@ background-color: rgba(192,192,192, 0.1);
|
|||
<tabstop>m_pCheckBoxPreventSleep</tabstop>
|
||||
<tabstop>m_pCheckBoxServiceEnabled</tabstop>
|
||||
<tabstop>m_pComboElevate</tabstop>
|
||||
<tabstop>m_pCheckBoxScrollDirection</tabstop>
|
||||
<tabstop>m_pCheckBoxLanguageSync</tabstop>
|
||||
<tabstop>m_pCheckBoxServerClientMode</tabstop>
|
||||
<tabstop>m_pCheckBoxClientHostMode</tabstop>
|
||||
</tabstops>
|
||||
<resources>
|
||||
<include location="../res/Synergy.qrc"/>
|
||||
|
|
|
|||
|
|
@ -1,3 +1,20 @@
|
|||
/*
|
||||
* synergy -- mouse and keyboard sharing utility
|
||||
* Copyright (C) 2021 Symless Ltd.
|
||||
*
|
||||
* This package is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* found in the file LICENSE that should have accompanied this file.
|
||||
*
|
||||
* This package is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "TrayIcon.h"
|
||||
|
||||
void TrayIcon::tryCreate() const {
|
||||
|
|
|
|||
|
|
@ -1,4 +1,22 @@
|
|||
/*
|
||||
* synergy -- mouse and keyboard sharing utility
|
||||
* Copyright (C) 2021 Symless Ltd.
|
||||
*
|
||||
* This package is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* found in the file LICENSE that should have accompanied this file.
|
||||
*
|
||||
* This package is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <QMenu>
|
||||
#include <QObject>
|
||||
#include <QSystemTrayIcon>
|
||||
|
|
|
|||
|
|
@ -17,11 +17,11 @@
|
|||
*/
|
||||
|
||||
#include "AppConfig.h"
|
||||
#include "LicenseManager.h"
|
||||
#include "MainWindow.h"
|
||||
#include "QSynergyApplication.h"
|
||||
#include "SetupWizard.h"
|
||||
#include "SetupWizardBlocker.h"
|
||||
#include "gui/dotenv.h"
|
||||
|
||||
#include <QMessageBox>
|
||||
#include <QtCore>
|
||||
|
|
@ -29,9 +29,6 @@
|
|||
|
||||
#if defined(Q_OS_MAC)
|
||||
#include <Carbon/Carbon.h>
|
||||
#endif
|
||||
|
||||
#ifdef Q_OS_DARWIN
|
||||
#include <cstdlib>
|
||||
#endif
|
||||
|
||||
|
|
@ -55,6 +52,8 @@ int main(int argc, char *argv[]) {
|
|||
::setenv("QT_BEARER_POLL_TIMEOUT", "-1", 1);
|
||||
#endif
|
||||
|
||||
dotenv(".env");
|
||||
|
||||
QCoreApplication::setOrganizationName("Synergy");
|
||||
QCoreApplication::setOrganizationDomain("http://symless.com/");
|
||||
QCoreApplication::setApplicationName("Synergy");
|
||||
|
|
@ -79,16 +78,11 @@ int main(int argc, char *argv[]) {
|
|||
AppConfig appConfig;
|
||||
qRegisterMetaType<Edition>("Edition");
|
||||
|
||||
#ifdef SYNERGY_ENABLE_LICENSING
|
||||
LicenseManager licenseManager(&appConfig);
|
||||
MainWindow mainWindow(appConfig, licenseManager);
|
||||
#else
|
||||
MainWindow mainWindow(appConfig);
|
||||
#endif
|
||||
|
||||
QObject::connect(
|
||||
dynamic_cast<QObject *>(&app), SIGNAL(aboutToQuit()), &mainWindow,
|
||||
SLOT(saveSettings()));
|
||||
&app, &QSynergyApplication::aboutToQuit, &mainWindow,
|
||||
&MainWindow::onAppAboutToQuit);
|
||||
|
||||
std::unique_ptr<SetupWizardBlocker> setupBlocker;
|
||||
if (qgetenv("XDG_SESSION_TYPE") == "wayland") {
|
||||
|
|
|
|||
|
|
@ -35,14 +35,10 @@ void ServerStateLabel::updateServerState(const QString &line) {
|
|||
m_clients.removeAll(message.getClientName());
|
||||
}
|
||||
|
||||
updateState();
|
||||
}
|
||||
|
||||
void ServerStateLabel::updateState() {
|
||||
if (m_clients.isEmpty()) {
|
||||
show();
|
||||
setText(tr("No clients connected"));
|
||||
} else {
|
||||
hide();
|
||||
setText(tr("Connected clients: %1").arg(m_clients.join(", ")));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -25,5 +25,6 @@ add_subdirectory(net)
|
|||
add_subdirectory(platform)
|
||||
add_subdirectory(server)
|
||||
add_subdirectory(synergy)
|
||||
add_subdirectory(shared)
|
||||
add_subdirectory(global)
|
||||
add_subdirectory(license)
|
||||
add_subdirectory(gui)
|
||||
|
|
|
|||
|
|
@ -56,7 +56,7 @@
|
|||
Client::Client(
|
||||
IEventQueue *events, const String &name, const NetworkAddress &address,
|
||||
ISocketFactory *socketFactory, synergy::Screen *screen,
|
||||
lib::synergy::ClientArgs const &args)
|
||||
synergy::ClientArgs const &args)
|
||||
: m_mock(false),
|
||||
m_name(name),
|
||||
m_serverAddress(address),
|
||||
|
|
|
|||
|
|
@ -65,7 +65,7 @@ public:
|
|||
Client(
|
||||
IEventQueue *events, const String &name, const NetworkAddress &address,
|
||||
ISocketFactory *socketFactory, synergy::Screen *screen,
|
||||
lib::synergy::ClientArgs const &args);
|
||||
synergy::ClientArgs const &args);
|
||||
Client(Client const &) = delete;
|
||||
Client(Client &&) = delete;
|
||||
~Client();
|
||||
|
|
@ -248,6 +248,6 @@ private:
|
|||
bool m_useSecureNetwork;
|
||||
bool m_enableClipboard;
|
||||
size_t m_maximumClipboardSize;
|
||||
lib::synergy::ClientArgs m_args;
|
||||
synergy::ClientArgs m_args;
|
||||
size_t m_resolvedAddressesCount = 0;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -21,6 +21,6 @@ if(ADD_HEADERS_TO_SOURCES)
|
|||
list(APPEND sources ${headers})
|
||||
endif()
|
||||
|
||||
add_library(shared STATIC ${sources})
|
||||
add_library(global STATIC ${sources})
|
||||
|
||||
target_link_libraries(shared arch base)
|
||||
target_link_libraries(global)
|
||||
|
|
@ -30,7 +30,8 @@ endif()
|
|||
add_library(${target} STATIC ${sources})
|
||||
target_link_libraries(
|
||||
${target}
|
||||
shared
|
||||
global
|
||||
license
|
||||
Qt6::Core
|
||||
Qt6::Widgets
|
||||
Qt6::Network)
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* synergy -- mouse and keyboard sharing utility
|
||||
* Copyright (C) 2014-2016 Symless Ltd.
|
||||
* Copyright (C) 2014 Symless Ltd.
|
||||
*
|
||||
* This package is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
|
|
@ -20,8 +20,8 @@
|
|||
#include <QProcess>
|
||||
|
||||
CommandProcess::CommandProcess(
|
||||
QString cmd, QStringList arguments, QString input)
|
||||
: m_Command(cmd),
|
||||
QString command, QStringList arguments, QString input)
|
||||
: m_Command(command),
|
||||
m_Arguments(arguments),
|
||||
m_Input(input) {}
|
||||
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* synergy -- mouse and keyboard sharing utility
|
||||
* Copyright (C) 2014-2016 Symless Ltd.
|
||||
* Copyright (C) 2014 Symless Ltd.
|
||||
*
|
||||
* This package is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* synergy -- mouse and keyboard sharing utility
|
||||
* Copyright (C) 2015-2016 Symless Ltd.
|
||||
* Copyright (C) 2015 Symless Ltd.
|
||||
*
|
||||
* This package is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
|
|
@ -15,7 +15,7 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "CoreInterface.h"
|
||||
#include "gui/CoreInterface.h"
|
||||
|
||||
#include "CommandProcess.h"
|
||||
|
||||
|
|
@ -32,22 +32,22 @@ static const char kSerialKeyFilename[] = "Synergy.subkey";
|
|||
static const char kSerialKeyFilename[] = ".synergy.subkey";
|
||||
#endif
|
||||
|
||||
QString CoreInterface::getProfileDir() {
|
||||
QString CoreInterface::getProfileDir() const {
|
||||
QStringList args("--get-profile-dir");
|
||||
return QDir::cleanPath(run(args));
|
||||
}
|
||||
|
||||
QString CoreInterface::getInstalledDir() {
|
||||
QString CoreInterface::getInstalledDir() const {
|
||||
QStringList args("--get-installed-dir");
|
||||
return QDir::cleanPath(run(args));
|
||||
}
|
||||
|
||||
QString CoreInterface::getArch() {
|
||||
QString CoreInterface::getArch() const {
|
||||
QStringList args("--get-arch");
|
||||
return run(args);
|
||||
}
|
||||
|
||||
QString CoreInterface::getSerialKeyFilePath() {
|
||||
QString CoreInterface::getSerialKeyFilePath() const {
|
||||
auto filename = getProfileDir() + QDir::separator() + kSerialKeyFilename;
|
||||
return QDir::cleanPath(filename);
|
||||
}
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* synergy -- mouse and keyboard sharing utility
|
||||
* Copyright (C) 2015-2016 Symless Ltd.
|
||||
* Copyright (C) 2015 Symless Ltd.
|
||||
*
|
||||
* This package is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
|
|
@ -21,9 +21,9 @@
|
|||
|
||||
class CoreInterface {
|
||||
public:
|
||||
QString getProfileDir();
|
||||
QString getInstalledDir();
|
||||
QString getArch();
|
||||
QString getSerialKeyFilePath();
|
||||
QString getProfileDir() const;
|
||||
QString getInstalledDir() const;
|
||||
QString getArch() const;
|
||||
QString getSerialKeyFilePath() const;
|
||||
QString run(const QStringList &args, const QString &input = "") const;
|
||||
};
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* synergy -- mouse and keyboard sharing utility
|
||||
* Copyright (C) 2022 Synergy Ltd.
|
||||
* Copyright (C) 2024 Symless Ltd.
|
||||
*
|
||||
* This package is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
|
|
@ -14,30 +14,19 @@
|
|||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <QNetworkAccessManager>
|
||||
#include <QObject>
|
||||
#include <QTimer>
|
||||
#include <QString>
|
||||
|
||||
class QNetworkReply;
|
||||
class AppConfig;
|
||||
|
||||
class LicenseRegistry : public QObject {
|
||||
Q_OBJECT
|
||||
namespace synergy::gui {
|
||||
|
||||
class IAppConfig {
|
||||
public:
|
||||
explicit LicenseRegistry(AppConfig &config);
|
||||
void scheduleRegistration();
|
||||
|
||||
public slots:
|
||||
void registerLicense();
|
||||
void handleResponse(QNetworkReply *reply);
|
||||
|
||||
private:
|
||||
AppConfig &m_config;
|
||||
QNetworkAccessManager m_manager;
|
||||
QTimer m_timer;
|
||||
|
||||
QByteArray getRequestData() const;
|
||||
virtual ~IAppConfig() = default;
|
||||
virtual QString tlsCertPath() const = 0;
|
||||
virtual QString tlsKeyLength() const = 0;
|
||||
virtual bool tlsEnabled() const = 0;
|
||||
};
|
||||
|
||||
} // namespace synergy::gui
|
||||
|
|
@ -1,7 +1,6 @@
|
|||
/*
|
||||
* synergy -- mouse and keyboard sharing utility
|
||||
* Copyright (C) 2012-2016 Symless Ltd.
|
||||
* Copyright (C) 2012 Nick Bolton
|
||||
* Copyright (C) 2012 Symless Ltd.
|
||||
*
|
||||
* This package is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
|
|
@ -17,7 +16,8 @@
|
|||
*/
|
||||
|
||||
#include "IpcReader.h"
|
||||
#include "shared/Ipc.h"
|
||||
#include "global/Ipc.h"
|
||||
|
||||
#include <QByteArray>
|
||||
#include <QMutex>
|
||||
#include <QTcpSocket>
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
/*
|
||||
* synergy -- mouse and keyboard sharing utility
|
||||
* Copyright (C) 2012-2016 Symless Ltd.
|
||||
* Copyright (C) 2012 Nick Bolton
|
||||
* Copyright (C) 2012 Symless Ltd.
|
||||
*
|
||||
* This package is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
|
|
|
|||
94
src/lib/gui/LicenseHandler.cpp
Normal file
94
src/lib/gui/LicenseHandler.cpp
Normal file
|
|
@ -0,0 +1,94 @@
|
|||
/*
|
||||
* synergy -- mouse and keyboard sharing utility
|
||||
* Copyright (C) 2015 Synergy Ltd.
|
||||
*
|
||||
* This package is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* found in the file LICENSE that should have accompanied this file.
|
||||
*
|
||||
* This package is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "LicenseHandler.h"
|
||||
|
||||
#include "license/ProductEdition.h"
|
||||
#include "license/parse_serial_key.h"
|
||||
|
||||
#include <QDebug>
|
||||
#include <QProcessEnvironment>
|
||||
#include <QTimer>
|
||||
|
||||
using namespace std::chrono;
|
||||
using namespace synergy::license;
|
||||
|
||||
const License &LicenseHandler::license() const { return m_license; }
|
||||
|
||||
Edition LicenseHandler::productEdition() const {
|
||||
return m_license.productEdition();
|
||||
}
|
||||
|
||||
QString LicenseHandler::productName() const {
|
||||
return QString::fromStdString(m_license.productName());
|
||||
}
|
||||
|
||||
LicenseHandler::ChangeSerialKeyResult
|
||||
LicenseHandler::changeSerialKey(const QString &hexString) {
|
||||
using enum LicenseHandler::ChangeSerialKeyResult;
|
||||
|
||||
if (hexString.isEmpty()) {
|
||||
qFatal("serial key is empty");
|
||||
return kFatal;
|
||||
}
|
||||
|
||||
qDebug() << "changing serial key to:" << hexString;
|
||||
auto serialKey = parseSerialKey(hexString.toStdString());
|
||||
|
||||
if (serialKey == m_license.serialKey()) {
|
||||
qDebug("serial key did not change, ignoring");
|
||||
return kUnchanged;
|
||||
}
|
||||
|
||||
if (!serialKey.isValid) {
|
||||
qDebug() << "invalid serial key, ignoring";
|
||||
return kInvalid;
|
||||
}
|
||||
|
||||
const auto license = License(serialKey);
|
||||
if (license.isExpired()) {
|
||||
qDebug("license is expired, ignoring");
|
||||
return kExpired;
|
||||
}
|
||||
|
||||
m_license = license;
|
||||
emit serialKeyChanged(hexString);
|
||||
|
||||
if (m_license.isSubscription()) {
|
||||
auto daysLeft = m_license.daysLeft();
|
||||
auto msLeft = duration_cast<milliseconds>(daysLeft);
|
||||
if (msLeft.count() < INT_MAX) {
|
||||
QTimer::singleShot(msLeft, this, SLOT(validateLicense()));
|
||||
} else {
|
||||
qDebug("license expiry too distant to schedule timer");
|
||||
}
|
||||
}
|
||||
|
||||
return kSuccess;
|
||||
}
|
||||
|
||||
void LicenseHandler::validate() const {
|
||||
if (!m_license.isValid()) {
|
||||
qDebug("license validation failed, license invalid");
|
||||
emit invalidLicense();
|
||||
}
|
||||
|
||||
if (m_license.isExpired()) {
|
||||
qDebug("license validation failed, license expired");
|
||||
emit invalidLicense();
|
||||
}
|
||||
}
|
||||
54
src/lib/gui/LicenseHandler.h
Normal file
54
src/lib/gui/LicenseHandler.h
Normal file
|
|
@ -0,0 +1,54 @@
|
|||
/*
|
||||
* synergy -- mouse and keyboard sharing utility
|
||||
* Copyright (C) 2015 Synergy Ltd.
|
||||
*
|
||||
* This package is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* found in the file LICENSE that should have accompanied this file.
|
||||
*
|
||||
* This package is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "license/License.h"
|
||||
#include "license/ProductEdition.h"
|
||||
|
||||
#include <QObject>
|
||||
|
||||
/**
|
||||
* @brief A convenience wrapper for `License` that provides Qt signals, etc.
|
||||
*/
|
||||
class LicenseHandler : public QObject {
|
||||
Q_OBJECT
|
||||
using License = synergy::license::License;
|
||||
using SerialKey = synergy::license::SerialKey;
|
||||
|
||||
public:
|
||||
enum class ChangeSerialKeyResult {
|
||||
kSuccess,
|
||||
kFatal,
|
||||
kUnchanged,
|
||||
kInvalid,
|
||||
kExpired,
|
||||
};
|
||||
|
||||
Edition productEdition() const;
|
||||
const License &license() const;
|
||||
void validate() const;
|
||||
QString productName() const;
|
||||
ChangeSerialKeyResult changeSerialKey(const QString &hexString);
|
||||
|
||||
signals:
|
||||
void serialKeyChanged(const QString &serialKey) const;
|
||||
void invalidLicense() const;
|
||||
|
||||
private:
|
||||
License m_license = License::invalid();
|
||||
};
|
||||
|
|
@ -1,3 +1,20 @@
|
|||
/*
|
||||
* synergy -- mouse and keyboard sharing utility
|
||||
* Copyright (C) 2024 Synergy Ltd.
|
||||
*
|
||||
* This package is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* found in the file LICENSE that should have accompanied this file.
|
||||
*
|
||||
* This package is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <QTcpSocket>
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@
|
|||
#include "QIpcClient.h"
|
||||
|
||||
#include "IpcReader.h"
|
||||
#include "shared/Ipc.h"
|
||||
#include "global/Ipc.h"
|
||||
|
||||
#include <QDataStream>
|
||||
#include <QHostAddress>
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* synergy -- mouse and keyboard sharing utility
|
||||
* Copyright (C) 2015-2016 Symless Ltd.
|
||||
* Copyright (C) 2015 Symless Ltd.
|
||||
*
|
||||
* This package is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
|
|
@ -15,9 +15,9 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "SslCertificate.h"
|
||||
#include "TlsCertificate.h"
|
||||
|
||||
#include "Fingerprint.h"
|
||||
#include "TlsFingerprint.h"
|
||||
|
||||
#include <QCoreApplication>
|
||||
#include <QDir>
|
||||
|
|
@ -89,14 +89,14 @@ QString openSslWindowsBinary() {
|
|||
|
||||
using namespace synergy::gui;
|
||||
|
||||
SslCertificate::SslCertificate(QObject *parent) : QObject(parent) {
|
||||
TlsCertificate::TlsCertificate(QObject *parent) : QObject(parent) {
|
||||
m_ProfileDir = m_CoreInterface.getProfileDir();
|
||||
if (m_ProfileDir.isEmpty()) {
|
||||
emit error(tr("Failed to get profile directory."));
|
||||
}
|
||||
}
|
||||
|
||||
bool SslCertificate::runTool(const QStringList &args) {
|
||||
bool TlsCertificate::runTool(const QStringList &args) {
|
||||
QString program;
|
||||
#if defined(Q_OS_WIN)
|
||||
program = openSslWindowsBinary();
|
||||
|
|
@ -134,7 +134,7 @@ bool SslCertificate::runTool(const QStringList &args) {
|
|||
return true;
|
||||
}
|
||||
|
||||
void SslCertificate::generateCertificate(
|
||||
void TlsCertificate::generateCertificate(
|
||||
const QString &path, const QString &keyLength, bool forceGen) {
|
||||
QString sslDirPath =
|
||||
QString("%1%2%3").arg(m_ProfileDir).arg(QDir::separator()).arg(kSslDir);
|
||||
|
|
@ -193,7 +193,7 @@ void SslCertificate::generateCertificate(
|
|||
emit generateFinished();
|
||||
}
|
||||
|
||||
void SslCertificate::generateFingerprint(const QString &certificateFilename) {
|
||||
void TlsCertificate::generateFingerprint(const QString &certificateFilename) {
|
||||
QStringList arguments;
|
||||
arguments.append("x509");
|
||||
arguments.append("-fingerprint");
|
||||
|
|
@ -212,14 +212,14 @@ void SslCertificate::generateFingerprint(const QString &certificateFilename) {
|
|||
i++;
|
||||
QString fingerprint = m_ToolOutput.mid(i, m_ToolOutput.size() - i);
|
||||
|
||||
Fingerprint::local().trust(fingerprint, false);
|
||||
TlsFingerprint::local().trust(fingerprint, false);
|
||||
emit info(tr("SSL fingerprint generated."));
|
||||
} else {
|
||||
emit error(tr("Failed to find SSL fingerprint."));
|
||||
}
|
||||
}
|
||||
|
||||
QString SslCertificate::getCertKeyLength(const QString &path) {
|
||||
QString TlsCertificate::getCertKeyLength(const QString &path) {
|
||||
|
||||
QStringList arguments;
|
||||
arguments.append("rsa");
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* synergy -- mouse and keyboard sharing utility
|
||||
* Copyright (C) 2015-2016 Symless Ltd.
|
||||
* Copyright (C) 2015 Symless Ltd.
|
||||
*
|
||||
* This package is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
|
|
@ -17,16 +17,15 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include "CoreInterface.h"
|
||||
#include "gui/CoreInterface.h"
|
||||
|
||||
#include <QObject>
|
||||
#include <base/String.h>
|
||||
|
||||
class SslCertificate : public QObject {
|
||||
class TlsCertificate : public QObject {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit SslCertificate(QObject *parent = 0);
|
||||
explicit TlsCertificate(QObject *parent = nullptr);
|
||||
|
||||
public slots:
|
||||
/// @brief Generates a TLS cert and private key
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* synergy -- mouse and keyboard sharing utility
|
||||
* Copyright (C) 2015-2016 Symless Ltd.
|
||||
* Copyright (C) 2015 Symless Ltd.
|
||||
*
|
||||
* This package is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
|
|
@ -15,9 +15,9 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "Fingerprint.h"
|
||||
#include "TlsFingerprint.h"
|
||||
|
||||
#include "CoreInterface.h"
|
||||
#include "gui/CoreInterface.h"
|
||||
|
||||
#include <QDir>
|
||||
#include <QTextStream>
|
||||
|
|
@ -27,10 +27,12 @@ static const char kLocalFilename[] = "Local.txt";
|
|||
static const char kTrustedServersFilename[] = "TrustedServers.txt";
|
||||
static const char kTrustedClientsFilename[] = "TrustedClients.txt";
|
||||
|
||||
Fingerprint::Fingerprint(const QString &filename) { m_Filename = filename; }
|
||||
TlsFingerprint::TlsFingerprint(const QString &filename) {
|
||||
m_Filename = filename;
|
||||
}
|
||||
|
||||
void Fingerprint::trust(const QString &fingerprintText, bool append) {
|
||||
Fingerprint::persistDirectory();
|
||||
void TlsFingerprint::trust(const QString &fingerprintText, bool append) {
|
||||
TlsFingerprint::persistDirectory();
|
||||
|
||||
QIODevice::OpenMode openMode;
|
||||
if (append) {
|
||||
|
|
@ -47,8 +49,8 @@ void Fingerprint::trust(const QString &fingerprintText, bool append) {
|
|||
}
|
||||
}
|
||||
|
||||
bool Fingerprint::fileExists() const {
|
||||
QString dirName = Fingerprint::directoryPath();
|
||||
bool TlsFingerprint::fileExists() const {
|
||||
QString dirName = TlsFingerprint::directoryPath();
|
||||
if (!QDir(dirName).exists()) {
|
||||
return false;
|
||||
}
|
||||
|
|
@ -57,7 +59,7 @@ bool Fingerprint::fileExists() const {
|
|||
return file.exists();
|
||||
}
|
||||
|
||||
bool Fingerprint::isTrusted(const QString &fingerprintText) {
|
||||
bool TlsFingerprint::isTrusted(const QString &fingerprintText) {
|
||||
QStringList list = readList();
|
||||
foreach (QString trusted, list) {
|
||||
if (trusted == fingerprintText) {
|
||||
|
|
@ -67,10 +69,10 @@ bool Fingerprint::isTrusted(const QString &fingerprintText) {
|
|||
return false;
|
||||
}
|
||||
|
||||
QStringList Fingerprint::readList(const int readTo) {
|
||||
QStringList TlsFingerprint::readList(const int readTo) {
|
||||
QStringList list;
|
||||
|
||||
QString dirName = Fingerprint::directoryPath();
|
||||
QString dirName = TlsFingerprint::directoryPath();
|
||||
if (!QDir(dirName).exists()) {
|
||||
return list;
|
||||
}
|
||||
|
|
@ -91,36 +93,38 @@ QStringList Fingerprint::readList(const int readTo) {
|
|||
return list;
|
||||
}
|
||||
|
||||
QString Fingerprint::readFirst() {
|
||||
QString TlsFingerprint::readFirst() {
|
||||
QStringList list = readList(1);
|
||||
return list.at(0);
|
||||
}
|
||||
|
||||
QString Fingerprint::filePath() const {
|
||||
QString dir = Fingerprint::directoryPath();
|
||||
QString TlsFingerprint::filePath() const {
|
||||
QString dir = TlsFingerprint::directoryPath();
|
||||
return QString("%1/%2").arg(dir).arg(m_Filename);
|
||||
}
|
||||
|
||||
void Fingerprint::persistDirectory() {
|
||||
QDir dir(Fingerprint::directoryPath());
|
||||
void TlsFingerprint::persistDirectory() {
|
||||
QDir dir(TlsFingerprint::directoryPath());
|
||||
if (!dir.exists()) {
|
||||
dir.mkpath(".");
|
||||
}
|
||||
}
|
||||
|
||||
QString Fingerprint::directoryPath() {
|
||||
QString TlsFingerprint::directoryPath() {
|
||||
CoreInterface coreInterface;
|
||||
QString profileDir = coreInterface.getProfileDir();
|
||||
|
||||
return QString("%1/%2").arg(profileDir).arg(kDirName);
|
||||
}
|
||||
|
||||
Fingerprint Fingerprint::local() { return Fingerprint(kLocalFilename); }
|
||||
|
||||
Fingerprint Fingerprint::trustedServers() {
|
||||
return Fingerprint(kTrustedServersFilename);
|
||||
TlsFingerprint TlsFingerprint::local() {
|
||||
return TlsFingerprint(kLocalFilename);
|
||||
}
|
||||
|
||||
Fingerprint Fingerprint::trustedClients() {
|
||||
return Fingerprint(kTrustedClientsFilename);
|
||||
TlsFingerprint TlsFingerprint::trustedServers() {
|
||||
return TlsFingerprint(kTrustedServersFilename);
|
||||
}
|
||||
|
||||
TlsFingerprint TlsFingerprint::trustedClients() {
|
||||
return TlsFingerprint(kTrustedClientsFilename);
|
||||
}
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* synergy -- mouse and keyboard sharing utility
|
||||
* Copyright (C) 2015-2016 Symless Ltd.
|
||||
* Copyright (C) 2015 Symless Ltd.
|
||||
*
|
||||
* This package is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
|
|
@ -19,9 +19,9 @@
|
|||
|
||||
#include <QString>
|
||||
|
||||
class Fingerprint {
|
||||
class TlsFingerprint {
|
||||
private:
|
||||
Fingerprint(const QString &filename);
|
||||
TlsFingerprint(const QString &filename);
|
||||
|
||||
public:
|
||||
void trust(const QString &fingerprintText, bool append = true);
|
||||
|
|
@ -32,9 +32,9 @@ public:
|
|||
bool fileExists() const;
|
||||
|
||||
public:
|
||||
static Fingerprint local();
|
||||
static Fingerprint trustedServers();
|
||||
static Fingerprint trustedClients();
|
||||
static TlsFingerprint local();
|
||||
static TlsFingerprint trustedServers();
|
||||
static TlsFingerprint trustedClients();
|
||||
static QString directoryPath();
|
||||
static QString localFingerprint();
|
||||
static bool localFingerprintExists();
|
||||
47
src/lib/gui/TlsUtility.cpp
Normal file
47
src/lib/gui/TlsUtility.cpp
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
/*
|
||||
* synergy -- mouse and keyboard sharing utility
|
||||
* Copyright (C) 2024 Symless Ltd.
|
||||
*
|
||||
* This package is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* found in the file LICENSE that should have accompanied this file.
|
||||
*
|
||||
* This package is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "TlsUtility.h"
|
||||
|
||||
#include "TlsCertificate.h"
|
||||
#include "constants.h"
|
||||
|
||||
namespace synergy::gui {
|
||||
|
||||
bool TlsUtility::isAvailable() const {
|
||||
return !kLicensingEnabled || m_license.isTlsAvailable();
|
||||
}
|
||||
|
||||
bool TlsUtility::isAvailableAndEnabled() const {
|
||||
const auto &config = m_appConfig;
|
||||
return isAvailable() && config.tlsEnabled();
|
||||
}
|
||||
|
||||
void TlsUtility::generateCertificate(bool replace) const {
|
||||
if (!isAvailableAndEnabled()) {
|
||||
qFatal("unable to generate tls certificate, "
|
||||
"tls is either not available or not enabled");
|
||||
}
|
||||
|
||||
auto path = m_appConfig.tlsCertPath();
|
||||
auto length = m_appConfig.tlsKeyLength();
|
||||
|
||||
TlsCertificate cert;
|
||||
cert.generateCertificate(path, length, replace);
|
||||
}
|
||||
|
||||
} // namespace synergy::gui
|
||||
58
src/lib/gui/TlsUtility.h
Normal file
58
src/lib/gui/TlsUtility.h
Normal file
|
|
@ -0,0 +1,58 @@
|
|||
/*
|
||||
* synergy -- mouse and keyboard sharing utility
|
||||
* Copyright (C) 2024 Symless Ltd.
|
||||
*
|
||||
* This package is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* found in the file LICENSE that should have accompanied this file.
|
||||
*
|
||||
* This package is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "IAppConfig.h"
|
||||
|
||||
#include "license/License.h"
|
||||
#include <stdexcept>
|
||||
|
||||
namespace synergy::gui {
|
||||
|
||||
class TlsUtility {
|
||||
public:
|
||||
explicit TlsUtility(
|
||||
const IAppConfig &appConfig, const license::License &license)
|
||||
: m_appConfig(appConfig),
|
||||
m_license(license) {}
|
||||
|
||||
/**
|
||||
* @brief Combines the availability and the enabled status of TLS.
|
||||
*
|
||||
* @return Given that the app setting for TLS is enabled:
|
||||
* If licensing is enabled, it checks whether the product has TLS
|
||||
* available, and if licensing is not enabled, true is returned.
|
||||
*/
|
||||
bool isAvailableAndEnabled() const;
|
||||
|
||||
/**
|
||||
* @return true if TLS is available, regardless of whether it is enabled.
|
||||
*/
|
||||
bool isAvailable() const;
|
||||
|
||||
/**
|
||||
* @param replace Replace certificate on disk (default: false).
|
||||
*/
|
||||
void generateCertificate(bool replace = false) const;
|
||||
|
||||
private:
|
||||
const IAppConfig &m_appConfig;
|
||||
const license::License &m_license;
|
||||
};
|
||||
|
||||
} // namespace synergy::gui
|
||||
|
|
@ -1,7 +1,6 @@
|
|||
/*
|
||||
* synergy -- mouse and keyboard sharing utility
|
||||
* Copyright (C) 2012-2016 Symless Ltd.
|
||||
* Copyright (C) 2012 Nick Bolton
|
||||
* Copyright (C) 2012 Symless Ltd.
|
||||
*
|
||||
* This package is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
|
|
@ -26,23 +25,28 @@
|
|||
#include <QRegularExpression>
|
||||
#include <memory>
|
||||
|
||||
VersionChecker::VersionChecker(std::shared_ptr<QNetworkAccessManager> nam)
|
||||
: m_manager(nam ? nam : std::make_shared<QNetworkAccessManager>(this)) {
|
||||
const char *const kVersion = SYNERGY_VERSION;
|
||||
|
||||
VersionChecker::VersionChecker(std::shared_ptr<QNetworkAccessManager> network)
|
||||
: m_network(
|
||||
network ? network : std::make_shared<QNetworkAccessManager>(this)) {
|
||||
connect(
|
||||
m_manager.get(), SIGNAL(finished(QNetworkReply *)), this,
|
||||
m_network.get(), SIGNAL(finished(QNetworkReply *)), this,
|
||||
SLOT(replyFinished(QNetworkReply *)));
|
||||
}
|
||||
|
||||
void VersionChecker::checkLatest() {
|
||||
auto request = QNetworkRequest(QUrl(SYNERGY_VERSION_URL));
|
||||
request.setHeader(
|
||||
QNetworkRequest::UserAgentHeader, QString("Synergy (") + SYNERGY_VERSION +
|
||||
") " +
|
||||
QSysInfo::prettyProductName());
|
||||
request.setRawHeader("X-Synergy-Version", SYNERGY_VERSION);
|
||||
void VersionChecker::checkLatest() const {
|
||||
const QString url =
|
||||
qEnvironmentVariable("SYNERGY_VERSION_URL", SYNERGY_VERSION_URL);
|
||||
auto request = QNetworkRequest(url);
|
||||
auto userAgent = QString("Synergy %1 on %2")
|
||||
.arg(kVersion)
|
||||
.arg(QSysInfo::prettyProductName());
|
||||
request.setHeader(QNetworkRequest::UserAgentHeader, userAgent);
|
||||
request.setRawHeader("X-Synergy-Version", kVersion);
|
||||
request.setRawHeader(
|
||||
"X-Synergy-Language", QLocale::system().name().toStdString().c_str());
|
||||
m_manager->get(request);
|
||||
m_network->get(request);
|
||||
}
|
||||
|
||||
void VersionChecker::replyFinished(QNetworkReply *reply) {
|
||||
|
|
@ -53,7 +57,7 @@ void VersionChecker::replyFinished(QNetworkReply *reply) {
|
|||
}
|
||||
}
|
||||
|
||||
int VersionChecker::getStageVersion(QString stage) const {
|
||||
int VersionChecker::getStageVersion(QString stage) {
|
||||
const char *stableName = "stable";
|
||||
const char *rcName = "rc";
|
||||
const char *betaName = "beta";
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
/*
|
||||
* synergy -- mouse and keyboard sharing utility
|
||||
* Copyright (C) 2012-2019 Symless Ltd.
|
||||
* Copyright (C) 2012 Nick Bolton
|
||||
* Copyright (C) 2012 Symless Ltd.
|
||||
*
|
||||
* This package is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
|
|
@ -24,23 +23,24 @@
|
|||
|
||||
class QNetworkAccessManager;
|
||||
class QNetworkReply;
|
||||
class VersionCheckerTests;
|
||||
|
||||
class VersionChecker : public QObject {
|
||||
Q_OBJECT
|
||||
|
||||
friend class VersionCheckerTests;
|
||||
|
||||
public:
|
||||
VersionChecker(std::shared_ptr<QNetworkAccessManager> manager = nullptr);
|
||||
virtual ~VersionChecker() {}
|
||||
void checkLatest();
|
||||
void setApp(const QString &app) { m_app = app; }
|
||||
int compareVersions(const QString &left, const QString &right);
|
||||
explicit VersionChecker(
|
||||
std::shared_ptr<QNetworkAccessManager> network = nullptr);
|
||||
void checkLatest() const;
|
||||
public slots:
|
||||
void replyFinished(QNetworkReply *reply);
|
||||
signals:
|
||||
void updateFound(const QString &version);
|
||||
|
||||
private:
|
||||
std::shared_ptr<QNetworkAccessManager> m_manager;
|
||||
QString m_app;
|
||||
static int compareVersions(const QString &left, const QString &right);
|
||||
|
||||
/**
|
||||
* \brief Converts a string stage to a integer value
|
||||
|
|
@ -48,5 +48,7 @@ private:
|
|||
* \return An integer representation of the stage, the higher the number the
|
||||
* more recent the version
|
||||
*/
|
||||
int getStageVersion(QString stage) const;
|
||||
static int getStageVersion(QString stage);
|
||||
|
||||
std::shared_ptr<QNetworkAccessManager> m_network;
|
||||
};
|
||||
|
|
|
|||
50
src/lib/gui/constants.h
Normal file
50
src/lib/gui/constants.h
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
/*
|
||||
* synergy -- mouse and keyboard sharing utility
|
||||
* Copyright (C) 2014 Symless Ltd.
|
||||
*
|
||||
* This package is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* found in the file LICENSE that should have accompanied this file.
|
||||
*
|
||||
* This package is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <QString>
|
||||
|
||||
#ifdef SYNERGY_ENABLE_LICENSING
|
||||
const bool kLicensingEnabled = true;
|
||||
#else
|
||||
const bool kLicensingEnabled = false;
|
||||
#endif // SYNERGY_ENABLE_LICENSING
|
||||
|
||||
const auto kColorWhite = "#ffffff";
|
||||
const auto kColorPrimary = "#ff7c00";
|
||||
const auto kColorSecondary = "#4285f4";
|
||||
|
||||
const auto kLinkStyleWhite = QString("color: %1").arg(kColorWhite);
|
||||
const auto kLinkStylePrimary = QString("color: %1").arg(kColorPrimary);
|
||||
const auto kLinkStyleSecondary = QString("color: %1").arg(kColorSecondary);
|
||||
|
||||
const auto kLinkBuy = R"(<a href="%1" style="%2">Buy now</a>)";
|
||||
const auto kLinkRenew = R"(<a href="%1" style="%2">Renew now</a>)";
|
||||
const auto kLinkDownload = R"(<a href="%1" style="%2">Download now</a>)";
|
||||
|
||||
const auto kUrlSourceQuery = "source=gui";
|
||||
const auto kUrlWebsite = "https://symless.com";
|
||||
const auto kUrlProduct = QString("%1/synergy").arg(kUrlWebsite);
|
||||
const auto kUrlPurchase =
|
||||
QString("%1/purchase?%2").arg(kUrlProduct).arg(kUrlSourceQuery);
|
||||
const auto kUrlContact =
|
||||
QString("%1/contact?%2").arg(kUrlProduct).arg(kUrlSourceQuery);
|
||||
const auto kUrlHelp =
|
||||
QString("%1/help?%2").arg(kUrlProduct).arg(kUrlSourceQuery);
|
||||
const auto kUrlDownload =
|
||||
QString("%1/download?%2").arg(kUrlProduct).arg(kUrlSourceQuery);
|
||||
91
src/lib/gui/dotenv.cpp
Normal file
91
src/lib/gui/dotenv.cpp
Normal file
|
|
@ -0,0 +1,91 @@
|
|||
/*
|
||||
* synergy -- mouse and keyboard sharing utility
|
||||
* Copyright (C) 2024 Symless Ltd.
|
||||
*
|
||||
* This package is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* found in the file LICENSE that should have accompanied this file.
|
||||
*
|
||||
* This package is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "dotenv.h"
|
||||
|
||||
#include <QDebug>
|
||||
#include <QFile>
|
||||
#include <QProcess>
|
||||
#include <QProcessEnvironment>
|
||||
#include <QString>
|
||||
#include <QTextStream>
|
||||
|
||||
namespace synergy::gui {
|
||||
|
||||
QPair<QString, QString> getPair(const QString &line);
|
||||
|
||||
/**
|
||||
* @brief A _very_ basic Qt .env file parser.
|
||||
*
|
||||
* This function re-invents the wheel to save adding a library dependency.
|
||||
* It does not support many things that a proper .env parser would, such as
|
||||
* trailing comments, escaping characters, multiline values, etc.
|
||||
*
|
||||
* If this function is not sufficient, replace it with a library such as:
|
||||
* https://github.com/adeharo9/cpp-dotenv
|
||||
*/
|
||||
void dotenv(const QString &filePath) {
|
||||
QFile file(filePath);
|
||||
if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
|
||||
qDebug("no .env file in current dir");
|
||||
return;
|
||||
}
|
||||
|
||||
qDebug("loading env vars from: %s", filePath.toUtf8().constData());
|
||||
|
||||
QTextStream in(&file);
|
||||
while (!in.atEnd()) {
|
||||
QString line = in.readLine().trimmed();
|
||||
if (line.startsWith('#'))
|
||||
continue;
|
||||
|
||||
auto [key, value] = getPair(line);
|
||||
if (key.isEmpty() || value.isEmpty())
|
||||
continue;
|
||||
|
||||
const auto keyBytes = key.toUtf8();
|
||||
const auto valueBytes = value.toUtf8();
|
||||
|
||||
const auto &key_c = keyBytes.constData();
|
||||
const auto &value_c = valueBytes.constData();
|
||||
|
||||
qDebug("%s=%s", key_c, value_c);
|
||||
qputenv(keyBytes, valueBytes);
|
||||
}
|
||||
}
|
||||
|
||||
QString stripQuotes(const QString &value) {
|
||||
QString result = value;
|
||||
if (result.startsWith('"') && result.endsWith('"')) {
|
||||
result = result.mid(1, result.length() - 2);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
QPair<QString, QString> getPair(const QString &line) {
|
||||
auto pos = line.indexOf('=');
|
||||
if (pos == -1) {
|
||||
return QPair<QString, QString>("", "");
|
||||
}
|
||||
|
||||
QString key = line.left(pos);
|
||||
QString value = line.mid(pos + 1);
|
||||
|
||||
return QPair<QString, QString>(key.trimmed(), stripQuotes(value.trimmed()));
|
||||
}
|
||||
|
||||
} // namespace synergy::gui
|
||||
30
src/lib/gui/dotenv.h
Normal file
30
src/lib/gui/dotenv.h
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
/*
|
||||
* synergy -- mouse and keyboard sharing utility
|
||||
* Copyright (C) 2024 Symless Ltd.
|
||||
*
|
||||
* This package is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* found in the file LICENSE that should have accompanied this file.
|
||||
*
|
||||
* This package is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <QString>
|
||||
|
||||
namespace synergy::gui {
|
||||
|
||||
/**
|
||||
* @param filePath Path to the .env file.
|
||||
* @param envVars Somewhere to save strings for the lifetime of the app.
|
||||
*/
|
||||
void dotenv(const QString &filePath);
|
||||
|
||||
} // namespace synergy::gui
|
||||
76
src/lib/gui/license_notices.cpp
Normal file
76
src/lib/gui/license_notices.cpp
Normal file
|
|
@ -0,0 +1,76 @@
|
|||
/*
|
||||
* synergy -- mouse and keyboard sharing utility
|
||||
* Copyright (C) 2024 Synergy Ltd.
|
||||
*
|
||||
* This package is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* found in the file LICENSE that should have accompanied this file.
|
||||
*
|
||||
* This package is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "license_notices.h"
|
||||
|
||||
#include "constants.h"
|
||||
#include "license/License.h"
|
||||
|
||||
using License = synergy::license::License;
|
||||
|
||||
namespace synergy::gui {
|
||||
|
||||
QString trialLicenseNotice(const License &license);
|
||||
QString subscriptionLicenseNotice(const License &license);
|
||||
|
||||
QString licenseNotice(const License &license) {
|
||||
if (license.isTrial()) {
|
||||
return trialLicenseNotice(license);
|
||||
} else if (license.isSubscription()) {
|
||||
return subscriptionLicenseNotice(license);
|
||||
} else {
|
||||
qFatal("license notice only for time limited licenses");
|
||||
}
|
||||
}
|
||||
|
||||
QString trialLicenseNotice(const License &license) {
|
||||
const QString buyLink =
|
||||
QString(kLinkBuy).arg(kUrlPurchase).arg(kLinkStyleWhite);
|
||||
if (license.isExpired()) {
|
||||
return QString("<p>Your trial has expired. %1</p>").arg(buyLink);
|
||||
} else {
|
||||
auto daysLeft = license.daysLeft().count();
|
||||
if (daysLeft <= 0) {
|
||||
return QString("<p>Your trial expires today. %1</p>").arg(buyLink);
|
||||
} else {
|
||||
return QString("<p>Your trial expires in %1 %2. %3</p>")
|
||||
.arg(daysLeft)
|
||||
.arg((daysLeft == 1) ? "day" : "days")
|
||||
.arg(buyLink);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
QString subscriptionLicenseNotice(const License &license) {
|
||||
const QString renewLink =
|
||||
QString(kLinkRenew).arg(kUrlPurchase).arg(kLinkStyleWhite);
|
||||
if (license.isExpired()) {
|
||||
return QString("<p>Your license has expired. %1</p>").arg(renewLink);
|
||||
} else {
|
||||
auto daysLeft = license.daysLeft().count();
|
||||
if (daysLeft <= 0) {
|
||||
return QString("<p>Your license expires today. %1</p>").arg(renewLink);
|
||||
} else {
|
||||
return QString("<p>Your license expires in %1 %2. %3</p>")
|
||||
.arg(daysLeft)
|
||||
.arg((daysLeft == 1) ? "day" : "days")
|
||||
.arg(renewLink);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace synergy::gui
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* synergy -- mouse and keyboard sharing utility
|
||||
* Copyright (C) 2015 Synergy Ltd.
|
||||
* Copyright (C) 2024 Synergy Ltd.
|
||||
*
|
||||
* This package is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
|
|
@ -15,33 +15,14 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef ACTIVATIONNOTIFIER_H
|
||||
#define ACTIVATIONNOTIFIER_H
|
||||
#pragma once
|
||||
|
||||
#include <QObject>
|
||||
#include "license/License.h"
|
||||
|
||||
class ActivationNotifier : public QObject {
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit ActivationNotifier(QObject *parent = 0);
|
||||
#include <QString>
|
||||
|
||||
void setIdentity(QString identity);
|
||||
void setUpdateInfo(
|
||||
QString const &fromVersion, QString const &toVersion,
|
||||
QString const &serialKey);
|
||||
namespace synergy::gui {
|
||||
|
||||
public slots:
|
||||
void notify();
|
||||
void notifyUpdate();
|
||||
QString licenseNotice(const synergy::license::License &license);
|
||||
|
||||
signals:
|
||||
void finished();
|
||||
|
||||
private:
|
||||
QString m_Identity;
|
||||
QString m_fromVersion;
|
||||
QString m_toVersion;
|
||||
QString m_serialKey;
|
||||
};
|
||||
|
||||
#endif // ACTIVATIONNOTIFIER_H
|
||||
} // namespace synergy::gui
|
||||
|
|
@ -17,9 +17,9 @@
|
|||
|
||||
#include "ipc/IpcClient.h"
|
||||
#include "base/TMethodEventJob.h"
|
||||
#include "global/Ipc.h"
|
||||
#include "ipc/IpcMessage.h"
|
||||
#include "ipc/IpcServerProxy.h"
|
||||
#include "shared/Ipc.h"
|
||||
|
||||
//
|
||||
// IpcClient
|
||||
|
|
|
|||
|
|
@ -19,10 +19,10 @@
|
|||
|
||||
#include "base/Log.h"
|
||||
#include "base/TMethodEventJob.h"
|
||||
#include "global/Ipc.h"
|
||||
#include "io/IStream.h"
|
||||
#include "ipc/IpcMessage.h"
|
||||
#include "ipc/IpcSettingMessage.h"
|
||||
#include "shared/Ipc.h"
|
||||
#include "synergy/ProtocolUtil.h"
|
||||
|
||||
//
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@
|
|||
#include "arch/IArchMultithread.h"
|
||||
#include "base/Event.h"
|
||||
#include "base/EventTypes.h"
|
||||
#include "shared/Ipc.h"
|
||||
#include "global/Ipc.h"
|
||||
|
||||
namespace synergy {
|
||||
class IStream;
|
||||
|
|
|
|||
|
|
@ -24,11 +24,11 @@
|
|||
#include "base/EventQueue.h"
|
||||
#include "base/TMethodEventJob.h"
|
||||
#include "base/TMethodJob.h"
|
||||
#include "global/Ipc.h"
|
||||
#include "ipc/IpcClientProxy.h"
|
||||
#include "ipc/IpcMessage.h"
|
||||
#include "ipc/IpcServer.h"
|
||||
#include "mt/Thread.h"
|
||||
#include "shared/Ipc.h"
|
||||
|
||||
enum EIpcLogOutputter {
|
||||
kBufferMaxSize = 1000,
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@
|
|||
#include "arch/Arch.h"
|
||||
#include "arch/IArchMultithread.h"
|
||||
#include "base/ILogOutputter.h"
|
||||
#include "shared/Ipc.h"
|
||||
#include "global/Ipc.h"
|
||||
|
||||
#include <deque>
|
||||
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@
|
|||
*/
|
||||
|
||||
#include "ipc/IpcMessage.h"
|
||||
#include "shared/Ipc.h"
|
||||
#include "global/Ipc.h"
|
||||
|
||||
IpcMessage::IpcMessage(IpcMessageType type) : m_type(type) {}
|
||||
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@
|
|||
|
||||
#include "base/Event.h"
|
||||
#include "base/String.h"
|
||||
#include "shared/Ipc.h"
|
||||
#include "global/Ipc.h"
|
||||
|
||||
class IpcMessage : public EventData {
|
||||
public:
|
||||
|
|
|
|||
|
|
@ -22,11 +22,11 @@
|
|||
#include "base/IEventQueue.h"
|
||||
#include "base/Log.h"
|
||||
#include "base/TMethodEventJob.h"
|
||||
#include "global/Ipc.h"
|
||||
#include "io/IStream.h"
|
||||
#include "ipc/IpcClientProxy.h"
|
||||
#include "ipc/IpcMessage.h"
|
||||
#include "net/IDataSocket.h"
|
||||
#include "shared/Ipc.h"
|
||||
|
||||
//
|
||||
// IpcServer
|
||||
|
|
|
|||
|
|
@ -20,9 +20,9 @@
|
|||
|
||||
#include "arch/Arch.h"
|
||||
#include "base/EventTypes.h"
|
||||
#include "global/Ipc.h"
|
||||
#include "net/NetworkAddress.h"
|
||||
#include "net/TCPListenSocket.h"
|
||||
#include "shared/Ipc.h"
|
||||
|
||||
#include <list>
|
||||
|
||||
|
|
|
|||
|
|
@ -20,9 +20,9 @@
|
|||
|
||||
#include "base/Log.h"
|
||||
#include "base/TMethodEventJob.h"
|
||||
#include "global/Ipc.h"
|
||||
#include "io/IStream.h"
|
||||
#include "ipc/IpcMessage.h"
|
||||
#include "shared/Ipc.h"
|
||||
#include "synergy/ProtocolUtil.h"
|
||||
|
||||
//
|
||||
|
|
|
|||
26
src/lib/license/CMakeLists.txt
Normal file
26
src/lib/license/CMakeLists.txt
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
# Synergy -- mouse and keyboard sharing utility
|
||||
# Copyright (C) 2012-2024 Symless Ltd.
|
||||
# Copyright (C) 2009-2012 Nick Bolton
|
||||
#
|
||||
# This package is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# found in the file LICENSE that should have accompanied this file.
|
||||
#
|
||||
# This package is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
file(GLOB headers "*.h")
|
||||
file(GLOB sources "*.cpp")
|
||||
|
||||
if(ADD_HEADERS_TO_SOURCES)
|
||||
list(APPEND sources ${headers})
|
||||
endif()
|
||||
|
||||
add_library(license STATIC ${sources})
|
||||
|
||||
target_link_libraries(license arch base)
|
||||
99
src/lib/license/License.cpp
Normal file
99
src/lib/license/License.cpp
Normal file
|
|
@ -0,0 +1,99 @@
|
|||
/*
|
||||
* synergy -- mouse and keyboard sharing utility
|
||||
* Copyright (C) 2016 Symless Ltd.
|
||||
*
|
||||
* This package is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* found in the file LICENSE that should have accompanied this file.
|
||||
*
|
||||
* This package is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "License.h"
|
||||
|
||||
#include "Product.h"
|
||||
#include "license/SerialKey.h"
|
||||
#include "license/parse_serial_key.h"
|
||||
|
||||
#include <chrono>
|
||||
#include <climits>
|
||||
|
||||
using namespace std::chrono;
|
||||
|
||||
namespace synergy::license {
|
||||
|
||||
License::License(const std::string &hexString)
|
||||
: m_serialKey(parseSerialKey(hexString)) {}
|
||||
|
||||
License::License(const SerialKey &serialKey) : m_serialKey(serialKey) {
|
||||
if (!m_serialKey.isValid) {
|
||||
throw InvalidSerialKey();
|
||||
}
|
||||
}
|
||||
|
||||
bool License::isTrial() const { return m_serialKey.type.isTrial(); }
|
||||
|
||||
bool License::isSubscription() const {
|
||||
return m_serialKey.type.isSubscription();
|
||||
}
|
||||
|
||||
bool License::isTimeLimited() const { return m_serialKey.type.isTimeLimited(); }
|
||||
|
||||
bool License::isTlsAvailable() const {
|
||||
return m_serialKey.product.isTlsAvailable();
|
||||
}
|
||||
|
||||
Edition License::productEdition() const {
|
||||
return m_serialKey.product.edition();
|
||||
}
|
||||
|
||||
bool License::isExpiring() const {
|
||||
if (!isTimeLimited()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!m_serialKey.warnTime.has_value()) {
|
||||
throw NoTimeLimitError();
|
||||
}
|
||||
|
||||
return m_nowFunc() >= m_serialKey.warnTime.value();
|
||||
}
|
||||
|
||||
bool License::isExpired() const {
|
||||
if (!isTimeLimited()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!m_serialKey.expireTime.has_value()) {
|
||||
throw NoTimeLimitError();
|
||||
}
|
||||
|
||||
return m_nowFunc() >= m_serialKey.expireTime.value();
|
||||
}
|
||||
|
||||
days License::daysLeft() const {
|
||||
if (!m_serialKey.expireTime.has_value()) {
|
||||
throw NoTimeLimitError();
|
||||
}
|
||||
|
||||
auto expireTime = m_serialKey.expireTime.value();
|
||||
|
||||
auto timeLeft = expireTime - m_nowFunc();
|
||||
return duration_cast<days>(timeLeft);
|
||||
}
|
||||
|
||||
std::string License::productName() const {
|
||||
auto name = m_serialKey.product.name();
|
||||
if (m_serialKey.type.isTrial()) {
|
||||
name += " (Trial)";
|
||||
}
|
||||
return name;
|
||||
}
|
||||
|
||||
} // namespace synergy::license
|
||||
93
src/lib/license/License.h
Normal file
93
src/lib/license/License.h
Normal file
|
|
@ -0,0 +1,93 @@
|
|||
/*
|
||||
* synergy -- mouse and keyboard sharing utility
|
||||
* Copyright (C) 2016 Symless Ltd.
|
||||
*
|
||||
* This package is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* found in the file LICENSE that should have accompanied this file.
|
||||
*
|
||||
* This package is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "SerialKey.h"
|
||||
|
||||
#include <chrono>
|
||||
#include <ctime>
|
||||
#include <functional>
|
||||
#include <string>
|
||||
|
||||
class Server;
|
||||
class LicenseHandler;
|
||||
class LicenseTests;
|
||||
|
||||
namespace synergy::license {
|
||||
|
||||
class License {
|
||||
friend class ::Server;
|
||||
friend class ::LicenseHandler;
|
||||
friend class ::LicenseTests;
|
||||
|
||||
using days = std::chrono::days;
|
||||
using system_clock = std::chrono::system_clock;
|
||||
using time_point = system_clock::time_point;
|
||||
using NowFunc = std::function<time_point()>;
|
||||
using LicenseError = std::runtime_error;
|
||||
|
||||
public:
|
||||
explicit License(const SerialKey &serialKey);
|
||||
explicit License(const std::string &hexString);
|
||||
|
||||
friend bool operator==(License const &lhs, License const &rhs) {
|
||||
return lhs.m_serialKey == rhs.m_serialKey;
|
||||
}
|
||||
|
||||
bool isValid() const { return m_serialKey.isValid; }
|
||||
bool isExpiring() const;
|
||||
bool isExpired() const;
|
||||
bool isTrial() const;
|
||||
bool isSubscription() const;
|
||||
bool isTimeLimited() const;
|
||||
bool isTlsAvailable() const;
|
||||
days daysLeft() const;
|
||||
Edition productEdition() const;
|
||||
std::string productName() const;
|
||||
const SerialKey &serialKey() const { return m_serialKey; }
|
||||
void invalidate() { m_serialKey = SerialKey::invalid(); }
|
||||
|
||||
class InvalidSerialKey : public LicenseError {
|
||||
public:
|
||||
explicit InvalidSerialKey() : LicenseError("invalid serial key") {}
|
||||
};
|
||||
|
||||
class NoTimeLimitError : public LicenseError {
|
||||
public:
|
||||
explicit NoTimeLimitError()
|
||||
: LicenseError("serial key has no time limit") {}
|
||||
};
|
||||
|
||||
protected:
|
||||
void setNowFunc(const NowFunc &nowFunc) { m_nowFunc = nowFunc; }
|
||||
|
||||
private:
|
||||
// for intentionality, force use of `invalid()` static function.
|
||||
License() = default;
|
||||
|
||||
// prevent copy, so that changes can be reflected in one instance.
|
||||
License(const License &) = default;
|
||||
License &operator=(const License &) = default;
|
||||
|
||||
static License invalid() { return License(); }
|
||||
|
||||
SerialKey m_serialKey = SerialKey::invalid();
|
||||
NowFunc m_nowFunc = []() { return system_clock::now(); };
|
||||
};
|
||||
|
||||
} // namespace synergy::license
|
||||
121
src/lib/license/Product.cpp
Normal file
121
src/lib/license/Product.cpp
Normal file
|
|
@ -0,0 +1,121 @@
|
|||
/*
|
||||
* synergy -- mouse and keyboard sharing utility
|
||||
* Copyright (C) 2016 Symless Ltd.
|
||||
*
|
||||
* This package is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* found in the file LICENSE that should have accompanied this file.
|
||||
*
|
||||
* This package is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <map>
|
||||
|
||||
#include "Product.h"
|
||||
|
||||
using SKE = Product::SerialKeyEditionID;
|
||||
|
||||
const char *const kLicensedProductName = "Synergy 1";
|
||||
|
||||
const std::string SKE::Pro = "pro";
|
||||
const std::string SKE::Basic = "basic";
|
||||
const std::string SKE::Buisiness = "business";
|
||||
|
||||
using Edition = Product::Edition;
|
||||
|
||||
const std::map<std::string, Edition, std::less<>> kSerialKeyEditions{
|
||||
{SKE::Basic, Edition::kBasic},
|
||||
{SKE::Pro, Edition::kPro},
|
||||
{SKE::Buisiness, Edition::kBusiness},
|
||||
};
|
||||
|
||||
Product::Product(Edition edition) : m_edition(edition) {}
|
||||
|
||||
Product::Product(const std::string &serialKeyEditionID) {
|
||||
setEdition(serialKeyEditionID);
|
||||
}
|
||||
|
||||
Edition Product::edition() const { return m_edition; }
|
||||
|
||||
std::string Product::serialKeyId() const {
|
||||
switch (edition()) {
|
||||
using enum Edition;
|
||||
|
||||
case kPro:
|
||||
return SKE::Pro;
|
||||
|
||||
case kBasic:
|
||||
return SKE::Basic;
|
||||
|
||||
case kBusiness:
|
||||
return SKE::Buisiness;
|
||||
|
||||
default:
|
||||
throw InvalidType();
|
||||
}
|
||||
}
|
||||
|
||||
std::string Product::name() const {
|
||||
|
||||
const std::string nameBase = kLicensedProductName;
|
||||
switch (edition()) {
|
||||
using enum Edition;
|
||||
|
||||
case kUnregistered:
|
||||
return nameBase + " (unregistered)";
|
||||
|
||||
case kBasic:
|
||||
return nameBase + " Basic";
|
||||
|
||||
case kPro:
|
||||
return nameBase + " Pro";
|
||||
|
||||
case kBusiness:
|
||||
return nameBase + " Business";
|
||||
|
||||
default:
|
||||
throw InvalidType();
|
||||
}
|
||||
}
|
||||
|
||||
void Product::setEdition(Edition edition) { m_edition = edition; }
|
||||
|
||||
void Product::setEdition(const std::string &name) {
|
||||
const auto &pType = kSerialKeyEditions.find(name);
|
||||
|
||||
if (pType != kSerialKeyEditions.end()) {
|
||||
m_edition = pType->second;
|
||||
} else {
|
||||
throw InvalidType();
|
||||
}
|
||||
}
|
||||
|
||||
bool Product::isValid() const {
|
||||
if (m_edition == Edition::kUnregistered) {
|
||||
return false;
|
||||
}
|
||||
return kSerialKeyEditions.contains(serialKeyId());
|
||||
}
|
||||
|
||||
bool Product::isTlsAvailable() const {
|
||||
switch (edition()) {
|
||||
using enum Edition;
|
||||
|
||||
case kPro:
|
||||
case kBusiness:
|
||||
return true;
|
||||
|
||||
case kBasic:
|
||||
case kUnregistered:
|
||||
return false;
|
||||
|
||||
default:
|
||||
throw InvalidType();
|
||||
}
|
||||
}
|
||||
64
src/lib/license/Product.h
Normal file
64
src/lib/license/Product.h
Normal file
|
|
@ -0,0 +1,64 @@
|
|||
/*
|
||||
* synergy -- mouse and keyboard sharing utility
|
||||
* Copyright (C) 2016 Symless Ltd.
|
||||
*
|
||||
* This package is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* found in the file LICENSE that should have accompanied this file.
|
||||
*
|
||||
* This package is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdexcept>
|
||||
#include <string>
|
||||
|
||||
class Product {
|
||||
friend bool operator==(Product const &, Product const &) = default;
|
||||
|
||||
public:
|
||||
class InvalidType : public std::runtime_error {
|
||||
public:
|
||||
explicit InvalidType() : std::runtime_error("invalid product type") {}
|
||||
};
|
||||
|
||||
enum class Edition {
|
||||
kUnregistered = -1,
|
||||
kBasic = 0,
|
||||
kPro = 1,
|
||||
kBusiness = 4,
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Product edition IDs found in a decoded serial key.
|
||||
*/
|
||||
class SerialKeyEditionID {
|
||||
public:
|
||||
static const std::string Basic;
|
||||
static const std::string Pro;
|
||||
static const std::string Buisiness;
|
||||
};
|
||||
|
||||
Product() = default;
|
||||
explicit Product(Edition edition);
|
||||
explicit Product(const std::string &serialKeyEditionID);
|
||||
|
||||
bool isValid() const;
|
||||
Edition edition() const;
|
||||
std::string serialKeyId() const;
|
||||
std::string name() const;
|
||||
bool isTlsAvailable() const;
|
||||
|
||||
void setEdition(Edition type);
|
||||
void setEdition(const std::string &serialKeyId);
|
||||
|
||||
private:
|
||||
Edition m_edition = Edition::kUnregistered;
|
||||
};
|
||||
|
|
@ -15,21 +15,9 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef EDITIONTYPE_H
|
||||
#define EDITIONTYPE_H
|
||||
#pragma once
|
||||
|
||||
/* Do not reorder these! */
|
||||
#include "Product.h"
|
||||
|
||||
enum Edition {
|
||||
kBasic,
|
||||
kPro,
|
||||
kValueNotUsed,
|
||||
kUnregistered,
|
||||
kBusiness,
|
||||
kBasicChina,
|
||||
kProChina,
|
||||
kLite,
|
||||
kUltimate
|
||||
};
|
||||
|
||||
#endif // EDITIONTYPE_H
|
||||
/// @deprecated Use `Product::Edition` instead
|
||||
using Edition = Product::Edition;
|
||||
60
src/lib/license/SerialKey.h
Normal file
60
src/lib/license/SerialKey.h
Normal file
|
|
@ -0,0 +1,60 @@
|
|||
/*
|
||||
* synergy -- mouse and keyboard sharing utility
|
||||
* Copyright (C) 2022 Symless Ltd.
|
||||
*
|
||||
* This package is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* found in the file LICENSE that should have accompanied this file.
|
||||
*
|
||||
* This package is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "ProductEdition.h"
|
||||
#include "SerialKeyType.h"
|
||||
#include "license/Product.h"
|
||||
#include "license/ProductEdition.h"
|
||||
|
||||
#include <chrono>
|
||||
#include <ctime>
|
||||
#include <optional>
|
||||
#include <string>
|
||||
|
||||
namespace synergy::license {
|
||||
|
||||
struct SerialKey {
|
||||
using time_point = std::chrono::system_clock::time_point;
|
||||
|
||||
friend bool operator==(const SerialKey &lhs, const SerialKey &rhs) {
|
||||
return (lhs.hexString == rhs.hexString) && (lhs.warnTime == rhs.warnTime) &&
|
||||
(lhs.expireTime == rhs.expireTime) && (lhs.product == rhs.product) &&
|
||||
(lhs.type == rhs.type);
|
||||
}
|
||||
|
||||
explicit SerialKey(const std::string &key) : hexString(key) {}
|
||||
|
||||
static SerialKey invalid() {
|
||||
return SerialKey(Product::Edition::kUnregistered);
|
||||
}
|
||||
|
||||
const std::string &toString() const { return hexString; }
|
||||
|
||||
bool isValid = false;
|
||||
std::string hexString = "";
|
||||
Product product;
|
||||
SerialKeyType type;
|
||||
std::optional<time_point> warnTime = std::nullopt;
|
||||
std::optional<time_point> expireTime = std::nullopt;
|
||||
|
||||
private:
|
||||
explicit SerialKey(Edition edition) : product(edition) {}
|
||||
};
|
||||
|
||||
} // namespace synergy::license
|
||||
|
|
@ -19,18 +19,16 @@
|
|||
|
||||
const std::string SerialKeyType::Trial = "trial";
|
||||
const std::string SerialKeyType::Subscription = "subscription";
|
||||
const std::string SerialKeyType::Maintenance = "maintenance";
|
||||
|
||||
SerialKeyType::SerialKeyType() {}
|
||||
|
||||
void SerialKeyType::setKeyType(const std::string &Type) {
|
||||
m_isTrial = (Type == SerialKeyType::Trial);
|
||||
m_isTemporary = (m_isTrial || (Type == SerialKeyType::Subscription));
|
||||
m_isMaintenance = (Type == SerialKeyType::Maintenance);
|
||||
void SerialKeyType::setType(const std::string_view &type) {
|
||||
m_isTrial = (type == SerialKeyType::Trial);
|
||||
m_isSubscription = (type == SerialKeyType::Subscription);
|
||||
}
|
||||
|
||||
bool SerialKeyType::isTrial() const { return m_isTrial; }
|
||||
|
||||
bool SerialKeyType::isTemporary() const { return m_isTemporary; }
|
||||
bool SerialKeyType::isSubscription() const { return m_isSubscription; }
|
||||
|
||||
bool SerialKeyType::isMaintenance() const { return m_isMaintenance; }
|
||||
bool SerialKeyType::isTimeLimited() const {
|
||||
return m_isTrial || m_isSubscription;
|
||||
}
|
||||
|
|
@ -21,31 +21,22 @@
|
|||
|
||||
class SerialKeyType {
|
||||
private:
|
||||
friend bool operator==(SerialKeyType const &, SerialKeyType const &);
|
||||
friend bool
|
||||
operator==(SerialKeyType const &lhs, SerialKeyType const &rhs) = default;
|
||||
|
||||
public:
|
||||
static const std::string Trial;
|
||||
static const std::string Subscription;
|
||||
static const std::string Maintenance;
|
||||
|
||||
SerialKeyType();
|
||||
explicit SerialKeyType() = default;
|
||||
explicit SerialKeyType(const std::string_view &type) { setType(type); }
|
||||
|
||||
void setKeyType(const std::string &type);
|
||||
void setType(const std::string_view &type);
|
||||
bool isTrial() const;
|
||||
bool isTemporary() const;
|
||||
bool isMaintenance() const;
|
||||
bool isSubscription() const;
|
||||
bool isTimeLimited() const;
|
||||
|
||||
private:
|
||||
bool m_isTrial = false;
|
||||
bool m_isTemporary = false;
|
||||
bool m_isMaintenance = false;
|
||||
bool m_isSubscription = false;
|
||||
};
|
||||
|
||||
inline bool operator==(SerialKeyType const &lhs, SerialKeyType const &rhs) {
|
||||
return (lhs.m_isTrial == rhs.m_isTrial) &&
|
||||
(lhs.m_isTemporary == rhs.m_isTemporary);
|
||||
}
|
||||
|
||||
inline bool operator!=(SerialKeyType const &lhs, SerialKeyType const &rhs) {
|
||||
return !(lhs == rhs);
|
||||
}
|
||||
143
src/lib/license/parse_serial_key.cpp
Normal file
143
src/lib/license/parse_serial_key.cpp
Normal file
|
|
@ -0,0 +1,143 @@
|
|||
/*
|
||||
* synergy -- mouse and keyboard sharing utility
|
||||
* Copyright (C) 2024 Symless Ltd.
|
||||
*
|
||||
* This package is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* found in the file LICENSE that should have accompanied this file.
|
||||
*
|
||||
* This package is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "parse_serial_key.h"
|
||||
|
||||
#include "SerialKey.h"
|
||||
#include "SerialKeyType.h"
|
||||
#include "utils/trim.h"
|
||||
|
||||
#include <cctype>
|
||||
#include <optional>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
using Parts = std::vector<std::string>;
|
||||
using system_clock = std::chrono::system_clock;
|
||||
using time_point = system_clock::time_point;
|
||||
|
||||
namespace synergy::license {
|
||||
|
||||
std::string decode(const std::string &hexString);
|
||||
Parts tokenize(const std::string &plainText);
|
||||
SerialKey parseV1(const std::string &hexString, const Parts &parts);
|
||||
SerialKey parseV2(const std::string &hexString, const Parts &parts);
|
||||
std::optional<time_point> parseDate(const std::string &unixTimeString);
|
||||
|
||||
SerialKey parseSerialKey(const std::string &hexString) {
|
||||
const auto &plainText = decode(hexString);
|
||||
const auto &parts = tokenize(plainText);
|
||||
const auto &version = parts.at(0);
|
||||
|
||||
if (version == "v1") {
|
||||
return parseV1(hexString, parts);
|
||||
} else if (version == "v2") {
|
||||
return parseV2(hexString, parts);
|
||||
} else {
|
||||
throw InvalidSerialKeyVersion(version);
|
||||
}
|
||||
}
|
||||
|
||||
std::string decode(const std::string &hexString) {
|
||||
std::string trimmed = utils::trim(hexString);
|
||||
|
||||
if (trimmed.length() % 2 != 0) {
|
||||
throw InvalidHexString();
|
||||
}
|
||||
|
||||
std::string plainText;
|
||||
plainText.reserve(trimmed.length() / 2);
|
||||
|
||||
for (size_t i = 0; i < trimmed.length(); i += 2) {
|
||||
std::string byteString = trimmed.substr(i, 2);
|
||||
auto byte = static_cast<char>(std::stoi(byteString, nullptr, 16));
|
||||
plainText.push_back(byte);
|
||||
}
|
||||
|
||||
return plainText;
|
||||
}
|
||||
|
||||
SerialKey parseV1(const std::string &hexString, const Parts &parts) {
|
||||
if (parts.size() < 8) {
|
||||
throw InvalidSerialKeyFormat();
|
||||
}
|
||||
|
||||
// e.g.: {v1;basic;name;1;email;company name;1398297600;1398384000}
|
||||
SerialKey serialKey(hexString);
|
||||
serialKey.product = Product(parts.at(1));
|
||||
serialKey.warnTime = parseDate(parts.at(6));
|
||||
serialKey.expireTime = parseDate(parts.at(7));
|
||||
serialKey.isValid = true;
|
||||
return serialKey;
|
||||
}
|
||||
|
||||
SerialKey parseV2(const std::string &hexString, const Parts &parts) {
|
||||
if (parts.size() < 9) {
|
||||
throw InvalidSerialKeyFormat();
|
||||
}
|
||||
// e.g.: {v2;trial;basic;name;1;email;company name;1398297600;1398384000}
|
||||
SerialKey serialKey(hexString);
|
||||
serialKey.type = SerialKeyType(parts.at(1));
|
||||
serialKey.product = Product(parts.at(2));
|
||||
serialKey.warnTime = parseDate(parts.at(7));
|
||||
serialKey.expireTime = parseDate(parts.at(8));
|
||||
serialKey.isValid = true;
|
||||
return serialKey;
|
||||
}
|
||||
|
||||
Parts tokenize(const std::string &plainText) {
|
||||
if (plainText.front() != '{' || plainText.back() != '}') {
|
||||
throw InvalidSerialKeyFormat();
|
||||
}
|
||||
|
||||
const auto serialData = plainText.substr(1, plainText.length() - 2);
|
||||
|
||||
Parts parts;
|
||||
std::stringstream ss(serialData);
|
||||
std::string item;
|
||||
|
||||
while (std::getline(ss, item, ';')) {
|
||||
parts.push_back(item);
|
||||
}
|
||||
|
||||
// it's possible that the last character is a delimiter, so add an empty part
|
||||
if (!serialData.empty() && serialData.back() == ';') {
|
||||
parts.emplace_back("");
|
||||
}
|
||||
|
||||
return parts;
|
||||
}
|
||||
|
||||
std::optional<time_point> parseDate(const std::string &unixTimeString) {
|
||||
auto clean = utils::trim(unixTimeString);
|
||||
if (clean.empty()) {
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
try {
|
||||
auto seconds = std::stoi(clean);
|
||||
if (seconds < 0) {
|
||||
throw InvalidSerialKeyDate(unixTimeString);
|
||||
}
|
||||
return time_point{std::chrono::seconds{seconds}};
|
||||
} catch (const std::invalid_argument &) {
|
||||
throw InvalidSerialKeyDate(unixTimeString);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace synergy::license
|
||||
57
src/lib/license/parse_serial_key.h
Normal file
57
src/lib/license/parse_serial_key.h
Normal file
|
|
@ -0,0 +1,57 @@
|
|||
/*
|
||||
* synergy -- mouse and keyboard sharing utility
|
||||
* Copyright (C) 2024 Symless Ltd.
|
||||
*
|
||||
* This package is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* found in the file LICENSE that should have accompanied this file.
|
||||
*
|
||||
* This package is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "SerialKey.h"
|
||||
|
||||
#include <stdexcept>
|
||||
#include <string>
|
||||
|
||||
namespace synergy::license {
|
||||
|
||||
class SerialKeyParseError : public std::runtime_error {
|
||||
public:
|
||||
explicit SerialKeyParseError(const std::string &message)
|
||||
: std::runtime_error(message) {}
|
||||
};
|
||||
|
||||
class InvalidHexString : public SerialKeyParseError {
|
||||
public:
|
||||
explicit InvalidHexString()
|
||||
: SerialKeyParseError("invalid hex string length") {}
|
||||
};
|
||||
|
||||
class InvalidSerialKeyFormat : public SerialKeyParseError {
|
||||
public:
|
||||
explicit InvalidSerialKeyFormat()
|
||||
: SerialKeyParseError("invalid serial key format") {}
|
||||
};
|
||||
|
||||
class InvalidSerialKeyDate : public SerialKeyParseError {
|
||||
public:
|
||||
explicit InvalidSerialKeyDate(const std::string &date)
|
||||
: SerialKeyParseError("invalid serial key date: " + date) {}
|
||||
};
|
||||
|
||||
class InvalidSerialKeyVersion : public SerialKeyParseError {
|
||||
public:
|
||||
explicit InvalidSerialKeyVersion(const std::string &version)
|
||||
: SerialKeyParseError("invalid serial key version: " + version) {}
|
||||
};
|
||||
|
||||
SerialKey parseSerialKey(const std::string &hexString);
|
||||
|
||||
} // namespace synergy::license
|
||||
|
|
@ -93,7 +93,7 @@ MSWindowsScreen *MSWindowsScreen::s_screen = NULL;
|
|||
|
||||
MSWindowsScreen::MSWindowsScreen(
|
||||
bool isPrimary, bool noHooks, bool stopOnDeskSwitch, IEventQueue *events,
|
||||
bool enableLangSync, lib::synergy::ClientScrollDirection scrollDirection)
|
||||
bool enableLangSync, synergy::ClientScrollDirection scrollDirection)
|
||||
: PlatformScreen(events, scrollDirection),
|
||||
m_isPrimary(isPrimary),
|
||||
m_noHooks(noHooks),
|
||||
|
|
|
|||
|
|
@ -44,8 +44,8 @@ public:
|
|||
MSWindowsScreen(
|
||||
bool isPrimary, bool noHooks, bool stopOnDeskSwitch, IEventQueue *events,
|
||||
bool enableLangSync = false,
|
||||
lib::synergy::ClientScrollDirection scrollDirection =
|
||||
lib::synergy::ClientScrollDirection::SERVER);
|
||||
synergy::ClientScrollDirection scrollDirection =
|
||||
synergy::ClientScrollDirection::SERVER);
|
||||
virtual ~MSWindowsScreen();
|
||||
|
||||
//! @name manipulators
|
||||
|
|
|
|||
|
|
@ -23,11 +23,11 @@
|
|||
#include "base/Log.h"
|
||||
#include "base/TMethodJob.h"
|
||||
#include "base/log_outputters.h"
|
||||
#include "global/Ipc.h"
|
||||
#include "ipc/IpcLogOutputter.h"
|
||||
#include "ipc/IpcMessage.h"
|
||||
#include "ipc/IpcServer.h"
|
||||
#include "mt/Thread.h"
|
||||
#include "shared/Ipc.h"
|
||||
#include "synergy/App.h"
|
||||
#include "synergy/ArgsBase.h"
|
||||
|
||||
|
|
|
|||
|
|
@ -56,8 +56,8 @@ class OSXScreen : public PlatformScreen {
|
|||
public:
|
||||
OSXScreen(
|
||||
IEventQueue *events, bool isPrimary, bool enableLangSync = false,
|
||||
lib::synergy::ClientScrollDirection scrollDirection =
|
||||
lib::synergy::ClientScrollDirection::SERVER);
|
||||
synergy::ClientScrollDirection scrollDirection =
|
||||
synergy::ClientScrollDirection::SERVER);
|
||||
|
||||
virtual ~OSXScreen();
|
||||
|
||||
|
|
|
|||
|
|
@ -86,7 +86,7 @@ bool OSXScreen::s_hasGHOM = false;
|
|||
OSXScreen::OSXScreen(IEventQueue* events,
|
||||
bool isPrimary,
|
||||
bool enableLangSync,
|
||||
lib::synergy::ClientScrollDirection scrollDirection) :
|
||||
synergy::ClientScrollDirection scrollDirection) :
|
||||
PlatformScreen(events, scrollDirection),
|
||||
m_isPrimary(isPrimary),
|
||||
m_isOnScreen(m_isPrimary),
|
||||
|
|
|
|||
|
|
@ -98,7 +98,7 @@ XWindowsScreen *XWindowsScreen::s_screen = NULL;
|
|||
XWindowsScreen::XWindowsScreen(
|
||||
const char *displayName, bool isPrimary, bool disableXInitThreads,
|
||||
int mouseScrollDelta, IEventQueue *events,
|
||||
lib::synergy::ClientScrollDirection scrollDirection)
|
||||
synergy::ClientScrollDirection scrollDirection)
|
||||
: PlatformScreen(events, scrollDirection),
|
||||
m_isPrimary(isPrimary),
|
||||
m_mouseScrollDelta(mouseScrollDelta),
|
||||
|
|
|
|||
|
|
@ -42,8 +42,8 @@ public:
|
|||
XWindowsScreen(
|
||||
const char *displayName, bool isPrimary, bool disableXInitThreads,
|
||||
int mouseScrollDelta, IEventQueue *events,
|
||||
lib::synergy::ClientScrollDirection m_clientScrollDirection =
|
||||
lib::synergy::ClientScrollDirection::SERVER);
|
||||
synergy::ClientScrollDirection m_clientScrollDirection =
|
||||
synergy::ClientScrollDirection::SERVER);
|
||||
virtual ~XWindowsScreen();
|
||||
|
||||
//! @name manipulators
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ endif()
|
|||
|
||||
add_library(server STATIC ${sources})
|
||||
|
||||
target_link_libraries(server shared)
|
||||
target_link_libraries(server global license)
|
||||
|
||||
if(UNIX)
|
||||
target_link_libraries(server synlib)
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@
|
|||
#include "base/TMethodEventJob.h"
|
||||
#include "base/TMethodJob.h"
|
||||
#include "common/stdexcept.h"
|
||||
#include "license/License.h"
|
||||
#include "mt/Thread.h"
|
||||
#include "net/IDataSocket.h"
|
||||
#include "net/IListenSocket.h"
|
||||
|
|
@ -33,7 +34,6 @@
|
|||
#include "server/ClientProxy.h"
|
||||
#include "server/ClientProxyUnknown.h"
|
||||
#include "server/PrimaryClient.h"
|
||||
#include "shared/SerialKey.h"
|
||||
#include "synergy/AppUtil.h"
|
||||
#include "synergy/DropHelper.h"
|
||||
#include "synergy/FileChunk.h"
|
||||
|
|
@ -54,13 +54,15 @@
|
|||
#include <fstream>
|
||||
#include <sstream>
|
||||
|
||||
using namespace synergy::license;
|
||||
|
||||
//
|
||||
// Server
|
||||
//
|
||||
|
||||
Server::Server(
|
||||
Config &config, PrimaryClient *primaryClient, synergy::Screen *screen,
|
||||
IEventQueue *events, lib::synergy::ServerArgs const &args)
|
||||
IEventQueue *events, synergy::ServerArgs const &args)
|
||||
: m_mock(false),
|
||||
m_primaryClient(primaryClient),
|
||||
m_active(primaryClient),
|
||||
|
|
@ -429,7 +431,8 @@ void Server::switchScreen(
|
|||
assert(dst != NULL);
|
||||
|
||||
// if trial is expired, exit the process
|
||||
if (m_args.m_serial.isExpired(std::time(0))) {
|
||||
License license(m_args.m_serialKey);
|
||||
if (license.isExpired()) {
|
||||
LOG((CLOG_ERR "trial has expired, aborting server"));
|
||||
exit(kExitSuccess);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -111,7 +111,7 @@ public:
|
|||
*/
|
||||
Server(
|
||||
Config &config, PrimaryClient *primaryClient, synergy::Screen *screen,
|
||||
IEventQueue *events, lib::synergy::ServerArgs const &args);
|
||||
IEventQueue *events, synergy::ServerArgs const &args);
|
||||
Server(Server const &) = delete;
|
||||
Server(Server &&) = delete;
|
||||
~Server();
|
||||
|
|
@ -490,5 +490,5 @@ private:
|
|||
bool m_waitDragInfoThread;
|
||||
|
||||
ClientListener *m_clientListener;
|
||||
lib::synergy::ServerArgs m_args;
|
||||
synergy::ServerArgs m_args;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,123 +0,0 @@
|
|||
/*
|
||||
* synergy -- mouse and keyboard sharing utility
|
||||
* Copyright (C) 2016 Symless Ltd.
|
||||
*
|
||||
* This package is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* found in the file LICENSE that should have accompanied this file.
|
||||
*
|
||||
* This package is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "SerialKey.h"
|
||||
|
||||
#include "SerialKeyEdition.h"
|
||||
#include "SerialKeyParser.h"
|
||||
#include <climits>
|
||||
#include <stdexcept>
|
||||
#include <vector>
|
||||
|
||||
SerialKey::SerialKey(Edition edition) : m_data(edition) {}
|
||||
|
||||
SerialKey::SerialKey(const std::string &serial) : m_data(serial) {
|
||||
SerialKeyParser parser;
|
||||
|
||||
if (parser.parse(serial)) {
|
||||
m_data = parser.getData();
|
||||
} else {
|
||||
throw std::runtime_error("Invalid serial key");
|
||||
}
|
||||
}
|
||||
|
||||
bool SerialKey::isExpiring(time_t currentTime) const {
|
||||
bool result = false;
|
||||
|
||||
if (isTemporary()) {
|
||||
unsigned long long currentTimeAsLL =
|
||||
static_cast<unsigned long long>(currentTime);
|
||||
if ((m_data.warnTime <= currentTimeAsLL) &&
|
||||
(currentTimeAsLL < m_data.expireTime)) {
|
||||
result = true;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
bool SerialKey::isExpired(time_t currentTime) const {
|
||||
bool result = false;
|
||||
|
||||
if (isTemporary()) {
|
||||
unsigned long long currentTimeAsLL =
|
||||
static_cast<unsigned long long>(currentTime);
|
||||
if (m_data.expireTime <= currentTimeAsLL) {
|
||||
result = true;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
bool SerialKey::isTrial() const { return m_data.keyType.isTrial(); }
|
||||
|
||||
bool SerialKey::isTemporary() const {
|
||||
return (m_data.keyType.isTemporary() && !m_data.edition.isChina());
|
||||
}
|
||||
|
||||
bool SerialKey::isMaintenance() const {
|
||||
return (m_data.keyType.isMaintenance() || m_data.edition.isChina());
|
||||
}
|
||||
|
||||
bool SerialKey::isValid() const {
|
||||
bool Valid = true;
|
||||
|
||||
if (!m_data.edition.isValid() || isExpired(::time(nullptr))) {
|
||||
Valid = false;
|
||||
}
|
||||
|
||||
return Valid;
|
||||
}
|
||||
|
||||
Edition SerialKey::edition() const { return m_data.edition.getType(); }
|
||||
|
||||
const std::string &SerialKey::toString() const { return m_data.key; }
|
||||
|
||||
time_t SerialKey::daysLeft(time_t currentTime) const {
|
||||
unsigned long long timeLeft = 0;
|
||||
unsigned long long const day = 60 * 60 * 24;
|
||||
|
||||
unsigned long long currentTimeAsLL =
|
||||
static_cast<unsigned long long>(currentTime);
|
||||
if (currentTimeAsLL < m_data.expireTime) {
|
||||
timeLeft = m_data.expireTime - currentTimeAsLL;
|
||||
}
|
||||
|
||||
unsigned long long daysLeft = 0;
|
||||
daysLeft = timeLeft % day != 0 ? 1 : 0;
|
||||
|
||||
return timeLeft / day + daysLeft;
|
||||
}
|
||||
|
||||
time_t SerialKey::getExpiration() const { return m_data.expireTime; }
|
||||
|
||||
int SerialKey::getSpanLeft(time_t time) const {
|
||||
int result{-1};
|
||||
|
||||
if (isTemporary() && !isExpired(time)) {
|
||||
auto timeLeft = (m_data.expireTime - time) * 1000;
|
||||
|
||||
if (timeLeft < INT_MAX) {
|
||||
result = static_cast<int>(timeLeft);
|
||||
} else {
|
||||
result = INT_MAX;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
|
@ -1,54 +0,0 @@
|
|||
/*
|
||||
* synergy -- mouse and keyboard sharing utility
|
||||
* Copyright (C) 2016 Symless Ltd.
|
||||
*
|
||||
* This package is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* found in the file LICENSE that should have accompanied this file.
|
||||
*
|
||||
* This package is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "SerialKeyData.h"
|
||||
#include "SerialKeyEdition.h"
|
||||
#include <ctime>
|
||||
#include <string>
|
||||
|
||||
class SerialKey {
|
||||
friend bool operator==(SerialKey const &, SerialKey const &);
|
||||
|
||||
public:
|
||||
explicit SerialKey(Edition edition = kUnregistered);
|
||||
explicit SerialKey(const std::string &serial);
|
||||
|
||||
bool isExpiring(time_t currentTime) const;
|
||||
bool isExpired(time_t currentTime) const;
|
||||
bool isTrial() const;
|
||||
bool isTemporary() const;
|
||||
bool isMaintenance() const;
|
||||
bool isValid() const;
|
||||
time_t daysLeft(time_t currentTime) const;
|
||||
time_t getExpiration() const;
|
||||
int getSpanLeft(time_t time = ::time(0)) const;
|
||||
Edition edition() const;
|
||||
const std::string &toString() const;
|
||||
|
||||
private:
|
||||
SerialKeyData m_data;
|
||||
};
|
||||
|
||||
inline bool operator==(SerialKey const &lhs, SerialKey const &rhs) {
|
||||
return (lhs.m_data == rhs.m_data);
|
||||
}
|
||||
|
||||
inline bool operator!=(SerialKey const &lhs, SerialKey const &rhs) {
|
||||
return !(lhs == rhs);
|
||||
}
|
||||
|
|
@ -1,52 +0,0 @@
|
|||
/*
|
||||
* synergy -- mouse and keyboard sharing utility
|
||||
* Copyright (C) 2022 Symless Ltd.
|
||||
*
|
||||
* This package is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* found in the file LICENSE that should have accompanied this file.
|
||||
*
|
||||
* This package is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "SerialKeyEdition.h"
|
||||
#include "SerialKeyType.h"
|
||||
#include <string>
|
||||
|
||||
/**
|
||||
* @brief The SerialKeyData struct
|
||||
* This is DTO which stores key data
|
||||
*/
|
||||
struct SerialKeyData {
|
||||
std::string key; // Encoded serial key as a string
|
||||
SerialKeyEdition edition; // Serial key edition
|
||||
SerialKeyType keyType; // Serial key type
|
||||
unsigned long long warnTime = 0; // Warning time
|
||||
unsigned long long expireTime = 0; // Expiration time
|
||||
|
||||
/**
|
||||
* @brief SerialKeyData constructor
|
||||
* @param key encoded key
|
||||
*/
|
||||
explicit SerialKeyData(const std::string &key) : key(key) {}
|
||||
|
||||
/**
|
||||
* @brief SerialKeyData default constructor
|
||||
* @param key edition. Unregistered by default
|
||||
*/
|
||||
explicit SerialKeyData(Edition edition = kUnregistered) : edition(edition) {}
|
||||
};
|
||||
|
||||
inline bool operator==(SerialKeyData const &lhs, SerialKeyData const &rhs) {
|
||||
return (lhs.key == rhs.key) && (lhs.warnTime == rhs.warnTime) &&
|
||||
(lhs.expireTime == rhs.expireTime) && (lhs.edition == rhs.edition) &&
|
||||
(lhs.keyType == rhs.keyType);
|
||||
}
|
||||
|
|
@ -1,126 +0,0 @@
|
|||
/*
|
||||
* synergy -- mouse and keyboard sharing utility
|
||||
* Copyright (C) 2016 Symless Ltd.
|
||||
*
|
||||
* This package is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* found in the file LICENSE that should have accompanied this file.
|
||||
*
|
||||
* This package is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <map>
|
||||
|
||||
#include "SerialKeyEdition.h"
|
||||
|
||||
const std::string SerialKeyEdition::Pro = "pro";
|
||||
const std::string SerialKeyEdition::ProChina = "pro_china";
|
||||
const std::string SerialKeyEdition::Basic = "basic";
|
||||
const std::string SerialKeyEdition::BasicChina = "basic_china";
|
||||
const std::string SerialKeyEdition::Buisiness = "business";
|
||||
const std::string SerialKeyEdition::Unregistered = "community";
|
||||
const std::string SerialKeyEdition::Ultimate = "ultimate";
|
||||
const std::string SerialKeyEdition::Lite = "lite";
|
||||
|
||||
const std::map<std::string, Edition, std::less<>> serialTypes{
|
||||
{SerialKeyEdition::Basic, kBasic},
|
||||
{SerialKeyEdition::Pro, kPro},
|
||||
{SerialKeyEdition::BasicChina, kBasicChina},
|
||||
{SerialKeyEdition::ProChina, kProChina},
|
||||
{SerialKeyEdition::Buisiness, kBusiness},
|
||||
{SerialKeyEdition::Lite, kLite},
|
||||
{SerialKeyEdition::Ultimate, kUltimate}};
|
||||
|
||||
SerialKeyEdition::SerialKeyEdition(Edition type) : m_type(type) {}
|
||||
|
||||
SerialKeyEdition::SerialKeyEdition(const std::string &type) { setType(type); }
|
||||
|
||||
Edition SerialKeyEdition::getType() const { return m_type; }
|
||||
|
||||
std::string SerialKeyEdition::getName() const {
|
||||
switch (getType()) {
|
||||
case kLite:
|
||||
return Lite;
|
||||
|
||||
case kUltimate:
|
||||
return Ultimate;
|
||||
|
||||
case kPro:
|
||||
return Pro;
|
||||
|
||||
case kBasic:
|
||||
return Basic;
|
||||
|
||||
case kBusiness:
|
||||
return Buisiness;
|
||||
|
||||
case kBasicChina:
|
||||
return BasicChina;
|
||||
|
||||
case kProChina:
|
||||
return ProChina;
|
||||
|
||||
default:
|
||||
return Unregistered;
|
||||
}
|
||||
}
|
||||
|
||||
std::string SerialKeyEdition::getProductName() const {
|
||||
const std::string nameBase = "Synergy 1";
|
||||
|
||||
switch (getType()) {
|
||||
|
||||
case kLite:
|
||||
return nameBase;
|
||||
|
||||
case kUltimate:
|
||||
return nameBase + " Ultimate";
|
||||
|
||||
case kPro:
|
||||
return nameBase + " Pro";
|
||||
|
||||
case kBasic:
|
||||
return nameBase + " Basic";
|
||||
|
||||
case kBusiness:
|
||||
return nameBase + " Business";
|
||||
|
||||
case kBasicChina:
|
||||
return nameBase + " 中文版";
|
||||
|
||||
case kProChina:
|
||||
return nameBase + " Pro 中文版";
|
||||
|
||||
default:
|
||||
return nameBase + " (Unregistered)";
|
||||
}
|
||||
}
|
||||
|
||||
void SerialKeyEdition::setType(Edition type) {
|
||||
m_type = type;
|
||||
setType(getName());
|
||||
}
|
||||
|
||||
void SerialKeyEdition::setType(const std::string &name) {
|
||||
const auto &pType = serialTypes.find(name);
|
||||
|
||||
if (pType != serialTypes.end()) {
|
||||
m_type = pType->second;
|
||||
} else {
|
||||
m_type = kUnregistered;
|
||||
}
|
||||
}
|
||||
|
||||
bool SerialKeyEdition::isValid() const {
|
||||
return serialTypes.contains(getName());
|
||||
}
|
||||
|
||||
bool SerialKeyEdition::isChina() const {
|
||||
return ((m_type == kBasicChina) || (m_type == kProChina));
|
||||
}
|
||||
|
|
@ -1,53 +0,0 @@
|
|||
/*
|
||||
* synergy -- mouse and keyboard sharing utility
|
||||
* Copyright (C) 2016 Symless Ltd.
|
||||
*
|
||||
* This package is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* found in the file LICENSE that should have accompanied this file.
|
||||
*
|
||||
* This package is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "EditionType.h"
|
||||
#include <string>
|
||||
|
||||
class SerialKeyEdition {
|
||||
friend bool
|
||||
operator==(SerialKeyEdition const &, SerialKeyEdition const &) = default;
|
||||
|
||||
public:
|
||||
SerialKeyEdition() = default;
|
||||
explicit SerialKeyEdition(Edition type);
|
||||
explicit SerialKeyEdition(const std::string &name);
|
||||
|
||||
Edition getType() const;
|
||||
std::string getName() const;
|
||||
std::string getProductName() const;
|
||||
|
||||
void setType(Edition type);
|
||||
void setType(const std::string &type);
|
||||
|
||||
bool isValid() const;
|
||||
bool isChina() const;
|
||||
|
||||
static const std::string Pro;
|
||||
static const std::string ProChina;
|
||||
static const std::string Basic;
|
||||
static const std::string BasicChina;
|
||||
static const std::string Buisiness;
|
||||
static const std::string Unregistered;
|
||||
static const std::string Ultimate;
|
||||
static const std::string Lite;
|
||||
|
||||
private:
|
||||
Edition m_type = kUnregistered;
|
||||
};
|
||||
|
|
@ -1,138 +0,0 @@
|
|||
/*
|
||||
* synergy -- mouse and keyboard sharing utility
|
||||
* Copyright (C) 2022 Symless Ltd.
|
||||
*
|
||||
* This package is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* found in the file LICENSE that should have accompanied this file.
|
||||
*
|
||||
* This package is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "SerialKeyParser.h"
|
||||
|
||||
void SerialKeyParser::setKey(const std::string &key) { m_data.key = key; }
|
||||
|
||||
void SerialKeyParser::setType(const std::string &type) {
|
||||
m_data.keyType.setKeyType(type);
|
||||
}
|
||||
|
||||
void SerialKeyParser::setEdition(const std::string &edition) {
|
||||
m_data.edition.setType(edition);
|
||||
if (m_data.keyType.isMaintenance() &&
|
||||
m_data.edition.getType() == Edition::kBasic) {
|
||||
m_data.edition.setType(kLite);
|
||||
} else if (
|
||||
m_data.keyType.isMaintenance() &&
|
||||
m_data.edition.getType() == Edition::kPro) {
|
||||
m_data.edition.setType(kUltimate);
|
||||
}
|
||||
}
|
||||
|
||||
void SerialKeyParser::setWarningTime(const std::string &warnTime) {
|
||||
sscanf(warnTime.c_str(), "%lld", &m_data.warnTime);
|
||||
}
|
||||
|
||||
void SerialKeyParser::setExpirationTime(const std::string &expTime) {
|
||||
sscanf(expTime.c_str(), "%lld", &m_data.expireTime);
|
||||
}
|
||||
|
||||
std::string SerialKeyParser::decode(const std::string &serial) const {
|
||||
static const char *const lut = "0123456789ABCDEF";
|
||||
std::string output;
|
||||
size_t len = serial.length();
|
||||
if (len & 1) {
|
||||
return output;
|
||||
}
|
||||
|
||||
output.reserve(len / 2);
|
||||
for (size_t i = 0; i < len; i += 2) {
|
||||
|
||||
char a = serial[i];
|
||||
char b = serial[i + 1];
|
||||
|
||||
const auto p = std::lower_bound(lut, lut + 16, a);
|
||||
const auto q = std::lower_bound(lut, lut + 16, b);
|
||||
|
||||
if (*q != b || *p != a) {
|
||||
return output;
|
||||
}
|
||||
|
||||
output.push_back(static_cast<char>(((p - lut) << 4) | (q - lut)));
|
||||
}
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
bool SerialKeyParser::parse(const std::string &plainSerial) {
|
||||
bool valid = false;
|
||||
auto key = decode(plainSerial);
|
||||
const auto parts = splitToParts(key);
|
||||
|
||||
if ((parts.size() == 8) && (parts.at(0).find("v1") != std::string::npos)) {
|
||||
setKey(plainSerial);
|
||||
parseV1(parts);
|
||||
valid = true;
|
||||
} else if (
|
||||
(parts.size() == 9) && (parts.at(0).find("v2") != std::string::npos)) {
|
||||
setKey(plainSerial);
|
||||
parseV2(parts);
|
||||
valid = true;
|
||||
}
|
||||
|
||||
return valid;
|
||||
}
|
||||
|
||||
const SerialKeyData &SerialKeyParser::getData() const { return m_data; }
|
||||
|
||||
void SerialKeyParser::parseV1(const std::vector<std::string> &parts) {
|
||||
// e.g.: {v1;basic;Bob;1;email;company name;1398297600;1398384000}
|
||||
setEdition(parts.at(1));
|
||||
setWarningTime(parts.at(6));
|
||||
setExpirationTime(parts.at(7));
|
||||
}
|
||||
|
||||
void SerialKeyParser::parseV2(const std::vector<std::string> &parts) {
|
||||
// e.g.: {v2;trial;basic;Bob;1;email;company name;1398297600;1398384000}
|
||||
setType(parts.at(1));
|
||||
setEdition(parts.at(2));
|
||||
setWarningTime(parts.at(7));
|
||||
setExpirationTime(parts.at(8));
|
||||
}
|
||||
|
||||
std::vector<std::string>
|
||||
SerialKeyParser::splitToParts(const std::string &plainSerial) const {
|
||||
// tokenize serialised subscription.
|
||||
std::vector<std::string> parts;
|
||||
|
||||
if (!plainSerial.empty()) {
|
||||
std::string parityStart = plainSerial.substr(0, 1);
|
||||
std::string parityEnd = plainSerial.substr(plainSerial.length() - 1, 1);
|
||||
|
||||
// check for parity chars { and }, record parity result, then remove them.
|
||||
if (parityStart == "{" && parityEnd == "}") {
|
||||
const auto serialData = plainSerial.substr(1, plainSerial.length() - 2);
|
||||
|
||||
std::string::size_type pos = 0;
|
||||
bool look = true;
|
||||
while (look) {
|
||||
std::string::size_type start = pos;
|
||||
pos = serialData.find(";", pos);
|
||||
if (pos == std::string::npos) {
|
||||
pos = serialData.length();
|
||||
look = false;
|
||||
}
|
||||
parts.push_back(serialData.substr(start, pos - start));
|
||||
pos += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return parts;
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue