2012-06-10 16:50:54 +00:00
|
|
|
/*
|
|
|
|
|
* synergy -- mouse and keyboard sharing utility
|
2024-07-16 08:30:35 +00:00
|
|
|
* Copyright (C) 2012 Symless Ltd.
|
2012-06-10 16:50:54 +00:00
|
|
|
* Copyright (C) 2008 Volker Lanz (vl@fidra.de)
|
2015-07-29 21:34:21 +00:00
|
|
|
*
|
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
|
2015-05-03 02:33:52 +00:00
|
|
|
* found in the file LICENSE that should have accompanied this file.
|
2015-07-29 21:34:21 +00:00
|
|
|
*
|
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/>.
|
|
|
|
|
*/
|
|
|
|
|
|
2016-09-06 15:13:50 +00:00
|
|
|
#define DOWNLOAD_URL "http://symless.com/?source=gui"
|
2024-07-02 19:07:06 +00:00
|
|
|
#define HELP_URL "http://symless.com/help?source=gui"
|
2012-06-10 16:50:54 +00:00
|
|
|
|
2021-01-10 13:31:56 +00:00
|
|
|
#include <array>
|
2012-07-03 14:15:05 +00:00
|
|
|
|
2012-06-10 16:50:54 +00:00
|
|
|
#include "MainWindow.h"
|
2015-04-15 12:09:22 +00:00
|
|
|
|
2012-06-10 16:50:54 +00:00
|
|
|
#include "AboutDialog.h"
|
2016-09-29 12:45:06 +00:00
|
|
|
#include "ActivationDialog.h"
|
2024-07-02 19:07:06 +00:00
|
|
|
#include "Fingerprint.h"
|
2016-10-17 16:57:14 +00:00
|
|
|
#include "LicenseManager.h"
|
2024-07-02 19:07:06 +00:00
|
|
|
#include "ServerConfigDialog.h"
|
|
|
|
|
#include "SettingsDialog.h"
|
2020-02-25 17:00:30 +00:00
|
|
|
#include <QPushButton>
|
2024-07-02 19:07:06 +00:00
|
|
|
#include <shared/EditionType.h>
|
2012-06-10 16:50:54 +00:00
|
|
|
|
2015-08-09 01:16:50 +00:00
|
|
|
#if defined(Q_OS_MAC)
|
|
|
|
|
#include "OSXHelpers.h"
|
|
|
|
|
#endif
|
|
|
|
|
|
2024-07-02 19:07:06 +00:00
|
|
|
#include <QDesktopServices>
|
|
|
|
|
#include <QFileDialog>
|
2014-02-14 16:21:02 +00:00
|
|
|
#include <QMenu>
|
|
|
|
|
#include <QMenuBar>
|
|
|
|
|
#include <QMessageBox>
|
2024-07-02 19:07:06 +00:00
|
|
|
#include <QNetworkAccessManager>
|
2024-07-08 14:37:51 +00:00
|
|
|
#include <QRegularExpression>
|
2024-07-02 19:07:06 +00:00
|
|
|
#include <QtCore>
|
|
|
|
|
#include <QtGui>
|
|
|
|
|
#include <QtNetwork>
|
2012-06-10 16:50:54 +00:00
|
|
|
|
|
|
|
|
#if defined(Q_OS_MAC)
|
|
|
|
|
#include <ApplicationServices/ApplicationServices.h>
|
|
|
|
|
#endif
|
|
|
|
|
|
2018-08-08 16:20:16 +00:00
|
|
|
static const int debugLogLevel = 1;
|
|
|
|
|
|
2024-07-02 19:07:06 +00:00
|
|
|
static const char *synergyLightIconFiles[] = {
|
2020-01-11 14:57:44 +00:00
|
|
|
":/res/icons/64x64/synergy-light-disconnected.png",
|
|
|
|
|
":/res/icons/64x64/synergy-light-disconnected.png",
|
|
|
|
|
":/res/icons/64x64/synergy-light-connected.png",
|
|
|
|
|
":/res/icons/64x64/synergy-light-transfering.png",
|
2024-07-02 19:07:06 +00:00
|
|
|
":/res/icons/64x64/synergy-light-disconnected.png"};
|
2020-01-11 14:57:44 +00:00
|
|
|
|
2024-07-02 19:07:06 +00:00
|
|
|
static const char *synergyDarkIconFiles[] = {
|
2020-01-11 14:57:44 +00:00
|
|
|
":/res/icons/64x64/synergy-dark-disconnected.png",
|
|
|
|
|
":/res/icons/64x64/synergy-dark-disconnected.png",
|
|
|
|
|
":/res/icons/64x64/synergy-dark-connected.png",
|
|
|
|
|
":/res/icons/64x64/synergy-dark-transfering.png",
|
2024-07-02 19:07:06 +00:00
|
|
|
":/res/icons/64x64/synergy-dark-disconnected.png" // synergyPendingRetry
|
2015-08-09 01:16:50 +00:00
|
|
|
};
|
2020-01-11 14:57:44 +00:00
|
|
|
|
2024-07-02 19:07:06 +00:00
|
|
|
static const char *synergyDefaultIconFiles[] = {
|
|
|
|
|
":/res/icons/16x16/synergy-disconnected.png", // synergyDisconnected
|
|
|
|
|
":/res/icons/16x16/synergy-disconnected.png", // synergyConnecting
|
|
|
|
|
":/res/icons/16x16/synergy-connected.png", // synergyConnected
|
|
|
|
|
":/res/icons/16x16/synergy-transfering.png", // synergyListening
|
|
|
|
|
":/res/icons/16x16/synergy-disconnected.png" // synergyPendingRetry
|
2012-06-10 16:50:54 +00:00
|
|
|
};
|
|
|
|
|
|
2024-07-04 09:14:54 +00:00
|
|
|
#ifdef SYNERGY_ENABLE_LICENSING
|
2024-07-02 19:07:06 +00:00
|
|
|
MainWindow::MainWindow(AppConfig &appConfig, LicenseManager &licenseManager)
|
2024-07-04 09:14:54 +00:00
|
|
|
#else
|
|
|
|
|
MainWindow::MainWindow(AppConfig &appConfig)
|
2018-06-07 15:22:49 +00:00
|
|
|
#endif
|
2024-07-02 19:07:06 +00:00
|
|
|
:
|
2024-07-04 09:14:54 +00:00
|
|
|
#ifdef SYNERGY_ENABLE_LICENSING
|
2024-07-16 13:36:44 +00:00
|
|
|
m_LicenseManager(&licenseManager),
|
|
|
|
|
m_ActivationDialogRunning(false),
|
2018-06-07 15:22:49 +00:00
|
|
|
#endif
|
2024-07-16 13:36:44 +00:00
|
|
|
m_AppConfig(&appConfig),
|
|
|
|
|
m_pSynergy(NULL),
|
2024-07-02 19:07:06 +00:00
|
|
|
m_SynergyState(synergyDisconnected),
|
2024-07-16 13:36:44 +00:00
|
|
|
m_ServerConfig(5, 3, m_AppConfig, this),
|
|
|
|
|
m_AlreadyHidden(false),
|
|
|
|
|
m_pMenuBar(NULL),
|
|
|
|
|
m_pMenuFile(NULL),
|
|
|
|
|
m_pMenuEdit(NULL),
|
|
|
|
|
m_pMenuWindow(NULL),
|
|
|
|
|
m_pMenuHelp(NULL),
|
|
|
|
|
m_pCancelButton(NULL),
|
|
|
|
|
m_ExpectedRunningState(kStopped),
|
|
|
|
|
m_SecureSocket(false),
|
|
|
|
|
m_serverConnection(*this),
|
|
|
|
|
m_clientConnection(*this) {
|
2018-08-08 13:41:37 +00:00
|
|
|
|
2024-07-02 19:07:06 +00:00
|
|
|
setupUi(this);
|
2021-08-16 08:21:14 +00:00
|
|
|
|
|
|
|
|
#if defined(Q_OS_MAC)
|
2024-07-02 19:07:06 +00:00
|
|
|
m_pRadioGroupServer->setAttribute(Qt::WA_MacShowFocusRect, 0);
|
|
|
|
|
m_pRadioGroupClient->setAttribute(Qt::WA_MacShowFocusRect, 0);
|
2021-08-16 08:21:14 +00:00
|
|
|
#endif
|
|
|
|
|
|
2024-07-02 19:07:06 +00:00
|
|
|
createMenuBar();
|
|
|
|
|
loadSettings();
|
|
|
|
|
initConnections();
|
2016-12-28 11:50:32 +00:00
|
|
|
|
2024-07-02 19:07:06 +00:00
|
|
|
m_pWidgetUpdate->hide();
|
|
|
|
|
m_VersionChecker.setApp(appPath(appConfig.synergycName()));
|
2021-04-12 09:03:37 +00:00
|
|
|
|
2024-07-02 19:07:06 +00:00
|
|
|
updateScreenName();
|
2024-07-16 13:36:44 +00:00
|
|
|
connect(
|
|
|
|
|
m_AppConfig, SIGNAL(screenNameChanged()), this, SLOT(updateScreenName()));
|
2024-07-02 19:07:06 +00:00
|
|
|
m_pLabelIpAddresses->setText(
|
|
|
|
|
tr("This computer's IP addresses: %1").arg(getIPAddresses()));
|
2012-06-10 16:50:54 +00:00
|
|
|
|
2012-07-14 17:01:29 +00:00
|
|
|
#if defined(Q_OS_WIN)
|
2024-07-02 19:07:06 +00:00
|
|
|
// ipc must always be enabled, so that we can disable command when switching
|
|
|
|
|
// to desktop mode.
|
2024-07-16 13:36:44 +00:00
|
|
|
connect(
|
|
|
|
|
&m_IpcClient, SIGNAL(readLogLine(const QString &)), this,
|
|
|
|
|
SLOT(appendLogRaw(const QString &)));
|
|
|
|
|
connect(
|
|
|
|
|
&m_IpcClient, SIGNAL(errorMessage(const QString &)), this,
|
|
|
|
|
SLOT(appendLogError(const QString &)));
|
|
|
|
|
connect(
|
|
|
|
|
&m_IpcClient, SIGNAL(infoMessage(const QString &)), this,
|
|
|
|
|
SLOT(appendLogInfo(const QString &)));
|
|
|
|
|
connect(
|
|
|
|
|
&m_IpcClient, SIGNAL(readLogLine(const QString &)), this,
|
|
|
|
|
SLOT(handleIdleService(const QString &)));
|
2024-07-02 19:07:06 +00:00
|
|
|
m_IpcClient.connectToHost();
|
2012-07-14 17:01:29 +00:00
|
|
|
#endif
|
2012-07-29 00:10:18 +00:00
|
|
|
|
2024-07-02 19:07:06 +00:00
|
|
|
// change default size based on os
|
2012-07-29 00:10:18 +00:00
|
|
|
#if defined(Q_OS_MAC)
|
2024-07-02 19:07:06 +00:00
|
|
|
resize(720, 550);
|
|
|
|
|
setMinimumSize(size());
|
2012-07-30 16:11:28 +00:00
|
|
|
#elif defined(Q_OS_LINUX)
|
2024-07-02 19:07:06 +00:00
|
|
|
resize(700, 530);
|
|
|
|
|
setMinimumSize(size());
|
2012-07-29 00:10:18 +00:00
|
|
|
#endif
|
2014-08-21 17:32:40 +00:00
|
|
|
|
2024-07-02 19:07:06 +00:00
|
|
|
m_trialLabel->hide();
|
2021-04-12 09:03:37 +00:00
|
|
|
|
2024-07-02 19:07:06 +00:00
|
|
|
// hide padlock icon
|
|
|
|
|
secureSocket(false);
|
2018-01-28 01:50:30 +00:00
|
|
|
|
2024-07-16 13:36:44 +00:00
|
|
|
connect(
|
|
|
|
|
this, SIGNAL(windowShown()), this, SLOT(on_windowShown()),
|
|
|
|
|
Qt::QueuedConnection);
|
2024-07-04 09:14:54 +00:00
|
|
|
#ifdef SYNERGY_ENABLE_LICENSING
|
2024-07-16 13:36:44 +00:00
|
|
|
connect(
|
|
|
|
|
m_LicenseManager, SIGNAL(editionChanged(Edition)), this,
|
|
|
|
|
SLOT(setEdition(Edition)), Qt::QueuedConnection);
|
2016-10-15 14:30:28 +00:00
|
|
|
|
2024-07-16 13:36:44 +00:00
|
|
|
connect(
|
|
|
|
|
m_LicenseManager, SIGNAL(showLicenseNotice(QString)), this,
|
|
|
|
|
SLOT(showLicenseNotice(QString)), Qt::QueuedConnection);
|
2016-10-15 14:30:28 +00:00
|
|
|
|
2024-07-16 13:36:44 +00:00
|
|
|
connect(
|
|
|
|
|
m_LicenseManager, SIGNAL(InvalidLicense()), this, SLOT(InvalidLicense()),
|
|
|
|
|
Qt::QueuedConnection);
|
2018-06-07 15:22:49 +00:00
|
|
|
#endif
|
2016-10-15 14:30:28 +00:00
|
|
|
|
2024-07-16 13:36:44 +00:00
|
|
|
connect(
|
|
|
|
|
m_AppConfig, SIGNAL(sslToggled()), this, SLOT(updateLocalFingerprint()),
|
|
|
|
|
Qt::QueuedConnection);
|
2016-10-15 14:30:28 +00:00
|
|
|
|
2024-07-02 19:07:06 +00:00
|
|
|
updateWindowTitle();
|
2016-10-26 14:57:38 +00:00
|
|
|
|
2024-07-02 19:07:06 +00:00
|
|
|
QString lastVersion = m_AppConfig->lastVersion();
|
|
|
|
|
if (lastVersion != SYNERGY_VERSION) {
|
|
|
|
|
m_AppConfig->setLastVersion(SYNERGY_VERSION);
|
2024-07-04 09:14:54 +00:00
|
|
|
|
|
|
|
|
#ifdef SYNERGY_ENABLE_LICENSING
|
2024-07-02 19:07:06 +00:00
|
|
|
m_LicenseManager->notifyUpdate(lastVersion, SYNERGY_VERSION);
|
2018-06-07 15:22:49 +00:00
|
|
|
#endif
|
2024-07-02 19:07:06 +00:00
|
|
|
}
|
2018-06-07 15:22:49 +00:00
|
|
|
|
2024-07-04 09:14:54 +00:00
|
|
|
#ifndef SYNERGY_ENABLE_LICENSING
|
2024-07-02 19:07:06 +00:00
|
|
|
m_pActivate->setVisible(false);
|
2018-08-03 15:58:23 +00:00
|
|
|
#endif
|
2012-06-10 16:50:54 +00:00
|
|
|
}
|
|
|
|
|
|
2024-07-02 19:07:06 +00:00
|
|
|
MainWindow::~MainWindow() {
|
2024-07-16 08:30:35 +00:00
|
|
|
if (appConfig().processMode() == ProcessMode::kDesktop) {
|
2024-07-02 19:07:06 +00:00
|
|
|
m_ExpectedRunningState = kStopped;
|
|
|
|
|
try {
|
|
|
|
|
stopDesktop();
|
|
|
|
|
} catch (...) {
|
|
|
|
|
// do not throw, since throwing from a dtor can result in unreliable
|
|
|
|
|
// behaviour.
|
|
|
|
|
qCritical() << "error stopping desktop in main window destructor";
|
2016-12-28 11:50:32 +00:00
|
|
|
}
|
2024-07-02 19:07:06 +00:00
|
|
|
}
|
2012-06-10 16:50:54 +00:00
|
|
|
}
|
|
|
|
|
|
2024-07-02 19:07:06 +00:00
|
|
|
void MainWindow::open() {
|
|
|
|
|
std::array<QAction *, 7> trayMenu = {
|
|
|
|
|
m_pActionStartSynergy, m_pActionStopSynergy, nullptr,
|
|
|
|
|
m_pActionMinimize, m_pActionRestore, nullptr,
|
|
|
|
|
m_pActionQuit};
|
2012-07-13 14:38:58 +00:00
|
|
|
|
2024-07-02 19:07:06 +00:00
|
|
|
m_trayIcon.create(trayMenu, [this](QObject const *o, const char *s) {
|
|
|
|
|
connect(o, s, this, SLOT(trayActivated(QSystemTrayIcon::ActivationReason)));
|
|
|
|
|
setIcon(synergyDisconnected);
|
|
|
|
|
});
|
2014-01-27 16:50:41 +00:00
|
|
|
|
2024-07-02 19:07:06 +00:00
|
|
|
if (appConfig().getAutoHide()) {
|
|
|
|
|
hide();
|
|
|
|
|
} else {
|
|
|
|
|
showNormal();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
m_VersionChecker.checkLatest();
|
|
|
|
|
|
|
|
|
|
// 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() &&
|
2024-07-16 08:30:35 +00:00
|
|
|
appConfig().processMode() == ProcessMode::kDesktop) {
|
2024-07-02 19:07:06 +00:00
|
|
|
startSynergy();
|
|
|
|
|
}
|
2012-07-13 14:38:58 +00:00
|
|
|
}
|
|
|
|
|
|
2024-07-02 19:07:06 +00:00
|
|
|
void MainWindow::setStatus(const QString &status) {
|
|
|
|
|
m_pStatusLabel->setText(status);
|
2012-06-10 16:50:54 +00:00
|
|
|
}
|
|
|
|
|
|
2024-07-02 19:07:06 +00:00
|
|
|
void MainWindow::createMenuBar() {
|
|
|
|
|
m_pMenuBar = new QMenuBar(this);
|
2024-07-08 14:37:51 +00:00
|
|
|
m_pMenuFile = new QMenu("File", m_pMenuBar);
|
|
|
|
|
m_pMenuEdit = new QMenu("Edit", m_pMenuBar);
|
|
|
|
|
m_pMenuWindow = new QMenu("Window", m_pMenuBar);
|
|
|
|
|
m_pMenuHelp = new QMenu("Help", m_pMenuBar);
|
2012-06-10 16:50:54 +00:00
|
|
|
|
2024-07-02 19:07:06 +00:00
|
|
|
m_pMenuBar->addAction(m_pMenuFile->menuAction());
|
|
|
|
|
m_pMenuBar->addAction(m_pMenuEdit->menuAction());
|
2012-06-10 16:50:54 +00:00
|
|
|
#if !defined(Q_OS_MAC)
|
2024-07-02 19:07:06 +00:00
|
|
|
m_pMenuBar->addAction(m_pMenuWindow->menuAction());
|
2012-06-10 16:50:54 +00:00
|
|
|
#endif
|
2024-07-02 19:07:06 +00:00
|
|
|
m_pMenuBar->addAction(m_pMenuHelp->menuAction());
|
2020-03-03 22:38:57 +00:00
|
|
|
|
2024-07-02 19:07:06 +00:00
|
|
|
m_pMenuFile->addAction(m_pActionStartSynergy);
|
|
|
|
|
m_pMenuFile->addAction(m_pActionStopSynergy);
|
|
|
|
|
m_pMenuFile->addSeparator();
|
|
|
|
|
m_pMenuFile->addAction(m_pActivate);
|
|
|
|
|
m_pMenuFile->addSeparator();
|
|
|
|
|
m_pMenuFile->addAction(m_pActionSave);
|
|
|
|
|
m_pMenuFile->addSeparator();
|
|
|
|
|
m_pMenuFile->addAction(m_pActionQuit);
|
|
|
|
|
m_pMenuEdit->addAction(m_pActionSettings);
|
|
|
|
|
m_pMenuWindow->addAction(m_pActionMinimize);
|
|
|
|
|
m_pMenuWindow->addAction(m_pActionRestore);
|
|
|
|
|
m_pMenuHelp->addAction(m_pActionAbout);
|
|
|
|
|
m_pMenuHelp->addAction(m_pActionHelp);
|
2012-06-10 16:50:54 +00:00
|
|
|
|
2024-07-02 19:07:06 +00:00
|
|
|
setMenuBar(m_pMenuBar);
|
2012-06-10 16:50:54 +00:00
|
|
|
}
|
|
|
|
|
|
2024-07-02 19:07:06 +00:00
|
|
|
void MainWindow::loadSettings() {
|
|
|
|
|
enableServer(appConfig().getServerGroupChecked());
|
|
|
|
|
enableClient(appConfig().getClientGroupChecked());
|
2012-06-10 16:50:54 +00:00
|
|
|
|
2024-07-02 19:07:06 +00:00
|
|
|
m_pLineEditHostname->setText(appConfig().getServerHostname());
|
|
|
|
|
m_pLineEditClienIp->setText(serverConfig().getClientAddress());
|
2012-06-10 16:50:54 +00:00
|
|
|
}
|
|
|
|
|
|
2024-07-02 19:07:06 +00:00
|
|
|
void MainWindow::initConnections() {
|
|
|
|
|
connect(m_pActionMinimize, SIGNAL(triggered()), this, SLOT(hide()));
|
|
|
|
|
connect(m_pActionRestore, SIGNAL(triggered()), this, SLOT(showNormal()));
|
2024-07-16 13:36:44 +00:00
|
|
|
connect(
|
|
|
|
|
m_pActionStartSynergy, SIGNAL(triggered()), this, SLOT(actionStart()));
|
2024-07-02 19:07:06 +00:00
|
|
|
connect(m_pActionStopSynergy, SIGNAL(triggered()), this, SLOT(stopSynergy()));
|
|
|
|
|
connect(m_pActionQuit, SIGNAL(triggered()), qApp, SLOT(quit()));
|
2024-07-16 13:36:44 +00:00
|
|
|
connect(
|
|
|
|
|
&m_VersionChecker, SIGNAL(updateFound(const QString &)), this,
|
|
|
|
|
SLOT(updateFound(const QString &)));
|
2012-06-10 16:50:54 +00:00
|
|
|
}
|
|
|
|
|
|
2024-07-02 19:07:06 +00:00
|
|
|
void MainWindow::saveSettings() {
|
|
|
|
|
// program settings
|
|
|
|
|
appConfig().setServerGroupChecked(m_pRadioGroupServer->isChecked());
|
|
|
|
|
appConfig().setClientGroupChecked(m_pRadioGroupClient->isChecked());
|
|
|
|
|
appConfig().setServerHostname(m_pLineEditHostname->text());
|
|
|
|
|
serverConfig().setClientAddress(m_pLineEditClienIp->text());
|
2020-03-31 10:09:50 +00:00
|
|
|
|
2024-07-02 19:07:06 +00:00
|
|
|
/* Save everything */
|
|
|
|
|
GUI::Config::ConfigWriter::make()->globalSave();
|
2012-06-10 16:50:54 +00:00
|
|
|
}
|
|
|
|
|
|
2024-07-02 19:07:06 +00:00
|
|
|
void MainWindow::setIcon(qSynergyState state) const {
|
|
|
|
|
QIcon icon;
|
2015-08-09 01:16:50 +00:00
|
|
|
|
|
|
|
|
#ifdef Q_OS_MAC
|
2024-07-02 19:07:06 +00:00
|
|
|
switch (getOSXIconsTheme()) {
|
|
|
|
|
case IconsTheme::ICONS_DARK:
|
|
|
|
|
icon.addFile(synergyDarkIconFiles[state]);
|
|
|
|
|
break;
|
|
|
|
|
case IconsTheme::ICONS_LIGHT:
|
|
|
|
|
icon.addFile(synergyLightIconFiles[state]);
|
|
|
|
|
break;
|
|
|
|
|
case IconsTheme::ICONS_TEMPLATE:
|
|
|
|
|
default:
|
|
|
|
|
icon.addFile(synergyDarkIconFiles[state]);
|
|
|
|
|
icon.setIsMask(true);
|
|
|
|
|
break;
|
|
|
|
|
}
|
2015-08-09 01:16:50 +00:00
|
|
|
#else
|
2024-07-02 19:07:06 +00:00
|
|
|
icon.addFile(synergyDefaultIconFiles[state]);
|
2015-08-09 01:16:50 +00:00
|
|
|
#endif
|
2012-06-10 16:50:54 +00:00
|
|
|
|
2024-07-02 19:07:06 +00:00
|
|
|
m_trayIcon.set(icon);
|
2012-06-10 16:50:54 +00:00
|
|
|
}
|
|
|
|
|
|
2024-07-02 19:07:06 +00:00
|
|
|
void MainWindow::trayActivated(QSystemTrayIcon::ActivationReason reason) {
|
|
|
|
|
if (reason == QSystemTrayIcon::DoubleClick) {
|
|
|
|
|
if (isVisible()) {
|
|
|
|
|
hide();
|
|
|
|
|
} else {
|
|
|
|
|
showNormal();
|
|
|
|
|
activateWindow();
|
2016-12-28 11:50:32 +00:00
|
|
|
}
|
2024-07-02 19:07:06 +00:00
|
|
|
}
|
2012-06-10 16:50:54 +00:00
|
|
|
}
|
|
|
|
|
|
2024-07-02 19:07:06 +00:00
|
|
|
void MainWindow::logOutput() {
|
|
|
|
|
if (m_pSynergy) {
|
|
|
|
|
QString text(m_pSynergy->readAllStandardOutput());
|
2024-07-08 14:37:51 +00:00
|
|
|
for (QString line : text.split(QRegularExpression("\r|\n|\r\n"))) {
|
2024-07-02 19:07:06 +00:00
|
|
|
if (!line.isEmpty()) {
|
|
|
|
|
appendLogRaw(line);
|
|
|
|
|
}
|
2016-12-28 11:50:32 +00:00
|
|
|
}
|
2024-07-02 19:07:06 +00:00
|
|
|
}
|
2012-06-10 16:50:54 +00:00
|
|
|
}
|
|
|
|
|
|
2024-07-02 19:07:06 +00:00
|
|
|
void MainWindow::logError() {
|
|
|
|
|
if (m_pSynergy) {
|
|
|
|
|
appendLogRaw(m_pSynergy->readAllStandardError());
|
|
|
|
|
}
|
2012-06-10 16:50:54 +00:00
|
|
|
}
|
|
|
|
|
|
2024-07-02 19:07:06 +00:00
|
|
|
void MainWindow::updateFound(const QString &version) {
|
|
|
|
|
m_pWidgetUpdate->show();
|
|
|
|
|
m_pLabelUpdate->setText(tr("<p>Your version of Synergy is out of date. "
|
|
|
|
|
"Version <b>%1</b> is now available to "
|
|
|
|
|
"<a href=\"%2\">download</a>.</p>")
|
|
|
|
|
.arg(version)
|
|
|
|
|
.arg(DOWNLOAD_URL));
|
2012-07-04 23:27:03 +00:00
|
|
|
}
|
|
|
|
|
|
2024-07-02 19:07:06 +00:00
|
|
|
void MainWindow::appendLogInfo(const QString &text) {
|
|
|
|
|
appendLogRaw(getTimeStamp() + " INFO: " + text);
|
2014-11-27 10:36:43 +00:00
|
|
|
}
|
|
|
|
|
|
2024-07-02 19:07:06 +00:00
|
|
|
void MainWindow::appendLogDebug(const QString &text) {
|
|
|
|
|
if (appConfig().logLevel() >= debugLogLevel) {
|
|
|
|
|
appendLogRaw(getTimeStamp() + " DEBUG: " + text);
|
|
|
|
|
}
|
2012-07-04 23:27:03 +00:00
|
|
|
}
|
|
|
|
|
|
2024-07-02 19:07:06 +00:00
|
|
|
void MainWindow::appendLogError(const QString &text) {
|
|
|
|
|
appendLogRaw(getTimeStamp() + " ERROR: " + text);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void MainWindow::appendLogRaw(const QString &text) {
|
2024-07-08 14:37:51 +00:00
|
|
|
foreach (QString line, text.split(QRegularExpression("\r|\n|\r\n"))) {
|
2024-07-02 19:07:06 +00:00
|
|
|
if (!line.isEmpty()) {
|
2018-07-04 17:05:10 +00:00
|
|
|
|
2024-07-02 19:07:06 +00:00
|
|
|
// HACK: macOS 10.13.4+ spamming error lines in logs making them
|
|
|
|
|
// impossible to read and debug; giving users a red herring.
|
|
|
|
|
if (line.contains("calling TIS/TSM in non-main thread environment")) {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
2018-07-04 17:05:10 +00:00
|
|
|
|
2024-07-02 19:07:06 +00:00
|
|
|
m_pLogOutput->appendPlainText(line);
|
|
|
|
|
updateFromLogLine(line);
|
2016-12-28 11:50:32 +00:00
|
|
|
}
|
2024-07-02 19:07:06 +00:00
|
|
|
}
|
2012-07-28 18:54:50 +00:00
|
|
|
}
|
|
|
|
|
|
2024-07-02 19:07:06 +00:00
|
|
|
void MainWindow::handleIdleService(const QString &text) {
|
2024-07-08 14:37:51 +00:00
|
|
|
foreach (QString line, text.split(QRegularExpression("\r|\n|\r\n"))) {
|
2024-07-02 19:07:06 +00:00
|
|
|
// only start if there is no active service running
|
|
|
|
|
if (!line.isEmpty() && line.contains("service status: idle") &&
|
|
|
|
|
appConfig().startedBefore()) {
|
|
|
|
|
startSynergy();
|
2021-05-27 08:05:53 +00:00
|
|
|
}
|
2024-07-02 19:07:06 +00:00
|
|
|
}
|
2021-05-27 08:05:53 +00:00
|
|
|
}
|
|
|
|
|
|
2024-07-02 19:07:06 +00:00
|
|
|
void MainWindow::updateFromLogLine(const QString &line) {
|
|
|
|
|
// TODO: This shouldn't be updating from log needs a better way of doing this
|
|
|
|
|
checkConnected(line);
|
|
|
|
|
checkFingerprint(line);
|
|
|
|
|
checkSecureSocket(line);
|
2018-07-28 00:52:56 +00:00
|
|
|
|
2024-07-02 19:07:06 +00:00
|
|
|
// subprocess (synergys, synergyc) is not allowed to show notifications
|
|
|
|
|
// process the log from it and show notificatino from synergy instead
|
2021-06-29 10:20:56 +00:00
|
|
|
#ifdef Q_OS_MAC
|
2024-07-02 19:07:06 +00:00
|
|
|
checkOSXNotification(line);
|
2021-06-29 10:20:56 +00:00
|
|
|
#endif
|
|
|
|
|
|
2024-07-04 09:14:54 +00:00
|
|
|
#ifdef SYNERGY_ENABLE_LICENSING
|
2024-07-02 19:07:06 +00:00
|
|
|
checkLicense(line);
|
2018-06-07 15:22:49 +00:00
|
|
|
#endif
|
2015-06-01 18:57:43 +00:00
|
|
|
}
|
|
|
|
|
|
2024-07-02 19:07:06 +00:00
|
|
|
void MainWindow::checkConnected(const QString &line) {
|
|
|
|
|
// TODO: implement ipc connection state messages to replace this hack.
|
|
|
|
|
if (m_pRadioGroupServer->isChecked()) {
|
|
|
|
|
m_serverConnection.update(line);
|
|
|
|
|
m_pLabelServerState->updateServerState(line);
|
|
|
|
|
} else {
|
|
|
|
|
m_clientConnection.update(line);
|
|
|
|
|
m_pLabelClientState->updateClientState(line);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (line.contains("connected to server") || line.contains("has connected")) {
|
|
|
|
|
setSynergyState(synergyConnected);
|
|
|
|
|
|
|
|
|
|
if (!appConfig().startedBefore() && isVisible()) {
|
|
|
|
|
QMessageBox::information(
|
|
|
|
|
this, "Synergy",
|
|
|
|
|
tr("Synergy is now connected. You can close the "
|
|
|
|
|
"config window and Synergy will remain connected in "
|
|
|
|
|
"the background."));
|
|
|
|
|
|
|
|
|
|
appConfig().setStartedBefore(true);
|
|
|
|
|
}
|
|
|
|
|
} else if (line.contains("started server")) {
|
|
|
|
|
setSynergyState(synergyListening);
|
2024-07-16 13:36:44 +00:00
|
|
|
} else if (
|
|
|
|
|
line.contains("disconnected from server") ||
|
|
|
|
|
line.contains("process exited")) {
|
2024-07-02 19:07:06 +00:00
|
|
|
setSynergyState(synergyDisconnected);
|
|
|
|
|
} else if (line.contains("connecting to")) {
|
|
|
|
|
setSynergyState(synergyConnecting);
|
|
|
|
|
}
|
2015-04-15 12:09:22 +00:00
|
|
|
}
|
|
|
|
|
|
2024-07-04 09:14:54 +00:00
|
|
|
#ifdef SYNERGY_ENABLE_LICENSING
|
2024-07-02 19:07:06 +00:00
|
|
|
void MainWindow::checkLicense(const QString &line) {
|
|
|
|
|
if (line.contains("trial has expired")) {
|
|
|
|
|
licenseManager().refresh();
|
|
|
|
|
raiseActivationDialog();
|
|
|
|
|
}
|
2016-10-17 16:49:14 +00:00
|
|
|
}
|
2018-06-07 15:22:49 +00:00
|
|
|
#endif
|
2016-10-17 16:49:14 +00:00
|
|
|
|
2024-07-02 19:07:06 +00:00
|
|
|
void MainWindow::checkFingerprint(const QString &line) {
|
2024-07-08 14:37:51 +00:00
|
|
|
QRegularExpression re(".*server fingerprint: ([A-F0-9:]+)");
|
|
|
|
|
auto match = re.match(line);
|
|
|
|
|
if (!match.hasMatch()) {
|
2024-07-02 19:07:06 +00:00
|
|
|
return;
|
|
|
|
|
}
|
2016-12-28 11:50:32 +00:00
|
|
|
|
2024-07-08 14:37:51 +00:00
|
|
|
auto fingerprint = match.captured(1);
|
2024-07-02 19:07:06 +00:00
|
|
|
if (Fingerprint::trustedServers().isTrusted(fingerprint)) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
2016-12-28 11:50:32 +00:00
|
|
|
|
2024-07-02 19:07:06 +00:00
|
|
|
static bool messageBoxAlreadyShown = false;
|
2016-12-28 11:50:32 +00:00
|
|
|
|
2024-07-02 19:07:06 +00:00
|
|
|
if (!messageBoxAlreadyShown) {
|
|
|
|
|
stopSynergy();
|
2016-12-28 11:50:32 +00:00
|
|
|
|
2024-07-02 19:07:06 +00:00
|
|
|
messageBoxAlreadyShown = true;
|
|
|
|
|
QMessageBox::StandardButton fingerprintReply = QMessageBox::information(
|
|
|
|
|
this, tr("Security question"),
|
|
|
|
|
tr("You are connecting to a server. Here is it's fingerprint:\n\n"
|
|
|
|
|
"%1\n\n"
|
|
|
|
|
"Compare this fingerprint to the one on your server's screen."
|
|
|
|
|
"If the two don't match exactly, then it's probably not the server "
|
|
|
|
|
"you're expecting (it could be a malicious user).\n\n"
|
|
|
|
|
"To automatically trust this fingerprint for future "
|
|
|
|
|
"connections, click Yes. To reject this fingerprint and "
|
|
|
|
|
"disconnect from the server, click No.")
|
|
|
|
|
.arg(fingerprint),
|
|
|
|
|
QMessageBox::Yes | QMessageBox::No);
|
|
|
|
|
|
|
|
|
|
if (fingerprintReply == QMessageBox::Yes) {
|
|
|
|
|
// restart core process after trusting fingerprint.
|
|
|
|
|
Fingerprint::trustedServers().trust(fingerprint);
|
|
|
|
|
startSynergy();
|
2016-12-28 11:50:32 +00:00
|
|
|
}
|
2024-07-02 19:07:06 +00:00
|
|
|
|
|
|
|
|
messageBoxAlreadyShown = false;
|
|
|
|
|
}
|
2012-06-10 16:50:54 +00:00
|
|
|
}
|
|
|
|
|
|
2024-07-16 08:30:35 +00:00
|
|
|
bool MainWindow::checkSecureSocket(const QString &line) {
|
|
|
|
|
static const QString tlsCheckString = "network encryption protocol: ";
|
|
|
|
|
const auto index = line.indexOf(tlsCheckString, 0, Qt::CaseInsensitive);
|
|
|
|
|
if (index == -1) {
|
|
|
|
|
return false;
|
2024-07-02 19:07:06 +00:00
|
|
|
}
|
2024-07-16 08:30:35 +00:00
|
|
|
|
|
|
|
|
secureSocket(true);
|
|
|
|
|
m_SecureSocketVersion = line.mid(index + tlsCheckString.size());
|
|
|
|
|
return true;
|
2018-07-28 00:52:56 +00:00
|
|
|
}
|
2021-06-29 10:20:56 +00:00
|
|
|
|
|
|
|
|
#ifdef Q_OS_MAC
|
2024-07-02 19:07:06 +00:00
|
|
|
void MainWindow::checkOSXNotification(const QString &line) {
|
|
|
|
|
static const QString OSXNotificationSubstring = "OSX Notification: ";
|
|
|
|
|
if (line.contains(OSXNotificationSubstring) && line.contains('|')) {
|
|
|
|
|
int delimterPosition = line.indexOf('|');
|
|
|
|
|
int notificationStartPosition = line.indexOf(OSXNotificationSubstring);
|
2024-07-16 13:36:44 +00:00
|
|
|
QString title = line.mid(
|
|
|
|
|
notificationStartPosition + OSXNotificationSubstring.length(),
|
|
|
|
|
delimterPosition - notificationStartPosition -
|
|
|
|
|
OSXNotificationSubstring.length());
|
2024-07-02 19:07:06 +00:00
|
|
|
QString body =
|
|
|
|
|
line.mid(delimterPosition + 1, line.length() - delimterPosition);
|
|
|
|
|
if (!showOSXNotification(title, body)) {
|
|
|
|
|
appendLogInfo("OSX notification was not shown");
|
|
|
|
|
}
|
|
|
|
|
}
|
2021-06-29 10:20:56 +00:00
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
2024-07-02 19:07:06 +00:00
|
|
|
QString MainWindow::getTimeStamp() {
|
|
|
|
|
QDateTime current = QDateTime::currentDateTime();
|
|
|
|
|
return '[' + current.toString(Qt::ISODate) + ']';
|
2015-07-06 22:50:21 +00:00
|
|
|
}
|
|
|
|
|
|
2024-07-02 19:07:06 +00:00
|
|
|
void MainWindow::restartSynergy() {
|
|
|
|
|
stopSynergy();
|
|
|
|
|
startSynergy();
|
2015-07-30 22:52:14 +00:00
|
|
|
}
|
|
|
|
|
|
2024-07-02 19:07:06 +00:00
|
|
|
void MainWindow::showEvent(QShowEvent *event) {
|
|
|
|
|
QMainWindow::showEvent(event);
|
|
|
|
|
emit windowShown();
|
2016-10-04 10:48:47 +00:00
|
|
|
}
|
|
|
|
|
|
2024-07-02 19:07:06 +00:00
|
|
|
void MainWindow::clearLog() { m_pLogOutput->clear(); }
|
2012-06-10 16:50:54 +00:00
|
|
|
|
2024-07-02 19:07:06 +00:00
|
|
|
void MainWindow::startSynergy() {
|
|
|
|
|
saveSettings();
|
2021-03-01 13:23:27 +00:00
|
|
|
|
2021-06-29 10:20:56 +00:00
|
|
|
#ifdef Q_OS_MAC
|
2024-07-02 19:07:06 +00:00
|
|
|
requestOSXNotificationPermission();
|
2021-06-29 10:20:56 +00:00
|
|
|
#endif
|
|
|
|
|
|
2024-07-04 09:14:54 +00:00
|
|
|
#ifdef SYNERGY_ENABLE_LICENSING
|
2024-07-02 19:07:06 +00:00
|
|
|
SerialKey serialKey = m_LicenseManager->serialKey();
|
|
|
|
|
if (!serialKey.isValid()) {
|
|
|
|
|
if (QDialog::Rejected == raiseActivationDialog()) {
|
|
|
|
|
return;
|
2016-12-28 11:50:32 +00:00
|
|
|
}
|
2024-07-02 19:07:06 +00:00
|
|
|
}
|
|
|
|
|
m_LicenseManager->registerLicense();
|
2018-06-07 15:22:49 +00:00
|
|
|
#endif
|
2024-07-16 08:30:35 +00:00
|
|
|
bool desktopMode = appConfig().processMode() == ProcessMode::kDesktop;
|
|
|
|
|
bool serviceMode = appConfig().processMode() == ProcessMode::kService;
|
2012-07-28 22:58:51 +00:00
|
|
|
|
2024-07-02 19:07:06 +00:00
|
|
|
appendLogDebug("starting process");
|
|
|
|
|
m_ExpectedRunningState = kStarted;
|
|
|
|
|
setSynergyState(synergyConnecting);
|
2012-06-10 16:50:54 +00:00
|
|
|
|
2024-07-02 19:07:06 +00:00
|
|
|
QString app;
|
|
|
|
|
QStringList args;
|
2012-06-10 16:50:54 +00:00
|
|
|
|
2024-07-02 19:07:06 +00:00
|
|
|
args << "-f"
|
|
|
|
|
<< "--no-tray"
|
|
|
|
|
<< "--debug" << appConfig().logLevelText();
|
2012-06-10 16:50:54 +00:00
|
|
|
|
2024-07-02 19:07:06 +00:00
|
|
|
args << "--name" << appConfig().screenName();
|
2014-08-21 17:32:40 +00:00
|
|
|
|
2024-07-02 19:07:06 +00:00
|
|
|
if (desktopMode) {
|
|
|
|
|
setSynergyProcess(new QProcess(this));
|
|
|
|
|
} else {
|
|
|
|
|
// tell client/server to talk to daemon through ipc.
|
|
|
|
|
args << "--ipc";
|
2012-07-28 13:34:35 +00:00
|
|
|
|
|
|
|
|
#if defined(Q_OS_WIN)
|
2024-07-02 19:07:06 +00:00
|
|
|
// tell the client/server to shut down when a ms windows desk
|
|
|
|
|
// is switched; this is because we may need to elevate or not
|
|
|
|
|
// based on which desk the user is in (login always needs
|
|
|
|
|
// elevation, where as default desk does not).
|
|
|
|
|
// Note that this is only enabled when synergy is set to elevate
|
|
|
|
|
// 'as needed' (e.g. on a UAC dialog popup) in order to prevent
|
|
|
|
|
// unnecessary restarts when synergy was started elevated or
|
|
|
|
|
// when it is not allowed to elevate. In these cases restarting
|
|
|
|
|
// the server is fruitless.
|
|
|
|
|
if (appConfig().elevateMode() == ElevateAsNeeded) {
|
|
|
|
|
args << "--stop-on-desk-switch";
|
2016-12-28 11:50:32 +00:00
|
|
|
}
|
2024-07-02 19:07:06 +00:00
|
|
|
#endif
|
|
|
|
|
}
|
2012-06-10 16:50:54 +00:00
|
|
|
|
2013-10-22 18:10:14 +00:00
|
|
|
#ifndef Q_OS_LINUX
|
2014-10-14 16:20:57 +00:00
|
|
|
|
2024-07-02 19:07:06 +00:00
|
|
|
if (m_ServerConfig.enableDragAndDrop()) {
|
|
|
|
|
args << "--enable-drag-drop";
|
|
|
|
|
}
|
2014-10-14 16:20:57 +00:00
|
|
|
|
2013-10-22 18:10:14 +00:00
|
|
|
#endif
|
2013-09-18 08:34:32 +00:00
|
|
|
|
2020-11-06 13:16:56 +00:00
|
|
|
#if defined(Q_OS_WIN)
|
2024-07-02 19:07:06 +00:00
|
|
|
if (m_AppConfig->getCryptoEnabled()) {
|
|
|
|
|
args << "--enable-crypto";
|
|
|
|
|
args << "--tls-cert"
|
|
|
|
|
<< QString("\"%1\"").arg(m_AppConfig->getTLSCertPath());
|
|
|
|
|
}
|
|
|
|
|
// on windows, the profile directory changes depending on the user that
|
|
|
|
|
// launched the process (e.g. when launched with elevation). setting the
|
|
|
|
|
// profile dir on launch ensures it uses the same profile dir is used
|
|
|
|
|
// no matter how its relaunched.
|
|
|
|
|
args << "--profile-dir" << getProfileRootForArg();
|
2020-11-06 13:16:56 +00:00
|
|
|
|
|
|
|
|
#else
|
2024-07-02 19:07:06 +00:00
|
|
|
if (m_AppConfig->getCryptoEnabled()) {
|
|
|
|
|
args << "--enable-crypto";
|
|
|
|
|
args << "--tls-cert" << m_AppConfig->getTLSCertPath();
|
|
|
|
|
}
|
2015-03-04 11:51:56 +00:00
|
|
|
#endif
|
2015-03-04 11:15:07 +00:00
|
|
|
|
2024-07-02 19:07:06 +00:00
|
|
|
if (m_AppConfig->getPreventSleep()) {
|
|
|
|
|
args << "--prevent-sleep";
|
|
|
|
|
}
|
2021-04-19 11:59:18 +00:00
|
|
|
|
2024-07-02 19:07:06 +00:00
|
|
|
// put a space between last log output and new instance.
|
|
|
|
|
if (!m_pLogOutput->toPlainText().isEmpty())
|
|
|
|
|
appendLogRaw("");
|
2016-12-28 11:50:32 +00:00
|
|
|
|
2024-07-16 13:36:44 +00:00
|
|
|
appendLogInfo(
|
|
|
|
|
"starting " +
|
|
|
|
|
QString(synergyType() == synergyServer ? "server" : "client"));
|
2016-12-28 11:50:32 +00:00
|
|
|
|
2024-07-02 19:07:06 +00:00
|
|
|
if ((synergyType() == synergyClient && !clientArgs(args, app)) ||
|
|
|
|
|
(synergyType() == synergyServer && !serverArgs(args, app))) {
|
|
|
|
|
stopSynergy();
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (desktopMode) {
|
2024-07-16 13:36:44 +00:00
|
|
|
connect(
|
|
|
|
|
synergyProcess(), SIGNAL(finished(int, QProcess::ExitStatus)), this,
|
|
|
|
|
SLOT(synergyFinished(int, QProcess::ExitStatus)));
|
|
|
|
|
connect(
|
|
|
|
|
synergyProcess(), SIGNAL(readyReadStandardOutput()), this,
|
|
|
|
|
SLOT(logOutput()));
|
|
|
|
|
connect(
|
|
|
|
|
synergyProcess(), SIGNAL(readyReadStandardError()), this,
|
|
|
|
|
SLOT(logError()));
|
2024-07-02 19:07:06 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
qDebug() << args;
|
|
|
|
|
|
|
|
|
|
// show command if debug log level...
|
|
|
|
|
if (appConfig().logLevel() >= 4) {
|
|
|
|
|
appendLogInfo(QString("command: %1 %2").arg(app, args.join(" ")));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
appendLogInfo("log level: " + appConfig().logLevelText());
|
|
|
|
|
|
|
|
|
|
if (appConfig().logToFile())
|
|
|
|
|
appendLogInfo("log file: " + appConfig().logFilename());
|
|
|
|
|
|
|
|
|
|
if (desktopMode) {
|
|
|
|
|
synergyProcess()->start(app, args);
|
|
|
|
|
if (!synergyProcess()->waitForStarted()) {
|
|
|
|
|
show();
|
|
|
|
|
QMessageBox::warning(
|
|
|
|
|
this, tr("Program can not be started"),
|
|
|
|
|
QString(
|
|
|
|
|
tr("The executable<br><br>%1<br><br>could not be successfully "
|
|
|
|
|
"started, although it does exist. Please check if you have "
|
|
|
|
|
"sufficient permissions to run this program.")
|
|
|
|
|
.arg(app)));
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (serviceMode) {
|
|
|
|
|
QString command(app + " " + args.join(" "));
|
|
|
|
|
m_IpcClient.sendCommand(command, appConfig().elevateMode());
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void MainWindow::actionStart() {
|
|
|
|
|
m_clientConnection.setCheckConnection(true);
|
|
|
|
|
startSynergy();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void MainWindow::retryStart() {
|
|
|
|
|
// This function is only called after a failed start
|
|
|
|
|
// Only start synergy if the current state is pending retry
|
|
|
|
|
if (m_SynergyState == synergyPendingRetry) {
|
2021-04-28 12:34:04 +00:00
|
|
|
startSynergy();
|
2024-07-02 19:07:06 +00:00
|
|
|
}
|
2021-04-28 12:34:04 +00:00
|
|
|
}
|
|
|
|
|
|
2024-07-02 19:07:06 +00:00
|
|
|
bool MainWindow::clientArgs(QStringList &args, QString &app) {
|
|
|
|
|
app = appPath(appConfig().synergycName());
|
2012-06-10 16:50:54 +00:00
|
|
|
|
2024-07-02 19:07:06 +00:00
|
|
|
if (!QFile::exists(app)) {
|
|
|
|
|
show();
|
|
|
|
|
QMessageBox::warning(
|
|
|
|
|
this, tr("Synergy client not found"),
|
|
|
|
|
tr("The executable for the synergy client does not exist."));
|
|
|
|
|
return false;
|
|
|
|
|
}
|
2012-06-10 16:50:54 +00:00
|
|
|
|
2013-10-16 17:20:32 +00:00
|
|
|
#if defined(Q_OS_WIN)
|
2024-07-02 19:07:06 +00:00
|
|
|
// wrap in quotes so a malicious user can't start \Program.exe as admin.
|
|
|
|
|
app = QString("\"%1\"").arg(app);
|
2013-10-16 16:52:30 +00:00
|
|
|
#endif
|
2013-10-03 14:24:58 +00:00
|
|
|
|
2024-07-02 19:07:06 +00:00
|
|
|
if (appConfig().logToFile()) {
|
|
|
|
|
appConfig().persistLogDir();
|
|
|
|
|
args << "--log" << appConfig().logFilenameCmd();
|
|
|
|
|
}
|
2012-06-10 16:50:54 +00:00
|
|
|
|
2024-07-02 19:07:06 +00:00
|
|
|
if (appConfig().getLanguageSync()) {
|
|
|
|
|
args << "--sync-language";
|
|
|
|
|
}
|
2021-10-04 15:51:12 +00:00
|
|
|
|
2024-07-02 19:07:06 +00:00
|
|
|
if (appConfig().getInvertScrollDirection()) {
|
|
|
|
|
args << "--invert-scroll";
|
|
|
|
|
}
|
2021-05-13 06:30:24 +00:00
|
|
|
|
2024-07-02 19:07:06 +00:00
|
|
|
if (m_pLineEditHostname->text().isEmpty() &&
|
|
|
|
|
!appConfig().getClientHostMode()) {
|
2024-07-08 14:37:51 +00:00
|
|
|
show();
|
2024-07-16 13:36:44 +00:00
|
|
|
QMessageBox::warning(
|
|
|
|
|
this, tr("Hostname is empty"),
|
|
|
|
|
tr("Please fill in a hostname for the synergy "
|
|
|
|
|
"client to connect to."));
|
2024-07-08 14:37:51 +00:00
|
|
|
return false;
|
2024-07-02 19:07:06 +00:00
|
|
|
}
|
2021-05-19 11:08:24 +00:00
|
|
|
|
2024-07-02 19:07:06 +00:00
|
|
|
if (appConfig().getClientHostMode()) {
|
|
|
|
|
args << "--host";
|
|
|
|
|
args << ":" + QString::number(appConfig().port());
|
|
|
|
|
} else {
|
|
|
|
|
QString hostName = m_pLineEditHostname->text();
|
|
|
|
|
// if interface is IPv6 - ensure that ip is in square brackets
|
|
|
|
|
if (hostName.count(':') > 1) {
|
|
|
|
|
if (hostName[0] != '[') {
|
|
|
|
|
hostName.insert(0, '[');
|
|
|
|
|
}
|
|
|
|
|
if (hostName[hostName.size() - 1] != ']') {
|
|
|
|
|
hostName.push_back(']');
|
|
|
|
|
}
|
2021-05-19 11:08:24 +00:00
|
|
|
}
|
2024-07-02 19:07:06 +00:00
|
|
|
args << hostName + ":" + QString::number(appConfig().port());
|
|
|
|
|
}
|
2021-05-19 11:08:24 +00:00
|
|
|
|
2024-07-02 19:07:06 +00:00
|
|
|
return true;
|
2012-06-10 16:50:54 +00:00
|
|
|
}
|
|
|
|
|
|
2024-07-02 19:07:06 +00:00
|
|
|
QString MainWindow::configFilename() {
|
|
|
|
|
QString configFullPath;
|
|
|
|
|
if (appConfig().getUseExternalConfig()) {
|
|
|
|
|
configFullPath = appConfig().getConfigFile();
|
|
|
|
|
} else {
|
|
|
|
|
QStringList errors;
|
|
|
|
|
for (auto path :
|
|
|
|
|
{QStandardPaths::AppDataLocation, QStandardPaths::AppConfigLocation}) {
|
|
|
|
|
auto configDirPath = QStandardPaths::writableLocation(path);
|
|
|
|
|
if (!QDir().mkpath(configDirPath)) {
|
|
|
|
|
errors.push_back(
|
|
|
|
|
tr("Failed to create config folder \"%1\"").arg(configDirPath));
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
QFile configFile(configDirPath + "/LastConfig.cfg");
|
|
|
|
|
if (!configFile.open(QIODevice::WriteOnly | QIODevice::Truncate)) {
|
|
|
|
|
errors.push_back(
|
|
|
|
|
tr("File:\"%1\" Error:%2")
|
|
|
|
|
.arg(configFile.fileName(), configFile.errorString()));
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
serverConfig().save(configFile);
|
|
|
|
|
configFile.close();
|
|
|
|
|
configFullPath = configFile.fileName();
|
|
|
|
|
|
|
|
|
|
break;
|
2016-12-28 11:50:32 +00:00
|
|
|
}
|
2024-07-02 19:07:06 +00:00
|
|
|
|
|
|
|
|
if (configFullPath.isEmpty()) {
|
2024-07-16 13:36:44 +00:00
|
|
|
QMessageBox::critical(
|
|
|
|
|
this, tr("Cannot write configuration file"), errors.join('\n'));
|
2016-12-28 11:50:32 +00:00
|
|
|
}
|
2024-07-02 19:07:06 +00:00
|
|
|
}
|
2021-04-12 09:03:37 +00:00
|
|
|
|
2024-07-02 19:07:06 +00:00
|
|
|
return configFullPath;
|
2012-06-10 16:50:54 +00:00
|
|
|
}
|
|
|
|
|
|
2024-07-02 19:07:06 +00:00
|
|
|
QString MainWindow::address() const {
|
|
|
|
|
QString i = appConfig().networkInterface();
|
|
|
|
|
// if interface is IPv6 - ensure that ip is in square brackets
|
|
|
|
|
if (i.count(':') > 1) {
|
|
|
|
|
if (i[0] != '[') {
|
|
|
|
|
i.insert(0, '[');
|
|
|
|
|
}
|
|
|
|
|
if (i[i.size() - 1] != ']') {
|
|
|
|
|
i.push_back(']');
|
2021-04-26 07:37:34 +00:00
|
|
|
}
|
2024-07-02 19:07:06 +00:00
|
|
|
}
|
|
|
|
|
return (!i.isEmpty() ? i : "") + ":" + QString::number(appConfig().port());
|
2012-06-10 16:50:54 +00:00
|
|
|
}
|
|
|
|
|
|
2024-07-02 19:07:06 +00:00
|
|
|
QString MainWindow::appPath(const QString &name) {
|
|
|
|
|
return appConfig().synergyProgramDir() + name;
|
2012-06-10 16:50:54 +00:00
|
|
|
}
|
|
|
|
|
|
2024-07-02 19:07:06 +00:00
|
|
|
bool MainWindow::serverArgs(QStringList &args, QString &app) {
|
|
|
|
|
app = appPath(appConfig().synergysName());
|
2012-06-10 16:50:54 +00:00
|
|
|
|
2024-07-02 19:07:06 +00:00
|
|
|
if (!QFile::exists(app)) {
|
|
|
|
|
QMessageBox::warning(
|
|
|
|
|
this, tr("Synergy server not found"),
|
|
|
|
|
tr("The executable for the synergy server does not exist."));
|
|
|
|
|
return false;
|
|
|
|
|
}
|
2012-06-10 16:50:54 +00:00
|
|
|
|
2024-07-02 19:07:06 +00:00
|
|
|
if (appConfig().getServerClientMode() &&
|
|
|
|
|
m_pLineEditClienIp->text().isEmpty()) {
|
2024-07-16 13:36:44 +00:00
|
|
|
QMessageBox::warning(
|
|
|
|
|
this, tr("Client IP address or name is empty"),
|
|
|
|
|
tr("Please fill in a client IP address or name."));
|
2024-07-02 19:07:06 +00:00
|
|
|
return false;
|
|
|
|
|
}
|
2022-09-22 08:12:13 +00:00
|
|
|
|
2013-10-16 17:20:32 +00:00
|
|
|
#if defined(Q_OS_WIN)
|
2024-07-02 19:07:06 +00:00
|
|
|
// wrap in quotes so a malicious user can't start \Program.exe as admin.
|
|
|
|
|
app = QString("\"%1\"").arg(app);
|
2013-10-16 16:52:30 +00:00
|
|
|
#endif
|
2013-10-03 14:24:58 +00:00
|
|
|
|
2024-07-02 19:07:06 +00:00
|
|
|
if (appConfig().logToFile()) {
|
|
|
|
|
appConfig().persistLogDir();
|
2014-05-28 11:59:14 +00:00
|
|
|
|
2024-07-02 19:07:06 +00:00
|
|
|
args << "--log" << appConfig().logFilenameCmd();
|
|
|
|
|
}
|
2012-06-10 16:50:54 +00:00
|
|
|
|
2024-07-02 19:07:06 +00:00
|
|
|
QString configFilename = this->configFilename();
|
|
|
|
|
if (configFilename.isEmpty()) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
2014-05-28 12:05:05 +00:00
|
|
|
#if defined(Q_OS_WIN)
|
2024-07-02 19:07:06 +00:00
|
|
|
// wrap in quotes in case username contains spaces.
|
|
|
|
|
configFilename = QString("\"%1\"").arg(configFilename);
|
2014-05-28 12:05:05 +00:00
|
|
|
#endif
|
2024-07-02 19:07:06 +00:00
|
|
|
args << "-c" << configFilename << "--address" << address();
|
|
|
|
|
appendLogInfo("config file: " + configFilename);
|
2012-06-10 16:50:54 +00:00
|
|
|
|
2024-07-04 09:14:54 +00:00
|
|
|
#ifdef SYNERGY_ENABLE_LICENSING
|
2024-07-02 19:07:06 +00:00
|
|
|
if (!appConfig().serialKey().isEmpty()) {
|
|
|
|
|
args << "--serial-key" << appConfig().serialKey();
|
|
|
|
|
}
|
2018-06-07 15:22:49 +00:00
|
|
|
#endif
|
2016-10-18 13:56:48 +00:00
|
|
|
|
2024-07-02 19:07:06 +00:00
|
|
|
return true;
|
2012-06-10 16:50:54 +00:00
|
|
|
}
|
|
|
|
|
|
2024-07-02 19:07:06 +00:00
|
|
|
void MainWindow::stopSynergy() {
|
|
|
|
|
appendLogDebug("stopping process");
|
2015-07-29 21:34:21 +00:00
|
|
|
|
2024-07-02 19:07:06 +00:00
|
|
|
m_ExpectedRunningState = kStopped;
|
2015-07-29 21:34:21 +00:00
|
|
|
|
2024-07-16 08:30:35 +00:00
|
|
|
if (appConfig().processMode() == ProcessMode::kService) {
|
2024-07-02 19:07:06 +00:00
|
|
|
stopService();
|
2024-07-16 08:30:35 +00:00
|
|
|
} else if (appConfig().processMode() == ProcessMode::kDesktop) {
|
2024-07-02 19:07:06 +00:00
|
|
|
stopDesktop();
|
|
|
|
|
}
|
2012-06-10 16:50:54 +00:00
|
|
|
|
2024-07-02 19:07:06 +00:00
|
|
|
setSynergyState(synergyDisconnected);
|
2012-07-28 18:54:50 +00:00
|
|
|
|
2024-07-02 19:07:06 +00:00
|
|
|
// reset so that new connects cause auto-hide.
|
|
|
|
|
m_AlreadyHidden = false;
|
2012-06-10 16:50:54 +00:00
|
|
|
}
|
|
|
|
|
|
2024-07-02 19:07:06 +00:00
|
|
|
void MainWindow::stopService() {
|
|
|
|
|
// send empty command to stop service from laucning anything.
|
|
|
|
|
m_IpcClient.sendCommand("", appConfig().elevateMode());
|
2012-07-28 22:13:14 +00:00
|
|
|
}
|
|
|
|
|
|
2024-07-02 19:07:06 +00:00
|
|
|
void MainWindow::stopDesktop() {
|
|
|
|
|
QMutexLocker locker(&m_StopDesktopMutex);
|
|
|
|
|
if (!synergyProcess()) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
2012-07-28 22:13:14 +00:00
|
|
|
|
2024-07-02 19:07:06 +00:00
|
|
|
appendLogInfo("stopping synergy desktop process");
|
2012-07-28 22:13:14 +00:00
|
|
|
|
2024-07-02 19:07:06 +00:00
|
|
|
if (synergyProcess()->isOpen()) {
|
|
|
|
|
synergyProcess()->close();
|
|
|
|
|
}
|
2012-07-28 22:13:14 +00:00
|
|
|
|
2024-07-02 19:07:06 +00:00
|
|
|
delete synergyProcess();
|
|
|
|
|
setSynergyProcess(NULL);
|
2012-07-28 22:13:14 +00:00
|
|
|
}
|
|
|
|
|
|
2024-07-02 19:07:06 +00:00
|
|
|
void MainWindow::synergyFinished(int exitCode, QProcess::ExitStatus) {
|
|
|
|
|
if (exitCode == 0) {
|
|
|
|
|
appendLogInfo(QString("process exited normally"));
|
|
|
|
|
} else {
|
|
|
|
|
appendLogError(QString("process exited with error code: %1").arg(exitCode));
|
|
|
|
|
}
|
2015-07-29 01:01:39 +00:00
|
|
|
|
2024-07-02 19:07:06 +00:00
|
|
|
if (m_ExpectedRunningState == kStarted) {
|
2019-04-30 12:12:17 +00:00
|
|
|
|
2024-07-02 19:07:06 +00:00
|
|
|
setSynergyState(synergyPendingRetry);
|
|
|
|
|
QTimer::singleShot(1000, this, SLOT(retryStart()));
|
|
|
|
|
appendLogInfo(QString("detected process not running, auto restarting"));
|
|
|
|
|
} else {
|
|
|
|
|
setSynergyState(synergyDisconnected);
|
|
|
|
|
}
|
2012-06-10 16:50:54 +00:00
|
|
|
}
|
|
|
|
|
|
2024-07-02 19:07:06 +00:00
|
|
|
void MainWindow::setSynergyState(qSynergyState state) {
|
|
|
|
|
// always assume connection is not secure when connection changes
|
|
|
|
|
// to anything except connected. the only way the padlock shows is
|
|
|
|
|
// when the correct TLS version string is detected.
|
|
|
|
|
if (state != synergyConnected) {
|
|
|
|
|
secureSocket(false);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (synergyState() == state)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
if ((state == synergyConnected) || (state == synergyConnecting) ||
|
|
|
|
|
(state == synergyListening) || (state == synergyPendingRetry)) {
|
2024-07-16 13:36:44 +00:00
|
|
|
disconnect(
|
|
|
|
|
m_pButtonToggleStart, SIGNAL(clicked()), m_pActionStartSynergy,
|
|
|
|
|
SLOT(trigger()));
|
|
|
|
|
connect(
|
|
|
|
|
m_pButtonToggleStart, SIGNAL(clicked()), m_pActionStopSynergy,
|
|
|
|
|
SLOT(trigger()));
|
2024-07-02 19:07:06 +00:00
|
|
|
m_pButtonToggleStart->setText(tr("&Stop"));
|
|
|
|
|
m_pButtonApply->setEnabled(true);
|
|
|
|
|
} else if (state == synergyDisconnected) {
|
2024-07-16 13:36:44 +00:00
|
|
|
disconnect(
|
|
|
|
|
m_pButtonToggleStart, SIGNAL(clicked()), m_pActionStopSynergy,
|
|
|
|
|
SLOT(trigger()));
|
|
|
|
|
connect(
|
|
|
|
|
m_pButtonToggleStart, SIGNAL(clicked()), m_pActionStartSynergy,
|
|
|
|
|
SLOT(trigger()));
|
2024-07-02 19:07:06 +00:00
|
|
|
m_pButtonToggleStart->setText(tr("&Start"));
|
|
|
|
|
m_pButtonApply->setEnabled(false);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool running = false;
|
|
|
|
|
if (state == synergyConnected || state == synergyListening) {
|
|
|
|
|
running = true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
m_pActionStartSynergy->setEnabled(!running);
|
|
|
|
|
m_pActionStopSynergy->setEnabled(running);
|
|
|
|
|
|
|
|
|
|
switch (state) {
|
|
|
|
|
case synergyListening: {
|
|
|
|
|
if (synergyType() == synergyServer) {
|
|
|
|
|
setStatus(
|
|
|
|
|
tr("Synergy is waiting for clients").arg(m_SecureSocketVersion));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case synergyConnected: {
|
|
|
|
|
if (m_SecureSocket) {
|
|
|
|
|
setStatus(
|
|
|
|
|
tr("Synergy is connected (with %1)").arg(m_SecureSocketVersion));
|
|
|
|
|
} else {
|
|
|
|
|
setStatus(tr("Synergy is running (without TLS encryption)")
|
|
|
|
|
.arg(m_SecureSocketVersion));
|
2016-12-28 11:50:32 +00:00
|
|
|
}
|
2024-07-02 19:07:06 +00:00
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case synergyConnecting:
|
|
|
|
|
setStatus(tr("Synergy is starting..."));
|
|
|
|
|
break;
|
|
|
|
|
case synergyPendingRetry:
|
|
|
|
|
setStatus(tr("There was an error, retrying..."));
|
|
|
|
|
break;
|
|
|
|
|
case synergyDisconnected:
|
|
|
|
|
setStatus(tr("Synergy is not running"));
|
|
|
|
|
break;
|
|
|
|
|
}
|
2016-12-28 11:50:32 +00:00
|
|
|
|
2024-07-02 19:07:06 +00:00
|
|
|
setIcon(state);
|
2016-12-28 11:50:32 +00:00
|
|
|
|
2024-07-02 19:07:06 +00:00
|
|
|
m_SynergyState = state;
|
2012-06-10 16:50:54 +00:00
|
|
|
}
|
|
|
|
|
|
2024-07-02 19:07:06 +00:00
|
|
|
void MainWindow::setVisible(bool visible) {
|
|
|
|
|
QMainWindow::setVisible(visible);
|
|
|
|
|
m_pActionMinimize->setEnabled(visible);
|
|
|
|
|
m_pActionRestore->setEnabled(!visible);
|
2012-06-10 16:50:54 +00:00
|
|
|
|
2014-02-14 16:21:02 +00:00
|
|
|
#if __MAC_OS_X_VERSION_MIN_REQUIRED >= 1070 // lion
|
2024-07-02 19:07:06 +00:00
|
|
|
// dock hide only supported on lion :(
|
|
|
|
|
ProcessSerialNumber psn = {0, kCurrentProcess};
|
2016-12-29 14:54:26 +00:00
|
|
|
#pragma GCC diagnostic push
|
|
|
|
|
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
|
2024-07-02 19:07:06 +00:00
|
|
|
GetCurrentProcess(&psn);
|
2016-12-29 14:54:26 +00:00
|
|
|
#pragma GCC diagnostic pop
|
2024-07-02 19:07:06 +00:00
|
|
|
if (visible)
|
|
|
|
|
TransformProcessType(&psn, kProcessTransformToForegroundApplication);
|
|
|
|
|
else
|
|
|
|
|
TransformProcessType(&psn, kProcessTransformToBackgroundApplication);
|
2012-06-10 16:50:54 +00:00
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
|
2024-07-02 19:07:06 +00:00
|
|
|
QString MainWindow::getIPAddresses() {
|
|
|
|
|
QStringList result;
|
|
|
|
|
bool hinted = false;
|
|
|
|
|
const auto localnet = QHostAddress::parseSubnet("192.168.0.0/16");
|
|
|
|
|
const QList<QHostAddress> addresses = QNetworkInterface::allAddresses();
|
2021-04-16 11:41:36 +00:00
|
|
|
|
2024-07-02 19:07:06 +00:00
|
|
|
for (const auto &address : addresses) {
|
|
|
|
|
if (address.protocol() == QAbstractSocket::IPv4Protocol &&
|
|
|
|
|
address != QHostAddress(QHostAddress::LocalHost) &&
|
|
|
|
|
!address.isInSubnet(QHostAddress::parseSubnet("169.254.0.0/16"))) {
|
2021-04-16 11:41:36 +00:00
|
|
|
|
2024-07-02 19:07:06 +00:00
|
|
|
// usually 192.168.x.x is a useful ip for the user, so indicate
|
|
|
|
|
// this by making it bold.
|
|
|
|
|
if (!hinted && address.isInSubnet(localnet)) {
|
|
|
|
|
QString format = "<span style=\"color:#4285F4;\">%1</span>";
|
|
|
|
|
result.append(format.arg(address.toString()));
|
|
|
|
|
hinted = true;
|
|
|
|
|
} else {
|
|
|
|
|
result.append(address.toString());
|
|
|
|
|
}
|
2016-12-28 11:50:32 +00:00
|
|
|
}
|
2024-07-02 19:07:06 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (result.isEmpty()) {
|
|
|
|
|
result.append(tr("Unknown"));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return result.join(", ");
|
2013-05-29 20:46:24 +00:00
|
|
|
}
|
|
|
|
|
|
2024-07-02 19:07:06 +00:00
|
|
|
void MainWindow::setEdition(Edition edition) {
|
2024-07-04 09:14:54 +00:00
|
|
|
#ifdef SYNERGY_ENABLE_LICENSING
|
2024-07-02 19:07:06 +00:00
|
|
|
setWindowTitle(m_LicenseManager->getEditionName(edition));
|
2018-06-07 15:22:49 +00:00
|
|
|
#endif
|
2015-02-05 14:17:34 +00:00
|
|
|
}
|
|
|
|
|
|
2024-07-04 09:14:54 +00:00
|
|
|
#ifdef SYNERGY_ENABLE_LICENSING
|
2024-07-02 19:07:06 +00:00
|
|
|
void MainWindow::InvalidLicense() {
|
|
|
|
|
stopSynergy();
|
|
|
|
|
m_AppConfig->activationHasRun(false);
|
2016-10-14 16:38:31 +00:00
|
|
|
}
|
|
|
|
|
|
2024-07-02 19:07:06 +00:00
|
|
|
void MainWindow::showLicenseNotice(const QString ¬ice) {
|
|
|
|
|
this->m_trialLabel->hide();
|
2020-09-24 19:11:47 +00:00
|
|
|
|
2024-07-02 19:07:06 +00:00
|
|
|
if (!notice.isEmpty()) {
|
|
|
|
|
this->m_trialLabel->setText(notice);
|
|
|
|
|
this->m_trialLabel->show();
|
|
|
|
|
}
|
2020-09-24 19:11:47 +00:00
|
|
|
|
2024-07-02 19:07:06 +00:00
|
|
|
setWindowTitle(m_LicenseManager->activeEditionName());
|
2016-10-14 16:38:31 +00:00
|
|
|
}
|
2018-06-07 15:22:49 +00:00
|
|
|
#endif
|
2016-10-14 16:38:31 +00:00
|
|
|
|
2024-07-02 19:07:06 +00:00
|
|
|
void MainWindow::updateLocalFingerprint() {
|
|
|
|
|
if (m_AppConfig->getCryptoEnabled() && Fingerprint::local().fileExists() &&
|
|
|
|
|
m_pRadioGroupServer->isChecked()) {
|
|
|
|
|
m_pLabelFingerprint->setVisible(true);
|
|
|
|
|
} else {
|
|
|
|
|
m_pLabelFingerprint->setVisible(false);
|
|
|
|
|
}
|
2015-04-21 16:56:01 +00:00
|
|
|
}
|
|
|
|
|
|
2024-07-04 09:14:54 +00:00
|
|
|
#ifdef SYNERGY_ENABLE_LICENSING
|
2024-07-02 19:07:06 +00:00
|
|
|
LicenseManager &MainWindow::licenseManager() const { return *m_LicenseManager; }
|
2018-06-07 15:22:49 +00:00
|
|
|
#endif
|
2016-10-14 10:28:37 +00:00
|
|
|
|
2024-07-02 19:07:06 +00:00
|
|
|
bool MainWindow::on_m_pActionSave_triggered() {
|
|
|
|
|
QString fileName =
|
|
|
|
|
QFileDialog::getSaveFileName(this, tr("Save configuration as..."));
|
2012-06-10 16:50:54 +00:00
|
|
|
|
2024-07-02 19:07:06 +00:00
|
|
|
if (!fileName.isEmpty() && !serverConfig().save(fileName)) {
|
2024-07-16 13:36:44 +00:00
|
|
|
QMessageBox::warning(
|
|
|
|
|
this, tr("Save failed"), tr("Could not save configuration to file."));
|
2024-07-02 19:07:06 +00:00
|
|
|
return true;
|
|
|
|
|
}
|
2012-06-10 16:50:54 +00:00
|
|
|
|
2024-07-02 19:07:06 +00:00
|
|
|
return false;
|
2012-06-10 16:50:54 +00:00
|
|
|
}
|
|
|
|
|
|
2024-07-02 19:07:06 +00:00
|
|
|
void MainWindow::on_m_pActionAbout_triggered() {
|
|
|
|
|
AboutDialog dlg(this, appConfig());
|
|
|
|
|
dlg.exec();
|
2012-06-10 16:50:54 +00:00
|
|
|
}
|
|
|
|
|
|
2024-07-02 19:07:06 +00:00
|
|
|
void MainWindow::on_m_pActionHelp_triggered() {
|
|
|
|
|
QDesktopServices::openUrl(QUrl(HELP_URL));
|
2020-03-03 22:38:57 +00:00
|
|
|
}
|
|
|
|
|
|
2024-07-02 19:07:06 +00:00
|
|
|
void MainWindow::updateWindowTitle() {
|
2024-07-04 09:14:54 +00:00
|
|
|
#ifdef SYNERGY_ENABLE_LICENSING
|
2024-07-02 19:07:06 +00:00
|
|
|
setWindowTitle(m_LicenseManager->activeEditionName());
|
2024-07-04 09:14:54 +00:00
|
|
|
#else
|
|
|
|
|
setWindowTitle(SYNERGY_PRODUCT_NAME);
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
#ifdef SYNERGY_ENABLE_LICENSING
|
2024-07-02 19:07:06 +00:00
|
|
|
m_LicenseManager->refresh();
|
2021-09-28 08:39:53 +00:00
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
|
2024-07-02 19:07:06 +00:00
|
|
|
void MainWindow::on_m_pActionSettings_triggered() {
|
|
|
|
|
auto result = SettingsDialog(this, appConfig()).exec();
|
|
|
|
|
if (result == QDialog::Accepted) {
|
|
|
|
|
enableServer(appConfig().getServerGroupChecked());
|
|
|
|
|
enableClient(appConfig().getClientGroupChecked());
|
|
|
|
|
auto state = synergyState();
|
|
|
|
|
if ((state == synergyConnected) || (state == synergyConnecting) ||
|
|
|
|
|
(state == synergyListening)) {
|
|
|
|
|
restartSynergy();
|
2021-08-12 13:31:03 +00:00
|
|
|
}
|
2024-07-02 19:07:06 +00:00
|
|
|
}
|
2012-06-10 16:50:54 +00:00
|
|
|
}
|
|
|
|
|
|
2024-07-02 19:07:06 +00:00
|
|
|
void MainWindow::autoAddScreen(const QString name) {
|
2018-08-08 16:20:16 +00:00
|
|
|
|
2024-07-04 09:14:54 +00:00
|
|
|
#ifdef SYNERGY_ENABLE_LICENSING
|
2024-07-02 19:07:06 +00:00
|
|
|
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;
|
|
|
|
|
}
|
2018-06-07 15:22:49 +00:00
|
|
|
#endif
|
2016-12-28 11:50:32 +00:00
|
|
|
|
2024-07-02 19:07:06 +00:00
|
|
|
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;
|
2016-12-28 11:50:32 +00:00
|
|
|
}
|
2024-07-02 19:07:06 +00:00
|
|
|
}
|
2014-08-21 17:32:40 +00:00
|
|
|
}
|
|
|
|
|
|
2024-07-02 19:07:06 +00:00
|
|
|
void MainWindow::showConfigureServer(const QString &message) {
|
2024-07-04 09:14:54 +00:00
|
|
|
ServerConfigDialog dlg(this, serverConfig(), appConfig());
|
2024-07-02 19:07:06 +00:00
|
|
|
dlg.message(message);
|
|
|
|
|
auto result = dlg.exec();
|
2021-08-20 12:22:07 +00:00
|
|
|
|
2024-07-02 19:07:06 +00:00
|
|
|
if (result == QDialog::Accepted) {
|
|
|
|
|
auto state = synergyState();
|
|
|
|
|
if ((state == synergyConnected) || (state == synergyConnecting) ||
|
|
|
|
|
(state == synergyListening)) {
|
|
|
|
|
restartSynergy();
|
2021-08-20 12:22:07 +00:00
|
|
|
}
|
2024-07-02 19:07:06 +00:00
|
|
|
}
|
2012-06-10 16:50:54 +00:00
|
|
|
}
|
|
|
|
|
|
2024-07-02 19:07:06 +00:00
|
|
|
void MainWindow::on_m_pButtonConfigureServer_clicked() {
|
|
|
|
|
showConfigureServer();
|
2014-08-21 17:32:40 +00:00
|
|
|
}
|
|
|
|
|
|
2024-07-02 19:07:06 +00:00
|
|
|
void MainWindow::on_m_pActivate_triggered() {
|
2024-07-04 09:14:54 +00:00
|
|
|
#ifdef SYNERGY_ENABLE_LICENSING
|
2024-07-02 19:07:06 +00:00
|
|
|
raiseActivationDialog();
|
2018-06-07 15:22:49 +00:00
|
|
|
#endif
|
2012-06-10 16:50:54 +00:00
|
|
|
}
|
|
|
|
|
|
2024-07-02 19:07:06 +00:00
|
|
|
void MainWindow::on_m_pButtonApply_clicked() {
|
|
|
|
|
m_clientConnection.setCheckConnection(true);
|
|
|
|
|
restartSynergy();
|
2012-07-28 18:54:50 +00:00
|
|
|
}
|
2014-08-26 11:22:09 +00:00
|
|
|
|
2024-07-04 09:14:54 +00:00
|
|
|
#ifdef SYNERGY_ENABLE_LICENSING
|
2024-07-02 19:07:06 +00:00
|
|
|
int MainWindow::raiseActivationDialog() {
|
|
|
|
|
if (m_ActivationDialogRunning) {
|
|
|
|
|
return QDialog::Rejected;
|
|
|
|
|
}
|
|
|
|
|
ActivationDialog activationDialog(this, appConfig(), licenseManager());
|
|
|
|
|
m_ActivationDialogRunning = true;
|
|
|
|
|
int result = activationDialog.exec();
|
|
|
|
|
m_ActivationDialogRunning = false;
|
|
|
|
|
if (!m_PendingClientNames.empty()) {
|
|
|
|
|
foreach (const QString &name, m_PendingClientNames) {
|
|
|
|
|
autoAddScreen(name);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
m_PendingClientNames.clear();
|
|
|
|
|
}
|
|
|
|
|
return result;
|
2016-10-19 15:01:15 +00:00
|
|
|
}
|
2018-08-03 22:41:50 +00:00
|
|
|
#endif
|
2016-10-19 15:01:15 +00:00
|
|
|
|
2024-07-02 19:07:06 +00:00
|
|
|
void MainWindow::on_windowShown() {
|
2024-07-04 09:14:54 +00:00
|
|
|
#ifdef SYNERGY_ENABLE_LICENSING
|
2024-07-02 19:07:06 +00:00
|
|
|
auto serialKey = m_LicenseManager->serialKey();
|
|
|
|
|
if (!m_AppConfig->activationHasRun() && !serialKey.isValid()) {
|
|
|
|
|
setEdition(Edition::kUnregistered);
|
|
|
|
|
raiseActivationDialog();
|
|
|
|
|
}
|
2018-06-07 15:22:49 +00:00
|
|
|
#endif
|
2016-10-04 10:48:47 +00:00
|
|
|
}
|
|
|
|
|
|
2024-07-02 19:07:06 +00:00
|
|
|
QString MainWindow::getProfileRootForArg() {
|
|
|
|
|
CoreInterface coreInterface;
|
|
|
|
|
QString dir = coreInterface.getProfileDir();
|
2015-03-04 11:15:07 +00:00
|
|
|
|
2024-07-02 19:07:06 +00:00
|
|
|
// HACK: strip our app name since we're returning the root dir.
|
2015-04-15 12:09:22 +00:00
|
|
|
#if defined(Q_OS_WIN)
|
2024-07-02 19:07:06 +00:00
|
|
|
dir.replace("\\Synergy", "");
|
2015-03-04 11:15:07 +00:00
|
|
|
#else
|
2024-07-02 19:07:06 +00:00
|
|
|
dir.replace("/.synergy", "");
|
2015-03-04 11:15:07 +00:00
|
|
|
#endif
|
|
|
|
|
|
2024-07-02 19:07:06 +00:00
|
|
|
return QString("\"%1\"").arg(dir);
|
2015-03-04 11:15:07 +00:00
|
|
|
}
|
2018-07-28 00:52:56 +00:00
|
|
|
|
2024-07-02 19:07:06 +00:00
|
|
|
void MainWindow::secureSocket(bool secureSocket) {
|
|
|
|
|
m_SecureSocket = secureSocket;
|
|
|
|
|
if (secureSocket) {
|
|
|
|
|
m_pLabelPadlock->show();
|
|
|
|
|
} else {
|
|
|
|
|
m_pLabelPadlock->hide();
|
|
|
|
|
}
|
2018-07-28 00:52:56 +00:00
|
|
|
}
|
2018-08-08 15:47:45 +00:00
|
|
|
|
2024-07-02 19:07:06 +00:00
|
|
|
void MainWindow::on_m_pLabelComputerName_linkActivated(const QString &) {
|
|
|
|
|
m_pActionSettings->trigger();
|
2021-04-12 09:03:37 +00:00
|
|
|
}
|
|
|
|
|
|
2024-07-02 19:07:06 +00:00
|
|
|
void MainWindow::on_m_pLabelFingerprint_linkActivated(const QString &) {
|
2024-07-16 13:36:44 +00:00
|
|
|
QMessageBox::information(
|
|
|
|
|
this, "SSL/TLS fingerprint", Fingerprint::local().readFirst());
|
2021-04-12 09:03:37 +00:00
|
|
|
}
|
|
|
|
|
|
2024-07-02 19:07:06 +00:00
|
|
|
void MainWindow::windowStateChanged() {
|
|
|
|
|
if (windowState() == Qt::WindowMinimized && appConfig().getMinimizeToTray())
|
|
|
|
|
hide();
|
2018-01-30 22:32:00 +00:00
|
|
|
}
|
2021-01-20 11:27:46 +00:00
|
|
|
|
2024-07-02 19:07:06 +00:00
|
|
|
void MainWindow::updateScreenName() {
|
|
|
|
|
m_pLabelComputerName->setText(
|
|
|
|
|
tr("This computer's name: %1 (<a href=\"#\" style=\"text-decoration: "
|
2024-07-08 14:37:51 +00:00
|
|
|
"none; color: #4285F4;\">change</a>)")
|
2024-07-02 19:07:06 +00:00
|
|
|
.arg(appConfig().screenName()));
|
|
|
|
|
serverConfig().updateServerName();
|
2021-02-04 17:10:27 +00:00
|
|
|
}
|
2021-04-12 09:03:37 +00:00
|
|
|
|
2024-07-02 19:07:06 +00:00
|
|
|
void MainWindow::enableServer(bool enable) {
|
|
|
|
|
m_AppConfig->setServerGroupChecked(enable);
|
|
|
|
|
m_pRadioGroupServer->setChecked(enable);
|
2022-09-22 08:12:13 +00:00
|
|
|
|
2024-07-02 19:07:06 +00:00
|
|
|
if (enable) {
|
|
|
|
|
if (m_AppConfig->getServerClientMode()) {
|
|
|
|
|
m_pLabelClientIp->show();
|
|
|
|
|
m_pLineEditClienIp->show();
|
|
|
|
|
m_pButtonConnectToClient->show();
|
|
|
|
|
} else {
|
|
|
|
|
m_pLabelClientIp->hide();
|
|
|
|
|
m_pLineEditClienIp->hide();
|
|
|
|
|
m_pButtonConnectToClient->hide();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
m_pButtonConfigureServer->show();
|
|
|
|
|
m_pLabelServerState->show();
|
|
|
|
|
updateLocalFingerprint();
|
|
|
|
|
m_pButtonToggleStart->setEnabled(enable);
|
|
|
|
|
} else {
|
|
|
|
|
m_pLabelFingerprint->hide();
|
|
|
|
|
m_pButtonConfigureServer->hide();
|
|
|
|
|
m_pLabelServerState->hide();
|
|
|
|
|
m_pLabelClientIp->hide();
|
|
|
|
|
m_pLineEditClienIp->hide();
|
|
|
|
|
m_pButtonConnectToClient->hide();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void MainWindow::enableClient(bool enable) {
|
|
|
|
|
m_AppConfig->setClientGroupChecked(enable);
|
|
|
|
|
m_pRadioGroupClient->setChecked(enable);
|
|
|
|
|
|
|
|
|
|
if (enable) {
|
|
|
|
|
if (m_AppConfig->getClientHostMode()) {
|
|
|
|
|
m_pLabelServerName->hide();
|
|
|
|
|
m_pLineEditHostname->hide();
|
|
|
|
|
m_pButtonConnect->hide();
|
|
|
|
|
} else {
|
|
|
|
|
m_pLabelServerName->show();
|
|
|
|
|
m_pLineEditHostname->show();
|
|
|
|
|
m_pButtonConnect->show();
|
|
|
|
|
}
|
|
|
|
|
m_pButtonToggleStart->setEnabled(enable);
|
|
|
|
|
} else {
|
|
|
|
|
m_pLabelClientState->hide();
|
|
|
|
|
m_pLabelServerName->hide();
|
|
|
|
|
m_pLineEditHostname->hide();
|
|
|
|
|
m_pButtonConnect->hide();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void MainWindow::closeEvent(QCloseEvent *event) {
|
|
|
|
|
#if defined(Q_OS_LINUX)
|
|
|
|
|
QCoreApplication::quit();
|
2021-09-22 14:45:05 +00:00
|
|
|
#endif
|
2024-07-02 19:07:06 +00:00
|
|
|
QWidget::closeEvent(event);
|
2021-09-22 14:45:05 +00:00
|
|
|
}
|
2021-04-15 14:59:03 +00:00
|
|
|
|
2024-07-02 19:07:06 +00:00
|
|
|
void MainWindow::on_m_pRadioGroupServer_clicked(bool) {
|
|
|
|
|
enableServer(true);
|
|
|
|
|
enableClient(false);
|
|
|
|
|
m_AppConfig->saveSettings();
|
2021-04-15 14:59:03 +00:00
|
|
|
}
|
2021-04-12 09:03:37 +00:00
|
|
|
|
2024-07-02 19:07:06 +00:00
|
|
|
void MainWindow::on_m_pRadioGroupClient_clicked(bool) {
|
|
|
|
|
enableClient(true);
|
|
|
|
|
enableServer(false);
|
|
|
|
|
m_AppConfig->saveSettings();
|
2021-04-12 09:03:37 +00:00
|
|
|
}
|
|
|
|
|
|
2024-07-02 19:07:06 +00:00
|
|
|
void MainWindow::on_m_pButtonConnect_clicked() { on_m_pButtonApply_clicked(); }
|
2021-04-15 14:59:03 +00:00
|
|
|
|
2024-07-02 19:07:06 +00:00
|
|
|
void MainWindow::on_m_pButtonConnectToClient_clicked() {
|
|
|
|
|
on_m_pButtonApply_clicked();
|
2022-09-22 08:12:13 +00:00
|
|
|
}
|