deskflow/src/gui/src/SettingsDialog.cpp

369 lines
14 KiB
C++
Raw Normal View History

2012-06-10 16:50:54 +00:00
/*
* synergy -- mouse and keyboard sharing utility
2016-09-07 14:24:00 +00:00
* Copyright (C) 2012-2016 Symless Ltd.
2012-06-10 16:50:54 +00:00
* Copyright (C) 2008 Volker Lanz (vl@fidra.de)
*
2012-06-10 16:50:54 +00:00
* 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.
*
2012-06-10 16:50:54 +00:00
* 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 "SettingsDialog.h"
2021-04-13 10:23:22 +00:00
#include "validators/ScreenNameValidator.h"
#include "AppConfig.h"
#include "CoreInterface.h"
#include "MainWindow.h"
#include "QSynergyApplication.h"
#include "QUtility.h"
#include "SslCertificate.h"
#include "UpgradeDialog.h"
2012-06-10 16:50:54 +00:00
#include <QDir>
#include <QFileDialog>
#include <QMessageBox>
2012-06-10 16:50:54 +00:00
#include <QtCore>
#include <QtGui>
SettingsDialog::SettingsDialog(QWidget *parent, AppConfig &config)
: QDialog(parent, Qt::WindowTitleHint | Qt::WindowSystemMenuHint),
Ui::SettingsDialogBase(),
m_appConfig(config) {
setupUi(this);
// TODO: maybe just accept MainWindow type in ctor?
m_pMainWindow = dynamic_cast<MainWindow *>(parent);
loadFromConfig();
m_isSystemAtStart = appConfig().isSystemScoped();
buttonBox->button(QDialogButtonBox::Save)->setEnabled(false);
enableControls(appConfig().isWritable());
m_pCheckBoxLanguageSync->setEnabled(isClientMode());
m_pCheckBoxScrollDirection->setEnabled(isClientMode());
const auto &serveConfig = m_pMainWindow->serverConfig();
m_pLineEditScreenName->setValidator(new validators::ScreenNameValidator(
m_pLineEditScreenName, m_pLabelNameError, (&serveConfig.screens())));
connect(
m_pLineEditLogFilename, SIGNAL(textChanged(QString)), this,
SLOT(onChange()));
connect(
m_pComboLogLevel, SIGNAL(currentIndexChanged(int)), this,
SLOT(onChange()));
connect(
m_pLineEditCertificatePath, SIGNAL(textChanged(QString)), this,
SLOT(onChange()));
connect(m_pCheckBoxMinimizeToTray, SIGNAL(clicked()), this, SLOT(onChange()));
connect(m_pCheckBoxAutoHide, SIGNAL(clicked()), this, SLOT(onChange()));
connect(m_pCheckBoxPreventSleep, SIGNAL(clicked()), this, SLOT(onChange()));
connect(
m_pLineEditInterface, SIGNAL(textEdited(QString)), this,
SLOT(onChange()));
connect(m_pSpinBoxPort, SIGNAL(valueChanged(int)), this, SLOT(onChange()));
connect(
m_pLineEditScreenName, SIGNAL(textEdited(QString)), this,
SLOT(onChange()));
connect(
m_pComboElevate, SIGNAL(currentIndexChanged(int)), this,
SLOT(onChange()));
connect(m_pCheckBoxLanguageSync, SIGNAL(clicked()), this, SLOT(onChange()));
connect(
m_pCheckBoxScrollDirection, SIGNAL(clicked()), this, SLOT(onChange()));
connect(m_pCheckBoxClientHostMode, SIGNAL(clicked()), this, SLOT(onChange()));
connect(
m_pCheckBoxServerClientMode, SIGNAL(clicked()), this, SLOT(onChange()));
adjustSize();
}
void SettingsDialog::accept() {
appConfig().setLoadFromSystemScope(m_pRadioSystemScope->isChecked());
appConfig().setScreenName(m_pLineEditScreenName->text());
appConfig().setPort(m_pSpinBoxPort->value());
appConfig().setNetworkInterface(m_pLineEditInterface->text());
appConfig().setLogLevel(m_pComboLogLevel->currentIndex());
appConfig().setLogToFile(m_pCheckBoxLogToFile->isChecked());
appConfig().setLogFilename(m_pLineEditLogFilename->text());
appConfig().setElevateMode(
static_cast<ElevateMode>(m_pComboElevate->currentIndex()));
appConfig().setAutoHide(m_pCheckBoxAutoHide->isChecked());
appConfig().setPreventSleep(m_pCheckBoxPreventSleep->isChecked());
appConfig().setMinimizeToTray(m_pCheckBoxMinimizeToTray->isChecked());
appConfig().setTLSCertPath(m_pLineEditCertificatePath->text());
appConfig().setTLSKeyLength(m_pComboBoxKeyLength->currentText());
appConfig().setCryptoEnabled(m_pCheckBoxEnableCrypto->isChecked());
appConfig().setLanguageSync(m_pCheckBoxLanguageSync->isChecked());
appConfig().setInvertScrollDirection(m_pCheckBoxScrollDirection->isChecked());
appConfig().setClientHostMode(m_pCheckBoxClientHostMode->isChecked());
appConfig().setServerClientMode(m_pCheckBoxServerClientMode->isChecked());
appConfig().saveSettings();
QDialog::accept();
}
void SettingsDialog::reject() {
// We should restore scope at start if the user rejects changes.
if (appConfig().isSystemScoped() != m_isSystemAtStart) {
appConfig().setLoadFromSystemScope(m_isSystemAtStart);
}
QDialog::reject();
}
void SettingsDialog::loadFromConfig() {
m_pLineEditScreenName->setText(appConfig().screenName());
m_pSpinBoxPort->setValue(appConfig().port());
m_pLineEditInterface->setText(appConfig().networkInterface());
m_pComboLogLevel->setCurrentIndex(appConfig().logLevel());
m_pCheckBoxLogToFile->setChecked(appConfig().logToFile());
m_pLineEditLogFilename->setText(appConfig().logFilename());
m_pCheckBoxAutoHide->setChecked(appConfig().getAutoHide());
m_pCheckBoxPreventSleep->setChecked(appConfig().getPreventSleep());
m_pCheckBoxMinimizeToTray->setChecked(appConfig().getMinimizeToTray());
m_pLineEditCertificatePath->setText(appConfig().getTLSCertPath());
m_pCheckBoxEnableCrypto->setChecked(m_appConfig.getCryptoEnabled());
m_pCheckBoxLanguageSync->setChecked(m_appConfig.getLanguageSync());
m_pCheckBoxScrollDirection->setChecked(
m_appConfig.getInvertScrollDirection());
m_pCheckBoxClientHostMode->setChecked(m_appConfig.getClientHostMode());
m_pCheckBoxServerClientMode->setChecked(m_appConfig.getServerClientMode());
setupSeurity();
if (m_appConfig.isSystemScoped()) {
m_pRadioSystemScope->setChecked(true);
} else {
m_pRadioUserScope->setChecked(true);
}
2014-10-27 17:15:50 +00:00
#if defined(Q_OS_WIN)
m_pComboElevate->setCurrentIndex(static_cast<int>(appConfig().elevateMode()));
2014-10-27 17:15:50 +00:00
#else
// elevate checkbox is only useful on ms windows.
m_pLabelElevate->hide();
m_pComboElevate->hide();
#endif
m_pCheckBoxClientHostMode->setVisible(
isClientMode() && appConfig().getInitiateConnectionFromServer());
m_pCheckBoxServerClientMode->setVisible(
!isClientMode() && appConfig().getInitiateConnectionFromServer());
2012-06-10 16:50:54 +00:00
}
void SettingsDialog::setupSeurity() {
// If the tls file exists test its key length
if (QFile(appConfig().getTLSCertPath()).exists()) {
updateKeyLengthOnFile(appConfig().getTLSCertPath());
} else {
m_pComboBoxKeyLength->setCurrentIndex(
m_pComboBoxKeyLength->findText(appConfig().getTLSKeyLength()));
}
m_pCheckBoxEnableCrypto->setChecked(m_appConfig.getCryptoEnabled());
if (appConfig().getClientGroupChecked()) {
m_pLabelKeyLength->hide();
m_pComboBoxKeyLength->hide();
m_pLabelCertificate->hide();
m_pLineEditCertificatePath->hide();
m_pPushButtonBrowseCert->hide();
m_pPushButtonRegenCert->hide();
}
}
bool SettingsDialog::isClientMode() const {
return (m_pMainWindow->synergyType() == MainWindow::synergyClient);
}
void SettingsDialog::on_m_pCheckBoxLogToFile_stateChanged(int i) {
bool checked = i == 2;
2012-06-10 16:50:54 +00:00
m_pLabelLogPath->setEnabled(checked);
m_pLineEditLogFilename->setEnabled(checked);
m_pButtonBrowseLog->setEnabled(checked);
buttonBox->button(QDialogButtonBox::Save)->setEnabled(isModified());
2012-06-10 16:50:54 +00:00
}
void SettingsDialog::on_m_pButtonBrowseLog_clicked() {
QString fileName = QFileDialog::getSaveFileName(
this, tr("Save log file to..."), m_pLineEditLogFilename->text(),
"Logs (*.log *.txt)");
if (!fileName.isEmpty()) {
m_pLineEditLogFilename->setText(fileName);
}
2012-06-10 16:50:54 +00:00
}
2013-04-11 16:51:17 +00:00
void SettingsDialog::on_m_pCheckBoxEnableCrypto_clicked(bool checked) {
if (appConfig().isCryptoAvailable()) {
m_pLabelKeyLength->setEnabled(checked);
m_pComboBoxKeyLength->setEnabled(checked);
m_pLabelCertificate->setEnabled(checked);
m_pLineEditCertificatePath->setEnabled(checked);
m_pPushButtonBrowseCert->setEnabled(checked);
m_pPushButtonRegenCert->setEnabled(checked);
buttonBox->button(QDialogButtonBox::Save)->setEnabled(isModified());
} else {
m_pCheckBoxEnableCrypto->setChecked(false);
Simplify compile options and use comprehensive edition logic (#7365) * Simplify options * Use more sensible edition logic * Use set instead of option for string * Improve macro for product name * Add tests launch config * Restore unregistered state * Reorganize cases for title and improve function name * Code coverage on by default * Fixed copyright * Improve code coverage and test readability * Separate build-all and build-coverage * Back out coverage on by default * Fixed bad var in cmake * More verbose logging for coverage * Restore tasks * Restore preLaunchTask * Use default comparitor * Move temp files to temp dir * Add tasks for tests * Support for wstring * Upgrade sonar-scanner to 6 on Debian 12 * Use modern pip install * Install python for sonarcloud * Use Ubuntu and install deps * Fixed sonar-scanner URL * Fix exported dir * Persist build dir * Don't use venv for pip install gcovr * Fixed another path * Update actions/checkout to v4 for SonarCloud analysis workflow * Add coverage task * Improve coverage for SerialKeyEdition.cpp * Enable licensing for builds * Fixed invalid macro names, missing arguments, etc * Fixed more copyright * Fixed incorrect use of "enterprise" * Fixed incorrect use of "business" * Experiment with environment * Make package prefix variable * Add environment matrix to all OS * Improve job names * Make job names easier to read * Roll back environment matrix (too much noise) * Fixed: default should override required * Refactor CI with vars * Fixed arg for env.get_env
2024-07-04 09:14:54 +00:00
#ifdef SYNERGY_ENABLE_LICENSING
auto edition = appConfig().edition();
if (edition == Edition::kLite || edition == Edition::kBasic) {
UpgradeDialog upgradeDialog(this);
if (appConfig().edition() == Edition::kLite) {
upgradeDialog.showDialog(
"Upgrade to Synergy Ultimate to enable TLS encryption.");
} else if (appConfig().edition() == Edition::kBasic) {
upgradeDialog.showDialog(
"Upgrade to Synergy Pro to enable TLS encryption.");
}
2021-05-12 13:48:33 +00:00
}
Simplify compile options and use comprehensive edition logic (#7365) * Simplify options * Use more sensible edition logic * Use set instead of option for string * Improve macro for product name * Add tests launch config * Restore unregistered state * Reorganize cases for title and improve function name * Code coverage on by default * Fixed copyright * Improve code coverage and test readability * Separate build-all and build-coverage * Back out coverage on by default * Fixed bad var in cmake * More verbose logging for coverage * Restore tasks * Restore preLaunchTask * Use default comparitor * Move temp files to temp dir * Add tasks for tests * Support for wstring * Upgrade sonar-scanner to 6 on Debian 12 * Use modern pip install * Install python for sonarcloud * Use Ubuntu and install deps * Fixed sonar-scanner URL * Fix exported dir * Persist build dir * Don't use venv for pip install gcovr * Fixed another path * Update actions/checkout to v4 for SonarCloud analysis workflow * Add coverage task * Improve coverage for SerialKeyEdition.cpp * Enable licensing for builds * Fixed invalid macro names, missing arguments, etc * Fixed more copyright * Fixed incorrect use of "enterprise" * Fixed incorrect use of "business" * Experiment with environment * Make package prefix variable * Add environment matrix to all OS * Improve job names * Make job names easier to read * Roll back environment matrix (too much noise) * Fixed: default should override required * Refactor CI with vars * Fixed arg for env.get_env
2024-07-04 09:14:54 +00:00
#endif // SYNERGY_ENABLE_LICENSING
}
}
void SettingsDialog::on_m_pRadioSystemScope_toggled(bool checked) {
// We only need to test the System scoped Radio as they are connected
appConfig().setLoadFromSystemScope(checked);
loadFromConfig();
buttonBox->button(QDialogButtonBox::Save)
->setEnabled(m_isSystemAtStart != checked);
enableControls(appConfig().isWritable());
}
void SettingsDialog::on_m_pPushButtonBrowseCert_clicked() {
QString fileName = QFileDialog::getSaveFileName(
this, tr("Select a TLS certificate to use..."),
m_pLineEditCertificatePath->text(), "Cert (*.pem)", nullptr,
QFileDialog::DontConfirmOverwrite);
if (!fileName.isEmpty()) {
m_pLineEditCertificatePath->setText(fileName);
// If the tls file exists test its key length and update
if (QFile(appConfig().getTLSCertPath()).exists()) {
updateKeyLengthOnFile(fileName);
}
}
updateRegenButton();
}
void SettingsDialog::on_m_pComboBoxKeyLength_currentIndexChanged(int index) {
buttonBox->button(QDialogButtonBox::Save)->setEnabled(isModified());
updateRegenButton();
}
void SettingsDialog::updateRegenButton() {
// Disable the Regenerate cert button if the key length is different to saved
auto keyChanged =
appConfig().getTLSKeyLength() != m_pComboBoxKeyLength->currentText();
auto pathChanged =
appConfig().getTLSCertPath() != m_pLineEditCertificatePath->text();
// NOR the above bools, if any have changed regen should be disabled as it
// will be done on save
auto nor = !(keyChanged || pathChanged);
m_pPushButtonRegenCert->setEnabled(
nor && m_pCheckBoxEnableCrypto->isChecked());
}
void SettingsDialog::on_m_pPushButtonRegenCert_clicked() {
appConfig().generateCertificate(true);
}
void SettingsDialog::updateKeyLengthOnFile(const QString &path) {
SslCertificate ssl;
auto length = ssl.getCertKeyLength(path);
auto index = m_pComboBoxKeyLength->findText(length);
m_pComboBoxKeyLength->setCurrentIndex(index);
// Also update what is in the appconfig to match the file itself
appConfig().setTLSKeyLength(length);
}
bool SettingsDialog::isModified() {
return (
!m_pLineEditScreenName->text().isEmpty() &&
m_pLabelNameError->text().isEmpty() &&
(appConfig().screenName() != m_pLineEditScreenName->text() ||
appConfig().port() != m_pSpinBoxPort->value() ||
appConfig().networkInterface() != m_pLineEditInterface->text() ||
appConfig().logLevel() != m_pComboLogLevel->currentIndex() ||
appConfig().logToFile() != m_pCheckBoxLogToFile->isChecked() ||
appConfig().logFilename() != m_pLineEditLogFilename->text() ||
appConfig().elevateMode() !=
static_cast<ElevateMode>(m_pComboElevate->currentIndex()) ||
appConfig().getAutoHide() != m_pCheckBoxAutoHide->isChecked() ||
appConfig().getPreventSleep() != m_pCheckBoxPreventSleep->isChecked() ||
appConfig().getMinimizeToTray() !=
m_pCheckBoxMinimizeToTray->isChecked() ||
appConfig().getTLSCertPath() != m_pLineEditCertificatePath->text() ||
appConfig().getTLSKeyLength() != m_pComboBoxKeyLength->currentText() ||
appConfig().getCryptoEnabled() != m_pCheckBoxEnableCrypto->isChecked() ||
appConfig().isSystemScoped() != m_isSystemAtStart ||
appConfig().getLanguageSync() != m_pCheckBoxLanguageSync->isChecked() ||
appConfig().getClientHostMode() !=
m_pCheckBoxClientHostMode->isChecked() ||
appConfig().getServerClientMode() !=
m_pCheckBoxServerClientMode->isChecked() ||
appConfig().getInvertScrollDirection() !=
m_pCheckBoxScrollDirection->isChecked()));
}
void SettingsDialog::enableControls(bool enable) {
m_pLineEditScreenName->setEnabled(enable);
m_pSpinBoxPort->setEnabled(enable);
m_pLineEditInterface->setEnabled(enable);
m_pComboLogLevel->setEnabled(enable);
m_pCheckBoxLogToFile->setEnabled(enable);
m_pComboElevate->setEnabled(enable);
m_pCheckBoxAutoHide->setEnabled(enable);
m_pCheckBoxPreventSleep->setEnabled(enable);
m_pCheckBoxMinimizeToTray->setEnabled(enable);
m_pLineEditCertificatePath->setEnabled(enable);
m_pComboBoxKeyLength->setEnabled(enable);
m_pPushButtonBrowseCert->setEnabled(enable);
m_pCheckBoxEnableCrypto->setEnabled(enable);
m_labelAdminRightsMessage->setVisible(!enable);
m_pCheckBoxLanguageSync->setEnabled(enable);
m_pCheckBoxScrollDirection->setEnabled(enable);
m_pCheckBoxClientHostMode->setEnabled(enable);
m_pCheckBoxServerClientMode->setEnabled(enable);
if (enable) {
m_pLabelLogPath->setEnabled(m_pCheckBoxLogToFile->isChecked());
m_pLineEditLogFilename->setEnabled(m_pCheckBoxLogToFile->isChecked());
m_pButtonBrowseLog->setEnabled(m_pCheckBoxLogToFile->isChecked());
m_pLabelKeyLength->setEnabled(m_pCheckBoxEnableCrypto->isChecked());
m_pComboBoxKeyLength->setEnabled(m_pCheckBoxEnableCrypto->isChecked());
m_pLabelCertificate->setEnabled(m_pCheckBoxEnableCrypto->isChecked());
m_pLineEditCertificatePath->setEnabled(
m_pCheckBoxEnableCrypto->isChecked());
m_pPushButtonBrowseCert->setEnabled(m_pCheckBoxEnableCrypto->isChecked());
updateRegenButton();
} else {
m_pLabelLogPath->setEnabled(enable);
m_pLineEditLogFilename->setEnabled(enable);
m_pButtonBrowseLog->setEnabled(enable);
m_pLabelKeyLength->setEnabled(enable);
m_pComboBoxKeyLength->setEnabled(enable);
m_pLabelCertificate->setEnabled(enable);
m_pLineEditCertificatePath->setEnabled(enable);
m_pPushButtonBrowseCert->setEnabled(enable);
m_pPushButtonRegenCert->setEnabled(enable);
}
}
void SettingsDialog::onChange() {
buttonBox->button(QDialogButtonBox::Save)->setEnabled(isModified());
}