diff --git a/dist/wix/Product.wxs b/dist/wix/Product.wxs index 3bef6988..b6f91dd4 100644 --- a/dist/wix/Product.wxs +++ b/dist/wix/Product.wxs @@ -42,7 +42,6 @@ - @@ -56,6 +55,17 @@ + + 1 + 1 NOT Installed diff --git a/src/gui/res/Synergy.qrc b/src/gui/res/Synergy.qrc index 8f8ac0c8..479b7a05 100644 --- a/src/gui/res/Synergy.qrc +++ b/src/gui/res/Synergy.qrc @@ -54,5 +54,6 @@ image/spinning-wheel.gif icons/16x16/padlock.png icons/16x16/synergy-transfering.png + icons/16x16/auto-config.png diff --git a/src/gui/res/icons/16x16/auto-config.png b/src/gui/res/icons/16x16/auto-config.png new file mode 100644 index 00000000..88484f43 Binary files /dev/null and b/src/gui/res/icons/16x16/auto-config.png differ diff --git a/src/gui/src/AppConfig.cpp b/src/gui/src/AppConfig.cpp index b4abd062..547d0866 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 39330d77..756492a6 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 00000000..b16a0c78 --- /dev/null +++ b/src/gui/src/BonjourWindows.cpp @@ -0,0 +1,203 @@ +/* + * 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, + AppConfig& appConfig) : + m_pSettingsDialog(settingsDialog), + m_pMainWindow(mainWindow), + m_pBonjourInstall(nullptr), + m_pDownloadMessageBox(nullptr), + m_pDataDownloader(nullptr), + m_appConfig(appConfig) +{ +} + +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::downloadAndInstall() +{ + QUrl url; + int arch = getProcessorArch(); + if (arch == kProcessorArchWin32) { + url.setUrl(bonjourBaseUrl + bonjourFilename32); + m_pMainWindow->appendLogInfo("downloading bonjour (32-bit)"); + } + else if (arch == kProcessorArchWin64) { + url.setUrl(bonjourBaseUrl + bonjourFilename64); + m_pMainWindow->appendLogInfo("downloading bonjour (64-bit)"); + } + 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(downloadFinished())); + } + + m_pDataDownloader->download(url); + + if (m_pDownloadMessageBox != nullptr) { + delete m_pDownloadMessageBox; + m_pDownloadMessageBox = nullptr; + } + + m_pDownloadMessageBox = new QMessageBox(m_pSettingsDialog); + m_pDownloadMessageBox->setWindowTitle("Synergy Auto Config"); + 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::downloadFinished() +{ + m_pMainWindow->appendLogInfo("bonjour downloaded"); + install(); +} + +void BonjourWindows::install() +{ + m_pMainWindow->appendLogInfo("installing bonjour"); + + 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(installFinished())); + 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 installed"); + m_appConfig.setAutoConfig(true); + 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 00000000..7c2cbe22 --- /dev/null +++ b/src/gui/src/BonjourWindows.h @@ -0,0 +1,65 @@ +/* + * 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 AppConfig; + +class BonjourWindows : public QObject +{ + Q_OBJECT + +public: + BonjourWindows(SettingsDialog* settingsDialog, MainWindow* mainWindow, AppConfig& appConfig); + virtual ~BonjourWindows(); + +public: + void downloadAndInstall(); + bool isRunning() const; + +protected slots: + void downloadFinished(); + void installFinished(); + +private: + void install(); + +private: + SettingsDialog* m_pSettingsDialog; + MainWindow* m_pMainWindow; + CommandProcess* m_pBonjourInstall; + QMessageBox* m_pDownloadMessageBox; + DataDownloader* m_pDataDownloader; + AppConfig& m_appConfig; +}; + +#endif // Q_OS_WIN diff --git a/src/gui/src/DataDownloader.cpp b/src/gui/src/DataDownloader.cpp index 4f778489..215adc8f 100644 --- a/src/gui/src/DataDownloader.cpp +++ b/src/gui/src/DataDownloader.cpp @@ -34,6 +34,7 @@ void DataDownloader::complete(QNetworkReply* reply) { m_Data = reply->readAll(); reply->deleteLater(); + m_pReply = nullptr; if (!m_Data.isEmpty()) { m_IsFinished = true; @@ -48,7 +49,9 @@ QByteArray DataDownloader::data() const void DataDownloader::cancel() { - m_pReply->abort(); + if (m_pReply != nullptr) { + m_pReply->abort(); + } } void DataDownloader::download(QUrl url) diff --git a/src/gui/src/MainWindow.cpp b/src/gui/src/MainWindow.cpp index 342fdee8..624d71ba 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 (*.*)")); @@ -71,6 +62,8 @@ static const QString synergyConfigFilter(QObject::tr("Synergy Configurations (*. static const char* tlsVersion = "TLS 1.2"; static const char* tlsCheckString = "network encryption protocol: TLSv1.2"; +static const int debugLogLevel = 1; + static const char* synergyIconFiles[] = { ":/res/icons/16x16/synergy-disconnected.png", @@ -85,11 +78,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_ActivationDialogRunning(false), #endif + m_pZeroconf(nullptr), + m_Settings(settings), + m_AppConfig(&appConfig), m_pSynergy(NULL), m_SynergyState(synergyDisconnected), m_ServerConfig(&m_Settings, 5, 3, m_AppConfig->screenName(), this), @@ -102,22 +98,15 @@ 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) { +#ifndef SYNERGY_ENTERPRISE + m_pZeroconf = new Zeroconf(this); +#endif + setupUi(this); createMenuBar(); @@ -146,11 +135,6 @@ MainWindow::MainWindow (QSettings& settings, AppConfig& appConfig, setMinimumSize(size()); #endif - m_SuppressAutoConfigWarning = true; - m_pCheckBoxAutoConfig->setChecked(appConfig.autoConfig()); - m_SuppressAutoConfigWarning = false; - - m_pComboServerList->hide(); m_trialWidget->hide(); // hide padlock icon @@ -191,7 +175,11 @@ MainWindow::MainWindow (QSettings& settings, AppConfig& appConfig, #ifdef SYNERGY_ENTERPRISE m_pActivate->setVisible(false); - m_pCheckBoxAutoConfig->setVisible(false); +#endif + +#ifndef SYNERGY_ENTERPRISE + updateZeroconfService(); + updateAutoConfigWidgets(); #endif } @@ -202,19 +190,11 @@ MainWindow::~MainWindow() stopDesktop(); } - saveSettings(); - #ifndef SYNERGY_ENTERPRISE - delete m_pZeroconfService; + delete m_pZeroconf; #endif - if (m_DownloadMessageBox != NULL) { - delete m_DownloadMessageBox; - } - - if (m_BonjourInstall != NULL) { - delete m_BonjourInstall; - } + saveSettings(); delete m_pSslCertificate; } @@ -229,19 +209,11 @@ 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). if (appConfig().startedBefore() && appConfig().processMode() == Desktop) { - m_SuppressEmptyServerWarning = true; startSynergy(); - m_SuppressEmptyServerWarning = false; } } @@ -438,7 +410,7 @@ void MainWindow::appendLogInfo(const QString& text) } void MainWindow::appendLogDebug(const QString& text) { - if (appConfig().logLevel() >= 4) { + if (appConfig().logLevel() >= debugLogLevel) { appendLogRaw(getTimeStamp() + " DEBUG: " + text); } } @@ -773,7 +745,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()); @@ -784,15 +756,13 @@ bool MainWindow::clientArgs(QStringList& args, QString& app) if (m_pLineEditHostname->text().isEmpty()) { show(); - if (!m_SuppressEmptyServerWarning) { - QMessageBox::warning(this, tr("Hostname is empty"), - tr("Please fill in a hostname for the synergy client to connect to.")); - } + QMessageBox::warning( + this, tr("Hostname is empty"), + tr("Please fill in a hostname for the synergy client to connect to.")); return false; } args << m_pLineEditHostname->text() + ":" + QString::number(appConfig().port()); - return true; } @@ -1101,30 +1071,19 @@ void MainWindow::changeEvent(QEvent* event) } } -#ifndef SYNERGY_ENTERPRISE -void MainWindow::updateZeroconfService() +void MainWindow::zeroconfServerDetected(const QString name) { - 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); - } - } + // don't add to the server combo box if not in client mode. + if (synergyType() != synergyClient) { + return; + } + + // don't add yourself to the server list. + if (getIPAddresses().contains(name)) { + return; } -} -#endif -void MainWindow::serverDetected(const QString name) -{ if (m_pComboServerList->findText(name) == -1) { - // Note: the first added item triggers startSynergy m_pComboServerList->addItem(name); } @@ -1223,21 +1182,15 @@ MainWindow::licenseManager() const void MainWindow::on_m_pGroupClient_toggled(bool on) { m_pGroupServer->setChecked(!on); -#ifndef SYNERGY_ENTERPRISE - if (on) { - updateZeroconfService(); - } -#endif + + // only call in either client or server toggle, but not both + // since the toggle functions call eachother indirectly. + updateZeroconfService(); } 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() @@ -1272,9 +1225,51 @@ void MainWindow::on_m_pActionAbout_triggered() dlg.exec(); } +void MainWindow::updateZeroconfService() +{ +#ifndef SYNERGY_ENTERPRISE + + // reset the server list in case one has gone away. + // it'll be re-added after the zeroconf service restarts. + m_pComboServerList->clear(); + + if (m_pZeroconf != nullptr) { + if (appConfig().autoConfig()) { + m_pZeroconf->startService(); + } + else { + m_pZeroconf->stopService(); + } + } +#endif +} + +void MainWindow::updateAutoConfigWidgets() +{ + if (appConfig().autoConfig()) { + m_pLabelAutoDetected->show(); + m_pComboServerList->show(); + + m_pLabelServerName->hide(); + m_pLineEditHostname->hide(); + + m_pWidgetAutoConfig->hide(); + } + else { + m_pLabelServerName->show(); + m_pLineEditHostname->show(); + + m_pLabelAutoDetected->hide(); + m_pComboServerList->hide(); + + m_pWidgetAutoConfig->show(); + } +} + void MainWindow::on_m_pActionSettings_triggered() { ProcessMode lastProcessMode = appConfig().processMode(); + bool lastAutoConfig = appConfig().autoConfig(); SettingsDialog dlg(this, appConfig()); dlg.exec(); @@ -1283,40 +1278,45 @@ void MainWindow::on_m_pActionSettings_triggered() { onModeChanged(true, true); } + + if (lastAutoConfig != appConfig().autoConfig()) { + updateAutoConfigWidgets(); + updateZeroconfService(); + } } void MainWindow::autoAddScreen(const QString name) { - if (!m_ServerConfig.ignoreAutoConfigClient()) { + if (m_ServerConfig.ignoreAutoConfigClient()) { + appendLogDebug(QString("ignoring zeroconf screen: %1").arg(name)); + return; + } + #ifndef SYNERGY_ENTERPRISE - if (m_ActivationDialogRunning) { - // TODO: refactor this code - // add this screen to the pending list and check this list until - // users finish activation dialog - m_PendingClientNames.append(name); - return; - } + if (m_ActivationDialogRunning) { + // TODO: refactor this code + // add this screen to the pending list and check this list until + // users finish activation dialog + m_PendingClientNames.append(name); + return; + } #endif - int r = m_ServerConfig.autoAddScreen(name); - if (r != kAutoAddScreenOk) { - switch (r) { - case kAutoAddScreenManualServer: - showConfigureServer( - tr("Please add the server (%1) to the grid.") - .arg(appConfig().screenName())); - break; + int r = m_ServerConfig.autoAddScreen(name); + if (r != kAutoAddScreenOk) { + switch (r) { + case kAutoAddScreenManualServer: + showConfigureServer( + tr("Please add the server (%1) to the grid.") + .arg(appConfig().screenName())); + break; - case kAutoAddScreenManualClient: - showConfigureServer( - tr("Please drag the new client screen (%1) " - "to the desired position on the grid.") - .arg(name)); - break; - } - } - else { - restartSynergy(); + case kAutoAddScreenManualClient: + showConfigureServer( + tr("Please drag the new client screen (%1) " + "to the desired position on the grid.") + .arg(name)); + break; } } } @@ -1345,211 +1345,7 @@ 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 ) -{ - 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) { @@ -1568,9 +1364,6 @@ int MainWindow::raiseActivationDialog() m_PendingClientNames.clear(); } - if (result == QDialog::Accepted) { - restartSynergy(); - } return result; } #endif @@ -1612,3 +1405,8 @@ void MainWindow::secureSocket(bool secureSocket) m_pLabelPadlock->hide(); } } + +void MainWindow::on_m_pLabelAutoConfig_linkActivated(const QString &) +{ + m_pActionSettings->trigger(); +} diff --git a/src/gui/src/MainWindow.h b/src/gui/src/MainWindow.h index a42a9663..e267ccf2 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,14 +117,16 @@ 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 + void updateZeroconfService(); + public slots: void setEdition(Edition edition); #ifndef SYNERGY_ENTERPRISE @@ -155,9 +155,6 @@ public slots: void logOutput(); void logError(); void updateFound(const QString& version); -#ifndef SYNERGY_ENTERPRISE - void bonjourInstallFinished(); -#endif void saveSettings(); protected: @@ -190,11 +187,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 +203,14 @@ public slots: void secureSocket(bool secureSocket); private: +#ifndef SYNERGY_ENTERPRISE + LicenseManager* m_LicenseManager; + bool m_ActivationDialogRunning; + QStringList m_PendingClientNames; +#endif + Zeroconf* m_pZeroconf; QSettings& m_Settings; AppConfig* m_AppConfig; - LicenseManager* m_LicenseManager; QProcess* m_pSynergy; int m_SynergyState; ServerConfig m_ServerConfig; @@ -228,37 +225,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; + void updateAutoConfigWidgets(); + 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_pLabelAutoConfig_linkActivated(const QString &link); + signals: void windowShown(); }; - -#endif - diff --git a/src/gui/src/MainWindowBase.ui b/src/gui/src/MainWindowBase.ui index 7069b8b2..42f44dd6 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 @@ -129,6 +129,81 @@ + + + + + 0 + 28 + + + + + 2 + + + 0 + + + 0 + + + 8 + + + + + + 0 + 0 + + + + + 16 + 20 + + + + + 244 + 16777215 + + + + + + + :/res/icons/16x16/auto-config.png + + + + + + + <html><head/><body><p>Manual Config mode active, consider using Auto Config instead (<a href="#"><span style=" text-decoration: underline; color:#007af4;">Settings</span></a>)</p></body></html> + + + Qt::RichText + + + + + + + Qt::Horizontal + + + + 200 + 0 + + + + + + + @@ -289,9 +364,9 @@ QFormLayout::AllNonFixedFieldsGrow - + - Screen name: + Client name: @@ -305,7 +380,7 @@ - &Server IP: + &Server: m_pLineEditHostname @@ -313,16 +388,25 @@ - - - - - - Auto config + + + + 0 + 0 + + + + + 200 + 0 + + + + Hostname or IP address of the server computer. - + @@ -332,12 +416,19 @@ - 120 + 200 0 + + + + Server: + + + @@ -391,7 +482,7 @@ - :/res/icons/16x16/padlock.png + :/res/icons/16x16/padlock.png @@ -542,7 +633,7 @@ - + diff --git a/src/gui/src/ServerConfig.cpp b/src/gui/src/ServerConfig.cpp index bddb1444..fd821e5a 100644 --- a/src/gui/src/ServerConfig.cpp +++ b/src/gui/src/ServerConfig.cpp @@ -303,7 +303,7 @@ int ServerConfig::autoAddScreen(const QString name) } } if (findScreenName(name, targetIndex)) { - // already exists. + m_pMainWindow->appendLogDebug(QString("ignoring screen already in config: %1").arg(name)); return kAutoAddScreenIgnore; } diff --git a/src/gui/src/SettingsDialog.cpp b/src/gui/src/SettingsDialog.cpp index 00b656ac..50f3ab23 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,41 @@ 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, m_appConfig); + if (m_pBonjourWindows->isRunning()) { + allowAutoConfig(); + } + + 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(); + + m_pCheckBoxAutoConfig->hide(); + m_pLabelInstallBonjour->hide(); + #else - m_pCheckBoxEnableCrypto->setEnabled(m_appConfig.edition() == kPro); + + bool isPro = m_appConfig.edition() == kPro; + m_pCheckBoxEnableCrypto->setEnabled(isPro); + m_pLabelProUpgrade->setVisible(!isPro); + + m_pCheckBoxAutoConfig->setChecked(appConfig().autoConfig()); + #endif } @@ -81,6 +108,7 @@ void SettingsDialog::accept() appConfig().setLanguage(m_pComboLanguage->itemData(m_pComboLanguage->currentIndex()).toString()); appConfig().setElevateMode(static_cast(m_pComboElevate->currentIndex())); appConfig().setAutoHide(m_pCheckBoxAutoHide->isChecked()); + appConfig().setAutoConfig(m_pCheckBoxAutoConfig->isChecked()); appConfig().saveSettings(); QDialog::accept(); } @@ -96,7 +124,7 @@ void SettingsDialog::reject() void SettingsDialog::changeEvent(QEvent* event) { - if (event != 0) + if (event != nullptr) { switch (event->type()) { @@ -118,6 +146,13 @@ void SettingsDialog::changeEvent(QEvent* event) } } +void SettingsDialog::allowAutoConfig() +{ + m_pLabelInstallBonjour->hide(); + m_pCheckBoxAutoConfig->setEnabled(true); + m_pCheckBoxAutoConfig->setChecked(m_appConfig.autoConfig()); +} + void SettingsDialog::on_m_pCheckBoxLogToFile_stateChanged(int i) { bool checked = i == 2; @@ -152,7 +187,13 @@ 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&) +{ +#if defined(Q_OS_WIN) + m_pBonjourWindows->downloadAndInstall(); +#endif +} diff --git a/src/gui/src/SettingsDialog.h b/src/gui/src/SettingsDialog.h index 298197aa..738bb457 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,18 @@ 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); }; #endif diff --git a/src/gui/src/SettingsDialogBase.ui b/src/gui/src/SettingsDialogBase.ui index 476600d0..b85417c2 100644 --- a/src/gui/src/SettingsDialogBase.ui +++ b/src/gui/src/SettingsDialogBase.ui @@ -6,8 +6,8 @@ 0 0 - 368 - 446 + 357 + 496 @@ -157,7 +157,23 @@ - + + + Qt::Vertical + + + QSizePolicy::Minimum + + + + 20 + 10 + + + + + + true @@ -168,38 +184,96 @@ - &Network Security + &Network QFormLayout::AllNonFixedFieldsGrow - - - - false - - - Use &TLS encryption - - - + + 2 + + + 12 + + + 2 + + + 12 + - - - Qt::Horizontal + + + 0 - - - 40 - 20 - + + 12 - + + + + false + + + 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 + + + + + + + <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> + + + Qt::RichText + + + true + + + + + + + + Qt::Vertical + + + QSizePolicy::Minimum + + + + 20 + 10 + + + + @@ -290,10 +364,13 @@ Qt::Vertical + + QSizePolicy::MinimumExpanding + 20 - 40 + 10 @@ -317,7 +394,6 @@ m_pLineEditInterface m_pComboElevate m_pCheckBoxAutoHide - m_pCheckBoxEnableCrypto m_pComboLogLevel m_pCheckBoxLogToFile m_pLineEditLogFilename diff --git a/src/gui/src/SetupWizard.cpp b/src/gui/src/SetupWizard.cpp index 863b2aa3..4714a965 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 00000000..b2a0e6b7 --- /dev/null +++ b/src/gui/src/Zeroconf.cpp @@ -0,0 +1,58 @@ +/* + * 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() +{ + if (m_pZeroconfService != nullptr) { + m_pMainWindow->appendLogInfo("restarting zeroconf service"); + delete m_pZeroconfService; + m_pZeroconfService = nullptr; + } + else { + m_pMainWindow->appendLogInfo("starting zeroconf service"); + } + + m_pZeroconfService = new ZeroconfService(m_pMainWindow); + + m_pMainWindow->appendLogInfo("started zeroconf service"); +} + +void Zeroconf::stopService() +{ + if (m_pZeroconfService != nullptr) { + m_pMainWindow->appendLogInfo("stopping zeroconf service"); + delete m_pZeroconfService; + m_pZeroconfService = nullptr; + m_pMainWindow->appendLogInfo("stopped zeroconf service"); + } +} diff --git a/src/gui/src/Zeroconf.h b/src/gui/src/Zeroconf.h new file mode 100644 index 00000000..c2e77191 --- /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 856fce91..e8a124f2 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"));