diff --git a/src/gui/src/AppConfig.cpp b/src/gui/src/AppConfig.cpp index b4abd062d..547d08669 100644 --- a/src/gui/src/AppConfig.cpp +++ b/src/gui/src/AppConfig.cpp @@ -54,7 +54,6 @@ AppConfig::AppConfig(QSettings* settings) : m_ProcessMode(DEFAULT_PROCESS_MODE), m_AutoConfig(true), m_ElevateMode(defaultElevateMode), - m_AutoConfigPrompted(false), m_CryptoEnabled(false), m_AutoHide(false), m_LastExpiringWarningTime(0) @@ -147,7 +146,6 @@ void AppConfig::loadSettings() QVariant(static_cast(defaultElevateMode))); } m_ElevateMode = static_cast(elevateMode.toInt()); - m_AutoConfigPrompted = settings().value("autoConfigPrompted", false).toBool(); m_Edition = static_cast(settings().value("edition", kUnregistered).toInt()); m_ActivateEmail = settings().value("activateEmail", "").toString(); m_CryptoEnabled = settings().value("cryptoEnabled", true).toBool(); @@ -174,7 +172,6 @@ void AppConfig::saveSettings() // flag is mapped this way settings().setValue("elevateMode", m_ElevateMode == ElevateAlways); settings().setValue("elevateModeEnum", static_cast(m_ElevateMode)); - settings().setValue("autoConfigPrompted", m_AutoConfigPrompted); settings().setValue("edition", m_Edition); settings().setValue("cryptoEnabled", m_CryptoEnabled); settings().setValue("autoHide", m_AutoHide); @@ -234,13 +231,6 @@ void AppConfig::setAutoConfig(bool autoConfig) m_AutoConfig = autoConfig; } -bool AppConfig::autoConfigPrompted() { return m_AutoConfigPrompted; } - -void AppConfig::setAutoConfigPrompted(bool prompted) -{ - m_AutoConfigPrompted = prompted; -} - #ifndef SYNERGY_ENTERPRISE void AppConfig::setEdition(Edition e) { m_Edition = e; diff --git a/src/gui/src/AppConfig.h b/src/gui/src/AppConfig.h index 39330d778..756492a64 100644 --- a/src/gui/src/AppConfig.h +++ b/src/gui/src/AppConfig.h @@ -77,8 +77,6 @@ class AppConfig: public QObject bool startedBefore() const; bool autoConfig() const; void setAutoConfig(bool autoConfig); - bool autoConfigPrompted(); - void setAutoConfigPrompted(bool prompted); #ifndef SYNERGY_ENTERPRISE void setEdition(Edition); Edition edition() const; @@ -141,7 +139,6 @@ protected: bool m_StartedBefore; bool m_AutoConfig; ElevateMode m_ElevateMode; - bool m_AutoConfigPrompted; Edition m_Edition; QString m_ActivateEmail; bool m_CryptoEnabled; diff --git a/src/gui/src/BonjourWindows.cpp b/src/gui/src/BonjourWindows.cpp new file mode 100644 index 000000000..09b82281e --- /dev/null +++ b/src/gui/src/BonjourWindows.cpp @@ -0,0 +1,191 @@ +/* + * synergy -- mouse and keyboard sharing utility + * Copyright (C) 2012-2018 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 . + */ + +#include "BonjourWindows.h" + +#if defined(Q_OS_WIN) + +#include "MainWindow.h" +#include "SettingsDialog.h" +#include "DataDownloader.h" +#include "QUtility.h" +#include "CommandProcess.h" + +#include +#include +#include +#include +#include + +#define WIN32_LEAN_AND_MEAN +#include + +BonjourWindows::BonjourWindows(SettingsDialog* settingsDialog, MainWindow* mainWindow) : + m_pSettingsDialog(settingsDialog), + m_pMainWindow(mainWindow), + m_pBonjourInstall(nullptr), + m_pDownloadMessageBox(nullptr), + m_pDataDownloader(nullptr) +{ +} + +BonjourWindows::~BonjourWindows() +{ + if (m_pBonjourInstall != nullptr) { + delete m_pBonjourInstall; + } + + if (m_pDownloadMessageBox != nullptr) { + delete m_pDownloadMessageBox; + } + + if (m_pDataDownloader != nullptr) { + delete m_pDataDownloader; + } +} + +void BonjourWindows::download() +{ + QUrl url; + int arch = getProcessorArch(); + if (arch == kProcessorArchWin32) { + url.setUrl(bonjourBaseUrl + bonjourFilename32); + m_pMainWindow->appendLogInfo("downloading 32-bit bonjour"); + } + else if (arch == kProcessorArchWin64) { + url.setUrl(bonjourBaseUrl + bonjourFilename64); + m_pMainWindow->appendLogInfo("downloading 64-bit bonjour"); + } + else { + QMessageBox::critical( + m_pSettingsDialog, tr("Synergy Auto Config"), + tr("Failed to detect system architecture.")); + return; + } + + if (m_pDataDownloader == nullptr) { + m_pDataDownloader = new DataDownloader(this); + connect(m_pDataDownloader, SIGNAL(isComplete()), SLOT(installBonjour())); + } + + m_pDataDownloader->download(url); + + if (m_pDownloadMessageBox != nullptr) { + delete m_pDownloadMessageBox; + m_pDownloadMessageBox = nullptr; + } + + m_pDownloadMessageBox = new QMessageBox(m_pSettingsDialog); + m_pDownloadMessageBox->setWindowTitle("Synergy"); + m_pDownloadMessageBox->setIcon(QMessageBox::Information); + m_pDownloadMessageBox->setText("Installing Bonjour, please wait..."); + QAbstractButton* cancel = m_pDownloadMessageBox->addButton( + tr("Cancel"), QMessageBox::RejectRole); + + m_pDownloadMessageBox->exec(); + + if (cancel == m_pDownloadMessageBox->clickedButton()) { + m_pDataDownloader->cancel(); + } +} + +void BonjourWindows::install() +{ + QString tempLocation = QStandardPaths::writableLocation(QStandardPaths::TempLocation); + + QString filename = tempLocation; + filename.append("\\").append(bonjourTargetFilename); + QFile file(filename); + if (!file.open(QIODevice::WriteOnly)) { + m_pDownloadMessageBox->hide(); + + QMessageBox::warning( + m_pSettingsDialog, "Synergy", + tr("Failed to download Bonjour installer to location: %1") + .arg(tempLocation)); + return; + } + + file.write(m_pDataDownloader->data()); + file.close(); + + QStringList arguments; + arguments.append("/i"); + QString winFilename = QDir::toNativeSeparators(filename); + arguments.append(winFilename); + arguments.append("/passive"); + + if (m_pBonjourInstall != nullptr) { + delete m_pBonjourInstall; + m_pBonjourInstall = nullptr; + } + + m_pBonjourInstall = new CommandProcess("msiexec", arguments); + + QThread* thread = new QThread; + connect(m_pBonjourInstall, SIGNAL(finished()), this, + SLOT(bonjourInstallFinished())); + connect(m_pBonjourInstall, SIGNAL(finished()), thread, SLOT(quit())); + connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater())); + + m_pBonjourInstall->moveToThread(thread); + thread->start(); + + QMetaObject::invokeMethod(m_pBonjourInstall, "run", Qt::QueuedConnection); + + m_pDownloadMessageBox->hide(); +} + +bool BonjourWindows::isRunning() const +{ + QString name = "Bonjour Service"; + + SC_HANDLE hSCManager; + hSCManager = OpenSCManager(nullptr, nullptr, SC_MANAGER_CONNECT); + + if (hSCManager == nullptr) { + m_pMainWindow->appendLogError( + QString("failed to open a service controller manager, error: %1").arg(GetLastError())); + return false; + } + + auto array = name.toLocal8Bit(); + SC_HANDLE hService = OpenService(hSCManager, array.data(), SERVICE_QUERY_STATUS); + + if (hService == nullptr) { + m_pMainWindow->appendLogDebug( + QString("failed to open service: %1").arg(name)); + return false; + } + + SERVICE_STATUS status; + if (QueryServiceStatus(hService, &status)) { + if (status.dwCurrentState == SERVICE_RUNNING) { + return true; + } + } + + return false; +} + +void BonjourWindows::installFinished() +{ + m_pMainWindow->appendLogInfo("bonjour install finished"); + m_pSettingsDialog->allowAutoConfig(); +} + +#endif // Q_OS_WIN diff --git a/src/gui/src/BonjourWindows.h b/src/gui/src/BonjourWindows.h new file mode 100644 index 000000000..031d0f499 --- /dev/null +++ b/src/gui/src/BonjourWindows.h @@ -0,0 +1,60 @@ +/* + * synergy -- mouse and keyboard sharing utility + * Copyright (C) 2012-2018 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 . + */ + +#pragma once + +#include + +#if defined(Q_OS_WIN) + +#include + +static QString bonjourBaseUrl = "http://binaries.symless.com/bonjour/"; +static const char bonjourFilename32[] = "Bonjour.msi"; +static const char bonjourFilename64[] = "Bonjour64.msi"; +static const char bonjourTargetFilename[] = "Bonjour.msi"; + +class SettingsDialog; +class MainWindow; +class CommandProcess; +class DataDownloader; + +class BonjourWindows : public QObject +{ + Q_OBJECT + +public: + BonjourWindows(SettingsDialog* settingsDialog, MainWindow* mainWindow); + virtual ~BonjourWindows(); + +public: + void download(); + void install(); + bool isRunning() const; + +protected slots: + void installFinished(); + +private: + SettingsDialog* m_pSettingsDialog; + MainWindow* m_pMainWindow; + CommandProcess* m_pBonjourInstall; + QMessageBox* m_pDownloadMessageBox; + DataDownloader* m_pDataDownloader; +}; + +#endif // Q_OS_WIN diff --git a/src/gui/src/MainWindow.cpp b/src/gui/src/MainWindow.cpp index 342fdee8c..6b2e90514 100644 --- a/src/gui/src/MainWindow.cpp +++ b/src/gui/src/MainWindow.cpp @@ -27,7 +27,6 @@ #include "ServerConfigDialog.h" #include "SettingsDialog.h" #include "ActivationDialog.h" -#include "ZeroconfService.h" #include "DataDownloader.h" #include "CommandProcess.h" #include "LicenseManager.h" @@ -35,6 +34,7 @@ #include "QUtility.h" #include "ProcessorArch.h" #include "SslCertificate.h" +#include "Zeroconf.h" #include #include @@ -51,18 +51,9 @@ #include #endif -#if defined(Q_OS_WIN) -#define WIN32_LEAN_AND_MEAN -#include -#endif - #if defined(Q_OS_WIN) static const char synergyConfigName[] = "synergy.sgc"; static const QString synergyConfigFilter(QObject::tr("Synergy Configurations (*.sgc);;All files (*.*)")); -static QString bonjourBaseUrl = "http://binaries.symless.com/bonjour/"; -static const char bonjourFilename32[] = "Bonjour.msi"; -static const char bonjourFilename64[] = "Bonjour64.msi"; -static const char bonjourTargetFilename[] = "Bonjour.msi"; #else static const char synergyConfigName[] = "synergy.conf"; static const QString synergyConfigFilter(QObject::tr("Synergy Configurations (*.conf);;All files (*.*)")); @@ -85,11 +76,14 @@ MainWindow::MainWindow (QSettings& settings, AppConfig& appConfig) MainWindow::MainWindow (QSettings& settings, AppConfig& appConfig, LicenseManager& licenseManager) #endif -: m_Settings(settings), - m_AppConfig(&appConfig), +: #ifndef SYNERGY_ENTERPRISE m_LicenseManager(&licenseManager), + m_pZeroconf(nullptr), + m_ActivationDialogRunning(false), #endif + m_Settings(settings), + m_AppConfig(&appConfig), m_pSynergy(NULL), m_SynergyState(synergyDisconnected), m_ServerConfig(&m_Settings, 5, 3, m_AppConfig->screenName(), this), @@ -102,21 +96,12 @@ MainWindow::MainWindow (QSettings& settings, AppConfig& appConfig, m_pMenuEdit(NULL), m_pMenuWindow(NULL), m_pMenuHelp(NULL), -#ifndef SYNERGY_ENTERPRISE - m_pZeroconfService(NULL), -#endif - m_pDataDownloader(NULL), - m_DownloadMessageBox(NULL), m_pCancelButton(NULL), m_SuppressAutoConfigWarning(false), - m_BonjourInstall(NULL), m_SuppressEmptyServerWarning(false), m_ExpectedRunningState(kStopped), - m_pSslCertificate(NULL) -#ifndef SYNERGY_ENTERPRISE - , m_ActivationDialogRunning(false) -#endif - , m_SecureSocket(false) + m_pSslCertificate(NULL), + m_SecureSocket(false) { setupUi(this); @@ -147,10 +132,10 @@ MainWindow::MainWindow (QSettings& settings, AppConfig& appConfig, #endif m_SuppressAutoConfigWarning = true; - m_pCheckBoxAutoConfig->setChecked(appConfig.autoConfig()); + m_pLabelAutoDetected->setVisible(appConfig.autoConfig()); + m_pComboServerList->setVisible(appConfig.autoConfig()); m_SuppressAutoConfigWarning = false; - m_pComboServerList->hide(); m_trialWidget->hide(); // hide padlock icon @@ -191,7 +176,14 @@ MainWindow::MainWindow (QSettings& settings, AppConfig& appConfig, #ifdef SYNERGY_ENTERPRISE m_pActivate->setVisible(false); - m_pCheckBoxAutoConfig->setVisible(false); +#endif + + m_pZeroconf = new Zeroconf(this); + +#ifndef SYNERGY_ENTERPRISE + if (m_AppConfig->autoConfig()) { + m_pZeroconf->startService(); + } #endif } @@ -202,19 +194,13 @@ MainWindow::~MainWindow() stopDesktop(); } - saveSettings(); - #ifndef SYNERGY_ENTERPRISE - delete m_pZeroconfService; + if (m_AppConfig->autoConfig()) { + m_pZeroconf->stopService(); + } #endif - if (m_DownloadMessageBox != NULL) { - delete m_DownloadMessageBox; - } - - if (m_BonjourInstall != NULL) { - delete m_BonjourInstall; - } + saveSettings(); delete m_pSslCertificate; } @@ -229,12 +215,6 @@ void MainWindow::open() m_VersionChecker.checkLatest(); -#ifndef SYNERGY_ENTERPRISE - if (!appConfig().autoConfigPrompted()) { - promptAutoConfig(); - } -#endif - // only start if user has previously started. this stops the gui from // auto hiding before the user has configured synergy (which of course // confuses first time users, who think synergy has crashed). @@ -773,7 +753,7 @@ bool MainWindow::clientArgs(QStringList& args, QString& app) #ifndef SYNERGY_ENTERPRISE // check auto config first, if it is disabled or no server detected, // use line edit host name if it is not empty - if (m_pCheckBoxAutoConfig->isChecked()) { + if (appConfig().autoConfig()) { if (m_pComboServerList->count() != 0) { QString serverIp = m_pComboServerList->currentText(); args << serverIp + ":" + QString::number(appConfig().port()); @@ -1101,27 +1081,7 @@ void MainWindow::changeEvent(QEvent* event) } } -#ifndef SYNERGY_ENTERPRISE -void MainWindow::updateZeroconfService() -{ - QMutexLocker locker(&m_UpdateZeroconfMutex); - - if (isBonjourRunning()) { - if (!m_AppConfig->wizardShouldRun()) { - if (m_pZeroconfService) { - delete m_pZeroconfService; - m_pZeroconfService = NULL; - } - - if (m_AppConfig->autoConfig() || synergyType() == synergyServer) { - m_pZeroconfService = new ZeroconfService(this); - } - } - } -} -#endif - -void MainWindow::serverDetected(const QString name) +void MainWindow::zeroconfServerDetected(const QString name) { if (m_pComboServerList->findText(name) == -1) { // Note: the first added item triggers startSynergy @@ -1223,21 +1183,11 @@ MainWindow::licenseManager() const void MainWindow::on_m_pGroupClient_toggled(bool on) { m_pGroupServer->setChecked(!on); -#ifndef SYNERGY_ENTERPRISE - if (on) { - updateZeroconfService(); - } -#endif } void MainWindow::on_m_pGroupServer_toggled(bool on) { m_pGroupClient->setChecked(!on); -#ifndef SYNERGY_ENTERPRISE - if (on) { - updateZeroconfService(); - } -#endif } bool MainWindow::on_m_pButtonBrowseConfigFile_clicked() @@ -1345,211 +1295,13 @@ void MainWindow::on_m_pButtonApply_clicked() restartSynergy(); } -#if defined(Q_OS_WIN) -bool MainWindow::isServiceRunning(QString name) -{ - SC_HANDLE hSCManager; - hSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_CONNECT); - if (hSCManager == NULL) { - appendLogError("failed to open a service controller manager, error: " + - GetLastError()); - return false; - } - - auto array = name.toLocal8Bit(); - SC_HANDLE hService = OpenService(hSCManager, array.data(), SERVICE_QUERY_STATUS); - - if (hService == NULL) { - appendLogDebug("failed to open service: " + name); - return false; - } - - SERVICE_STATUS status; - if (QueryServiceStatus(hService, &status)) { - if (status.dwCurrentState == SERVICE_RUNNING) { - return true; - } - } -#else -bool MainWindow::isServiceRunning() -{ -#endif - return false; -} - -#ifndef SYNERGY_ENTERPRISE -bool MainWindow::isBonjourRunning() -{ - bool result = false; - -#if defined(Q_OS_WIN) - result = isServiceRunning("Bonjour Service"); -#else - result = true; -#endif - - return result; -} - -void MainWindow::downloadBonjour() -{ -#if defined(Q_OS_WIN) - QUrl url; - int arch = getProcessorArch(); - if (arch == kProcessorArchWin32) { - url.setUrl(bonjourBaseUrl + bonjourFilename32); - appendLogInfo("downloading 32-bit Bonjour"); - } - else if (arch == kProcessorArchWin64) { - url.setUrl(bonjourBaseUrl + bonjourFilename64); - appendLogInfo("downloading 64-bit Bonjour"); - } - else { - QMessageBox::critical( - this, tr("Synergy"), - tr("Failed to detect system architecture.")); - return; - } - - if (m_pDataDownloader == NULL) { - m_pDataDownloader = new DataDownloader(this); - connect(m_pDataDownloader, SIGNAL(isComplete()), SLOT(installBonjour())); - } - - m_pDataDownloader->download(url); - - if (m_DownloadMessageBox == NULL) { - m_DownloadMessageBox = new QMessageBox(this); - m_DownloadMessageBox->setWindowTitle("Synergy"); - m_DownloadMessageBox->setIcon(QMessageBox::Information); - m_DownloadMessageBox->setText("Installing Bonjour, please wait..."); - m_DownloadMessageBox->setStandardButtons(0); - m_pCancelButton = m_DownloadMessageBox->addButton( - tr("Cancel"), QMessageBox::RejectRole); - } - - m_DownloadMessageBox->exec(); - - if (m_DownloadMessageBox->clickedButton() == m_pCancelButton) { - m_pDataDownloader->cancel(); - } -#endif -} - -void MainWindow::installBonjour() -{ -#if defined(Q_OS_WIN) -#if QT_VERSION >= 0x050000 - QString tempLocation = QStandardPaths::writableLocation(QStandardPaths::TempLocation); -#else - QString tempLocation = QDesktopServices::storageLocation( - QDesktopServices::TempLocation); -#endif - QString filename = tempLocation; - filename.append("\\").append(bonjourTargetFilename); - QFile file(filename); - if (!file.open(QIODevice::WriteOnly)) { - m_DownloadMessageBox->hide(); - - QMessageBox::warning( - this, "Synergy", - tr("Failed to download Bonjour installer to location: %1") - .arg(tempLocation)); - return; - } - - file.write(m_pDataDownloader->data()); - file.close(); - - QStringList arguments; - arguments.append("/i"); - QString winFilename = QDir::toNativeSeparators(filename); - arguments.append(winFilename); - arguments.append("/passive"); - if (m_BonjourInstall == NULL) { - m_BonjourInstall = new CommandProcess("msiexec", arguments); - } - - QThread* thread = new QThread; - connect(m_BonjourInstall, SIGNAL(finished()), this, - SLOT(bonjourInstallFinished())); - connect(m_BonjourInstall, SIGNAL(finished()), thread, SLOT(quit())); - connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater())); - - m_BonjourInstall->moveToThread(thread); - thread->start(); - - QMetaObject::invokeMethod(m_BonjourInstall, "run", Qt::QueuedConnection); - - m_DownloadMessageBox->hide(); -#endif -} - -void MainWindow::promptAutoConfig() -{ - if (!isBonjourRunning()) { - int r = QMessageBox::question( - this, tr("Synergy"), - tr("Do you want to enable auto config and install Bonjour?\n\n" - "This feature helps you establish the connection."), - QMessageBox::Yes | QMessageBox::No); - - if (r == QMessageBox::Yes) { - m_AppConfig->setAutoConfig(true); - downloadBonjour(); - } - else { - m_AppConfig->setAutoConfig(false); - m_pCheckBoxAutoConfig->setChecked(false); - } - } - - m_AppConfig->setAutoConfigPrompted(true); -} - -void MainWindow::on_m_pComboServerList_currentIndexChanged(QString ) +void MainWindow::on_m_pComboServerList_currentIndexChanged(const QString &arg1) { if (m_pComboServerList->count() != 0) { restartSynergy(); } } -void MainWindow::on_m_pCheckBoxAutoConfig_toggled(bool checked) -{ - if (!isBonjourRunning() && checked) { - if (!m_SuppressAutoConfigWarning) { - int r = QMessageBox::information( - this, tr("Synergy"), - tr("Auto config feature requires Bonjour.\n\n" - "Do you want to install Bonjour?"), - QMessageBox::Yes | QMessageBox::No); - - if (r == QMessageBox::Yes) { - downloadBonjour(); - } - } - - m_pCheckBoxAutoConfig->setChecked(false); - return; - } - - m_pLineEditHostname->setDisabled(checked); - appConfig().setAutoConfig(checked); - updateZeroconfService(); - - if (!checked) { - m_pComboServerList->clear(); - m_pComboServerList->hide(); - } -} - -void MainWindow::bonjourInstallFinished() -{ - appendLogInfo("Bonjour install finished"); - - m_pCheckBoxAutoConfig->setChecked(true); -} - int MainWindow::raiseActivationDialog() { if (m_ActivationDialogRunning) { @@ -1573,7 +1325,6 @@ int MainWindow::raiseActivationDialog() } return result; } -#endif void MainWindow::on_windowShown() { diff --git a/src/gui/src/MainWindow.h b/src/gui/src/MainWindow.h index a42a96637..69e19be11 100644 --- a/src/gui/src/MainWindow.h +++ b/src/gui/src/MainWindow.h @@ -16,9 +16,7 @@ * along with this program. If not, see . */ -#if !defined(MAINWINDOW__H) - -#define MAINWINDOW__H +#pragma once #include #include @@ -54,11 +52,11 @@ class QAbstractButton; class LogDialog; class QSynergyApplication; class SetupWizard; -class ZeroconfService; class DataDownloader; class CommandProcess; class SslCertificate; class LicenseManager; +class Zeroconf; class MainWindow : public QMainWindow, public Ui::MainWindowBase { @@ -119,10 +117,10 @@ class MainWindow : public QMainWindow, public Ui::MainWindowBase void showConfigureServer(const QString& message); void showConfigureServer() { showConfigureServer(""); } void autoAddScreen(const QString name); - void serverDetected(const QString name); + void zeroconfServerDetected(const QString name); void updateLocalFingerprint(); + Zeroconf& zeroconf() { return *m_pZeroconf; } #ifndef SYNERGY_ENTERPRISE - void updateZeroconfService(); LicenseManager& licenseManager() const; int raiseActivationDialog(); #endif @@ -155,9 +153,6 @@ public slots: void logOutput(); void logError(); void updateFound(const QString& version); -#ifndef SYNERGY_ENTERPRISE - void bonjourInstallFinished(); -#endif void saveSettings(); protected: @@ -190,11 +185,6 @@ public slots: bool isServiceRunning(); #endif -#ifndef SYNERGY_ENTERPRISE - bool isBonjourRunning(); - void downloadBonjour(); - void promptAutoConfig(); -#endif QString getProfileRootForArg(); void checkConnected(const QString& line); void checkFingerprint(const QString& line); @@ -211,9 +201,14 @@ public slots: void secureSocket(bool secureSocket); private: +#ifndef SYNERGY_ENTERPRISE + LicenseManager* m_LicenseManager; + Zeroconf* m_pZeroconf; + bool m_ActivationDialogRunning; + QStringList m_PendingClientNames; +#endif QSettings& m_Settings; AppConfig* m_AppConfig; - LicenseManager* m_LicenseManager; QProcess* m_pSynergy; int m_SynergyState; ServerConfig m_ServerConfig; @@ -228,37 +223,20 @@ public slots: QMenu* m_pMenuEdit; QMenu* m_pMenuWindow; QMenu* m_pMenuHelp; -#ifndef SYNERGY_ENTERPRISE - ZeroconfService* m_pZeroconfService; -#endif - DataDownloader* m_pDataDownloader; - QMessageBox* m_DownloadMessageBox; QAbstractButton* m_pCancelButton; - QMutex m_UpdateZeroconfMutex; bool m_SuppressAutoConfigWarning; - CommandProcess* m_BonjourInstall; bool m_SuppressEmptyServerWarning; qRuningState m_ExpectedRunningState; QMutex m_StopDesktopMutex; SslCertificate* m_pSslCertificate; -#ifndef SYNERGY_ENTERPRISE - bool m_ActivationDialogRunning; - QStringList m_PendingClientNames; -#endif bool m_SecureSocket; private slots: void on_m_pButtonApply_clicked(); -#ifndef SYNERGY_ENTERPRISE - void on_m_pCheckBoxAutoConfig_toggled(bool checked); - void on_m_pComboServerList_currentIndexChanged(QString ); - void installBonjour(); -#endif void on_windowShown(); + void on_m_pComboServerList_currentIndexChanged(const QString &arg1); + signals: void windowShown(); }; - -#endif - diff --git a/src/gui/src/MainWindowBase.ui b/src/gui/src/MainWindowBase.ui index 7069b8b25..429dfcd2c 100644 --- a/src/gui/src/MainWindowBase.ui +++ b/src/gui/src/MainWindowBase.ui @@ -48,7 +48,7 @@ - :/res/icons/16x16/warning.png + :/res/icons/16x16/warning.png @@ -99,7 +99,7 @@ - :/res/icons/16x16/warning.png + :/res/icons/16x16/warning.png @@ -315,13 +315,6 @@ - - - - Auto config - - - @@ -338,6 +331,13 @@ + + + + Auto detected: + + + @@ -391,7 +391,7 @@ - :/res/icons/16x16/padlock.png + :/res/icons/16x16/padlock.png @@ -542,7 +542,7 @@ - + diff --git a/src/gui/src/SettingsDialog.cpp b/src/gui/src/SettingsDialog.cpp index 00b656ac7..b73254335 100644 --- a/src/gui/src/SettingsDialog.cpp +++ b/src/gui/src/SettingsDialog.cpp @@ -25,6 +25,8 @@ #include "AppConfig.h" #include "SslCertificate.h" #include "MainWindow.h" +#include "BonjourWindows.h" +#include "Zeroconf.h" #include #include @@ -37,10 +39,14 @@ static const char networkSecurity[] = "ns"; SettingsDialog::SettingsDialog(QWidget* parent, AppConfig& config) : QDialog(parent, Qt::WindowTitleHint | Qt::WindowSystemMenuHint), Ui::SettingsDialogBase(), - m_appConfig(config) + m_appConfig(config), + m_pBonjourWindows(nullptr) { setupUi(this); + // TODO: maybe just accept MainWindow type in ctor? + m_pMainWindow = dynamic_cast(parent); + m_Locale.fillLanguageComboBox(m_pComboLanguage); m_pLineEditScreenName->setText(appConfig().screenName()); @@ -53,20 +59,32 @@ SettingsDialog::SettingsDialog(QWidget* parent, AppConfig& config) : m_pCheckBoxAutoHide->setChecked(appConfig().getAutoHide()); #if defined(Q_OS_WIN) - m_pComboElevate->setCurrentIndex(static_cast(appConfig().elevateMode())); + m_pBonjourWindows = new BonjourWindows(this, m_pMainWindow); + if (m_pBonjourWindows->isRunning()) { + allowAutoConfig(); + m_pCheckBoxAutoConfig->setChecked(m_appConfig.autoConfig()); + } + + m_pComboElevate->setCurrentIndex(static_cast(appConfig().elevateMode())); m_pCheckBoxAutoHide->hide(); #else // elevate checkbox is only useful on ms windows. m_pLabelElevate->hide(); m_pComboElevate->hide(); + + // for linux and mac, allow auto config by default + allowAutoConfig(); #endif m_pCheckBoxEnableCrypto->setChecked(m_appConfig.getCryptoEnabled()); #ifdef SYNERGY_ENTERPRISE m_pCheckBoxEnableCrypto->setEnabled(true); + m_pLabelProUpgrade->hide(); #else - m_pCheckBoxEnableCrypto->setEnabled(m_appConfig.edition() == kPro); + bool isPro = m_appConfig.edition() == kPro; + m_pCheckBoxEnableCrypto->setEnabled(isPro); + m_pLabelProUpgrade->setVisible(!isPro); #endif } @@ -96,7 +114,7 @@ void SettingsDialog::reject() void SettingsDialog::changeEvent(QEvent* event) { - if (event != 0) + if (event != nullptr) { switch (event->type()) { @@ -118,6 +136,12 @@ void SettingsDialog::changeEvent(QEvent* event) } } +void SettingsDialog::allowAutoConfig() +{ + m_pLabelInstallBonjour->hide(); + m_pCheckBoxAutoConfig->setEnabled(true); +} + void SettingsDialog::on_m_pCheckBoxLogToFile_stateChanged(int i) { bool checked = i == 2; @@ -152,7 +176,21 @@ void SettingsDialog::on_m_pCheckBoxEnableCrypto_toggled(bool checked) if (checked) { SslCertificate sslCertificate; sslCertificate.generateCertificate(); - MainWindow& mainWindow = dynamic_cast (*this->parent()); - mainWindow.updateLocalFingerprint(); + m_pMainWindow->updateLocalFingerprint(); + } +} + +void SettingsDialog::on_m_pLabelInstallBonjour_linkActivated(const QString&) +{ + m_pBonjourWindows->download(); +} + +void SettingsDialog::on_m_pCheckBoxAutoConfig_toggled(bool checked) +{ + if (checked) { + m_pMainWindow->zeroconf().startService(); + } + else { + m_pMainWindow->zeroconf().stopService(); } } diff --git a/src/gui/src/SettingsDialog.h b/src/gui/src/SettingsDialog.h index 298197aa5..5a524596a 100644 --- a/src/gui/src/SettingsDialog.h +++ b/src/gui/src/SettingsDialog.h @@ -25,7 +25,9 @@ #include "SynergyLocale.h" #include "CoreInterface.h" +class MainWindow; class AppConfig; +class BonjourWindows; class SettingsDialog : public QDialog, public Ui::SettingsDialogBase { @@ -35,6 +37,7 @@ class SettingsDialog : public QDialog, public Ui::SettingsDialogBase SettingsDialog(QWidget* parent, AppConfig& config); static QString browseForSynergyc(QWidget* parent, const QString& programDir, const QString& synergycName); static QString browseForSynergys(QWidget* parent, const QString& programDir, const QString& synergysName); + void allowAutoConfig(); protected: void accept(); @@ -43,15 +46,19 @@ class SettingsDialog : public QDialog, public Ui::SettingsDialogBase AppConfig& appConfig() { return m_appConfig; } private: + MainWindow* m_pMainWindow; AppConfig& m_appConfig; SynergyLocale m_Locale; CoreInterface m_CoreInterface; + BonjourWindows* m_pBonjourWindows; private slots: void on_m_pCheckBoxEnableCrypto_toggled(bool checked); void on_m_pComboLanguage_currentIndexChanged(int index); void on_m_pCheckBoxLogToFile_stateChanged(int ); void on_m_pButtonBrowseLog_clicked(); + void on_m_pLabelInstallBonjour_linkActivated(const QString &link); + void on_m_pCheckBoxAutoConfig_toggled(bool checked); }; #endif diff --git a/src/gui/src/SettingsDialogBase.ui b/src/gui/src/SettingsDialogBase.ui index 476600d00..a96f29f58 100644 --- a/src/gui/src/SettingsDialogBase.ui +++ b/src/gui/src/SettingsDialogBase.ui @@ -157,7 +157,7 @@ - + true @@ -168,7 +168,7 @@ - &Network Security + &Network @@ -180,22 +180,42 @@ false - Use &TLS encryption + Enable &TLS Encryption + + + + + + + false + + + Enable Auto Config + + + + + + + <html><head/><body><p><a href="#"><span style=" text-decoration: underline; color:#007af4;">Install Bonjour</span></a></p></body></html> + + + Qt::RichText + + + true - - - Qt::Horizontal + + + <html><head/><body><p><a href="https://symless.com/account?source=gui&amp;intent=upgrade"><span style=" text-decoration: underline; color:#007af4;">Upgrade to Pro</span></a></p></body></html> - - - 40 - 20 - + + Qt::RichText - + diff --git a/src/gui/src/SetupWizard.cpp b/src/gui/src/SetupWizard.cpp index 863b2aa3a..4714a9654 100644 --- a/src/gui/src/SetupWizard.cpp +++ b/src/gui/src/SetupWizard.cpp @@ -126,9 +126,6 @@ void SetupWizard::accept() if (m_StartMain) { -#ifndef SYNERGY_ENTERPRISE - m_MainWindow.updateZeroconfService(); -#endif m_MainWindow.open(); } } diff --git a/src/gui/src/Zeroconf.cpp b/src/gui/src/Zeroconf.cpp new file mode 100644 index 000000000..65eb81f74 --- /dev/null +++ b/src/gui/src/Zeroconf.cpp @@ -0,0 +1,46 @@ +/* + * synergy -- mouse and keyboard sharing utility + * Copyright (C) 2012-2018 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 . + */ + +#include "Zeroconf.h" + +#include "ZeroconfService.h" +#include "MainWindow.h" + +Zeroconf::Zeroconf(MainWindow* mainWindow) : + m_pMainWindow(mainWindow), + m_pZeroconfService(nullptr) +{ +} + +Zeroconf::~Zeroconf() +{ + stopService(); +} + +void Zeroconf::startService() +{ + stopService(); + m_pZeroconfService = new ZeroconfService(m_pMainWindow); +} + +void Zeroconf::stopService() +{ + if (m_pZeroconfService != nullptr) { + delete m_pZeroconfService; + m_pZeroconfService = nullptr; + } +} diff --git a/src/gui/src/Zeroconf.h b/src/gui/src/Zeroconf.h new file mode 100644 index 000000000..c2e771915 --- /dev/null +++ b/src/gui/src/Zeroconf.h @@ -0,0 +1,38 @@ +/* + * synergy -- mouse and keyboard sharing utility + * Copyright (C) 2012-2018 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 . + */ + +#pragma once + +#include + +class MainWindow; +class ZeroconfService; + +class Zeroconf : public QObject +{ + Q_OBJECT + +public: + Zeroconf(MainWindow* mainWindow); + virtual ~Zeroconf(); + void startService(); + void stopService(); + +private: + MainWindow* m_pMainWindow; + ZeroconfService* m_pZeroconfService; +}; diff --git a/src/gui/src/ZeroconfService.cpp b/src/gui/src/ZeroconfService.cpp index 856fce91b..e8a124f2e 100644 --- a/src/gui/src/ZeroconfService.cpp +++ b/src/gui/src/ZeroconfService.cpp @@ -38,8 +38,8 @@ const char* ZeroconfService:: m_ClientServiceName = "_synergyClient._tcp"; ZeroconfService::ZeroconfService(MainWindow* mainWindow) : m_pMainWindow(mainWindow), - m_pZeroconfBrowser(0), - m_pZeroconfRegister(0), + m_pZeroconfBrowser(nullptr), + m_pZeroconfRegister(nullptr), m_ServiceRegistered(false) { if (m_pMainWindow->synergyType() == MainWindow::synergyServer) { @@ -81,7 +81,7 @@ void ZeroconfService::serverDetected(const QList& list) registerService(false); m_pMainWindow->appendLogInfo(tr("zeroconf server detected: %1").arg( record.serviceName)); - m_pMainWindow->serverDetected(record.serviceName); + m_pMainWindow->zeroconfServerDetected(record.serviceName); } } @@ -96,7 +96,8 @@ void ZeroconfService::clientDetected(const QList& list) void ZeroconfService::errorHandle(DNSServiceErrorType errorCode) { - QMessageBox::critical(0, tr("Zero configuration service"), + QMessageBox::critical( + m_pMainWindow, tr("Synergy Auto Config"), tr("Error code: %1.").arg(errorCode)); } @@ -127,8 +128,9 @@ bool ZeroconfService::registerService(bool server) if (!m_ServiceRegistered) { if (!m_zeroconfServer.listen()) { - QMessageBox::critical(0, tr("Zero configuration service"), - tr("Unable to start the zeroconf: %1.") + QMessageBox::critical( + m_pMainWindow, tr("Synergy Auto Config"), + tr("Unable to start zeroconf: %1.") .arg(m_zeroconfServer.errorString())); result = false; } @@ -137,7 +139,8 @@ bool ZeroconfService::registerService(bool server) if (server) { QString localIP = getLocalIPAddresses(); if (localIP.isEmpty()) { - QMessageBox::warning(m_pMainWindow, tr("Synergy"), + QMessageBox::warning( + m_pMainWindow, tr("Synergy Auto Config"), tr("Failed to get local IP address. " "Please manually type in server address " "on your clients"));