Refactor local/global save/load and show dev thanks message (#7423)
* WIP: Show dev thanks message * Improve error messages and guard license code * Print core command * Allow license tests when licensing disabled by default * Don't check invalid serial key * Fixed typo * Add error checking * Use shared ptr instead of static deps * Actually save and load the setting * Add dev thanks vars to CI * Show thanks message after connected * Refactor hack-job of local/global save/load to remove coupling and use Qt events system * Simplify config loading * Overloads for optionals * Fixed global config scope not loaded * Save message state before showing to avoid multiple messages * Update ChangeLog * Fixed lint warnings * Make function const * Reduce verbosity * Remove dead code, show version on start, tidy up lint warnings * Make product name code safer * Connect on enter press * Only show server specific wording when on server * Add emit commands * Log info and error * Remove deaad code * Remove test member * Disable start context menu action unless usable * Show more relvant connect message * Fixed close to tray not applied, and simplified restart core logic * Remove redundant include
This commit is contained in:
parent
e0c08852bf
commit
157fe818d8
50 changed files with 1525 additions and 1186 deletions
1
.github/workflows/ci.yml
vendored
1
.github/workflows/ci.yml
vendored
|
|
@ -27,6 +27,7 @@ env:
|
||||||
SYNERGY_PRODUCT_NAME: ${{ vars.SYNERGY_PRODUCT_NAME }}
|
SYNERGY_PRODUCT_NAME: ${{ vars.SYNERGY_PRODUCT_NAME }}
|
||||||
SYNERGY_PACKAGE_PREFIX: ${{ vars.SYNERGY_PACKAGE_PREFIX }}
|
SYNERGY_PACKAGE_PREFIX: ${{ vars.SYNERGY_PACKAGE_PREFIX }}
|
||||||
SYNERGY_ENABLE_LICENSING: ${{ vars.SYNERGY_ENABLE_LICENSING }}
|
SYNERGY_ENABLE_LICENSING: ${{ vars.SYNERGY_ENABLE_LICENSING }}
|
||||||
|
SYNERGY_SHOW_DEV_THANKS: ${{ vars.SYNERGY_SHOW_DEV_THANKS }}
|
||||||
PACKAGE_BUILD: ${{ !github.event.pull_request.draft }}
|
PACKAGE_BUILD: ${{ !github.event.pull_request.draft }}
|
||||||
PACKAGE_UPLOAD: ${{ !github.event.pull_request.draft && github.event_name != 'schedule' }}
|
PACKAGE_UPLOAD: ${{ !github.event.pull_request.draft && github.event_name != 'schedule' }}
|
||||||
UPLOAD_TO_GITHUB: ${{ github.event_name == 'pull_request' && !github.event.pull_request.draft }}
|
UPLOAD_TO_GITHUB: ${{ github.event_name == 'pull_request' && !github.event.pull_request.draft }}
|
||||||
|
|
|
||||||
|
|
@ -66,6 +66,7 @@ Enhancements:
|
||||||
- #7421 Only load core after settings have fully loaded
|
- #7421 Only load core after settings have fully loaded
|
||||||
- #7419 Introduce 'Advanced' tab to Preferences window
|
- #7419 Introduce 'Advanced' tab to Preferences window
|
||||||
- #7422 Handle empty value for computer name setting
|
- #7422 Handle empty value for computer name setting
|
||||||
|
- #7423 Refactor local/global save/load and show dev thanks message
|
||||||
|
|
||||||
# 1.14.6
|
# 1.14.6
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -60,6 +60,11 @@ macro(configure_definitions)
|
||||||
add_definitions(-DSYNERGY_PRODUCT_NAME="${PRODUCT_NAME}")
|
add_definitions(-DSYNERGY_PRODUCT_NAME="${PRODUCT_NAME}")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
if(SHOW_DEV_THANKS)
|
||||||
|
message(STATUS "Enabling dev thanks message")
|
||||||
|
add_definitions(-DSYNERGY_SHOW_DEV_THANKS=1)
|
||||||
|
endif()
|
||||||
|
|
||||||
if(NOT CMAKE_BUILD_TYPE STREQUAL "Debug")
|
if(NOT CMAKE_BUILD_TYPE STREQUAL "Debug")
|
||||||
message(STATUS "Disabling debug build")
|
message(STATUS "Disabling debug build")
|
||||||
add_definitions(-DNDEBUG)
|
add_definitions(-DNDEBUG)
|
||||||
|
|
@ -108,6 +113,9 @@ macro(configure_options)
|
||||||
# licensing is off by default to make life easier for contributors.
|
# licensing is off by default to make life easier for contributors.
|
||||||
set(DEFAULT_ENABLE_LICENSING OFF)
|
set(DEFAULT_ENABLE_LICENSING OFF)
|
||||||
|
|
||||||
|
# by default, show the dev thanks message.
|
||||||
|
set(DEFAULT_SHOW_DEV_THANKS ON)
|
||||||
|
|
||||||
if("$ENV{SYNERGY_BUILD_MINIMAL}" STREQUAL "true")
|
if("$ENV{SYNERGY_BUILD_MINIMAL}" STREQUAL "true")
|
||||||
set(DEFAULT_BUILD_GUI OFF)
|
set(DEFAULT_BUILD_GUI OFF)
|
||||||
set(DEFAULT_BUILD_INSTALLER OFF)
|
set(DEFAULT_BUILD_INSTALLER OFF)
|
||||||
|
|
@ -129,11 +137,16 @@ macro(configure_options)
|
||||||
set(DEFAULT_ENABLE_COVERAGE ON)
|
set(DEFAULT_ENABLE_COVERAGE ON)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
if("$ENV{SYNERGY_SHOW_DEV_THANKS}" STREQUAL "false")
|
||||||
|
set(DEFAULT_SHOW_DEV_THANKS OFF)
|
||||||
|
endif()
|
||||||
|
|
||||||
option(BUILD_GUI "Build GUI" ${DEFAULT_BUILD_GUI})
|
option(BUILD_GUI "Build GUI" ${DEFAULT_BUILD_GUI})
|
||||||
option(BUILD_INSTALLER "Build installer" ${DEFAULT_BUILD_INSTALLER})
|
option(BUILD_INSTALLER "Build installer" ${DEFAULT_BUILD_INSTALLER})
|
||||||
option(BUILD_TESTS "Build tests" ${DEFAULT_BUILD_TESTS})
|
option(BUILD_TESTS "Build tests" ${DEFAULT_BUILD_TESTS})
|
||||||
option(BUILD_UNIFIED "Build unified binary" ${DEFAULT_BUILD_UNIFIED})
|
option(BUILD_UNIFIED "Build unified binary" ${DEFAULT_BUILD_UNIFIED})
|
||||||
option(ENABLE_LICENSING "Enable licensing" ${DEFAULT_ENABLE_LICENSING})
|
option(ENABLE_LICENSING "Enable licensing" ${DEFAULT_ENABLE_LICENSING})
|
||||||
option(ENABLE_COVERAGE "Enable test coverage" ${DEFAULT_ENABLE_COVERAGE})
|
option(ENABLE_COVERAGE "Enable test coverage" ${DEFAULT_ENABLE_COVERAGE})
|
||||||
|
option(SHOW_DEV_THANKS "Show dev thanks message" ${DEFAULT_SHOW_DEV_THANKS})
|
||||||
|
|
||||||
endmacro()
|
endmacro()
|
||||||
|
|
|
||||||
|
|
@ -24,23 +24,14 @@
|
||||||
#include "OSXHelpers.h"
|
#include "OSXHelpers.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef GIT_SHA_SHORT
|
#include "gui/version.h"
|
||||||
const QString kVersionAppend = GIT_SHA_SHORT;
|
|
||||||
#else
|
|
||||||
const QString kVersionAppend;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
AboutDialog::AboutDialog(MainWindow *parent, const AppConfig &config)
|
AboutDialog::AboutDialog(MainWindow *parent)
|
||||||
: QDialog(parent, Qt::WindowTitleHint | Qt::WindowSystemMenuHint),
|
: QDialog(parent, Qt::WindowTitleHint | Qt::WindowSystemMenuHint),
|
||||||
Ui::AboutDialogBase() {
|
Ui::AboutDialogBase() {
|
||||||
setupUi(this);
|
setupUi(this);
|
||||||
|
|
||||||
QString version(SYNERGY_VERSION);
|
m_pLabelSynergyVersion->setText(synergy::gui::version());
|
||||||
if (!kVersionAppend.isEmpty()) {
|
|
||||||
version.append(QString(" (%1)").arg(kVersionAppend));
|
|
||||||
}
|
|
||||||
|
|
||||||
m_pLabelSynergyVersion->setText(version);
|
|
||||||
|
|
||||||
QString buildDateString = QString::fromLocal8Bit(__DATE__).simplified();
|
QString buildDateString = QString::fromLocal8Bit(__DATE__).simplified();
|
||||||
QDate buildDate = QLocale("en_US").toDate(buildDateString, "MMM d yyyy");
|
QDate buildDate = QLocale("en_US").toDate(buildDateString, "MMM d yyyy");
|
||||||
|
|
|
||||||
|
|
@ -30,7 +30,7 @@ class QString;
|
||||||
class AboutDialog : public QDialog, public Ui::AboutDialogBase {
|
class AboutDialog : public QDialog, public Ui::AboutDialogBase {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
AboutDialog(MainWindow *parent, const AppConfig &config);
|
explicit AboutDialog(MainWindow *parent);
|
||||||
int exec() override;
|
int exec() override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
|
||||||
|
|
@ -23,6 +23,7 @@
|
||||||
#include "gui/LicenseHandler.h"
|
#include "gui/LicenseHandler.h"
|
||||||
#include "gui/constants.h"
|
#include "gui/constants.h"
|
||||||
#include "gui/license_notices.h"
|
#include "gui/license_notices.h"
|
||||||
|
#include "gui/styles.h"
|
||||||
#include "license/ProductEdition.h"
|
#include "license/ProductEdition.h"
|
||||||
#include "license/parse_serial_key.h"
|
#include "license/parse_serial_key.h"
|
||||||
#include "ui_ActivationDialog.h"
|
#include "ui_ActivationDialog.h"
|
||||||
|
|
@ -107,7 +108,6 @@ void ActivationDialog::accept() {
|
||||||
}
|
}
|
||||||
|
|
||||||
showSuccessDialog();
|
showSuccessDialog();
|
||||||
m_pAppConfig->setActivationHasRun(true);
|
|
||||||
QDialog::accept();
|
QDialog::accept();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -122,6 +122,7 @@ void ActivationDialog::showResultDialog(
|
||||||
QMessageBox::information(
|
QMessageBox::information(
|
||||||
this, title,
|
this, title,
|
||||||
"Heads up, the serial key you entered was the same as last time.");
|
"Heads up, the serial key you entered was the same as last time.");
|
||||||
|
QDialog::accept();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case kInvalid:
|
case kInvalid:
|
||||||
|
|
|
||||||
|
|
@ -22,11 +22,14 @@
|
||||||
#include "ActivationDialog.h"
|
#include "ActivationDialog.h"
|
||||||
#include "ServerConfigDialog.h"
|
#include "ServerConfigDialog.h"
|
||||||
#include "SettingsDialog.h"
|
#include "SettingsDialog.h"
|
||||||
|
#include "gui/ConfigScopes.h"
|
||||||
#include "gui/LicenseHandler.h"
|
#include "gui/LicenseHandler.h"
|
||||||
#include "gui/TlsFingerprint.h"
|
#include "gui/TlsFingerprint.h"
|
||||||
#include "gui/VersionChecker.h"
|
#include "gui/VersionChecker.h"
|
||||||
#include "gui/constants.h"
|
#include "gui/constants.h"
|
||||||
#include "gui/license_notices.h"
|
#include "gui/license_notices.h"
|
||||||
|
#include "gui/messages.h"
|
||||||
|
#include "gui/styles.h"
|
||||||
#include "license/License.h"
|
#include "license/License.h"
|
||||||
|
|
||||||
#if defined(Q_OS_MAC)
|
#if defined(Q_OS_MAC)
|
||||||
|
|
@ -58,12 +61,6 @@ using namespace synergy::license;
|
||||||
static const int kRetryDelay = 1000;
|
static const int kRetryDelay = 1000;
|
||||||
static const int kDebugLogLevel = 1;
|
static const int kDebugLogLevel = 1;
|
||||||
|
|
||||||
#ifdef SYNERGY_PRODUCT_NAME
|
|
||||||
const QString kProductName = SYNERGY_PRODUCT_NAME;
|
|
||||||
#else
|
|
||||||
const QString kProductName;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(Q_OS_MAC)
|
#if defined(Q_OS_MAC)
|
||||||
|
|
||||||
static const char *const kLightIconFiles[] = {
|
static const char *const kLightIconFiles[] = {
|
||||||
|
|
@ -89,9 +86,10 @@ static const char *const kDefaultIconFiles[] = {
|
||||||
":/res/icons/16x16/synergy-transfering.png",
|
":/res/icons/16x16/synergy-transfering.png",
|
||||||
":/res/icons/16x16/synergy-disconnected.png"};
|
":/res/icons/16x16/synergy-disconnected.png"};
|
||||||
|
|
||||||
MainWindow::MainWindow(AppConfig &appConfig)
|
MainWindow::MainWindow(ConfigScopes &configScopes, AppConfig &appConfig)
|
||||||
: m_AppConfig(appConfig),
|
: m_ConfigScopes(configScopes),
|
||||||
m_ServerConfig(5, 3, &m_AppConfig, this),
|
m_AppConfig(appConfig),
|
||||||
|
m_ServerConfig(appConfig, *this),
|
||||||
m_ServerConnection(*this),
|
m_ServerConnection(*this),
|
||||||
m_ClientConnection(*this),
|
m_ClientConnection(*this),
|
||||||
m_TlsUtility(appConfig, m_LicenseHandler.license()),
|
m_TlsUtility(appConfig, m_LicenseHandler.license()),
|
||||||
|
|
@ -101,21 +99,13 @@ MainWindow::MainWindow(AppConfig &appConfig)
|
||||||
setupControls();
|
setupControls();
|
||||||
connectSlots();
|
connectSlots();
|
||||||
|
|
||||||
#if defined(Q_OS_WIN)
|
// handled by `onCreated`
|
||||||
|
|
||||||
// TODO: only connect permenantly to ipc when switching to service mode.
|
|
||||||
// if switching from service to desktop, connect only to stop the service
|
|
||||||
// and don't retry.
|
|
||||||
m_IpcClient.connectToHost();
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
emit created();
|
emit created();
|
||||||
}
|
}
|
||||||
|
|
||||||
MainWindow::~MainWindow() {
|
MainWindow::~MainWindow() {
|
||||||
try {
|
try {
|
||||||
if (appConfig().processMode() == ProcessMode::kDesktop) {
|
if (m_AppConfig.processMode() == ProcessMode::kDesktop) {
|
||||||
m_ExpectedRunningState = RuningState::Stopped;
|
m_ExpectedRunningState = RuningState::Stopped;
|
||||||
stopDesktop();
|
stopDesktop();
|
||||||
}
|
}
|
||||||
|
|
@ -132,18 +122,16 @@ MainWindow::~MainWindow() {
|
||||||
|
|
||||||
void MainWindow::restoreWindow() {
|
void MainWindow::restoreWindow() {
|
||||||
|
|
||||||
const auto &config = appConfig();
|
const auto &windowSize = m_AppConfig.mainWindowSize();
|
||||||
|
if (windowSize.has_value()) {
|
||||||
const auto &size = config.mainWindowSize();
|
|
||||||
if (size.has_value()) {
|
|
||||||
qDebug("restoring main window size");
|
qDebug("restoring main window size");
|
||||||
resize(size.value());
|
resize(windowSize.value());
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto &position = config.mainWindowPosition();
|
const auto &windowPosition = m_AppConfig.mainWindowPosition();
|
||||||
if (position.has_value()) {
|
if (windowPosition.has_value()) {
|
||||||
qDebug("restoring main window position");
|
qDebug("restoring main window position");
|
||||||
move(position.value());
|
move(windowPosition.value());
|
||||||
}
|
}
|
||||||
|
|
||||||
// give the window chance to restore its size and position before the window
|
// give the window chance to restore its size and position before the window
|
||||||
|
|
@ -159,10 +147,9 @@ void MainWindow::saveWindow() {
|
||||||
}
|
}
|
||||||
|
|
||||||
qDebug("saving window size and position");
|
qDebug("saving window size and position");
|
||||||
auto &config = appConfig();
|
m_AppConfig.setMainWindowSize(size());
|
||||||
config.setMainWindowSize(size());
|
m_AppConfig.setMainWindowPosition(pos());
|
||||||
config.setMainWindowPosition(pos());
|
m_ConfigScopes.save();
|
||||||
config.saveSettings();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::setupControls() {
|
void MainWindow::setupControls() {
|
||||||
|
|
@ -210,7 +197,8 @@ void MainWindow::connectSlots() const {
|
||||||
Qt::QueuedConnection);
|
Qt::QueuedConnection);
|
||||||
|
|
||||||
connect(
|
connect(
|
||||||
&m_AppConfig, &AppConfig::loaded, this, &MainWindow::onAppConfigLoaded);
|
&m_ConfigScopes, &ConfigScopes::saving, this,
|
||||||
|
&MainWindow::onConfigScopesSaving, Qt::DirectConnection);
|
||||||
|
|
||||||
connect(
|
connect(
|
||||||
&m_AppConfig, &AppConfig::tlsChanged, this,
|
&m_AppConfig, &AppConfig::tlsChanged, this,
|
||||||
|
|
@ -267,20 +255,30 @@ void MainWindow::connectSlots() const {
|
||||||
&MainWindow::onWindowSaveTimerTimeout);
|
&MainWindow::onWindowSaveTimerTimeout);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::onAppAboutToQuit() { m_AppConfig.saveSettings(); }
|
void MainWindow::onAppAboutToQuit() { m_ConfigScopes.save(); }
|
||||||
|
|
||||||
void MainWindow::onCreated() {
|
void MainWindow::onCreated() {
|
||||||
// it may seem a bit over-complicated to load the app config through a
|
|
||||||
// signal/slot, but there is a good reason: intentionality; we want to
|
|
||||||
// ensure that the ctor is fully executed before we start loading the
|
|
||||||
// app config. a signal is the clearest way to communicate this.
|
|
||||||
m_AppConfig.loadAllScopes();
|
|
||||||
|
|
||||||
const auto serverEnabled = appConfig().serverGroupChecked();
|
#if defined(Q_OS_WIN)
|
||||||
const auto clientEnabled = appConfig().clientGroupChecked();
|
|
||||||
if (serverEnabled || clientEnabled) {
|
// TODO: only connect permenantly to ipc when switching to service mode.
|
||||||
startCore();
|
// if switching from service to desktop, connect only to stop the service
|
||||||
|
// and don't retry.
|
||||||
|
m_IpcClient.connectToHost();
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
m_ConfigScopes.signalReady();
|
||||||
|
|
||||||
|
applyCloseToTray();
|
||||||
|
|
||||||
|
if (kLicensingEnabled && !m_AppConfig.serialKey().isEmpty()) {
|
||||||
|
m_LicenseHandler.changeSerialKey(m_AppConfig.serialKey());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
updateScreenName();
|
||||||
|
applyConfig();
|
||||||
|
restoreWindow();
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::onShown() {
|
void MainWindow::onShown() {
|
||||||
|
|
@ -299,7 +297,7 @@ void MainWindow::onLicenseHandlerSerialKeyChanged(const QString &serialKey) {
|
||||||
|
|
||||||
if (m_AppConfig.serialKey() != serialKey) {
|
if (m_AppConfig.serialKey() != serialKey) {
|
||||||
m_AppConfig.setSerialKey(serialKey);
|
m_AppConfig.setSerialKey(serialKey);
|
||||||
m_AppConfig.saveSettings();
|
m_ConfigScopes.save();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -308,16 +306,7 @@ void MainWindow::onLicenseHandlerInvalidLicense() {
|
||||||
showActivationDialog();
|
showActivationDialog();
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::onAppConfigLoaded() {
|
void MainWindow::onConfigScopesSaving() { m_ServerConfig.commit(); }
|
||||||
QApplication::setQuitOnLastWindowClosed(!m_AppConfig.closeToTray());
|
|
||||||
if (!m_AppConfig.serialKey().isEmpty()) {
|
|
||||||
m_LicenseHandler.changeSerialKey(m_AppConfig.serialKey());
|
|
||||||
}
|
|
||||||
|
|
||||||
updateScreenName();
|
|
||||||
applyConfig();
|
|
||||||
restoreWindow();
|
|
||||||
}
|
|
||||||
|
|
||||||
void MainWindow::onAppConfigTlsChanged() {
|
void MainWindow::onAppConfigTlsChanged() {
|
||||||
updateLocalFingerprint();
|
updateLocalFingerprint();
|
||||||
|
|
@ -421,7 +410,7 @@ bool MainWindow::on_m_pActionSave_triggered() {
|
||||||
QString fileName =
|
QString fileName =
|
||||||
QFileDialog::getSaveFileName(this, QString("Save configuration as..."));
|
QFileDialog::getSaveFileName(this, QString("Save configuration as..."));
|
||||||
|
|
||||||
if (!fileName.isEmpty() && !serverConfig().save(fileName)) {
|
if (!fileName.isEmpty() && !m_ServerConfig.save(fileName)) {
|
||||||
QMessageBox::warning(
|
QMessageBox::warning(
|
||||||
this, QString("Save failed"),
|
this, QString("Save failed"),
|
||||||
QString("Could not save configuration to file."));
|
QString("Could not save configuration to file."));
|
||||||
|
|
@ -432,8 +421,8 @@ bool MainWindow::on_m_pActionSave_triggered() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::on_m_pActionAbout_triggered() {
|
void MainWindow::on_m_pActionAbout_triggered() {
|
||||||
AboutDialog dlg(this, appConfig());
|
AboutDialog about(this);
|
||||||
dlg.exec();
|
about.exec();
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::on_m_pActionHelp_triggered() {
|
void MainWindow::on_m_pActionHelp_triggered() {
|
||||||
|
|
@ -442,13 +431,14 @@ void MainWindow::on_m_pActionHelp_triggered() {
|
||||||
|
|
||||||
void MainWindow::on_m_pActionSettings_triggered() {
|
void MainWindow::on_m_pActionSettings_triggered() {
|
||||||
auto result =
|
auto result =
|
||||||
SettingsDialog(this, appConfig(), m_LicenseHandler.license()).exec();
|
SettingsDialog(this, m_AppConfig, m_LicenseHandler.license()).exec();
|
||||||
if (result == QDialog::Accepted) {
|
if (result == QDialog::Accepted) {
|
||||||
enableServer(appConfig().serverGroupChecked());
|
m_ConfigScopes.save();
|
||||||
enableClient(appConfig().clientGroupChecked());
|
|
||||||
auto state = m_CoreState;
|
applyConfig();
|
||||||
if ((state == CoreState::Connected) || (state == CoreState::Connecting) ||
|
applyCloseToTray();
|
||||||
(state == CoreState::Listening)) {
|
|
||||||
|
if (isCoreActive()) {
|
||||||
restartCore();
|
restartCore();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -460,6 +450,14 @@ void MainWindow::on_m_pButtonConfigureServer_clicked() {
|
||||||
|
|
||||||
void MainWindow::on_m_pActivate_triggered() { showActivationDialog(); }
|
void MainWindow::on_m_pActivate_triggered() { showActivationDialog(); }
|
||||||
|
|
||||||
|
void MainWindow::on_m_pLineEditHostname_returnPressed() {
|
||||||
|
m_pButtonConnect->click();
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::on_m_pLineEditClientIp_returnPressed() {
|
||||||
|
m_pButtonConnectToClient->click();
|
||||||
|
}
|
||||||
|
|
||||||
void MainWindow::on_m_pButtonApply_clicked() {
|
void MainWindow::on_m_pButtonApply_clicked() {
|
||||||
m_ClientConnection.setCheckConnection(true);
|
m_ClientConnection.setCheckConnection(true);
|
||||||
restartCore();
|
restartCore();
|
||||||
|
|
@ -477,13 +475,13 @@ void MainWindow::on_m_pLabelFingerprint_linkActivated(const QString &) {
|
||||||
void MainWindow::on_m_pRadioGroupServer_clicked(bool) {
|
void MainWindow::on_m_pRadioGroupServer_clicked(bool) {
|
||||||
enableServer(true);
|
enableServer(true);
|
||||||
enableClient(false);
|
enableClient(false);
|
||||||
m_AppConfig.saveSettings();
|
m_ConfigScopes.save();
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::on_m_pRadioGroupClient_clicked(bool) {
|
void MainWindow::on_m_pRadioGroupClient_clicked(bool) {
|
||||||
enableClient(true);
|
enableClient(true);
|
||||||
enableServer(false);
|
enableServer(false);
|
||||||
m_AppConfig.saveSettings();
|
m_ConfigScopes.save();
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::on_m_pButtonConnect_clicked() { on_m_pButtonApply_clicked(); }
|
void MainWindow::on_m_pButtonConnect_clicked() { on_m_pButtonApply_clicked(); }
|
||||||
|
|
@ -527,7 +525,7 @@ void MainWindow::open() {
|
||||||
setIcon(CoreState::Disconnected);
|
setIcon(CoreState::Disconnected);
|
||||||
});
|
});
|
||||||
|
|
||||||
if (appConfig().autoHide()) {
|
if (m_AppConfig.autoHide()) {
|
||||||
hide();
|
hide();
|
||||||
} else {
|
} else {
|
||||||
showNormal();
|
showNormal();
|
||||||
|
|
@ -538,8 +536,8 @@ void MainWindow::open() {
|
||||||
// only start if user has previously started. this stops the gui from
|
// only start if user has previously started. this stops the gui from
|
||||||
// auto hiding before the user has configured synergy (which of course
|
// auto hiding before the user has configured synergy (which of course
|
||||||
// confuses first time users, who think synergy has crashed).
|
// confuses first time users, who think synergy has crashed).
|
||||||
if (appConfig().startedBefore() &&
|
if (m_AppConfig.startedBefore() &&
|
||||||
appConfig().processMode() == ProcessMode::kDesktop) {
|
m_AppConfig.processMode() == ProcessMode::kDesktop) {
|
||||||
startCore();
|
startCore();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -580,20 +578,24 @@ void MainWindow::createMenuBar() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::applyConfig() {
|
void MainWindow::applyConfig() {
|
||||||
enableServer(appConfig().serverGroupChecked());
|
enableServer(m_AppConfig.serverGroupChecked());
|
||||||
enableClient(appConfig().clientGroupChecked());
|
enableClient(m_AppConfig.clientGroupChecked());
|
||||||
|
|
||||||
m_pLineEditHostname->setText(appConfig().serverHostname());
|
m_pLineEditHostname->setText(m_AppConfig.serverHostname());
|
||||||
m_pLineEditClientIp->setText(serverConfig().getClientAddress());
|
m_pLineEditClientIp->setText(m_ServerConfig.getClientAddress());
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::applyCloseToTray() const {
|
||||||
|
QApplication::setQuitOnLastWindowClosed(!m_AppConfig.closeToTray());
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::saveSettings() {
|
void MainWindow::saveSettings() {
|
||||||
appConfig().setServerGroupChecked(m_pRadioGroupServer->isChecked());
|
m_AppConfig.setServerGroupChecked(m_pRadioGroupServer->isChecked());
|
||||||
appConfig().setClientGroupChecked(m_pRadioGroupClient->isChecked());
|
m_AppConfig.setClientGroupChecked(m_pRadioGroupClient->isChecked());
|
||||||
appConfig().setServerHostname(m_pLineEditHostname->text());
|
m_AppConfig.setServerHostname(m_pLineEditHostname->text());
|
||||||
serverConfig().setClientAddress(m_pLineEditClientIp->text());
|
m_ServerConfig.setClientAddress(m_pLineEditClientIp->text());
|
||||||
|
|
||||||
appConfig().scopes().saveAll();
|
m_ConfigScopes.save();
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::setIcon(CoreState state) const {
|
void MainWindow::setIcon(CoreState state) const {
|
||||||
|
|
@ -622,19 +624,22 @@ void MainWindow::setIcon(CoreState state) const {
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::appendLogInfo(const QString &text) {
|
void MainWindow::appendLogInfo(const QString &text) {
|
||||||
|
qInfo("%s", text.toStdString().c_str());
|
||||||
|
|
||||||
processCoreLogLine(getTimeStamp() + " INFO: " + text);
|
processCoreLogLine(getTimeStamp() + " INFO: " + text);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::appendLogDebug(const QString &text) {
|
void MainWindow::appendLogDebug(const QString &text) {
|
||||||
qDebug("%s", text.toStdString().c_str());
|
qDebug("%s", text.toStdString().c_str());
|
||||||
|
|
||||||
if (appConfig().logLevel() >= kDebugLogLevel) {
|
if (m_AppConfig.logLevel() >= kDebugLogLevel) {
|
||||||
processCoreLogLine(getTimeStamp() + " DEBUG: " + text);
|
processCoreLogLine(getTimeStamp() + " DEBUG: " + text);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::appendLogError(const QString &text) {
|
void MainWindow::appendLogError(const QString &text) {
|
||||||
onIpcClientReadLogLine(getTimeStamp() + " ERROR: " + text);
|
qCritical("%s", text.toStdString().c_str());
|
||||||
|
processCoreLogLine(getTimeStamp() + " ERROR: " + text);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::processCoreLogLine(const QString &text) {
|
void MainWindow::processCoreLogLine(const QString &text) {
|
||||||
|
|
@ -644,7 +649,7 @@ void MainWindow::processCoreLogLine(const QString &text) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// only start if there is no active service running
|
// only start if there is no active service running
|
||||||
if (line.contains("service status: idle") && appConfig().startedBefore()) {
|
if (line.contains("service status: idle") && m_AppConfig.startedBefore()) {
|
||||||
startCore();
|
startCore();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -689,15 +694,11 @@ void MainWindow::checkConnected(const QString &line) {
|
||||||
if (line.contains("connected to server") || line.contains("has connected")) {
|
if (line.contains("connected to server") || line.contains("has connected")) {
|
||||||
setCoreState(CoreState::Connected);
|
setCoreState(CoreState::Connected);
|
||||||
|
|
||||||
if (!appConfig().startedBefore() && isVisible()) {
|
if (isVisible()) {
|
||||||
QMessageBox::information(
|
showFirstRunMessage();
|
||||||
this, "Synergy",
|
showDevThanksMessage();
|
||||||
QString("Synergy is now connected. You can close the "
|
|
||||||
"config window and Synergy will remain connected in "
|
|
||||||
"the background."));
|
|
||||||
|
|
||||||
appConfig().setStartedBefore(true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} else if (line.contains("started server")) {
|
} else if (line.contains("started server")) {
|
||||||
setCoreState(CoreState::Listening);
|
setCoreState(CoreState::Listening);
|
||||||
} else if (
|
} else if (
|
||||||
|
|
@ -803,8 +804,53 @@ void MainWindow::showEvent(QShowEvent *event) {
|
||||||
emit shown();
|
emit shown();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MainWindow::closeEvent(QCloseEvent *event) {
|
||||||
|
if (!m_AppConfig.closeToTray()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
qDebug("window will hide to tray");
|
||||||
|
if (!m_AppConfig.showCloseReminder()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
messages::showCloseReminder(this);
|
||||||
|
m_AppConfig.setShowCloseReminder(false);
|
||||||
|
m_ConfigScopes.save();
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::showFirstRunMessage() {
|
||||||
|
if (m_AppConfig.startedBefore()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_AppConfig.setStartedBefore(true);
|
||||||
|
m_ConfigScopes.save();
|
||||||
|
|
||||||
|
const auto isServer = coreMode() == CoreMode::Server;
|
||||||
|
messages::showFirstRunMessage(
|
||||||
|
this, m_AppConfig.closeToTray(), m_AppConfig.enableService(), isServer);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::showDevThanksMessage() {
|
||||||
|
if (!m_AppConfig.showDevThanks()) {
|
||||||
|
qDebug("skipping dev thanks message, disabled in settings");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (kLicensingEnabled) {
|
||||||
|
qDebug("licensing enabled, skipping dev thanks message");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_AppConfig.setShowDevThanks(false);
|
||||||
|
m_ConfigScopes.save();
|
||||||
|
|
||||||
|
messages::showDevThanks(this, kProductName);
|
||||||
|
}
|
||||||
|
|
||||||
void MainWindow::startCore() {
|
void MainWindow::startCore() {
|
||||||
appendLogDebug("starting core process");
|
appendLogInfo(QString("starting core %1 process").arg(coreModeString()));
|
||||||
|
|
||||||
saveSettings();
|
saveSettings();
|
||||||
|
|
||||||
|
|
@ -828,11 +874,11 @@ void MainWindow::startCore() {
|
||||||
|
|
||||||
args << "-f"
|
args << "-f"
|
||||||
<< "--no-tray"
|
<< "--no-tray"
|
||||||
<< "--debug" << appConfig().logLevelText();
|
<< "--debug" << m_AppConfig.logLevelText();
|
||||||
|
|
||||||
args << "--name" << appConfig().screenName();
|
args << "--name" << m_AppConfig.screenName();
|
||||||
|
|
||||||
ProcessMode mode = appConfig().processMode();
|
ProcessMode mode = m_AppConfig.processMode();
|
||||||
|
|
||||||
if (mode == ProcessMode::kDesktop) {
|
if (mode == ProcessMode::kDesktop) {
|
||||||
m_pCoreProcess = std::make_unique<QProcess>(this);
|
m_pCoreProcess = std::make_unique<QProcess>(this);
|
||||||
|
|
@ -850,7 +896,7 @@ void MainWindow::startCore() {
|
||||||
// unnecessary restarts when synergy was started elevated or
|
// unnecessary restarts when synergy was started elevated or
|
||||||
// when it is not allowed to elevate. In these cases restarting
|
// when it is not allowed to elevate. In these cases restarting
|
||||||
// the server is fruitless.
|
// the server is fruitless.
|
||||||
if (appConfig().elevateMode() == ElevateAsNeeded) {
|
if (m_AppConfig.elevateMode() == ElevateAsNeeded) {
|
||||||
args << "--stop-on-desk-switch";
|
args << "--stop-on-desk-switch";
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -896,10 +942,6 @@ void MainWindow::startCore() {
|
||||||
if (!m_pLogOutput->toPlainText().isEmpty())
|
if (!m_pLogOutput->toPlainText().isEmpty())
|
||||||
onIpcClientReadLogLine("");
|
onIpcClientReadLogLine("");
|
||||||
|
|
||||||
appendLogInfo(
|
|
||||||
"starting " +
|
|
||||||
QString(coreMode() == CoreMode::Server ? "server" : "client"));
|
|
||||||
|
|
||||||
if ((coreMode() == CoreMode::Client && !clientArgs(args, app)) ||
|
if ((coreMode() == CoreMode::Client && !clientArgs(args, app)) ||
|
||||||
(coreMode() == CoreMode::Server && !serverArgs(args, app))) {
|
(coreMode() == CoreMode::Server && !serverArgs(args, app))) {
|
||||||
onActionStopCoreTriggered();
|
onActionStopCoreTriggered();
|
||||||
|
|
@ -918,15 +960,14 @@ void MainWindow::startCore() {
|
||||||
&MainWindow::onCoreProcessReadyReadStandardError);
|
&MainWindow::onCoreProcessReadyReadStandardError);
|
||||||
}
|
}
|
||||||
|
|
||||||
// show command if debug log level...
|
if (m_AppConfig.logLevel() >= kDebugLogLevel) {
|
||||||
if (appConfig().logLevel() >= 4) {
|
|
||||||
appendLogInfo(QString("command: %1 %2").arg(app, args.join(" ")));
|
appendLogInfo(QString("command: %1 %2").arg(app, args.join(" ")));
|
||||||
}
|
}
|
||||||
|
|
||||||
appendLogInfo("log level: " + appConfig().logLevelText());
|
appendLogInfo("log level: " + m_AppConfig.logLevelText());
|
||||||
|
|
||||||
if (appConfig().logToFile())
|
if (m_AppConfig.logToFile())
|
||||||
appendLogInfo("log file: " + appConfig().logFilename());
|
appendLogInfo("log file: " + m_AppConfig.logFilename());
|
||||||
|
|
||||||
if (mode == ProcessMode::kDesktop) {
|
if (mode == ProcessMode::kDesktop) {
|
||||||
m_pCoreProcess->start(app, args);
|
m_pCoreProcess->start(app, args);
|
||||||
|
|
@ -944,12 +985,12 @@ void MainWindow::startCore() {
|
||||||
}
|
}
|
||||||
} else if (mode == ProcessMode::kService) {
|
} else if (mode == ProcessMode::kService) {
|
||||||
QString command(app + " " + args.join(" "));
|
QString command(app + " " + args.join(" "));
|
||||||
m_IpcClient.sendCommand(command, appConfig().elevateMode());
|
m_IpcClient.sendCommand(command, m_AppConfig.elevateMode());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MainWindow::clientArgs(QStringList &args, QString &app) {
|
bool MainWindow::clientArgs(QStringList &args, QString &app) {
|
||||||
app = appPath(appConfig().coreClientName());
|
app = appPath(m_AppConfig.coreClientName());
|
||||||
|
|
||||||
if (!QFile::exists(app)) {
|
if (!QFile::exists(app)) {
|
||||||
show();
|
show();
|
||||||
|
|
@ -959,22 +1000,22 @@ bool MainWindow::clientArgs(QStringList &args, QString &app) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (appConfig().logToFile()) {
|
if (m_AppConfig.logToFile()) {
|
||||||
appConfig().persistLogDir();
|
m_AppConfig.persistLogDir();
|
||||||
args << "--log" << appConfig().logFilename();
|
args << "--log" << m_AppConfig.logFilename();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (appConfig().languageSync()) {
|
if (m_AppConfig.languageSync()) {
|
||||||
args << "--sync-language";
|
args << "--sync-language";
|
||||||
}
|
}
|
||||||
|
|
||||||
if (appConfig().invertScrollDirection()) {
|
if (m_AppConfig.invertScrollDirection()) {
|
||||||
args << "--invert-scroll";
|
args << "--invert-scroll";
|
||||||
}
|
}
|
||||||
|
|
||||||
if (appConfig().invertConnection()) {
|
if (m_AppConfig.invertConnection()) {
|
||||||
args << "--host";
|
args << "--host";
|
||||||
args << ":" + QString::number(appConfig().port());
|
args << ":" + QString::number(m_AppConfig.port());
|
||||||
} else {
|
} else {
|
||||||
if (m_pLineEditHostname->text().isEmpty()) {
|
if (m_pLineEditHostname->text().isEmpty()) {
|
||||||
show();
|
show();
|
||||||
|
|
@ -994,7 +1035,7 @@ bool MainWindow::clientArgs(QStringList &args, QString &app) {
|
||||||
hostName.push_back(']');
|
hostName.push_back(']');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
args << hostName + ":" + QString::number(appConfig().port());
|
args << hostName + ":" + QString::number(m_AppConfig.port());
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|
@ -1002,8 +1043,8 @@ bool MainWindow::clientArgs(QStringList &args, QString &app) {
|
||||||
|
|
||||||
QString MainWindow::configFilename() {
|
QString MainWindow::configFilename() {
|
||||||
QString configFullPath;
|
QString configFullPath;
|
||||||
if (appConfig().useExternalConfig()) {
|
if (m_AppConfig.useExternalConfig()) {
|
||||||
configFullPath = appConfig().configFile();
|
configFullPath = m_AppConfig.configFile();
|
||||||
} else {
|
} else {
|
||||||
QStringList errors;
|
QStringList errors;
|
||||||
for (auto path :
|
for (auto path :
|
||||||
|
|
@ -1023,7 +1064,7 @@ QString MainWindow::configFilename() {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
serverConfig().save(configFile);
|
m_ServerConfig.save(configFile);
|
||||||
configFile.close();
|
configFile.close();
|
||||||
configFullPath = configFile.fileName();
|
configFullPath = configFile.fileName();
|
||||||
|
|
||||||
|
|
@ -1040,7 +1081,7 @@ QString MainWindow::configFilename() {
|
||||||
}
|
}
|
||||||
|
|
||||||
QString MainWindow::address() const {
|
QString MainWindow::address() const {
|
||||||
QString i = appConfig().networkInterface();
|
QString i = m_AppConfig.networkInterface();
|
||||||
// if interface is IPv6 - ensure that ip is in square brackets
|
// if interface is IPv6 - ensure that ip is in square brackets
|
||||||
if (i.count(':') > 1) {
|
if (i.count(':') > 1) {
|
||||||
if (i[0] != '[') {
|
if (i[0] != '[') {
|
||||||
|
|
@ -1050,7 +1091,7 @@ QString MainWindow::address() const {
|
||||||
i.push_back(']');
|
i.push_back(']');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return (!i.isEmpty() ? i : "") + ":" + QString::number(appConfig().port());
|
return (!i.isEmpty() ? i : "") + ":" + QString::number(m_AppConfig.port());
|
||||||
}
|
}
|
||||||
|
|
||||||
QString MainWindow::appPath(const QString &name) const {
|
QString MainWindow::appPath(const QString &name) const {
|
||||||
|
|
@ -1059,7 +1100,7 @@ QString MainWindow::appPath(const QString &name) const {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MainWindow::serverArgs(QStringList &args, QString &app) {
|
bool MainWindow::serverArgs(QStringList &args, QString &app) {
|
||||||
app = appPath(appConfig().coreServerName());
|
app = appPath(m_AppConfig.coreServerName());
|
||||||
|
|
||||||
if (!QFile::exists(app)) {
|
if (!QFile::exists(app)) {
|
||||||
QMessageBox::warning(
|
QMessageBox::warning(
|
||||||
|
|
@ -1068,17 +1109,17 @@ bool MainWindow::serverArgs(QStringList &args, QString &app) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (appConfig().invertConnection() && m_pLineEditClientIp->text().isEmpty()) {
|
if (m_AppConfig.invertConnection() && m_pLineEditClientIp->text().isEmpty()) {
|
||||||
QMessageBox::warning(
|
QMessageBox::warning(
|
||||||
this, QString("Client IP address or name is empty"),
|
this, QString("Client IP address or name is empty"),
|
||||||
QString("Please fill in a client IP address or name."));
|
QString("Please fill in a client IP address or name."));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (appConfig().logToFile()) {
|
if (m_AppConfig.logToFile()) {
|
||||||
appConfig().persistLogDir();
|
m_AppConfig.persistLogDir();
|
||||||
|
|
||||||
args << "--log" << appConfig().logFilename();
|
args << "--log" << m_AppConfig.logFilename();
|
||||||
}
|
}
|
||||||
|
|
||||||
QString configFilename = this->configFilename();
|
QString configFilename = this->configFilename();
|
||||||
|
|
@ -1089,8 +1130,8 @@ bool MainWindow::serverArgs(QStringList &args, QString &app) {
|
||||||
args << "-c" << configFilename << "--address" << address();
|
args << "-c" << configFilename << "--address" << address();
|
||||||
appendLogInfo("config file: " + configFilename);
|
appendLogInfo("config file: " + configFilename);
|
||||||
|
|
||||||
if (kLicensingEnabled && !appConfig().serialKey().isEmpty()) {
|
if (kLicensingEnabled && !m_AppConfig.serialKey().isEmpty()) {
|
||||||
args << "--serial-key" << appConfig().serialKey();
|
args << "--serial-key" << m_AppConfig.serialKey();
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|
@ -1101,9 +1142,9 @@ void MainWindow::stopCore() {
|
||||||
|
|
||||||
m_ExpectedRunningState = RuningState::Stopped;
|
m_ExpectedRunningState = RuningState::Stopped;
|
||||||
|
|
||||||
if (appConfig().processMode() == ProcessMode::kService) {
|
if (m_AppConfig.processMode() == ProcessMode::kService) {
|
||||||
stopService();
|
stopService();
|
||||||
} else if (appConfig().processMode() == ProcessMode::kDesktop) {
|
} else if (m_AppConfig.processMode() == ProcessMode::kDesktop) {
|
||||||
stopDesktop();
|
stopDesktop();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1115,7 +1156,7 @@ void MainWindow::stopCore() {
|
||||||
|
|
||||||
void MainWindow::stopService() {
|
void MainWindow::stopService() {
|
||||||
// send empty command to stop service from laucning anything.
|
// send empty command to stop service from laucning anything.
|
||||||
m_IpcClient.sendCommand("", appConfig().elevateMode());
|
m_IpcClient.sendCommand("", m_AppConfig.elevateMode());
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::stopDesktop() {
|
void MainWindow::stopDesktop() {
|
||||||
|
|
@ -1229,8 +1270,31 @@ void MainWindow::setVisible(bool visible) {
|
||||||
}
|
}
|
||||||
|
|
||||||
MainWindow::CoreMode MainWindow::coreMode() const {
|
MainWindow::CoreMode MainWindow::coreMode() const {
|
||||||
auto isClient = m_pRadioGroupClient->isChecked();
|
using enum CoreMode;
|
||||||
return isClient ? CoreMode::Client : CoreMode::Server;
|
|
||||||
|
auto serverChecked = m_pRadioGroupServer->isChecked();
|
||||||
|
auto clientChecked = m_pRadioGroupClient->isChecked();
|
||||||
|
|
||||||
|
if (serverChecked) {
|
||||||
|
return Server;
|
||||||
|
} else if (clientChecked) {
|
||||||
|
return Client;
|
||||||
|
} else {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
QString MainWindow::coreModeString() const {
|
||||||
|
using enum CoreMode;
|
||||||
|
|
||||||
|
switch (coreMode()) {
|
||||||
|
case Server:
|
||||||
|
return "server";
|
||||||
|
case Client:
|
||||||
|
return "client";
|
||||||
|
default:
|
||||||
|
qFatal("invalid core mode");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
QString MainWindow::getIPAddresses() const {
|
QString MainWindow::getIPAddresses() const {
|
||||||
|
|
@ -1291,22 +1355,22 @@ void MainWindow::updateLocalFingerprint() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
LicenseHandler &MainWindow::licenseHandler() { return m_LicenseHandler; }
|
QString MainWindow::productName() const {
|
||||||
|
|
||||||
void MainWindow::updateWindowTitle() {
|
|
||||||
if (kLicensingEnabled) {
|
if (kLicensingEnabled) {
|
||||||
setWindowTitle(m_LicenseHandler.productName());
|
return m_LicenseHandler.productName();
|
||||||
|
} else if (!kProductName.isEmpty()) {
|
||||||
|
return kProductName;
|
||||||
} else {
|
} else {
|
||||||
setWindowTitle(kProductName);
|
qFatal("product name not set");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MainWindow::updateWindowTitle() { setWindowTitle(productName()); }
|
||||||
|
|
||||||
void MainWindow::autoAddScreen(const QString name) {
|
void MainWindow::autoAddScreen(const QString name) {
|
||||||
|
|
||||||
if (m_ActivationDialogRunning) {
|
if (m_ActivationDialogRunning) {
|
||||||
// TODO: refactor this code
|
// add this screen to the pending list if the activation dialog is running.
|
||||||
// add this screen to the pending list and check this list until
|
|
||||||
// users finish activation dialog
|
|
||||||
m_PendingClientNames.append(name);
|
m_PendingClientNames.append(name);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -1316,7 +1380,7 @@ void MainWindow::autoAddScreen(const QString name) {
|
||||||
switch (r) {
|
switch (r) {
|
||||||
case kAutoAddScreenManualServer:
|
case kAutoAddScreenManualServer:
|
||||||
showConfigureServer(QString("Please add the server (%1) to the grid.")
|
showConfigureServer(QString("Please add the server (%1) to the grid.")
|
||||||
.arg(appConfig().screenName()));
|
.arg(m_AppConfig.screenName()));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case kAutoAddScreenManualClient:
|
case kAutoAddScreenManualClient:
|
||||||
|
|
@ -1328,18 +1392,18 @@ void MainWindow::autoAddScreen(const QString name) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::showConfigureServer(const QString &message) {
|
bool MainWindow::isCoreActive() const {
|
||||||
using enum CoreState;
|
using enum CoreState;
|
||||||
|
|
||||||
ServerConfigDialog dlg(this, serverConfig(), appConfig());
|
auto state = m_CoreState;
|
||||||
dlg.message(message);
|
return (state == Connected) || (state == Connecting) || (state == Listening);
|
||||||
auto result = dlg.exec();
|
}
|
||||||
|
|
||||||
if (result == QDialog::Accepted) {
|
void MainWindow::showConfigureServer(const QString &message) {
|
||||||
auto state = m_CoreState;
|
ServerConfigDialog dialog(this, serverConfig(), m_AppConfig);
|
||||||
if ((state == Connected) || (state == Connecting) || (state == Listening)) {
|
dialog.message(message);
|
||||||
restartCore();
|
if ((dialog.exec() == QDialog::Accepted) && isCoreActive()) {
|
||||||
}
|
restartCore();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1354,6 +1418,11 @@ int MainWindow::showActivationDialog() {
|
||||||
int result = activationDialog.exec();
|
int result = activationDialog.exec();
|
||||||
m_ActivationDialogRunning = false;
|
m_ActivationDialogRunning = false;
|
||||||
|
|
||||||
|
if (result == QDialog::Accepted) {
|
||||||
|
m_AppConfig.setActivationHasRun(true);
|
||||||
|
m_ConfigScopes.save();
|
||||||
|
}
|
||||||
|
|
||||||
if (!m_PendingClientNames.empty()) {
|
if (!m_PendingClientNames.empty()) {
|
||||||
foreach (const QString &name, m_PendingClientNames) {
|
foreach (const QString &name, m_PendingClientNames) {
|
||||||
autoAddScreen(name);
|
autoAddScreen(name);
|
||||||
|
|
@ -1391,23 +1460,33 @@ void MainWindow::updateScreenName() {
|
||||||
m_pLabelComputerName->setText(
|
m_pLabelComputerName->setText(
|
||||||
QString("This computer's name: %1 "
|
QString("This computer's name: %1 "
|
||||||
R"((<a href="#" style="color: %2">change</a>))")
|
R"((<a href="#" style="color: %2">change</a>))")
|
||||||
.arg(appConfig().screenName())
|
.arg(m_AppConfig.screenName())
|
||||||
.arg(kColorSecondary));
|
.arg(kColorSecondary));
|
||||||
serverConfig().updateServerName();
|
m_ServerConfig.updateServerName();
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::enableServer(bool enable) {
|
void MainWindow::enableServer(bool enable) {
|
||||||
|
qDebug(enable ? "server enabled" : "server disabled");
|
||||||
m_AppConfig.setServerGroupChecked(enable);
|
m_AppConfig.setServerGroupChecked(enable);
|
||||||
m_pRadioGroupServer->setChecked(enable);
|
m_pRadioGroupServer->setChecked(enable);
|
||||||
m_pWidgetServer->setEnabled(enable);
|
m_pWidgetServer->setEnabled(enable);
|
||||||
m_pWidgetServerInverse->setVisible(m_AppConfig.invertConnection());
|
m_pWidgetServerInverse->setVisible(m_AppConfig.invertConnection());
|
||||||
m_pButtonToggleStart->setEnabled(true);
|
|
||||||
|
if (enable) {
|
||||||
|
m_pButtonToggleStart->setEnabled(true);
|
||||||
|
m_pActionStartCore->setEnabled(true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::enableClient(bool enable) {
|
void MainWindow::enableClient(bool enable) {
|
||||||
|
qDebug(enable ? "client enabled" : "client disabled");
|
||||||
m_AppConfig.setClientGroupChecked(enable);
|
m_AppConfig.setClientGroupChecked(enable);
|
||||||
m_pRadioGroupClient->setChecked(enable);
|
m_pRadioGroupClient->setChecked(enable);
|
||||||
m_pWidgetClient->setEnabled(enable);
|
m_pWidgetClient->setEnabled(enable);
|
||||||
m_pWidgetClient->setVisible(!m_AppConfig.invertConnection());
|
m_pWidgetClient->setVisible(!m_AppConfig.invertConnection());
|
||||||
m_pButtonToggleStart->setEnabled(true);
|
|
||||||
|
if (enable) {
|
||||||
|
m_pButtonToggleStart->setEnabled(true);
|
||||||
|
m_pActionStartCore->setEnabled(true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -79,22 +79,23 @@ public:
|
||||||
PendingRetry
|
PendingRetry
|
||||||
};
|
};
|
||||||
|
|
||||||
enum class CoreMode { Client, Server };
|
enum class CoreMode { None, Client, Server };
|
||||||
enum class LogLevel { Error, Info };
|
enum class LogLevel { Error, Info };
|
||||||
enum class RuningState { Started, Stopped };
|
enum class RuningState { Started, Stopped };
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit MainWindow(AppConfig &appConfig);
|
explicit MainWindow(
|
||||||
|
synergy::gui::ConfigScopes &configScopes, AppConfig &appConfig);
|
||||||
~MainWindow() override;
|
~MainWindow() override;
|
||||||
|
|
||||||
void setVisible(bool visible) override;
|
void setVisible(bool visible) override;
|
||||||
CoreMode coreMode() const;
|
CoreMode coreMode() const;
|
||||||
|
QString coreModeString() const;
|
||||||
QString address() const;
|
QString address() const;
|
||||||
QString appPath(const QString &name) const;
|
QString appPath(const QString &name) const;
|
||||||
void open();
|
void open();
|
||||||
ServerConfig &serverConfig() { return m_ServerConfig; }
|
ServerConfig &serverConfig() { return m_ServerConfig; }
|
||||||
void autoAddScreen(const QString name);
|
void autoAddScreen(const QString name);
|
||||||
LicenseHandler &licenseHandler();
|
|
||||||
int showActivationDialog();
|
int showActivationDialog();
|
||||||
void appendLogInfo(const QString &text);
|
void appendLogInfo(const QString &text);
|
||||||
void appendLogDebug(const QString &text);
|
void appendLogDebug(const QString &text);
|
||||||
|
|
@ -110,7 +111,7 @@ public slots:
|
||||||
private slots:
|
private slots:
|
||||||
void onCreated();
|
void onCreated();
|
||||||
void onShown();
|
void onShown();
|
||||||
void onAppConfigLoaded();
|
void onConfigScopesSaving();
|
||||||
void onAppConfigTlsChanged();
|
void onAppConfigTlsChanged();
|
||||||
void onAppConfigScreenNameChanged();
|
void onAppConfigScreenNameChanged();
|
||||||
void onAppConfigInvertConnection();
|
void onAppConfigInvertConnection();
|
||||||
|
|
@ -142,15 +143,17 @@ private slots:
|
||||||
void on_m_pActionHelp_triggered();
|
void on_m_pActionHelp_triggered();
|
||||||
void on_m_pActionSettings_triggered();
|
void on_m_pActionSettings_triggered();
|
||||||
void on_m_pActivate_triggered();
|
void on_m_pActivate_triggered();
|
||||||
|
void on_m_pLineEditHostname_returnPressed();
|
||||||
|
void on_m_pLineEditClientIp_returnPressed();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QSettings &settings() { return *appConfig().scopes().currentSettings(); }
|
|
||||||
AppConfig &appConfig() { return m_AppConfig; }
|
AppConfig &appConfig() { return m_AppConfig; }
|
||||||
AppConfig const &appConfig() const { return m_AppConfig; }
|
AppConfig const &appConfig() const { return m_AppConfig; }
|
||||||
void createMenuBar();
|
void createMenuBar();
|
||||||
void createStatusBar();
|
void createStatusBar();
|
||||||
void createTrayIcon();
|
void createTrayIcon();
|
||||||
void applyConfig();
|
void applyConfig();
|
||||||
|
void applyCloseToTray() const;
|
||||||
void setIcon(CoreState state) const;
|
void setIcon(CoreState state) const;
|
||||||
void setCoreState(CoreState state);
|
void setCoreState(CoreState state);
|
||||||
bool checkForApp(int which, QString &app);
|
bool checkForApp(int which, QString &app);
|
||||||
|
|
@ -172,6 +175,7 @@ private:
|
||||||
QString getTimeStamp() const;
|
QString getTimeStamp() const;
|
||||||
void restartCore();
|
void restartCore();
|
||||||
void showEvent(QShowEvent *) override;
|
void showEvent(QShowEvent *) override;
|
||||||
|
void closeEvent(QCloseEvent *event) override;
|
||||||
void secureSocket(bool secureSocket);
|
void secureSocket(bool secureSocket);
|
||||||
void windowStateChanged();
|
void windowStateChanged();
|
||||||
void connectSlots() const;
|
void connectSlots() const;
|
||||||
|
|
@ -183,6 +187,7 @@ private:
|
||||||
void updateScreenName();
|
void updateScreenName();
|
||||||
void saveSettings();
|
void saveSettings();
|
||||||
QString configFilename();
|
QString configFilename();
|
||||||
|
bool isCoreActive() const;
|
||||||
void showConfigureServer(const QString &message);
|
void showConfigureServer(const QString &message);
|
||||||
void showConfigureServer() { showConfigureServer(""); }
|
void showConfigureServer() { showConfigureServer(""); }
|
||||||
void showLicenseNotice();
|
void showLicenseNotice();
|
||||||
|
|
@ -192,6 +197,9 @@ private:
|
||||||
void setupControls();
|
void setupControls();
|
||||||
void resizeEvent(QResizeEvent *event) override;
|
void resizeEvent(QResizeEvent *event) override;
|
||||||
void moveEvent(QMoveEvent *event) override;
|
void moveEvent(QMoveEvent *event) override;
|
||||||
|
void showFirstRunMessage();
|
||||||
|
void showDevThanksMessage();
|
||||||
|
QString productName() const;
|
||||||
|
|
||||||
#ifdef Q_OS_MAC
|
#ifdef Q_OS_MAC
|
||||||
void checkOSXNotification(const QString &line);
|
void checkOSXNotification(const QString &line);
|
||||||
|
|
@ -216,9 +224,10 @@ private:
|
||||||
bool m_SecureSocket = false;
|
bool m_SecureSocket = false;
|
||||||
QString m_SecureSocketVersion = "";
|
QString m_SecureSocketVersion = "";
|
||||||
bool m_SaveWindow = false;
|
bool m_SaveWindow = false;
|
||||||
|
|
||||||
AppConfig &m_AppConfig;
|
|
||||||
LicenseHandler m_LicenseHandler;
|
LicenseHandler m_LicenseHandler;
|
||||||
|
|
||||||
|
synergy::gui::ConfigScopes &m_ConfigScopes;
|
||||||
|
AppConfig &m_AppConfig;
|
||||||
ServerConfig m_ServerConfig;
|
ServerConfig m_ServerConfig;
|
||||||
ServerConnection m_ServerConnection;
|
ServerConnection m_ServerConnection;
|
||||||
ClientConnection m_ClientConnection;
|
ClientConnection m_ClientConnection;
|
||||||
|
|
|
||||||
|
|
@ -103,7 +103,7 @@
|
||||||
</property>
|
</property>
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout_8">
|
<layout class="QHBoxLayout" name="horizontalLayout_8">
|
||||||
<item>
|
<item>
|
||||||
<widget class="QFrame" name="m_pGroupServer">
|
<widget class="QGroupBox" name="m_pGroupServer">
|
||||||
<property name="sizePolicy">
|
<property name="sizePolicy">
|
||||||
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
|
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
|
||||||
<horstretch>0</horstretch>
|
<horstretch>0</horstretch>
|
||||||
|
|
@ -268,7 +268,7 @@
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QFrame" name="m_pGroupClient">
|
<widget class="QGroupBox" name="m_pGroupClient">
|
||||||
<property name="sizePolicy">
|
<property name="sizePolicy">
|
||||||
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
|
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
|
||||||
<horstretch>0</horstretch>
|
<horstretch>0</horstretch>
|
||||||
|
|
@ -599,6 +599,9 @@
|
||||||
</property>
|
</property>
|
||||||
</action>
|
</action>
|
||||||
<action name="m_pActionStartCore">
|
<action name="m_pActionStartCore">
|
||||||
|
<property name="enabled">
|
||||||
|
<bool>false</bool>
|
||||||
|
</property>
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>&Start</string>
|
<string>&Start</string>
|
||||||
</property>
|
</property>
|
||||||
|
|
|
||||||
|
|
@ -24,18 +24,4 @@
|
||||||
#include <QtGui>
|
#include <QtGui>
|
||||||
|
|
||||||
QSynergyApplication::QSynergyApplication(int &argc, char **argv)
|
QSynergyApplication::QSynergyApplication(int &argc, char **argv)
|
||||||
: QApplication(argc, argv) {
|
: QApplication(argc, argv) {}
|
||||||
|
|
||||||
// Setting the style to 'Fusion' seems to fix issues such as text being
|
|
||||||
// rendered as black on black. This may not be the style we want long-term
|
|
||||||
// but it does fix the style issues for now.
|
|
||||||
setStyle("Fusion");
|
|
||||||
}
|
|
||||||
|
|
||||||
void QSynergyApplication::commitData(const QSessionManager &) const {
|
|
||||||
foreach (QWidget *widget, topLevelWidgets()) {
|
|
||||||
MainWindow *mainWindow = qobject_cast<MainWindow *>(widget);
|
|
||||||
if (mainWindow)
|
|
||||||
mainWindow->saveSettings();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -26,6 +26,4 @@ class QSynergyApplication : public QApplication {
|
||||||
public:
|
public:
|
||||||
QSynergyApplication(int &argc, char **argv);
|
QSynergyApplication(int &argc, char **argv);
|
||||||
~QSynergyApplication() override = default;
|
~QSynergyApplication() override = default;
|
||||||
|
|
||||||
void commitData(const QSessionManager &manager) const;
|
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,7 @@
|
||||||
|
|
||||||
#include "ScreenSettingsDialog.h"
|
#include "ScreenSettingsDialog.h"
|
||||||
#include "Screen.h"
|
#include "Screen.h"
|
||||||
#include "gui/constants.h"
|
#include "gui/styles.h"
|
||||||
#include "validators/AliasValidator.h"
|
#include "validators/AliasValidator.h"
|
||||||
#include "validators/ScreenNameValidator.h"
|
#include "validators/ScreenNameValidator.h"
|
||||||
#include "validators/ValidationError.h"
|
#include "validators/ValidationError.h"
|
||||||
|
|
|
||||||
|
|
@ -21,8 +21,6 @@
|
||||||
#include "AddClientDialog.h"
|
#include "AddClientDialog.h"
|
||||||
#include "Hotkey.h"
|
#include "Hotkey.h"
|
||||||
#include "MainWindow.h"
|
#include "MainWindow.h"
|
||||||
#include "gui/ConfigScopes.h"
|
|
||||||
#include "gui/constants.h"
|
|
||||||
|
|
||||||
#include <QAbstractButton>
|
#include <QAbstractButton>
|
||||||
#include <QMessageBox>
|
#include <QMessageBox>
|
||||||
|
|
@ -44,23 +42,14 @@ static const struct {
|
||||||
const int serverDefaultIndex = 7;
|
const int serverDefaultIndex = 7;
|
||||||
|
|
||||||
ServerConfig::ServerConfig(
|
ServerConfig::ServerConfig(
|
||||||
int numColumns, int numRows, AppConfig *appConfig, MainWindow *mainWindow)
|
AppConfig &appConfig, MainWindow &mainWindow, int columns, int rows)
|
||||||
: m_pAppConfig(appConfig),
|
: m_pAppConfig(&appConfig),
|
||||||
m_pMainWindow(mainWindow),
|
m_pMainWindow(&mainWindow),
|
||||||
m_Screens(numColumns),
|
m_Screens(columns),
|
||||||
m_NumColumns(numColumns),
|
m_Columns(columns),
|
||||||
m_NumRows(numRows),
|
m_Rows(rows),
|
||||||
m_ClipboardSharingSize(defaultClipboardSharingSize()) {
|
m_ClipboardSharingSize(defaultClipboardSharingSize()) {
|
||||||
appConfig->scopes().registerReceiver(this);
|
recall();
|
||||||
}
|
|
||||||
|
|
||||||
ServerConfig::~ServerConfig() {
|
|
||||||
try {
|
|
||||||
ServerConfig::saveSettings();
|
|
||||||
} catch (const std::exception &e) {
|
|
||||||
qDebug() << e.what();
|
|
||||||
m_pMainWindow->appendLogError(e.what());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ServerConfig::save(const QString &fileName) const {
|
bool ServerConfig::save(const QString &fileName) const {
|
||||||
|
|
@ -75,8 +64,8 @@ bool ServerConfig::save(const QString &fileName) const {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ServerConfig::operator==(const ServerConfig &sc) const {
|
bool ServerConfig::operator==(const ServerConfig &sc) const {
|
||||||
return m_Screens == sc.m_Screens && m_NumColumns == sc.m_NumColumns &&
|
return m_Screens == sc.m_Screens && m_Columns == sc.m_Columns &&
|
||||||
m_NumRows == sc.m_NumRows && m_HasHeartbeat == sc.m_HasHeartbeat &&
|
m_Rows == sc.m_Rows && m_HasHeartbeat == sc.m_HasHeartbeat &&
|
||||||
m_Heartbeat == sc.m_Heartbeat &&
|
m_Heartbeat == sc.m_Heartbeat &&
|
||||||
m_RelativeMouseMoves == sc.m_RelativeMouseMoves &&
|
m_RelativeMouseMoves == sc.m_RelativeMouseMoves &&
|
||||||
m_Win32KeepForeground == sc.m_Win32KeepForeground &&
|
m_Win32KeepForeground == sc.m_Win32KeepForeground &&
|
||||||
|
|
@ -99,7 +88,7 @@ void ServerConfig::save(QFile &file) const {
|
||||||
outStream << *this;
|
outStream << *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ServerConfig::init() {
|
void ServerConfig::setupScreens() {
|
||||||
switchCorners().clear();
|
switchCorners().clear();
|
||||||
screens().clear();
|
screens().clear();
|
||||||
hotkeys().clear();
|
hotkeys().clear();
|
||||||
|
|
@ -114,7 +103,9 @@ void ServerConfig::init() {
|
||||||
addScreen(Screen());
|
addScreen(Screen());
|
||||||
}
|
}
|
||||||
|
|
||||||
void ServerConfig::saveSettings() {
|
void ServerConfig::commit() {
|
||||||
|
qDebug("committing server config");
|
||||||
|
|
||||||
settings().beginGroup("internalConfig");
|
settings().beginGroup("internalConfig");
|
||||||
settings().remove("");
|
settings().remove("");
|
||||||
|
|
||||||
|
|
@ -163,7 +154,9 @@ void ServerConfig::saveSettings() {
|
||||||
settings().endGroup();
|
settings().endGroup();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ServerConfig::loadSettings() {
|
void ServerConfig::recall() {
|
||||||
|
qDebug("recalling server config");
|
||||||
|
|
||||||
settings().beginGroup("internalConfig");
|
settings().beginGroup("internalConfig");
|
||||||
|
|
||||||
setNumColumns(settings().value("numColumns", 5).toInt());
|
setNumColumns(settings().value("numColumns", 5).toInt());
|
||||||
|
|
@ -171,7 +164,7 @@ void ServerConfig::loadSettings() {
|
||||||
|
|
||||||
// we need to know the number of columns and rows before we can set up
|
// we need to know the number of columns and rows before we can set up
|
||||||
// ourselves
|
// ourselves
|
||||||
init();
|
setupScreens();
|
||||||
|
|
||||||
haveHeartbeat(settings().value("hasHeartbeat", false).toBool());
|
haveHeartbeat(settings().value("hasHeartbeat", false).toBool());
|
||||||
setHeartbeat(settings().value("heartbeat", 5000).toInt());
|
setHeartbeat(settings().value("heartbeat", 5000).toInt());
|
||||||
|
|
@ -398,7 +391,6 @@ int ServerConfig::autoAddScreen(const QString name) {
|
||||||
return kAutoAddScreenManualClient;
|
return kAutoAddScreenManualClient;
|
||||||
}
|
}
|
||||||
|
|
||||||
saveSettings();
|
|
||||||
return kAutoAddScreenOk;
|
return kAutoAddScreenOk;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -410,7 +402,6 @@ void ServerConfig::updateServerName() {
|
||||||
for (auto &screen : screens()) {
|
for (auto &screen : screens()) {
|
||||||
if (screen.isServer()) {
|
if (screen.isServer()) {
|
||||||
screen.setName(m_pAppConfig->screenName());
|
screen.setName(m_pAppConfig->screenName());
|
||||||
saveSettings();
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -553,5 +544,5 @@ QString ServerConfig::getClientAddress() const {
|
||||||
}
|
}
|
||||||
|
|
||||||
QSettings &ServerConfig::settings() {
|
QSettings &ServerConfig::settings() {
|
||||||
return *m_pAppConfig->scopes().currentSettings();
|
return *m_pAppConfig->scopes().activeSettings();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -21,10 +21,12 @@
|
||||||
#include "Hotkey.h"
|
#include "Hotkey.h"
|
||||||
#include "ScreenConfig.h"
|
#include "ScreenConfig.h"
|
||||||
#include "ScreenList.h"
|
#include "ScreenList.h"
|
||||||
#include "gui/CommonConfig.h"
|
|
||||||
|
|
||||||
#include <QList>
|
#include <QList>
|
||||||
|
|
||||||
|
const auto kDefaultColumns = 5;
|
||||||
|
const auto kDefaultRows = 3;
|
||||||
|
|
||||||
class QTextStream;
|
class QTextStream;
|
||||||
class QSettings;
|
class QSettings;
|
||||||
class QString;
|
class QString;
|
||||||
|
|
@ -33,7 +35,7 @@ class ServerConfigDialog;
|
||||||
class MainWindow;
|
class MainWindow;
|
||||||
class AppConfig;
|
class AppConfig;
|
||||||
|
|
||||||
class ServerConfig : public ScreenConfig, public synergy::gui::CommonConfig {
|
class ServerConfig : public ScreenConfig {
|
||||||
friend class ServerConfigDialog;
|
friend class ServerConfigDialog;
|
||||||
friend class ServerConnection;
|
friend class ServerConnection;
|
||||||
friend QTextStream &
|
friend QTextStream &
|
||||||
|
|
@ -41,15 +43,15 @@ class ServerConfig : public ScreenConfig, public synergy::gui::CommonConfig {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
ServerConfig(
|
ServerConfig(
|
||||||
int numColumns, int numRows, AppConfig *appConfig,
|
AppConfig &appConfig, MainWindow &mainWindow,
|
||||||
MainWindow *mainWindow);
|
int columns = kDefaultColumns, int rows = kDefaultRows);
|
||||||
~ServerConfig() override;
|
~ServerConfig() = default;
|
||||||
|
|
||||||
bool operator==(const ServerConfig &sc) const;
|
bool operator==(const ServerConfig &sc) const;
|
||||||
|
|
||||||
const ScreenList &screens() const { return m_Screens; }
|
const ScreenList &screens() const { return m_Screens; }
|
||||||
int numColumns() const { return m_NumColumns; }
|
int numColumns() const { return m_Columns; }
|
||||||
int numRows() const { return m_NumRows; }
|
int numRows() const { return m_Rows; }
|
||||||
bool hasHeartbeat() const { return m_HasHeartbeat; }
|
bool hasHeartbeat() const { return m_HasHeartbeat; }
|
||||||
int heartbeat() const { return m_Heartbeat; }
|
int heartbeat() const { return m_Heartbeat; }
|
||||||
bool relativeMouseMoves() const { return m_RelativeMouseMoves; }
|
bool relativeMouseMoves() const { return m_RelativeMouseMoves; }
|
||||||
|
|
@ -68,8 +70,7 @@ public:
|
||||||
size_t clipboardSharingSize() const { return m_ClipboardSharingSize; }
|
size_t clipboardSharingSize() const { return m_ClipboardSharingSize; }
|
||||||
static size_t defaultClipboardSharingSize();
|
static size_t defaultClipboardSharingSize();
|
||||||
|
|
||||||
void saveSettings() override;
|
void commit();
|
||||||
void loadSettings() override;
|
|
||||||
bool save(const QString &fileName) const;
|
bool save(const QString &fileName) const;
|
||||||
void save(QFile &file) const;
|
void save(QFile &file) const;
|
||||||
int numScreens() const;
|
int numScreens() const;
|
||||||
|
|
@ -84,13 +85,15 @@ public:
|
||||||
QString getClientAddress() const;
|
QString getClientAddress() const;
|
||||||
void setClientAddress(const QString &address);
|
void setClientAddress(const QString &address);
|
||||||
|
|
||||||
protected:
|
private:
|
||||||
|
void recall();
|
||||||
|
void setupScreens();
|
||||||
QSettings &settings();
|
QSettings &settings();
|
||||||
ScreenList &screens() { return m_Screens; }
|
ScreenList &screens() { return m_Screens; }
|
||||||
void setScreens(const ScreenList &screens) { m_Screens = screens; }
|
void setScreens(const ScreenList &screens) { m_Screens = screens; }
|
||||||
void addScreen(const Screen &screen) { m_Screens.append(screen); }
|
void addScreen(const Screen &screen) { m_Screens.append(screen); }
|
||||||
void setNumColumns(int n) { m_NumColumns = n; }
|
void setNumColumns(int n) { m_Columns = n; }
|
||||||
void setNumRows(int n) { m_NumRows = n; }
|
void setNumRows(int n) { m_Rows = n; }
|
||||||
void haveHeartbeat(bool on) { m_HasHeartbeat = on; }
|
void haveHeartbeat(bool on) { m_HasHeartbeat = on; }
|
||||||
void setHeartbeat(int val) { m_Heartbeat = val; }
|
void setHeartbeat(int val) { m_Heartbeat = val; }
|
||||||
void setRelativeMouseMoves(bool on) { m_RelativeMouseMoves = on; }
|
void setRelativeMouseMoves(bool on) { m_RelativeMouseMoves = on; }
|
||||||
|
|
@ -109,11 +112,7 @@ protected:
|
||||||
size_t setClipboardSharingSize(size_t size);
|
size_t setClipboardSharingSize(size_t size);
|
||||||
QList<bool> &switchCorners() { return m_SwitchCorners; }
|
QList<bool> &switchCorners() { return m_SwitchCorners; }
|
||||||
HotkeyList &hotkeys() { return m_Hotkeys; }
|
HotkeyList &hotkeys() { return m_Hotkeys; }
|
||||||
|
|
||||||
void init();
|
|
||||||
int adjacentScreenIndex(int idx, int deltaColumn, int deltaRow) const;
|
int adjacentScreenIndex(int idx, int deltaColumn, int deltaRow) const;
|
||||||
|
|
||||||
private:
|
|
||||||
bool findScreenName(const QString &name, int &index);
|
bool findScreenName(const QString &name, int &index);
|
||||||
bool fixNoServer(const QString &name, int &index);
|
bool fixNoServer(const QString &name, int &index);
|
||||||
int showAddClientDialog(const QString &clientName);
|
int showAddClientDialog(const QString &clientName);
|
||||||
|
|
@ -139,8 +138,8 @@ private:
|
||||||
AppConfig *m_pAppConfig;
|
AppConfig *m_pAppConfig;
|
||||||
MainWindow *m_pMainWindow;
|
MainWindow *m_pMainWindow;
|
||||||
ScreenList m_Screens;
|
ScreenList m_Screens;
|
||||||
int m_NumColumns;
|
int m_Columns;
|
||||||
int m_NumRows;
|
int m_Rows;
|
||||||
size_t m_ClipboardSharingSize;
|
size_t m_ClipboardSharingSize;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -332,7 +332,7 @@
|
||||||
</widget>
|
</widget>
|
||||||
<widget class="QWidget" name="m_pTabAdvanced">
|
<widget class="QWidget" name="m_pTabAdvanced">
|
||||||
<attribute name="title">
|
<attribute name="title">
|
||||||
<string>Advanced server settings</string>
|
<string>Advanced</string>
|
||||||
</attribute>
|
</attribute>
|
||||||
<layout class="QGridLayout">
|
<layout class="QGridLayout">
|
||||||
<property name="leftMargin">
|
<property name="leftMargin">
|
||||||
|
|
@ -839,289 +839,284 @@
|
||||||
</sizepolicy>
|
</sizepolicy>
|
||||||
</property>
|
</property>
|
||||||
<attribute name="title">
|
<attribute name="title">
|
||||||
<string>Advanced config</string>
|
<string>Config file</string>
|
||||||
</attribute>
|
</attribute>
|
||||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||||
|
<property name="spacing">
|
||||||
|
<number>15</number>
|
||||||
|
</property>
|
||||||
|
<property name="leftMargin">
|
||||||
|
<number>120</number>
|
||||||
|
</property>
|
||||||
|
<property name="topMargin">
|
||||||
|
<number>30</number>
|
||||||
|
</property>
|
||||||
|
<property name="rightMargin">
|
||||||
|
<number>120</number>
|
||||||
|
</property>
|
||||||
|
<item alignment="Qt::AlignHCenter">
|
||||||
|
<widget class="QLabel" name="label_5">
|
||||||
|
<property name="font">
|
||||||
|
<font>
|
||||||
|
<pointsize>18</pointsize>
|
||||||
|
<bold>true</bold>
|
||||||
|
</font>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Core server config file</string>
|
||||||
|
</property>
|
||||||
|
<property name="textFormat">
|
||||||
|
<enum>Qt::PlainText</enum>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<layout class="QVBoxLayout" name="verticalLayout">
|
<widget class="QLabel" name="label_6">
|
||||||
|
<property name="text">
|
||||||
|
<string>Use a Core server config file to create complex screen layouts that are not possible with the simple grid-based screen layout editor.
|
||||||
|
|
||||||
|
[How to write a config file](https://symless.com/synergy/help/creating-text-config-files)
|
||||||
|
|
||||||
|
Enabling this setting will disable the server config GUI.</string>
|
||||||
|
</property>
|
||||||
|
<property name="textFormat">
|
||||||
|
<enum>Qt::MarkdownText</enum>
|
||||||
|
</property>
|
||||||
|
<property name="alignment">
|
||||||
|
<set>Qt::AlignCenter</set>
|
||||||
|
</property>
|
||||||
|
<property name="wordWrap">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<spacer name="verticalSpacer_4">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Vertical</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeType">
|
||||||
|
<enum>QSizePolicy::Maximum</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>20</width>
|
||||||
|
<height>30</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||||
|
<property name="leftMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="topMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
<item>
|
<item>
|
||||||
<spacer name="verticalSpacer_2">
|
<spacer name="horizontalSpacer_2">
|
||||||
<property name="orientation">
|
<property name="orientation">
|
||||||
<enum>Qt::Vertical</enum>
|
<enum>Qt::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeType">
|
||||||
|
<enum>QSizePolicy::Expanding</enum>
|
||||||
</property>
|
</property>
|
||||||
<property name="sizeHint" stdset="0">
|
<property name="sizeHint" stdset="0">
|
||||||
<size>
|
<size>
|
||||||
<width>20</width>
|
<width>40</width>
|
||||||
<height>40</height>
|
<height>20</height>
|
||||||
</size>
|
</size>
|
||||||
</property>
|
</property>
|
||||||
</spacer>
|
</spacer>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QLabel" name="label_5">
|
<widget class="QCheckBox" name="m_pCheckBoxUseExternalConfig">
|
||||||
<property name="text">
|
<property name="sizePolicy">
|
||||||
<string><html><head/><body><p style="text-align: center; font-family: Arial; font-size: 18px; line-height: 25px;">Config override</p></body></html></string>
|
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
</property>
|
</property>
|
||||||
<property name="textFormat">
|
<property name="minimumSize">
|
||||||
<enum>Qt::RichText</enum>
|
<size>
|
||||||
|
<width>300</width>
|
||||||
|
<height>0</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Use Core server config file</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<spacer name="verticalSpacer_3">
|
<spacer name="horizontalSpacer_3">
|
||||||
<property name="orientation">
|
<property name="orientation">
|
||||||
<enum>Qt::Vertical</enum>
|
<enum>Qt::Horizontal</enum>
|
||||||
</property>
|
</property>
|
||||||
<property name="sizeType">
|
<property name="sizeType">
|
||||||
<enum>QSizePolicy::Minimum</enum>
|
<enum>QSizePolicy::Expanding</enum>
|
||||||
</property>
|
</property>
|
||||||
<property name="sizeHint" stdset="0">
|
<property name="sizeHint" stdset="0">
|
||||||
<size>
|
<size>
|
||||||
<width>20</width>
|
<width>40</width>
|
||||||
<height>5</height>
|
<height>20</height>
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
</spacer>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QLabel" name="label_6">
|
|
||||||
<property name="text">
|
|
||||||
<string><html><head/><body><p style="text-align: center; font-size: 13px; font-family: Arial; line-hegiht: 18px;">If you have a config file and want to override all setttings with this file.</p></body></html></string>
|
|
||||||
</property>
|
|
||||||
<property name="textFormat">
|
|
||||||
<enum>Qt::RichText</enum>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<spacer name="verticalSpacer_4">
|
|
||||||
<property name="orientation">
|
|
||||||
<enum>Qt::Vertical</enum>
|
|
||||||
</property>
|
|
||||||
<property name="sizeType">
|
|
||||||
<enum>QSizePolicy::Maximum</enum>
|
|
||||||
</property>
|
|
||||||
<property name="sizeHint" stdset="0">
|
|
||||||
<size>
|
|
||||||
<width>20</width>
|
|
||||||
<height>30</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
</spacer>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
|
||||||
<property name="leftMargin">
|
|
||||||
<number>0</number>
|
|
||||||
</property>
|
|
||||||
<property name="topMargin">
|
|
||||||
<number>0</number>
|
|
||||||
</property>
|
|
||||||
<item>
|
|
||||||
<spacer name="horizontalSpacer_2">
|
|
||||||
<property name="orientation">
|
|
||||||
<enum>Qt::Horizontal</enum>
|
|
||||||
</property>
|
|
||||||
<property name="sizeType">
|
|
||||||
<enum>QSizePolicy::Expanding</enum>
|
|
||||||
</property>
|
|
||||||
<property name="sizeHint" stdset="0">
|
|
||||||
<size>
|
|
||||||
<width>40</width>
|
|
||||||
<height>20</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
</spacer>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QCheckBox" name="m_pCheckBoxUseExternalConfig">
|
|
||||||
<property name="sizePolicy">
|
|
||||||
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
|
||||||
<horstretch>0</horstretch>
|
|
||||||
<verstretch>0</verstretch>
|
|
||||||
</sizepolicy>
|
|
||||||
</property>
|
|
||||||
<property name="minimumSize">
|
|
||||||
<size>
|
|
||||||
<width>300</width>
|
|
||||||
<height>0</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string>Use configuration file</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<spacer name="horizontalSpacer_3">
|
|
||||||
<property name="orientation">
|
|
||||||
<enum>Qt::Horizontal</enum>
|
|
||||||
</property>
|
|
||||||
<property name="sizeType">
|
|
||||||
<enum>QSizePolicy::Expanding</enum>
|
|
||||||
</property>
|
|
||||||
<property name="sizeHint" stdset="0">
|
|
||||||
<size>
|
|
||||||
<width>40</width>
|
|
||||||
<height>20</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
</spacer>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout_3">
|
|
||||||
<property name="leftMargin">
|
|
||||||
<number>40</number>
|
|
||||||
</property>
|
|
||||||
<property name="topMargin">
|
|
||||||
<number>0</number>
|
|
||||||
</property>
|
|
||||||
<item>
|
|
||||||
<spacer name="horizontalSpacer_4">
|
|
||||||
<property name="orientation">
|
|
||||||
<enum>Qt::Horizontal</enum>
|
|
||||||
</property>
|
|
||||||
<property name="sizeType">
|
|
||||||
<enum>QSizePolicy::Expanding</enum>
|
|
||||||
</property>
|
|
||||||
<property name="sizeHint" stdset="0">
|
|
||||||
<size>
|
|
||||||
<width>40</width>
|
|
||||||
<height>20</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
</spacer>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QLabel" name="m_pLabelConfigFile">
|
|
||||||
<property name="enabled">
|
|
||||||
<bool>false</bool>
|
|
||||||
</property>
|
|
||||||
<property name="sizePolicy">
|
|
||||||
<sizepolicy hsizetype="Fixed" vsizetype="Preferred">
|
|
||||||
<horstretch>0</horstretch>
|
|
||||||
<verstretch>0</verstretch>
|
|
||||||
</sizepolicy>
|
|
||||||
</property>
|
|
||||||
<property name="minimumSize">
|
|
||||||
<size>
|
|
||||||
<width>96</width>
|
|
||||||
<height>0</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string>Config file path</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<spacer name="horizontalSpacer_6">
|
|
||||||
<property name="orientation">
|
|
||||||
<enum>Qt::Horizontal</enum>
|
|
||||||
</property>
|
|
||||||
<property name="sizeType">
|
|
||||||
<enum>QSizePolicy::Fixed</enum>
|
|
||||||
</property>
|
|
||||||
<property name="sizeHint" stdset="0">
|
|
||||||
<size>
|
|
||||||
<width>10</width>
|
|
||||||
<height>20</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
</spacer>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QLineEdit" name="m_pEditConfigFile">
|
|
||||||
<property name="enabled">
|
|
||||||
<bool>false</bool>
|
|
||||||
</property>
|
|
||||||
<property name="sizePolicy">
|
|
||||||
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
|
||||||
<horstretch>0</horstretch>
|
|
||||||
<verstretch>0</verstretch>
|
|
||||||
</sizepolicy>
|
|
||||||
</property>
|
|
||||||
<property name="minimumSize">
|
|
||||||
<size>
|
|
||||||
<width>180</width>
|
|
||||||
<height>0</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QPushButton" name="m_pButtonBrowseConfigFile">
|
|
||||||
<property name="enabled">
|
|
||||||
<bool>false</bool>
|
|
||||||
</property>
|
|
||||||
<property name="sizePolicy">
|
|
||||||
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
|
||||||
<horstretch>0</horstretch>
|
|
||||||
<verstretch>0</verstretch>
|
|
||||||
</sizepolicy>
|
|
||||||
</property>
|
|
||||||
<property name="minimumSize">
|
|
||||||
<size>
|
|
||||||
<width>0</width>
|
|
||||||
<height>0</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
<property name="cursor">
|
|
||||||
<cursorShape>PointingHandCursor</cursorShape>
|
|
||||||
</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>
|
|
||||||
<item>
|
|
||||||
<spacer name="horizontalSpacer_5">
|
|
||||||
<property name="orientation">
|
|
||||||
<enum>Qt::Horizontal</enum>
|
|
||||||
</property>
|
|
||||||
<property name="sizeType">
|
|
||||||
<enum>QSizePolicy::Expanding</enum>
|
|
||||||
</property>
|
|
||||||
<property name="sizeHint" stdset="0">
|
|
||||||
<size>
|
|
||||||
<width>40</width>
|
|
||||||
<height>20</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
</spacer>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<spacer name="verticalSpacer">
|
|
||||||
<property name="orientation">
|
|
||||||
<enum>Qt::Vertical</enum>
|
|
||||||
</property>
|
|
||||||
<property name="sizeHint" stdset="0">
|
|
||||||
<size>
|
|
||||||
<width>20</width>
|
|
||||||
<height>40</height>
|
|
||||||
</size>
|
</size>
|
||||||
</property>
|
</property>
|
||||||
</spacer>
|
</spacer>
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</item>
|
</item>
|
||||||
|
<item>
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout_3">
|
||||||
|
<property name="leftMargin">
|
||||||
|
<number>40</number>
|
||||||
|
</property>
|
||||||
|
<property name="topMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<item>
|
||||||
|
<spacer name="horizontalSpacer_4">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeType">
|
||||||
|
<enum>QSizePolicy::Expanding</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>40</width>
|
||||||
|
<height>20</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="m_pLabelConfigFile">
|
||||||
|
<property name="enabled">
|
||||||
|
<bool>false</bool>
|
||||||
|
</property>
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Fixed" vsizetype="Preferred">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="minimumSize">
|
||||||
|
<size>
|
||||||
|
<width>96</width>
|
||||||
|
<height>0</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Config file path</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<spacer name="horizontalSpacer_6">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeType">
|
||||||
|
<enum>QSizePolicy::Fixed</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>10</width>
|
||||||
|
<height>20</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLineEdit" name="m_pEditConfigFile">
|
||||||
|
<property name="enabled">
|
||||||
|
<bool>false</bool>
|
||||||
|
</property>
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="minimumSize">
|
||||||
|
<size>
|
||||||
|
<width>180</width>
|
||||||
|
<height>0</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="m_pButtonBrowseConfigFile">
|
||||||
|
<property name="enabled">
|
||||||
|
<bool>false</bool>
|
||||||
|
</property>
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="minimumSize">
|
||||||
|
<size>
|
||||||
|
<width>0</width>
|
||||||
|
<height>0</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="cursor">
|
||||||
|
<cursorShape>PointingHandCursor</cursorShape>
|
||||||
|
</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>
|
||||||
|
<item>
|
||||||
|
<spacer name="horizontalSpacer_5">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeType">
|
||||||
|
<enum>QSizePolicy::Expanding</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>40</width>
|
||||||
|
<height>20</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<spacer name="verticalSpacer">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Vertical</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>20</width>
|
||||||
|
<height>40</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
</widget>
|
</widget>
|
||||||
|
|
|
||||||
|
|
@ -69,10 +69,10 @@ void ServerConnection::addClient(const QString &clientName) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void ServerConnection::configureClient(const QString &clientName) {
|
void ServerConnection::configureClient(const QString &clientName) {
|
||||||
ServerConfigDialog dlg(
|
ServerConfigDialog dialog(
|
||||||
&m_parent, m_parent.serverConfig(), m_parent.appConfig());
|
&m_parent, m_parent.serverConfig(), m_parent.appConfig());
|
||||||
|
|
||||||
if (dlg.addClient(clientName) && dlg.exec() == QDialog::Accepted) {
|
if (dialog.addClient(clientName) && dialog.exec() == QDialog::Accepted) {
|
||||||
m_parent.restartCore();
|
m_parent.restartCore();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -53,7 +53,7 @@ SettingsDialog::SettingsDialog(
|
||||||
m_pMainWindow = dynamic_cast<MainWindow *>(parent);
|
m_pMainWindow = dynamic_cast<MainWindow *>(parent);
|
||||||
|
|
||||||
loadFromConfig();
|
loadFromConfig();
|
||||||
m_isSystemAtStart = appConfig().isSystemScoped();
|
m_wasOriginallySystemScope = appConfig().isActiveScopeSystem();
|
||||||
updateControlsEnabled();
|
updateControlsEnabled();
|
||||||
|
|
||||||
const auto &serveConfig = m_pMainWindow->serverConfig();
|
const auto &serveConfig = m_pMainWindow->serverConfig();
|
||||||
|
|
@ -86,18 +86,17 @@ void SettingsDialog::accept() {
|
||||||
appConfig().setTlsEnabled(m_pCheckBoxEnableCrypto->isChecked());
|
appConfig().setTlsEnabled(m_pCheckBoxEnableCrypto->isChecked());
|
||||||
appConfig().setLanguageSync(m_pCheckBoxLanguageSync->isChecked());
|
appConfig().setLanguageSync(m_pCheckBoxLanguageSync->isChecked());
|
||||||
appConfig().setInvertScrollDirection(m_pCheckBoxScrollDirection->isChecked());
|
appConfig().setInvertScrollDirection(m_pCheckBoxScrollDirection->isChecked());
|
||||||
appConfig().setServiceEnabled(m_pCheckBoxServiceEnabled->isChecked());
|
appConfig().setEnableService(m_pCheckBoxServiceEnabled->isChecked());
|
||||||
appConfig().setCloseToTray(m_pCheckBoxCloseToTray->isChecked());
|
appConfig().setCloseToTray(m_pCheckBoxCloseToTray->isChecked());
|
||||||
appConfig().setInvertConnection(m_pInvertConnection->isChecked());
|
appConfig().setInvertConnection(m_pInvertConnection->isChecked());
|
||||||
|
|
||||||
appConfig().saveSettings();
|
|
||||||
QDialog::accept();
|
QDialog::accept();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SettingsDialog::reject() {
|
void SettingsDialog::reject() {
|
||||||
// We should restore scope at start if the user rejects changes.
|
// restore original system scope value on reject.
|
||||||
if (appConfig().isSystemScoped() != m_isSystemAtStart) {
|
if (appConfig().isActiveScopeSystem() != m_wasOriginallySystemScope) {
|
||||||
appConfig().setLoadFromSystemScope(m_isSystemAtStart);
|
appConfig().setLoadFromSystemScope(m_wasOriginallySystemScope);
|
||||||
}
|
}
|
||||||
|
|
||||||
QDialog::reject();
|
QDialog::reject();
|
||||||
|
|
@ -117,10 +116,10 @@ void SettingsDialog::loadFromConfig() {
|
||||||
m_pCheckBoxEnableCrypto->setChecked(m_appConfig.tlsEnabled());
|
m_pCheckBoxEnableCrypto->setChecked(m_appConfig.tlsEnabled());
|
||||||
m_pCheckBoxLanguageSync->setChecked(m_appConfig.languageSync());
|
m_pCheckBoxLanguageSync->setChecked(m_appConfig.languageSync());
|
||||||
m_pCheckBoxScrollDirection->setChecked(m_appConfig.invertScrollDirection());
|
m_pCheckBoxScrollDirection->setChecked(m_appConfig.invertScrollDirection());
|
||||||
m_pCheckBoxServiceEnabled->setChecked(m_appConfig.serviceEnabled());
|
m_pCheckBoxServiceEnabled->setChecked(m_appConfig.enableService());
|
||||||
m_pCheckBoxCloseToTray->setChecked(m_appConfig.closeToTray());
|
m_pCheckBoxCloseToTray->setChecked(m_appConfig.closeToTray());
|
||||||
|
|
||||||
if (m_appConfig.isSystemScoped()) {
|
if (m_appConfig.isActiveScopeSystem()) {
|
||||||
m_pRadioSystemScope->setChecked(true);
|
m_pRadioSystemScope->setChecked(true);
|
||||||
} else {
|
} else {
|
||||||
m_pRadioUserScope->setChecked(true);
|
m_pRadioUserScope->setChecked(true);
|
||||||
|
|
@ -147,14 +146,15 @@ void SettingsDialog::updateTlsControls() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void SettingsDialog::updateTlsControlsEnabled() {
|
void SettingsDialog::updateTlsControlsEnabled() {
|
||||||
|
bool writable = appConfig().isActiveScopeWritable();
|
||||||
auto clientMode = appConfig().clientGroupChecked();
|
auto clientMode = appConfig().clientGroupChecked();
|
||||||
auto tlsAvailable = m_tlsUtility.isAvailableAndEnabled();
|
auto tlsAvailable = m_tlsUtility.isAvailableAndEnabled();
|
||||||
auto tlsChecked = m_pCheckBoxEnableCrypto->isChecked();
|
auto tlsChecked = m_pCheckBoxEnableCrypto->isChecked();
|
||||||
auto enabled = !clientMode && tlsAvailable && tlsChecked;
|
auto enabled = writable && !clientMode && tlsAvailable && tlsChecked;
|
||||||
|
|
||||||
qDebug(
|
qDebug(
|
||||||
"tls enabled=%d, client=%d, available=%d, checked=%d", enabled,
|
"tls enabled=%d, writable=%d, client=%d, available=%d, checked=%d",
|
||||||
clientMode, tlsAvailable, tlsChecked);
|
enabled, writable, clientMode, tlsAvailable, tlsChecked);
|
||||||
|
|
||||||
m_pLabelKeyLength->setEnabled(enabled);
|
m_pLabelKeyLength->setEnabled(enabled);
|
||||||
m_pComboBoxKeyLength->setEnabled(enabled);
|
m_pComboBoxKeyLength->setEnabled(enabled);
|
||||||
|
|
@ -165,7 +165,7 @@ void SettingsDialog::updateTlsControlsEnabled() {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SettingsDialog::isClientMode() const {
|
bool SettingsDialog::isClientMode() const {
|
||||||
return (m_pMainWindow->coreMode() == MainWindow::CoreMode::Client);
|
return m_pMainWindow->coreMode() == MainWindow::CoreMode::Client;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SettingsDialog::on_m_pCheckBoxLogToFile_stateChanged(int i) {
|
void SettingsDialog::on_m_pCheckBoxLogToFile_stateChanged(int i) {
|
||||||
|
|
@ -254,7 +254,7 @@ void SettingsDialog::updateKeyLengthOnFile(const QString &path) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void SettingsDialog::updateControlsEnabled() {
|
void SettingsDialog::updateControlsEnabled() {
|
||||||
bool writable = appConfig().isWritable();
|
bool writable = appConfig().isActiveScopeWritable();
|
||||||
|
|
||||||
m_pLineEditScreenName->setEnabled(writable);
|
m_pLineEditScreenName->setEnabled(writable);
|
||||||
m_pSpinBoxPort->setEnabled(writable);
|
m_pSpinBoxPort->setEnabled(writable);
|
||||||
|
|
|
||||||
|
|
@ -76,7 +76,7 @@ private:
|
||||||
/// @brief Stores settings scope at start of settings dialog
|
/// @brief Stores settings scope at start of settings dialog
|
||||||
/// This is neccessary to restore state if user changes
|
/// This is neccessary to restore state if user changes
|
||||||
/// the scope and doesn't save changes
|
/// the scope and doesn't save changes
|
||||||
bool m_isSystemAtStart = false;
|
bool m_wasOriginallySystemScope = false;
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void on_m_pCheckBoxEnableCrypto_clicked(bool checked);
|
void on_m_pCheckBoxEnableCrypto_clicked(bool checked);
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* synergy -- mouse and keyboard sharing utility
|
* synergy -- mouse and keyboard sharing utility
|
||||||
* Copyright (C) 2012-2016 Symless Ltd.
|
* Copyright (C) 2012 Symless Ltd.
|
||||||
*
|
*
|
||||||
* This package is free software; you can redistribute it and/or
|
* This package is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License
|
* modify it under the terms of the GNU General Public License
|
||||||
|
|
@ -17,18 +17,16 @@
|
||||||
|
|
||||||
#include "SetupWizard.h"
|
#include "SetupWizard.h"
|
||||||
|
|
||||||
#include "MainWindow.h"
|
#include "gui/styles.h"
|
||||||
#include "gui/constants.h"
|
|
||||||
#include "validators/ScreenNameValidator.h"
|
#include "validators/ScreenNameValidator.h"
|
||||||
#include "validators/ValidationError.h"
|
#include "validators/ValidationError.h"
|
||||||
|
|
||||||
SetupWizard::SetupWizard(MainWindow &mainWindow) : m_mainWindow(mainWindow) {
|
SetupWizard::SetupWizard(AppConfig &appConfig) : m_appConfig(appConfig) {
|
||||||
|
|
||||||
setupUi(this);
|
setupUi(this);
|
||||||
|
|
||||||
m_pLabelError->setStyleSheet(kStyleErrorActiveLabel);
|
m_pLabelError->setStyleSheet(kStyleErrorActiveLabel);
|
||||||
|
|
||||||
m_pLineEditName->setText(m_mainWindow.appConfig().screenName());
|
m_pLineEditName->setText(appConfig.screenName());
|
||||||
m_pLineEditName->setValidator(new validators::ScreenNameValidator(
|
m_pLineEditName->setValidator(new validators::ScreenNameValidator(
|
||||||
m_pLineEditName, new validators::ValidationError(this, m_pLabelError)));
|
m_pLineEditName, new validators::ValidationError(this, m_pLabelError)));
|
||||||
|
|
||||||
|
|
@ -39,13 +37,8 @@ SetupWizard::SetupWizard(MainWindow &mainWindow) : m_mainWindow(mainWindow) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetupWizard::accept() {
|
void SetupWizard::accept() {
|
||||||
AppConfig &appConfig = m_mainWindow.appConfig();
|
m_appConfig.setWizardHasRun();
|
||||||
|
m_appConfig.setScreenName(m_pLineEditName->text());
|
||||||
appConfig.setWizardHasRun();
|
|
||||||
appConfig.setScreenName(m_pLineEditName->text());
|
|
||||||
appConfig.saveSettings();
|
|
||||||
|
|
||||||
m_mainWindow.open();
|
|
||||||
QDialog::accept();
|
QDialog::accept();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -19,6 +19,8 @@
|
||||||
|
|
||||||
#include "ui_SetupWizardBase.h"
|
#include "ui_SetupWizardBase.h"
|
||||||
|
|
||||||
|
#include "gui/AppConfig.h"
|
||||||
|
|
||||||
#include <QDialog>
|
#include <QDialog>
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
|
|
||||||
|
|
@ -28,14 +30,14 @@ class SetupWizard : public QDialog, public Ui::SetupWizardBase {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit SetupWizard(MainWindow &mainWindow);
|
explicit SetupWizard(AppConfig &appConfig);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void accept();
|
void accept();
|
||||||
void reject();
|
void reject();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
MainWindow &m_mainWindow;
|
AppConfig &m_appConfig;
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void onLineEditNameChanged(const QString &error);
|
void onLineEditNameChanged(const QString &error);
|
||||||
|
|
|
||||||
|
|
@ -6,8 +6,8 @@
|
||||||
<rect>
|
<rect>
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>772</width>
|
<width>764</width>
|
||||||
<height>634</height>
|
<height>612</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<property name="sizePolicy">
|
<property name="sizePolicy">
|
||||||
|
|
@ -36,10 +36,10 @@
|
||||||
<number>20</number>
|
<number>20</number>
|
||||||
</property>
|
</property>
|
||||||
<property name="leftMargin">
|
<property name="leftMargin">
|
||||||
<number>100</number>
|
<number>150</number>
|
||||||
</property>
|
</property>
|
||||||
<property name="rightMargin">
|
<property name="rightMargin">
|
||||||
<number>100</number>
|
<number>150</number>
|
||||||
</property>
|
</property>
|
||||||
<item>
|
<item>
|
||||||
<spacer name="verticalSpacer_2">
|
<spacer name="verticalSpacer_2">
|
||||||
|
|
@ -54,7 +54,7 @@
|
||||||
</property>
|
</property>
|
||||||
</spacer>
|
</spacer>
|
||||||
</item>
|
</item>
|
||||||
<item alignment="Qt::AlignHCenter">
|
<item alignment="Qt::AlignHCenter|Qt::AlignTop">
|
||||||
<widget class="QLabel" name="m_pLabelImage">
|
<widget class="QLabel" name="m_pLabelImage">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string/>
|
<string/>
|
||||||
|
|
@ -63,11 +63,11 @@
|
||||||
<pixmap resource="../res/Synergy.qrc">:/res/image/welcome.png</pixmap>
|
<pixmap resource="../res/Synergy.qrc">:/res/image/welcome.png</pixmap>
|
||||||
</property>
|
</property>
|
||||||
<property name="margin">
|
<property name="margin">
|
||||||
<number>30</number>
|
<number>1</number>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item alignment="Qt::AlignHCenter">
|
<item alignment="Qt::AlignHCenter|Qt::AlignTop">
|
||||||
<widget class="QLabel" name="m_pLabelTitle">
|
<widget class="QLabel" name="m_pLabelTitle">
|
||||||
<property name="font">
|
<property name="font">
|
||||||
<font>
|
<font>
|
||||||
|
|
@ -86,6 +86,15 @@
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<layout class="QFormLayout" name="formLayout">
|
<layout class="QFormLayout" name="formLayout">
|
||||||
|
<property name="leftMargin">
|
||||||
|
<number>50</number>
|
||||||
|
</property>
|
||||||
|
<property name="topMargin">
|
||||||
|
<number>30</number>
|
||||||
|
</property>
|
||||||
|
<property name="rightMargin">
|
||||||
|
<number>50</number>
|
||||||
|
</property>
|
||||||
<item row="0" column="0">
|
<item row="0" column="0">
|
||||||
<widget class="QLabel" name="m_pLabelName">
|
<widget class="QLabel" name="m_pLabelName">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
|
|
@ -121,7 +130,7 @@
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</item>
|
</item>
|
||||||
<item alignment="Qt::AlignHCenter">
|
<item alignment="Qt::AlignHCenter|Qt::AlignTop">
|
||||||
<widget class="QLabel" name="m_pHelpList">
|
<widget class="QLabel" name="m_pHelpList">
|
||||||
<property name="sizePolicy">
|
<property name="sizePolicy">
|
||||||
<sizepolicy hsizetype="Fixed" vsizetype="Preferred">
|
<sizepolicy hsizetype="Fixed" vsizetype="Preferred">
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* synergy -- mouse and keyboard sharing utility
|
* synergy -- mouse and keyboard sharing utility
|
||||||
* Copyright (C) 2016 Symless Ltd.
|
* Copyright (C) 2021 Symless Ltd.
|
||||||
*
|
*
|
||||||
* This package is free software; you can redistribute it and/or
|
* This package is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License
|
* modify it under the terms of the GNU General Public License
|
||||||
|
|
@ -33,9 +33,7 @@ static const std::vector<const char *> blockerText = {
|
||||||
"Please switch to Xorg if you wish to continue using Synergy today.",
|
"Please switch to Xorg if you wish to continue using Synergy today.",
|
||||||
};
|
};
|
||||||
|
|
||||||
SetupWizardBlocker::SetupWizardBlocker(
|
SetupWizardBlocker::SetupWizardBlocker(BlockerType type) {
|
||||||
MainWindow &mainWindow, qBlockerType type)
|
|
||||||
: m_MainWindow(mainWindow) {
|
|
||||||
setupUi(this);
|
setupUi(this);
|
||||||
|
|
||||||
m_pLabelTitle->setText(blockerTitels[static_cast<int>(type)]);
|
m_pLabelTitle->setText(blockerTitels[static_cast<int>(type)]);
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* synergy -- mouse and keyboard sharing utility
|
* synergy -- mouse and keyboard sharing utility
|
||||||
* Copyright (C) 2012-2016 Symless Ltd.
|
* Copyright (C) 2021 Symless Ltd.
|
||||||
*
|
*
|
||||||
* This package is free software; you can redistribute it and/or
|
* This package is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License
|
* modify it under the terms of the GNU General Public License
|
||||||
|
|
@ -16,7 +16,9 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "ui_SetupWizardBlocker.h"
|
#include "ui_SetupWizardBlocker.h"
|
||||||
|
|
||||||
#include <QDialog>
|
#include <QDialog>
|
||||||
|
|
||||||
class MainWindow;
|
class MainWindow;
|
||||||
|
|
@ -25,13 +27,10 @@ class SetupWizardBlocker : public QDialog, public Ui::SetupWizardBlocker {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
enum class qBlockerType { waylandDetected };
|
enum class BlockerType { Wayland };
|
||||||
explicit SetupWizardBlocker(MainWindow &mainWindow, qBlockerType type);
|
explicit SetupWizardBlocker(BlockerType type);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void onlineSupport();
|
void onlineSupport();
|
||||||
void cancel();
|
void cancel();
|
||||||
|
|
||||||
private:
|
|
||||||
MainWindow &m_MainWindow;
|
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -21,9 +21,16 @@
|
||||||
#include "SetupWizard.h"
|
#include "SetupWizard.h"
|
||||||
#include "SetupWizardBlocker.h"
|
#include "SetupWizardBlocker.h"
|
||||||
#include "gui/AppConfig.h"
|
#include "gui/AppConfig.h"
|
||||||
|
#include "gui/ConfigScopes.h"
|
||||||
|
#include "gui/constants.h"
|
||||||
#include "gui/dotenv.h"
|
#include "gui/dotenv.h"
|
||||||
|
#include "gui/messages.h"
|
||||||
|
#include "gui/version.h"
|
||||||
|
|
||||||
|
#include <QApplication>
|
||||||
|
#include <QDebug>
|
||||||
#include <QMessageBox>
|
#include <QMessageBox>
|
||||||
|
#include <QObject>
|
||||||
#include <QtCore>
|
#include <QtCore>
|
||||||
#include <QtGui>
|
#include <QtGui>
|
||||||
|
|
||||||
|
|
@ -46,19 +53,23 @@ bool checkMacAssistiveDevices();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
int main(int argc, char *argv[]) {
|
int main(int argc, char *argv[]) {
|
||||||
|
|
||||||
#ifdef Q_OS_DARWIN
|
#ifdef Q_OS_DARWIN
|
||||||
/* Workaround for QTBUG-40332 - "High ping when QNetworkAccessManager is
|
/* Workaround for QTBUG-40332 - "High ping when QNetworkAccessManager is
|
||||||
* instantiated" */
|
* instantiated" */
|
||||||
::setenv("QT_BEARER_POLL_TIMEOUT", "-1", 1);
|
::setenv("QT_BEARER_POLL_TIMEOUT", "-1", 1);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
dotenv(".env");
|
QCoreApplication::setOrganizationName(kAppName);
|
||||||
|
QCoreApplication::setApplicationName(kAppName);
|
||||||
QCoreApplication::setOrganizationName("Synergy");
|
QCoreApplication::setOrganizationDomain(kAppDomain);
|
||||||
QCoreApplication::setOrganizationDomain("http://symless.com/");
|
|
||||||
QCoreApplication::setApplicationName("Synergy");
|
|
||||||
|
|
||||||
QSynergyApplication app(argc, argv);
|
QSynergyApplication app(argc, argv);
|
||||||
|
qInstallMessageHandler(synergy::gui::messages::messageHandler);
|
||||||
|
|
||||||
|
qInfo("Synergy v%s", synergy::gui::version().toUtf8().constData());
|
||||||
|
|
||||||
|
dotenv(".env");
|
||||||
|
|
||||||
#if defined(Q_OS_MAC)
|
#if defined(Q_OS_MAC)
|
||||||
|
|
||||||
|
|
@ -75,31 +86,41 @@ int main(int argc, char *argv[]) {
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
AppConfig appConfig;
|
|
||||||
qRegisterMetaType<Edition>("Edition");
|
qRegisterMetaType<Edition>("Edition");
|
||||||
|
|
||||||
MainWindow mainWindow(appConfig);
|
ConfigScopes configScopes;
|
||||||
|
AppConfig appConfig(configScopes);
|
||||||
|
|
||||||
|
QObject::connect(
|
||||||
|
&configScopes, &ConfigScopes::saving, &appConfig,
|
||||||
|
[&appConfig]() { appConfig.commit(); }, Qt::DirectConnection);
|
||||||
|
|
||||||
|
std::unique_ptr<SetupWizardBlocker> setupBlocker;
|
||||||
|
if (qgetenv("XDG_SESSION_TYPE") == "wayland") {
|
||||||
|
SetupWizardBlocker blocked(SetupWizardBlocker::BlockerType::Wayland);
|
||||||
|
blocked.exec();
|
||||||
|
qInfo("wayland detected, exiting");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (appConfig.wizardShouldRun()) {
|
||||||
|
SetupWizard wizard(appConfig);
|
||||||
|
auto result = wizard.exec();
|
||||||
|
if (result != QDialog::Accepted) {
|
||||||
|
qInfo("wizard cancelled, exiting");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
configScopes.save();
|
||||||
|
}
|
||||||
|
|
||||||
|
MainWindow mainWindow(configScopes, appConfig);
|
||||||
|
|
||||||
QObject::connect(
|
QObject::connect(
|
||||||
&app, &QSynergyApplication::aboutToQuit, &mainWindow,
|
&app, &QSynergyApplication::aboutToQuit, &mainWindow,
|
||||||
&MainWindow::onAppAboutToQuit);
|
&MainWindow::onAppAboutToQuit);
|
||||||
|
|
||||||
std::unique_ptr<SetupWizardBlocker> setupBlocker;
|
mainWindow.open();
|
||||||
if (qgetenv("XDG_SESSION_TYPE") == "wayland") {
|
|
||||||
setupBlocker.reset(new SetupWizardBlocker(
|
|
||||||
mainWindow, SetupWizardBlocker::qBlockerType::waylandDetected));
|
|
||||||
setupBlocker->show();
|
|
||||||
return QApplication::exec();
|
|
||||||
}
|
|
||||||
|
|
||||||
std::unique_ptr<SetupWizard> setupWizard;
|
|
||||||
if (appConfig.wizardShouldRun()) {
|
|
||||||
setupWizard.reset(new SetupWizard(mainWindow));
|
|
||||||
setupWizard->show();
|
|
||||||
} else {
|
|
||||||
mainWindow.open();
|
|
||||||
}
|
|
||||||
|
|
||||||
return QSynergyApplication::exec();
|
return QSynergyApplication::exec();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,7 @@
|
||||||
|
|
||||||
#include "LineEditValidator.h"
|
#include "LineEditValidator.h"
|
||||||
|
|
||||||
#include "gui/constants.h"
|
#include "gui/styles.h"
|
||||||
#include <qvalidator.h>
|
#include <qvalidator.h>
|
||||||
|
|
||||||
namespace validators {
|
namespace validators {
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,7 @@
|
||||||
|
|
||||||
#include "ValidationError.h"
|
#include "ValidationError.h"
|
||||||
|
|
||||||
#include "gui/constants.h"
|
#include "gui/styles.h"
|
||||||
|
|
||||||
namespace validators {
|
namespace validators {
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -49,8 +49,6 @@ static const int s_family[] = {
|
||||||
|
|
||||||
static const int s_type[] = {SOCK_DGRAM, SOCK_STREAM};
|
static const int s_type[] = {SOCK_DGRAM, SOCK_STREAM};
|
||||||
|
|
||||||
ArchNetworkBSD::Deps ArchNetworkBSD::s_deps;
|
|
||||||
|
|
||||||
#if !HAVE_INET_ATON
|
#if !HAVE_INET_ATON
|
||||||
// parse dotted quad addresses. we don't bother with the weird BSD'ism
|
// parse dotted quad addresses. we don't bother with the weird BSD'ism
|
||||||
// of handling octal and hex and partial forms.
|
// of handling octal and hex and partial forms.
|
||||||
|
|
@ -274,13 +272,13 @@ int ArchNetworkBSD::pollSocket(PollEntry pe[], int num, double timeout) {
|
||||||
// return if nothing to do
|
// return if nothing to do
|
||||||
if (num == 0) {
|
if (num == 0) {
|
||||||
if (timeout > 0.0) {
|
if (timeout > 0.0) {
|
||||||
m_deps.sleep(timeout);
|
m_pDeps->sleep(timeout);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// allocate space for translated query
|
// allocate space for translated query
|
||||||
auto pfdPtr = m_deps.makePollFD(1 + num);
|
auto pfdPtr = m_pDeps->makePollFD(1 + num);
|
||||||
auto *pfd = pfdPtr.get();
|
auto *pfd = pfdPtr.get();
|
||||||
|
|
||||||
// translate query
|
// translate query
|
||||||
|
|
@ -308,14 +306,14 @@ int ArchNetworkBSD::pollSocket(PollEntry pe[], int num, double timeout) {
|
||||||
int t = (timeout < 0.0) ? -1 : static_cast<int>(1000.0 * timeout);
|
int t = (timeout < 0.0) ? -1 : static_cast<int>(1000.0 * timeout);
|
||||||
|
|
||||||
// do the poll
|
// do the poll
|
||||||
n = m_deps.poll(pfd, n, t);
|
n = m_pDeps->poll(pfd, n, t);
|
||||||
|
|
||||||
// reset the unblock pipe
|
// reset the unblock pipe
|
||||||
if (n > 0 && unblockPipe != nullptr && (pfd[num].revents & POLLIN) != 0) {
|
if (n > 0 && unblockPipe != nullptr && (pfd[num].revents & POLLIN) != 0) {
|
||||||
// the unblock event was signalled. flush the pipe.
|
// the unblock event was signalled. flush the pipe.
|
||||||
char dummy[100];
|
char dummy[100];
|
||||||
do {
|
do {
|
||||||
m_deps.read(unblockPipe[0], dummy, sizeof(dummy));
|
m_pDeps->read(unblockPipe[0], dummy, sizeof(dummy));
|
||||||
} while (errno != EAGAIN);
|
} while (errno != EAGAIN);
|
||||||
|
|
||||||
// don't count this unblock pipe in return value
|
// don't count this unblock pipe in return value
|
||||||
|
|
@ -326,7 +324,7 @@ int ArchNetworkBSD::pollSocket(PollEntry pe[], int num, double timeout) {
|
||||||
if (n == -1) {
|
if (n == -1) {
|
||||||
if (errno == EINTR) {
|
if (errno == EINTR) {
|
||||||
// interrupted system call
|
// interrupted system call
|
||||||
m_deps.testCancelThread();
|
m_pDeps->testCancelThread();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
throwError(errno);
|
throwError(errno);
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,7 @@
|
||||||
|
|
||||||
#include "arch/IArchMultithread.h"
|
#include "arch/IArchMultithread.h"
|
||||||
#include "arch/IArchNetwork.h"
|
#include "arch/IArchNetwork.h"
|
||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
#if HAVE_SYS_TYPES_H
|
#if HAVE_SYS_TYPES_H
|
||||||
|
|
@ -69,6 +70,7 @@ public:
|
||||||
|
|
||||||
//! Berkeley (BSD) sockets implementation of IArchNetwork
|
//! Berkeley (BSD) sockets implementation of IArchNetwork
|
||||||
class ArchNetworkBSD : public IArchNetwork {
|
class ArchNetworkBSD : public IArchNetwork {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
struct Deps {
|
struct Deps {
|
||||||
virtual ~Deps() = default;
|
virtual ~Deps() = default;
|
||||||
|
|
@ -79,8 +81,8 @@ public:
|
||||||
virtual void testCancelThread();
|
virtual void testCancelThread();
|
||||||
};
|
};
|
||||||
|
|
||||||
explicit ArchNetworkBSD() : m_deps(s_deps) {}
|
explicit ArchNetworkBSD(std::shared_ptr<Deps> deps = std::make_shared<Deps>())
|
||||||
explicit ArchNetworkBSD(Deps &deps) : m_deps(deps) {}
|
: m_pDeps(deps) {}
|
||||||
ArchNetworkBSD(ArchNetworkBSD const &) = delete;
|
ArchNetworkBSD(ArchNetworkBSD const &) = delete;
|
||||||
ArchNetworkBSD(ArchNetworkBSD &&) = delete;
|
ArchNetworkBSD(ArchNetworkBSD &&) = delete;
|
||||||
~ArchNetworkBSD() override;
|
~ArchNetworkBSD() override;
|
||||||
|
|
@ -128,7 +130,6 @@ private:
|
||||||
void throwNameError(int);
|
void throwNameError(int);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static Deps s_deps;
|
std::shared_ptr<Deps> m_pDeps;
|
||||||
Deps &m_deps;
|
|
||||||
ArchMutex m_mutex{};
|
ArchMutex m_mutex{};
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -86,146 +86,156 @@ const char *const AppConfig::m_SettingsName[] = {
|
||||||
"initiateConnectionFromServer", // kInvertConnection
|
"initiateConnectionFromServer", // kInvertConnection
|
||||||
"", // 35 = clientHostMode, obsolete
|
"", // 35 = clientHostMode, obsolete
|
||||||
"", // 36 = serverClientMode, obsolete
|
"", // 36 = serverClientMode, obsolete
|
||||||
"serviceEnabled",
|
"enableService",
|
||||||
"closeToTray",
|
"closeToTray",
|
||||||
"mainWindowSize",
|
"mainWindowSize",
|
||||||
"mainWindowPosition",
|
"mainWindowPosition",
|
||||||
|
"showDevThanks",
|
||||||
|
"showCloseReminder",
|
||||||
};
|
};
|
||||||
|
|
||||||
static const char *logLevelNames[] = {"INFO", "DEBUG", "DEBUG1", "DEBUG2"};
|
static const char *logLevelNames[] = {"INFO", "DEBUG", "DEBUG1", "DEBUG2"};
|
||||||
|
|
||||||
AppConfig::Deps AppConfig::s_Deps;
|
AppConfig::AppConfig(
|
||||||
|
synergy::gui::IConfigScopes &scopes, std::shared_ptr<Deps> deps)
|
||||||
AppConfig::AppConfig(Deps &deps) : m_Deps(deps), m_ScreenName(deps.hostname()) {
|
: m_scopes(scopes),
|
||||||
|
m_pDeps(deps),
|
||||||
m_Deps.scopes().registerReceiver(this);
|
m_ScreenName(deps->hostname()) {
|
||||||
|
determineScope();
|
||||||
|
recall();
|
||||||
}
|
}
|
||||||
|
|
||||||
void AppConfig::loadAllScopes() {
|
void AppConfig::recall() {
|
||||||
m_Deps.scopes().loadAll();
|
|
||||||
|
|
||||||
// User settings exist and the load from system scope variable is true
|
|
||||||
if (m_Deps.scopes().hasSetting(
|
|
||||||
settingName(Setting::kLoadSystemSettings),
|
|
||||||
ConfigScopes::Scope::User)) {
|
|
||||||
setLoadFromSystemScope(m_LoadFromSystemScope);
|
|
||||||
}
|
|
||||||
// If user setting don't exist but system ones do, load the system settings
|
|
||||||
else if (m_Deps.scopes().hasSetting(
|
|
||||||
settingName(Setting::kScreenName),
|
|
||||||
ConfigScopes::Scope::System)) {
|
|
||||||
setLoadFromSystemScope(true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void AppConfig::loadSettings() {
|
|
||||||
using enum AppConfig::Setting;
|
using enum AppConfig::Setting;
|
||||||
|
|
||||||
qDebug("loading settings");
|
qDebug("recalling app config");
|
||||||
|
|
||||||
loadCommonSettings();
|
recallFromAllScopes();
|
||||||
loadScopeSettings();
|
recallFromCurrentScope();
|
||||||
loadSerialKey();
|
|
||||||
loadElevateMode();
|
|
||||||
|
|
||||||
emit loaded();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void AppConfig::loadCommonSettings() {
|
void AppConfig::recallFromAllScopes() {
|
||||||
using enum Setting;
|
using enum Setting;
|
||||||
|
|
||||||
m_WizardLastRun = loadCommonSetting(kWizardLastRun, m_WizardLastRun).toInt();
|
m_WizardLastRun = findInAllScopes(kWizardLastRun, m_WizardLastRun).toInt();
|
||||||
m_LoadFromSystemScope =
|
m_LoadFromSystemScope =
|
||||||
loadCommonSetting(kLoadSystemSettings, m_LoadFromSystemScope).toBool();
|
findInAllScopes(kLoadSystemSettings, m_LoadFromSystemScope).toBool();
|
||||||
m_licenseNextCheck =
|
m_licenseNextCheck =
|
||||||
loadCommonSetting(kLicenseNextCheck, m_licenseNextCheck).toULongLong();
|
findInAllScopes(kLicenseNextCheck, m_licenseNextCheck).toULongLong();
|
||||||
}
|
}
|
||||||
|
|
||||||
void AppConfig::loadScopeSettings() {
|
void AppConfig::recallFromCurrentScope() {
|
||||||
using enum Setting;
|
using enum Setting;
|
||||||
|
|
||||||
loadScreenName();
|
recallScreenName();
|
||||||
|
recallSerialKey();
|
||||||
|
recallElevateMode();
|
||||||
|
|
||||||
m_Port = loadSetting(kPort, m_Port).toInt();
|
m_Port = getFromCurrentScope(kPort, m_Port).toInt();
|
||||||
m_Interface = loadSetting(kInterface, m_Interface).toString();
|
m_Interface = getFromCurrentScope(kInterface, m_Interface).toString();
|
||||||
m_LogLevel = loadSetting(kLogLevel, m_LogLevel).toInt();
|
m_LogLevel = getFromCurrentScope(kLogLevel, m_LogLevel).toInt();
|
||||||
m_LogToFile = loadSetting(kLogToFile, m_LogToFile).toBool();
|
m_LogToFile = getFromCurrentScope(kLogToFile, m_LogToFile).toBool();
|
||||||
m_LogFilename = loadSetting(kLogFilename, m_LogFilename).toString();
|
m_LogFilename = getFromCurrentScope(kLogFilename, m_LogFilename).toString();
|
||||||
m_StartedBefore = loadSetting(kStartedBefore, m_StartedBefore).toBool();
|
m_StartedBefore =
|
||||||
m_AutoHide = loadSetting(kAutoHide, m_AutoHide).toBool();
|
getFromCurrentScope(kStartedBefore, m_StartedBefore).toBool();
|
||||||
m_LastVersion = loadSetting(kLastVersion, m_LastVersion).toString();
|
m_AutoHide = getFromCurrentScope(kAutoHide, m_AutoHide).toBool();
|
||||||
|
m_LastVersion = getFromCurrentScope(kLastVersion, m_LastVersion).toString();
|
||||||
m_ActivationHasRun =
|
m_ActivationHasRun =
|
||||||
loadSetting(kActivationHasRun, m_ActivationHasRun).toBool();
|
getFromCurrentScope(kActivationHasRun, m_ActivationHasRun).toBool();
|
||||||
m_ServerGroupChecked =
|
m_ServerGroupChecked =
|
||||||
loadSetting(kServerGroupChecked, m_ServerGroupChecked).toBool();
|
getFromCurrentScope(kServerGroupChecked, m_ServerGroupChecked).toBool();
|
||||||
m_UseExternalConfig =
|
m_UseExternalConfig =
|
||||||
loadSetting(kUseExternalConfig, m_UseExternalConfig).toBool();
|
getFromCurrentScope(kUseExternalConfig, m_UseExternalConfig).toBool();
|
||||||
m_ConfigFile = loadSetting(kConfigFile, m_ConfigFile).toString();
|
m_ConfigFile = getFromCurrentScope(kConfigFile, m_ConfigFile).toString();
|
||||||
m_UseInternalConfig =
|
m_UseInternalConfig =
|
||||||
loadSetting(kUseInternalConfig, m_UseInternalConfig).toBool();
|
getFromCurrentScope(kUseInternalConfig, m_UseInternalConfig).toBool();
|
||||||
m_ClientGroupChecked =
|
m_ClientGroupChecked =
|
||||||
loadSetting(kClientGroupChecked, m_ClientGroupChecked).toBool();
|
getFromCurrentScope(kClientGroupChecked, m_ClientGroupChecked).toBool();
|
||||||
m_ServerHostname = loadSetting(kServerHostname, m_ServerHostname).toString();
|
m_ServerHostname =
|
||||||
m_PreventSleep = loadSetting(kPreventSleep, m_PreventSleep).toBool();
|
getFromCurrentScope(kServerHostname, m_ServerHostname).toString();
|
||||||
m_LanguageSync = loadSetting(kLanguageSync, m_LanguageSync).toBool();
|
m_PreventSleep = getFromCurrentScope(kPreventSleep, m_PreventSleep).toBool();
|
||||||
|
m_LanguageSync = getFromCurrentScope(kLanguageSync, m_LanguageSync).toBool();
|
||||||
m_InvertScrollDirection =
|
m_InvertScrollDirection =
|
||||||
loadSetting(kInvertScrollDirection, m_InvertScrollDirection).toBool();
|
getFromCurrentScope(kInvertScrollDirection, m_InvertScrollDirection)
|
||||||
|
.toBool();
|
||||||
m_InvertConnection =
|
m_InvertConnection =
|
||||||
loadSetting(kInvertConnection, m_InvertConnection).toBool();
|
getFromCurrentScope(kInvertConnection, m_InvertConnection).toBool();
|
||||||
m_ServiceEnabled = loadSetting(kServiceEnabled, m_ServiceEnabled).toBool();
|
m_EnableService =
|
||||||
m_CloseToTray = loadSetting(kCloseToTray, m_CloseToTray).toBool();
|
getFromCurrentScope(kEnableService, m_EnableService).toBool();
|
||||||
m_TlsEnabled = loadSetting(kTlsEnabled, m_TlsEnabled).toBool();
|
m_CloseToTray = getFromCurrentScope(kCloseToTray, m_CloseToTray).toBool();
|
||||||
m_TlsCertPath = loadSetting(kTlsCertPath, m_TlsCertPath).toString();
|
m_TlsEnabled = getFromCurrentScope(kTlsEnabled, m_TlsEnabled).toBool();
|
||||||
m_TlsKeyLength = loadSetting(kTlsKeyLength, m_TlsKeyLength).toString();
|
m_TlsCertPath = getFromCurrentScope(kTlsCertPath, m_TlsCertPath).toString();
|
||||||
m_MainWindowPosition = loadOptional<QPoint>(
|
m_TlsKeyLength =
|
||||||
kMainWindowPosition, [](QVariant v) { return v.toPoint(); });
|
getFromCurrentScope(kTlsKeyLength, m_TlsKeyLength).toString();
|
||||||
m_MainWindowSize = loadOptional<QSize>(
|
m_MainWindowPosition = getFromCurrentScope<QPoint>(
|
||||||
kMainWindowSize, [](QVariant v) { return v.toSize(); });
|
kMainWindowPosition, [](const QVariant &v) { return v.toPoint(); });
|
||||||
|
m_MainWindowSize = getFromCurrentScope<QSize>(
|
||||||
|
kMainWindowSize, [](const QVariant &v) { return v.toSize(); });
|
||||||
|
m_ShowDevThanks =
|
||||||
|
getFromCurrentScope(kShowDevThanks, m_ShowDevThanks).toBool();
|
||||||
|
m_ShowCloseReminder =
|
||||||
|
getFromCurrentScope(kShowCloseReminder, m_ShowCloseReminder).toBool();
|
||||||
}
|
}
|
||||||
|
|
||||||
void AppConfig::saveSettings() {
|
void AppConfig::recallScreenName() {
|
||||||
using enum Setting;
|
using enum Setting;
|
||||||
|
|
||||||
qDebug("saving settings");
|
const auto &screenName =
|
||||||
|
getFromCurrentScope(kScreenName, m_ScreenName).toString().trimmed();
|
||||||
|
|
||||||
setCommonSetting(kWizardLastRun, m_WizardLastRun);
|
// for some reason, the screen name can be saved as an empty string
|
||||||
setCommonSetting(kLoadSystemSettings, m_LoadFromSystemScope);
|
// in the config file. this is probably a bug. if this happens, then default
|
||||||
setCommonSetting(kClientGroupChecked, m_ClientGroupChecked);
|
// back to the hostname.
|
||||||
setCommonSetting(kServerGroupChecked, m_ServerGroupChecked);
|
if (screenName.isEmpty()) {
|
||||||
setCommonSetting(kLicenseNextCheck, m_licenseNextCheck);
|
qWarning("screen name was empty in config, setting to hostname");
|
||||||
|
m_ScreenName = m_pDeps->hostname();
|
||||||
if (isWritable()) {
|
} else {
|
||||||
setSetting(kScreenName, m_ScreenName);
|
m_ScreenName = screenName;
|
||||||
setSetting(kPort, m_Port);
|
|
||||||
setSetting(kInterface, m_Interface);
|
|
||||||
setSetting(kLogLevel, m_LogLevel);
|
|
||||||
setSetting(kLogToFile, m_LogToFile);
|
|
||||||
setSetting(kLogFilename, m_LogFilename);
|
|
||||||
setSetting(kStartedBefore, m_StartedBefore);
|
|
||||||
setSetting(kElevateMode, static_cast<int>(m_ElevateMode));
|
|
||||||
setSetting(kElevateModeLegacy, m_ElevateMode == ElevateAlways);
|
|
||||||
setSetting(kTlsEnabled, m_TlsEnabled);
|
|
||||||
setSetting(kAutoHide, m_AutoHide);
|
|
||||||
setSetting(kSerialKey, m_SerialKey);
|
|
||||||
setSetting(kLastVersion, m_LastVersion);
|
|
||||||
setSetting(kActivationHasRun, m_ActivationHasRun);
|
|
||||||
setSetting(kUseExternalConfig, m_UseExternalConfig);
|
|
||||||
setSetting(kConfigFile, m_ConfigFile);
|
|
||||||
setSetting(kUseInternalConfig, m_UseInternalConfig);
|
|
||||||
setSetting(kServerHostname, m_ServerHostname);
|
|
||||||
setSetting(kPreventSleep, m_PreventSleep);
|
|
||||||
setSetting(kLanguageSync, m_LanguageSync);
|
|
||||||
setSetting(kInvertScrollDirection, m_InvertScrollDirection);
|
|
||||||
setSetting(kInvertConnection, m_InvertConnection);
|
|
||||||
setSetting(kServiceEnabled, m_ServiceEnabled);
|
|
||||||
setSetting(kCloseToTray, m_CloseToTray);
|
|
||||||
setOptional(kMainWindowSize, m_MainWindowSize);
|
|
||||||
setOptional(kMainWindowPosition, m_MainWindowPosition);
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
setModified(false);
|
void AppConfig::commit() {
|
||||||
|
using enum Setting;
|
||||||
|
|
||||||
emit saved();
|
qDebug("comitting app config");
|
||||||
|
|
||||||
|
saveToAllScopes(kWizardLastRun, m_WizardLastRun);
|
||||||
|
saveToAllScopes(kLoadSystemSettings, m_LoadFromSystemScope);
|
||||||
|
saveToAllScopes(kClientGroupChecked, m_ClientGroupChecked);
|
||||||
|
saveToAllScopes(kServerGroupChecked, m_ServerGroupChecked);
|
||||||
|
saveToAllScopes(kLicenseNextCheck, m_licenseNextCheck);
|
||||||
|
|
||||||
|
if (isActiveScopeWritable()) {
|
||||||
|
setInCurrentScope(kScreenName, m_ScreenName);
|
||||||
|
setInCurrentScope(kPort, m_Port);
|
||||||
|
setInCurrentScope(kInterface, m_Interface);
|
||||||
|
setInCurrentScope(kLogLevel, m_LogLevel);
|
||||||
|
setInCurrentScope(kLogToFile, m_LogToFile);
|
||||||
|
setInCurrentScope(kLogFilename, m_LogFilename);
|
||||||
|
setInCurrentScope(kStartedBefore, m_StartedBefore);
|
||||||
|
setInCurrentScope(kElevateMode, static_cast<int>(m_ElevateMode));
|
||||||
|
setInCurrentScope(kElevateModeLegacy, m_ElevateMode == ElevateAlways);
|
||||||
|
setInCurrentScope(kTlsEnabled, m_TlsEnabled);
|
||||||
|
setInCurrentScope(kAutoHide, m_AutoHide);
|
||||||
|
setInCurrentScope(kSerialKey, m_SerialKey);
|
||||||
|
setInCurrentScope(kLastVersion, m_LastVersion);
|
||||||
|
setInCurrentScope(kActivationHasRun, m_ActivationHasRun);
|
||||||
|
setInCurrentScope(kUseExternalConfig, m_UseExternalConfig);
|
||||||
|
setInCurrentScope(kConfigFile, m_ConfigFile);
|
||||||
|
setInCurrentScope(kUseInternalConfig, m_UseInternalConfig);
|
||||||
|
setInCurrentScope(kServerHostname, m_ServerHostname);
|
||||||
|
setInCurrentScope(kPreventSleep, m_PreventSleep);
|
||||||
|
setInCurrentScope(kLanguageSync, m_LanguageSync);
|
||||||
|
setInCurrentScope(kInvertScrollDirection, m_InvertScrollDirection);
|
||||||
|
setInCurrentScope(kInvertConnection, m_InvertConnection);
|
||||||
|
setInCurrentScope(kEnableService, m_EnableService);
|
||||||
|
setInCurrentScope(kCloseToTray, m_CloseToTray);
|
||||||
|
setInCurrentScope(kShowDevThanks, m_ShowDevThanks);
|
||||||
|
setInCurrentScope(kShowCloseReminder, m_ShowCloseReminder);
|
||||||
|
|
||||||
|
setInCurrentScope(kMainWindowSize, m_MainWindowSize);
|
||||||
|
setInCurrentScope(kMainWindowPosition, m_MainWindowPosition);
|
||||||
|
}
|
||||||
|
|
||||||
if (m_TlsChanged) {
|
if (m_TlsChanged) {
|
||||||
m_TlsChanged = false;
|
m_TlsChanged = false;
|
||||||
|
|
@ -233,37 +243,45 @@ void AppConfig::saveSettings() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void AppConfig::loadScreenName() {
|
void AppConfig::determineScope() {
|
||||||
using enum Setting;
|
|
||||||
|
|
||||||
const auto &screenName =
|
qDebug("determining config scope");
|
||||||
loadSetting(kScreenName, m_ScreenName).toString().trimmed();
|
|
||||||
|
|
||||||
// for some reason, the screen name can be saved as an empty string
|
// first, try to determine if the system scope should be used according to the
|
||||||
// in the config file. this is probably a bug. if this happens, then default
|
// user scope...
|
||||||
// back to the hostname.
|
if (m_scopes.scopeContains(
|
||||||
if (screenName.isEmpty()) {
|
settingName(Setting::kLoadSystemSettings),
|
||||||
qWarning("screen name was empty in config, setting to hostname");
|
ConfigScopes::Scope::User)) {
|
||||||
m_ScreenName = m_Deps.hostname();
|
auto loadFromSystemScope =
|
||||||
} else {
|
m_scopes
|
||||||
m_ScreenName = screenName;
|
.getFromScope(
|
||||||
|
settingName(Setting::kLoadSystemSettings),
|
||||||
|
m_LoadFromSystemScope, ConfigScopes::Scope::User)
|
||||||
|
.toBool();
|
||||||
|
|
||||||
|
setLoadFromSystemScope(loadFromSystemScope);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ...failing that, check the system scope instead to see if an arbitrary
|
||||||
|
// required setting is present. if it is, then we can assume that the system
|
||||||
|
// scope should be used.
|
||||||
|
else if (m_scopes.scopeContains(
|
||||||
|
settingName(Setting::kScreenName),
|
||||||
|
ConfigScopes::Scope::System)) {
|
||||||
|
setLoadFromSystemScope(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void AppConfig::loadSerialKey() {
|
void AppConfig::recallSerialKey() {
|
||||||
using enum Setting;
|
using enum Setting;
|
||||||
|
|
||||||
// only set the serial key if the current settings scope has they key.
|
if (!m_scopes.scopeContains(settingName(kLoadSystemSettings))) {
|
||||||
bool shouldLoad = m_Deps.scopes().hasSetting(
|
|
||||||
settingName(kLoadSystemSettings), ConfigScopes::Scope::Current);
|
|
||||||
|
|
||||||
if (!shouldLoad) {
|
|
||||||
qDebug("no serial key in current scope, skipping");
|
qDebug("no serial key in current scope, skipping");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto &serialKey =
|
const auto &serialKey =
|
||||||
loadSetting(kSerialKey, m_SerialKey).toString().trimmed();
|
getFromCurrentScope(kSerialKey, m_SerialKey).toString().trimmed();
|
||||||
|
|
||||||
if (serialKey.isEmpty()) {
|
if (serialKey.isEmpty()) {
|
||||||
qDebug("serial key is empty, skipping");
|
qDebug("serial key is empty, skipping");
|
||||||
|
|
@ -273,18 +291,18 @@ void AppConfig::loadSerialKey() {
|
||||||
m_SerialKey = serialKey;
|
m_SerialKey = serialKey;
|
||||||
}
|
}
|
||||||
|
|
||||||
void AppConfig::loadElevateMode() {
|
void AppConfig::recallElevateMode() {
|
||||||
using enum Setting;
|
using enum Setting;
|
||||||
|
|
||||||
if (!m_Deps.scopes().hasSetting(settingName(kElevateMode))) {
|
if (!m_scopes.scopeContains(settingName(kElevateMode))) {
|
||||||
qDebug("elevate mode not set yet, skipping");
|
qDebug("elevate mode not set yet, skipping");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
QVariant elevateMode = loadSetting(kElevateMode);
|
QVariant elevateMode = getFromCurrentScope(kElevateMode);
|
||||||
if (!elevateMode.isValid()) {
|
if (!elevateMode.isValid()) {
|
||||||
qDebug("elevate mode not valid, loading legacy setting");
|
qDebug("elevate mode not valid, loading legacy setting");
|
||||||
elevateMode = loadSetting(
|
elevateMode = getFromCurrentScope(
|
||||||
kElevateModeLegacy, QVariant(static_cast<int>(kDefaultElevateMode)));
|
kElevateModeLegacy, QVariant(static_cast<int>(kDefaultElevateMode)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -292,7 +310,7 @@ void AppConfig::loadElevateMode() {
|
||||||
}
|
}
|
||||||
|
|
||||||
QString AppConfig::defaultTlsCertPath() const {
|
QString AppConfig::defaultTlsCertPath() const {
|
||||||
QDir path(m_Deps.profileDir());
|
QDir path(m_pDeps->profileDir());
|
||||||
path = path.filePath("SSL");
|
path = path.filePath("SSL");
|
||||||
path = path.filePath("Synergy.pem");
|
path = path.filePath("Synergy.pem");
|
||||||
return path.absolutePath();
|
return path.absolutePath();
|
||||||
|
|
@ -303,103 +321,113 @@ QString AppConfig::settingName(Setting name) {
|
||||||
return m_SettingsName[index];
|
return m_SettingsName[index];
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T> void AppConfig::setSetting(Setting name, T value) {
|
template <typename T> void AppConfig::setInCurrentScope(Setting name, T value) {
|
||||||
m_Deps.scopes().setSetting(settingName(name), value);
|
m_scopes.setInScope(settingName(name), value);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T> void AppConfig::setCommonSetting(Setting name, T value) {
|
template <typename T> void AppConfig::saveToAllScopes(Setting name, T value) {
|
||||||
m_Deps.scopes().setSetting(
|
m_scopes.setInScope(settingName(name), value, ConfigScopes::Scope::User);
|
||||||
settingName(name), value, ConfigScopes::Scope::User);
|
m_scopes.setInScope(settingName(name), value, ConfigScopes::Scope::System);
|
||||||
m_Deps.scopes().setSetting(
|
|
||||||
settingName(name), value, ConfigScopes::Scope::System);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QVariant AppConfig::loadSetting(Setting name, const QVariant &defaultValue) {
|
QVariant AppConfig::getFromCurrentScope(
|
||||||
return m_Deps.scopes().loadSetting(settingName(name), defaultValue);
|
Setting name, const QVariant &defaultValue) const {
|
||||||
|
return m_scopes.getFromScope(settingName(name), defaultValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
std::optional<T>
|
std::optional<T> AppConfig::getFromCurrentScope(
|
||||||
AppConfig::loadOptional(Setting name, std::function<T(QVariant)> toType) const {
|
Setting name, std::function<T(const QVariant &)> toType) const {
|
||||||
if (m_Deps.scopes().hasSetting(settingName(name))) {
|
if (m_scopes.scopeContains(settingName(name))) {
|
||||||
return toType(m_Deps.scopes().loadSetting(settingName(name)));
|
return toType(m_scopes.getFromScope(settingName(name)));
|
||||||
} else {
|
} else {
|
||||||
return std::nullopt;
|
return std::nullopt;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
void AppConfig::setOptional(Setting name, const std::optional<T> &value) {
|
void AppConfig::setInCurrentScope(Setting name, const std::optional<T> &value) {
|
||||||
if (value.has_value()) {
|
if (value.has_value()) {
|
||||||
m_Deps.scopes().setSetting(settingName(name), value.value());
|
m_scopes.setInScope(settingName(name), value.value());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
QVariant
|
QVariant
|
||||||
AppConfig::loadCommonSetting(Setting name, const QVariant &defaultValue) const {
|
AppConfig::findInAllScopes(Setting name, const QVariant &defaultValue) const {
|
||||||
|
using enum ConfigScopes::Scope;
|
||||||
|
|
||||||
QVariant result(defaultValue);
|
QVariant result(defaultValue);
|
||||||
QString setting(settingName(name));
|
QString setting(settingName(name));
|
||||||
|
|
||||||
if (m_Deps.scopes().hasSetting(setting)) {
|
if (m_scopes.scopeContains(setting)) {
|
||||||
result = m_Deps.scopes().loadSetting(setting, defaultValue);
|
result = m_scopes.getFromScope(setting, defaultValue);
|
||||||
} else if (m_Deps.scopes().getScope() == ConfigScopes::Scope::System) {
|
} else if (m_scopes.activeScope() == System) {
|
||||||
if (m_Deps.scopes().hasSetting(setting, ConfigScopes::Scope::User)) {
|
if (m_scopes.scopeContains(setting, User)) {
|
||||||
result = m_Deps.scopes().loadSetting(
|
result = m_scopes.getFromScope(setting, defaultValue, User);
|
||||||
setting, defaultValue, ConfigScopes::Scope::User);
|
|
||||||
}
|
}
|
||||||
} else if (m_Deps.scopes().hasSetting(setting, ConfigScopes::Scope::System)) {
|
} else if (m_scopes.scopeContains(setting, System)) {
|
||||||
result = m_Deps.scopes().loadSetting(
|
result = m_scopes.getFromScope(setting, defaultValue, System);
|
||||||
setting, defaultValue, ConfigScopes::Scope::System);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
void AppConfig::loadScope(ConfigScopes::Scope scope) {
|
void AppConfig::loadScope(ConfigScopes::Scope scope) {
|
||||||
|
using enum ConfigScopes::Scope;
|
||||||
|
|
||||||
if (m_Deps.scopes().getScope() != scope) {
|
switch (scope) {
|
||||||
setDefaultValues();
|
case User:
|
||||||
m_Deps.scopes().setScope(scope);
|
qDebug("loading user settings scope");
|
||||||
if (m_Deps.scopes().hasSetting(
|
break;
|
||||||
settingName(Setting::kScreenName), m_Deps.scopes().getScope())) {
|
|
||||||
// If the user already has settings, then load them up now.
|
case System:
|
||||||
m_Deps.scopes().loadAll();
|
qDebug("loading system settings scope");
|
||||||
}
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
qFatal("invalid scope");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_scopes.activeScope() == scope) {
|
||||||
|
qDebug("already in required scope, skipping");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_scopes.setActiveScope(scope);
|
||||||
|
|
||||||
|
// only signal ready if there is at least one setting in the required scope.
|
||||||
|
// this prevents the current settings from being set back to default.
|
||||||
|
if (m_scopes.scopeContains(
|
||||||
|
settingName(Setting::kScreenName), m_scopes.activeScope())) {
|
||||||
|
m_scopes.signalReady();
|
||||||
|
} else {
|
||||||
|
qDebug("no screen name in scope, skipping");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void AppConfig::setDefaultValues() { m_InvertConnection = false; }
|
|
||||||
|
|
||||||
void AppConfig::setLoadFromSystemScope(bool value) {
|
void AppConfig::setLoadFromSystemScope(bool value) {
|
||||||
|
using enum ConfigScopes::Scope;
|
||||||
|
|
||||||
if (value) {
|
if (value) {
|
||||||
qDebug("loading system settings scope");
|
qDebug("loading system settings scope");
|
||||||
loadScope(ConfigScopes::Scope::System);
|
loadScope(System);
|
||||||
} else {
|
} else {
|
||||||
qDebug("loading user settings scope");
|
qDebug("loading user settings scope");
|
||||||
loadScope(ConfigScopes::Scope::User);
|
loadScope(User);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// set after loading scope since it may have been overridden.
|
||||||
* It's very imprortant to set this variable after loadScope
|
|
||||||
* because during scope loading this variable can be rewritten with old value
|
|
||||||
*/
|
|
||||||
m_LoadFromSystemScope = value;
|
m_LoadFromSystemScope = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AppConfig::isWritable() const { return m_Deps.scopes().isWritable(); }
|
bool AppConfig::isActiveScopeWritable() const {
|
||||||
|
return m_scopes.isActiveScopeWritable();
|
||||||
bool AppConfig::isSystemScoped() const {
|
|
||||||
return m_Deps.scopes().getScope() == ConfigScopes::Scope::System;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
bool AppConfig::isActiveScopeSystem() const {
|
||||||
void AppConfig::setSettingModified(T &variable, const T &newValue) {
|
return m_scopes.activeScope() == ConfigScopes::Scope::System;
|
||||||
if (variable != newValue) {
|
|
||||||
variable = newValue;
|
|
||||||
setModified(true);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QString AppConfig::logDir() const {
|
QString AppConfig::logDir() const {
|
||||||
// by default log to home dir
|
// by default log to home dir
|
||||||
return QDir::home().absolutePath() + "/";
|
return QDir::home().absolutePath() + "/";
|
||||||
|
|
@ -418,7 +446,7 @@ void AppConfig::persistLogDir() const {
|
||||||
// Begin getters
|
// Begin getters
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
IConfigScopes &AppConfig::scopes() { return m_Deps.scopes(); }
|
IConfigScopes &AppConfig::scopes() { return m_scopes; }
|
||||||
|
|
||||||
bool AppConfig::activationHasRun() const { return m_ActivationHasRun; }
|
bool AppConfig::activationHasRun() const { return m_ActivationHasRun; }
|
||||||
|
|
||||||
|
|
@ -439,7 +467,7 @@ const QString &AppConfig::logFilename() const { return m_LogFilename; }
|
||||||
QString AppConfig::logLevelText() const { return logLevelNames[logLevel()]; }
|
QString AppConfig::logLevelText() const { return logLevelNames[logLevel()]; }
|
||||||
|
|
||||||
ProcessMode AppConfig::processMode() const {
|
ProcessMode AppConfig::processMode() const {
|
||||||
return m_ServiceEnabled ? ProcessMode::kService : ProcessMode::kDesktop;
|
return m_EnableService ? ProcessMode::kService : ProcessMode::kDesktop;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AppConfig::wizardShouldRun() const {
|
bool AppConfig::wizardShouldRun() const {
|
||||||
|
|
@ -478,7 +506,7 @@ QString AppConfig::tlsCertPath() const { return m_TlsCertPath; }
|
||||||
|
|
||||||
QString AppConfig::tlsKeyLength() const { return m_TlsKeyLength; }
|
QString AppConfig::tlsKeyLength() const { return m_TlsKeyLength; }
|
||||||
|
|
||||||
bool AppConfig::serviceEnabled() const { return m_ServiceEnabled; }
|
bool AppConfig::enableService() const { return m_EnableService; }
|
||||||
|
|
||||||
bool AppConfig::closeToTray() const { return m_CloseToTray; }
|
bool AppConfig::closeToTray() const { return m_CloseToTray; }
|
||||||
|
|
||||||
|
|
@ -504,6 +532,10 @@ std::optional<QPoint> AppConfig::mainWindowPosition() const {
|
||||||
return m_MainWindowPosition;
|
return m_MainWindowPosition;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool AppConfig::showDevThanks() const { return m_ShowDevThanks; }
|
||||||
|
|
||||||
|
bool AppConfig::showCloseReminder() const { return m_ShowCloseReminder; }
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
// End getters
|
// End getters
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
@ -515,109 +547,94 @@ std::optional<QPoint> AppConfig::mainWindowPosition() const {
|
||||||
void AppConfig::clearSerialKey() { m_SerialKey.clear(); }
|
void AppConfig::clearSerialKey() { m_SerialKey.clear(); }
|
||||||
|
|
||||||
void AppConfig::setTlsEnabled(bool value) {
|
void AppConfig::setTlsEnabled(bool value) {
|
||||||
setSettingModified(m_TlsEnabled, value);
|
// we purposefully do not set the 'tls changed' flag when enabling/disabling
|
||||||
m_TlsChanged = true;
|
// tls, since that would cause the certificate to regenerate, which could get
|
||||||
|
// pretty annoying.
|
||||||
|
|
||||||
|
m_TlsEnabled = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
void AppConfig::setTlsCertPath(const QString &value) {
|
void AppConfig::setTlsCertPath(const QString &value) {
|
||||||
setSettingModified(m_TlsCertPath, value);
|
m_TlsChanged = m_TlsCertPath != value;
|
||||||
m_TlsChanged = true;
|
m_TlsCertPath = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
void AppConfig::setTlsKeyLength(const QString &value) {
|
void AppConfig::setTlsKeyLength(const QString &value) {
|
||||||
setSettingModified(m_TlsKeyLength, value);
|
m_TlsChanged = m_TlsKeyLength != value;
|
||||||
m_TlsChanged = true;
|
m_TlsKeyLength = value;
|
||||||
}
|
}
|
||||||
void AppConfig::setSerialKey(const QString &serialKey) {
|
void AppConfig::setSerialKey(const QString &serialKey) {
|
||||||
setSettingModified(m_SerialKey, serialKey);
|
m_SerialKey = serialKey;
|
||||||
setCommonSetting(Setting::kSerialKey, m_SerialKey);
|
saveToAllScopes(Setting::kSerialKey, m_SerialKey);
|
||||||
}
|
}
|
||||||
void AppConfig::setServerGroupChecked(bool newValue) {
|
void AppConfig::setServerGroupChecked(bool newValue) {
|
||||||
setSettingModified(m_ServerGroupChecked, newValue);
|
m_ServerGroupChecked = newValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
void AppConfig::setUseExternalConfig(bool newValue) {
|
void AppConfig::setUseExternalConfig(bool newValue) {
|
||||||
setSettingModified(m_UseExternalConfig, newValue);
|
m_UseExternalConfig = newValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
void AppConfig::setConfigFile(const QString &newValue) {
|
void AppConfig::setConfigFile(const QString &newValue) {
|
||||||
setSettingModified(m_ConfigFile, newValue);
|
m_ConfigFile = newValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
void AppConfig::setUseInternalConfig(bool newValue) {
|
void AppConfig::setUseInternalConfig(bool newValue) {
|
||||||
setSettingModified(m_UseInternalConfig, newValue);
|
m_UseInternalConfig = newValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
void AppConfig::setClientGroupChecked(bool newValue) {
|
void AppConfig::setClientGroupChecked(bool newValue) {
|
||||||
setSettingModified(m_ClientGroupChecked, newValue);
|
m_ClientGroupChecked = newValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
void AppConfig::setServerHostname(const QString &newValue) {
|
void AppConfig::setServerHostname(const QString &newValue) {
|
||||||
setSettingModified(m_ServerHostname, newValue);
|
m_ServerHostname = newValue;
|
||||||
}
|
}
|
||||||
void AppConfig::setLastVersion(const QString &version) {
|
void AppConfig::setLastVersion(const QString &version) {
|
||||||
setSettingModified(m_LastVersion, version);
|
m_LastVersion = version;
|
||||||
}
|
}
|
||||||
|
|
||||||
void AppConfig::setScreenName(const QString &s) {
|
void AppConfig::setScreenName(const QString &s) {
|
||||||
setSettingModified(m_ScreenName, s);
|
m_ScreenName = s;
|
||||||
emit screenNameChanged();
|
emit screenNameChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
void AppConfig::setPort(int i) { setSettingModified(m_Port, i); }
|
void AppConfig::setPort(int i) { m_Port = i; }
|
||||||
|
|
||||||
void AppConfig::setNetworkInterface(const QString &s) {
|
void AppConfig::setNetworkInterface(const QString &s) { m_Interface = s; }
|
||||||
setSettingModified(m_Interface, s);
|
|
||||||
}
|
|
||||||
|
|
||||||
void AppConfig::setLogLevel(int i) { setSettingModified(m_LogLevel, i); }
|
void AppConfig::setLogLevel(int i) { m_LogLevel = i; }
|
||||||
|
|
||||||
void AppConfig::setLogToFile(bool b) { setSettingModified(m_LogToFile, b); }
|
void AppConfig::setLogToFile(bool b) { m_LogToFile = b; }
|
||||||
|
|
||||||
void AppConfig::setLogFilename(const QString &s) {
|
void AppConfig::setLogFilename(const QString &s) { m_LogFilename = s; }
|
||||||
setSettingModified(m_LogFilename, s);
|
|
||||||
}
|
|
||||||
|
|
||||||
void AppConfig::setWizardHasRun() {
|
void AppConfig::setWizardHasRun() { m_WizardLastRun = kWizardVersion; }
|
||||||
setSettingModified(m_WizardLastRun, kWizardVersion);
|
|
||||||
}
|
|
||||||
|
|
||||||
void AppConfig::setStartedBefore(bool b) {
|
void AppConfig::setStartedBefore(bool b) { m_StartedBefore = b; }
|
||||||
setSettingModified(m_StartedBefore, b);
|
|
||||||
}
|
|
||||||
|
|
||||||
void AppConfig::setElevateMode(ElevateMode em) {
|
void AppConfig::setElevateMode(ElevateMode em) { m_ElevateMode = em; }
|
||||||
setSettingModified(m_ElevateMode, em);
|
|
||||||
}
|
|
||||||
|
|
||||||
void AppConfig::setAutoHide(bool b) { setSettingModified(m_AutoHide, b); }
|
void AppConfig::setAutoHide(bool b) { m_AutoHide = b; }
|
||||||
|
|
||||||
void AppConfig::setLicenseNextCheck(unsigned long long time) {
|
void AppConfig::setLicenseNextCheck(unsigned long long time) {
|
||||||
setSettingModified(m_licenseNextCheck, time);
|
m_licenseNextCheck = time;
|
||||||
}
|
}
|
||||||
|
|
||||||
void AppConfig::setInvertScrollDirection(bool newValue) {
|
void AppConfig::setInvertScrollDirection(bool newValue) {
|
||||||
setSettingModified(m_InvertScrollDirection, newValue);
|
m_InvertScrollDirection = newValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
void AppConfig::setLanguageSync(bool newValue) {
|
void AppConfig::setLanguageSync(bool newValue) { m_LanguageSync = newValue; }
|
||||||
setSettingModified(m_LanguageSync, newValue);
|
|
||||||
}
|
|
||||||
|
|
||||||
void AppConfig::setPreventSleep(bool newValue) {
|
void AppConfig::setPreventSleep(bool newValue) { m_PreventSleep = newValue; }
|
||||||
setSettingModified(m_PreventSleep, newValue);
|
|
||||||
}
|
|
||||||
|
|
||||||
void AppConfig::setServiceEnabled(bool enabled) {
|
void AppConfig::setEnableService(bool enabled) { m_EnableService = enabled; }
|
||||||
setSettingModified(m_ServiceEnabled, enabled);
|
|
||||||
}
|
|
||||||
|
|
||||||
void AppConfig::setCloseToTray(bool minimize) {
|
void AppConfig::setCloseToTray(bool minimize) { m_CloseToTray = minimize; }
|
||||||
setSettingModified(m_CloseToTray, minimize);
|
|
||||||
}
|
|
||||||
|
|
||||||
void AppConfig::setInvertConnection(bool value) {
|
void AppConfig::setInvertConnection(bool value) {
|
||||||
setSettingModified(m_InvertConnection, value);
|
m_InvertConnection = value;
|
||||||
emit invertConnectionChanged();
|
emit invertConnectionChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -629,6 +646,12 @@ void AppConfig::setMainWindowPosition(const QPoint &position) {
|
||||||
m_MainWindowPosition = position;
|
m_MainWindowPosition = position;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void AppConfig::setShowDevThanks(bool value) { m_ShowDevThanks = value; }
|
||||||
|
|
||||||
|
void AppConfig::setShowCloseReminder(bool value) {
|
||||||
|
m_ShowCloseReminder = value;
|
||||||
|
}
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
// End setters
|
// End setters
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,6 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "CommonConfig.h"
|
|
||||||
#include "ConfigScopes.h"
|
#include "ConfigScopes.h"
|
||||||
#include "CoreInterface.h"
|
#include "CoreInterface.h"
|
||||||
#include "ElevateMode.h"
|
#include "ElevateMode.h"
|
||||||
|
|
@ -31,7 +30,7 @@
|
||||||
#include <QSize>
|
#include <QSize>
|
||||||
#include <QString>
|
#include <QString>
|
||||||
#include <QVariant>
|
#include <QVariant>
|
||||||
#include <mutex>
|
#include <optional>
|
||||||
|
|
||||||
enum class ProcessMode { kService, kDesktop };
|
enum class ProcessMode { kService, kDesktop };
|
||||||
|
|
||||||
|
|
@ -42,7 +41,13 @@ const QString kDefaultLogFile = "synergy.log";
|
||||||
const ProcessMode kDefaultProcessMode = ProcessMode::kService;
|
const ProcessMode kDefaultProcessMode = ProcessMode::kService;
|
||||||
#else
|
#else
|
||||||
const ProcessMode kDefaultProcessMode = ProcessMode::kDesktop;
|
const ProcessMode kDefaultProcessMode = ProcessMode::kDesktop;
|
||||||
#endif
|
#endif // Q_OS_WIN
|
||||||
|
|
||||||
|
#ifdef SYNERGY_SHOW_DEV_THANKS
|
||||||
|
const bool kDefaultShowDevThanks = true;
|
||||||
|
#else
|
||||||
|
const bool kDefaultShowDevThanks = false;
|
||||||
|
#endif // SYNERGY_SHOW_DEV_THANKS
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Simply reads and writes app settings.
|
* @brief Simply reads and writes app settings.
|
||||||
|
|
@ -52,9 +57,7 @@ const ProcessMode kDefaultProcessMode = ProcessMode::kDesktop;
|
||||||
* instance is widely accessible, but that has previously led to this class
|
* instance is widely accessible, but that has previously led to this class
|
||||||
* becoming a god object.
|
* becoming a god object.
|
||||||
*/
|
*/
|
||||||
class AppConfig : public QObject,
|
class AppConfig : public QObject, public synergy::gui::IAppConfig {
|
||||||
public synergy::gui::CommonConfig,
|
|
||||||
public synergy::gui::IAppConfig {
|
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
@ -96,10 +99,12 @@ private:
|
||||||
kInvertConnection = 34,
|
kInvertConnection = 34,
|
||||||
// 35 = client-host-mode, obsolete
|
// 35 = client-host-mode, obsolete
|
||||||
// 36 = server-client-mode, obsolete
|
// 36 = server-client-mode, obsolete
|
||||||
kServiceEnabled = 37,
|
kEnableService = 37,
|
||||||
kCloseToTray = 38,
|
kCloseToTray = 38,
|
||||||
kMainWindowSize = 39,
|
kMainWindowSize = 39,
|
||||||
kMainWindowPosition = 40,
|
kMainWindowPosition = 40,
|
||||||
|
kShowDevThanks = 41,
|
||||||
|
kShowCloseReminder = 42,
|
||||||
};
|
};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
@ -108,29 +113,33 @@ public:
|
||||||
virtual QString profileDir() const {
|
virtual QString profileDir() const {
|
||||||
return m_coreInterface.getProfileDir();
|
return m_coreInterface.getProfileDir();
|
||||||
}
|
}
|
||||||
virtual synergy::gui::IConfigScopes &scopes() { return m_Scopes; }
|
|
||||||
virtual QString hostname() const { return QHostInfo::localHostName(); }
|
virtual QString hostname() const { return QHostInfo::localHostName(); }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
[[no_unique_address]] CoreInterface m_coreInterface;
|
[[no_unique_address]] CoreInterface m_coreInterface;
|
||||||
synergy::gui::ConfigScopes m_Scopes;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
explicit AppConfig() : AppConfig(s_Deps) {}
|
explicit AppConfig(
|
||||||
explicit AppConfig(Deps &deps);
|
synergy::gui::IConfigScopes &scopes,
|
||||||
|
std::shared_ptr<Deps> deps = std::make_shared<Deps>());
|
||||||
|
|
||||||
synergy::gui::IConfigScopes &scopes();
|
synergy::gui::IConfigScopes &scopes();
|
||||||
void saveSettings() override;
|
|
||||||
void loadAllScopes();
|
/**
|
||||||
void loadSettings() override;
|
* @brief Commits the current settings to the active scope.
|
||||||
|
* This should only be called when the settings are about to be saved.
|
||||||
|
*/
|
||||||
|
void commit();
|
||||||
|
|
||||||
|
void determineScope();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Getters
|
* Getters
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void setActivationHasRun(bool value);
|
void setActivationHasRun(bool value);
|
||||||
bool isWritable() const;
|
bool isActiveScopeWritable() const;
|
||||||
bool isSystemScoped() const;
|
bool isActiveScopeSystem() const;
|
||||||
const QString &screenName() const;
|
const QString &screenName() const;
|
||||||
int port() const;
|
int port() const;
|
||||||
const QString &networkInterface() const;
|
const QString &networkInterface() const;
|
||||||
|
|
@ -159,7 +168,7 @@ public:
|
||||||
bool clientGroupChecked() const;
|
bool clientGroupChecked() const;
|
||||||
QString serverHostname() const;
|
QString serverHostname() const;
|
||||||
QString lastVersion() const;
|
QString lastVersion() const;
|
||||||
bool serviceEnabled() const;
|
bool enableService() const;
|
||||||
bool closeToTray() const;
|
bool closeToTray() const;
|
||||||
QString serialKey() const;
|
QString serialKey() const;
|
||||||
bool activationHasRun() const;
|
bool activationHasRun() const;
|
||||||
|
|
@ -168,6 +177,8 @@ public:
|
||||||
QString tlsKeyLength() const override;
|
QString tlsKeyLength() const override;
|
||||||
std::optional<QSize> mainWindowSize() const;
|
std::optional<QSize> mainWindowSize() const;
|
||||||
std::optional<QPoint> mainWindowPosition() const;
|
std::optional<QPoint> mainWindowPosition() const;
|
||||||
|
bool showDevThanks() const;
|
||||||
|
bool showCloseReminder() const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Setters
|
* Setters
|
||||||
|
|
@ -197,13 +208,15 @@ public:
|
||||||
void setClientGroupChecked(bool);
|
void setClientGroupChecked(bool);
|
||||||
void setServerHostname(const QString &);
|
void setServerHostname(const QString &);
|
||||||
void setLastVersion(const QString &version);
|
void setLastVersion(const QString &version);
|
||||||
void setServiceEnabled(bool enabled);
|
void setEnableService(bool enabled);
|
||||||
void setCloseToTray(bool minimize);
|
void setCloseToTray(bool minimize);
|
||||||
void setTlsCertPath(const QString &path);
|
void setTlsCertPath(const QString &path);
|
||||||
void setTlsKeyLength(const QString &length);
|
void setTlsKeyLength(const QString &length);
|
||||||
void setInvertConnection(bool value);
|
void setInvertConnection(bool value);
|
||||||
void setMainWindowSize(const QSize &size);
|
void setMainWindowSize(const QSize &size);
|
||||||
void setMainWindowPosition(const QPoint &position);
|
void setMainWindowPosition(const QPoint &position);
|
||||||
|
void setShowDevThanks(bool show);
|
||||||
|
void setShowCloseReminder(bool show);
|
||||||
|
|
||||||
/// @brief Sets the user preference to load from SystemScope.
|
/// @brief Sets the user preference to load from SystemScope.
|
||||||
/// @param [in] value
|
/// @param [in] value
|
||||||
|
|
@ -214,11 +227,13 @@ public:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static QString settingName(AppConfig::Setting name);
|
static QString settingName(AppConfig::Setting name);
|
||||||
void loadScreenName();
|
|
||||||
void loadSerialKey();
|
void recall();
|
||||||
void loadElevateMode();
|
void recallScreenName();
|
||||||
void loadCommonSettings();
|
void recallSerialKey();
|
||||||
void loadScopeSettings();
|
void recallElevateMode();
|
||||||
|
void recallFromAllScopes();
|
||||||
|
void recallFromCurrentScope();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Loads a setting if it exists, otherwise returns `std::nullopt`
|
* @brief Loads a setting if it exists, otherwise returns `std::nullopt`
|
||||||
|
|
@ -226,60 +241,48 @@ private:
|
||||||
* @param toType A function to convert the QVariant to the desired type.
|
* @param toType A function to convert the QVariant to the desired type.
|
||||||
*/
|
*/
|
||||||
template <typename T>
|
template <typename T>
|
||||||
std::optional<T>
|
std::optional<T> getFromCurrentScope(
|
||||||
loadOptional(Setting name, std::function<T(QVariant)> toType) const;
|
Setting name, std::function<T(const QVariant &)> toType) const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Sets a setting if the value is not `std::nullopt`.
|
* @brief Sets a setting if the value is not `std::nullopt`.
|
||||||
*/
|
*/
|
||||||
template <typename T>
|
template <typename T>
|
||||||
void setOptional(Setting name, const std::optional<T> &value);
|
void setInCurrentScope(Setting name, const std::optional<T> &value);
|
||||||
|
|
||||||
/// @brief Sets the value of a setting
|
/// @brief Sets the value of a setting
|
||||||
/// @param [in] name The Setting to be saved
|
/// @param [in] name The Setting to be saved
|
||||||
/// @param [in] value The Value to be saved
|
/// @param [in] value The Value to be saved
|
||||||
template <typename T> void setSetting(AppConfig::Setting name, T value);
|
template <typename T>
|
||||||
|
void setInCurrentScope(AppConfig::Setting name, T value);
|
||||||
|
|
||||||
/// @brief Sets the value of a common setting
|
/// @brief Sets the value of a common setting
|
||||||
/// which should have the same value for all scopes
|
/// which should have the same value for all scopes
|
||||||
/// @param [in] name The Setting to be saved
|
/// @param [in] name The Setting to be saved
|
||||||
/// @param [in] value The Value to be saved
|
/// @param [in] value The Value to be saved
|
||||||
template <typename T> void setCommonSetting(AppConfig::Setting name, T value);
|
template <typename T> void saveToAllScopes(AppConfig::Setting name, T value);
|
||||||
|
|
||||||
/// @brief Loads a setting
|
QVariant getFromCurrentScope(
|
||||||
/// @param [in] name The setting to be loaded
|
|
||||||
/// @param [in] defaultValue The default value of the setting
|
|
||||||
QVariant loadSetting(
|
|
||||||
AppConfig::Setting name, const QVariant &defaultValue = QVariant());
|
|
||||||
|
|
||||||
/// @brief Loads a common setting
|
|
||||||
/// @param [in] name The setting to be loaded
|
|
||||||
/// @param [in] defaultValue The default value of the setting
|
|
||||||
QVariant loadCommonSetting(
|
|
||||||
AppConfig::Setting name, const QVariant &defaultValue = QVariant()) const;
|
AppConfig::Setting name, const QVariant &defaultValue = QVariant()) const;
|
||||||
|
|
||||||
/// @brief Sets the setting in the config checking if it has changed and
|
/**
|
||||||
/// flagging that settings
|
* @brief Finds a value by searching each scope starting with the current
|
||||||
/// needs to be saved if the setting was different
|
* scope.
|
||||||
/// @param [in] variable the setting that will be changed
|
*/
|
||||||
/// @param [in] newValue The new value of the setting
|
QVariant findInAllScopes(
|
||||||
template <typename T> void setSettingModified(T &variable, const T &newValue);
|
AppConfig::Setting name, const QVariant &defaultValue = QVariant()) const;
|
||||||
|
|
||||||
/// @brief This method loads config from specified scope
|
/// @brief This method loads config from specified scope
|
||||||
/// @param [in] scope which should be loaded.
|
/// @param [in] scope which should be loaded.
|
||||||
void loadScope(synergy::gui::ConfigScopes::Scope scope);
|
void loadScope(synergy::gui::ConfigScopes::Scope scope);
|
||||||
|
|
||||||
/// @brief This function sets default values
|
|
||||||
/// 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.
|
* @brief Gets a TLS certificate path based on the user's profile dir.
|
||||||
*/
|
*/
|
||||||
QString defaultTlsCertPath() const;
|
QString defaultTlsCertPath() const;
|
||||||
|
|
||||||
static Deps s_Deps;
|
synergy::gui::IConfigScopes &m_scopes;
|
||||||
Deps &m_Deps;
|
std::shared_ptr<Deps> m_pDeps;
|
||||||
QString m_ScreenName;
|
QString m_ScreenName;
|
||||||
int m_Port = 24800;
|
int m_Port = 24800;
|
||||||
QString m_Interface = "";
|
QString m_Interface = "";
|
||||||
|
|
@ -306,12 +309,15 @@ private:
|
||||||
bool m_UseInternalConfig = false;
|
bool m_UseInternalConfig = false;
|
||||||
bool m_ClientGroupChecked = false;
|
bool m_ClientGroupChecked = false;
|
||||||
QString m_ServerHostname = "";
|
QString m_ServerHostname = "";
|
||||||
bool m_ServiceEnabled = kDefaultProcessMode == ProcessMode::kService;
|
bool m_EnableService = kDefaultProcessMode == ProcessMode::kService;
|
||||||
bool m_CloseToTray = false;
|
bool m_CloseToTray = true;
|
||||||
QString m_TlsCertPath = defaultTlsCertPath();
|
QString m_TlsCertPath = defaultTlsCertPath();
|
||||||
QString m_TlsKeyLength = "2048";
|
QString m_TlsKeyLength = "2048";
|
||||||
std::optional<QSize> m_MainWindowSize;
|
std::optional<QSize> m_MainWindowSize;
|
||||||
std::optional<QPoint> m_MainWindowPosition;
|
std::optional<QPoint> m_MainWindowPosition;
|
||||||
|
bool m_ShowDevThanks = kDefaultShowDevThanks;
|
||||||
|
bool m_LoadFromSystemScope = false;
|
||||||
|
bool m_ShowCloseReminder = true;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Flag is set when any TLS is setting is changed, and is reset
|
* @brief Flag is set when any TLS is setting is changed, and is reset
|
||||||
|
|
@ -319,19 +325,6 @@ private:
|
||||||
*/
|
*/
|
||||||
bool m_TlsChanged = false;
|
bool m_TlsChanged = false;
|
||||||
|
|
||||||
/// @brief should the setting be loaded from
|
|
||||||
/// SystemScope
|
|
||||||
/// If the user has settings but this is
|
|
||||||
/// true then system settings will be
|
|
||||||
/// loaded instead of the users
|
|
||||||
bool m_LoadFromSystemScope = false;
|
|
||||||
|
|
||||||
/// @brief As the settings will be accessible by multiple objects this lock
|
|
||||||
/// will ensure that
|
|
||||||
/// it cant be modified by more that one object at a time if the
|
|
||||||
/// setting is being switched from system to user.
|
|
||||||
std::mutex m_settings_lock;
|
|
||||||
|
|
||||||
static const char m_CoreServerName[];
|
static const char m_CoreServerName[];
|
||||||
static const char m_CoreClientName[];
|
static const char m_CoreClientName[];
|
||||||
static const char m_LogDir[];
|
static const char m_LogDir[];
|
||||||
|
|
@ -339,12 +332,10 @@ private:
|
||||||
/// @brief Contains the string values of the settings names that will be saved
|
/// @brief Contains the string values of the settings names that will be saved
|
||||||
static const char *const m_SettingsName[];
|
static const char *const m_SettingsName[];
|
||||||
|
|
||||||
/// @brief Contains the name of the default configuration filename
|
/// @brief Core config filename (not the Qt settings filename)
|
||||||
static const char m_ConfigFilename[];
|
static const char m_ConfigFilename[];
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void loaded();
|
|
||||||
void saved();
|
|
||||||
void tlsChanged();
|
void tlsChanged();
|
||||||
void screenNameChanged();
|
void screenNameChanged();
|
||||||
void invertConnectionChanged();
|
void invertConnectionChanged();
|
||||||
|
|
|
||||||
|
|
@ -17,58 +17,81 @@
|
||||||
|
|
||||||
#include "ConfigScopes.h"
|
#include "ConfigScopes.h"
|
||||||
|
|
||||||
#include "CommonConfig.h"
|
|
||||||
|
|
||||||
#include <QCoreApplication>
|
#include <QCoreApplication>
|
||||||
#include <QFile>
|
#include <QFile>
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
|
const auto kSystemConfigFilename = "SystemConfig.ini";
|
||||||
|
const auto kUnixSystemConfigPath = "/usr/local/etc/symless/";
|
||||||
|
|
||||||
namespace synergy::gui {
|
namespace synergy::gui {
|
||||||
|
|
||||||
QString getSystemSettingPath() {
|
QString getSystemSettingPath() {
|
||||||
const QString settingFilename("SystemConfig.ini");
|
const QString settingFilename(kSystemConfigFilename);
|
||||||
QString path;
|
|
||||||
#if defined(Q_OS_WIN)
|
#if defined(Q_OS_WIN)
|
||||||
path = QCoreApplication::applicationDirPath() + "\\";
|
return QCoreApplication::applicationDirPath() + "\\";
|
||||||
#elif defined(Q_OS_DARWIN)
|
#elif defined(Q_OS_DARWIN)
|
||||||
// Global preferances dir
|
// it would be nice to use /Library dir, but qt has no elevate system.
|
||||||
// Would be nice to use /library, but QT has no elevate system in place
|
return kUnixSystemConfigPath + settingFilename;
|
||||||
path = "/usr/local/etc/symless/";
|
|
||||||
#elif defined(Q_OS_LINUX)
|
#elif defined(Q_OS_LINUX)
|
||||||
// QT adds application and filename to the end of the path already on linux
|
// qt already adds application and filename to the end of the path on linux.
|
||||||
path = "/usr/local/etc/symless/";
|
return kUnixSystemConfigPath;
|
||||||
return path;
|
|
||||||
#else
|
#else
|
||||||
assert("OS not supported");
|
qFatal("unsupported platform");
|
||||||
|
return "";
|
||||||
#endif
|
#endif
|
||||||
return path + settingFilename;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(Q_OS_WIN)
|
#if defined(Q_OS_WIN)
|
||||||
void loadWindowsLegacy(QSettings &settings) {
|
void loadWindowsLegacy(QSettings &settings) {
|
||||||
if (!QFile(settings.fileName()).exists()) {
|
if (QFile(settings.fileName()).exists()) {
|
||||||
QSettings::setPath(
|
qDebug("system settings already exist, skipping legacy load");
|
||||||
QSettings::IniFormat, QSettings::SystemScope, "SystemConfig.ini");
|
return;
|
||||||
QSettings oldSystemSettings(
|
|
||||||
QSettings::IniFormat, QSettings::SystemScope,
|
|
||||||
QCoreApplication::organizationName(),
|
|
||||||
QCoreApplication::applicationName());
|
|
||||||
|
|
||||||
if (QFile(oldSystemSettings.fileName()).exists()) {
|
|
||||||
for (const auto &key : oldSystemSettings.allKeys()) {
|
|
||||||
settings.setValue(key, oldSystemSettings.value(key));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Restore system settings path
|
|
||||||
QSettings::setPath(
|
|
||||||
QSettings::IniFormat, QSettings::SystemScope, getSystemSettingPath());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QSettings::setPath(
|
||||||
|
QSettings::IniFormat, QSettings::SystemScope, kSystemConfigFilename);
|
||||||
|
QSettings oldSystemSettings(
|
||||||
|
QSettings::IniFormat, QSettings::SystemScope,
|
||||||
|
QCoreApplication::organizationName(),
|
||||||
|
QCoreApplication::applicationName());
|
||||||
|
|
||||||
|
if (QFile(oldSystemSettings.fileName()).exists()) {
|
||||||
|
for (const auto &key : oldSystemSettings.allKeys()) {
|
||||||
|
settings.setValue(key, oldSystemSettings.value(key));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
QSettings::setPath(
|
||||||
|
QSettings::IniFormat, QSettings::SystemScope, getSystemSettingPath());
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
ConfigScopes::ConfigScopes() {
|
ConfigScopes::ConfigScopes() {
|
||||||
|
auto orgName = QCoreApplication::organizationName();
|
||||||
|
if (orgName.isEmpty()) {
|
||||||
|
qFatal("unable to load config, organization name is empty");
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
qDebug() << "org name for config:" << orgName;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto appName = QCoreApplication::applicationName();
|
||||||
|
if (appName.isEmpty()) {
|
||||||
|
qFatal("unable to load config, application name is empty");
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
qDebug() << "app name for config:" << appName;
|
||||||
|
}
|
||||||
|
|
||||||
|
// default to user scope.
|
||||||
|
// if we set the scope specifically then we also have to set the application
|
||||||
|
// name and the organisation name which breaks backwards compatibility.
|
||||||
|
m_pUserSettings = std::make_unique<QSettings>();
|
||||||
|
|
||||||
|
qDebug() << "user settings path:" << m_pUserSettings->fileName();
|
||||||
|
|
||||||
QSettings::setPath(
|
QSettings::setPath(
|
||||||
QSettings::Format::IniFormat, QSettings::Scope::SystemScope,
|
QSettings::Format::IniFormat, QSettings::Scope::SystemScope,
|
||||||
getSystemSettingPath());
|
getSystemSettingPath());
|
||||||
|
|
@ -76,47 +99,57 @@ ConfigScopes::ConfigScopes() {
|
||||||
// Config will default to User settings if they exist,
|
// Config will default to User settings if they exist,
|
||||||
// otherwise it will load System setting and save them to User settings
|
// otherwise it will load System setting and save them to User settings
|
||||||
m_pSystemSettings = std::make_unique<QSettings>(
|
m_pSystemSettings = std::make_unique<QSettings>(
|
||||||
QSettings::Format::IniFormat, QSettings::Scope::SystemScope,
|
QSettings::Format::IniFormat, QSettings::Scope::SystemScope, orgName,
|
||||||
QCoreApplication::organizationName(),
|
appName);
|
||||||
QCoreApplication::applicationName());
|
|
||||||
|
|
||||||
// default to user scope.
|
qDebug() << "system settings path:" << m_pSystemSettings->fileName();
|
||||||
// if we set the scope specifically then we also have to set the application
|
|
||||||
// name and the organisation name which breaks backwards compatibility.
|
|
||||||
m_pUserSettings = std::make_unique<QSettings>();
|
|
||||||
|
|
||||||
load();
|
|
||||||
}
|
|
||||||
|
|
||||||
ConfigScopes::~ConfigScopes() {
|
|
||||||
while (!m_pReceivers.empty()) {
|
|
||||||
m_pReceivers.pop_back();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ConfigScopes::load() {
|
|
||||||
#if defined(Q_OS_WIN)
|
#if defined(Q_OS_WIN)
|
||||||
// This call is needed for backwardcapability with old settings.
|
|
||||||
loadWindowsLegacy(*m_pSystemSettings);
|
loadWindowsLegacy(*m_pSystemSettings);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ConfigScopes::hasSetting(const QString &name, Scope scope) const {
|
void ConfigScopes::signalReady() { emit ready(); }
|
||||||
|
|
||||||
|
void ConfigScopes::save() {
|
||||||
|
qDebug("emitting config saving signal");
|
||||||
|
emit saving();
|
||||||
|
|
||||||
|
qDebug("writing config to filesystem");
|
||||||
|
m_pUserSettings->sync();
|
||||||
|
m_pSystemSettings->sync();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ConfigScopes::isActiveScopeWritable() const {
|
||||||
|
return activeSettings()->isWritable();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ConfigScopes::setActiveScope(ConfigScopes::Scope scope) {
|
||||||
|
m_currentScope = scope;
|
||||||
|
}
|
||||||
|
|
||||||
|
ConfigScopes::Scope ConfigScopes::activeScope() const { return m_currentScope; }
|
||||||
|
|
||||||
|
bool ConfigScopes::scopeContains(const QString &name, Scope scope) const {
|
||||||
switch (scope) {
|
switch (scope) {
|
||||||
case Scope::User:
|
case Scope::User:
|
||||||
return m_pUserSettings->contains(name);
|
return m_pUserSettings->contains(name);
|
||||||
case Scope::System:
|
case Scope::System:
|
||||||
return m_pSystemSettings->contains(name);
|
return m_pSystemSettings->contains(name);
|
||||||
default:
|
default:
|
||||||
return currentSettings()->contains(name);
|
return activeSettings()->contains(name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ConfigScopes::isWritable() const {
|
QSettings *ConfigScopes::activeSettings() const {
|
||||||
return currentSettings()->isWritable();
|
if (m_currentScope == Scope::User) {
|
||||||
|
return m_pUserSettings.get();
|
||||||
|
} else {
|
||||||
|
return m_pSystemSettings.get();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
QVariant ConfigScopes::loadSetting(
|
QVariant ConfigScopes::getFromScope(
|
||||||
const QString &name, const QVariant &defaultValue, Scope scope) const {
|
const QString &name, const QVariant &defaultValue, Scope scope) const {
|
||||||
switch (scope) {
|
switch (scope) {
|
||||||
case Scope::User:
|
case Scope::User:
|
||||||
|
|
@ -124,68 +157,23 @@ QVariant ConfigScopes::loadSetting(
|
||||||
case Scope::System:
|
case Scope::System:
|
||||||
return m_pSystemSettings->value(name, defaultValue);
|
return m_pSystemSettings->value(name, defaultValue);
|
||||||
default:
|
default:
|
||||||
return currentSettings()->value(name, defaultValue);
|
return activeSettings()->value(name, defaultValue);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConfigScopes::setScope(ConfigScopes::Scope scope) {
|
void ConfigScopes::setInScope(
|
||||||
m_CurrentScope = scope;
|
|
||||||
}
|
|
||||||
|
|
||||||
ConfigScopes::Scope ConfigScopes::getScope() const { return m_CurrentScope; }
|
|
||||||
|
|
||||||
void ConfigScopes::loadAll() {
|
|
||||||
for (auto &i : m_pReceivers) {
|
|
||||||
i->loadSettings();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ConfigScopes::saveAll() {
|
|
||||||
|
|
||||||
// Save if there are any unsaved changes otherwise skip
|
|
||||||
if (unsavedChanges()) {
|
|
||||||
for (auto &i : m_pReceivers) {
|
|
||||||
i->saveSettings();
|
|
||||||
}
|
|
||||||
|
|
||||||
m_pUserSettings->sync();
|
|
||||||
m_pSystemSettings->sync();
|
|
||||||
|
|
||||||
m_unsavedChanges = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
QSettings *ConfigScopes::currentSettings() const {
|
|
||||||
if (m_CurrentScope == Scope::User) {
|
|
||||||
return m_pUserSettings.get();
|
|
||||||
} else {
|
|
||||||
return m_pSystemSettings.get();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ConfigScopes::registerReceiver(CommonConfig *receiver) {
|
|
||||||
m_pReceivers.push_back(receiver);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool ConfigScopes::unsavedChanges() const {
|
|
||||||
if (m_unsavedChanges) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (const auto &i : m_pReceivers) {
|
|
||||||
if (i->modified()) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ConfigScopes::markUnsaved() { m_unsavedChanges = true; }
|
|
||||||
|
|
||||||
void ConfigScopes::setSetting(
|
|
||||||
const QString &name, const QVariant &value, Scope scope) {
|
const QString &name, const QVariant &value, Scope scope) {
|
||||||
currentSettings()->setValue(name, value);
|
switch (scope) {
|
||||||
m_unsavedChanges = true;
|
case Scope::User:
|
||||||
|
m_pUserSettings->setValue(name, value);
|
||||||
|
break;
|
||||||
|
case Scope::System:
|
||||||
|
m_pSystemSettings->setValue(name, value);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
activeSettings()->setValue(name, value);
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace synergy::gui
|
} // namespace synergy::gui
|
||||||
|
|
|
||||||
|
|
@ -19,94 +19,44 @@
|
||||||
|
|
||||||
#include "IConfigScopes.h"
|
#include "IConfigScopes.h"
|
||||||
|
|
||||||
|
#include <QObject>
|
||||||
#include <QSettings>
|
#include <QSettings>
|
||||||
#include <QVariant>
|
#include <QVariant>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
namespace synergy::gui {
|
namespace synergy::gui {
|
||||||
|
|
||||||
class CommonConfig;
|
/// @brief Encapsulates Qt config for both user and global scopes.
|
||||||
|
class ConfigScopes : public QObject, public IConfigScopes {
|
||||||
/// @brief A general config reader and writer for user and gloabl settings
|
Q_OBJECT
|
||||||
class ConfigScopes : public IConfigScopes {
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit ConfigScopes();
|
explicit ConfigScopes();
|
||||||
virtual ~ConfigScopes();
|
virtual ~ConfigScopes() = default;
|
||||||
|
|
||||||
/// @brief Checks if the setting exists
|
void signalReady() override;
|
||||||
/// @param [in] name The name of the setting to check
|
void save() override;
|
||||||
/// @param [in] scope The scope to search in
|
bool scopeContains(
|
||||||
/// @return bool True if the current scope has the named setting
|
const QString &name, Scope scope = Scope::Current) const override;
|
||||||
bool
|
bool isActiveScopeWritable() const override;
|
||||||
hasSetting(const QString &name, Scope scope = Scope::Current) const override;
|
void setInScope(
|
||||||
|
|
||||||
/// @brief Checks if the current scope settings writable
|
|
||||||
/// @return bool True if the current scope writable
|
|
||||||
bool isWritable() const override;
|
|
||||||
|
|
||||||
/// @brief Sets the value of a setting
|
|
||||||
/// @param [in] name The Setting to be saved
|
|
||||||
/// @param [in] value The Value to be saved (Templated)
|
|
||||||
/// @param [in] scope The scope to get the value from, default is current
|
|
||||||
/// scope
|
|
||||||
void setSetting(
|
|
||||||
const QString &name, const QVariant &value,
|
const QString &name, const QVariant &value,
|
||||||
Scope scope = Scope::Current) override;
|
Scope scope = Scope::Current) override;
|
||||||
|
QVariant getFromScope(
|
||||||
/// @brief Loads a setting
|
|
||||||
/// @param [in] name The setting to be loaded
|
|
||||||
/// @param [in] defaultValue The default value of the setting
|
|
||||||
/// @param [in] scope The scope to get the value from, default is current
|
|
||||||
/// scope
|
|
||||||
QVariant loadSetting(
|
|
||||||
const QString &name, const QVariant &defaultValue = QVariant(),
|
const QString &name, const QVariant &defaultValue = QVariant(),
|
||||||
Scope scope = Scope::Current) const override;
|
Scope scope = Scope::Current) const override;
|
||||||
|
void setActiveScope(Scope scope = Scope::User) override;
|
||||||
|
Scope activeScope() const override;
|
||||||
|
QSettings *activeSettings() const override;
|
||||||
|
|
||||||
/// @brief Changes the setting save and load location between System and User
|
signals:
|
||||||
/// scope
|
void ready();
|
||||||
/// @param [in] scope The scope to set
|
void saving();
|
||||||
void setScope(Scope scope = Scope::User) override;
|
|
||||||
|
|
||||||
/// @brief Get the current scope the settings are loading and save from.
|
|
||||||
/// @return Scope An enum defining the current scope
|
|
||||||
Scope getScope() const override;
|
|
||||||
|
|
||||||
/// @brief trigger a config load across all registered classes
|
|
||||||
void loadAll() override;
|
|
||||||
|
|
||||||
/// @brief trigger a config save across all registered classes
|
|
||||||
void saveAll() override;
|
|
||||||
|
|
||||||
/// @brief Returns the current scopes settings object
|
|
||||||
/// If more specialize control into the settings is needed this can
|
|
||||||
/// provide direct access to the settings file handler
|
|
||||||
/// @return QSettings The Settings object as a reference
|
|
||||||
QSettings *currentSettings() const override;
|
|
||||||
|
|
||||||
/// @brief This marks the settings as unsaved if the settings() was used to
|
|
||||||
/// directly affect the config file
|
|
||||||
void markUnsaved();
|
|
||||||
|
|
||||||
/// @brief Register a class to receives requests to save and load settings
|
|
||||||
void registerReceiver(CommonConfig *receiver) override;
|
|
||||||
|
|
||||||
/// @brief Checks if any registered class has any unsaved changes
|
|
||||||
/// @return bool True if any registered class has unsaved changes
|
|
||||||
bool unsavedChanges() const;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void load();
|
Scope m_currentScope = Scope::User;
|
||||||
|
|
||||||
Scope m_CurrentScope = Scope::User;
|
|
||||||
std::unique_ptr<QSettings> m_pUserSettings;
|
std::unique_ptr<QSettings> m_pUserSettings;
|
||||||
std::unique_ptr<QSettings> m_pSystemSettings;
|
std::unique_ptr<QSettings> m_pSystemSettings;
|
||||||
|
|
||||||
/// @brief Receivers of load/save callbacks
|
|
||||||
std::list<CommonConfig *> m_pReceivers;
|
|
||||||
|
|
||||||
/// @brief Is set to true when settings are changed
|
|
||||||
bool m_unsavedChanges = false;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace synergy::gui
|
} // namespace synergy::gui
|
||||||
|
|
|
||||||
|
|
@ -17,8 +17,6 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "gui/CommonConfig.h"
|
|
||||||
|
|
||||||
#include <QSettings>
|
#include <QSettings>
|
||||||
#include <QString>
|
#include <QString>
|
||||||
#include <QVariant>
|
#include <QVariant>
|
||||||
|
|
@ -31,21 +29,42 @@ public:
|
||||||
|
|
||||||
virtual ~IConfigScopes() = default;
|
virtual ~IConfigScopes() = default;
|
||||||
|
|
||||||
virtual void registerReceiver(CommonConfig *receiver) = 0;
|
virtual Scope activeScope() const = 0;
|
||||||
virtual void loadAll() = 0;
|
virtual void setActiveScope(Scope scope = Scope::User) = 0;
|
||||||
|
virtual bool isActiveScopeWritable() const = 0;
|
||||||
|
virtual QSettings *activeSettings() const = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Signals to listeners that the settings that they should read.
|
||||||
|
*/
|
||||||
|
virtual void signalReady() = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Signalls to listeners to save and calls `sync` on underlying Qt
|
||||||
|
* config.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
virtual void save() = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Check a scope for a config value (default is current scope).
|
||||||
|
*/
|
||||||
virtual bool
|
virtual bool
|
||||||
hasSetting(const QString &name, Scope scope = Scope::Current) const = 0;
|
scopeContains(const QString &name, Scope scope = Scope::Current) const = 0;
|
||||||
virtual QVariant loadSetting(
|
|
||||||
|
/**
|
||||||
|
* @brief Load a config value from a scope (default is current scope).
|
||||||
|
*/
|
||||||
|
virtual QVariant getFromScope(
|
||||||
const QString &name, const QVariant &defaultValue = QVariant(),
|
const QString &name, const QVariant &defaultValue = QVariant(),
|
||||||
Scope scope = Scope::Current) const = 0;
|
Scope scope = Scope::Current) const = 0;
|
||||||
virtual void setSetting(
|
|
||||||
|
/**
|
||||||
|
* @brief Set a config value in a scope (default is current scope).
|
||||||
|
*/
|
||||||
|
virtual void setInScope(
|
||||||
const QString &name, const QVariant &value,
|
const QString &name, const QVariant &value,
|
||||||
Scope scope = Scope::Current) = 0;
|
Scope scope = Scope::Current) = 0;
|
||||||
virtual Scope getScope() const = 0;
|
|
||||||
virtual void setScope(Scope scope = Scope::User) = 0;
|
|
||||||
virtual bool isWritable() const = 0;
|
|
||||||
virtual QSettings *currentSettings() const = 0;
|
|
||||||
virtual void saveAll() = 0;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace synergy::gui
|
} // namespace synergy::gui
|
||||||
|
|
|
||||||
|
|
@ -17,6 +17,7 @@
|
||||||
|
|
||||||
#include "LicenseHandler.h"
|
#include "LicenseHandler.h"
|
||||||
|
|
||||||
|
#include "constants.h"
|
||||||
#include "license/ProductEdition.h"
|
#include "license/ProductEdition.h"
|
||||||
#include "license/parse_serial_key.h"
|
#include "license/parse_serial_key.h"
|
||||||
|
|
||||||
|
|
@ -41,6 +42,10 @@ LicenseHandler::ChangeSerialKeyResult
|
||||||
LicenseHandler::changeSerialKey(const QString &hexString) {
|
LicenseHandler::changeSerialKey(const QString &hexString) {
|
||||||
using enum LicenseHandler::ChangeSerialKeyResult;
|
using enum LicenseHandler::ChangeSerialKeyResult;
|
||||||
|
|
||||||
|
if (!m_enabled) {
|
||||||
|
qFatal("cannot set serial key, licensing is disabled");
|
||||||
|
}
|
||||||
|
|
||||||
if (hexString.isEmpty()) {
|
if (hexString.isEmpty()) {
|
||||||
qFatal("serial key is empty");
|
qFatal("serial key is empty");
|
||||||
return kFatal;
|
return kFatal;
|
||||||
|
|
|
||||||
|
|
@ -17,6 +17,7 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "gui/constants.h"
|
||||||
#include "license/License.h"
|
#include "license/License.h"
|
||||||
#include "license/ProductEdition.h"
|
#include "license/ProductEdition.h"
|
||||||
|
|
||||||
|
|
@ -44,11 +45,13 @@ public:
|
||||||
void validate() const;
|
void validate() const;
|
||||||
QString productName() const;
|
QString productName() const;
|
||||||
ChangeSerialKeyResult changeSerialKey(const QString &hexString);
|
ChangeSerialKeyResult changeSerialKey(const QString &hexString);
|
||||||
|
void setEnabled(bool enabled) { m_enabled = enabled; }
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void serialKeyChanged(const QString &serialKey) const;
|
void serialKeyChanged(const QString &serialKey) const;
|
||||||
void invalidLicense() const;
|
void invalidLicense() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
bool m_enabled = kLicensingEnabled;
|
||||||
License m_license = License::invalid();
|
License m_license = License::invalid();
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -56,13 +56,13 @@ QIpcClient::~QIpcClient() {
|
||||||
void QIpcClient::connected() {
|
void QIpcClient::connected() {
|
||||||
|
|
||||||
sendHello();
|
sendHello();
|
||||||
infoMessage("connection established");
|
emit infoMessage("connection established");
|
||||||
}
|
}
|
||||||
|
|
||||||
void QIpcClient::connectToHost() {
|
void QIpcClient::connectToHost() {
|
||||||
m_Enabled = true;
|
m_Enabled = true;
|
||||||
|
|
||||||
infoMessage("connecting to service...");
|
emit infoMessage("connecting to service...");
|
||||||
const auto port = static_cast<quint16>(kIpcPort);
|
const auto port = static_cast<quint16>(kIpcPort);
|
||||||
m_Socket->connectToHost(QHostAddress(QHostAddress::LocalHost), port);
|
m_Socket->connectToHost(QHostAddress(QHostAddress::LocalHost), port);
|
||||||
|
|
||||||
|
|
@ -73,7 +73,7 @@ void QIpcClient::connectToHost() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void QIpcClient::disconnectFromHost() {
|
void QIpcClient::disconnectFromHost() {
|
||||||
infoMessage("service disconnect");
|
emit infoMessage("service disconnect");
|
||||||
m_Reader->stop();
|
m_Reader->stop();
|
||||||
m_Socket->close();
|
m_Socket->close();
|
||||||
}
|
}
|
||||||
|
|
@ -92,7 +92,7 @@ void QIpcClient::error(QAbstractSocket::SocketError error) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
errorMessage(QString("ipc connection error, %1").arg(text));
|
emit errorMessage(QString("ipc connection error, %1").arg(text));
|
||||||
|
|
||||||
QTimer::singleShot(1000, this, SLOT(retryConnect()));
|
QTimer::singleShot(1000, this, SLOT(retryConnect()));
|
||||||
}
|
}
|
||||||
|
|
@ -133,7 +133,9 @@ void QIpcClient::sendCommand(
|
||||||
stream->writeRawData(elevateBuf, 1);
|
stream->writeRawData(elevateBuf, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void QIpcClient::handleReadLogLine(const QString &text) { readLogLine(text); }
|
void QIpcClient::handleReadLogLine(const QString &text) {
|
||||||
|
emit readLogLine(text);
|
||||||
|
}
|
||||||
|
|
||||||
// TODO: qt must have a built in way of converting int to bytes.
|
// TODO: qt must have a built in way of converting int to bytes.
|
||||||
void QIpcClient::intToBytes(int value, char *buffer, int size) {
|
void QIpcClient::intToBytes(int value, char *buffer, int size) {
|
||||||
|
|
|
||||||
|
|
@ -32,6 +32,9 @@ bool TlsUtility::isAvailableAndEnabled() const {
|
||||||
}
|
}
|
||||||
|
|
||||||
void TlsUtility::generateCertificate(bool replace) const {
|
void TlsUtility::generateCertificate(bool replace) const {
|
||||||
|
qDebug("generating tls certificate, "
|
||||||
|
"all clients must trust the new fingerprint");
|
||||||
|
|
||||||
if (!isAvailableAndEnabled()) {
|
if (!isAvailableAndEnabled()) {
|
||||||
qFatal("unable to generate tls certificate, "
|
qFatal("unable to generate tls certificate, "
|
||||||
"tls is either not available or not enabled");
|
"tls is either not available or not enabled");
|
||||||
|
|
|
||||||
|
|
@ -19,25 +19,33 @@
|
||||||
|
|
||||||
#include <QString>
|
#include <QString>
|
||||||
|
|
||||||
|
const auto kAppName = "Synergy";
|
||||||
|
|
||||||
|
// TODO: change to `com.symless`. we'll need to gracefully import old settings,
|
||||||
|
// since qt uses this on some platforms when saving settings.
|
||||||
|
const auto kAppDomain = "https://symless.com";
|
||||||
|
|
||||||
|
#ifdef SYNERGY_PRODUCT_NAME
|
||||||
|
const QString kProductName = SYNERGY_PRODUCT_NAME;
|
||||||
|
#else
|
||||||
|
const QString kProductName;
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef SYNERGY_ENABLE_LICENSING
|
#ifdef SYNERGY_ENABLE_LICENSING
|
||||||
const bool kLicensingEnabled = true;
|
const bool kLicensingEnabled = true;
|
||||||
#else
|
#else
|
||||||
const bool kLicensingEnabled = false;
|
const bool kLicensingEnabled = false;
|
||||||
#endif // SYNERGY_ENABLE_LICENSING
|
#endif // SYNERGY_ENABLE_LICENSING
|
||||||
|
|
||||||
const auto kColorWhite = "#ffffff";
|
|
||||||
const auto kColorPrimary = "#ff7c00";
|
|
||||||
const auto kColorSecondary = "#4285f4";
|
|
||||||
const auto kColorTertiary = "#33b2cc";
|
|
||||||
const auto kColorError = "#ec4c47";
|
|
||||||
const auto kColorNotice = "#3b67d3";
|
|
||||||
|
|
||||||
const auto kLinkBuy = R"(<a href="%1" style="color: %2">Buy now</a>)";
|
const auto kLinkBuy = R"(<a href="%1" style="color: %2">Buy now</a>)";
|
||||||
const auto kLinkRenew = R"(<a href="%1" style="color: %2">Renew now</a>)";
|
const auto kLinkRenew = R"(<a href="%1" style="color: %2">Renew now</a>)";
|
||||||
const auto kLinkDownload = R"(<a href="%1" style="color: %2">Download now</a>)";
|
const auto kLinkDownload = R"(<a href="%1" style="color: %2">Download now</a>)";
|
||||||
|
|
||||||
const auto kUrlSourceQuery = "source=gui";
|
const auto kUrlSourceQuery = "source=gui";
|
||||||
const auto kUrlWebsite = "https://symless.com";
|
const auto kUrlWebsite = "https://symless.com";
|
||||||
|
const auto kUrlContribute = "https://github.com/symless/synergy-core";
|
||||||
|
const auto kUrlGnomeTrayFix =
|
||||||
|
"https://extensions.gnome.org/extension/2890/tray-icons-reloaded/";
|
||||||
const auto kUrlProduct = QString("%1/synergy").arg(kUrlWebsite);
|
const auto kUrlProduct = QString("%1/synergy").arg(kUrlWebsite);
|
||||||
const auto kUrlPurchase =
|
const auto kUrlPurchase =
|
||||||
QString("%1/purchase?%2").arg(kUrlProduct, kUrlSourceQuery);
|
QString("%1/purchase?%2").arg(kUrlProduct, kUrlSourceQuery);
|
||||||
|
|
@ -46,21 +54,3 @@ const auto kUrlContact =
|
||||||
const auto kUrlHelp = QString("%1/help?%2").arg(kUrlProduct, kUrlSourceQuery);
|
const auto kUrlHelp = QString("%1/help?%2").arg(kUrlProduct, kUrlSourceQuery);
|
||||||
const auto kUrlDownload =
|
const auto kUrlDownload =
|
||||||
QString("%1/download?%2").arg(kUrlProduct, kUrlSourceQuery);
|
QString("%1/download?%2").arg(kUrlProduct, kUrlSourceQuery);
|
||||||
|
|
||||||
const auto kStyleLineEditErrorBorder =
|
|
||||||
QString("border: 1px solid %1; border-radius: 2px; padding: 2px;")
|
|
||||||
.arg(kColorError);
|
|
||||||
|
|
||||||
const auto kStyleErrorActiveLabel = //
|
|
||||||
QString("padding: 3px 5px; border-radius: 3px; "
|
|
||||||
"background-color: %1; color: %2")
|
|
||||||
.arg(kColorError, kColorWhite);
|
|
||||||
|
|
||||||
const auto kStyleErrorInactiveLabel = //
|
|
||||||
QString("padding: 3px 5px; border-radius: 3px;"
|
|
||||||
"background-color: none");
|
|
||||||
|
|
||||||
const auto kStyleNoticeLabel = //
|
|
||||||
QString("padding: 3px 5px; border-radius: 3px;"
|
|
||||||
"background-color: %1; color: %2")
|
|
||||||
.arg(kColorNotice, kColorWhite);
|
|
||||||
|
|
|
||||||
|
|
@ -19,6 +19,7 @@
|
||||||
|
|
||||||
#include "constants.h"
|
#include "constants.h"
|
||||||
#include "license/License.h"
|
#include "license/License.h"
|
||||||
|
#include "styles.h"
|
||||||
|
|
||||||
using License = synergy::license::License;
|
using License = synergy::license::License;
|
||||||
|
|
||||||
|
|
|
||||||
159
src/lib/gui/messages.cpp
Normal file
159
src/lib/gui/messages.cpp
Normal file
|
|
@ -0,0 +1,159 @@
|
||||||
|
/*
|
||||||
|
* 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 "messages.h"
|
||||||
|
|
||||||
|
#include "constants.h"
|
||||||
|
#include "styles.h"
|
||||||
|
|
||||||
|
#include <QDateTime>
|
||||||
|
#include <QMessageBox>
|
||||||
|
#include <QTime>
|
||||||
|
|
||||||
|
namespace synergy::gui::messages {
|
||||||
|
|
||||||
|
void messageHandler(
|
||||||
|
QtMsgType type, const QMessageLogContext &context, const QString &message) {
|
||||||
|
|
||||||
|
auto datetime = QDateTime::currentDateTime().toString("yyyy-MM-ddTHH:mm:ss");
|
||||||
|
const auto filename = QString(context.file).split("/").last();
|
||||||
|
auto function = context.function ? context.function : "";
|
||||||
|
|
||||||
|
QString typeString;
|
||||||
|
auto out = stdout;
|
||||||
|
switch (type) {
|
||||||
|
case QtDebugMsg:
|
||||||
|
typeString = "DEBUG";
|
||||||
|
break;
|
||||||
|
case QtInfoMsg:
|
||||||
|
typeString = "INFO";
|
||||||
|
break;
|
||||||
|
case QtWarningMsg:
|
||||||
|
typeString = "WARNING";
|
||||||
|
out = stderr;
|
||||||
|
break;
|
||||||
|
case QtCriticalMsg:
|
||||||
|
typeString = "CRITICAL";
|
||||||
|
out = stderr;
|
||||||
|
break;
|
||||||
|
case QtFatalMsg:
|
||||||
|
typeString = "FATAL";
|
||||||
|
out = stderr;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto logLine = QString("[%1] %2: %3\n\t%4:%5, %6")
|
||||||
|
.arg(datetime)
|
||||||
|
.arg(typeString)
|
||||||
|
.arg(message)
|
||||||
|
.arg(filename)
|
||||||
|
.arg(context.line)
|
||||||
|
.arg(function);
|
||||||
|
|
||||||
|
auto logLineUtf = logLine.toUtf8();
|
||||||
|
auto logLine_c = logLineUtf.constData();
|
||||||
|
fprintf(out, "%s\n", logLine_c);
|
||||||
|
|
||||||
|
if (type == QtFatalMsg) {
|
||||||
|
auto contextString =
|
||||||
|
QString("%1:%2\n%3").arg(filename).arg(context.line).arg(function);
|
||||||
|
|
||||||
|
QMessageBox::critical(
|
||||||
|
nullptr, "Fatal error",
|
||||||
|
QString("<p>Sorry, a fatal error has occurred "
|
||||||
|
"and the application must now exit.</p>"
|
||||||
|
"<p>Please "
|
||||||
|
R"(<a href="%1" style="color: %2">contact us</a>)"
|
||||||
|
" and copy/paste the following error:</p>"
|
||||||
|
"<pre>%3\n\n%4</pre>")
|
||||||
|
.arg(kUrlContact, kColorSecondary, message, contextString));
|
||||||
|
|
||||||
|
// developers: if you hit this line in your debugger, traverse the stack to
|
||||||
|
// find the cause of the fatal error.
|
||||||
|
// important: crash the app on fatal error to prevent the app being used in
|
||||||
|
// a broken state.
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void showCloseReminder(QWidget *parent) {
|
||||||
|
QString message =
|
||||||
|
"<p>Synergy will continue to run in the background and can be accessed "
|
||||||
|
"via the Synergy icon in your system notifications area. This setting "
|
||||||
|
"can be disabled.</p>";
|
||||||
|
|
||||||
|
#if defined(Q_OS_LINUX)
|
||||||
|
message += QString("<p>On some Linux systems such as GNOME 3, the "
|
||||||
|
"notification area might be disabled. "
|
||||||
|
"You may need to "
|
||||||
|
R"(<a href="%1" %2>enable an extension</a>)"
|
||||||
|
" to see the Synergy tray icon.</p>")
|
||||||
|
.arg(kUrlGnomeTrayFix, kStyleLink);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
QMessageBox::information(parent, "Notification area icon", message);
|
||||||
|
}
|
||||||
|
|
||||||
|
void showFirstRunMessage(
|
||||||
|
QWidget *parent, bool closeToTray, bool enableService, bool isServer) {
|
||||||
|
|
||||||
|
auto message = QString("<p>Synergy is now connected!</p>");
|
||||||
|
|
||||||
|
if (isServer) {
|
||||||
|
message +=
|
||||||
|
"<p>Try moving your mouse to your other computer. Once there, go ahead "
|
||||||
|
"and type something.</p>"
|
||||||
|
"<p>Don't forget, you can copy and paste between computers too.</p>";
|
||||||
|
} else {
|
||||||
|
message += "<p>Try controlling this computer remotely.</p>";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!closeToTray && !enableService) {
|
||||||
|
message +=
|
||||||
|
"<p>As you do not have the setting enabled to keep Synergy running in "
|
||||||
|
"the background, you'll need to keep this window open or minimized to "
|
||||||
|
"keep Synergy running.</p>";
|
||||||
|
} else {
|
||||||
|
message +=
|
||||||
|
"<p>You can now close this window and Synergy will continue to run in "
|
||||||
|
"the background. This setting can be disabled.</p>";
|
||||||
|
}
|
||||||
|
|
||||||
|
QMessageBox::information(parent, "Connected", message);
|
||||||
|
}
|
||||||
|
|
||||||
|
void showDevThanks(QWidget *parent, const QString &productName) {
|
||||||
|
if (productName.isEmpty()) {
|
||||||
|
qFatal("product name not set");
|
||||||
|
}
|
||||||
|
|
||||||
|
QMessageBox::information(
|
||||||
|
parent, "Thank you!",
|
||||||
|
QString(
|
||||||
|
"<p>Thanks for using %1.</p>"
|
||||||
|
"<p>If you enjoy using this app, you can support the developers by "
|
||||||
|
R"(<a href="%1" style="color: %2")>purchasing a license</a>)"
|
||||||
|
" or "
|
||||||
|
R"(<a href="%3" style="color: %4")>contributing code</a>.)"
|
||||||
|
"</p>"
|
||||||
|
"<p>This message will only appear once.</p>")
|
||||||
|
.arg(
|
||||||
|
productName, kUrlPurchase, kColorSecondary, kUrlContribute,
|
||||||
|
kColorSecondary));
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace synergy::gui::messages
|
||||||
36
src/lib/gui/messages.h
Normal file
36
src/lib/gui/messages.h
Normal file
|
|
@ -0,0 +1,36 @@
|
||||||
|
/*
|
||||||
|
* 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 <QMessageLogContext>
|
||||||
|
#include <QString>
|
||||||
|
#include <QWidget>
|
||||||
|
|
||||||
|
namespace synergy::gui::messages {
|
||||||
|
|
||||||
|
void messageHandler(
|
||||||
|
QtMsgType type, const QMessageLogContext &context, const QString &msg);
|
||||||
|
|
||||||
|
void showFirstRunMessage(
|
||||||
|
QWidget *parent, bool closeToTray, bool enableService, bool isServer);
|
||||||
|
|
||||||
|
void showCloseReminder(QWidget *parent);
|
||||||
|
|
||||||
|
void showDevThanks(QWidget *parent, const QString &productName);
|
||||||
|
|
||||||
|
} // namespace synergy::gui::messages
|
||||||
49
src/lib/gui/styles.h
Normal file
49
src/lib/gui/styles.h
Normal file
|
|
@ -0,0 +1,49 @@
|
||||||
|
/*
|
||||||
|
* 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>
|
||||||
|
|
||||||
|
const auto kColorWhite = "#ffffff";
|
||||||
|
const auto kColorPrimary = "#ff7c00";
|
||||||
|
const auto kColorSecondary = "#4285f4";
|
||||||
|
const auto kColorTertiary = "#33b2cc";
|
||||||
|
const auto kColorError = "#ec4c47";
|
||||||
|
const auto kColorNotice = "#3b67d3";
|
||||||
|
const auto kColorLightGrey = "#666666";
|
||||||
|
|
||||||
|
const auto kStyleLink = //
|
||||||
|
QString("color: %1").arg(kColorSecondary);
|
||||||
|
|
||||||
|
const auto kStyleLineEditErrorBorder =
|
||||||
|
QString("border: 1px solid %1; border-radius: 2px; padding: 2px;")
|
||||||
|
.arg(kColorError);
|
||||||
|
|
||||||
|
const auto kStyleErrorActiveLabel = //
|
||||||
|
QString("padding: 3px 5px; border-radius: 3px; "
|
||||||
|
"background-color: %1; color: %2")
|
||||||
|
.arg(kColorError, kColorWhite);
|
||||||
|
|
||||||
|
const auto kStyleErrorInactiveLabel = //
|
||||||
|
QString("padding: 3px 5px; border-radius: 3px;"
|
||||||
|
"background-color: none");
|
||||||
|
|
||||||
|
const auto kStyleNoticeLabel = //
|
||||||
|
QString("padding: 3px 5px; border-radius: 3px;"
|
||||||
|
"background-color: %1; color: %2")
|
||||||
|
.arg(kColorNotice, kColorWhite);
|
||||||
38
src/lib/gui/version.cpp
Normal file
38
src/lib/gui/version.cpp
Normal file
|
|
@ -0,0 +1,38 @@
|
||||||
|
/*
|
||||||
|
* 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 "version.h"
|
||||||
|
|
||||||
|
const QString kVersion = SYNERGY_VERSION;
|
||||||
|
|
||||||
|
#ifdef GIT_SHA_SHORT
|
||||||
|
const QString kVersionGitSha = GIT_SHA_SHORT;
|
||||||
|
#else
|
||||||
|
const QString kVersionGitSha;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
namespace synergy::gui {
|
||||||
|
|
||||||
|
QString version() {
|
||||||
|
QString result(kVersion);
|
||||||
|
if (!kVersionGitSha.isEmpty()) {
|
||||||
|
result.append(QString(" (%1)").arg(kVersionGitSha));
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace synergy::gui
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* synergy -- mouse and keyboard sharing utility
|
* synergy -- mouse and keyboard sharing utility
|
||||||
* Copyright (C) 2020 Symless Ltd.
|
* Copyright (C) 2024 Symless Ltd.
|
||||||
*
|
*
|
||||||
* This package is free software; you can redistribute it and/or
|
* This package is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License
|
* modify it under the terms of the GNU General Public License
|
||||||
|
|
@ -17,20 +17,10 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <QString>
|
||||||
|
|
||||||
namespace synergy::gui {
|
namespace synergy::gui {
|
||||||
|
|
||||||
/// @brief Common configuration interface
|
QString version();
|
||||||
class CommonConfig {
|
|
||||||
public:
|
|
||||||
CommonConfig() = default;
|
|
||||||
virtual ~CommonConfig() = default;
|
|
||||||
virtual void loadSettings() = 0;
|
|
||||||
virtual void saveSettings() = 0;
|
|
||||||
bool modified() const { return m_modified; }
|
|
||||||
void setModified(bool modified) { m_modified = modified; }
|
|
||||||
|
|
||||||
private:
|
|
||||||
bool m_modified = false;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace synergy::gui
|
} // namespace synergy::gui
|
||||||
|
|
@ -435,11 +435,13 @@ void Server::switchScreen(
|
||||||
BaseClientProxy *dst, SInt32 x, SInt32 y, bool forScreensaver) {
|
BaseClientProxy *dst, SInt32 x, SInt32 y, bool forScreensaver) {
|
||||||
assert(dst != NULL);
|
assert(dst != NULL);
|
||||||
|
|
||||||
// if trial is expired, exit the process
|
if (m_args.m_serialKey.isValid) {
|
||||||
License license(m_args.m_serialKey);
|
// if license is expired, exit the process
|
||||||
if (license.isExpired()) {
|
License license(m_args.m_serialKey);
|
||||||
LOG((CLOG_ERR "trial has expired, aborting server"));
|
if (license.isExpired()) {
|
||||||
exit(kExitSuccess);
|
LOG((CLOG_ERR "trial has expired, aborting server"));
|
||||||
|
exit(kExitSuccess);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
|
|
|
||||||
|
|
@ -17,6 +17,8 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "gui/messages.h"
|
||||||
|
|
||||||
#include <QCoreApplication>
|
#include <QCoreApplication>
|
||||||
#include <gtest/gtest.h>
|
#include <gtest/gtest.h>
|
||||||
|
|
||||||
|
|
@ -26,6 +28,7 @@ public:
|
||||||
char **argv = nullptr;
|
char **argv = nullptr;
|
||||||
int argc = 0;
|
int argc = 0;
|
||||||
s_app = std::make_unique<QCoreApplication>(argc, argv);
|
s_app = std::make_unique<QCoreApplication>(argc, argv);
|
||||||
|
qInstallMessageHandler(synergy::gui::messages::messageHandler);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void TearDownTestSuite() { s_app.reset(); }
|
static void TearDownTestSuite() { s_app.reset(); }
|
||||||
|
|
|
||||||
|
|
@ -17,6 +17,8 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "gui/messages.h"
|
||||||
|
|
||||||
#include <QApplication>
|
#include <QApplication>
|
||||||
#include <gtest/gtest.h>
|
#include <gtest/gtest.h>
|
||||||
|
|
||||||
|
|
@ -26,6 +28,7 @@ public:
|
||||||
char **argv = nullptr;
|
char **argv = nullptr;
|
||||||
int argc = 0;
|
int argc = 0;
|
||||||
s_app = std::make_unique<QApplication>(argc, argv);
|
s_app = std::make_unique<QApplication>(argc, argv);
|
||||||
|
qInstallMessageHandler(synergy::gui::messages::messageHandler);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void TearDownTestSuite() { s_app.reset(); }
|
static void TearDownTestSuite() { s_app.reset(); }
|
||||||
|
|
|
||||||
|
|
@ -33,6 +33,8 @@ using PollFD = struct pollfd[];
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
struct MockDeps : public ArchNetworkBSD::Deps {
|
struct MockDeps : public ArchNetworkBSD::Deps {
|
||||||
|
std::shared_ptr<PollFD> m_pollFD;
|
||||||
|
|
||||||
MockDeps() {
|
MockDeps() {
|
||||||
ON_CALL(*this, makePollFD(_)).WillByDefault([this](nfds_t n) {
|
ON_CALL(*this, makePollFD(_)).WillByDefault([this](nfds_t n) {
|
||||||
m_pollFD = ArchNetworkBSD::Deps::makePollFD(n);
|
m_pollFD = ArchNetworkBSD::Deps::makePollFD(n);
|
||||||
|
|
@ -40,29 +42,31 @@ struct MockDeps : public ArchNetworkBSD::Deps {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static std::shared_ptr<NiceMock<MockDeps>> makeNice() {
|
||||||
|
return std::make_shared<NiceMock<MockDeps>>();
|
||||||
|
}
|
||||||
|
|
||||||
MOCK_METHOD(void, sleep, (double), (override));
|
MOCK_METHOD(void, sleep, (double), (override));
|
||||||
MOCK_METHOD(int, poll, (struct pollfd *, nfds_t, int), (override));
|
MOCK_METHOD(int, poll, (struct pollfd *, nfds_t, int), (override));
|
||||||
MOCK_METHOD(std::shared_ptr<PollFD>, makePollFD, (nfds_t), (override));
|
MOCK_METHOD(std::shared_ptr<PollFD>, makePollFD, (nfds_t), (override));
|
||||||
MOCK_METHOD(ssize_t, read, (int, void *, size_t), (override));
|
MOCK_METHOD(ssize_t, read, (int, void *, size_t), (override));
|
||||||
MOCK_METHOD(void, testCancelThread, (), (override));
|
MOCK_METHOD(void, testCancelThread, (), (override));
|
||||||
|
|
||||||
std::shared_ptr<PollFD> m_pollFD;
|
|
||||||
};
|
};
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
TEST(ArchNetworkBSDTests, pollSocket_zeroEntries_callsSleep) {
|
TEST(ArchNetworkBSDTests, pollSocket_zeroEntries_callsSleep) {
|
||||||
MockDeps deps;
|
auto deps = MockDeps::makeNice();
|
||||||
ArchNetworkBSD networkBSD(deps);
|
ArchNetworkBSD networkBSD(deps);
|
||||||
|
|
||||||
EXPECT_CALL(deps, sleep(1)).Times(1);
|
EXPECT_CALL(*deps, sleep(1)).Times(1);
|
||||||
auto result = networkBSD.pollSocket(nullptr, 0, 1);
|
auto result = networkBSD.pollSocket(nullptr, 0, 1);
|
||||||
|
|
||||||
EXPECT_EQ(result, 0);
|
EXPECT_EQ(result, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(ArchNetworkBSDTests, pollSocket_mockAccessError_throws) {
|
TEST(ArchNetworkBSDTests, pollSocket_mockAccessError_throws) {
|
||||||
NiceMock<MockDeps> deps;
|
auto deps = MockDeps::makeNice();
|
||||||
ON_CALL(deps, poll(_, _, _)).WillByDefault([]() {
|
ON_CALL(*deps, poll(_, _, _)).WillByDefault([]() {
|
||||||
errno = EACCES;
|
errno = EACCES;
|
||||||
return -1;
|
return -1;
|
||||||
});
|
});
|
||||||
|
|
@ -77,8 +81,8 @@ TEST(ArchNetworkBSDTests, pollSocket_mockAccessError_throws) {
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(ArchNetworkBSDTests, pollSocket_pfdHasRevents_copiedToEntries) {
|
TEST(ArchNetworkBSDTests, pollSocket_pfdHasRevents_copiedToEntries) {
|
||||||
NiceMock<MockDeps> deps;
|
auto deps = MockDeps::makeNice();
|
||||||
ON_CALL(deps, poll(_, _, _)).WillByDefault([](auto pfd, auto, auto) {
|
ON_CALL(*deps, poll(_, _, _)).WillByDefault([](auto pfd, auto, auto) {
|
||||||
pfd[0].revents = POLLIN | POLLOUT | POLLERR | POLLNVAL;
|
pfd[0].revents = POLLIN | POLLOUT | POLLERR | POLLNVAL;
|
||||||
return 0;
|
return 0;
|
||||||
});
|
});
|
||||||
|
|
@ -93,50 +97,50 @@ TEST(ArchNetworkBSDTests, pollSocket_pfdHasRevents_copiedToEntries) {
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(ArchNetworkBSDTests, pollSocket_nullSocket_fdIsNegativeOne) {
|
TEST(ArchNetworkBSDTests, pollSocket_nullSocket_fdIsNegativeOne) {
|
||||||
NiceMock<MockDeps> deps;
|
auto deps = MockDeps::makeNice();
|
||||||
ArchNetworkBSD networkBSD(deps);
|
ArchNetworkBSD networkBSD(deps);
|
||||||
PollEntries entries{{nullptr, 0, 0}};
|
PollEntries entries{{nullptr, 0, 0}};
|
||||||
|
|
||||||
networkBSD.pollSocket(entries.data(), static_cast<int>(entries.size()), 1);
|
networkBSD.pollSocket(entries.data(), static_cast<int>(entries.size()), 1);
|
||||||
|
|
||||||
EXPECT_EQ(deps.m_pollFD[0].fd, -1);
|
EXPECT_EQ(deps->m_pollFD[0].fd, -1);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(ArchNetworkBSDTests, pollSocket_socketSet_fdWasSet) {
|
TEST(ArchNetworkBSDTests, pollSocket_socketSet_fdWasSet) {
|
||||||
NiceMock<MockDeps> deps;
|
auto deps = MockDeps::makeNice();
|
||||||
ArchNetworkBSD networkBSD(deps);
|
ArchNetworkBSD networkBSD(deps);
|
||||||
ArchSocketImpl socket{1, 0};
|
ArchSocketImpl socket{1, 0};
|
||||||
PollEntries entries{{&socket, 0, 0}};
|
PollEntries entries{{&socket, 0, 0}};
|
||||||
|
|
||||||
networkBSD.pollSocket(entries.data(), static_cast<int>(entries.size()), 1);
|
networkBSD.pollSocket(entries.data(), static_cast<int>(entries.size()), 1);
|
||||||
|
|
||||||
EXPECT_EQ(deps.m_pollFD[0].fd, 1);
|
EXPECT_EQ(deps->m_pollFD[0].fd, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(ArchNetworkBSDTests, pollSocket_eventHasPollInBit_bitWasSet) {
|
TEST(ArchNetworkBSDTests, pollSocket_eventHasPollInBit_bitWasSet) {
|
||||||
NiceMock<MockDeps> deps;
|
auto deps = MockDeps::makeNice();
|
||||||
ArchNetworkBSD networkBSD(deps);
|
ArchNetworkBSD networkBSD(deps);
|
||||||
ArchSocketImpl socket{1, 0};
|
ArchSocketImpl socket{1, 0};
|
||||||
PollEntries entries{{&socket, IArchNetwork::kPOLLIN, 0}};
|
PollEntries entries{{&socket, IArchNetwork::kPOLLIN, 0}};
|
||||||
|
|
||||||
networkBSD.pollSocket(entries.data(), static_cast<int>(entries.size()), 1);
|
networkBSD.pollSocket(entries.data(), static_cast<int>(entries.size()), 1);
|
||||||
|
|
||||||
EXPECT_EQ(deps.m_pollFD[0].events, POLLIN);
|
EXPECT_EQ(deps->m_pollFD[0].events, POLLIN);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(ArchNetworkBSDTests, pollSocket_eventHasPollOutBit_bitWasSet) {
|
TEST(ArchNetworkBSDTests, pollSocket_eventHasPollOutBit_bitWasSet) {
|
||||||
NiceMock<MockDeps> deps;
|
auto deps = MockDeps::makeNice();
|
||||||
ArchNetworkBSD networkBSD(deps);
|
ArchNetworkBSD networkBSD(deps);
|
||||||
ArchSocketImpl socket{1, 0};
|
ArchSocketImpl socket{1, 0};
|
||||||
PollEntries entries{{&socket, IArchNetwork::kPOLLOUT, 0}};
|
PollEntries entries{{&socket, IArchNetwork::kPOLLOUT, 0}};
|
||||||
|
|
||||||
networkBSD.pollSocket(entries.data(), static_cast<int>(entries.size()), 1);
|
networkBSD.pollSocket(entries.data(), static_cast<int>(entries.size()), 1);
|
||||||
|
|
||||||
EXPECT_EQ(deps.m_pollFD[0].events, POLLOUT);
|
EXPECT_EQ(deps->m_pollFD[0].events, POLLOUT);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(ArchNetworkBSDTests, pollSocket_nullSocket_unblockPipeAppended) {
|
TEST(ArchNetworkBSDTests, pollSocket_nullSocket_unblockPipeAppended) {
|
||||||
NiceMock<MockDeps> deps;
|
auto deps = MockDeps::makeNice();
|
||||||
ArchNetworkBSD networkBSD(deps);
|
ArchNetworkBSD networkBSD(deps);
|
||||||
PollEntries entries{{nullptr, 0, 0}};
|
PollEntries entries{{nullptr, 0, 0}};
|
||||||
|
|
||||||
|
|
@ -144,42 +148,42 @@ TEST(ArchNetworkBSDTests, pollSocket_nullSocket_unblockPipeAppended) {
|
||||||
|
|
||||||
// interesting: unblock pipe fd comes from `getNetworkDataForThread` which
|
// interesting: unblock pipe fd comes from `getNetworkDataForThread` which
|
||||||
// seems to differ depending on linux distro.
|
// seems to differ depending on linux distro.
|
||||||
EXPECT_GT(deps.m_pollFD[1].fd, -1);
|
EXPECT_GT(deps->m_pollFD[1].fd, -1);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(ArchNetworkBSDTests, pollSocket_unblockPipeReventsError_readCalled) {
|
TEST(ArchNetworkBSDTests, pollSocket_unblockPipeReventsError_readCalled) {
|
||||||
const auto unblockPipeIndex = 1;
|
const auto unblockPipeIndex = 1;
|
||||||
NiceMock<MockDeps> deps;
|
auto deps = MockDeps::makeNice();
|
||||||
ON_CALL(deps, poll(_, _, _)).WillByDefault([](auto pfd, auto, auto) {
|
ON_CALL(*deps, poll(_, _, _)).WillByDefault([](auto pfd, auto, auto) {
|
||||||
pfd[unblockPipeIndex].revents = POLLIN;
|
pfd[unblockPipeIndex].revents = POLLIN;
|
||||||
return 1;
|
return 1;
|
||||||
});
|
});
|
||||||
ON_CALL(deps, read(_, _, _)).WillByDefault([]() {
|
ON_CALL(*deps, read(_, _, _)).WillByDefault([]() {
|
||||||
errno = EAGAIN;
|
errno = EAGAIN;
|
||||||
return 0;
|
return 0;
|
||||||
});
|
});
|
||||||
ArchNetworkBSD networkBSD(deps);
|
ArchNetworkBSD networkBSD(deps);
|
||||||
PollEntries entries{{nullptr, 0, 0}};
|
PollEntries entries{{nullptr, 0, 0}};
|
||||||
|
|
||||||
EXPECT_CALL(deps, read(_, _, _)).Times(1);
|
EXPECT_CALL(*deps, read(_, _, _)).Times(1);
|
||||||
networkBSD.pollSocket(entries.data(), static_cast<int>(entries.size()), 1);
|
networkBSD.pollSocket(entries.data(), static_cast<int>(entries.size()), 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(ArchNetworkBSDTests, pollSocket_interruptSystemCall_testCancelThread) {
|
TEST(ArchNetworkBSDTests, pollSocket_interruptSystemCall_testCancelThread) {
|
||||||
NiceMock<MockDeps> deps;
|
auto deps = MockDeps::makeNice();
|
||||||
ON_CALL(deps, poll(_, _, _)).WillByDefault([]() {
|
ON_CALL(*deps, poll(_, _, _)).WillByDefault([]() {
|
||||||
errno = EINTR;
|
errno = EINTR;
|
||||||
return -1;
|
return -1;
|
||||||
});
|
});
|
||||||
ArchNetworkBSD networkBSD(deps);
|
ArchNetworkBSD networkBSD(deps);
|
||||||
PollEntries entries{{nullptr, 0, 0}};
|
PollEntries entries{{nullptr, 0, 0}};
|
||||||
|
|
||||||
EXPECT_CALL(deps, testCancelThread()).Times(1);
|
EXPECT_CALL(*deps, testCancelThread()).Times(1);
|
||||||
networkBSD.pollSocket(entries.data(), static_cast<int>(entries.size()), 1);
|
networkBSD.pollSocket(entries.data(), static_cast<int>(entries.size()), 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(ArchNetworkBSDTests, isAnyAddr_goodAddress_returnsTrue) {
|
TEST(ArchNetworkBSDTests, isAnyAddr_goodAddress_returnsTrue) {
|
||||||
MockDeps deps;
|
auto deps = MockDeps::makeNice();
|
||||||
ArchNetworkBSD networkBSD(deps);
|
ArchNetworkBSD networkBSD(deps);
|
||||||
std::unique_ptr<ArchNetAddressImpl> addr;
|
std::unique_ptr<ArchNetAddressImpl> addr;
|
||||||
addr.reset(networkBSD.newAnyAddr(IArchNetwork::kINET6));
|
addr.reset(networkBSD.newAnyAddr(IArchNetwork::kINET6));
|
||||||
|
|
@ -190,7 +194,7 @@ TEST(ArchNetworkBSDTests, isAnyAddr_goodAddress_returnsTrue) {
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(ArchNetworkBSDTests, isAnyAddr_badAddress_returnsFalse) {
|
TEST(ArchNetworkBSDTests, isAnyAddr_badAddress_returnsFalse) {
|
||||||
MockDeps deps;
|
auto deps = MockDeps::makeNice();
|
||||||
ArchNetworkBSD networkBSD(deps);
|
ArchNetworkBSD networkBSD(deps);
|
||||||
std::unique_ptr<ArchNetAddressImpl> addr;
|
std::unique_ptr<ArchNetAddressImpl> addr;
|
||||||
addr.reset(networkBSD.newAnyAddr(IArchNetwork::kINET6));
|
addr.reset(networkBSD.newAnyAddr(IArchNetwork::kINET6));
|
||||||
|
|
|
||||||
|
|
@ -27,37 +27,35 @@ namespace {
|
||||||
|
|
||||||
class MockScopes : public synergy::gui::IConfigScopes {
|
class MockScopes : public synergy::gui::IConfigScopes {
|
||||||
public:
|
public:
|
||||||
|
MOCK_METHOD(void, signalReady, (), (override));
|
||||||
MOCK_METHOD(
|
MOCK_METHOD(
|
||||||
void, registerReceiver, (synergy::gui::CommonConfig * receiver),
|
bool, scopeContains, (const QString &name, Scope scope),
|
||||||
(override));
|
(const, override));
|
||||||
MOCK_METHOD(void, loadAll, (), (override));
|
|
||||||
MOCK_METHOD(
|
MOCK_METHOD(
|
||||||
bool, hasSetting, (const QString &name, Scope scope), (const, override));
|
QVariant, getFromScope,
|
||||||
MOCK_METHOD(
|
|
||||||
QVariant, loadSetting,
|
|
||||||
(const QString &name, const QVariant &defaultValue, Scope scope),
|
(const QString &name, const QVariant &defaultValue, Scope scope),
|
||||||
(const, override));
|
(const, override));
|
||||||
MOCK_METHOD(
|
MOCK_METHOD(
|
||||||
void, setSetting,
|
void, setInScope,
|
||||||
(const QString &name, const QVariant &value, Scope scope), (override));
|
(const QString &name, const QVariant &value, Scope scope), (override));
|
||||||
MOCK_METHOD(Scope, getScope, (), (const, override));
|
MOCK_METHOD(Scope, activeScope, (), (const, override));
|
||||||
MOCK_METHOD(void, setScope, (Scope scope), (override));
|
MOCK_METHOD(void, setActiveScope, (Scope scope), (override));
|
||||||
MOCK_METHOD(bool, isWritable, (), (const, override));
|
MOCK_METHOD(bool, isActiveScopeWritable, (), (const, override));
|
||||||
MOCK_METHOD(QSettings *, currentSettings, (), (const, override));
|
MOCK_METHOD(QSettings *, activeSettings, (), (const, override));
|
||||||
MOCK_METHOD(void, saveAll, (), (override));
|
MOCK_METHOD(void, save, (), (override));
|
||||||
};
|
};
|
||||||
|
|
||||||
struct MockDeps : public AppConfig::Deps {
|
struct MockDeps : public AppConfig::Deps {
|
||||||
NiceMock<MockScopes> m_scopes;
|
|
||||||
|
|
||||||
MockDeps() {
|
MockDeps() {
|
||||||
ON_CALL(*this, profileDir()).WillByDefault(Return("stub"));
|
ON_CALL(*this, profileDir()).WillByDefault(Return("stub"));
|
||||||
ON_CALL(*this, scopes()).WillByDefault(ReturnRef(m_scopes));
|
|
||||||
ON_CALL(*this, hostname()).WillByDefault(Return("stub"));
|
ON_CALL(*this, hostname()).WillByDefault(Return("stub"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static std::shared_ptr<NiceMock<MockDeps>> makeNice() {
|
||||||
|
return std::make_shared<NiceMock<MockDeps>>();
|
||||||
|
}
|
||||||
|
|
||||||
MOCK_METHOD(QString, profileDir, (), (const, override));
|
MOCK_METHOD(QString, profileDir, (), (const, override));
|
||||||
MOCK_METHOD(synergy::gui::IConfigScopes &, scopes, (), (override));
|
|
||||||
MOCK_METHOD(QString, hostname, (), (const, override));
|
MOCK_METHOD(QString, hostname, (), (const, override));
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -66,43 +64,36 @@ struct MockDeps : public AppConfig::Deps {
|
||||||
class AppConfigTests : public Test {};
|
class AppConfigTests : public Test {};
|
||||||
|
|
||||||
TEST_F(AppConfigTests, ctor_byDefault_screenNameIsHostname) {
|
TEST_F(AppConfigTests, ctor_byDefault_screenNameIsHostname) {
|
||||||
NiceMock<MockDeps> deps;
|
NiceMock<MockScopes> scopes;
|
||||||
ON_CALL(deps, hostname()).WillByDefault(Return("test"));
|
auto deps = MockDeps::makeNice();
|
||||||
|
ON_CALL(*deps, hostname()).WillByDefault(Return("test hostname"));
|
||||||
|
|
||||||
AppConfig appConfig(deps);
|
AppConfig appConfig(scopes, deps);
|
||||||
|
|
||||||
ASSERT_EQ(appConfig.screenName().toStdString(), "test");
|
ASSERT_EQ(appConfig.screenName().toStdString(), "test hostname");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(AppConfigTests, loadAllScopes_byDefault_callsScopesLoadAll) {
|
TEST_F(AppConfigTests, ctor_byDefault_getsFromScope) {
|
||||||
NiceMock<MockDeps> deps;
|
NiceMock<MockScopes> scopes;
|
||||||
AppConfig appConfig(deps);
|
auto deps = MockDeps::makeNice();
|
||||||
|
|
||||||
EXPECT_CALL(deps.m_scopes, loadAll());
|
ON_CALL(scopes, scopeContains(_, _)).WillByDefault(Return(true));
|
||||||
|
ON_CALL(scopes, getFromScope(_, _, _))
|
||||||
|
.WillByDefault(Return(QVariant("test screen")));
|
||||||
|
EXPECT_CALL(scopes, getFromScope(_, _, _)).Times(AnyNumber());
|
||||||
|
|
||||||
appConfig.loadAllScopes();
|
AppConfig appConfig(scopes, deps);
|
||||||
|
|
||||||
|
ASSERT_EQ(appConfig.screenName().toStdString(), "test screen");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(AppConfigTests, loadSettings_byDefault_callsScopesLoadSetting) {
|
TEST_F(AppConfigTests, commit_byDefault_setsToScope) {
|
||||||
NiceMock<MockDeps> deps;
|
NiceMock<MockScopes> scopes;
|
||||||
AppConfig appConfig(deps);
|
auto deps = MockDeps::makeNice();
|
||||||
|
AppConfig appConfig(scopes, deps);
|
||||||
|
|
||||||
ON_CALL(deps.m_scopes, hasSetting(_, _)).WillByDefault(Return(true));
|
ON_CALL(scopes, isActiveScopeWritable()).WillByDefault(Return(true));
|
||||||
ON_CALL(deps.m_scopes, loadSetting(_, _, _))
|
EXPECT_CALL(scopes, setInScope(_, _, _)).Times(AnyNumber());
|
||||||
.WillByDefault(Return(QVariant("test")));
|
|
||||||
EXPECT_CALL(deps.m_scopes, loadSetting(_, _, _)).Times(AnyNumber());
|
|
||||||
|
|
||||||
appConfig.loadSettings();
|
appConfig.commit();
|
||||||
|
|
||||||
ASSERT_EQ(appConfig.screenName().toStdString(), "test");
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_F(AppConfigTests, saveSettings_byDefault_callsScopesSetSetting) {
|
|
||||||
NiceMock<MockDeps> deps;
|
|
||||||
AppConfig appConfig(deps);
|
|
||||||
|
|
||||||
ON_CALL(deps.m_scopes, isWritable()).WillByDefault(Return(true));
|
|
||||||
EXPECT_CALL(deps.m_scopes, setSetting(_, _, _)).Times(AnyNumber());
|
|
||||||
|
|
||||||
appConfig.saveSettings();
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -28,6 +28,7 @@ const auto kFuture = system_clock::now() + hours(1);
|
||||||
|
|
||||||
TEST(LicenseHandlerTests, changeSerialKey_validExpiredLicense_returnsTrue) {
|
TEST(LicenseHandlerTests, changeSerialKey_validExpiredLicense_returnsTrue) {
|
||||||
LicenseHandler licenseHandler;
|
LicenseHandler licenseHandler;
|
||||||
|
licenseHandler.setEnabled(true);
|
||||||
auto hexString = //
|
auto hexString = //
|
||||||
"7B76313B70726F3B6E69636B20626F6C746F6E3B313B6"
|
"7B76313B70726F3B6E69636B20626F6C746F6E3B313B6"
|
||||||
"E69636B4073796D6C6573732E636F6D3B203B303B307D";
|
"E69636B4073796D6C6573732E636F6D3B203B303B307D";
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue