Format all source with Clang and introduce lint workflow (#7364)

* Lint script with CLang format

* Use `-i` for `clang-format` and add more logging for lint scripts

* Apply LLVM CLang formatting

* Fixed comment

* Update ChangeLog

* Fixed bad return code logic

* Improve output for linters

* Fixed re-used var in clang lint

* Fixed include order for tests and use `#if 0` instead of commenting out code

* Use full Clang format dump

* Dump Ubuntu Clang format

* Dump Clang format from Debian

* Dumped from: clang-format version 18.1.8

* Revert "Dumped from: clang-format version 18.1.8"

This reverts commit b9bbda2995bb0b4b65baf14afebb0361ec64e644.

* Remove BasedOnStyle

* Restore base Clang format file

* Use clang-format from pip

* Apply Clang format 18 style

* Add clang_format deps

* Fixed include order issues and *some* accidental includes
This commit is contained in:
Nick Bolton 2024-07-02 20:07:06 +01:00 committed by GitHub
parent f2cc964b3d
commit 37bb0f989e
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
664 changed files with 62656 additions and 70427 deletions

11
.clang-format Normal file
View file

@ -0,0 +1,11 @@
# Important: Use the same version of clang-format as our linter, which is:
#
# $ ./scripts/install_deps.py --only-python
# $ ./build/python/bin/clang-format --version
#
# Warning: If you use a different version, the formatting will be different.
#
# To install a specific version of clang-format, use pip:
# $ pip install clang-format==<version>
BasedOnStyle: LLVM

View file

@ -1,23 +0,0 @@
# Runs
name: "Lint CMake files"
on:
pull_request:
jobs:
lint-cmake-files:
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Install dependencies
run: |
python3 -m venv build/python
source build/python/bin/activate
pip install cmake_format pyyaml
- name: Lint CMake files
run: ./scripts/lint_cmake_files.py

26
.github/workflows/lint-source.yml vendored Normal file
View file

@ -0,0 +1,26 @@
# Lints CMake config and C++ source code.
name: "Lint source code"
on:
pull_request:
jobs:
lint-cmake-files:
runs-on: ubuntu-latest
timeout-minutes: 5
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Install dependencies
run: |
python3 -m venv build/python
source build/python/bin/activate
pip install pyyaml cmake_format clang_format
- name: Linting with CMake formatter
run: ./scripts/lint_cmake.py
- name: Linting with Clang format
run: ./scripts/lint_clang.py

View file

@ -38,6 +38,7 @@ Enhancements:
- #7360 Re-implement packaging for GitHub workflows (Windows) - #7360 Re-implement packaging for GitHub workflows (Windows)
- #7361 Re-implement packaging for GitHub workflows (Linux) - #7361 Re-implement packaging for GitHub workflows (Linux)
- #7363 Schedule CI daily at 5am to detect code rot early - #7363 Schedule CI daily at 5am to detect code rot early
- #7364 Format all source with Clang and introduce lint workflow
# 1.14.6 # 1.14.6

View file

@ -13,6 +13,11 @@ def main():
parser.add_argument( parser.add_argument(
"--only", type=str, help="Only install the specified dependency" "--only", type=str, help="Only install the specified dependency"
) )
parser.add_argument(
"--only-python",
action="store_true",
help="Only install Python dependencies",
)
args = parser.parse_args() args = parser.parse_args()
env.ensure_dependencies() env.ensure_dependencies()
@ -20,12 +25,13 @@ def main():
env.install_requirements() env.install_requirements()
error = False error = False
try: if not args.only_python:
deps = Dependencies(args.only) try:
deps.install() deps = Dependencies(args.only)
except Exception: deps.install()
traceback.print_exc() except Exception:
error = True traceback.print_exc()
error = True
if args.pause_on_exit: if args.pause_on_exit:
input("Press enter to continue...") input("Press enter to continue...")

14
scripts/lib/fs.py Normal file
View file

@ -0,0 +1,14 @@
import os, fnmatch
def find_files(search_dirs, include_files, exclude_dirs=[]):
"""Recursively find files, excluding specified directories"""
matches = []
for dir in search_dirs:
for root, dirnames, filenames in os.walk(dir):
dirnames[:] = [d for d in dirnames if d not in exclude_dirs]
for pattern in include_files:
for filename in fnmatch.filter(filenames, pattern):
matches.append(os.path.join(root, filename))
return matches

57
scripts/lint_clang.py Executable file
View file

@ -0,0 +1,57 @@
#!/usr/bin/env python3
import argparse, sys
import lib.fs as fs
import lib.env as env
include_files = [
"*.h",
"*.c",
"*.hpp",
"*.cpp",
]
dirs = ["src"]
def main():
"""
Cross-platform equivalent of using find and xargs with clang-format.
Lints by performing a dry run (--dry-run) which fails when formatting is needed.
"""
parser = argparse.ArgumentParser()
parser.add_argument(
"--format",
action="store_true",
help="In-place format all files",
)
args = parser.parse_args()
env.ensure_in_venv(__file__)
from clang_format import clang_format # type: ignore
cmd_args = ["-i"] if args.format else ["--dry-run", "--Werror"]
files_recursive = fs.find_files(dirs, include_files)
if args.format:
print("Formatting files with Clang formatter:")
else:
print("Checking files with Clang formatter:")
for file in files_recursive:
print(file)
if files_recursive:
sys.argv = [""] + cmd_args + files_recursive
result = clang_format()
if result == 0:
print("Clang lint passed")
sys.exit(result)
else:
print("No files for Clang to process", file=sys.stderr)
sys.exit(0)
if __name__ == "__main__":
main()

59
scripts/lint_cmake.py Executable file
View file

@ -0,0 +1,59 @@
#!/usr/bin/env python3
import sys, argparse
import lib.env as env
import lib.fs as fs
include_files = [
"*.cmake",
"CMakeLists.txt",
]
exclude_dirs = [
"ext",
"build",
]
def main():
"""
Cross-platform equivalent of using find and xargs with cmake-format.
Lints by performing a dry run (--check) which fails when formatting is needed.
"""
parser = argparse.ArgumentParser()
parser.add_argument(
"--format",
action="store_true",
help="In-place format all files",
)
args = parser.parse_args()
env.ensure_in_venv(__file__)
from cmakelang.format.__main__ import main as cmake_format_main
cmd_args = ["--in-place"] if args.format else ["--check"]
files_recursive = fs.find_files(".", include_files, exclude_dirs)
if args.format:
print("Formatting files with CMake formatter:")
else:
print("Checking files with CMake formatter:")
for file in files_recursive:
print(file)
if files_recursive:
sys.argv = [""] + cmd_args + files_recursive
result = cmake_format_main()
if result == 0:
print("CMake lint passed")
sys.exit(result)
else:
print("No CMake files found to process.", file=sys.stderr)
sys.exit(0)
if __name__ == "__main__":
main()

View file

@ -1,51 +0,0 @@
#!/usr/bin/env python3
import sys, os, argparse, fnmatch
import lib.env as env
include_files = [
"*.cmake",
"CMakeLists.txt",
]
exclude_dirs = [
"ext",
"build",
]
def find_files(base_dir, include_files, exclude_dirs):
"""Recursively find files, excluding specified directories"""
matches = []
for root, dirnames, filenames in os.walk(base_dir):
dirnames[:] = [d for d in dirnames if d not in exclude_dirs]
for pattern in include_files:
for filename in fnmatch.filter(filenames, pattern):
matches.append(os.path.join(root, filename))
return matches
def main():
parser = argparse.ArgumentParser()
parser.add_argument("--format", action="store_true", help="Formats all CMake files")
args = parser.parse_args()
# important: load venv before loading modules that install deps.
env.ensure_in_venv(__file__)
from cmakelang.format.__main__ import main as cmake_format_main
new_args = ["--in-place"] if args.format else ["--check"]
files_recursive = find_files(".", include_files, exclude_dirs)
if files_recursive:
sys.argv = [""] + new_args + files_recursive
sys.exit(cmake_format_main())
else:
print("No CMake files found to process.")
sys.exit(0)
if __name__ == "__main__":
main()

View file

@ -1,4 +1,5 @@
cmake_format cmake_format
clang-format
python-dotenv python-dotenv
pyyaml pyyaml
dmgbuild; sys_platform == 'darwin' dmgbuild; sys_platform == 'darwin'

View file

@ -2,11 +2,11 @@
* synergy -- mouse and keyboard sharing utility * synergy -- mouse and keyboard sharing utility
* Copyright (C) 2012-2022 Symless Ltd. * Copyright (C) 2012-2022 Symless Ltd.
* Copyright (C) 2002 Chris Schoeneman * Copyright (C) 2002 Chris Schoeneman
* *
* This package is free software; you can redistribute it and/or * This package is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
* found in the file LICENSE that should have accompanied this file. * found in the file LICENSE that should have accompanied this file.
* *
* This package is distributed in the hope that it will be useful, * This package is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
@ -15,54 +15,54 @@
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include <iostream> #include "arch/Arch.h"
#include "base/EventQueue.h"
#include "base/Log.h"
#include "synergy/ClientApp.h" #include "synergy/ClientApp.h"
#include "synergy/ServerApp.h" #include "synergy/ServerApp.h"
#include "arch/Arch.h" #include <iostream>
#include "base/Log.h"
#include "base/EventQueue.h"
void showHelp()
{
std::cout<<"Usage: synergy-core <server | client> [...options]"<<std::endl;
std::cout<<"server - start as a server (synergys)"<<std::endl;
std::cout<<"client - start as a client (synergyc)"<<std::endl;
std::cout<<"use synergy-core <server|client> --help for more information."<<std::endl;
}
bool isServer(int argc, char** argv)
{
return (argc > 1 && argv[1] == std::string("server"));
}
bool isClient(int argc, char** argv)
{
return (argc > 1 && argv[1] == std::string("client"));
}
int main(int argc, char** argv)
{
#if SYSAPI_WIN32 #if SYSAPI_WIN32
ArchMiscWindows::setInstanceWin32(GetModuleHandle(NULL)); #include "arch/win32/ArchMiscWindows.h"
#endif #endif
Arch arch; void showHelp() {
arch.init(); std::cout << "Usage: synergy-core <server | client> [...options]"
<< std::endl;
Log log; std::cout << "server - start as a server (synergys)" << std::endl;
EventQueue events; std::cout << "client - start as a client (synergyc)" << std::endl;
std::cout << "use synergy-core <server|client> --help for more information."
if (isServer(argc, argv)) { << std::endl;
ServerApp app(&events, nullptr); }
return app.run(argc, argv);
} bool isServer(int argc, char **argv) {
else if (isClient(argc, argv)) { return (argc > 1 && argv[1] == std::string("server"));
ClientApp app(&events, nullptr); }
return app.run(argc, argv);
} bool isClient(int argc, char **argv) {
else { return (argc > 1 && argv[1] == std::string("client"));
showHelp(); }
}
int main(int argc, char **argv) {
return 0; #if SYSAPI_WIN32
ArchMiscWindows::setInstanceWin32(GetModuleHandle(NULL));
#endif
Arch arch;
arch.init();
Log log;
EventQueue events;
if (isServer(argc, argv)) {
ServerApp app(&events, nullptr);
return app.run(argc, argv);
} else if (isClient(argc, argv)) {
ClientApp app(&events, nullptr);
return app.run(argc, argv);
} else {
showHelp();
}
return 0;
} }

View file

@ -2,11 +2,11 @@
* synergy -- mouse and keyboard sharing utility * synergy -- mouse and keyboard sharing utility
* Copyright (C) 2012-2016 Symless Ltd. * Copyright (C) 2012-2016 Symless Ltd.
* Copyright (C) 2003 Chris Schoeneman * Copyright (C) 2003 Chris Schoeneman
* *
* This package is free software; you can redistribute it and/or * This package is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
* found in the file LICENSE that should have accompanied this file. * found in the file LICENSE that should have accompanied this file.
* *
* This package is distributed in the hope that it will be useful, * This package is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
@ -18,359 +18,308 @@
#include "MSWindowsClientTaskBarReceiver.h" #include "MSWindowsClientTaskBarReceiver.h"
#include "resource.h" #include "arch/Arch.h"
#include "arch/win32/ArchMiscWindows.h"
#include "arch/win32/ArchTaskBarWindows.h"
#include "base/EventQueue.h"
#include "base/EventTypes.h"
#include "base/log_outputters.h"
#include "client/Client.h" #include "client/Client.h"
#include "platform/MSWindowsClipboard.h" #include "platform/MSWindowsClipboard.h"
#include "platform/MSWindowsScreen.h" #include "platform/MSWindowsScreen.h"
#include "arch/win32/ArchTaskBarWindows.h" #include "resource.h"
#include "arch/win32/ArchMiscWindows.h"
#include "arch/Arch.h"
#include "base/EventQueue.h"
#include "base/log_outputters.h"
#include "base/EventTypes.h"
// //
// MSWindowsClientTaskBarReceiver // MSWindowsClientTaskBarReceiver
// //
const UINT MSWindowsClientTaskBarReceiver::s_stateToIconID[kMaxState] = const UINT MSWindowsClientTaskBarReceiver::s_stateToIconID[kMaxState] = {
{ IDI_TASKBAR_NOT_RUNNING, IDI_TASKBAR_NOT_WORKING, IDI_TASKBAR_NOT_CONNECTED,
IDI_TASKBAR_NOT_RUNNING, IDI_TASKBAR_NOT_CONNECTED, IDI_TASKBAR_CONNECTED};
IDI_TASKBAR_NOT_WORKING,
IDI_TASKBAR_NOT_CONNECTED,
IDI_TASKBAR_NOT_CONNECTED,
IDI_TASKBAR_CONNECTED
};
MSWindowsClientTaskBarReceiver::MSWindowsClientTaskBarReceiver( MSWindowsClientTaskBarReceiver::MSWindowsClientTaskBarReceiver(
HINSTANCE appInstance, const BufferedLogOutputter* logBuffer, IEventQueue* events) : HINSTANCE appInstance, const BufferedLogOutputter *logBuffer,
ClientTaskBarReceiver(events), IEventQueue *events)
m_appInstance(appInstance), : ClientTaskBarReceiver(events), m_appInstance(appInstance), m_window(NULL),
m_window(NULL), m_logBuffer(logBuffer) {
m_logBuffer(logBuffer) for (UInt32 i = 0; i < kMaxState; ++i) {
{ m_icon[i] = loadIcon(s_stateToIconID[i]);
for (UInt32 i = 0; i < kMaxState; ++i) { }
m_icon[i] = loadIcon(s_stateToIconID[i]); m_menu = LoadMenu(m_appInstance, MAKEINTRESOURCE(IDR_TASKBAR));
// don't create the window yet. we'll create it on demand. this
// has the side benefit of being created in the thread used for
// the task bar. that's good because it means the existence of
// the window won't prevent changing the main thread's desktop.
// add ourself to the task bar
ARCH->addReceiver(this);
}
MSWindowsClientTaskBarReceiver::~MSWindowsClientTaskBarReceiver() { cleanup(); }
void MSWindowsClientTaskBarReceiver::cleanup() {
ARCH->removeReceiver(this);
for (UInt32 i = 0; i < kMaxState; ++i) {
deleteIcon(m_icon[i]);
}
DestroyMenu(m_menu);
destroyWindow();
}
void MSWindowsClientTaskBarReceiver::showStatus() {
// create the window
createWindow();
// lock self while getting status
lock();
// get the current status
std::string status = getToolTip();
// done getting status
unlock();
// update dialog
HWND child = GetDlgItem(m_window, IDC_TASKBAR_STATUS_STATUS);
SendMessage(child, WM_SETTEXT, 0, (LPARAM)status.c_str());
if (!IsWindowVisible(m_window)) {
// position it by the mouse
POINT cursorPos;
GetCursorPos(&cursorPos);
RECT windowRect;
GetWindowRect(m_window, &windowRect);
int x = cursorPos.x;
int y = cursorPos.y;
int fw = GetSystemMetrics(SM_CXDLGFRAME);
int fh = GetSystemMetrics(SM_CYDLGFRAME);
int ww = windowRect.right - windowRect.left;
int wh = windowRect.bottom - windowRect.top;
int sw = GetSystemMetrics(SM_CXFULLSCREEN);
int sh = GetSystemMetrics(SM_CYFULLSCREEN);
if (fw < 1) {
fw = 1;
} }
m_menu = LoadMenu(m_appInstance, MAKEINTRESOURCE(IDR_TASKBAR)); if (fh < 1) {
fh = 1;
// don't create the window yet. we'll create it on demand. this
// has the side benefit of being created in the thread used for
// the task bar. that's good because it means the existence of
// the window won't prevent changing the main thread's desktop.
// add ourself to the task bar
ARCH->addReceiver(this);
}
MSWindowsClientTaskBarReceiver::~MSWindowsClientTaskBarReceiver()
{
cleanup();
}
void
MSWindowsClientTaskBarReceiver::cleanup()
{
ARCH->removeReceiver(this);
for (UInt32 i = 0; i < kMaxState; ++i) {
deleteIcon(m_icon[i]);
} }
DestroyMenu(m_menu); if (x + ww - fw > sw) {
destroyWindow(); x -= ww - fw;
} } else {
x -= fw;
void
MSWindowsClientTaskBarReceiver::showStatus()
{
// create the window
createWindow();
// lock self while getting status
lock();
// get the current status
std::string status = getToolTip();
// done getting status
unlock();
// update dialog
HWND child = GetDlgItem(m_window, IDC_TASKBAR_STATUS_STATUS);
SendMessage(child, WM_SETTEXT, 0, (LPARAM)status.c_str());
if (!IsWindowVisible(m_window)) {
// position it by the mouse
POINT cursorPos;
GetCursorPos(&cursorPos);
RECT windowRect;
GetWindowRect(m_window, &windowRect);
int x = cursorPos.x;
int y = cursorPos.y;
int fw = GetSystemMetrics(SM_CXDLGFRAME);
int fh = GetSystemMetrics(SM_CYDLGFRAME);
int ww = windowRect.right - windowRect.left;
int wh = windowRect.bottom - windowRect.top;
int sw = GetSystemMetrics(SM_CXFULLSCREEN);
int sh = GetSystemMetrics(SM_CYFULLSCREEN);
if (fw < 1) {
fw = 1;
}
if (fh < 1) {
fh = 1;
}
if (x + ww - fw > sw) {
x -= ww - fw;
}
else {
x -= fw;
}
if (x < 0) {
x = 0;
}
if (y + wh - fh > sh) {
y -= wh - fh;
}
else {
y -= fh;
}
if (y < 0) {
y = 0;
}
SetWindowPos(m_window, HWND_TOPMOST, x, y, ww, wh,
SWP_SHOWWINDOW);
} }
} if (x < 0) {
x = 0;
void
MSWindowsClientTaskBarReceiver::runMenu(int x, int y)
{
// do popup menu. we need a window to pass to TrackPopupMenu().
// the SetForegroundWindow() and SendMessage() calls around
// TrackPopupMenu() are to get the menu to be dismissed when
// another window gets activated and are just one of those
// win32 weirdnesses.
createWindow();
SetForegroundWindow(m_window);
HMENU menu = GetSubMenu(m_menu, 0);
SetMenuDefaultItem(menu, IDC_TASKBAR_STATUS, FALSE);
HMENU logLevelMenu = GetSubMenu(menu, 3);
CheckMenuRadioItem(logLevelMenu, 0, 6,
CLOG->getFilter() - kERROR, MF_BYPOSITION);
int n = TrackPopupMenu(menu,
TPM_NONOTIFY |
TPM_RETURNCMD |
TPM_LEFTBUTTON |
TPM_RIGHTBUTTON,
x, y, 0, m_window, NULL);
SendMessage(m_window, WM_NULL, 0, 0);
// perform the requested operation
switch (n) {
case IDC_TASKBAR_STATUS:
showStatus();
break;
case IDC_TASKBAR_LOG:
copyLog();
break;
case IDC_TASKBAR_SHOW_LOG:
ARCH->showConsole(true);
break;
case IDC_TASKBAR_LOG_LEVEL_ERROR:
CLOG->setFilter(kERROR);
break;
case IDC_TASKBAR_LOG_LEVEL_WARNING:
CLOG->setFilter(kWARNING);
break;
case IDC_TASKBAR_LOG_LEVEL_NOTE:
CLOG->setFilter(kNOTE);
break;
case IDC_TASKBAR_LOG_LEVEL_INFO:
CLOG->setFilter(kINFO);
break;
case IDC_TASKBAR_LOG_LEVEL_DEBUG:
CLOG->setFilter(kDEBUG);
break;
case IDC_TASKBAR_LOG_LEVEL_DEBUG1:
CLOG->setFilter(kDEBUG1);
break;
case IDC_TASKBAR_LOG_LEVEL_DEBUG2:
CLOG->setFilter(kDEBUG2);
break;
case IDC_TASKBAR_QUIT:
quit();
break;
} }
if (y + wh - fh > sh) {
y -= wh - fh;
} else {
y -= fh;
}
if (y < 0) {
y = 0;
}
SetWindowPos(m_window, HWND_TOPMOST, x, y, ww, wh, SWP_SHOWWINDOW);
}
} }
void void MSWindowsClientTaskBarReceiver::runMenu(int x, int y) {
MSWindowsClientTaskBarReceiver::primaryAction() // do popup menu. we need a window to pass to TrackPopupMenu().
{ // the SetForegroundWindow() and SendMessage() calls around
// TrackPopupMenu() are to get the menu to be dismissed when
// another window gets activated and are just one of those
// win32 weirdnesses.
createWindow();
SetForegroundWindow(m_window);
HMENU menu = GetSubMenu(m_menu, 0);
SetMenuDefaultItem(menu, IDC_TASKBAR_STATUS, FALSE);
HMENU logLevelMenu = GetSubMenu(menu, 3);
CheckMenuRadioItem(logLevelMenu, 0, 6, CLOG->getFilter() - kERROR,
MF_BYPOSITION);
int n = TrackPopupMenu(
menu, TPM_NONOTIFY | TPM_RETURNCMD | TPM_LEFTBUTTON | TPM_RIGHTBUTTON, x,
y, 0, m_window, NULL);
SendMessage(m_window, WM_NULL, 0, 0);
// perform the requested operation
switch (n) {
case IDC_TASKBAR_STATUS:
showStatus(); showStatus();
break;
case IDC_TASKBAR_LOG:
copyLog();
break;
case IDC_TASKBAR_SHOW_LOG:
ARCH->showConsole(true);
break;
case IDC_TASKBAR_LOG_LEVEL_ERROR:
CLOG->setFilter(kERROR);
break;
case IDC_TASKBAR_LOG_LEVEL_WARNING:
CLOG->setFilter(kWARNING);
break;
case IDC_TASKBAR_LOG_LEVEL_NOTE:
CLOG->setFilter(kNOTE);
break;
case IDC_TASKBAR_LOG_LEVEL_INFO:
CLOG->setFilter(kINFO);
break;
case IDC_TASKBAR_LOG_LEVEL_DEBUG:
CLOG->setFilter(kDEBUG);
break;
case IDC_TASKBAR_LOG_LEVEL_DEBUG1:
CLOG->setFilter(kDEBUG1);
break;
case IDC_TASKBAR_LOG_LEVEL_DEBUG2:
CLOG->setFilter(kDEBUG2);
break;
case IDC_TASKBAR_QUIT:
quit();
break;
}
} }
void MSWindowsClientTaskBarReceiver::primaryAction() { showStatus(); }
const IArchTaskBarReceiver::Icon const IArchTaskBarReceiver::Icon
MSWindowsClientTaskBarReceiver::getIcon() const MSWindowsClientTaskBarReceiver::getIcon() const {
{ return static_cast<Icon>(m_icon[getStatus()]);
return static_cast<Icon>(m_icon[getStatus()]);
} }
void void MSWindowsClientTaskBarReceiver::copyLog() const {
MSWindowsClientTaskBarReceiver::copyLog() const if (m_logBuffer != NULL) {
{ // collect log buffer
if (m_logBuffer != NULL) { String data;
// collect log buffer for (BufferedLogOutputter::const_iterator index = m_logBuffer->begin();
String data; index != m_logBuffer->end(); ++index) {
for (BufferedLogOutputter::const_iterator index = m_logBuffer->begin(); data += *index;
index != m_logBuffer->end(); ++index) { data += "\n";
data += *index;
data += "\n";
}
// copy log to clipboard
if (!data.empty()) {
MSWindowsClipboard clipboard(m_window);
clipboard.open(0);
clipboard.emptyUnowned();
clipboard.add(IClipboard::kText, data);
clipboard.close();
}
} }
// copy log to clipboard
if (!data.empty()) {
MSWindowsClipboard clipboard(m_window);
clipboard.open(0);
clipboard.emptyUnowned();
clipboard.add(IClipboard::kText, data);
clipboard.close();
}
}
} }
void void MSWindowsClientTaskBarReceiver::onStatusChanged() {
MSWindowsClientTaskBarReceiver::onStatusChanged() if (IsWindowVisible(m_window)) {
{ showStatus();
if (IsWindowVisible(m_window)) { }
showStatus();
}
} }
HICON HICON
MSWindowsClientTaskBarReceiver::loadIcon(UINT id) MSWindowsClientTaskBarReceiver::loadIcon(UINT id) {
{ HANDLE icon = LoadImage(m_appInstance, MAKEINTRESOURCE(id), IMAGE_ICON, 0, 0,
HANDLE icon = LoadImage(m_appInstance, LR_DEFAULTCOLOR);
MAKEINTRESOURCE(id), return static_cast<HICON>(icon);
IMAGE_ICON,
0, 0,
LR_DEFAULTCOLOR);
return static_cast<HICON>(icon);
} }
void void MSWindowsClientTaskBarReceiver::deleteIcon(HICON icon) {
MSWindowsClientTaskBarReceiver::deleteIcon(HICON icon) if (icon != NULL) {
{ DestroyIcon(icon);
if (icon != NULL) { }
DestroyIcon(icon);
}
} }
void void MSWindowsClientTaskBarReceiver::createWindow() {
MSWindowsClientTaskBarReceiver::createWindow() // ignore if already created
{ if (m_window != NULL) {
// ignore if already created return;
if (m_window != NULL) { }
return;
}
// get the status dialog // get the status dialog
m_window = CreateDialogParam(m_appInstance, m_window = CreateDialogParam(
MAKEINTRESOURCE(IDD_TASKBAR_STATUS), m_appInstance, MAKEINTRESOURCE(IDD_TASKBAR_STATUS), NULL,
NULL, (DLGPROC)&MSWindowsClientTaskBarReceiver::staticDlgProc,
(DLGPROC)&MSWindowsClientTaskBarReceiver::staticDlgProc, reinterpret_cast<LPARAM>(static_cast<void *>(this)));
reinterpret_cast<LPARAM>(
static_cast<void*>(this)));
// window should appear on top of everything, including (especially) // window should appear on top of everything, including (especially)
// the task bar. // the task bar.
LONG_PTR style = GetWindowLongPtr(m_window, GWL_EXSTYLE); LONG_PTR style = GetWindowLongPtr(m_window, GWL_EXSTYLE);
style |= WS_EX_TOOLWINDOW | WS_EX_TOPMOST; style |= WS_EX_TOOLWINDOW | WS_EX_TOPMOST;
SetWindowLongPtr(m_window, GWL_EXSTYLE, style); SetWindowLongPtr(m_window, GWL_EXSTYLE, style);
// tell the task bar about this dialog // tell the task bar about this dialog
ArchTaskBarWindows::addDialog(m_window); ArchTaskBarWindows::addDialog(m_window);
} }
void void MSWindowsClientTaskBarReceiver::destroyWindow() {
MSWindowsClientTaskBarReceiver::destroyWindow() if (m_window != NULL) {
{ ArchTaskBarWindows::removeDialog(m_window);
if (m_window != NULL) { DestroyWindow(m_window);
ArchTaskBarWindows::removeDialog(m_window); m_window = NULL;
DestroyWindow(m_window); }
m_window = NULL;
}
} }
BOOL BOOL MSWindowsClientTaskBarReceiver::dlgProc(HWND hwnd, UINT msg, WPARAM wParam,
MSWindowsClientTaskBarReceiver::dlgProc(HWND hwnd, LPARAM) {
UINT msg, WPARAM wParam, LPARAM) switch (msg) {
{ case WM_INITDIALOG:
switch (msg) { // use default focus
case WM_INITDIALOG: return TRUE;
// use default focus
return TRUE;
case WM_ACTIVATE: case WM_ACTIVATE:
// hide when another window is activated // hide when another window is activated
if (LOWORD(wParam) == WA_INACTIVE) { if (LOWORD(wParam) == WA_INACTIVE) {
ShowWindow(hwnd, SW_HIDE); ShowWindow(hwnd, SW_HIDE);
}
break;
} }
return FALSE; break;
}
return FALSE;
} }
BOOL CALLBACK BOOL CALLBACK MSWindowsClientTaskBarReceiver::staticDlgProc(HWND hwnd, UINT msg,
MSWindowsClientTaskBarReceiver::staticDlgProc(HWND hwnd, WPARAM wParam,
UINT msg, WPARAM wParam, LPARAM lParam) LPARAM lParam) {
{ // if msg is WM_INITDIALOG, extract the MSWindowsClientTaskBarReceiver*
// if msg is WM_INITDIALOG, extract the MSWindowsClientTaskBarReceiver* // and put it in the extra window data then forward the call.
// and put it in the extra window data then forward the call. MSWindowsClientTaskBarReceiver *self = NULL;
MSWindowsClientTaskBarReceiver* self = NULL; if (msg == WM_INITDIALOG) {
if (msg == WM_INITDIALOG) { self = static_cast<MSWindowsClientTaskBarReceiver *>(
self = static_cast<MSWindowsClientTaskBarReceiver*>( reinterpret_cast<void *>(lParam));
reinterpret_cast<void*>(lParam)); SetWindowLongPtr(hwnd, GWLP_USERDATA, (LONG_PTR)lParam);
SetWindowLongPtr(hwnd, GWLP_USERDATA, (LONG_PTR) lParam); } else {
} // get the extra window data and forward the call
else { LONG_PTR data = GetWindowLongPtr(hwnd, GWLP_USERDATA);
// get the extra window data and forward the call if (data != 0) {
LONG_PTR data = GetWindowLongPtr(hwnd, GWLP_USERDATA); self = (MSWindowsClientTaskBarReceiver *)data;
if (data != 0) {
self = (MSWindowsClientTaskBarReceiver*) data;
}
} }
}
// forward the message // forward the message
if (self != NULL) { if (self != NULL) {
return self->dlgProc(hwnd, msg, wParam, lParam); return self->dlgProc(hwnd, msg, wParam, lParam);
} } else {
else { return (msg == WM_INITDIALOG) ? TRUE : FALSE;
return (msg == WM_INITDIALOG) ? TRUE : FALSE; }
}
} }
IArchTaskBarReceiver* IArchTaskBarReceiver *
createTaskBarReceiver(const BufferedLogOutputter* logBuffer, IEventQueue* events) createTaskBarReceiver(const BufferedLogOutputter *logBuffer,
{ IEventQueue *events) {
ArchMiscWindows::setIcons( ArchMiscWindows::setIcons((HICON)LoadImage(ArchMiscWindows::instanceWin32(),
(HICON)LoadImage(ArchMiscWindows::instanceWin32(), MAKEINTRESOURCE(IDI_SYNERGY),
MAKEINTRESOURCE(IDI_SYNERGY), IMAGE_ICON, 32, 32, LR_SHARED),
IMAGE_ICON, (HICON)LoadImage(ArchMiscWindows::instanceWin32(),
32, 32, LR_SHARED), MAKEINTRESOURCE(IDI_SYNERGY),
(HICON)LoadImage(ArchMiscWindows::instanceWin32(), IMAGE_ICON, 16, 16, LR_SHARED));
MAKEINTRESOURCE(IDI_SYNERGY),
IMAGE_ICON,
16, 16, LR_SHARED));
return new MSWindowsClientTaskBarReceiver( return new MSWindowsClientTaskBarReceiver(
MSWindowsScreen::getWindowInstance(), logBuffer, events); MSWindowsScreen::getWindowInstance(), logBuffer, events);
} }

View file

@ -2,11 +2,11 @@
* synergy -- mouse and keyboard sharing utility * synergy -- mouse and keyboard sharing utility
* Copyright (C) 2012-2016 Symless Ltd. * Copyright (C) 2012-2016 Symless Ltd.
* Copyright (C) 2003 Chris Schoeneman * Copyright (C) 2003 Chris Schoeneman
* *
* This package is free software; you can redistribute it and/or * This package is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
* found in the file LICENSE that should have accompanied this file. * found in the file LICENSE that should have accompanied this file.
* *
* This package is distributed in the hope that it will be useful, * This package is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
@ -29,40 +29,39 @@ class IEventQueue;
//! Implementation of ClientTaskBarReceiver for Microsoft Windows //! Implementation of ClientTaskBarReceiver for Microsoft Windows
class MSWindowsClientTaskBarReceiver : public ClientTaskBarReceiver { class MSWindowsClientTaskBarReceiver : public ClientTaskBarReceiver {
public: public:
MSWindowsClientTaskBarReceiver(HINSTANCE, const BufferedLogOutputter*, IEventQueue* events); MSWindowsClientTaskBarReceiver(HINSTANCE, const BufferedLogOutputter *,
virtual ~MSWindowsClientTaskBarReceiver(); IEventQueue *events);
virtual ~MSWindowsClientTaskBarReceiver();
// IArchTaskBarReceiver overrides // IArchTaskBarReceiver overrides
virtual void showStatus(); virtual void showStatus();
virtual void runMenu(int x, int y); virtual void runMenu(int x, int y);
virtual void primaryAction(); virtual void primaryAction();
virtual const Icon getIcon() const; virtual const Icon getIcon() const;
void cleanup(); void cleanup();
protected: protected:
void copyLog() const; void copyLog() const;
// ClientTaskBarReceiver overrides // ClientTaskBarReceiver overrides
virtual void onStatusChanged(); virtual void onStatusChanged();
private: private:
HICON loadIcon(UINT); HICON loadIcon(UINT);
void deleteIcon(HICON); void deleteIcon(HICON);
void createWindow(); void createWindow();
void destroyWindow(); void destroyWindow();
BOOL dlgProc(HWND hwnd, BOOL dlgProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
UINT msg, WPARAM wParam, LPARAM lParam); static BOOL CALLBACK staticDlgProc(HWND hwnd, UINT msg, WPARAM wParam,
static BOOL CALLBACK LPARAM lParam);
staticDlgProc(HWND hwnd,
UINT msg, WPARAM wParam, LPARAM lParam);
private: private:
HINSTANCE m_appInstance; HINSTANCE m_appInstance;
HWND m_window; HWND m_window;
HMENU m_menu; HMENU m_menu;
HICON m_icon[kMaxState]; HICON m_icon[kMaxState];
const BufferedLogOutputter* m_logBuffer; const BufferedLogOutputter *m_logBuffer;
static const UINT s_stateToIconID[]; static const UINT s_stateToIconID[];
}; };

View file

@ -2,11 +2,11 @@
* synergy -- mouse and keyboard sharing utility * synergy -- mouse and keyboard sharing utility
* Copyright (C) 2012-2016 Symless Ltd. * Copyright (C) 2012-2016 Symless Ltd.
* Copyright (C) 2004 Chris Schoeneman * Copyright (C) 2004 Chris Schoeneman
* *
* This package is free software; you can redistribute it and/or * This package is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
* found in the file LICENSE that should have accompanied this file. * found in the file LICENSE that should have accompanied this file.
* *
* This package is distributed in the hope that it will be useful, * This package is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
@ -23,47 +23,35 @@
// OSXClientTaskBarReceiver // OSXClientTaskBarReceiver
// //
OSXClientTaskBarReceiver::OSXClientTaskBarReceiver( OSXClientTaskBarReceiver::OSXClientTaskBarReceiver(const BufferedLogOutputter *,
const BufferedLogOutputter*, IEventQueue *events)
IEventQueue* events) : : ClientTaskBarReceiver(events) {
ClientTaskBarReceiver(events) // add ourself to the task bar
{ ARCH->addReceiver(this);
// add ourself to the task bar
ARCH->addReceiver(this);
} }
OSXClientTaskBarReceiver::~OSXClientTaskBarReceiver() OSXClientTaskBarReceiver::~OSXClientTaskBarReceiver() {
{ ARCH->removeReceiver(this);
ARCH->removeReceiver(this);
} }
void void OSXClientTaskBarReceiver::showStatus() {
OSXClientTaskBarReceiver::showStatus() // do nothing
{
// do nothing
} }
void void OSXClientTaskBarReceiver::runMenu(int, int) {
OSXClientTaskBarReceiver::runMenu(int, int) // do nothing
{
// do nothing
} }
void void OSXClientTaskBarReceiver::primaryAction() {
OSXClientTaskBarReceiver::primaryAction() // do nothing
{
// do nothing
} }
const IArchTaskBarReceiver::Icon const IArchTaskBarReceiver::Icon OSXClientTaskBarReceiver::getIcon() const {
OSXClientTaskBarReceiver::getIcon() const return NULL;
{
return NULL;
} }
IArchTaskBarReceiver* IArchTaskBarReceiver *
createTaskBarReceiver(const BufferedLogOutputter* logBuffer, IEventQueue* events) createTaskBarReceiver(const BufferedLogOutputter *logBuffer,
{ IEventQueue *events) {
return new OSXClientTaskBarReceiver(logBuffer, events); return new OSXClientTaskBarReceiver(logBuffer, events);
} }

View file

@ -2,11 +2,11 @@
* synergy -- mouse and keyboard sharing utility * synergy -- mouse and keyboard sharing utility
* Copyright (C) 2012-2016 Symless Ltd. * Copyright (C) 2012-2016 Symless Ltd.
* Copyright (C) 2004 Chris Schoeneman * Copyright (C) 2004 Chris Schoeneman
* *
* This package is free software; you can redistribute it and/or * This package is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
* found in the file LICENSE that should have accompanied this file. * found in the file LICENSE that should have accompanied this file.
* *
* This package is distributed in the hope that it will be useful, * This package is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
@ -26,12 +26,12 @@ class IEventQueue;
//! Implementation of ClientTaskBarReceiver for OS X //! Implementation of ClientTaskBarReceiver for OS X
class OSXClientTaskBarReceiver : public ClientTaskBarReceiver { class OSXClientTaskBarReceiver : public ClientTaskBarReceiver {
public: public:
OSXClientTaskBarReceiver(const BufferedLogOutputter*, IEventQueue* events); OSXClientTaskBarReceiver(const BufferedLogOutputter *, IEventQueue *events);
virtual ~OSXClientTaskBarReceiver(); virtual ~OSXClientTaskBarReceiver();
// IArchTaskBarReceiver overrides // IArchTaskBarReceiver overrides
virtual void showStatus(); virtual void showStatus();
virtual void runMenu(int x, int y); virtual void runMenu(int x, int y);
virtual void primaryAction(); virtual void primaryAction();
virtual const Icon getIcon() const; virtual const Icon getIcon() const;
}; };

View file

@ -2,11 +2,11 @@
* synergy -- mouse and keyboard sharing utility * synergy -- mouse and keyboard sharing utility
* Copyright (C) 2012-2016 Symless Ltd. * Copyright (C) 2012-2016 Symless Ltd.
* Copyright (C) 2003 Chris Schoeneman * Copyright (C) 2003 Chris Schoeneman
* *
* This package is free software; you can redistribute it and/or * This package is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
* found in the file LICENSE that should have accompanied this file. * found in the file LICENSE that should have accompanied this file.
* *
* This package is distributed in the hope that it will be useful, * This package is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
@ -24,45 +24,35 @@
// //
CXWindowsClientTaskBarReceiver::CXWindowsClientTaskBarReceiver( CXWindowsClientTaskBarReceiver::CXWindowsClientTaskBarReceiver(
const BufferedLogOutputter*, const BufferedLogOutputter *, IEventQueue *events)
IEventQueue* events) : : ClientTaskBarReceiver(events) {
ClientTaskBarReceiver(events) // add ourself to the task bar
{ ARCH->addReceiver(this);
// add ourself to the task bar
ARCH->addReceiver(this);
} }
CXWindowsClientTaskBarReceiver::~CXWindowsClientTaskBarReceiver() CXWindowsClientTaskBarReceiver::~CXWindowsClientTaskBarReceiver() {
{ ARCH->removeReceiver(this);
ARCH->removeReceiver(this);
} }
void void CXWindowsClientTaskBarReceiver::showStatus() {
CXWindowsClientTaskBarReceiver::showStatus() // do nothing
{
// do nothing
} }
void void CXWindowsClientTaskBarReceiver::runMenu(int, int) {
CXWindowsClientTaskBarReceiver::runMenu(int, int) // do nothing
{
// do nothing
} }
void void CXWindowsClientTaskBarReceiver::primaryAction() {
CXWindowsClientTaskBarReceiver::primaryAction() // do nothing
{
// do nothing
} }
const IArchTaskBarReceiver::Icon const IArchTaskBarReceiver::Icon
CXWindowsClientTaskBarReceiver::getIcon() const CXWindowsClientTaskBarReceiver::getIcon() const {
{ return NULL;
return NULL;
} }
IArchTaskBarReceiver* IArchTaskBarReceiver *
createTaskBarReceiver(const BufferedLogOutputter* logBuffer, IEventQueue* events) createTaskBarReceiver(const BufferedLogOutputter *logBuffer,
{ IEventQueue *events) {
return new CXWindowsClientTaskBarReceiver(logBuffer, events); return new CXWindowsClientTaskBarReceiver(logBuffer, events);
} }

View file

@ -2,11 +2,11 @@
* synergy -- mouse and keyboard sharing utility * synergy -- mouse and keyboard sharing utility
* Copyright (C) 2012-2016 Symless Ltd. * Copyright (C) 2012-2016 Symless Ltd.
* Copyright (C) 2003 Chris Schoeneman * Copyright (C) 2003 Chris Schoeneman
* *
* This package is free software; you can redistribute it and/or * This package is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
* found in the file LICENSE that should have accompanied this file. * found in the file LICENSE that should have accompanied this file.
* *
* This package is distributed in the hope that it will be useful, * This package is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
@ -26,18 +26,21 @@ class IEventQueue;
//! Implementation of ClientTaskBarReceiver for X Windows //! Implementation of ClientTaskBarReceiver for X Windows
class CXWindowsClientTaskBarReceiver : public ClientTaskBarReceiver { class CXWindowsClientTaskBarReceiver : public ClientTaskBarReceiver {
public: public:
CXWindowsClientTaskBarReceiver( CXWindowsClientTaskBarReceiver(const BufferedLogOutputter *,
const BufferedLogOutputter*, IEventQueue* events); IEventQueue *events);
CXWindowsClientTaskBarReceiver(const CXWindowsClientTaskBarReceiver &) =delete; CXWindowsClientTaskBarReceiver(const CXWindowsClientTaskBarReceiver &) =
CXWindowsClientTaskBarReceiver(CXWindowsClientTaskBarReceiver &&) =delete; delete;
virtual ~CXWindowsClientTaskBarReceiver(); CXWindowsClientTaskBarReceiver(CXWindowsClientTaskBarReceiver &&) = delete;
virtual ~CXWindowsClientTaskBarReceiver();
CXWindowsClientTaskBarReceiver& operator=(const CXWindowsClientTaskBarReceiver &) =delete; CXWindowsClientTaskBarReceiver &
CXWindowsClientTaskBarReceiver& operator=(CXWindowsClientTaskBarReceiver &&) =delete; operator=(const CXWindowsClientTaskBarReceiver &) = delete;
CXWindowsClientTaskBarReceiver &
operator=(CXWindowsClientTaskBarReceiver &&) = delete;
// IArchTaskBarReceiver overrides // IArchTaskBarReceiver overrides
virtual void showStatus(); virtual void showStatus();
virtual void runMenu(int x, int y); virtual void runMenu(int x, int y);
virtual void primaryAction(); virtual void primaryAction();
virtual const Icon getIcon() const; virtual const Icon getIcon() const;
}; };

View file

@ -2,36 +2,36 @@
// Microsoft Developer Studio generated include file. // Microsoft Developer Studio generated include file.
// Used by synergyc.rc // Used by synergyc.rc
// //
#define IDS_FAILED 1 #define IDS_FAILED 1
#define IDS_INIT_FAILED 2 #define IDS_INIT_FAILED 2
#define IDS_UNCAUGHT_EXCEPTION 3 #define IDS_UNCAUGHT_EXCEPTION 3
#define IDI_SYNERGY 101 #define IDI_SYNERGY 101
#define IDI_TASKBAR_NOT_RUNNING 102 #define IDI_TASKBAR_NOT_RUNNING 102
#define IDI_TASKBAR_NOT_WORKING 103 #define IDI_TASKBAR_NOT_WORKING 103
#define IDI_TASKBAR_NOT_CONNECTED 104 #define IDI_TASKBAR_NOT_CONNECTED 104
#define IDI_TASKBAR_CONNECTED 105 #define IDI_TASKBAR_CONNECTED 105
#define IDR_TASKBAR 107 #define IDR_TASKBAR 107
#define IDD_TASKBAR_STATUS 108 #define IDD_TASKBAR_STATUS 108
#define IDC_TASKBAR_STATUS_STATUS 1000 #define IDC_TASKBAR_STATUS_STATUS 1000
#define IDC_TASKBAR_QUIT 40001 #define IDC_TASKBAR_QUIT 40001
#define IDC_TASKBAR_STATUS 40002 #define IDC_TASKBAR_STATUS 40002
#define IDC_TASKBAR_LOG 40003 #define IDC_TASKBAR_LOG 40003
#define IDC_TASKBAR_SHOW_LOG 40004 #define IDC_TASKBAR_SHOW_LOG 40004
#define IDC_TASKBAR_LOG_LEVEL_ERROR 40009 #define IDC_TASKBAR_LOG_LEVEL_ERROR 40009
#define IDC_TASKBAR_LOG_LEVEL_WARNING 40010 #define IDC_TASKBAR_LOG_LEVEL_WARNING 40010
#define IDC_TASKBAR_LOG_LEVEL_NOTE 40011 #define IDC_TASKBAR_LOG_LEVEL_NOTE 40011
#define IDC_TASKBAR_LOG_LEVEL_INFO 40012 #define IDC_TASKBAR_LOG_LEVEL_INFO 40012
#define IDC_TASKBAR_LOG_LEVEL_DEBUG 40013 #define IDC_TASKBAR_LOG_LEVEL_DEBUG 40013
#define IDC_TASKBAR_LOG_LEVEL_DEBUG1 40014 #define IDC_TASKBAR_LOG_LEVEL_DEBUG1 40014
#define IDC_TASKBAR_LOG_LEVEL_DEBUG2 40015 #define IDC_TASKBAR_LOG_LEVEL_DEBUG2 40015
// Next default values for new objects // Next default values for new objects
// //
#ifdef APSTUDIO_INVOKED #ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS #ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 109 #define _APS_NEXT_RESOURCE_VALUE 109
#define _APS_NEXT_COMMAND_VALUE 40016 #define _APS_NEXT_COMMAND_VALUE 40016
#define _APS_NEXT_CONTROL_VALUE 1001 #define _APS_NEXT_CONTROL_VALUE 1001
#define _APS_NEXT_SYMED_VALUE 101 #define _APS_NEXT_SYMED_VALUE 101
#endif #endif
#endif #endif

View file

@ -2,11 +2,11 @@
* synergy -- mouse and keyboard sharing utility * synergy -- mouse and keyboard sharing utility
* Copyright (C) 2012-2016 Symless Ltd. * Copyright (C) 2012-2016 Symless Ltd.
* Copyright (C) 2002 Chris Schoeneman * Copyright (C) 2002 Chris Schoeneman
* *
* This package is free software; you can redistribute it and/or * This package is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
* found in the file LICENSE that should have accompanied this file. * found in the file LICENSE that should have accompanied this file.
* *
* This package is distributed in the hope that it will be useful, * This package is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
@ -16,10 +16,14 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include "synergy/ClientApp.h"
#include "arch/Arch.h" #include "arch/Arch.h"
#include "base/Log.h"
#include "base/EventQueue.h" #include "base/EventQueue.h"
#include "base/Log.h"
#include "synergy/ClientApp.h"
#if SYSAPI_WIN32
#include "arch/win32/ArchMiscWindows.h"
#endif
#if WINAPI_MSWINDOWS #if WINAPI_MSWINDOWS
#include "MSWindowsClientTaskBarReceiver.h" #include "MSWindowsClientTaskBarReceiver.h"
@ -31,20 +35,18 @@
#error Platform not supported. #error Platform not supported.
#endif #endif
int int main(int argc, char **argv) {
main(int argc, char** argv)
{
#if SYSAPI_WIN32 #if SYSAPI_WIN32
// record window instance for tray icon, etc // record window instance for tray icon, etc
ArchMiscWindows::setInstanceWin32(GetModuleHandle(NULL)); ArchMiscWindows::setInstanceWin32(GetModuleHandle(NULL));
#endif #endif
Arch arch;
arch.init();
Log log; Arch arch;
EventQueue events; arch.init();
ClientApp app(&events, createTaskBarReceiver); Log log;
return app.run(argc, argv); EventQueue events;
ClientApp app(&events, createTaskBarReceiver);
return app.run(argc, argv);
} }

View file

@ -2,11 +2,11 @@
* synergy -- mouse and keyboard sharing utility * synergy -- mouse and keyboard sharing utility
* Copyright (C) 2012-2016 Symless Ltd. * Copyright (C) 2012-2016 Symless Ltd.
* Copyright (C) 2012 Nick Bolton * Copyright (C) 2012 Nick Bolton
* *
* This package is free software; you can redistribute it and/or * This package is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
* found in the file LICENSE that should have accompanied this file. * found in the file LICENSE that should have accompanied this file.
* *
* This package is distributed in the hope that it will be useful, * This package is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
@ -22,11 +22,9 @@
#ifdef SYSAPI_UNIX #ifdef SYSAPI_UNIX
int int main(int argc, char **argv) {
main(int argc, char** argv) DaemonApp app;
{ return app.run(argc, argv);
DaemonApp app;
return app.run(argc, argv);
} }
#elif SYSAPI_WIN32 #elif SYSAPI_WIN32
@ -34,11 +32,9 @@ main(int argc, char** argv)
#define WIN32_LEAN_AND_MEAN #define WIN32_LEAN_AND_MEAN
#include <Windows.h> #include <Windows.h>
int WINAPI int WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int) {
WinMain(HINSTANCE, HINSTANCE, LPSTR, int) DaemonApp app;
{ return app.run(__argc, __argv);
DaemonApp app;
return app.run(__argc, __argv);
} }
#endif #endif

View file

@ -2,11 +2,11 @@
* synergy -- mouse and keyboard sharing utility * synergy -- mouse and keyboard sharing utility
* Copyright (C) 2012-2016 Symless Ltd. * Copyright (C) 2012-2016 Symless Ltd.
* Copyright (C) 2003 Chris Schoeneman * Copyright (C) 2003 Chris Schoeneman
* *
* This package is free software; you can redistribute it and/or * This package is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
* found in the file LICENSE that should have accompanied this file. * found in the file LICENSE that should have accompanied this file.
* *
* This package is distributed in the hope that it will be useful, * This package is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
@ -18,391 +18,339 @@
#include "MSWindowsServerTaskBarReceiver.h" #include "MSWindowsServerTaskBarReceiver.h"
#include "resource.h"
#include "server/Server.h"
#include "platform/MSWindowsClipboard.h"
#include "platform/MSWindowsScreen.h"
#include "arch/win32/ArchTaskBarWindows.h"
#include "arch/win32/ArchMiscWindows.h"
#include "arch/Arch.h" #include "arch/Arch.h"
#include "arch/win32/ArchMiscWindows.h"
#include "arch/win32/ArchTaskBarWindows.h"
#include "base/EventQueue.h" #include "base/EventQueue.h"
#include "base/EventTypes.h"
#include "base/IEventQueue.h" #include "base/IEventQueue.h"
#include "base/log_outputters.h" #include "base/log_outputters.h"
#include "base/EventTypes.h" #include "platform/MSWindowsClipboard.h"
#include "platform/MSWindowsScreen.h"
#include "resource.h"
#include "server/Server.h"
// //
// MSWindowsServerTaskBarReceiver // MSWindowsServerTaskBarReceiver
// //
const UINT MSWindowsServerTaskBarReceiver::s_stateToIconID[kMaxState] = const UINT MSWindowsServerTaskBarReceiver::s_stateToIconID[kMaxState] = {
{ IDI_TASKBAR_NOT_RUNNING, IDI_TASKBAR_NOT_WORKING, IDI_TASKBAR_NOT_CONNECTED,
IDI_TASKBAR_NOT_RUNNING, IDI_TASKBAR_CONNECTED};
IDI_TASKBAR_NOT_WORKING,
IDI_TASKBAR_NOT_CONNECTED,
IDI_TASKBAR_CONNECTED
};
MSWindowsServerTaskBarReceiver::MSWindowsServerTaskBarReceiver( MSWindowsServerTaskBarReceiver::MSWindowsServerTaskBarReceiver(
HINSTANCE appInstance, const BufferedLogOutputter* logBuffer, IEventQueue* events) : HINSTANCE appInstance, const BufferedLogOutputter *logBuffer,
ServerTaskBarReceiver(events), IEventQueue *events)
m_events(events), : ServerTaskBarReceiver(events), m_events(events),
m_appInstance(appInstance), m_appInstance(appInstance), m_window(NULL), m_logBuffer(logBuffer) {
m_window(NULL), for (UInt32 i = 0; i < kMaxState; ++i) {
m_logBuffer(logBuffer) m_icon[i] = loadIcon(s_stateToIconID[i]);
{ }
for (UInt32 i = 0; i < kMaxState; ++i) { m_menu = LoadMenu(m_appInstance, MAKEINTRESOURCE(IDR_TASKBAR));
m_icon[i] = loadIcon(s_stateToIconID[i]);
}
m_menu = LoadMenu(m_appInstance, MAKEINTRESOURCE(IDR_TASKBAR));
// don't create the window yet. we'll create it on demand. this // don't create the window yet. we'll create it on demand. this
// has the side benefit of being created in the thread used for // has the side benefit of being created in the thread used for
// the task bar. that's good because it means the existence of // the task bar. that's good because it means the existence of
// the window won't prevent changing the main thread's desktop. // the window won't prevent changing the main thread's desktop.
// add ourself to the task bar // add ourself to the task bar
ARCH->addReceiver(this); ARCH->addReceiver(this);
} }
void void MSWindowsServerTaskBarReceiver::cleanup() {
MSWindowsServerTaskBarReceiver::cleanup() ARCH->removeReceiver(this);
{ for (UInt32 i = 0; i < kMaxState; ++i) {
ARCH->removeReceiver(this); deleteIcon(m_icon[i]);
for (UInt32 i = 0; i < kMaxState; ++i) { }
deleteIcon(m_icon[i]); DestroyMenu(m_menu);
} destroyWindow();
DestroyMenu(m_menu);
destroyWindow();
} }
MSWindowsServerTaskBarReceiver::~MSWindowsServerTaskBarReceiver() MSWindowsServerTaskBarReceiver::~MSWindowsServerTaskBarReceiver() { cleanup(); }
{
cleanup(); void MSWindowsServerTaskBarReceiver::showStatus() {
// create the window
createWindow();
// lock self while getting status
lock();
// get the current status
std::string status = getToolTip();
// get the connect clients, if any
const Clients &clients = getClients();
// done getting status
unlock();
// update dialog
HWND child = GetDlgItem(m_window, IDC_TASKBAR_STATUS_STATUS);
SendMessage(child, WM_SETTEXT, 0, (LPARAM)status.c_str());
child = GetDlgItem(m_window, IDC_TASKBAR_STATUS_CLIENTS);
SendMessage(child, LB_RESETCONTENT, 0, 0);
for (Clients::const_iterator index = clients.begin();
index != clients.end();) {
const char *client = index->c_str();
if (++index == clients.end()) {
SendMessage(child, LB_ADDSTRING, 0, (LPARAM)client);
} else {
SendMessage(child, LB_INSERTSTRING, (WPARAM)-1, (LPARAM)client);
}
}
if (!IsWindowVisible(m_window)) {
// position it by the mouse
POINT cursorPos;
GetCursorPos(&cursorPos);
RECT windowRect;
GetWindowRect(m_window, &windowRect);
int x = cursorPos.x;
int y = cursorPos.y;
int fw = GetSystemMetrics(SM_CXDLGFRAME);
int fh = GetSystemMetrics(SM_CYDLGFRAME);
int ww = windowRect.right - windowRect.left;
int wh = windowRect.bottom - windowRect.top;
int sw = GetSystemMetrics(SM_CXFULLSCREEN);
int sh = GetSystemMetrics(SM_CYFULLSCREEN);
if (fw < 1) {
fw = 1;
}
if (fh < 1) {
fh = 1;
}
if (x + ww - fw > sw) {
x -= ww - fw;
} else {
x -= fw;
}
if (x < 0) {
x = 0;
}
if (y + wh - fh > sh) {
y -= wh - fh;
} else {
y -= fh;
}
if (y < 0) {
y = 0;
}
SetWindowPos(m_window, HWND_TOPMOST, x, y, ww, wh, SWP_SHOWWINDOW);
}
} }
void void MSWindowsServerTaskBarReceiver::runMenu(int x, int y) {
MSWindowsServerTaskBarReceiver::showStatus() // do popup menu. we need a window to pass to TrackPopupMenu().
{ // the SetForegroundWindow() and SendMessage() calls around
// create the window // TrackPopupMenu() are to get the menu to be dismissed when
createWindow(); // another window gets activated and are just one of those
// win32 weirdnesses.
createWindow();
SetForegroundWindow(m_window);
HMENU menu = GetSubMenu(m_menu, 0);
SetMenuDefaultItem(menu, IDC_TASKBAR_STATUS, FALSE);
HMENU logLevelMenu = GetSubMenu(menu, 3);
CheckMenuRadioItem(logLevelMenu, 0, 6, CLOG->getFilter() - kERROR,
MF_BYPOSITION);
int n = TrackPopupMenu(
menu, TPM_NONOTIFY | TPM_RETURNCMD | TPM_LEFTBUTTON | TPM_RIGHTBUTTON, x,
y, 0, m_window, NULL);
SendMessage(m_window, WM_NULL, 0, 0);
// lock self while getting status // perform the requested operation
lock(); switch (n) {
case IDC_TASKBAR_STATUS:
// get the current status
std::string status = getToolTip();
// get the connect clients, if any
const Clients& clients = getClients();
// done getting status
unlock();
// update dialog
HWND child = GetDlgItem(m_window, IDC_TASKBAR_STATUS_STATUS);
SendMessage(child, WM_SETTEXT, 0, (LPARAM)status.c_str());
child = GetDlgItem(m_window, IDC_TASKBAR_STATUS_CLIENTS);
SendMessage(child, LB_RESETCONTENT, 0, 0);
for (Clients::const_iterator index = clients.begin();
index != clients.end(); ) {
const char* client = index->c_str();
if (++index == clients.end()) {
SendMessage(child, LB_ADDSTRING, 0, (LPARAM)client);
}
else {
SendMessage(child, LB_INSERTSTRING, (WPARAM)-1, (LPARAM)client);
}
}
if (!IsWindowVisible(m_window)) {
// position it by the mouse
POINT cursorPos;
GetCursorPos(&cursorPos);
RECT windowRect;
GetWindowRect(m_window, &windowRect);
int x = cursorPos.x;
int y = cursorPos.y;
int fw = GetSystemMetrics(SM_CXDLGFRAME);
int fh = GetSystemMetrics(SM_CYDLGFRAME);
int ww = windowRect.right - windowRect.left;
int wh = windowRect.bottom - windowRect.top;
int sw = GetSystemMetrics(SM_CXFULLSCREEN);
int sh = GetSystemMetrics(SM_CYFULLSCREEN);
if (fw < 1) {
fw = 1;
}
if (fh < 1) {
fh = 1;
}
if (x + ww - fw > sw) {
x -= ww - fw;
}
else {
x -= fw;
}
if (x < 0) {
x = 0;
}
if (y + wh - fh > sh) {
y -= wh - fh;
}
else {
y -= fh;
}
if (y < 0) {
y = 0;
}
SetWindowPos(m_window, HWND_TOPMOST, x, y, ww, wh,
SWP_SHOWWINDOW);
}
}
void
MSWindowsServerTaskBarReceiver::runMenu(int x, int y)
{
// do popup menu. we need a window to pass to TrackPopupMenu().
// the SetForegroundWindow() and SendMessage() calls around
// TrackPopupMenu() are to get the menu to be dismissed when
// another window gets activated and are just one of those
// win32 weirdnesses.
createWindow();
SetForegroundWindow(m_window);
HMENU menu = GetSubMenu(m_menu, 0);
SetMenuDefaultItem(menu, IDC_TASKBAR_STATUS, FALSE);
HMENU logLevelMenu = GetSubMenu(menu, 3);
CheckMenuRadioItem(logLevelMenu, 0, 6,
CLOG->getFilter() - kERROR, MF_BYPOSITION);
int n = TrackPopupMenu(menu,
TPM_NONOTIFY |
TPM_RETURNCMD |
TPM_LEFTBUTTON |
TPM_RIGHTBUTTON,
x, y, 0, m_window, NULL);
SendMessage(m_window, WM_NULL, 0, 0);
// perform the requested operation
switch (n) {
case IDC_TASKBAR_STATUS:
showStatus();
break;
case IDC_TASKBAR_LOG:
copyLog();
break;
case IDC_TASKBAR_SHOW_LOG:
ARCH->showConsole(true);
break;
case IDC_RELOAD_CONFIG:
m_events->addEvent(Event(m_events->forServerApp().reloadConfig(),
m_events->getSystemTarget()));
break;
case IDC_FORCE_RECONNECT:
m_events->addEvent(Event(m_events->forServerApp().forceReconnect(),
m_events->getSystemTarget()));
break;
case ID_SYNERGY_RESETSERVER:
m_events->addEvent(Event(m_events->forServerApp().resetServer(),
m_events->getSystemTarget()));
break;
case IDC_TASKBAR_LOG_LEVEL_ERROR:
CLOG->setFilter(kERROR);
break;
case IDC_TASKBAR_LOG_LEVEL_WARNING:
CLOG->setFilter(kWARNING);
break;
case IDC_TASKBAR_LOG_LEVEL_NOTE:
CLOG->setFilter(kNOTE);
break;
case IDC_TASKBAR_LOG_LEVEL_INFO:
CLOG->setFilter(kINFO);
break;
case IDC_TASKBAR_LOG_LEVEL_DEBUG:
CLOG->setFilter(kDEBUG);
break;
case IDC_TASKBAR_LOG_LEVEL_DEBUG1:
CLOG->setFilter(kDEBUG1);
break;
case IDC_TASKBAR_LOG_LEVEL_DEBUG2:
CLOG->setFilter(kDEBUG2);
break;
case IDC_TASKBAR_QUIT:
quit();
break;
}
}
void
MSWindowsServerTaskBarReceiver::primaryAction()
{
showStatus(); showStatus();
break;
case IDC_TASKBAR_LOG:
copyLog();
break;
case IDC_TASKBAR_SHOW_LOG:
ARCH->showConsole(true);
break;
case IDC_RELOAD_CONFIG:
m_events->addEvent(Event(m_events->forServerApp().reloadConfig(),
m_events->getSystemTarget()));
break;
case IDC_FORCE_RECONNECT:
m_events->addEvent(Event(m_events->forServerApp().forceReconnect(),
m_events->getSystemTarget()));
break;
case ID_SYNERGY_RESETSERVER:
m_events->addEvent(Event(m_events->forServerApp().resetServer(),
m_events->getSystemTarget()));
break;
case IDC_TASKBAR_LOG_LEVEL_ERROR:
CLOG->setFilter(kERROR);
break;
case IDC_TASKBAR_LOG_LEVEL_WARNING:
CLOG->setFilter(kWARNING);
break;
case IDC_TASKBAR_LOG_LEVEL_NOTE:
CLOG->setFilter(kNOTE);
break;
case IDC_TASKBAR_LOG_LEVEL_INFO:
CLOG->setFilter(kINFO);
break;
case IDC_TASKBAR_LOG_LEVEL_DEBUG:
CLOG->setFilter(kDEBUG);
break;
case IDC_TASKBAR_LOG_LEVEL_DEBUG1:
CLOG->setFilter(kDEBUG1);
break;
case IDC_TASKBAR_LOG_LEVEL_DEBUG2:
CLOG->setFilter(kDEBUG2);
break;
case IDC_TASKBAR_QUIT:
quit();
break;
}
} }
void MSWindowsServerTaskBarReceiver::primaryAction() { showStatus(); }
const IArchTaskBarReceiver::Icon const IArchTaskBarReceiver::Icon
MSWindowsServerTaskBarReceiver::getIcon() const MSWindowsServerTaskBarReceiver::getIcon() const {
{ return static_cast<Icon>(m_icon[getStatus()]);
return static_cast<Icon>(m_icon[getStatus()]);
} }
void void MSWindowsServerTaskBarReceiver::copyLog() const {
MSWindowsServerTaskBarReceiver::copyLog() const if (m_logBuffer != NULL) {
{ // collect log buffer
if (m_logBuffer != NULL) { String data;
// collect log buffer for (BufferedLogOutputter::const_iterator index = m_logBuffer->begin();
String data; index != m_logBuffer->end(); ++index) {
for (BufferedLogOutputter::const_iterator index = m_logBuffer->begin(); data += *index;
index != m_logBuffer->end(); ++index) { data += "\n";
data += *index;
data += "\n";
}
// copy log to clipboard
if (!data.empty()) {
MSWindowsClipboard clipboard(m_window);
clipboard.open(0);
clipboard.emptyUnowned();
clipboard.add(IClipboard::kText, data);
clipboard.close();
}
} }
// copy log to clipboard
if (!data.empty()) {
MSWindowsClipboard clipboard(m_window);
clipboard.open(0);
clipboard.emptyUnowned();
clipboard.add(IClipboard::kText, data);
clipboard.close();
}
}
} }
void void MSWindowsServerTaskBarReceiver::onStatusChanged() {
MSWindowsServerTaskBarReceiver::onStatusChanged() if (IsWindowVisible(m_window)) {
{ showStatus();
if (IsWindowVisible(m_window)) { }
showStatus();
}
} }
HICON HICON
MSWindowsServerTaskBarReceiver::loadIcon(UINT id) MSWindowsServerTaskBarReceiver::loadIcon(UINT id) {
{ HANDLE icon = LoadImage(m_appInstance, MAKEINTRESOURCE(id), IMAGE_ICON, 0, 0,
HANDLE icon = LoadImage(m_appInstance, LR_DEFAULTCOLOR);
MAKEINTRESOURCE(id), return static_cast<HICON>(icon);
IMAGE_ICON,
0, 0,
LR_DEFAULTCOLOR);
return static_cast<HICON>(icon);
} }
void void MSWindowsServerTaskBarReceiver::deleteIcon(HICON icon) {
MSWindowsServerTaskBarReceiver::deleteIcon(HICON icon) if (icon != NULL) {
{ DestroyIcon(icon);
if (icon != NULL) { }
DestroyIcon(icon);
}
} }
void void MSWindowsServerTaskBarReceiver::createWindow() {
MSWindowsServerTaskBarReceiver::createWindow() // ignore if already created
{ if (m_window != NULL) {
// ignore if already created return;
if (m_window != NULL) { }
return;
}
// get the status dialog // get the status dialog
m_window = CreateDialogParam(m_appInstance, m_window = CreateDialogParam(
MAKEINTRESOURCE(IDD_TASKBAR_STATUS), m_appInstance, MAKEINTRESOURCE(IDD_TASKBAR_STATUS), NULL,
NULL, (DLGPROC)&MSWindowsServerTaskBarReceiver::staticDlgProc,
(DLGPROC)&MSWindowsServerTaskBarReceiver::staticDlgProc, reinterpret_cast<LPARAM>(static_cast<void *>(this)));
reinterpret_cast<LPARAM>(
static_cast<void*>(this)));
// window should appear on top of everything, including (especially) // window should appear on top of everything, including (especially)
// the task bar. // the task bar.
LONG_PTR style = GetWindowLongPtr(m_window, GWL_EXSTYLE); LONG_PTR style = GetWindowLongPtr(m_window, GWL_EXSTYLE);
style |= WS_EX_TOOLWINDOW | WS_EX_TOPMOST; style |= WS_EX_TOOLWINDOW | WS_EX_TOPMOST;
SetWindowLongPtr(m_window, GWL_EXSTYLE, style); SetWindowLongPtr(m_window, GWL_EXSTYLE, style);
// tell the task bar about this dialog // tell the task bar about this dialog
ArchTaskBarWindows::addDialog(m_window); ArchTaskBarWindows::addDialog(m_window);
} }
void void MSWindowsServerTaskBarReceiver::destroyWindow() {
MSWindowsServerTaskBarReceiver::destroyWindow() if (m_window != NULL) {
{ ArchTaskBarWindows::removeDialog(m_window);
if (m_window != NULL) { DestroyWindow(m_window);
ArchTaskBarWindows::removeDialog(m_window); m_window = NULL;
DestroyWindow(m_window); }
m_window = NULL;
}
} }
BOOL BOOL MSWindowsServerTaskBarReceiver::dlgProc(HWND hwnd, UINT msg, WPARAM wParam,
MSWindowsServerTaskBarReceiver::dlgProc(HWND hwnd, LPARAM) {
UINT msg, WPARAM wParam, LPARAM) switch (msg) {
{ case WM_INITDIALOG:
switch (msg) { // use default focus
case WM_INITDIALOG: return TRUE;
// use default focus
return TRUE;
case WM_ACTIVATE: case WM_ACTIVATE:
// hide when another window is activated // hide when another window is activated
if (LOWORD(wParam) == WA_INACTIVE) { if (LOWORD(wParam) == WA_INACTIVE) {
ShowWindow(hwnd, SW_HIDE); ShowWindow(hwnd, SW_HIDE);
}
break;
} }
return FALSE; break;
}
return FALSE;
} }
BOOL CALLBACK BOOL CALLBACK MSWindowsServerTaskBarReceiver::staticDlgProc(HWND hwnd, UINT msg,
MSWindowsServerTaskBarReceiver::staticDlgProc(HWND hwnd, WPARAM wParam,
UINT msg, WPARAM wParam, LPARAM lParam) LPARAM lParam) {
{ // if msg is WM_INITDIALOG, extract the MSWindowsServerTaskBarReceiver*
// if msg is WM_INITDIALOG, extract the MSWindowsServerTaskBarReceiver* // and put it in the extra window data then forward the call.
// and put it in the extra window data then forward the call. MSWindowsServerTaskBarReceiver *self = NULL;
MSWindowsServerTaskBarReceiver* self = NULL; if (msg == WM_INITDIALOG) {
if (msg == WM_INITDIALOG) { self = static_cast<MSWindowsServerTaskBarReceiver *>(
self = static_cast<MSWindowsServerTaskBarReceiver*>( reinterpret_cast<void *>(lParam));
reinterpret_cast<void*>(lParam)); SetWindowLongPtr(hwnd, GWLP_USERDATA, lParam);
SetWindowLongPtr(hwnd, GWLP_USERDATA, lParam); } else {
} // get the extra window data and forward the call
else { LONG_PTR data = GetWindowLongPtr(hwnd, GWLP_USERDATA);
// get the extra window data and forward the call if (data != 0) {
LONG_PTR data = GetWindowLongPtr(hwnd, GWLP_USERDATA); self = static_cast<MSWindowsServerTaskBarReceiver *>(
if (data != 0) { reinterpret_cast<void *>(data));
self = static_cast<MSWindowsServerTaskBarReceiver*>(
reinterpret_cast<void*>(data));
}
} }
}
// forward the message // forward the message
if (self != NULL) { if (self != NULL) {
return self->dlgProc(hwnd, msg, wParam, lParam); return self->dlgProc(hwnd, msg, wParam, lParam);
} } else {
else { return (msg == WM_INITDIALOG) ? TRUE : FALSE;
return (msg == WM_INITDIALOG) ? TRUE : FALSE; }
}
} }
IArchTaskBarReceiver* IArchTaskBarReceiver *
createTaskBarReceiver(const BufferedLogOutputter* logBuffer, IEventQueue* events) createTaskBarReceiver(const BufferedLogOutputter *logBuffer,
{ IEventQueue *events) {
ArchMiscWindows::setIcons( ArchMiscWindows::setIcons((HICON)LoadImage(ArchMiscWindows::instanceWin32(),
(HICON)LoadImage(ArchMiscWindows::instanceWin32(), MAKEINTRESOURCE(IDI_SYNERGY),
MAKEINTRESOURCE(IDI_SYNERGY), IMAGE_ICON, 32, 32, LR_SHARED),
IMAGE_ICON, (HICON)LoadImage(ArchMiscWindows::instanceWin32(),
32, 32, LR_SHARED), MAKEINTRESOURCE(IDI_SYNERGY),
(HICON)LoadImage(ArchMiscWindows::instanceWin32(), IMAGE_ICON, 16, 16, LR_SHARED));
MAKEINTRESOURCE(IDI_SYNERGY),
IMAGE_ICON,
16, 16, LR_SHARED));
return new MSWindowsServerTaskBarReceiver( return new MSWindowsServerTaskBarReceiver(
MSWindowsScreen::getWindowInstance(), logBuffer, events); MSWindowsScreen::getWindowInstance(), logBuffer, events);
} }

View file

@ -2,11 +2,11 @@
* synergy -- mouse and keyboard sharing utility * synergy -- mouse and keyboard sharing utility
* Copyright (C) 2012-2016 Symless Ltd. * Copyright (C) 2012-2016 Symless Ltd.
* Copyright (C) 2003 Chris Schoeneman * Copyright (C) 2003 Chris Schoeneman
* *
* This package is free software; you can redistribute it and/or * This package is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
* found in the file LICENSE that should have accompanied this file. * found in the file LICENSE that should have accompanied this file.
* *
* This package is distributed in the hope that it will be useful, * This package is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
@ -29,41 +29,40 @@ class IEventQueue;
//! Implementation of ServerTaskBarReceiver for Microsoft Windows //! Implementation of ServerTaskBarReceiver for Microsoft Windows
class MSWindowsServerTaskBarReceiver : public ServerTaskBarReceiver { class MSWindowsServerTaskBarReceiver : public ServerTaskBarReceiver {
public: public:
MSWindowsServerTaskBarReceiver(HINSTANCE, const BufferedLogOutputter*, IEventQueue* events); MSWindowsServerTaskBarReceiver(HINSTANCE, const BufferedLogOutputter *,
virtual ~MSWindowsServerTaskBarReceiver(); IEventQueue *events);
virtual ~MSWindowsServerTaskBarReceiver();
// IArchTaskBarReceiver overrides // IArchTaskBarReceiver overrides
virtual void showStatus(); virtual void showStatus();
virtual void runMenu(int x, int y); virtual void runMenu(int x, int y);
virtual void primaryAction(); virtual void primaryAction();
virtual const Icon getIcon() const; virtual const Icon getIcon() const;
void cleanup(); void cleanup();
protected: protected:
void copyLog() const; void copyLog() const;
// ServerTaskBarReceiver overrides // ServerTaskBarReceiver overrides
virtual void onStatusChanged(); virtual void onStatusChanged();
private: private:
HICON loadIcon(UINT); HICON loadIcon(UINT);
void deleteIcon(HICON); void deleteIcon(HICON);
void createWindow(); void createWindow();
void destroyWindow(); void destroyWindow();
BOOL dlgProc(HWND hwnd, BOOL dlgProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
UINT msg, WPARAM wParam, LPARAM lParam); static BOOL CALLBACK staticDlgProc(HWND hwnd, UINT msg, WPARAM wParam,
static BOOL CALLBACK LPARAM lParam);
staticDlgProc(HWND hwnd,
UINT msg, WPARAM wParam, LPARAM lParam);
private: private:
HINSTANCE m_appInstance; HINSTANCE m_appInstance;
HWND m_window; HWND m_window;
HMENU m_menu; HMENU m_menu;
HICON m_icon[kMaxState]; HICON m_icon[kMaxState];
const BufferedLogOutputter* m_logBuffer; const BufferedLogOutputter *m_logBuffer;
IEventQueue* m_events; IEventQueue *m_events;
static const UINT s_stateToIconID[]; static const UINT s_stateToIconID[];
}; };

View file

@ -2,11 +2,11 @@
* synergy -- mouse and keyboard sharing utility * synergy -- mouse and keyboard sharing utility
* Copyright (C) 2012-2016 Symless Ltd. * Copyright (C) 2012-2016 Symless Ltd.
* Copyright (C) 2004 Chris Schoeneman * Copyright (C) 2004 Chris Schoeneman
* *
* This package is free software; you can redistribute it and/or * This package is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
* found in the file LICENSE that should have accompanied this file. * found in the file LICENSE that should have accompanied this file.
* *
* This package is distributed in the hope that it will be useful, * This package is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
@ -23,45 +23,35 @@
// OSXServerTaskBarReceiver // OSXServerTaskBarReceiver
// //
OSXServerTaskBarReceiver::OSXServerTaskBarReceiver( OSXServerTaskBarReceiver::OSXServerTaskBarReceiver(const BufferedLogOutputter *,
const BufferedLogOutputter*, IEventQueue* events) : IEventQueue *events)
ServerTaskBarReceiver(events) : ServerTaskBarReceiver(events) {
{ // add ourself to the task bar
// add ourself to the task bar ARCH->addReceiver(this);
ARCH->addReceiver(this);
} }
OSXServerTaskBarReceiver::~OSXServerTaskBarReceiver() OSXServerTaskBarReceiver::~OSXServerTaskBarReceiver() {
{ ARCH->removeReceiver(this);
ARCH->removeReceiver(this);
} }
void void OSXServerTaskBarReceiver::showStatus() {
OSXServerTaskBarReceiver::showStatus() // do nothing
{
// do nothing
} }
void void OSXServerTaskBarReceiver::runMenu(int, int) {
OSXServerTaskBarReceiver::runMenu(int, int) // do nothing
{
// do nothing
} }
void void OSXServerTaskBarReceiver::primaryAction() {
OSXServerTaskBarReceiver::primaryAction() // do nothing
{
// do nothing
} }
const IArchTaskBarReceiver::Icon const IArchTaskBarReceiver::Icon OSXServerTaskBarReceiver::getIcon() const {
OSXServerTaskBarReceiver::getIcon() const return NULL;
{
return NULL;
} }
IArchTaskBarReceiver* IArchTaskBarReceiver *
createTaskBarReceiver(const BufferedLogOutputter* logBuffer, IEventQueue* events) createTaskBarReceiver(const BufferedLogOutputter *logBuffer,
{ IEventQueue *events) {
return new OSXServerTaskBarReceiver(logBuffer, events); return new OSXServerTaskBarReceiver(logBuffer, events);
} }

View file

@ -2,11 +2,11 @@
* synergy -- mouse and keyboard sharing utility * synergy -- mouse and keyboard sharing utility
* Copyright (C) 2012-2016 Symless Ltd. * Copyright (C) 2012-2016 Symless Ltd.
* Copyright (C) 2004 Chris Schoeneman * Copyright (C) 2004 Chris Schoeneman
* *
* This package is free software; you can redistribute it and/or * This package is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
* found in the file LICENSE that should have accompanied this file. * found in the file LICENSE that should have accompanied this file.
* *
* This package is distributed in the hope that it will be useful, * This package is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
@ -25,12 +25,12 @@ class BufferedLogOutputter;
//! Implementation of ServerTaskBarReceiver for OS X //! Implementation of ServerTaskBarReceiver for OS X
class OSXServerTaskBarReceiver : public ServerTaskBarReceiver { class OSXServerTaskBarReceiver : public ServerTaskBarReceiver {
public: public:
OSXServerTaskBarReceiver(const BufferedLogOutputter*, IEventQueue* events); OSXServerTaskBarReceiver(const BufferedLogOutputter *, IEventQueue *events);
virtual ~OSXServerTaskBarReceiver(); virtual ~OSXServerTaskBarReceiver();
// IArchTaskBarReceiver overrides // IArchTaskBarReceiver overrides
virtual void showStatus(); virtual void showStatus();
virtual void runMenu(int x, int y); virtual void runMenu(int x, int y);
virtual void primaryAction(); virtual void primaryAction();
virtual const Icon getIcon() const; virtual const Icon getIcon() const;
}; };

View file

@ -2,11 +2,11 @@
* synergy -- mouse and keyboard sharing utility * synergy -- mouse and keyboard sharing utility
* Copyright (C) 2012-2016 Symless Ltd. * Copyright (C) 2012-2016 Symless Ltd.
* Copyright (C) 2003 Chris Schoeneman * Copyright (C) 2003 Chris Schoeneman
* *
* This package is free software; you can redistribute it and/or * This package is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
* found in the file LICENSE that should have accompanied this file. * found in the file LICENSE that should have accompanied this file.
* *
* This package is distributed in the hope that it will be useful, * This package is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
@ -24,44 +24,35 @@
// //
CXWindowsServerTaskBarReceiver::CXWindowsServerTaskBarReceiver( CXWindowsServerTaskBarReceiver::CXWindowsServerTaskBarReceiver(
const BufferedLogOutputter*, IEventQueue* events) : const BufferedLogOutputter *, IEventQueue *events)
ServerTaskBarReceiver(events) : ServerTaskBarReceiver(events) {
{ // add ourself to the task bar
// add ourself to the task bar ARCH->addReceiver(this);
ARCH->addReceiver(this);
} }
CXWindowsServerTaskBarReceiver::~CXWindowsServerTaskBarReceiver() CXWindowsServerTaskBarReceiver::~CXWindowsServerTaskBarReceiver() {
{ ARCH->removeReceiver(this);
ARCH->removeReceiver(this);
} }
void void CXWindowsServerTaskBarReceiver::showStatus() {
CXWindowsServerTaskBarReceiver::showStatus() // do nothing
{
// do nothing
} }
void void CXWindowsServerTaskBarReceiver::runMenu(int, int) {
CXWindowsServerTaskBarReceiver::runMenu(int, int) // do nothing
{
// do nothing
} }
void void CXWindowsServerTaskBarReceiver::primaryAction() {
CXWindowsServerTaskBarReceiver::primaryAction() // do nothing
{
// do nothing
} }
const IArchTaskBarReceiver::Icon const IArchTaskBarReceiver::Icon
CXWindowsServerTaskBarReceiver::getIcon() const CXWindowsServerTaskBarReceiver::getIcon() const {
{ return NULL;
return NULL;
} }
IArchTaskBarReceiver* IArchTaskBarReceiver *
createTaskBarReceiver(const BufferedLogOutputter* logBuffer, IEventQueue* events) createTaskBarReceiver(const BufferedLogOutputter *logBuffer,
{ IEventQueue *events) {
return new CXWindowsServerTaskBarReceiver(logBuffer, events); return new CXWindowsServerTaskBarReceiver(logBuffer, events);
} }

View file

@ -2,11 +2,11 @@
* synergy -- mouse and keyboard sharing utility * synergy -- mouse and keyboard sharing utility
* Copyright (C) 2012-2016 Symless Ltd. * Copyright (C) 2012-2016 Symless Ltd.
* Copyright (C) 2003 Chris Schoeneman * Copyright (C) 2003 Chris Schoeneman
* *
* This package is free software; you can redistribute it and/or * This package is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
* found in the file LICENSE that should have accompanied this file. * found in the file LICENSE that should have accompanied this file.
* *
* This package is distributed in the hope that it will be useful, * This package is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
@ -26,18 +26,21 @@ class IEventQueue;
//! Implementation of ServerTaskBarReceiver for X Windows //! Implementation of ServerTaskBarReceiver for X Windows
class CXWindowsServerTaskBarReceiver : public ServerTaskBarReceiver { class CXWindowsServerTaskBarReceiver : public ServerTaskBarReceiver {
public: public:
CXWindowsServerTaskBarReceiver( CXWindowsServerTaskBarReceiver(const BufferedLogOutputter *,
const BufferedLogOutputter*, IEventQueue* events); IEventQueue *events);
CXWindowsServerTaskBarReceiver(const CXWindowsServerTaskBarReceiver&) =delete; CXWindowsServerTaskBarReceiver(const CXWindowsServerTaskBarReceiver &) =
CXWindowsServerTaskBarReceiver(CXWindowsServerTaskBarReceiver&&) =delete; delete;
virtual ~CXWindowsServerTaskBarReceiver(); CXWindowsServerTaskBarReceiver(CXWindowsServerTaskBarReceiver &&) = delete;
virtual ~CXWindowsServerTaskBarReceiver();
CXWindowsServerTaskBarReceiver& operator=(const CXWindowsServerTaskBarReceiver&) =delete;
CXWindowsServerTaskBarReceiver& operator=(const CXWindowsServerTaskBarReceiver&&) =delete;
// IArchTaskBarReceiver overrides CXWindowsServerTaskBarReceiver &
virtual void showStatus(); operator=(const CXWindowsServerTaskBarReceiver &) = delete;
virtual void runMenu(int x, int y); CXWindowsServerTaskBarReceiver &
virtual void primaryAction(); operator=(const CXWindowsServerTaskBarReceiver &&) = delete;
virtual const Icon getIcon() const;
// IArchTaskBarReceiver overrides
virtual void showStatus();
virtual void runMenu(int x, int y);
virtual void primaryAction();
virtual const Icon getIcon() const;
}; };

View file

@ -2,41 +2,41 @@
// Microsoft Visual C++ generated include file. // Microsoft Visual C++ generated include file.
// Used by synergys.rc // Used by synergys.rc
// //
#define IDS_FAILED 1 #define IDS_FAILED 1
#define IDS_INIT_FAILED 2 #define IDS_INIT_FAILED 2
#define IDS_UNCAUGHT_EXCEPTION 3 #define IDS_UNCAUGHT_EXCEPTION 3
#define IDI_SYNERGY 101 #define IDI_SYNERGY 101
#define IDI_TASKBAR_NOT_RUNNING 102 #define IDI_TASKBAR_NOT_RUNNING 102
#define IDI_TASKBAR_NOT_WORKING 103 #define IDI_TASKBAR_NOT_WORKING 103
#define IDI_TASKBAR_NOT_CONNECTED 104 #define IDI_TASKBAR_NOT_CONNECTED 104
#define IDI_TASKBAR_CONNECTED 105 #define IDI_TASKBAR_CONNECTED 105
#define IDR_TASKBAR 107 #define IDR_TASKBAR 107
#define IDD_TASKBAR_STATUS 108 #define IDD_TASKBAR_STATUS 108
#define IDC_TASKBAR_STATUS_STATUS 1000 #define IDC_TASKBAR_STATUS_STATUS 1000
#define IDC_TASKBAR_STATUS_CLIENTS 1001 #define IDC_TASKBAR_STATUS_CLIENTS 1001
#define IDC_TASKBAR_QUIT 40003 #define IDC_TASKBAR_QUIT 40003
#define IDC_TASKBAR_STATUS 40004 #define IDC_TASKBAR_STATUS 40004
#define IDC_TASKBAR_LOG 40005 #define IDC_TASKBAR_LOG 40005
#define IDC_RELOAD_CONFIG 40006 #define IDC_RELOAD_CONFIG 40006
#define IDC_FORCE_RECONNECT 40007 #define IDC_FORCE_RECONNECT 40007
#define IDC_TASKBAR_SHOW_LOG 40008 #define IDC_TASKBAR_SHOW_LOG 40008
#define IDC_TASKBAR_LOG_LEVEL_ERROR 40009 #define IDC_TASKBAR_LOG_LEVEL_ERROR 40009
#define IDC_TASKBAR_LOG_LEVEL_WARNING 40010 #define IDC_TASKBAR_LOG_LEVEL_WARNING 40010
#define IDC_TASKBAR_LOG_LEVEL_NOTE 40011 #define IDC_TASKBAR_LOG_LEVEL_NOTE 40011
#define IDC_TASKBAR_LOG_LEVEL_INFO 40012 #define IDC_TASKBAR_LOG_LEVEL_INFO 40012
#define IDC_TASKBAR_LOG_LEVEL_DEBUG 40013 #define IDC_TASKBAR_LOG_LEVEL_DEBUG 40013
#define IDC_TASKBAR_LOG_LEVEL_DEBUG1 40014 #define IDC_TASKBAR_LOG_LEVEL_DEBUG1 40014
#define IDC_TASKBAR_LOG_LEVEL_DEBUG2 40015 #define IDC_TASKBAR_LOG_LEVEL_DEBUG2 40015
#define ID_SYNERGY_RELOADSYSTEM 40016 #define ID_SYNERGY_RELOADSYSTEM 40016
#define ID_SYNERGY_RESETSERVER 40017 #define ID_SYNERGY_RESETSERVER 40017
// Next default values for new objects // Next default values for new objects
// //
#ifdef APSTUDIO_INVOKED #ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS #ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 109 #define _APS_NEXT_RESOURCE_VALUE 109
#define _APS_NEXT_COMMAND_VALUE 40018 #define _APS_NEXT_COMMAND_VALUE 40018
#define _APS_NEXT_CONTROL_VALUE 1003 #define _APS_NEXT_CONTROL_VALUE 1003
#define _APS_NEXT_SYMED_VALUE 101 #define _APS_NEXT_SYMED_VALUE 101
#endif #endif
#endif #endif

View file

@ -2,11 +2,11 @@
* synergy -- mouse and keyboard sharing utility * synergy -- mouse and keyboard sharing utility
* Copyright (C) 2012-2016 Symless Ltd. * Copyright (C) 2012-2016 Symless Ltd.
* Copyright (C) 2002 Chris Schoeneman * Copyright (C) 2002 Chris Schoeneman
* *
* This package is free software; you can redistribute it and/or * This package is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
* found in the file LICENSE that should have accompanied this file. * found in the file LICENSE that should have accompanied this file.
* *
* This package is distributed in the hope that it will be useful, * This package is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
@ -16,10 +16,14 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include "synergy/ServerApp.h"
#include "arch/Arch.h" #include "arch/Arch.h"
#include "base/Log.h"
#include "base/EventQueue.h" #include "base/EventQueue.h"
#include "base/Log.h"
#include "synergy/ServerApp.h"
#if SYSAPI_WIN32
#include "arch/win32/ArchMiscWindows.h"
#endif
#if WINAPI_MSWINDOWS #if WINAPI_MSWINDOWS
#include "MSWindowsServerTaskBarReceiver.h" #include "MSWindowsServerTaskBarReceiver.h"
@ -31,20 +35,18 @@
#error Platform not supported. #error Platform not supported.
#endif #endif
int int main(int argc, char **argv) {
main(int argc, char** argv)
{
#if SYSAPI_WIN32 #if SYSAPI_WIN32
// record window instance for tray icon, etc // record window instance for tray icon, etc
ArchMiscWindows::setInstanceWin32(GetModuleHandle(NULL)); ArchMiscWindows::setInstanceWin32(GetModuleHandle(NULL));
#endif #endif
Arch arch;
arch.init();
Log log; Arch arch;
EventQueue events; arch.init();
ServerApp app(&events, createTaskBarReceiver); Log log;
return app.run(argc, argv); EventQueue events;
ServerApp app(&events, createTaskBarReceiver);
return app.run(argc, argv);
} }

View file

@ -1,11 +1,11 @@
/* /*
* synergy -- mouse and keyboard sharing utility * synergy -- mouse and keyboard sharing utility
* Copyright (C) 2014-2016 Symless Ltd. * Copyright (C) 2014-2016 Symless Ltd.
* *
* This package is free software; you can redistribute it and/or * This package is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
* found in the file LICENSE that should have accompanied this file. * found in the file LICENSE that should have accompanied this file.
* *
* This package is distributed in the hope that it will be useful, * This package is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
@ -15,17 +15,19 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include "synergy/ToolApp.h"
#include "arch/Arch.h" #include "arch/Arch.h"
#include "synergy/ToolApp.h"
int
main(int argc, char** argv)
{
#if SYSAPI_WIN32 #if SYSAPI_WIN32
// record window instance for tray icon, etc #include "arch/win32/ArchMiscWindows.h"
ArchMiscWindows::setInstanceWin32(GetModuleHandle(NULL));
#endif #endif
ToolApp app; int main(int argc, char **argv) {
return app.run(argc, argv); #if SYSAPI_WIN32
// record window instance for tray icon, etc
ArchMiscWindows::setInstanceWin32(GetModuleHandle(NULL));
#endif
ToolApp app;
return app.run(argc, argv);
} }

View file

@ -2,11 +2,11 @@
* synergy -- mouse and keyboard sharing utility * synergy -- mouse and keyboard sharing utility
* Copyright (C) 2012-2016 Symless Ltd. * Copyright (C) 2012-2016 Symless Ltd.
* Copyright (C) 2008 Volker Lanz (vl@fidra.de) * Copyright (C) 2008 Volker Lanz (vl@fidra.de)
* *
* This package is free software; you can redistribute it and/or * This package is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
* found in the file LICENSE that should have accompanied this file. * found in the file LICENSE that should have accompanied this file.
* *
* This package is distributed in the hope that it will be useful, * This package is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
@ -16,72 +16,68 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include "OSXHelpers.h"
#include "AboutDialog.h" #include "AboutDialog.h"
#include "OSXHelpers.h"
AboutDialog::AboutDialog(MainWindow* parent, const AppConfig& config) : AboutDialog::AboutDialog(MainWindow *parent, const AppConfig &config)
QDialog(parent, Qt::WindowTitleHint | Qt::WindowSystemMenuHint), : QDialog(parent, Qt::WindowTitleHint | Qt::WindowSystemMenuHint),
Ui::AboutDialogBase() Ui::AboutDialogBase() {
{ setupUi(this);
setupUi(this);
m_versionChecker.setApp(parent->appPath(config.synergycName())); m_versionChecker.setApp(parent->appPath(config.synergycName()));
m_pLabelSynergyVersion->setText(SYNERGY_VERSION); m_pLabelSynergyVersion->setText(SYNERGY_VERSION);
QString buildDateString = QString::fromLocal8Bit(__DATE__).simplified(); QString buildDateString = QString::fromLocal8Bit(__DATE__).simplified();
QDate buildDate = QLocale("en_US").toDate(buildDateString, "MMM d yyyy"); QDate buildDate = QLocale("en_US").toDate(buildDateString, "MMM d yyyy");
m_pLabelBuildDate->setText(buildDate.toString(Qt::SystemLocaleLongDate)); m_pLabelBuildDate->setText(buildDate.toString(Qt::SystemLocaleLongDate));
textEliteBackers->hide(); textEliteBackers->hide();
labelEliteBackers->hide(); labelEliteBackers->hide();
labelEliteBackerLink->hide(); labelEliteBackerLink->hide();
labelCreditsLink->hide(); labelCreditsLink->hide();
} }
int AboutDialog::exec() int AboutDialog::exec() {
{ // Sets the current build year into the copyright text
//Sets the current build year into the copyright text label_3->setText(getCopyrights() + getKeyContributors());
label_3->setText(getCopyrights() + getKeyContributors()); resizeWindow();
resizeWindow(); updateLogo();
updateLogo();
return QDialog::exec(); return QDialog::exec();
} }
void AboutDialog::resizeWindow() void AboutDialog::resizeWindow() {
{ QSize size(600, 310);
QSize size(600, 310); setMaximumSize(size);
setMaximumSize(size); setMinimumSize(size);
setMinimumSize(size); resize(size);
resize(size);
} }
void AboutDialog::updateLogo() const void AboutDialog::updateLogo() const {
{
#if defined(Q_OS_MAC) #if defined(Q_OS_MAC)
if (isOSXInterfaceStyleDark()) { if (isOSXInterfaceStyleDark()) {
QPixmap logo(":/res/image/about-dark.png"); QPixmap logo(":/res/image/about-dark.png");
if (!logo.isNull()) { if (!logo.isNull()) {
label_Logo->setPixmap(logo); label_Logo->setPixmap(logo);
}
} }
}
#endif #endif
} }
QString AboutDialog::getKeyContributors() const QString AboutDialog::getKeyContributors() const {
{ return QString(R"(<p style="font-size: 14px">Key contributors<br>
return QString(R"(<p style="font-size: 14px">Key contributors<br>
<span style="font-size: 11px">Chris Schoeneman, Nick Bolton, Richard Lee, Adam Feder, Volker Lanz, <span style="font-size: 11px">Chris Schoeneman, Nick Bolton, Richard Lee, Adam Feder, Volker Lanz,
Ryan Breen, Guido Poschta, Bertrand Landry Hetu, Tom Chadwick, Brent Priddy, Kyle Bloom, Ryan Breen, Guido Poschta, Bertrand Landry Hetu, Tom Chadwick, Brent Priddy, Kyle Bloom,
Daun Chung, Serhii Hadzhylov, Oleksandr Lysytsia, Olena Kutytska, Francisco Magalhães.</span> Daun Chung, Serhii Hadzhylov, Oleksandr Lysytsia, Olena Kutytska, Francisco Magalhães.</span>
</p>)"); </p>)");
} }
QString AboutDialog::getCopyrights() const QString AboutDialog::getCopyrights() const {
{ QString buildDateString = QString::fromLocal8Bit(__DATE__).simplified();
QString buildDateString = QString::fromLocal8Bit(__DATE__).simplified(); QDate buildDate = QLocale("en_US").toDate(buildDateString, "MMM d yyyy");
QDate buildDate = QLocale("en_US").toDate(buildDateString, "MMM d yyyy");
QString copyrights(R"(<p>Keyboard and mouse sharing application.<br /><br />Copyright © %%YEAR%% Symless Ltd.</p>)"); QString copyrights(
return copyrights.replace(QString("%%YEAR%%"), QString::number(buildDate.year())); R"(<p>Keyboard and mouse sharing application.<br /><br />Copyright © %%YEAR%% Symless Ltd.</p>)");
return copyrights.replace(QString("%%YEAR%%"),
QString::number(buildDate.year()));
} }

View file

@ -2,11 +2,11 @@
* synergy -- mouse and keyboard sharing utility * synergy -- mouse and keyboard sharing utility
* Copyright (C) 2012-2016 Symless Ltd. * Copyright (C) 2012-2016 Symless Ltd.
* Copyright (C) 2008 Volker Lanz (vl@fidra.de) * Copyright (C) 2008 Volker Lanz (vl@fidra.de)
* *
* This package is free software; you can redistribute it and/or * This package is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
* found in the file LICENSE that should have accompanied this file. * found in the file LICENSE that should have accompanied this file.
* *
* This package is distributed in the hope that it will be useful, * This package is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
@ -20,9 +20,9 @@
#define ABOUTDIALOG__H #define ABOUTDIALOG__H
#include <QDialog>
#include "VersionChecker.h"
#include "MainWindow.h" #include "MainWindow.h"
#include "VersionChecker.h"
#include <QDialog>
#include "ui_AboutDialogBase.h" #include "ui_AboutDialogBase.h"
@ -30,18 +30,18 @@ class QWidget;
class QString; class QString;
class AboutDialog : public QDialog, public Ui::AboutDialogBase { class AboutDialog : public QDialog, public Ui::AboutDialogBase {
Q_OBJECT Q_OBJECT
public: public:
AboutDialog(MainWindow* parent, const AppConfig& config); AboutDialog(MainWindow *parent, const AppConfig &config);
int exec() override; int exec() override;
private:
VersionChecker m_versionChecker;
void updateLogo() const;
virtual void resizeWindow(); private:
virtual QString getCopyrights() const; VersionChecker m_versionChecker;
virtual QString getKeyContributors() const; void updateLogo() const;
virtual void resizeWindow();
virtual QString getCopyrights() const;
virtual QString getKeyContributors() const;
}; };
#endif #endif

View file

@ -14,60 +14,59 @@
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include "CreditsLoader.h"
#include "AboutDialogEliteBackers.h" #include "AboutDialogEliteBackers.h"
#include "CreditsLoader.h"
AboutDialogEliteBackers::AboutDialogEliteBackers(MainWindow* parent, const AppConfig& config) : AboutDialogEliteBackers::AboutDialogEliteBackers(MainWindow *parent,
AboutDialog(parent, config), const AppConfig &config)
credits(*parent, config) : AboutDialog(parent, config), credits(*parent, config) {
{ setupCreditsLoader();
setupCreditsLoader();
textEliteBackers->show(); textEliteBackers->show();
labelEliteBackers->show(); labelEliteBackers->show();
labelEliteBackerLink->show(); labelEliteBackerLink->show();
labelCreditsLink->show(); labelCreditsLink->show();
} }
void AboutDialogEliteBackers::setupCreditsLoader() void AboutDialogEliteBackers::setupCreditsLoader() {
{ this->textEliteBackers->setText("Loading...");
this->textEliteBackers->setText("Loading..."); this->textEliteBackers->viewport()->setAutoFillBackground(false);
this->textEliteBackers->viewport()->setAutoFillBackground(false); this->textEliteBackers->document()->setDocumentMargin(0);
this->textEliteBackers->document()->setDocumentMargin(0);
connect(&credits, SIGNAL(loaded(const QString&)), this, SLOT(updateEliteBackers(const QString&))); connect(&credits, SIGNAL(loaded(const QString &)), this,
credits.loadEliteBackers(); SLOT(updateEliteBackers(const QString &)));
credits.loadEliteBackers();
} }
void AboutDialogEliteBackers::updateEliteBackers(const QString& eliteBackers) const void AboutDialogEliteBackers::updateEliteBackers(
{ const QString &eliteBackers) const {
this->textEliteBackers->setText(eliteBackers); this->textEliteBackers->setText(eliteBackers);
} }
QString AboutDialogEliteBackers::getCopyrights() const QString AboutDialogEliteBackers::getCopyrights() const {
{ QString buildDateString = QString::fromLocal8Bit(__DATE__).simplified();
QString buildDateString = QString::fromLocal8Bit(__DATE__).simplified(); QDate buildDate = QLocale("en_US").toDate(buildDateString, "MMM d yyyy");
QDate buildDate = QLocale("en_US").toDate(buildDateString, "MMM d yyyy");
QString aboutText(R"(<p>Keyboard and mouse sharing application. Cross platform and open source since 2001.<br /><br /> QString aboutText(
R"(<p>Keyboard and mouse sharing application. Cross platform and open source since 2001.<br /><br />
Copyright © %%YEAR%% Symless Ltd.<br /><br /> Copyright © %%YEAR%% Symless Ltd.<br /><br />
Synergy is released under the GNU General Public License (GPLv2).</p>)"); Synergy is released under the GNU General Public License (GPLv2).</p>)");
return aboutText.replace(QString("%%YEAR%%"), QString::number(buildDate.year())); return aboutText.replace(QString("%%YEAR%%"),
QString::number(buildDate.year()));
} }
void AboutDialogEliteBackers::resizeWindow() void AboutDialogEliteBackers::resizeWindow() {
{
// change default size based on os // change default size based on os
#if defined(Q_OS_MAC) #if defined(Q_OS_MAC)
QSize size(600, 490); QSize size(600, 490);
setMaximumSize(size); setMaximumSize(size);
setMinimumSize(size); setMinimumSize(size);
resize(size); resize(size);
#elif defined(Q_OS_LINUX) #elif defined(Q_OS_LINUX)
QSize size(600, 420); QSize size(600, 420);
setMaximumSize(size); setMaximumSize(size);
setMinimumSize(size); setMinimumSize(size);
resize(size); resize(size);
#endif #endif
} }

View file

@ -16,21 +16,21 @@
*/ */
#pragma once #pragma once
#include "CreditsLoader.h"
#include "AboutDialog.h" #include "AboutDialog.h"
#include "CreditsLoader.h"
class AboutDialogEliteBackers : public AboutDialog { class AboutDialogEliteBackers : public AboutDialog {
Q_OBJECT Q_OBJECT
public: public:
AboutDialogEliteBackers(MainWindow* parent, const AppConfig& config); AboutDialogEliteBackers(MainWindow *parent, const AppConfig &config);
public slots: public slots:
void updateEliteBackers(const QString& eliteBackers) const; void updateEliteBackers(const QString &eliteBackers) const;
private: private:
CreditsLoader credits; CreditsLoader credits;
void setupCreditsLoader(); void setupCreditsLoader();
void resizeWindow() override; void resizeWindow() override;
QString getCopyrights() const override; QString getCopyrights() const override;
}; };

View file

@ -2,11 +2,11 @@
* synergy -- mouse and keyboard sharing utility * synergy -- mouse and keyboard sharing utility
* Copyright (C) 2012-2016 Symless Ltd. * Copyright (C) 2012-2016 Symless Ltd.
* Copyright (C) 2008 Volker Lanz (vl@fidra.de) * Copyright (C) 2008 Volker Lanz (vl@fidra.de)
* *
* This package is free software; you can redistribute it and/or * This package is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
* found in the file LICENSE that should have accompanied this file. * found in the file LICENSE that should have accompanied this file.
* *
* This package is distributed in the hope that it will be useful, * This package is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
@ -21,148 +21,129 @@
#include <QSettings> #include <QSettings>
#include <QTextStream> #include <QTextStream>
const char* Action::m_ActionTypeNames[] = const char *Action::m_ActionTypeNames[] = {
{ "keyDown", "keyUp",
"keyDown", "keyUp", "keystroke", "keystroke", "switchToScreen",
"switchToScreen", "switchInDirection", "lockCursorToScreen", "restartServer", "switchInDirection", "lockCursorToScreen",
"mouseDown", "mouseUp", "mousebutton" "restartServer", "mouseDown",
}; "mouseUp", "mousebutton"};
const char* Action::m_SwitchDirectionNames[] = { "left", "right", "up", "down" }; const char *Action::m_SwitchDirectionNames[] = {"left", "right", "up", "down"};
const char* Action::m_LockCursorModeNames[] = { "toggle", "on", "off" }; const char *Action::m_LockCursorModeNames[] = {"toggle", "on", "off"};
Action::Action() : Action::Action()
m_KeySequence(), : m_KeySequence(), m_Type(keystroke), m_TypeScreenNames(),
m_Type(keystroke), m_SwitchScreenName(), m_SwitchDirection(switchLeft),
m_TypeScreenNames(), m_LockCursorMode(lockCursorToggle), m_ActiveOnRelease(false),
m_SwitchScreenName(), m_HasScreens(false) {}
m_SwitchDirection(switchLeft),
m_LockCursorMode(lockCursorToggle),
m_ActiveOnRelease(false),
m_HasScreens(false)
{
}
QString Action::text() const QString Action::text() const {
{ QString text =
QString text = QString(m_ActionTypeNames[keySequence().isMouseButton() ? type() + 6 : type() ]) + "("; QString(m_ActionTypeNames[keySequence().isMouseButton() ? type() + 6
: type()]) +
"(";
switch (type()) switch (type()) {
{ case keyDown:
case keyDown: case keyUp:
case keyUp: case keystroke: {
case keystroke: text += keySequence().toString();
{
text += keySequence().toString();
if (!keySequence().isMouseButton()) if (!keySequence().isMouseButton()) {
{ const QStringList &screens = typeScreenNames();
const QStringList& screens = typeScreenNames(); if (haveScreens() && !screens.isEmpty()) {
if (haveScreens() && !screens.isEmpty()) text += ",";
{
text += ",";
for (int i = 0; i < screens.size(); i++) for (int i = 0; i < screens.size(); i++) {
{ text += screens[i];
text += screens[i]; if (i != screens.size() - 1)
if (i != screens.size() - 1) text += ":";
text += ":"; }
} } else
} text += ",*";
else
text += ",*";
}
}
break;
case switchToScreen:
text += switchScreenName();
break;
case switchInDirection:
text += m_SwitchDirectionNames[m_SwitchDirection];
break;
case lockCursorToScreen:
text += m_LockCursorModeNames[m_LockCursorMode];
break;
case restartAllConnections:
text += "restart";
break;
default:
Q_ASSERT(0);
break;
} }
} break;
text += ")"; case switchToScreen:
text += switchScreenName();
break;
return text; case switchInDirection:
text += m_SwitchDirectionNames[m_SwitchDirection];
break;
case lockCursorToScreen:
text += m_LockCursorModeNames[m_LockCursorMode];
break;
case restartAllConnections:
text += "restart";
break;
default:
Q_ASSERT(0);
break;
}
text += ")";
return text;
} }
void Action::loadSettings(QSettings& settings) void Action::loadSettings(QSettings &settings) {
{ keySequence().loadSettings(settings);
keySequence().loadSettings(settings); setType(settings.value("type", keyDown).toInt());
setType(settings.value("type", keyDown).toInt());
typeScreenNames().clear(); typeScreenNames().clear();
int numTypeScreens = settings.beginReadArray("typeScreenNames"); int numTypeScreens = settings.beginReadArray("typeScreenNames");
for (int i = 0; i < numTypeScreens; i++) for (int i = 0; i < numTypeScreens; i++) {
{ settings.setArrayIndex(i);
settings.setArrayIndex(i); typeScreenNames().append(settings.value("typeScreenName").toString());
typeScreenNames().append(settings.value("typeScreenName").toString()); }
} settings.endArray();
settings.endArray();
setSwitchScreenName(settings.value("switchScreenName").toString()); setSwitchScreenName(settings.value("switchScreenName").toString());
setSwitchDirection(settings.value("switchInDirection", switchLeft).toInt()); setSwitchDirection(settings.value("switchInDirection", switchLeft).toInt());
setLockCursorMode(settings.value("lockCursorToScreen", lockCursorToggle).toInt()); setLockCursorMode(
setActiveOnRelease(settings.value("activeOnRelease", false).toBool()); settings.value("lockCursorToScreen", lockCursorToggle).toInt());
setHaveScreens(settings.value("hasScreens", false).toBool()); setActiveOnRelease(settings.value("activeOnRelease", false).toBool());
setRestartServer(settings.value("restartServer", false).toBool()); setHaveScreens(settings.value("hasScreens", false).toBool());
setRestartServer(settings.value("restartServer", false).toBool());
} }
void Action::saveSettings(QSettings& settings) const void Action::saveSettings(QSettings &settings) const {
{ keySequence().saveSettings(settings);
keySequence().saveSettings(settings); settings.setValue("type", type());
settings.setValue("type", type());
settings.beginWriteArray("typeScreenNames"); settings.beginWriteArray("typeScreenNames");
for (int i = 0; i < typeScreenNames().size(); i++) for (int i = 0; i < typeScreenNames().size(); i++) {
{ settings.setArrayIndex(i);
settings.setArrayIndex(i); settings.setValue("typeScreenName", typeScreenNames()[i]);
settings.setValue("typeScreenName", typeScreenNames()[i]); }
} settings.endArray();
settings.endArray();
settings.setValue("switchScreenName", switchScreenName()); settings.setValue("switchScreenName", switchScreenName());
settings.setValue("switchInDirection", switchDirection()); settings.setValue("switchInDirection", switchDirection());
settings.setValue("lockCursorToScreen", lockCursorMode()); settings.setValue("lockCursorToScreen", lockCursorMode());
settings.setValue("activeOnRelease", activeOnRelease()); settings.setValue("activeOnRelease", activeOnRelease());
settings.setValue("hasScreens", haveScreens()); settings.setValue("hasScreens", haveScreens());
settings.setValue("restartServer", restartServer()); settings.setValue("restartServer", restartServer());
} }
bool Action::operator==(const Action& a) const bool Action::operator==(const Action &a) const {
{ return m_KeySequence == a.m_KeySequence && m_Type == a.m_Type &&
return m_KeySequence == a.m_KeySequence && m_TypeScreenNames == a.m_TypeScreenNames &&
m_Type == a.m_Type && m_SwitchScreenName == a.m_SwitchScreenName &&
m_TypeScreenNames == a.m_TypeScreenNames && m_SwitchDirection == a.m_SwitchDirection &&
m_SwitchScreenName == a.m_SwitchScreenName && m_LockCursorMode == a.m_LockCursorMode &&
m_SwitchDirection == a.m_SwitchDirection && m_ActiveOnRelease == a.m_ActiveOnRelease &&
m_LockCursorMode == a.m_LockCursorMode && m_HasScreens == a.m_HasScreens && m_restartServer == a.m_restartServer;
m_ActiveOnRelease == a.m_ActiveOnRelease &&
m_HasScreens == a.m_HasScreens &&
m_restartServer == a.m_restartServer;
} }
QTextStream& operator<<(QTextStream& outStream, const Action& action) QTextStream &operator<<(QTextStream &outStream, const Action &action) {
{ if (action.activeOnRelease())
if (action.activeOnRelease()) outStream << ";";
outStream << ";";
outStream << action.text(); outStream << action.text();
return outStream; return outStream;
} }

View file

@ -2,11 +2,11 @@
* synergy -- mouse and keyboard sharing utility * synergy -- mouse and keyboard sharing utility
* Copyright (C) 2012-2016 Symless Ltd. * Copyright (C) 2012-2016 Symless Ltd.
* Copyright (C) 2008 Volker Lanz (vl@fidra.de) * Copyright (C) 2008 Volker Lanz (vl@fidra.de)
* *
* This package is free software; you can redistribute it and/or * This package is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
* found in the file LICENSE that should have accompanied this file. * found in the file LICENSE that should have accompanied this file.
* *
* This package is distributed in the hope that it will be useful, * This package is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
@ -22,93 +22,83 @@
#include "KeySequence.h" #include "KeySequence.h"
#include <QList>
#include <QString> #include <QString>
#include <QStringList> #include <QStringList>
#include <QList>
class ActionDialog; class ActionDialog;
class QSettings; class QSettings;
class QTextStream; class QTextStream;
class Action class Action {
{ friend class ActionDialog;
friend class ActionDialog; friend QTextStream &operator<<(QTextStream &outStream, const Action &action);
friend QTextStream& operator<<(QTextStream& outStream, const Action& action);
public: public:
enum ActionType { enum ActionType {
keyDown, keyDown,
keyUp, keyUp,
keystroke, keystroke,
switchToScreen, switchToScreen,
switchInDirection, switchInDirection,
lockCursorToScreen, lockCursorToScreen,
restartAllConnections, restartAllConnections,
mouseDown, mouseDown,
mouseUp, mouseUp,
mousebutton, mousebutton,
}; };
enum SwitchDirection { enum SwitchDirection { switchLeft, switchRight, switchUp, switchDown };
switchLeft, enum LockCursorMode { lockCursorToggle, lockCursonOn, lockCursorOff };
switchRight,
switchUp,
switchDown
};
enum LockCursorMode {
lockCursorToggle,
lockCursonOn,
lockCursorOff
};
public: public:
Action(); Action();
public: public:
QString text() const; QString text() const;
const KeySequence& keySequence() const { return m_KeySequence; } const KeySequence &keySequence() const { return m_KeySequence; }
void loadSettings(QSettings& settings); void loadSettings(QSettings &settings);
void saveSettings(QSettings& settings) const; void saveSettings(QSettings &settings) const;
int type() const { return m_Type; } int type() const { return m_Type; }
const QStringList& typeScreenNames() const { return m_TypeScreenNames; } const QStringList &typeScreenNames() const { return m_TypeScreenNames; }
const QString& switchScreenName() const { return m_SwitchScreenName; } const QString &switchScreenName() const { return m_SwitchScreenName; }
int switchDirection() const { return m_SwitchDirection; } int switchDirection() const { return m_SwitchDirection; }
int lockCursorMode() const { return m_LockCursorMode; } int lockCursorMode() const { return m_LockCursorMode; }
bool activeOnRelease() const { return m_ActiveOnRelease; } bool activeOnRelease() const { return m_ActiveOnRelease; }
bool haveScreens() const { return m_HasScreens; } bool haveScreens() const { return m_HasScreens; }
bool restartServer() const { return m_restartServer; } bool restartServer() const { return m_restartServer; }
bool operator==(const Action& a) const; bool operator==(const Action &a) const;
protected: protected:
KeySequence& keySequence() { return m_KeySequence; } KeySequence &keySequence() { return m_KeySequence; }
void setKeySequence(const KeySequence& seq) { m_KeySequence = seq; } void setKeySequence(const KeySequence &seq) { m_KeySequence = seq; }
void setType(int t) { m_Type = t; } void setType(int t) { m_Type = t; }
QStringList& typeScreenNames() { return m_TypeScreenNames; } QStringList &typeScreenNames() { return m_TypeScreenNames; }
void setSwitchScreenName(const QString& n) { m_SwitchScreenName = n; } void setSwitchScreenName(const QString &n) { m_SwitchScreenName = n; }
void setSwitchDirection(int d) { m_SwitchDirection = d; } void setSwitchDirection(int d) { m_SwitchDirection = d; }
void setLockCursorMode(int m) { m_LockCursorMode = m; } void setLockCursorMode(int m) { m_LockCursorMode = m; }
void setActiveOnRelease(bool b) { m_ActiveOnRelease = b; } void setActiveOnRelease(bool b) { m_ActiveOnRelease = b; }
void setHaveScreens(bool b) { m_HasScreens = b; } void setHaveScreens(bool b) { m_HasScreens = b; }
void setRestartServer( bool b) { m_restartServer = b; } void setRestartServer(bool b) { m_restartServer = b; }
private: private:
KeySequence m_KeySequence; KeySequence m_KeySequence;
int m_Type; int m_Type;
QStringList m_TypeScreenNames; QStringList m_TypeScreenNames;
QString m_SwitchScreenName; QString m_SwitchScreenName;
int m_SwitchDirection; int m_SwitchDirection;
int m_LockCursorMode; int m_LockCursorMode;
bool m_ActiveOnRelease; bool m_ActiveOnRelease;
bool m_HasScreens; bool m_HasScreens;
bool m_restartServer; bool m_restartServer;
static const char* m_ActionTypeNames[]; static const char *m_ActionTypeNames[];
static const char* m_SwitchDirectionNames[]; static const char *m_SwitchDirectionNames[];
static const char* m_LockCursorModeNames[]; static const char *m_LockCursorModeNames[];
}; };
typedef QList<Action> ActionList; typedef QList<Action> ActionList;
QTextStream& operator<<(QTextStream& outStream, const Action& action); QTextStream &operator<<(QTextStream &outStream, const Action &action);
#endif #endif

View file

@ -2,11 +2,11 @@
* synergy -- mouse and keyboard sharing utility * synergy -- mouse and keyboard sharing utility
* Copyright (C) 2012-2016 Symless Ltd. * Copyright (C) 2012-2016 Symless Ltd.
* Copyright (C) 2008 Volker Lanz (vl@fidra.de) * Copyright (C) 2008 Volker Lanz (vl@fidra.de)
* *
* This package is free software; you can redistribute it and/or * This package is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
* found in the file LICENSE that should have accompanied this file. * found in the file LICENSE that should have accompanied this file.
* *
* This package is distributed in the hope that it will be useful, * This package is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
@ -18,94 +18,93 @@
#include "ActionDialog.h" #include "ActionDialog.h"
#include "Hotkey.h"
#include "Action.h" #include "Action.h"
#include "ServerConfig.h" #include "Hotkey.h"
#include "KeySequence.h" #include "KeySequence.h"
#include "ServerConfig.h"
#include <QButtonGroup>
#include <QtCore> #include <QtCore>
#include <QtGui> #include <QtGui>
#include <QButtonGroup>
ActionDialog::ActionDialog(QWidget* parent, ServerConfig& config, Hotkey& hotkey, Action& action) : ActionDialog::ActionDialog(QWidget *parent, ServerConfig &config,
QDialog(parent, Qt::WindowTitleHint | Qt::WindowSystemMenuHint), Hotkey &hotkey, Action &action)
Ui::ActionDialogBase(), : QDialog(parent, Qt::WindowTitleHint | Qt::WindowSystemMenuHint),
m_ServerConfig(config), Ui::ActionDialogBase(), m_ServerConfig(config), m_Hotkey(hotkey),
m_Hotkey(hotkey), m_Action(action), m_pButtonGroupType(new QButtonGroup(this)) {
m_Action(action), setupUi(this);
m_pButtonGroupType(new QButtonGroup(this))
{
setupUi(this);
// work around Qt Designer's lack of a QButtonGroup; we need it to get // work around Qt Designer's lack of a QButtonGroup; we need it to get
// at the button id of the checked radio button // at the button id of the checked radio button
QRadioButton* const typeButtons[] = { m_pRadioPress, m_pRadioRelease, m_pRadioPressAndRelease, m_pRadioSwitchToScreen, m_pRadioSwitchInDirection, m_pRadioLockCursorToScreen , m_pRadioRestartAllConnections}; QRadioButton *const typeButtons[] = {m_pRadioPress,
m_pRadioRelease,
m_pRadioPressAndRelease,
m_pRadioSwitchToScreen,
m_pRadioSwitchInDirection,
m_pRadioLockCursorToScreen,
m_pRadioRestartAllConnections};
for (unsigned int i = 0; i < sizeof(typeButtons) / sizeof(typeButtons[0]); i++) for (unsigned int i = 0; i < sizeof(typeButtons) / sizeof(typeButtons[0]);
m_pButtonGroupType->addButton(typeButtons[i], i); i++)
m_pButtonGroupType->addButton(typeButtons[i], i);
m_pKeySequenceWidgetHotkey->setText(m_Action.keySequence().toString()); m_pKeySequenceWidgetHotkey->setText(m_Action.keySequence().toString());
m_pKeySequenceWidgetHotkey->setKeySequence(m_Action.keySequence()); m_pKeySequenceWidgetHotkey->setKeySequence(m_Action.keySequence());
m_pButtonGroupType->button(m_Action.type())->setChecked(true); m_pButtonGroupType->button(m_Action.type())->setChecked(true);
m_pComboSwitchInDirection->setCurrentIndex(m_Action.switchDirection()); m_pComboSwitchInDirection->setCurrentIndex(m_Action.switchDirection());
m_pComboLockCursorToScreen->setCurrentIndex(m_Action.lockCursorMode()); m_pComboLockCursorToScreen->setCurrentIndex(m_Action.lockCursorMode());
if (m_Action.activeOnRelease()) if (m_Action.activeOnRelease())
m_pRadioHotkeyReleased->setChecked(true); m_pRadioHotkeyReleased->setChecked(true);
else else
m_pRadioHotkeyPressed->setChecked(true); m_pRadioHotkeyPressed->setChecked(true);
m_pGroupBoxScreens->setChecked(m_Action.haveScreens()); m_pGroupBoxScreens->setChecked(m_Action.haveScreens());
int idx = 0; int idx = 0;
foreach(const Screen& screen, serverConfig().screens()) foreach (const Screen &screen, serverConfig().screens())
if (!screen.isNull()) if (!screen.isNull()) {
{ QListWidgetItem *pListItem = new QListWidgetItem(screen.name());
QListWidgetItem *pListItem = new QListWidgetItem(screen.name()); m_pListScreens->addItem(pListItem);
m_pListScreens->addItem(pListItem); if (m_Action.typeScreenNames().indexOf(screen.name()) != -1)
if (m_Action.typeScreenNames().indexOf(screen.name()) != -1) m_pListScreens->setCurrentItem(pListItem);
m_pListScreens->setCurrentItem(pListItem);
m_pComboSwitchToScreen->addItem(screen.name()); m_pComboSwitchToScreen->addItem(screen.name());
if (screen.name() == m_Action.switchScreenName()) if (screen.name() == m_Action.switchScreenName())
m_pComboSwitchToScreen->setCurrentIndex(idx); m_pComboSwitchToScreen->setCurrentIndex(idx);
idx++; idx++;
}
}
void ActionDialog::accept()
{
if (!sequenceWidget()->valid() && m_pButtonGroupType->checkedId() >= 0 && m_pButtonGroupType->checkedId() < 3)
return;
m_Action.setKeySequence(sequenceWidget()->keySequence());
m_Action.setType(m_pButtonGroupType->checkedId());
m_Action.setHaveScreens(m_pGroupBoxScreens->isChecked());
m_Action.typeScreenNames().clear();
foreach(const QListWidgetItem* pItem, m_pListScreens->selectedItems())
m_Action.typeScreenNames().append(pItem->text());
m_Action.setSwitchScreenName(m_pComboSwitchToScreen->currentText());
m_Action.setSwitchDirection(m_pComboSwitchInDirection->currentIndex());
m_Action.setLockCursorMode(m_pComboLockCursorToScreen->currentIndex());
m_Action.setActiveOnRelease(m_pRadioHotkeyReleased->isChecked());
m_Action.setRestartServer(m_pRadioRestartAllConnections->isChecked());
QDialog::accept();
}
void ActionDialog::on_m_pKeySequenceWidgetHotkey_keySequenceChanged()
{
if (sequenceWidget()->keySequence().isMouseButton())
{
m_pGroupBoxScreens->setEnabled(false);
m_pListScreens->setEnabled(false);
}
else
{
m_pGroupBoxScreens->setEnabled(true);
m_pListScreens->setEnabled(true);
} }
} }
void ActionDialog::accept() {
if (!sequenceWidget()->valid() && m_pButtonGroupType->checkedId() >= 0 &&
m_pButtonGroupType->checkedId() < 3)
return;
m_Action.setKeySequence(sequenceWidget()->keySequence());
m_Action.setType(m_pButtonGroupType->checkedId());
m_Action.setHaveScreens(m_pGroupBoxScreens->isChecked());
m_Action.typeScreenNames().clear();
foreach (const QListWidgetItem *pItem, m_pListScreens->selectedItems())
m_Action.typeScreenNames().append(pItem->text());
m_Action.setSwitchScreenName(m_pComboSwitchToScreen->currentText());
m_Action.setSwitchDirection(m_pComboSwitchInDirection->currentIndex());
m_Action.setLockCursorMode(m_pComboLockCursorToScreen->currentIndex());
m_Action.setActiveOnRelease(m_pRadioHotkeyReleased->isChecked());
m_Action.setRestartServer(m_pRadioRestartAllConnections->isChecked());
QDialog::accept();
}
void ActionDialog::on_m_pKeySequenceWidgetHotkey_keySequenceChanged() {
if (sequenceWidget()->keySequence().isMouseButton()) {
m_pGroupBoxScreens->setEnabled(false);
m_pListScreens->setEnabled(false);
} else {
m_pGroupBoxScreens->setEnabled(true);
m_pListScreens->setEnabled(true);
}
}

View file

@ -2,11 +2,11 @@
* synergy -- mouse and keyboard sharing utility * synergy -- mouse and keyboard sharing utility
* Copyright (C) 2012-2016 Symless Ltd. * Copyright (C) 2012-2016 Symless Ltd.
* Copyright (C) 2008 Volker Lanz (vl@fidra.de) * Copyright (C) 2008 Volker Lanz (vl@fidra.de)
* *
* This package is free software; you can redistribute it and/or * This package is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
* found in the file LICENSE that should have accompanied this file. * found in the file LICENSE that should have accompanied this file.
* *
* This package is distributed in the hope that it will be useful, * This package is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
@ -30,27 +30,29 @@ class QRadioButton;
class QButtonGroup; class QButtonGroup;
class ServerConfig; class ServerConfig;
class ActionDialog : public QDialog, public Ui::ActionDialogBase class ActionDialog : public QDialog, public Ui::ActionDialogBase {
{ Q_OBJECT
Q_OBJECT
public: public:
ActionDialog(QWidget* parent, ServerConfig& config, Hotkey& hotkey, Action& action); ActionDialog(QWidget *parent, ServerConfig &config, Hotkey &hotkey,
Action &action);
protected slots: protected slots:
void accept(); void accept();
void on_m_pKeySequenceWidgetHotkey_keySequenceChanged(); void on_m_pKeySequenceWidgetHotkey_keySequenceChanged();
protected: protected:
const KeySequenceWidget* sequenceWidget() const { return m_pKeySequenceWidgetHotkey; } const KeySequenceWidget *sequenceWidget() const {
const ServerConfig& serverConfig() const { return m_ServerConfig; } return m_pKeySequenceWidgetHotkey;
}
const ServerConfig &serverConfig() const { return m_ServerConfig; }
private: private:
const ServerConfig& m_ServerConfig; const ServerConfig &m_ServerConfig;
Hotkey& m_Hotkey; Hotkey &m_Hotkey;
Action& m_Action; Action &m_Action;
QButtonGroup* m_pButtonGroupType; QButtonGroup *m_pButtonGroupType;
}; };
#endif #endif

View file

@ -1,107 +1,102 @@
#include "ActivationDialog.h" #include "ActivationDialog.h"
#include "ui_ActivationDialog.h"
#include "CancelActivationDialog.h"
#include "AppConfig.h"
#include <shared/EditionType.h>
#include "ActivationNotifier.h" #include "ActivationNotifier.h"
#include "AppConfig.h"
#include "CancelActivationDialog.h"
#include "FailedLoginDialog.h"
#include "LicenseManager.h"
#include "MainWindow.h" #include "MainWindow.h"
#include "QUtility.h" #include "QUtility.h"
#include "LicenseManager.h" #include "ui_ActivationDialog.h"
#include "FailedLoginDialog.h" #include <shared/EditionType.h>
#include <QMessageBox> #include <QMessageBox>
#include <QThread> #include <QThread>
#include <iostream> #include <iostream>
ActivationDialog::ActivationDialog(QWidget* parent, AppConfig& appConfig, ActivationDialog::ActivationDialog(QWidget *parent, AppConfig &appConfig,
LicenseManager& licenseManager) : LicenseManager &licenseManager)
QDialog(parent), : QDialog(parent), ui(new Ui::ActivationDialog), m_appConfig(&appConfig),
ui(new Ui::ActivationDialog), m_LicenseManager(&licenseManager) {
m_appConfig(&appConfig), ui->setupUi(this);
m_LicenseManager (&licenseManager) refreshSerialKey();
{ time_t currentTime = ::time(0);
ui->setupUi(this); if (!m_LicenseManager->serialKey().isExpired(currentTime)) {
ui->m_trialWidget->hide();
}
}
void ActivationDialog::refreshSerialKey() {
ui->m_pTextEditSerialKey->setText(m_appConfig->serialKey());
ui->m_pTextEditSerialKey->setFocus();
ui->m_pTextEditSerialKey->moveCursor(QTextCursor::End);
ui->m_trialLabel->setText(
tr(m_LicenseManager->getLicenseNotice().toStdString().c_str()));
}
ActivationDialog::~ActivationDialog() { delete ui; }
void ActivationDialog::reject() {
if (m_LicenseManager->activeEdition() == kUnregistered) {
CancelActivationDialog cancelActivationDialog(this);
if (QDialog::Accepted == cancelActivationDialog.exec()) {
m_LicenseManager->skipActivation();
} else {
return;
}
}
QDialog::reject();
}
void ActivationDialog::accept() {
QMessageBox message;
m_appConfig->activationHasRun(true);
try {
SerialKey serialKey(
ui->m_pTextEditSerialKey->toPlainText().trimmed().toStdString());
m_LicenseManager->setSerialKey(serialKey);
} catch (std::exception &e) {
message.critical(
this, "Activation failed",
tr("An error occurred while trying to activate Synergy. "
"<a href=\"https://symless.com/synergy/contact-support?source=gui\" "
"style=\"text-decoration: none; color: #4285F4;\">"
"Please contact the helpdesk</a>, and provide the following "
"information:"
"<br><br>%1")
.arg(e.what()));
refreshSerialKey(); refreshSerialKey();
time_t currentTime = ::time(0); return;
if (!m_LicenseManager->serialKey().isExpired(currentTime)) { }
ui->m_trialWidget->hide();
}
}
void ActivationDialog::refreshSerialKey() m_LicenseManager->notifyActivation("serial:" + m_appConfig->serialKey());
{ Edition edition = m_LicenseManager->activeEdition();
ui->m_pTextEditSerialKey->setText(m_appConfig->serialKey()); time_t daysLeft = m_LicenseManager->serialKey().daysLeft(::time(0));
ui->m_pTextEditSerialKey->setFocus(); if (edition != kUnregistered) {
ui->m_pTextEditSerialKey->moveCursor(QTextCursor::End); QString thanksMessage = tr("Thanks for trying %1! %5\n\n%2 day%3 of "
ui->m_trialLabel->setText(tr(m_LicenseManager->getLicenseNotice().toStdString().c_str())); "your trial remain%4")
} .arg(m_LicenseManager->getEditionName(edition))
.arg(daysLeft)
.arg((daysLeft == 1) ? "" : "s")
.arg((daysLeft == 1) ? "s" : "");
ActivationDialog::~ActivationDialog() if (m_appConfig->isCryptoAvailable()) {
{ m_appConfig->generateCertificate();
delete ui; thanksMessage =
} thanksMessage.arg("If you're using SSL, "
void ActivationDialog::reject()
{
if (m_LicenseManager->activeEdition() == kUnregistered) {
CancelActivationDialog cancelActivationDialog(this);
if (QDialog::Accepted == cancelActivationDialog.exec()) {
m_LicenseManager->skipActivation();
} else {
return;
}
}
QDialog::reject();
}
void ActivationDialog::accept()
{
QMessageBox message;
m_appConfig->activationHasRun(true);
try {
SerialKey serialKey (ui->m_pTextEditSerialKey->toPlainText().
trimmed().toStdString());
m_LicenseManager->setSerialKey(serialKey);
}
catch (std::exception& e) {
message.critical(this, "Activation failed",
tr("An error occurred while trying to activate Synergy. "
"<a href=\"https://symless.com/synergy/contact-support?source=gui\" style=\"text-decoration: none; color: #4285F4;\">"
"Please contact the helpdesk</a>, and provide the following information:"
"<br><br>%1").arg(e.what()));
refreshSerialKey();
return;
}
m_LicenseManager->notifyActivation("serial:" + m_appConfig->serialKey());
Edition edition = m_LicenseManager->activeEdition();
time_t daysLeft = m_LicenseManager->serialKey().daysLeft(::time(0));
if (edition != kUnregistered) {
QString thanksMessage = tr("Thanks for trying %1! %5\n\n%2 day%3 of "
"your trial remain%4").
arg (m_LicenseManager->getEditionName(edition)).
arg (daysLeft).
arg ((daysLeft == 1) ? "" : "s").
arg ((daysLeft == 1) ? "s" : "");
if (m_appConfig->isCryptoAvailable()) {
m_appConfig->generateCertificate();
thanksMessage = thanksMessage.arg("If you're using SSL, "
"remember to activate all of your devices."); "remember to activate all of your devices.");
} else { } else {
thanksMessage = thanksMessage.arg(""); thanksMessage = thanksMessage.arg("");
}
if (m_LicenseManager->serialKey().isTrial()) {
message.information(this, "Thanks!", thanksMessage);
}
else {
message.information(this, "Activated!",
tr("Thanks for activating %1!").arg
(m_LicenseManager->getEditionName(edition)));
}
} }
QDialog::accept(); if (m_LicenseManager->serialKey().isTrial()) {
message.information(this, "Thanks!", thanksMessage);
} else {
message.information(this, "Activated!",
tr("Thanks for activating %1!")
.arg(m_LicenseManager->getEditionName(edition)));
}
}
QDialog::accept();
} }

View file

@ -1,8 +1,8 @@
#ifndef ACTIVATIONDIALOG_H #ifndef ACTIVATIONDIALOG_H
#define ACTIVATIONDIALOG_H #define ACTIVATIONDIALOG_H
#include <QDialog>
#include <LicenseManager.h> #include <LicenseManager.h>
#include <QDialog>
namespace Ui { namespace Ui {
class ActivationDialog; class ActivationDialog;
@ -10,26 +10,25 @@ class ActivationDialog;
class AppConfig; class AppConfig;
class ActivationDialog : public QDialog class ActivationDialog : public QDialog {
{ Q_OBJECT
Q_OBJECT
public: public:
ActivationDialog(QWidget *parent, AppConfig& appConfig, ActivationDialog(QWidget *parent, AppConfig &appConfig,
LicenseManager& licenseManager); LicenseManager &licenseManager);
~ActivationDialog(); ~ActivationDialog();
public slots: public slots:
void reject(); void reject();
void accept(); void accept();
protected: protected:
void refreshSerialKey(); void refreshSerialKey();
private: private:
Ui::ActivationDialog *ui; Ui::ActivationDialog *ui;
AppConfig* m_appConfig; AppConfig *m_appConfig;
LicenseManager* m_LicenseManager; LicenseManager *m_LicenseManager;
}; };
#endif // ACTIVATIONDIALOG_H #endif // ACTIVATIONDIALOG_H

View file

@ -19,31 +19,24 @@
#include "CoreInterface.h" #include "CoreInterface.h"
ActivationNotifier::ActivationNotifier(QObject *parent) : ActivationNotifier::ActivationNotifier(QObject *parent) : QObject(parent) {}
QObject(parent)
{ void ActivationNotifier::setIdentity(QString identity) {
m_Identity = identity;
} }
void ActivationNotifier::setIdentity(QString identity) void ActivationNotifier::setUpdateInfo(QString const &fromVersion,
{ QString const &toVersion,
m_Identity = identity; QString const &serialKey) {
m_fromVersion = fromVersion;
m_toVersion = toVersion;
m_serialKey = serialKey;
} }
void ActivationNotifier::setUpdateInfo(QString const& fromVersion, void ActivationNotifier::notify() {
QString const& toVersion, // TODO: use something other than CURL
QString const& serialKey)
{
m_fromVersion = fromVersion;
m_toVersion = toVersion;
m_serialKey = serialKey;
} }
void ActivationNotifier::notify() void ActivationNotifier::notifyUpdate() {
{ // TODO: use something other than CURL
// TODO: use something other than CURL
}
void ActivationNotifier::notifyUpdate()
{
// TODO: use something other than CURL
} }

View file

@ -20,28 +20,27 @@
#include <QObject> #include <QObject>
class ActivationNotifier : public QObject class ActivationNotifier : public QObject {
{ Q_OBJECT
Q_OBJECT
public: public:
explicit ActivationNotifier(QObject *parent = 0); explicit ActivationNotifier(QObject *parent = 0);
void setIdentity(QString identity); void setIdentity(QString identity);
void setUpdateInfo(QString const& fromVersion, void setUpdateInfo(QString const &fromVersion, QString const &toVersion,
QString const& toVersion, QString const& serialKey); QString const &serialKey);
public slots: public slots:
void notify(); void notify();
void notifyUpdate(); void notifyUpdate();
signals: signals:
void finished(); void finished();
private: private:
QString m_Identity; QString m_Identity;
QString m_fromVersion; QString m_fromVersion;
QString m_toVersion; QString m_toVersion;
QString m_serialKey; QString m_serialKey;
}; };
#endif // ACTIVATIONNOTIFIER_H #endif // ACTIVATIONNOTIFIER_H

View file

@ -18,112 +18,103 @@
#include "AddClientDialog.h" #include "AddClientDialog.h"
#include "ui_AddClientDialogBase.h" #include "ui_AddClientDialogBase.h"
#include <QPushButton>
#include <QLabel> #include <QLabel>
#include <QPushButton>
AddClientDialog::AddClientDialog(const QString& clientName, QWidget* parent) : AddClientDialog::AddClientDialog(const QString &clientName, QWidget *parent)
QDialog(parent, Qt::WindowTitleHint | Qt::WindowSystemMenuHint), : QDialog(parent, Qt::WindowTitleHint | Qt::WindowSystemMenuHint),
Ui::AddClientDialog(), Ui::AddClientDialog(), m_AddResult(kAddClientIgnore),
m_AddResult(kAddClientIgnore), m_IgnoreAutoConfigClient(false) {
m_IgnoreAutoConfigClient(false) setupUi(this);
{
setupUi(this);
m_pLabelHead->setText("A client wants to connect. " m_pLabelHead->setText("A client wants to connect. "
"Please choose a location for " + clientName + "."); "Please choose a location for " +
clientName + ".");
QIcon icon(":res/icons/64x64/video-display.png"); QIcon icon(":res/icons/64x64/video-display.png");
QSize IconSize(32,32); QSize IconSize(32, 32);
m_pButtonLeft = new QPushButton(this); m_pButtonLeft = new QPushButton(this);
m_pButtonLeft->setIcon(icon); m_pButtonLeft->setIcon(icon);
m_pButtonLeft->setIconSize(IconSize); m_pButtonLeft->setIconSize(IconSize);
gridLayout->addWidget(m_pButtonLeft, 2, 0, 1, 1, Qt::AlignCenter); gridLayout->addWidget(m_pButtonLeft, 2, 0, 1, 1, Qt::AlignCenter);
connect(m_pButtonLeft, SIGNAL(clicked()), this, SLOT(handleButtonLeft())); connect(m_pButtonLeft, SIGNAL(clicked()), this, SLOT(handleButtonLeft()));
m_pButtonUp = new QPushButton(this); m_pButtonUp = new QPushButton(this);
m_pButtonUp->setIcon(icon); m_pButtonUp->setIcon(icon);
m_pButtonUp->setIconSize(IconSize); m_pButtonUp->setIconSize(IconSize);
gridLayout->addWidget(m_pButtonUp, 1, 1, 1, 1, Qt::AlignCenter); gridLayout->addWidget(m_pButtonUp, 1, 1, 1, 1, Qt::AlignCenter);
connect(m_pButtonUp, SIGNAL(clicked()), this, SLOT(handleButtonUp())); connect(m_pButtonUp, SIGNAL(clicked()), this, SLOT(handleButtonUp()));
m_pButtonRight = new QPushButton(this); m_pButtonRight = new QPushButton(this);
m_pButtonRight->setIcon(icon); m_pButtonRight->setIcon(icon);
m_pButtonRight->setIconSize(IconSize); m_pButtonRight->setIconSize(IconSize);
gridLayout->addWidget(m_pButtonRight, 2, 2, 1, 1, Qt::AlignCenter); gridLayout->addWidget(m_pButtonRight, 2, 2, 1, 1, Qt::AlignCenter);
connect(m_pButtonRight, SIGNAL(clicked()), this, SLOT(handleButtonRight())); connect(m_pButtonRight, SIGNAL(clicked()), this, SLOT(handleButtonRight()));
m_pButtonDown = new QPushButton(this); m_pButtonDown = new QPushButton(this);
m_pButtonDown->setIcon(icon); m_pButtonDown->setIcon(icon);
m_pButtonDown->setIconSize(IconSize); m_pButtonDown->setIconSize(IconSize);
gridLayout->addWidget(m_pButtonDown, 3, 1, 1, 1, Qt::AlignCenter); gridLayout->addWidget(m_pButtonDown, 3, 1, 1, 1, Qt::AlignCenter);
connect(m_pButtonDown, SIGNAL(clicked()), this, SLOT(handleButtonDown())); connect(m_pButtonDown, SIGNAL(clicked()), this, SLOT(handleButtonDown()));
m_pLabelCenter = new QLabel(this); m_pLabelCenter = new QLabel(this);
m_pLabelCenter->setPixmap(QPixmap(":res/icons/64x64/video-display.png")); m_pLabelCenter->setPixmap(QPixmap(":res/icons/64x64/video-display.png"));
gridLayout->addWidget(m_pLabelCenter, 2, 1, 1, 1, Qt::AlignCenter); gridLayout->addWidget(m_pLabelCenter, 2, 1, 1, 1, Qt::AlignCenter);
#if defined(Q_OS_MAC) #if defined(Q_OS_MAC)
m_pDialogButtonBox->setLayoutDirection(Qt::RightToLeft); m_pDialogButtonBox->setLayoutDirection(Qt::RightToLeft);
#endif #endif
QPushButton* advanced = m_pDialogButtonBox->addButton("Advanced", QPushButton *advanced =
QDialogButtonBox::HelpRole); m_pDialogButtonBox->addButton("Advanced", QDialogButtonBox::HelpRole);
connect(advanced, SIGNAL(clicked()), this, SLOT(handleButtonAdvanced())); connect(advanced, SIGNAL(clicked()), this, SLOT(handleButtonAdvanced()));
} }
AddClientDialog::~AddClientDialog() AddClientDialog::~AddClientDialog() {
{ delete m_pButtonUp;
delete m_pButtonUp; delete m_pButtonDown;
delete m_pButtonDown; delete m_pButtonLeft;
delete m_pButtonLeft; delete m_pButtonRight;
delete m_pButtonRight; delete m_pLabelCenter;
delete m_pLabelCenter;
} }
void AddClientDialog::changeEvent(QEvent *e) void AddClientDialog::changeEvent(QEvent *e) {
{ QDialog::changeEvent(e);
QDialog::changeEvent(e); switch (e->type()) {
switch (e->type()) { case QEvent::LanguageChange:
case QEvent::LanguageChange: retranslateUi(this);
retranslateUi(this); break;
break; default:
default: break;
break; }
}
} }
void AddClientDialog::handleButtonLeft() void AddClientDialog::handleButtonLeft() {
{ m_AddResult = kAddClientLeft;
m_AddResult = kAddClientLeft; close();
close();
} }
void AddClientDialog::handleButtonUp() void AddClientDialog::handleButtonUp() {
{ m_AddResult = kAddClientUp;
m_AddResult = kAddClientUp; close();
close();
} }
void AddClientDialog::handleButtonRight() void AddClientDialog::handleButtonRight() {
{ m_AddResult = kAddClientRight;
m_AddResult = kAddClientRight; close();
close();
} }
void AddClientDialog::handleButtonDown() void AddClientDialog::handleButtonDown() {
{ m_AddResult = kAddClientDown;
m_AddResult = kAddClientDown; close();
close();
} }
void AddClientDialog::handleButtonAdvanced() void AddClientDialog::handleButtonAdvanced() {
{ m_AddResult = kAddClientOther;
m_AddResult = kAddClientOther; close();
close();
} }
void AddClientDialog::on_m_pCheckBoxIgnoreClient_toggled(bool checked) void AddClientDialog::on_m_pCheckBoxIgnoreClient_toggled(bool checked) {
{ m_IgnoreAutoConfigClient = checked;
m_IgnoreAutoConfigClient = checked;
} }

View file

@ -26,43 +26,42 @@ class QPushButton;
class QLabel; class QLabel;
enum { enum {
kAddClientRight, kAddClientRight,
kAddClientLeft, kAddClientLeft,
kAddClientUp, kAddClientUp,
kAddClientDown, kAddClientDown,
kAddClientOther, kAddClientOther,
kAddClientIgnore kAddClientIgnore
}; };
class AddClientDialog : public QDialog, public Ui::AddClientDialog class AddClientDialog : public QDialog, public Ui::AddClientDialog {
{ Q_OBJECT
Q_OBJECT
public: public:
AddClientDialog(const QString& clientName, QWidget* parent = 0); AddClientDialog(const QString &clientName, QWidget *parent = 0);
~AddClientDialog(); ~AddClientDialog();
int addResult() { return m_AddResult; } int addResult() { return m_AddResult; }
bool ignoreAutoConfigClient() { return m_IgnoreAutoConfigClient; } bool ignoreAutoConfigClient() { return m_IgnoreAutoConfigClient; }
protected: protected:
void changeEvent(QEvent *e); void changeEvent(QEvent *e);
private slots: private slots:
void on_m_pCheckBoxIgnoreClient_toggled(bool checked); void on_m_pCheckBoxIgnoreClient_toggled(bool checked);
void handleButtonLeft(); void handleButtonLeft();
void handleButtonUp(); void handleButtonUp();
void handleButtonRight(); void handleButtonRight();
void handleButtonDown(); void handleButtonDown();
void handleButtonAdvanced(); void handleButtonAdvanced();
private: private:
QPushButton* m_pButtonLeft; QPushButton *m_pButtonLeft;
QPushButton* m_pButtonUp; QPushButton *m_pButtonUp;
QPushButton* m_pButtonRight; QPushButton *m_pButtonRight;
QPushButton* m_pButtonDown; QPushButton *m_pButtonDown;
QLabel* m_pLabelCenter; QLabel *m_pLabelCenter;
int m_AddResult; int m_AddResult;
bool m_IgnoreAutoConfigClient; bool m_IgnoreAutoConfigClient;
}; };
#endif // ADDCLIENTDIALOG_H #endif // ADDCLIENTDIALOG_H

File diff suppressed because it is too large Load diff

View file

@ -20,15 +20,15 @@
#define APPCONFIG_H #define APPCONFIG_H
#include <QObject>
#include <QString>
#include <QVariant>
#include "ElevateMode.h"
#include <shared/EditionType.h>
#include <mutex>
#include "ConfigBase.h" #include "ConfigBase.h"
#include "ConfigWriter.h" #include "ConfigWriter.h"
#include "CoreInterface.h" #include "CoreInterface.h"
#include "ElevateMode.h"
#include <QObject>
#include <QString>
#include <QVariant>
#include <mutex>
#include <shared/EditionType.h>
// this should be incremented each time a new page is added. this is // this should be incremented each time a new page is added. this is
// saved to settings when the user finishes running the wizard. if // saved to settings when the user finishes running the wizard. if
@ -52,308 +52,307 @@ class SettingsDialog;
class ServerConfig; class ServerConfig;
class LicenseRegister; class LicenseRegister;
enum ProcessMode { enum ProcessMode { Service, Desktop };
Service,
Desktop
};
class AppConfig: public QObject, public GUI::Config::ConfigBase class AppConfig : public QObject, public GUI::Config::ConfigBase {
{ Q_OBJECT
Q_OBJECT
friend class SettingsDialog; friend class SettingsDialog;
friend class MainWindow; friend class MainWindow;
friend class SetupWizard; friend class SetupWizard;
friend class ServerConfig; friend class ServerConfig;
public: public:
AppConfig(); AppConfig();
public: public:
bool isWritable() const; bool isWritable() const;
bool isSystemScoped() const; bool isSystemScoped() const;
const QString& screenName() const; const QString &screenName() const;
int port() const; int port() const;
const QString& networkInterface() const; const QString &networkInterface() const;
int logLevel() const; int logLevel() const;
bool logToFile() const; bool logToFile() const;
const QString& logFilename() const; const QString &logFilename() const;
const QString logFilenameCmd() const; const QString logFilenameCmd() const;
QString logLevelText() const; QString logLevelText() const;
ProcessMode processMode() const; ProcessMode processMode() const;
bool wizardShouldRun() const; bool wizardShouldRun() const;
const QString& language() const; const QString &language() const;
bool startedBefore() const; bool startedBefore() const;
bool autoConfig() const; bool autoConfig() const;
void setAutoConfig(bool autoConfig); void setAutoConfig(bool autoConfig);
QString autoConfigServer() const; QString autoConfigServer() const;
void setAutoConfigServer(const QString& autoConfigServer); void setAutoConfigServer(const QString &autoConfigServer);
#ifndef SYNERGY_ENTERPRISE #ifndef SYNERGY_ENTERPRISE
void setEdition(Edition); void setEdition(Edition);
Edition edition() const; Edition edition() const;
void setSerialKey(const QString& serial); void setSerialKey(const QString &serial);
void clearSerialKey(); void clearSerialKey();
QString serialKey() const; QString serialKey() const;
int lastExpiringWarningTime() const; int lastExpiringWarningTime() const;
void setLastExpiringWarningTime(int t); void setLastExpiringWarningTime(int t);
#endif #endif
QString synergysName() const; QString synergysName() const;
QString synergycName() const; QString synergycName() const;
QString synergyProgramDir() const; QString synergyProgramDir() const;
QString synergyLogDir() const; QString synergyLogDir() const;
void persistLogDir(); void persistLogDir();
ElevateMode elevateMode(); ElevateMode elevateMode();
bool isCryptoAvailable() const; bool isCryptoAvailable() const;
void setCryptoEnabled(bool e); void setCryptoEnabled(bool e);
bool getCryptoEnabled() const; bool getCryptoEnabled() const;
void setAutoHide(bool b); void setAutoHide(bool b);
bool getAutoHide(); bool getAutoHide();
void setInvertScrollDirection(bool b); void setInvertScrollDirection(bool b);
bool getInvertScrollDirection() const; bool getInvertScrollDirection() const;
void setEliteBackersUrl(const QString&); void setEliteBackersUrl(const QString &);
void setLicenseNextCheck(unsigned long long); void setLicenseNextCheck(unsigned long long);
const QString& getEliteBackersUrl() const; const QString &getEliteBackersUrl() const;
const QString& getLicenseRegistryUrl() const; const QString &getLicenseRegistryUrl() const;
unsigned long long getLicenseNextCheck() const; unsigned long long getLicenseNextCheck() const;
const QString& getGuid() const; const QString &getGuid() const;
void setLanguageSync(bool b); void setLanguageSync(bool b);
bool getLanguageSync() const; bool getLanguageSync() const;
void setPreventSleep(bool b); void setPreventSleep(bool b);
bool getPreventSleep() const; bool getPreventSleep() const;
bool getClientHostMode() const; bool getClientHostMode() const;
bool getServerClientMode() const; bool getServerClientMode() const;
bool getInitiateConnectionFromServer() const; bool getInitiateConnectionFromServer() const;
#ifndef SYNERGY_ENTERPRISE #ifndef SYNERGY_ENTERPRISE
bool activationHasRun() const; bool activationHasRun() const;
AppConfig& activationHasRun(bool value); AppConfig &activationHasRun(bool value);
#endif #endif
/// @brief Sets the user preference to load from SystemScope. /// @brief Sets the user preference to load from SystemScope.
/// @param [in] value /// @param [in] value
/// True - This will set the variable and load the global scope settings. /// True - This will set the variable and load the global scope
/// False - This will set the variable and load the user scope settings. /// settings. False - This will set the variable and load the user
void setLoadFromSystemScope(bool value); /// scope settings.
void setLoadFromSystemScope(bool value);
bool getServerGroupChecked() const;
bool getUseExternalConfig() const;
const QString &getConfigFile() const;
bool getUseInternalConfig() const;
bool getClientGroupChecked() const;
QString getServerHostname() const;
bool getServerGroupChecked() const; /// @brief Gets the current TLS certificate path
bool getUseExternalConfig() const; /// @return QString The path to the cert
const QString& getConfigFile() const; QString getTLSCertPath() const;
bool getUseInternalConfig() const;
bool getClientGroupChecked() const;
QString getServerHostname() const;
/// @brief Gets the current TLS certificate path /// @brief Get the key length to be used for the private key of a TLS cert
/// @return QString The path to the cert /// @return QString The key length in bits
QString getTLSCertPath() const; QString getTLSKeyLength() const;
/// @brief Get the key length to be used for the private key of a TLS cert void setServerGroupChecked(bool);
/// @return QString The key length in bits void setUseExternalConfig(bool);
QString getTLSKeyLength() const; void setConfigFile(const QString &);
void setUseInternalConfig(bool);
void setClientGroupChecked(bool);
void setServerHostname(const QString &);
void setClientHostMode(bool newValue);
void setServerClientMode(bool newValue);
void setServerGroupChecked(bool); /// @brief Set the path to the TLS/SSL certificate file that will be used
void setUseExternalConfig(bool) ; /// @param [in] path The path to the Certificate
void setConfigFile(const QString&); void setTLSCertPath(const QString &path);
void setUseInternalConfig(bool) ;
void setClientGroupChecked(bool) ;
void setServerHostname(const QString&);
void setClientHostMode(bool newValue);
void setServerClientMode(bool newValue);
/// @brief Set the path to the TLS/SSL certificate file that will be used /// @brief Sets the key length of the private key to use in a TLS connection
/// @param [in] path The path to the Certificate /// @param [in] QString length The key length eg: 1024, 2048, 4096
void setTLSCertPath(const QString& path); void setTLSKeyLength(const QString &length);
/// @brief Sets the key length of the private key to use in a TLS connection QString lastVersion() const;
/// @param [in] QString length The key length eg: 1024, 2048, 4096
void setTLSKeyLength(const QString& length);
void setMinimizeToTray(bool b);
bool getMinimizeToTray();
QString lastVersion() const; void saveSettings() override;
void setLastVersion(const QString &version);
void setMinimizeToTray(bool b); /// @brief Generates TLS certificate
bool getMinimizeToTray(); /// @param [in] bool forceGeneration Generate certificate even if it's exists.
void generateCertificate(bool forceGeneration = false) const;
void saveSettings() override;
void setLastVersion(const QString& version);
/// @brief Generates TLS certificate
/// @param [in] bool forceGeneration Generate certificate even if it's exists.
void generateCertificate(bool forceGeneration=false) const;
protected: protected:
/// @brief The enumeration to easily access the names of the setting inside m_SynergySettingsName /// @brief The enumeration to easily access the names of the setting inside
enum Setting { /// m_SynergySettingsName
kScreenName, enum Setting {
kPort, kScreenName,
kInterfaceSetting, kPort,
kLogLevel, kInterfaceSetting,
kLogToFile, kLogLevel,
kLogFilename, kLogToFile,
kWizardLastRun, kLogFilename,
kLanguage, kWizardLastRun,
kStartedBefore, kLanguage,
kAutoConfig, kStartedBefore,
kAutoConfigServer, kAutoConfig,
kElevateModeSetting, kAutoConfigServer,
kElevateModeEnum, kElevateModeSetting,
kEditionSetting, kElevateModeEnum,
kCryptoEnabled, kEditionSetting,
kAutoHide, kCryptoEnabled,
kSerialKey, kAutoHide,
kLastVersion, kSerialKey,
kLastExpireWarningTime, kLastVersion,
kActivationHasRun, kLastExpireWarningTime,
kMinimizeToTray, kActivationHasRun,
kActivateEmail, kMinimizeToTray,
kLoadSystemSettings, kActivateEmail,
kGroupServerCheck, kLoadSystemSettings,
kUseExternalConfig, kGroupServerCheck,
kConfigFile, kUseExternalConfig,
kUseInternalConfig, kConfigFile,
kGroupClientCheck, kUseInternalConfig,
kServerHostname, kGroupClientCheck,
kTLSCertPath, kServerHostname,
kTLSKeyLength, kTLSCertPath,
kPreventSleep, kTLSKeyLength,
kLanguageSync, kPreventSleep,
kInvertScrollDirection, kLanguageSync,
kEliteBackersUrl, kInvertScrollDirection,
kGuid, kEliteBackersUrl,
kLicenseRegistryUrl, kGuid,
kLicenseNextCheck, kLicenseRegistryUrl,
kInitiateConnectionFromServer, kLicenseNextCheck,
kClientHostMode, kInitiateConnectionFromServer,
kServerClientMode kClientHostMode,
}; kServerClientMode
};
void setScreenName(const QString& s); void setScreenName(const QString &s);
void setPort(int i); void setPort(int i);
void setNetworkInterface(const QString& s); void setNetworkInterface(const QString &s);
void setLogLevel(int i); void setLogLevel(int i);
void setLogToFile(bool b); void setLogToFile(bool b);
void setLogFilename(const QString& s); void setLogFilename(const QString &s);
void setWizardHasRun(); void setWizardHasRun();
void setLanguage(const QString& language); void setLanguage(const QString &language);
void setStartedBefore(bool b); void setStartedBefore(bool b);
void setElevateMode(ElevateMode em); void setElevateMode(ElevateMode em);
/// @brief loads the setting from the current scope /// @brief loads the setting from the current scope
/// @param ignoreSystem should the load feature ignore the globalScope setting that was saved /// @param ignoreSystem should the load feature ignore the globalScope setting
void loadSettings() override; /// that was saved
static QString settingName(AppConfig::Setting name); void loadSettings() override;
static QString settingName(AppConfig::Setting name);
private: private:
QString m_ScreenName;
int m_Port;
QString m_Interface;
int m_LogLevel;
bool m_LogToFile;
QString m_LogFilename;
int m_WizardLastRun;
ProcessMode m_ProcessMode;
QString m_Language;
bool m_StartedBefore;
bool m_AutoConfig;
QString m_AutoConfigServer;
ElevateMode m_ElevateMode;
Edition m_Edition;
QString m_ActivateEmail;
bool m_CryptoEnabled;
bool m_AutoHide;
QString m_Serialkey;
QString m_lastVersion;
QString m_eliteBackersUrl;
QString m_guid;
QString m_licenseRegistryUrl;
unsigned long long m_licenseNextCheck;
int m_LastExpiringWarningTime;
bool m_ActivationHasRun;
bool m_MinimizeToTray;
bool m_InvertScrollDirection = false;
bool m_LanguageSync = true;
bool m_PreventSleep = false;
bool m_InitiateConnectionFromServer = false;
bool m_ClientHostMode = true;
bool m_ServerClientMode = true;
QString m_ScreenName; bool m_ServerGroupChecked;
int m_Port; bool m_UseExternalConfig;
QString m_Interface; QString m_ConfigFile;
int m_LogLevel; bool m_UseInternalConfig;
bool m_LogToFile; bool m_ClientGroupChecked;
QString m_LogFilename; QString m_ServerHostname;
int m_WizardLastRun;
ProcessMode m_ProcessMode;
QString m_Language;
bool m_StartedBefore;
bool m_AutoConfig;
QString m_AutoConfigServer;
ElevateMode m_ElevateMode;
Edition m_Edition;
QString m_ActivateEmail;
bool m_CryptoEnabled;
bool m_AutoHide;
QString m_Serialkey;
QString m_lastVersion;
QString m_eliteBackersUrl;
QString m_guid;
QString m_licenseRegistryUrl;
unsigned long long m_licenseNextCheck;
int m_LastExpiringWarningTime;
bool m_ActivationHasRun;
bool m_MinimizeToTray;
bool m_InvertScrollDirection = false;
bool m_LanguageSync = true;
bool m_PreventSleep = false;
bool m_InitiateConnectionFromServer = false;
bool m_ClientHostMode = true;
bool m_ServerClientMode = true;
bool m_ServerGroupChecked; QString m_TLSCertificatePath; /// @brief The path to the TLS certificate file
bool m_UseExternalConfig; QString m_TLSKeyLength; /// @brief The key length of the TLS cert to make
QString m_ConfigFile;
bool m_UseInternalConfig;
bool m_ClientGroupChecked;
QString m_ServerHostname;
QString m_TLSCertificatePath; /// @brief The path to the TLS certificate file bool m_LoadFromSystemScope; /// @brief should the setting be loaded from
QString m_TLSKeyLength; /// @brief The key length of the TLS cert to make /// SystemScope
/// If the user has settings but this is
/// true then system settings will be
/// loaded instead of the users
bool m_LoadFromSystemScope; /// @brief should the setting be loaded from SystemScope CoreInterface m_CoreInterface;
/// If the user has settings but this is true then
/// system settings will be loaded instead of the users
CoreInterface m_CoreInterface; static const char m_SynergysName[];
static const char m_SynergycName[];
static const char m_SynergyLogDir[];
static const char m_SynergysName[]; /// @brief Contains the string values of the settings names that will be saved
static const char m_SynergycName[]; static const char *m_SynergySettingsName[];
static const char m_SynergyLogDir[];
/// @brief Contains the string values of the settings names that will be saved /// @brief Contains the name of the default configuration filename
static const char* m_SynergySettingsName[]; static const char synergyConfigName[];
/// @brief Contains the name of the default configuration filename /// @brief Sets the value of a setting
static const char synergyConfigName[]; /// @param [in] name The Setting to be saved
/// @param [in] value The Value to be saved
template <typename T> void setSetting(AppConfig::Setting name, T value);
/// @brief Sets the value of a setting /// @brief Sets the value of a common setting
/// @param [in] name The Setting to be saved /// which should have the same value for all scopes
/// @param [in] value The Value to be saved /// @param [in] name The Setting to be saved
template <typename T> /// @param [in] value The Value to be saved
void setSetting(AppConfig::Setting name, T value); template <typename T> void setCommonSetting(AppConfig::Setting name, T value);
/// @brief Sets the value of a common setting /// @brief Loads a setting
/// which should have the same value for all scopes /// @param [in] name The setting to be loaded
/// @param [in] name The Setting to be saved /// @param [in] defaultValue The default value of the setting
/// @param [in] value The Value to be saved QVariant loadSetting(AppConfig::Setting name,
template <typename T> const QVariant &defaultValue = QVariant());
void setCommonSetting(AppConfig::Setting name, T value);
/// @brief Loads a setting /// @brief Loads a common setting
/// @param [in] name The setting to be loaded /// @param [in] name The setting to be loaded
/// @param [in] defaultValue The default value of the setting /// @param [in] defaultValue The default value of the setting
QVariant loadSetting(AppConfig::Setting name, const QVariant& defaultValue = QVariant()); QVariant loadCommonSetting(AppConfig::Setting name,
const QVariant &defaultValue = QVariant()) const;
/// @brief Loads a common setting /// @brief As the settings will be accessible by multiple objects this lock
/// @param [in] name The setting to be loaded /// will ensure that
/// @param [in] defaultValue The default value of the setting /// it cant be modified by more that one object at a time if the
QVariant loadCommonSetting(AppConfig::Setting name, const QVariant& defaultValue = QVariant()) const; /// setting is being switched from system to user.
std::mutex m_settings_lock;
/// @brief As the settings will be accessible by multiple objects this lock will ensure that /// @brief Sets the setting in the config checking if it has changed and
/// it cant be modified by more that one object at a time if the setting is being switched /// flagging that settings
/// from system to user. /// needs to be saved if the setting was different
std::mutex m_settings_lock; /// @param [in] variable the setting that will be changed
/// @param [in] newValue The new value of the setting
template <typename T> void setSettingModified(T &variable, const T &newValue);
/// @brief Sets the setting in the config checking if it has changed and flagging that settings /// @brief This method loads config from specified scope
/// needs to be saved if the setting was different /// @param [in] scope which should be loaded.
/// @param [in] variable the setting that will be changed void loadScope(GUI::Config::ConfigWriter::Scope scope);
/// @param [in] newValue The new value of the setting
template <typename T>
void setSettingModified(T& variable,const T& newValue);
/// @brief This method loads config from specified scope /// @brief This function sets default values
/// @param [in] scope which should be loaded. /// for settings that shouldn't be copied from between scopes.
void loadScope(GUI::Config::ConfigWriter::Scope scope); void setDefaultValues();
/// @brief This function sets default values signals:
/// for settings that shouldn't be copied from between scopes. void sslToggled() const;
void setDefaultValues(); void zeroConfToggled();
void screenNameChanged() const;
signals:
void sslToggled() const;
void zeroConfToggled();
void screenNameChanged() const;
}; };
#endif #endif

View file

@ -7,9 +7,12 @@ extern "C" {
#import <Cocoa/Cocoa.h> #import <Cocoa/Cocoa.h>
#if OSX_DEPLOYMENT_TARGET >= 1014 #if OSX_DEPLOYMENT_TARGET >= 1014
#import <UserNotifications/UNUserNotificationCenter.h> #import <UserNotifications/UNUserNotificationCenter.h>
@interface AppDelegate : NSObject <NSApplicationDelegate, NSUserNotificationCenterDelegate, UNUserNotificationCenterDelegate> @interface AppDelegate
: NSObject <NSApplicationDelegate, NSUserNotificationCenterDelegate,
UNUserNotificationCenterDelegate>
#else #else
@interface AppDelegate : NSObject <NSApplicationDelegate, NSUserNotificationCenterDelegate> @interface AppDelegate
: NSObject <NSApplicationDelegate, NSUserNotificationCenterDelegate>
#endif #endif
@end @end

View file

@ -2,11 +2,11 @@
* synergy -- mouse and keyboard sharing utility * synergy -- mouse and keyboard sharing utility
* Copyright (C) 2012-2016 Symless Ltd. * Copyright (C) 2012-2016 Symless Ltd.
* Copyright (C) 2008 Volker Lanz (vl@fidra.de) * Copyright (C) 2008 Volker Lanz (vl@fidra.de)
* *
* This package is free software; you can redistribute it and/or * This package is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
* found in the file LICENSE that should have accompanied this file. * found in the file LICENSE that should have accompanied this file.
* *
* This package is distributed in the hope that it will be useful, * This package is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
@ -18,29 +18,12 @@
#include "BaseConfig.h" #include "BaseConfig.h"
const char* BaseConfig::m_ModifierNames[] = const char *BaseConfig::m_ModifierNames[] = {"shift", "ctrl", "alt",
{ "meta", "super", "none"};
"shift",
"ctrl",
"alt",
"meta",
"super",
"none"
};
const char* BaseConfig::m_FixNames[] = const char *BaseConfig::m_FixNames[] = {
{ "halfDuplexCapsLock", "halfDuplexNumLock", "halfDuplexScrollLock",
"halfDuplexCapsLock", "xtestIsXineramaUnaware"};
"halfDuplexNumLock",
"halfDuplexScrollLock",
"xtestIsXineramaUnaware"
};
const char* BaseConfig::m_SwitchCornerNames[] =
{
"top-left",
"top-right",
"bottom-left",
"bottom-right"
};
const char *BaseConfig::m_SwitchCornerNames[] = {"top-left", "top-right",
"bottom-left", "bottom-right"};

View file

@ -2,11 +2,11 @@
* synergy -- mouse and keyboard sharing utility * synergy -- mouse and keyboard sharing utility
* Copyright (C) 2012-2016 Symless Ltd. * Copyright (C) 2012-2016 Symless Ltd.
* Copyright (C) 2008 Volker Lanz (vl@fidra.de) * Copyright (C) 2008 Volker Lanz (vl@fidra.de)
* *
* This package is free software; you can redistribute it and/or * This package is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
* found in the file LICENSE that should have accompanied this file. * found in the file LICENSE that should have accompanied this file.
* *
* This package is distributed in the hope that it will be useful, * This package is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
@ -24,68 +24,80 @@
#include <QString> #include <QString>
#include <QVariant> #include <QVariant>
class BaseConfig class BaseConfig {
{ public:
public: enum Modifier {
enum Modifier { DefaultMod = -1, Shift, Ctrl, Alt, Meta, Super, None, NumModifiers }; DefaultMod = -1,
enum SwitchCorner { TopLeft, TopRight, BottomLeft, BottomRight, NumSwitchCorners }; Shift,
enum Fix { CapsLock, NumLock, ScrollLock, XTest, NumFixes }; Ctrl,
Alt,
Meta,
Super,
None,
NumModifiers
};
enum SwitchCorner {
TopLeft,
TopRight,
BottomLeft,
BottomRight,
NumSwitchCorners
};
enum Fix { CapsLock, NumLock, ScrollLock, XTest, NumFixes };
protected: protected:
BaseConfig() {} BaseConfig() {}
virtual ~BaseConfig() {} virtual ~BaseConfig() {}
protected: protected:
template<typename T1, typename T2> template <typename T1, typename T2>
void readSettings(QSettings& settings, T1& array, const QString& arrayName, const T2& deflt) void readSettings(QSettings &settings, T1 &array, const QString &arrayName,
{ const T2 &deflt) {
int entries = settings.beginReadArray(arrayName + "Array"); int entries = settings.beginReadArray(arrayName + "Array");
array.clear(); array.clear();
for (int i = 0; i < entries; i++) for (int i = 0; i < entries; i++) {
{ settings.setArrayIndex(i);
settings.setArrayIndex(i); QVariant v = settings.value(arrayName, deflt);
QVariant v = settings.value(arrayName, deflt); array.append(v.value<T2>());
array.append(v.value<T2>()); }
} settings.endArray();
settings.endArray(); }
}
template<typename T1, typename T2> template <typename T1, typename T2>
void readSettings(QSettings& settings, T1& array, const QString& arrayName, const T2& deflt, int entries) void readSettings(QSettings &settings, T1 &array, const QString &arrayName,
{ const T2 &deflt, int entries) {
Q_ASSERT(array.size() >= entries); Q_ASSERT(array.size() >= entries);
settings.beginReadArray(arrayName + "Array"); settings.beginReadArray(arrayName + "Array");
for (int i = 0; i < entries; i++) for (int i = 0; i < entries; i++) {
{ settings.setArrayIndex(i);
settings.setArrayIndex(i); QVariant v = settings.value(arrayName, deflt);
QVariant v = settings.value(arrayName, deflt); array[i] = v.value<T2>();
array[i] = v.value<T2>(); }
} settings.endArray();
settings.endArray(); }
}
template<typename T> template <typename T>
void writeSettings(QSettings& settings, const T& array, const QString& arrayName) const void writeSettings(QSettings &settings, const T &array,
{ const QString &arrayName) const {
settings.beginWriteArray(arrayName + "Array"); settings.beginWriteArray(arrayName + "Array");
for (int i = 0; i < array.size(); i++) for (int i = 0; i < array.size(); i++) {
{ settings.setArrayIndex(i);
settings.setArrayIndex(i); settings.setValue(arrayName, array[i]);
settings.setValue(arrayName, array[i]); }
} settings.endArray();
settings.endArray(); }
}
public:
static const char *modifierName(int idx) { return m_ModifierNames[idx]; }
static const char *fixName(int idx) { return m_FixNames[idx]; }
static const char *switchCornerName(int idx) {
return m_SwitchCornerNames[idx];
}
public: private:
static const char* modifierName(int idx) { return m_ModifierNames[idx]; } static const char *m_ModifierNames[];
static const char* fixName(int idx) { return m_FixNames[idx]; } static const char *m_FixNames[];
static const char* switchCornerName(int idx) { return m_SwitchCornerNames[idx]; } static const char *m_SwitchCornerNames[];
private:
static const char* m_ModifierNames[];
static const char* m_FixNames[];
static const char* m_SwitchCornerNames[];
}; };
#endif #endif

View file

@ -19,185 +19,172 @@
#if defined(Q_OS_WIN) #if defined(Q_OS_WIN)
#include "MainWindow.h"
#include "SettingsDialog.h"
#include "DataDownloader.h"
#include "QUtility.h"
#include "CommandProcess.h" #include "CommandProcess.h"
#include "DataDownloader.h"
#include "MainWindow.h"
#include "QUtility.h"
#include "SettingsDialog.h"
#include <QUrl>
#include <QThread>
#include <QDir> #include <QDir>
#include <QStandardPaths>
#include <QMessageBox> #include <QMessageBox>
#include <QStandardPaths>
#include <QThread>
#include <QUrl>
#define WIN32_LEAN_AND_MEAN #define WIN32_LEAN_AND_MEAN
#include <Windows.h> #include <Windows.h>
BonjourWindows::BonjourWindows( BonjourWindows::BonjourWindows(SettingsDialog *settingsDialog,
SettingsDialog* settingsDialog, MainWindow *mainWindow, AppConfig &appConfig)
MainWindow* mainWindow, : m_pSettingsDialog(settingsDialog), m_pMainWindow(mainWindow),
AppConfig& appConfig) : m_pBonjourInstall(nullptr), m_pDownloadMessageBox(nullptr),
m_pSettingsDialog(settingsDialog), m_pDataDownloader(nullptr), m_appConfig(appConfig) {}
m_pMainWindow(mainWindow),
m_pBonjourInstall(nullptr), BonjourWindows::~BonjourWindows() {
m_pDownloadMessageBox(nullptr), if (m_pBonjourInstall != nullptr) {
m_pDataDownloader(nullptr), delete m_pBonjourInstall;
m_appConfig(appConfig) }
{
if (m_pDownloadMessageBox != nullptr) {
delete m_pDownloadMessageBox;
}
if (m_pDataDownloader != nullptr) {
delete m_pDataDownloader;
}
} }
BonjourWindows::~BonjourWindows() void BonjourWindows::downloadAndInstall() {
{ QUrl url;
if (m_pBonjourInstall != nullptr) { int arch = getProcessorArch();
delete m_pBonjourInstall; 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_pDownloadMessageBox != nullptr) { if (m_pDataDownloader == nullptr) {
delete m_pDownloadMessageBox; m_pDataDownloader = new DataDownloader(this);
} connect(m_pDataDownloader, SIGNAL(isComplete()), SLOT(downloadFinished()));
}
if (m_pDataDownloader != nullptr) { m_pDataDownloader->download(url);
delete m_pDataDownloader;
} 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::downloadAndInstall() void BonjourWindows::downloadFinished() {
{ m_pMainWindow->appendLogInfo("bonjour downloaded");
QUrl url; install();
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() void BonjourWindows::install() {
{ m_pMainWindow->appendLogInfo("installing bonjour");
m_pMainWindow->appendLogInfo("bonjour downloaded");
install();
}
void BonjourWindows::install() QString tempLocation =
{ QStandardPaths::writableLocation(QStandardPaths::TempLocation);
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);
QString filename = tempLocation;
filename.append("\\").append(bonjourTargetFilename);
QFile file(filename);
if (!file.open(QIODevice::WriteOnly)) {
m_pDownloadMessageBox->hide(); 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 bool BonjourWindows::isRunning() const {
{ QString name = "Bonjour Service";
QString name = "Bonjour Service";
SC_HANDLE hSCManager; SC_HANDLE hSCManager;
hSCManager = OpenSCManager(nullptr, nullptr, SC_MANAGER_CONNECT); 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;
}
}
if (hSCManager == nullptr) {
m_pMainWindow->appendLogError(
QString("failed to open a service controller manager, error: %1")
.arg(GetLastError()));
return false; 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() void BonjourWindows::installFinished() {
{ m_pMainWindow->appendLogInfo("bonjour installed");
m_pMainWindow->appendLogInfo("bonjour installed"); m_appConfig.setAutoConfig(true);
m_appConfig.setAutoConfig(true); m_pSettingsDialog->allowAutoConfig();
m_pSettingsDialog->allowAutoConfig();
} }
#endif // Q_OS_WIN #endif // Q_OS_WIN

View file

@ -34,32 +34,32 @@ class CommandProcess;
class DataDownloader; class DataDownloader;
class AppConfig; class AppConfig;
class BonjourWindows : public QObject class BonjourWindows : public QObject {
{ Q_OBJECT
Q_OBJECT
public: public:
BonjourWindows(SettingsDialog* settingsDialog, MainWindow* mainWindow, AppConfig& appConfig); BonjourWindows(SettingsDialog *settingsDialog, MainWindow *mainWindow,
virtual ~BonjourWindows(); AppConfig &appConfig);
virtual ~BonjourWindows();
public: public:
void downloadAndInstall(); void downloadAndInstall();
bool isRunning() const; bool isRunning() const;
protected slots: protected slots:
void downloadFinished(); void downloadFinished();
void installFinished(); void installFinished();
private: private:
void install(); void install();
private: private:
SettingsDialog* m_pSettingsDialog; SettingsDialog *m_pSettingsDialog;
MainWindow* m_pMainWindow; MainWindow *m_pMainWindow;
CommandProcess* m_pBonjourInstall; CommandProcess *m_pBonjourInstall;
QMessageBox* m_pDownloadMessageBox; QMessageBox *m_pDownloadMessageBox;
DataDownloader* m_pDataDownloader; DataDownloader *m_pDataDownloader;
AppConfig& m_appConfig; AppConfig &m_appConfig;
}; };
#endif // Q_OS_WIN #endif // Q_OS_WIN

View file

@ -1,14 +1,9 @@
#include "CancelActivationDialog.h" #include "CancelActivationDialog.h"
#include "ui_CancelActivationDialog.h" #include "ui_CancelActivationDialog.h"
CancelActivationDialog::CancelActivationDialog(QWidget *parent) : CancelActivationDialog::CancelActivationDialog(QWidget *parent)
QDialog(parent), : QDialog(parent), ui(new Ui::CancelActivationDialog) {
ui(new Ui::CancelActivationDialog) ui->setupUi(this);
{
ui->setupUi(this);
} }
CancelActivationDialog::~CancelActivationDialog() CancelActivationDialog::~CancelActivationDialog() { delete ui; }
{
delete ui;
}

View file

@ -7,16 +7,15 @@ namespace Ui {
class CancelActivationDialog; class CancelActivationDialog;
} }
class CancelActivationDialog : public QDialog class CancelActivationDialog : public QDialog {
{ Q_OBJECT
Q_OBJECT
public: public:
explicit CancelActivationDialog(QWidget *parent = 0); explicit CancelActivationDialog(QWidget *parent = 0);
~CancelActivationDialog(); ~CancelActivationDialog();
private: private:
Ui::CancelActivationDialog *ui; Ui::CancelActivationDialog *ui;
}; };
#endif // CANCELACTIVATIONDIALOG_H #endif // CANCELACTIVATIONDIALOG_H

View file

@ -20,78 +20,65 @@
#include "MainWindow.h" #include "MainWindow.h"
#include <QMessageBox>
#include <QHostAddress> #include <QHostAddress>
#include <QMessageBox>
ClientConnection::ClientConnection(MainWindow& parent) : ClientConnection::ClientConnection(MainWindow &parent) : m_parent(parent) {}
m_parent(parent)
{
}
void ClientConnection::update(const QString& line) void ClientConnection::update(const QString &line) {
{ if (m_checkConnection && checkMainWindow()) {
if (m_checkConnection && checkMainWindow()) if (line.contains("failed to connect to server")) {
{ m_checkConnection = false;
if (line.contains("failed to connect to server")) if (!line.contains("server refused client with our name") &&
{ !line.contains("Trying next address")) {
m_checkConnection = false; showMessage(getMessage(line));
if (!line.contains("server refused client with our name") && }
!line.contains("Trying next address")) } else if (line.contains("connected to server")) {
{ m_checkConnection = false;
showMessage(getMessage(line));
}
}
else if (line.contains("connected to server"))
{
m_checkConnection = false;
}
} }
}
} }
bool ClientConnection::checkMainWindow() bool ClientConnection::checkMainWindow() {
{ bool result = m_parent.isActiveWindow();
bool result = m_parent.isActiveWindow();
if (m_parent.isMinimized() || m_parent.isHidden()) if (m_parent.isMinimized() || m_parent.isHidden()) {
{ m_parent.showNormal();
m_parent.showNormal(); m_parent.activateWindow();
m_parent.activateWindow(); result = true;
result = true; }
return result;
}
QString ClientConnection::getMessage(const QString &line) const {
QString message(QObject::tr("Connection failed.\nCheck the IP address on the "
"server, your TLS and firewall settings."));
if (line.contains("server already has a connected client with our name")) {
message =
QObject::tr("Connection failed.\nYou can’t name 2 computers the same.");
} else {
QHostAddress address(m_parent.appConfig().getServerHostname());
if (address.isNull()) {
message =
QObject::tr(
"We can’t connect to the server \"%1\" try to connect using the "
"server IP address and check your firewall settings.")
.arg(m_parent.appConfig().getServerHostname());
} }
}
return result; return message;
} }
QString ClientConnection::getMessage(const QString& line) const void ClientConnection::showMessage(const QString &message) const {
{ QMessageBox dialog(&m_parent);
QString message(QObject::tr("Connection failed.\nCheck the IP address on the server, your TLS and firewall settings.")); dialog.addButton(QObject::tr("Close"), QMessageBox::RejectRole);
dialog.setText(message);
if (line.contains("server already has a connected client with our name")) dialog.exec();
{
message = QObject::tr("Connection failed.\nYou can’t name 2 computers the same.");
}
else
{
QHostAddress address(m_parent.appConfig().getServerHostname());
if (address.isNull())
{
message = QObject::tr("We can’t connect to the server \"%1\" try to connect using the server IP address and check your firewall settings.")
.arg(m_parent.appConfig().getServerHostname());
}
}
return message;
} }
void ClientConnection::showMessage(const QString& message) const void ClientConnection::setCheckConnection(bool checkConnection) {
{ m_checkConnection = checkConnection;
QMessageBox dialog(&m_parent);
dialog.addButton(QObject::tr("Close"), QMessageBox::RejectRole);
dialog.setText(message);
dialog.exec();
}
void ClientConnection::setCheckConnection(bool checkConnection)
{
m_checkConnection = checkConnection;
} }

View file

@ -23,20 +23,19 @@
class MainWindow; class MainWindow;
class ClientConnection class ClientConnection {
{ MainWindow &m_parent;
MainWindow& m_parent; bool m_checkConnection = false;
bool m_checkConnection = false;
public: public:
explicit ClientConnection(MainWindow& parent); explicit ClientConnection(MainWindow &parent);
void update(const QString& line); void update(const QString &line);
void setCheckConnection(bool checkConnection); void setCheckConnection(bool checkConnection);
private: private:
QString getMessage(const QString& line) const; QString getMessage(const QString &line) const;
bool checkMainWindow(); bool checkMainWindow();
void showMessage(const QString& message) const; void showMessage(const QString &message) const;
}; };
#endif // CLIENTCONNECTION_H #endif // CLIENTCONNECTION_H

View file

@ -20,44 +20,38 @@
#include <QProcess> #include <QProcess>
#include <stdexcept> #include <stdexcept>
CommandProcess::CommandProcess(QString cmd, QStringList arguments, QString input) : CommandProcess::CommandProcess(QString cmd, QStringList arguments,
m_Command(cmd), QString input)
m_Arguments(arguments), : m_Command(cmd), m_Arguments(arguments), m_Input(input) {}
m_Input(input)
{
}
QString CommandProcess::run() QString CommandProcess::run() {
{ QProcess process;
QProcess process; process.setReadChannel(QProcess::StandardOutput);
process.setReadChannel(QProcess::StandardOutput); process.start(m_Command, m_Arguments);
process.start(m_Command, m_Arguments); bool success = process.waitForStarted();
bool success = process.waitForStarted();
QString output, error; QString output, error;
if (success) if (success) {
{ if (!m_Input.isEmpty()) {
if (!m_Input.isEmpty()) { process.write(m_Input.toStdString().c_str());
process.write(m_Input.toStdString().c_str());
}
if (process.waitForFinished()) {
output = QString::fromLocal8Bit(process.readAllStandardOutput().trimmed());
error = process.readAllStandardError().trimmed();
}
} }
int code = process.exitCode(); if (process.waitForFinished()) {
if (!error.isEmpty() || !success || code != 0) output =
{ QString::fromLocal8Bit(process.readAllStandardOutput().trimmed());
throw std::runtime_error( error = process.readAllStandardError().trimmed();
QString("Code: %1\nError: %2")
.arg(process.exitCode())
.arg(error.isEmpty() ? "Unknown" : error)
.toStdString());
} }
}
emit finished(); int code = process.exitCode();
if (!error.isEmpty() || !success || code != 0) {
throw std::runtime_error(QString("Code: %1\nError: %2")
.arg(process.exitCode())
.arg(error.isEmpty() ? "Unknown" : error)
.toStdString());
}
return output; emit finished();
return output;
} }

View file

@ -21,23 +21,22 @@
#include <QObject> #include <QObject>
#include <QStringList> #include <QStringList>
class CommandProcess : public QObject class CommandProcess : public QObject {
{ Q_OBJECT
Q_OBJECT
public: public:
CommandProcess(QString cmd, QStringList arguments, QString input = ""); CommandProcess(QString cmd, QStringList arguments, QString input = "");
signals: signals:
void finished(); void finished();
public slots: public slots:
QString run(); QString run();
private: private:
QString m_Command; QString m_Command;
QStringList m_Arguments; QStringList m_Arguments;
QString m_Input; QString m_Input;
}; };
#endif // COMMANDTHREAD_H #endif // COMMANDTHREAD_H

View file

@ -19,30 +19,33 @@
#define SYNERGY_CORE_CONFIGBASE_H #define SYNERGY_CORE_CONFIGBASE_H
namespace GUI { namespace GUI {
namespace Config { namespace Config {
///@brief This abstract class will be used by all classes that use the ConfigWriter ///@brief This abstract class will be used by all classes that use the
/// to allow global saving and loading /// ConfigWriter
class ConfigBase { /// to allow global saving and loading
public : class ConfigBase {
ConfigBase() = default; public:
ConfigBase() = default;
virtual ~ConfigBase() = default; virtual ~ConfigBase() = default;
/// @brief The function that is called when the settings need to be loaded from file /// @brief The function that is called when the settings need to be loaded
virtual void loadSettings() = 0; /// from file
virtual void loadSettings() = 0;
/// @brief The function that is called when the settings need to be saved to file /// @brief The function that is called when the settings need to be saved to
virtual void saveSettings() = 0; /// file
virtual void saveSettings() = 0;
/// @brief Returns true if the class has marked itself with having unsaved changes /// @brief Returns true if the class has marked itself with having unsaved
bool modified() const { return m_unsavedChanges; } /// changes
bool modified() const { return m_unsavedChanges; }
protected: protected:
/// @brief Does the class have unsaved changes in it. /// @brief Does the class have unsaved changes in it.
bool m_unsavedChanges = false; bool m_unsavedChanges = false;
};
}; } // namespace Config
} } // namespace GUI
} #endif // SYNERGY_CORE_CONFIGBASE_H
#endif //SYNERGY_CORE_CONFIGBASE_H

View file

@ -20,207 +20,193 @@
#include <QCoreApplication> #include <QCoreApplication>
#include <QFile> #include <QFile>
#include "ConfigWriter.h"
#include "ConfigBase.h" #include "ConfigBase.h"
#include "ConfigWriter.h"
namespace { namespace {
QString getSystemSettingPath() QString getSystemSettingPath() {
{ const QString settingFilename("SystemConfig.ini");
const QString settingFilename("SystemConfig.ini"); QString path;
QString path;
#if defined(Q_OS_WIN) #if defined(Q_OS_WIN)
// Program file // Program file
path = QCoreApplication::applicationDirPath() + "\\"; path = QCoreApplication::applicationDirPath() + "\\";
#elif defined(Q_OS_DARWIN) #elif defined(Q_OS_DARWIN)
//Global preferances dir // Global preferances dir
// Would be nice to use /library, but QT has no elevate system in place // Would be nice to use /library, but QT has no elevate system in place
path = "/usr/local/etc/symless/"; path = "/usr/local/etc/symless/";
#elif defined(Q_OS_LINUX) #elif defined(Q_OS_LINUX)
// QT adds application and filename to the end of the path already on linux // QT adds application and filename to the end of the path already on linux
path = "/usr/local/etc/symless/"; path = "/usr/local/etc/symless/";
return path; return path;
#else #else
assert("OS not supported"); assert("OS not supported");
#endif #endif
return path + settingFilename; return path + settingFilename;
} }
#if defined(Q_OS_WIN) #if defined(Q_OS_WIN)
void loadOldSystemSettings(QSettings& settings) void loadOldSystemSettings(QSettings &settings) {
{ if (!QFile(settings.fileName()).exists()) {
if (!QFile(settings.fileName()).exists()) { QSettings::setPath(QSettings::IniFormat, QSettings::SystemScope,
QSettings::setPath(QSettings::IniFormat, QSettings::SystemScope, "SystemConfig.ini"); "SystemConfig.ini");
QSettings oldSystemSettings (QSettings::IniFormat, QSettings oldSystemSettings(QSettings::IniFormat, QSettings::SystemScope,
QSettings::SystemScope, QCoreApplication::organizationName(),
QCoreApplication::organizationName(), QCoreApplication::applicationName());
QCoreApplication::applicationName());
if (QFile(oldSystemSettings.fileName()).exists()) { if (QFile(oldSystemSettings.fileName()).exists()) {
for (const auto& key : oldSystemSettings.allKeys()) { for (const auto &key : oldSystemSettings.allKeys()) {
settings.setValue(key, oldSystemSettings.value(key)); settings.setValue(key, oldSystemSettings.value(key));
} }
}
//Restore system settings path
QSettings::setPath(QSettings::IniFormat, QSettings::SystemScope, getSystemSettingPath());
} }
// Restore system settings path
QSettings::setPath(QSettings::IniFormat, QSettings::SystemScope,
getSystemSettingPath());
}
} }
#endif #endif
} } // namespace
namespace GUI { namespace GUI {
namespace Config { namespace Config {
//Assignment of static variable // Assignment of static variable
ConfigWriter *ConfigWriter::s_pConfiguration = nullptr; ConfigWriter *ConfigWriter::s_pConfiguration = nullptr;
ConfigWriter *ConfigWriter::make() {
ConfigWriter *ConfigWriter::make() { // Only one ConfigWriter can exist at any one time (Singleton)
// Only one ConfigWriter can exist at any one time (Singleton) if (!s_pConfiguration) {
if (!s_pConfiguration) { s_pConfiguration = new ConfigWriter();
s_pConfiguration = new ConfigWriter(); }
} return s_pConfiguration;
return s_pConfiguration;
}
ConfigWriter::ConfigWriter() {
QSettings::setPath(QSettings::Format::IniFormat,
QSettings::Scope::SystemScope,
getSystemSettingPath());
//Config will default to User settings if they exist,
// otherwise it will load System setting and save them to User settings
m_pSettingsSystem = new QSettings(QSettings::Format::IniFormat,
QSettings::Scope::SystemScope,
QCoreApplication::organizationName(),
QCoreApplication::applicationName());
#if defined(Q_OS_WIN)
//This call is needed for backwardcapability with old settings.
loadOldSystemSettings(*m_pSettingsSystem);
#endif
//defaults to user scope, if we set the scope specifically then we also have to set
// the application name and the organisation name which breaks backwards compatibility
// See #6730
m_pSettingsUser = new QSettings();
//Set scope to user for initially
m_pSettingsCurrent = m_pSettingsUser;
}
void ConfigWriter::destroy() {
destroy(s_pConfiguration);
}
ConfigWriter::~ConfigWriter() {
while(!m_pCallerList.empty()) {
m_pCallerList.pop_back();
}
m_pSettingsCurrent = nullptr; //this only references other pointers
destroy(m_pSettingsSystem);
destroy(m_pSettingsUser);
}
bool ConfigWriter::hasSetting(const QString &name, Scope scope) const {
switch (scope){
case kUser:
return m_pSettingsUser->contains(name);
case kSystem:
return m_pSettingsSystem->contains(name);
default:
return m_pSettingsCurrent->contains(name);
}
}
bool ConfigWriter::isWritable() const {
return m_pSettingsCurrent->isWritable();
}
QVariant ConfigWriter::loadSetting(const QString& name, const QVariant &defaultValue, Scope scope) {
switch (scope){
case kUser:
return m_pSettingsUser->value(name, defaultValue);
case kSystem:
return m_pSettingsSystem->value(name, defaultValue);
default:
return m_pSettingsCurrent->value(name, defaultValue);
}
}
void ConfigWriter::setScope(ConfigWriter::Scope scope) {
if (m_CurrentScope != scope) {
m_CurrentScope = scope;
switch (scope) {
case kUser:
m_pSettingsCurrent = m_pSettingsUser;
break;
case kSystem:
m_pSettingsCurrent = m_pSettingsSystem;
break;
default:
//setScope should never be kCurrent
assert(scope);
}
}
}
ConfigWriter::Scope ConfigWriter::getScope() const {
return m_CurrentScope;
}
void ConfigWriter::globalLoad() {
for (auto &i : m_pCallerList) {
i->loadSettings();
}
}
void ConfigWriter::globalSave() {
//Save if there are any unsaved changes otherwise skip
if (unsavedChanges()) {
for (auto &i : m_pCallerList) {
i->saveSettings();
}
m_pSettingsUser->sync();
m_pSettingsSystem->sync();
m_unsavedChanges = false;
}
}
QSettings &ConfigWriter::settings() {
return *m_pSettingsCurrent;
}
void ConfigWriter::registerClass(ConfigBase * receiver) {
m_pCallerList.push_back(receiver);
}
bool ConfigWriter::unsavedChanges() const {
if (m_unsavedChanges) {
return true;
}
for (const auto &i : m_pCallerList) {
if (i->modified()){
//If any class returns true there is no point checking more
return true;
}
}
// If this line is reached no class has unsaved changes
return false;
}
void ConfigWriter::markUnsaved() {
m_unsavedChanges = true;
}
}
} }
ConfigWriter::ConfigWriter() {
QSettings::setPath(QSettings::Format::IniFormat,
QSettings::Scope::SystemScope, getSystemSettingPath());
// Config will default to User settings if they exist,
// otherwise it will load System setting and save them to User settings
m_pSettingsSystem =
new QSettings(QSettings::Format::IniFormat, QSettings::Scope::SystemScope,
QCoreApplication::organizationName(),
QCoreApplication::applicationName());
#if defined(Q_OS_WIN)
// This call is needed for backwardcapability with old settings.
loadOldSystemSettings(*m_pSettingsSystem);
#endif
// defaults to user scope, if we set the scope specifically then we also have
// to set
// the application name and the organisation name which breaks backwards
// compatibility See #6730
m_pSettingsUser = new QSettings();
// Set scope to user for initially
m_pSettingsCurrent = m_pSettingsUser;
}
void ConfigWriter::destroy() { destroy(s_pConfiguration); }
ConfigWriter::~ConfigWriter() {
while (!m_pCallerList.empty()) {
m_pCallerList.pop_back();
}
m_pSettingsCurrent = nullptr; // this only references other pointers
destroy(m_pSettingsSystem);
destroy(m_pSettingsUser);
}
bool ConfigWriter::hasSetting(const QString &name, Scope scope) const {
switch (scope) {
case kUser:
return m_pSettingsUser->contains(name);
case kSystem:
return m_pSettingsSystem->contains(name);
default:
return m_pSettingsCurrent->contains(name);
}
}
bool ConfigWriter::isWritable() const {
return m_pSettingsCurrent->isWritable();
}
QVariant ConfigWriter::loadSetting(const QString &name,
const QVariant &defaultValue, Scope scope) {
switch (scope) {
case kUser:
return m_pSettingsUser->value(name, defaultValue);
case kSystem:
return m_pSettingsSystem->value(name, defaultValue);
default:
return m_pSettingsCurrent->value(name, defaultValue);
}
}
void ConfigWriter::setScope(ConfigWriter::Scope scope) {
if (m_CurrentScope != scope) {
m_CurrentScope = scope;
switch (scope) {
case kUser:
m_pSettingsCurrent = m_pSettingsUser;
break;
case kSystem:
m_pSettingsCurrent = m_pSettingsSystem;
break;
default:
// setScope should never be kCurrent
assert(scope);
}
}
}
ConfigWriter::Scope ConfigWriter::getScope() const { return m_CurrentScope; }
void ConfigWriter::globalLoad() {
for (auto &i : m_pCallerList) {
i->loadSettings();
}
}
void ConfigWriter::globalSave() {
// Save if there are any unsaved changes otherwise skip
if (unsavedChanges()) {
for (auto &i : m_pCallerList) {
i->saveSettings();
}
m_pSettingsUser->sync();
m_pSettingsSystem->sync();
m_unsavedChanges = false;
}
}
QSettings &ConfigWriter::settings() { return *m_pSettingsCurrent; }
void ConfigWriter::registerClass(ConfigBase *receiver) {
m_pCallerList.push_back(receiver);
}
bool ConfigWriter::unsavedChanges() const {
if (m_unsavedChanges) {
return true;
}
for (const auto &i : m_pCallerList) {
if (i->modified()) {
// If any class returns true there is no point checking more
return true;
}
}
// If this line is reached no class has unsaved changes
return false;
}
void ConfigWriter::markUnsaved() { m_unsavedChanges = true; }
} // namespace Config
} // namespace GUI

View file

@ -17,133 +17,141 @@
#ifndef SYNERGY_CORE_CONFIGWRITER_H #ifndef SYNERGY_CORE_CONFIGWRITER_H
#define SYNERGY_CORE_CONFIGWRITER_H #define SYNERGY_CORE_CONFIGWRITER_H
#include <QVariant>
#include <QSettings> #include <QSettings>
#include <QVariant>
/// @brief Contains GUI code /// @brief Contains GUI code
namespace GUI { namespace GUI {
/// @brief Contains Configuration code /// @brief Contains Configuration code
namespace Config { namespace Config {
//Forward declare the class referenced by pointer // Forward declare the class referenced by pointer
class ConfigBase; class ConfigBase;
class ConfigWriter: private QObject { class ConfigWriter : private QObject {
public: public:
/// @brief the public way to construct the configuration calls
/// The pointer returned is owned by this class and should not be
/// stored by other classes.
static ConfigWriter *make();
/// @brief the public way to construct the configuration calls /// @brief the public way to destroy the configuration class
/// The pointer returned is owned by this class and should not be stored static void destroy();
/// by other classes.
static ConfigWriter* make();
/// @brief the public way to destroy the configuration class ~ConfigWriter() override;
static void destroy();
~ConfigWriter() override; ///@brief An Enumeration of all the scopes available
enum Scope { kCurrent, kSystem, kUser };
///@brief An Enumeration of all the scopes available /// @brief Checks if the setting exists
enum Scope { kCurrent, kSystem, kUser}; /// @param [in] name The name of the setting to check
/// @param [in] scope The scope to search in
/// @return bool True if the current scope has the named setting
bool hasSetting(const QString &name, Scope scope = kCurrent) const;
/// @brief Checks if the setting exists /// @brief Checks if the current scope settings writable
/// @param [in] name The name of the setting to check /// @return bool True if the current scope writable
/// @param [in] scope The scope to search in bool isWritable() const;
/// @return bool True if the current scope has the named setting
bool hasSetting(const QString& name, Scope scope = kCurrent) const;
/// @brief Checks if the current scope settings writable /// @brief Sets the value of a setting
/// @return bool True if the current scope writable /// @param [in] name The Setting to be saved
bool isWritable() const; /// @param [in] value The Value to be saved (Templated)
/// @param [in] scope The scope to get the value from, default is current
/// scope
template <typename T>
void setSetting(const QString &name, T value, Scope scope = kCurrent);
/// @brief Sets the value of a setting /// @brief Loads a setting
/// @param [in] name The Setting to be saved /// @param [in] name The setting to be loaded
/// @param [in] value The Value to be saved (Templated) /// @param [in] defaultValue The default value of the setting
/// @param [in] scope The scope to get the value from, default is current scope /// @param [in] scope The scope to get the value from, default is current
template <typename T> /// scope
void setSetting(const QString& name, T value, Scope scope = kCurrent); QVariant loadSetting(const QString &name,
const QVariant &defaultValue = QVariant(),
Scope scope = kCurrent);
/// @brief Loads a setting /// @brief Changes the setting save and load location between System and User
/// @param [in] name The setting to be loaded /// scope
/// @param [in] defaultValue The default value of the setting /// @param [in] scope The scope to set
/// @param [in] scope The scope to get the value from, default is current scope void setScope(Scope scope = kUser);
QVariant loadSetting(const QString& name, const QVariant& defaultValue = QVariant(), Scope scope = kCurrent);
/// @brief Changes the setting save and load location between System and User scope /// @brief Get the current scope the settings are loading and save from.
/// @param [in] scope The scope to set /// @return Scope An enum defining the current scope
void setScope(Scope scope = kUser); Scope getScope() const;
/// @brief Get the current scope the settings are loading and save from. /// @brief trigger a config load across all registered classes
/// @return Scope An enum defining the current scope void globalLoad();
Scope getScope() const;
/// @brief trigger a config load across all registered classes /// @brief trigger a config save across all registered classes
void globalLoad(); void globalSave();
/// @brief trigger a config save across all registered classes /// @brief Returns the current scopes settings object
void globalSave(); /// If more specialize control into the settings is needed this can
/// provide direct access to the settings file handler
/// @return QSettings The Settings object as a reference
QSettings &settings();
/// @brief Returns the current scopes settings object /// @brief This marks the settings as unsaved if the settings() was used to
/// If more specialize control into the settings is needed this can provide /// directly affect the config file
/// direct access to the settings file handler void markUnsaved();
/// @return QSettings The Settings object as a reference
QSettings& settings();
/// @brief This marks the settings as unsaved if the settings() was used to directly affect the config file /// @brief Register a class to receives globalLoad and globalSave events
void markUnsaved(); /// @param [in] ConfigBase The class that will receive the events
void registerClass(ConfigBase *receiver);
/// @brief Register a class to receives globalLoad and globalSave events /// @brief Checks if any registered class has any unsaved changes
/// @param [in] ConfigBase The class that will receive the events /// @return bool True if any registered class has unsaved changes
void registerClass(ConfigBase* receiver); bool unsavedChanges() const;
/// @brief Checks if any registered class has any unsaved changes protected:
/// @return bool True if any registered class has unsaved changes Scope m_CurrentScope = kUser; /// @brief The current scope of the settings
bool unsavedChanges() const;
protected: QSettings *m_pSettingsCurrent =
nullptr; /// @brief The currently active settings
QSettings *m_pSettingsUser = nullptr; /// @brief The user specific settings
QSettings *m_pSettingsSystem = nullptr; /// @brief The system wide settings
Scope m_CurrentScope = kUser; /// @brief The current scope of the settings private:
/// @brief Contains a list all all classes that hook into the writer.
/// This allows all classes that save settings to be called an updated
/// on a save and reload by any other class
std::list<ConfigBase *> m_pCallerList;
QSettings* m_pSettingsCurrent = nullptr; /// @brief The currently active settings /// @brief if this class modified settings then set the flag
QSettings* m_pSettingsUser = nullptr; /// @brief The user specific settings bool m_unsavedChanges = false;
QSettings* m_pSettingsSystem = nullptr; /// @brief The system wide settings
private: /// @brief The constructor, as this is a singolton we want to control who can
/// call the constructor
ConfigWriter();
/// @brief Contains a list all all classes that hook into the writer. /// @brief the pointer of the ConfigWriter for singolton use
/// This allows all classes that save settings to be called an updated static ConfigWriter *s_pConfiguration;
/// on a save and reload by any other class
std::list<ConfigBase*> m_pCallerList;
/// @brief if this class modified settings then set the flag /// @brief deletes pointers and sets the value to null
bool m_unsavedChanges = false; template <class T> static inline void destroy(T *&p) {
delete p;
p = 0;
}
};
/// @brief The constructor, as this is a singolton we want to control who can call the constructor // Implementation of a template function needs to be visible to all calls thus
ConfigWriter(); // is must be in the header Moved so its not bulking out the class definition
template <typename T>
/// @brief the pointer of the ConfigWriter for singolton use void ConfigWriter::setSetting(const QString &name, T value, Scope scope) {
static ConfigWriter* s_pConfiguration; switch (scope) {
case kUser:
/// @brief deletes pointers and sets the value to null m_pSettingsUser->setValue(name, value);
template<class T> static inline void destroy(T*& p) { delete p; p = 0; } break;
}; case kSystem:
m_pSettingsSystem->setValue(name, value);
// Implementation of a template function needs to be visible to all calls thus is must be in the header break;
// Moved so its not bulking out the class definition default:
template<typename T> m_pSettingsCurrent->setValue(name, value);
void ConfigWriter::setSetting(const QString& name, T value, Scope scope) { break;
switch (scope){ }
case kUser: m_unsavedChanges = true;
m_pSettingsUser->setValue(name, value);
break;
case kSystem:
m_pSettingsSystem->setValue(name, value);
break;
default:
m_pSettingsCurrent->setValue(name, value);
break;
}
m_unsavedChanges = true;
}
}
} }
#endif //SYNERGY_CORE_CONFIGWRITER_H } // namespace Config
} // namespace GUI
#endif // SYNERGY_CORE_CONFIGWRITER_H

View file

@ -21,9 +21,9 @@
#include "QUtility.h" #include "QUtility.h"
#include <QCoreApplication> #include <QCoreApplication>
#include <QDir>
#include <QProcess> #include <QProcess>
#include <QtGlobal> #include <QtGlobal>
#include <QDir>
#include <stdexcept> #include <stdexcept>
static const char kCoreBinary[] = "syntool"; static const char kCoreBinary[] = "syntool";
@ -34,40 +34,31 @@ static const char kSerialKeyFilename[] = "Synergy.subkey";
static const char kSerialKeyFilename[] = ".synergy.subkey"; static const char kSerialKeyFilename[] = ".synergy.subkey";
#endif #endif
CoreInterface::CoreInterface() CoreInterface::CoreInterface() {}
{
QString CoreInterface::getProfileDir() {
QStringList args("--get-profile-dir");
return run(args);
} }
QString CoreInterface::getProfileDir() QString CoreInterface::getInstalledDir() {
{ QStringList args("--get-installed-dir");
QStringList args("--get-profile-dir"); return run(args);
return run(args);
} }
QString CoreInterface::getInstalledDir() QString CoreInterface::getArch() {
{ QStringList args("--get-arch");
QStringList args("--get-installed-dir"); return run(args);
return run(args);
} }
QString CoreInterface::getArch() QString CoreInterface::getSerialKeyFilePath() {
{ QString filename = getProfileDir() + QDir::separator() + kSerialKeyFilename;
QStringList args("--get-arch"); return filename;
return run(args);
} }
QString CoreInterface::getSerialKeyFilePath() QString CoreInterface::run(const QStringList &args, const QString &input) {
{ QString program(QCoreApplication::applicationDirPath() + "/" + kCoreBinary);
QString filename = getProfileDir() + QDir::separator() + kSerialKeyFilename;
return filename;
}
QString CoreInterface::run(const QStringList& args, const QString& input) CommandProcess commandProcess(program, args, input);
{ return commandProcess.run();
QString program(
QCoreApplication::applicationDirPath()
+ "/" + kCoreBinary);
CommandProcess commandProcess(program, args, input);
return commandProcess.run();
} }

View file

@ -19,14 +19,13 @@
#include <QString> #include <QString>
class CoreInterface class CoreInterface {
{
public: public:
CoreInterface(); CoreInterface();
QString getProfileDir(); QString getProfileDir();
QString getInstalledDir(); QString getInstalledDir();
QString getArch(); QString getArch();
QString getSerialKeyFilePath(); QString getSerialKeyFilePath();
QString run(const QStringList& args, const QString& input = ""); QString run(const QStringList &args, const QString &input = "");
}; };

View file

@ -16,93 +16,83 @@
*/ */
#include "CreditsLoader.h" #include "CreditsLoader.h"
#include "MainWindow.h"
#include "AppConfig.h" #include "AppConfig.h"
#include "MainWindow.h"
#include <QNetworkReply>
#include <QNetworkRequest>
#include <QJsonDocument> #include <QJsonDocument>
#include <QJsonParseError> #include <QJsonParseError>
#include <QNetworkReply>
#include <QNetworkRequest>
namespace { namespace {
class CreditsResponse { class CreditsResponse {
public: public:
explicit CreditsResponse(const QByteArray& response) { explicit CreditsResponse(const QByteArray &response) {
auto data = parseJson(response); auto data = parseJson(response);
m_status = data["status"].toString(); m_status = data["status"].toString();
if (isSuccess()) { if (isSuccess()) {
m_data = data["data"].toString(); m_data = data["data"].toString();
} } else if (isFailed()) {
else if (isFailed()) { m_data = data["message"].toString();
m_data = data["message"].toString(); } else {
} m_data = "Unknown response from the server";
else {
m_data = "Unknown response from the server";
}
} }
}
bool isSuccess() const { bool isSuccess() const { return (m_status == "success"); }
return (m_status == "success");
}
bool isFailed() const { bool isFailed() const { return (m_status == "failed"); }
return (m_status == "failed");
}
const QString& getData() const { const QString &getData() const { return m_data; }
return m_data;
}
private: private:
QMap<QString, QVariant> parseJson(const QByteArray& json) const { QMap<QString, QVariant> parseJson(const QByteArray &json) const {
QJsonParseError jsonError; QJsonParseError jsonError;
auto data = QJsonDocument::fromJson(json, &jsonError); auto data = QJsonDocument::fromJson(json, &jsonError);
if (jsonError.error == QJsonParseError::NoError) { if (jsonError.error == QJsonParseError::NoError) {
return data.toVariant().toMap(); return data.toVariant().toMap();
}
return QMap<QString, QVariant>();
} }
return QMap<QString, QVariant>();
}
QString m_data; QString m_data;
QString m_status; QString m_status;
}; };
} // namespace
CreditsLoader::CreditsLoader(MainWindow &mainWindow, const AppConfig &config)
: m_mainWindow(mainWindow), m_config(config) {
connect(&m_manager, SIGNAL(finished(QNetworkReply *)), this,
SLOT(replyFinished(QNetworkReply *)));
} }
CreditsLoader::CreditsLoader(MainWindow& mainWindow, const AppConfig& config) : void CreditsLoader::loadEliteBackers() {
m_mainWindow(mainWindow), const auto ELITE_BACKERS_URL = m_config.getEliteBackersUrl();
m_config(config) m_mainWindow.appendLogDebug(
{ QString("Send request: %1").arg(ELITE_BACKERS_URL));
connect(&m_manager, SIGNAL(finished(QNetworkReply*)), this, SLOT(replyFinished(QNetworkReply*))); const auto url = QUrl(ELITE_BACKERS_URL);
const auto request = QNetworkRequest(url);
m_manager.get(request);
} }
void CreditsLoader::loadEliteBackers() void CreditsLoader::replyFinished(QNetworkReply *reply) const {
{ auto response = reply->readAll();
const auto ELITE_BACKERS_URL = m_config.getEliteBackersUrl(); m_mainWindow.appendLogDebug(
m_mainWindow.appendLogDebug(QString("Send request: %1").arg(ELITE_BACKERS_URL)); QString("Received response: %1").arg(response.toStdString().c_str()));
const auto url = QUrl(ELITE_BACKERS_URL);
const auto request = QNetworkRequest(url); CreditsResponse creditsResponse(response);
m_manager.get(request); if (creditsResponse.isSuccess()) {
emit loaded(creditsResponse.getData());
} else {
error(QString("Server error: %1").arg(creditsResponse.getData()));
}
} }
void CreditsLoader::replyFinished(QNetworkReply* reply) const void CreditsLoader::error(const QString &error) const {
{ m_mainWindow.appendLogError(error);
auto response = reply->readAll(); emit loaded("Something went wrong when retrieving the list of Elite Backers. "
m_mainWindow.appendLogDebug(QString("Received response: %1").arg(response.toStdString().c_str())); "Check the logs for more info.");
CreditsResponse creditsResponse(response);
if (creditsResponse.isSuccess()) {
emit loaded(creditsResponse.getData());
}
else {
error(QString("Server error: %1").arg(creditsResponse.getData()));
}
}
void CreditsLoader::error(const QString& error) const
{
m_mainWindow.appendLogError(error);
emit loaded("Something went wrong when retrieving the list of Elite Backers. Check the logs for more info.");
} }

View file

@ -16,30 +16,29 @@
*/ */
#pragma once #pragma once
#include <QObject>
#include <QNetworkAccessManager> #include <QNetworkAccessManager>
#include <QObject>
class QNetworkReply; class QNetworkReply;
class MainWindow; class MainWindow;
class AppConfig; class AppConfig;
class CreditsLoader : public QObject class CreditsLoader : public QObject {
{ Q_OBJECT
Q_OBJECT
public: public:
explicit CreditsLoader(MainWindow& mainWindow, const AppConfig& config); explicit CreditsLoader(MainWindow &mainWindow, const AppConfig &config);
void loadEliteBackers(); void loadEliteBackers();
signals: signals:
void loaded(const QString& eliteBakers) const; void loaded(const QString &eliteBakers) const;
public slots: public slots:
void replyFinished(QNetworkReply* reply) const; void replyFinished(QNetworkReply *reply) const;
private: private:
MainWindow& m_mainWindow; MainWindow &m_mainWindow;
const AppConfig& m_config; const AppConfig &m_config;
QNetworkAccessManager m_manager; QNetworkAccessManager m_manager;
void error(const QString& error) const; void error(const QString &error) const;
}; };

View file

@ -17,45 +17,34 @@
#include "DataDownloader.h" #include "DataDownloader.h"
DataDownloader::DataDownloader(QObject* parent) : DataDownloader::DataDownloader(QObject *parent)
QObject(parent), : QObject(parent), m_pReply(nullptr), m_IsFinished(false) {
m_pReply(nullptr), connect(&m_NetworkManager, SIGNAL(finished(QNetworkReply *)),
m_IsFinished(false) SLOT(complete(QNetworkReply *)));
{
connect(&m_NetworkManager, SIGNAL(finished(QNetworkReply*)),
SLOT(complete(QNetworkReply*)));
} }
DataDownloader::~DataDownloader() DataDownloader::~DataDownloader() {}
{
void DataDownloader::complete(QNetworkReply *reply) {
m_Data = reply->readAll();
reply->deleteLater();
m_pReply = nullptr;
if (!m_Data.isEmpty()) {
m_IsFinished = true;
emit isComplete();
}
} }
void DataDownloader::complete(QNetworkReply* reply) QByteArray DataDownloader::data() const { return m_Data; }
{
m_Data = reply->readAll();
reply->deleteLater();
m_pReply = nullptr;
if (!m_Data.isEmpty()) { void DataDownloader::cancel() {
m_IsFinished = true; if (m_pReply != nullptr) {
emit isComplete(); m_pReply->abort();
} }
} }
QByteArray DataDownloader::data() const void DataDownloader::download(QUrl url) {
{ QNetworkRequest request(url);
return m_Data; m_pReply = m_NetworkManager.get(request);
}
void DataDownloader::cancel()
{
if (m_pReply != nullptr) {
m_pReply->abort();
}
}
void DataDownloader::download(QUrl url)
{
QNetworkRequest request(url);
m_pReply = m_NetworkManager.get(request);
} }

View file

@ -18,36 +18,35 @@
#ifndef DATADOWNLOADER_H #ifndef DATADOWNLOADER_H
#define DATADOWNLOADER_H #define DATADOWNLOADER_H
#include <QObject>
#include <QByteArray> #include <QByteArray>
#include <QNetworkAccessManager> #include <QNetworkAccessManager>
#include <QNetworkRequest>
#include <QNetworkReply> #include <QNetworkReply>
#include <QNetworkRequest>
#include <QObject>
class DataDownloader : public QObject class DataDownloader : public QObject {
{ Q_OBJECT
Q_OBJECT
public: public:
explicit DataDownloader(QObject* parent = 0); explicit DataDownloader(QObject *parent = 0);
virtual ~DataDownloader(); virtual ~DataDownloader();
QByteArray data() const; QByteArray data() const;
void cancel(); void cancel();
void download(QUrl url); void download(QUrl url);
bool isFinished() const { return m_IsFinished; } bool isFinished() const { return m_IsFinished; }
signals: signals:
void isComplete(); void isComplete();
private slots: private slots:
void complete(QNetworkReply* reply); void complete(QNetworkReply *reply);
private: private:
QNetworkAccessManager m_NetworkManager; QNetworkAccessManager m_NetworkManager;
QByteArray m_Data; QByteArray m_Data;
QNetworkReply* m_pReply; QNetworkReply *m_pReply;
bool m_IsFinished; bool m_IsFinished;
}; };
#endif // DATADOWNLOADER_H #endif // DATADOWNLOADER_H

View file

@ -32,10 +32,6 @@
// ElevateAlways | false | true // ElevateAlways | false | true
// ElevateNever | false | false // ElevateNever | false | false
// //
enum ElevateMode { enum ElevateMode { ElevateAsNeeded = 0, ElevateAlways = 1, ElevateNever = 2 };
ElevateAsNeeded = 0,
ElevateAlways = 1,
ElevateNever = 2
};
extern const ElevateMode defaultElevateMode; extern const ElevateMode defaultElevateMode;

View file

@ -1,15 +1,10 @@
#include "FailedLoginDialog.h" #include "FailedLoginDialog.h"
#include "ui_FailedLoginDialog.h" #include "ui_FailedLoginDialog.h"
FailedLoginDialog::FailedLoginDialog(QWidget *parent, QString message): FailedLoginDialog::FailedLoginDialog(QWidget *parent, QString message)
QDialog(parent), : QDialog(parent), ui(new Ui::FailedLoginDialog) {
ui(new Ui::FailedLoginDialog) ui->setupUi(this);
{ ui->messageLabel->setText(ui->messageLabel->text().arg(message));
ui->setupUi(this);
ui->messageLabel->setText(ui->messageLabel->text().arg(message));
} }
FailedLoginDialog::~FailedLoginDialog() FailedLoginDialog::~FailedLoginDialog() { delete ui; }
{
delete ui;
}

View file

@ -8,16 +8,15 @@ namespace Ui {
class FailedLoginDialog; class FailedLoginDialog;
} }
class FailedLoginDialog : public QDialog class FailedLoginDialog : public QDialog {
{ Q_OBJECT
Q_OBJECT
public: public:
explicit FailedLoginDialog(QWidget *parent = 0, QString message = ""); explicit FailedLoginDialog(QWidget *parent = 0, QString message = "");
~FailedLoginDialog(); ~FailedLoginDialog();
private: private:
Ui::FailedLoginDialog *ui; Ui::FailedLoginDialog *ui;
}; };
#endif // FAILEDLOGINDIALOG_H #endif // FAILEDLOGINDIALOG_H

View file

@ -27,123 +27,100 @@ static const char kLocalFilename[] = "Local.txt";
static const char kTrustedServersFilename[] = "TrustedServers.txt"; static const char kTrustedServersFilename[] = "TrustedServers.txt";
static const char kTrustedClientsFilename[] = "TrustedClients.txt"; static const char kTrustedClientsFilename[] = "TrustedClients.txt";
Fingerprint::Fingerprint(const QString& filename) Fingerprint::Fingerprint(const QString &filename) { m_Filename = filename; }
{
m_Filename = filename; void Fingerprint::trust(const QString &fingerprintText, bool append) {
Fingerprint::persistDirectory();
QIODevice::OpenMode openMode;
if (append) {
openMode = QIODevice::Append;
} else {
openMode = QIODevice::WriteOnly;
}
QFile file(filePath());
if (file.open(openMode)) {
QTextStream out(&file);
out << fingerprintText << "\n";
file.close();
}
} }
void Fingerprint::trust(const QString& fingerprintText, bool append) bool Fingerprint::fileExists() const {
{ QString dirName = Fingerprint::directoryPath();
Fingerprint::persistDirectory(); if (!QDir(dirName).exists()) {
QIODevice::OpenMode openMode;
if (append) {
openMode = QIODevice::Append;
}
else {
openMode = QIODevice::WriteOnly;
}
QFile file(filePath());
if (file.open(openMode))
{
QTextStream out(&file);
out << fingerprintText << "\n";
file.close();
}
}
bool Fingerprint::fileExists() const
{
QString dirName = Fingerprint::directoryPath();
if (!QDir(dirName).exists()) {
return false;
}
QFile file(filePath());
return file.exists();
}
bool Fingerprint::isTrusted(const QString& fingerprintText)
{
QStringList list = readList();
foreach (QString trusted, list)
{
if (trusted == fingerprintText) {
return true;
}
}
return false; return false;
}
QFile file(filePath());
return file.exists();
} }
QStringList Fingerprint::readList(const int readTo) bool Fingerprint::isTrusted(const QString &fingerprintText) {
{ QStringList list = readList();
QStringList list; foreach (QString trusted, list) {
if (trusted == fingerprintText) {
QString dirName = Fingerprint::directoryPath(); return true;
if (!QDir(dirName).exists()) {
return list;
} }
}
return false;
}
QFile file(filePath()); QStringList Fingerprint::readList(const int readTo) {
QStringList list;
if (file.open(QIODevice::ReadOnly))
{
QTextStream in(&file);
while (!in.atEnd())
{
list.append(in.readLine());
if (list.size() == readTo) {
break;
}
}
file.close();
}
QString dirName = Fingerprint::directoryPath();
if (!QDir(dirName).exists()) {
return list; return list;
} }
QString Fingerprint::readFirst() QFile file(filePath());
{
QStringList list = readList(1);
return list.at(0);
}
QString Fingerprint::filePath() const if (file.open(QIODevice::ReadOnly)) {
{ QTextStream in(&file);
QString dir = Fingerprint::directoryPath(); while (!in.atEnd()) {
return QString("%1/%2").arg(dir).arg(m_Filename); list.append(in.readLine());
} if (list.size() == readTo) {
break;
void Fingerprint::persistDirectory() }
{
QDir dir(Fingerprint::directoryPath());
if (!dir.exists()) {
dir.mkpath(".");
} }
file.close();
}
return list;
} }
QString Fingerprint::directoryPath() QString Fingerprint::readFirst() {
{ QStringList list = readList(1);
CoreInterface coreInterface; return list.at(0);
QString profileDir = coreInterface.getProfileDir();
return QString("%1/%2")
.arg(profileDir)
.arg(kDirName);
} }
Fingerprint Fingerprint::local() QString Fingerprint::filePath() const {
{ QString dir = Fingerprint::directoryPath();
return Fingerprint(kLocalFilename); return QString("%1/%2").arg(dir).arg(m_Filename);
} }
Fingerprint Fingerprint::trustedServers() void Fingerprint::persistDirectory() {
{ QDir dir(Fingerprint::directoryPath());
return Fingerprint(kTrustedServersFilename); if (!dir.exists()) {
dir.mkpath(".");
}
} }
Fingerprint Fingerprint::trustedClients() QString Fingerprint::directoryPath() {
{ CoreInterface coreInterface;
return Fingerprint(kTrustedClientsFilename); QString profileDir = coreInterface.getProfileDir();
return QString("%1/%2").arg(profileDir).arg(kDirName);
}
Fingerprint Fingerprint::local() { return Fingerprint(kLocalFilename); }
Fingerprint Fingerprint::trustedServers() {
return Fingerprint(kTrustedServersFilename);
}
Fingerprint Fingerprint::trustedClients() {
return Fingerprint(kTrustedClientsFilename);
} }

View file

@ -19,28 +19,27 @@
#include <QString> #include <QString>
class Fingerprint class Fingerprint {
{
private: private:
Fingerprint(const QString& filename); Fingerprint(const QString &filename);
public: public:
void trust(const QString& fingerprintText, bool append = true); void trust(const QString &fingerprintText, bool append = true);
bool isTrusted(const QString& fingerprintText); bool isTrusted(const QString &fingerprintText);
QStringList readList(const int readTo = -1); QStringList readList(const int readTo = -1);
QString readFirst(); QString readFirst();
QString filePath() const; QString filePath() const;
bool fileExists() const; bool fileExists() const;
public: public:
static Fingerprint local(); static Fingerprint local();
static Fingerprint trustedServers(); static Fingerprint trustedServers();
static Fingerprint trustedClients(); static Fingerprint trustedClients();
static QString directoryPath(); static QString directoryPath();
static QString localFingerprint(); static QString localFingerprint();
static bool localFingerprintExists(); static bool localFingerprintExists();
static void persistDirectory(); static void persistDirectory();
private: private:
QString m_Filename; QString m_Filename;
}; };

View file

@ -2,11 +2,11 @@
* synergy -- mouse and keyboard sharing utility * synergy -- mouse and keyboard sharing utility
* Copyright (C) 2012-2016 Symless Ltd. * Copyright (C) 2012-2016 Symless Ltd.
* Copyright (C) 2008 Volker Lanz (vl@fidra.de) * Copyright (C) 2008 Volker Lanz (vl@fidra.de)
* *
* This package is free software; you can redistribute it and/or * This package is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
* found in the file LICENSE that should have accompanied this file. * found in the file LICENSE that should have accompanied this file.
* *
* This package is distributed in the hope that it will be useful, * This package is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
@ -20,61 +20,50 @@
#include <QSettings> #include <QSettings>
Hotkey::Hotkey() : Hotkey::Hotkey() : m_KeySequence(), m_Actions() {}
m_KeySequence(),
m_Actions() QString Hotkey::text() const {
{ QString text = keySequence().toString();
if (keySequence().isMouseButton())
return "mousebutton(" + text + ")";
return "keystroke(" + text + ")";
} }
QString Hotkey::text() const void Hotkey::loadSettings(QSettings &settings) {
{ keySequence().loadSettings(settings);
QString text = keySequence().toString();
if (keySequence().isMouseButton()) actions().clear();
return "mousebutton(" + text + ")"; int num = settings.beginReadArray("actions");
for (int i = 0; i < num; i++) {
settings.setArrayIndex(i);
Action a;
a.loadSettings(settings);
actions().append(a);
}
return "keystroke(" + text + ")"; settings.endArray();
} }
void Hotkey::loadSettings(QSettings& settings) void Hotkey::saveSettings(QSettings &settings) const {
{ keySequence().saveSettings(settings);
keySequence().loadSettings(settings);
actions().clear(); settings.beginWriteArray("actions");
int num = settings.beginReadArray("actions"); for (int i = 0; i < actions().size(); i++) {
for (int i = 0; i < num; i++) settings.setArrayIndex(i);
{ actions()[i].saveSettings(settings);
settings.setArrayIndex(i); }
Action a; settings.endArray();
a.loadSettings(settings);
actions().append(a);
}
settings.endArray();
} }
void Hotkey::saveSettings(QSettings& settings) const bool Hotkey::operator==(const Hotkey &hk) const {
{ return m_KeySequence == hk.m_KeySequence && m_Actions == hk.m_Actions;
keySequence().saveSettings(settings);
settings.beginWriteArray("actions");
for (int i = 0; i < actions().size(); i++)
{
settings.setArrayIndex(i);
actions()[i].saveSettings(settings);
}
settings.endArray();
} }
bool Hotkey::operator==(const Hotkey& hk) const QTextStream &operator<<(QTextStream &outStream, const Hotkey &hotkey) {
{ for (int i = 0; i < hotkey.actions().size(); i++)
return m_KeySequence == hk.m_KeySequence && m_Actions == hk.m_Actions; outStream << "\t" << hotkey.text() << " = " << hotkey.actions()[i] << endl;
}
QTextStream& operator<<(QTextStream& outStream, const Hotkey& hotkey) return outStream;
{
for (int i = 0; i < hotkey.actions().size(); i++)
outStream << "\t" << hotkey.text() << " = " << hotkey.actions()[i] << endl;
return outStream;
} }

View file

@ -2,11 +2,11 @@
* synergy -- mouse and keyboard sharing utility * synergy -- mouse and keyboard sharing utility
* Copyright (C) 2012-2016 Symless Ltd. * Copyright (C) 2012-2016 Symless Ltd.
* Copyright (C) 2008 Volker Lanz (vl@fidra.de) * Copyright (C) 2008 Volker Lanz (vl@fidra.de)
* *
* This package is free software; you can redistribute it and/or * This package is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
* found in the file LICENSE that should have accompanied this file. * found in the file LICENSE that should have accompanied this file.
* *
* This package is distributed in the hope that it will be useful, * This package is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
@ -20,8 +20,8 @@
#define HOTKEY_H #define HOTKEY_H
#include <QString>
#include <QList> #include <QList>
#include <QString>
#include <QTextStream> #include <QTextStream>
#include "Action.h" #include "Action.h"
@ -31,38 +31,36 @@ class HotkeyDialog;
class ServerConfigDialog; class ServerConfigDialog;
class QSettings; class QSettings;
class Hotkey class Hotkey {
{ friend class HotkeyDialog;
friend class HotkeyDialog; friend class ServerConfigDialog;
friend class ServerConfigDialog; friend QTextStream &operator<<(QTextStream &outStream, const Hotkey &hotkey);
friend QTextStream& operator<<(QTextStream& outStream, const Hotkey& hotkey);
public: public:
Hotkey(); Hotkey();
public: public:
QString text() const; QString text() const;
const KeySequence& keySequence() const { return m_KeySequence; } const KeySequence &keySequence() const { return m_KeySequence; }
const ActionList& actions() const { return m_Actions; } const ActionList &actions() const { return m_Actions; }
void loadSettings(QSettings& settings); void loadSettings(QSettings &settings);
void saveSettings(QSettings& settings) const; void saveSettings(QSettings &settings) const;
bool operator==(const Hotkey& hk) const; bool operator==(const Hotkey &hk) const;
protected: protected:
KeySequence& keySequence() { return m_KeySequence; } KeySequence &keySequence() { return m_KeySequence; }
void setKeySequence(const KeySequence& seq) { m_KeySequence = seq; } void setKeySequence(const KeySequence &seq) { m_KeySequence = seq; }
ActionList& actions() { return m_Actions; } ActionList &actions() { return m_Actions; }
private:
private: KeySequence m_KeySequence;
KeySequence m_KeySequence; ActionList m_Actions;
ActionList m_Actions;
}; };
typedef QList<Hotkey> HotkeyList; typedef QList<Hotkey> HotkeyList;
QTextStream& operator<<(QTextStream& outStream, const Hotkey& hotkey); QTextStream &operator<<(QTextStream &outStream, const Hotkey &hotkey);
#endif #endif

View file

@ -2,11 +2,11 @@
* synergy -- mouse and keyboard sharing utility * synergy -- mouse and keyboard sharing utility
* Copyright (C) 2012-2016 Symless Ltd. * Copyright (C) 2012-2016 Symless Ltd.
* Copyright (C) 2008 Volker Lanz (vl@fidra.de) * Copyright (C) 2008 Volker Lanz (vl@fidra.de)
* *
* This package is free software; you can redistribute it and/or * This package is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
* found in the file LICENSE that should have accompanied this file. * found in the file LICENSE that should have accompanied this file.
* *
* This package is distributed in the hope that it will be useful, * This package is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
@ -21,21 +21,18 @@
#include <QtCore> #include <QtCore>
#include <QtGui> #include <QtGui>
HotkeyDialog::HotkeyDialog (QWidget* parent, Hotkey& hotkey) : HotkeyDialog::HotkeyDialog(QWidget *parent, Hotkey &hotkey)
QDialog(parent, Qt::WindowTitleHint | Qt::WindowSystemMenuHint), : QDialog(parent, Qt::WindowTitleHint | Qt::WindowSystemMenuHint),
Ui::HotkeyDialogBase(), Ui::HotkeyDialogBase(), m_Hotkey(hotkey) {
m_Hotkey(hotkey) setupUi(this);
{
setupUi(this);
m_pKeySequenceWidgetHotkey->setText(m_Hotkey.text()); m_pKeySequenceWidgetHotkey->setText(m_Hotkey.text());
} }
void HotkeyDialog::accept() void HotkeyDialog::accept() {
{ if (!sequenceWidget()->valid())
if (!sequenceWidget()->valid()) return;
return;
hotkey().setKeySequence(sequenceWidget()->keySequence()); hotkey().setKeySequence(sequenceWidget()->keySequence());
QDialog::accept(); QDialog::accept();
} }

View file

@ -2,11 +2,11 @@
* synergy -- mouse and keyboard sharing utility * synergy -- mouse and keyboard sharing utility
* Copyright (C) 2012-2016 Symless Ltd. * Copyright (C) 2012-2016 Symless Ltd.
* Copyright (C) 2008 Volker Lanz (vl@fidra.de) * Copyright (C) 2008 Volker Lanz (vl@fidra.de)
* *
* This package is free software; you can redistribute it and/or * This package is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
* found in the file LICENSE that should have accompanied this file. * found in the file LICENSE that should have accompanied this file.
* *
* This package is distributed in the hope that it will be useful, * This package is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
@ -20,30 +20,31 @@
#define HOTKEYDIALOG_H #define HOTKEYDIALOG_H
#include "ui_HotkeyDialogBase.h"
#include "Hotkey.h" #include "Hotkey.h"
#include "ui_HotkeyDialogBase.h"
#include <QDialog> #include <QDialog>
class HotkeyDialog : public QDialog, public Ui::HotkeyDialogBase class HotkeyDialog : public QDialog, public Ui::HotkeyDialogBase {
{ Q_OBJECT
Q_OBJECT
public: public:
HotkeyDialog(QWidget* parent, Hotkey& hotkey); HotkeyDialog(QWidget *parent, Hotkey &hotkey);
public: public:
const Hotkey& hotkey() const { return m_Hotkey; } const Hotkey &hotkey() const { return m_Hotkey; }
protected slots: protected slots:
void accept(); void accept();
protected: protected:
const KeySequenceWidget* sequenceWidget() const { return m_pKeySequenceWidgetHotkey; } const KeySequenceWidget *sequenceWidget() const {
Hotkey& hotkey() { return m_Hotkey; } return m_pKeySequenceWidgetHotkey;
}
Hotkey &hotkey() { return m_Hotkey; }
private: private:
Hotkey& m_Hotkey; Hotkey &m_Hotkey;
}; };
#endif #endif

View file

@ -20,7 +20,7 @@
#include "Ipc.h" #include "Ipc.h"
const char* kIpcMsgHello = "IHEL%1i"; const char *kIpcMsgHello = "IHEL%1i";
const char* kIpcMsgLogLine = "ILOG%s"; const char *kIpcMsgLogLine = "ILOG%s";
const char* kIpcMsgCommand = "ICMD%s%1i"; const char *kIpcMsgCommand = "ICMD%s%1i";
const char* kIpcMsgShutdown = "ISDN"; const char *kIpcMsgShutdown = "ISDN";

View file

@ -24,19 +24,19 @@
#define IPC_PORT 24801 #define IPC_PORT 24801
enum qIpcMessageType { enum qIpcMessageType {
kIpcHello, kIpcHello,
kIpcLogLine, kIpcLogLine,
kIpcCommand, kIpcCommand,
kIpcShutdown, kIpcShutdown,
}; };
enum qIpcClientType { enum qIpcClientType {
kIpcClientUnknown, kIpcClientUnknown,
kIpcClientGui, kIpcClientGui,
kIpcClientNode, kIpcClientNode,
}; };
extern const char* kIpcMsgHello; extern const char *kIpcMsgHello;
extern const char* kIpcMsgLogLine; extern const char *kIpcMsgLogLine;
extern const char* kIpcMsgCommand; extern const char *kIpcMsgCommand;
extern const char* kIpcMsgShutdown; extern const char *kIpcMsgShutdown;

View file

@ -17,130 +17,122 @@
*/ */
#include "IpcClient.h" #include "IpcClient.h"
#include <QTcpSocket>
#include <QHostAddress>
#include <iostream>
#include <QTimer>
#include "IpcReader.h"
#include "Ipc.h" #include "Ipc.h"
#include "IpcReader.h"
#include <QDataStream> #include <QDataStream>
#include <QHostAddress>
#include <QTcpSocket>
#include <QTimer>
#include <iostream>
IpcClient::IpcClient() : IpcClient::IpcClient() : m_ReaderStarted(false), m_Enabled(false) {
m_ReaderStarted(false), m_Socket = new QTcpSocket(this);
m_Enabled(false) connect(m_Socket, SIGNAL(connected()), this, SLOT(connected()));
{ connect(m_Socket, SIGNAL(error(QAbstractSocket::SocketError)), this,
m_Socket = new QTcpSocket(this); SLOT(error(QAbstractSocket::SocketError)));
connect(m_Socket, SIGNAL(connected()), this, SLOT(connected()));
connect(m_Socket, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(error(QAbstractSocket::SocketError)));
m_Reader = new IpcReader(m_Socket); m_Reader = new IpcReader(m_Socket);
connect(m_Reader, SIGNAL(readLogLine(const QString&)), this, SLOT(handleReadLogLine(const QString&))); connect(m_Reader, SIGNAL(readLogLine(const QString &)), this,
SLOT(handleReadLogLine(const QString &)));
} }
IpcClient::~IpcClient() IpcClient::~IpcClient() {}
{
void IpcClient::connected() {
sendHello();
infoMessage("connection established");
} }
void IpcClient::connected() void IpcClient::connectToHost() {
{ m_Enabled = true;
sendHello();
infoMessage("connection established"); infoMessage("connecting to service...");
m_Socket->connectToHost(QHostAddress(QHostAddress::LocalHost), IPC_PORT);
if (!m_ReaderStarted) {
m_Reader->start();
m_ReaderStarted = true;
}
} }
void IpcClient::connectToHost() void IpcClient::disconnectFromHost() {
{ infoMessage("service disconnect");
m_Enabled = true; m_Reader->stop();
m_Socket->close();
infoMessage("connecting to service...");
m_Socket->connectToHost(QHostAddress(QHostAddress::LocalHost), IPC_PORT);
if (!m_ReaderStarted) {
m_Reader->start();
m_ReaderStarted = true;
}
} }
void IpcClient::disconnectFromHost() void IpcClient::error(QAbstractSocket::SocketError error) {
{ QString text;
infoMessage("service disconnect"); switch (error) {
m_Reader->stop(); case 0:
m_Socket->close(); text = "connection refused";
break;
case 1:
text = "remote host closed";
break;
default:
text = QString("code=%1").arg(error);
break;
}
errorMessage(QString("ipc connection error, %1").arg(text));
QTimer::singleShot(1000, this, SLOT(retryConnect()));
} }
void IpcClient::error(QAbstractSocket::SocketError error) void IpcClient::retryConnect() {
{ if (m_Enabled) {
QString text; connectToHost();
switch (error) { }
case 0: text = "connection refused"; break;
case 1: text = "remote host closed"; break;
default: text = QString("code=%1").arg(error); break;
}
errorMessage(QString("ipc connection error, %1").arg(text));
QTimer::singleShot(1000, this, SLOT(retryConnect()));
} }
void IpcClient::retryConnect() void IpcClient::sendHello() {
{ QDataStream stream(m_Socket);
if (m_Enabled) { stream.writeRawData(kIpcMsgHello, 4);
connectToHost();
} char typeBuf[1];
typeBuf[0] = kIpcClientGui;
stream.writeRawData(typeBuf, 1);
} }
void IpcClient::sendHello() void IpcClient::sendCommand(const QString &command, ElevateMode const elevate) {
{ QDataStream stream(m_Socket);
QDataStream stream(m_Socket);
stream.writeRawData(kIpcMsgHello, 4);
char typeBuf[1]; stream.writeRawData(kIpcMsgCommand, 4);
typeBuf[0] = kIpcClientGui;
stream.writeRawData(typeBuf, 1); std::string stdStringCommand = command.toStdString();
const char *charCommand = stdStringCommand.c_str();
int length = static_cast<int>(
strlen(charCommand)); // Compliant: we made sure that charCommand variable
// ended with null(String type is safe)
char lenBuf[4];
intToBytes(length, lenBuf, 4);
stream.writeRawData(lenBuf, 4);
stream.writeRawData(charCommand, length);
char elevateBuf[1];
// Refer to enum ElevateMode documentation for why this flag is mapped this
// way
elevateBuf[0] = (elevate == ElevateAlways) ? 1 : 0;
stream.writeRawData(elevateBuf, 1);
} }
void IpcClient::sendCommand(const QString& command, ElevateMode const elevate) void IpcClient::handleReadLogLine(const QString &text) { readLogLine(text); }
{
QDataStream stream(m_Socket);
stream.writeRawData(kIpcMsgCommand, 4);
std::string stdStringCommand = command.toStdString();
const char* charCommand = stdStringCommand.c_str();
int length = static_cast<int>(strlen(charCommand)); // Compliant: we made sure that charCommand variable ended with null(String type is safe)
char lenBuf[4];
intToBytes(length, lenBuf, 4);
stream.writeRawData(lenBuf, 4);
stream.writeRawData(charCommand, length);
char elevateBuf[1];
// Refer to enum ElevateMode documentation for why this flag is mapped this way
elevateBuf[0] = (elevate == ElevateAlways) ? 1 : 0;
stream.writeRawData(elevateBuf, 1);
}
void IpcClient::handleReadLogLine(const QString& text)
{
readLogLine(text);
}
// TODO: qt must have a built in way of converting int to bytes. // TODO: qt must have a built in way of converting int to bytes.
void IpcClient::intToBytes(int value, char *buffer, int size) void IpcClient::intToBytes(int value, char *buffer, int size) {
{ if (size == 1) {
if (size == 1) { buffer[0] = value & 0xff;
buffer[0] = value & 0xff; } else if (size == 2) {
} buffer[0] = (value >> 8) & 0xff;
else if (size == 2) { buffer[1] = value & 0xff;
buffer[0] = (value >> 8) & 0xff; } else if (size == 4) {
buffer[1] = value & 0xff; buffer[0] = (value >> 24) & 0xff;
} buffer[1] = (value >> 16) & 0xff;
else if (size == 4) { buffer[2] = (value >> 8) & 0xff;
buffer[0] = (value >> 24) & 0xff; buffer[3] = value & 0xff;
buffer[1] = (value >> 16) & 0xff; } else {
buffer[2] = (value >> 8) & 0xff; // TODO: other sizes, if needed.
buffer[3] = value & 0xff; }
}
else {
// TODO: other sizes, if needed.
}
} }

View file

@ -18,46 +18,45 @@
#pragma once #pragma once
#include <QObject>
#include <QAbstractSocket> #include <QAbstractSocket>
#include <QObject>
#include "ElevateMode.h" #include "ElevateMode.h"
class QTcpSocket; class QTcpSocket;
class IpcReader; class IpcReader;
class IpcClient : public QObject class IpcClient : public QObject {
{ Q_OBJECT
Q_OBJECT
public: public:
IpcClient(); IpcClient();
virtual ~IpcClient(); virtual ~IpcClient();
void sendHello(); void sendHello();
void sendCommand(const QString& command, ElevateMode elevate); void sendCommand(const QString &command, ElevateMode elevate);
void connectToHost(); void connectToHost();
void disconnectFromHost(); void disconnectFromHost();
public slots: public slots:
void retryConnect(); void retryConnect();
private: private:
void intToBytes(int value, char* buffer, int size); void intToBytes(int value, char *buffer, int size);
private slots: private slots:
void connected(); void connected();
void error(QAbstractSocket::SocketError error); void error(QAbstractSocket::SocketError error);
void handleReadLogLine(const QString& text); void handleReadLogLine(const QString &text);
signals: signals:
void readLogLine(const QString& text); void readLogLine(const QString &text);
void infoMessage(const QString& text); void infoMessage(const QString &text);
void errorMessage(const QString& text); void errorMessage(const QString &text);
private: private:
QTcpSocket* m_Socket; QTcpSocket *m_Socket;
IpcReader* m_Reader; IpcReader *m_Reader;
bool m_ReaderStarted; bool m_ReaderStarted;
bool m_Enabled; bool m_Enabled;
}; };

View file

@ -17,115 +17,96 @@
*/ */
#include "IpcReader.h" #include "IpcReader.h"
#include <QTcpSocket>
#include "Ipc.h" #include "Ipc.h"
#include <iostream>
#include <QMutex>
#include <QByteArray> #include <QByteArray>
#include <QMutex>
#include <QTcpSocket>
#include <iostream>
IpcReader::IpcReader(QTcpSocket* socket) : IpcReader::IpcReader(QTcpSocket *socket) : m_Socket(socket) {}
m_Socket(socket)
{ IpcReader::~IpcReader() {}
void IpcReader::start() {
connect(m_Socket, SIGNAL(readyRead()), this, SLOT(read()));
} }
IpcReader::~IpcReader() void IpcReader::stop() {
{ disconnect(m_Socket, SIGNAL(readyRead()), this, SLOT(read()));
} }
void IpcReader::start() void IpcReader::read() {
{ QMutexLocker locker(&m_Mutex);
connect(m_Socket, SIGNAL(readyRead()), this, SLOT(read())); std::cout << "ready read" << std::endl;
while (m_Socket->bytesAvailable()) {
std::cout << "bytes available" << std::endl;
char codeBuf[5];
readStream(codeBuf, 4);
codeBuf[4] = 0;
std::cout << "ipc read: " << codeBuf << std::endl;
if (memcmp(codeBuf, kIpcMsgLogLine, 4) == 0) {
std::cout << "reading log line" << std::endl;
char lenBuf[4];
readStream(lenBuf, 4);
int len = bytesToInt(lenBuf, 4);
char *data = new char[len];
readStream(data, len);
QString line = QString::fromUtf8(data, len);
delete[] data;
readLogLine(line);
} else {
std::cerr << "aborting, message invalid" << std::endl;
return;
}
}
std::cout << "read done" << std::endl;
} }
void IpcReader::stop() bool IpcReader::readStream(char *buffer, int length) {
{ std::cout << "reading stream" << std::endl;
disconnect(m_Socket, SIGNAL(readyRead()), this, SLOT(read()));
}
void IpcReader::read() int read = 0;
{ while (read < length) {
QMutexLocker locker(&m_Mutex); int ask = length - read;
std::cout << "ready read" << std::endl; if (m_Socket->bytesAvailable() < ask) {
std::cout << "buffer too short, waiting" << std::endl;
while (m_Socket->bytesAvailable()) { m_Socket->waitForReadyRead(-1);
std::cout << "bytes available" << std::endl;
char codeBuf[5];
readStream(codeBuf, 4);
codeBuf[4] = 0;
std::cout << "ipc read: " << codeBuf << std::endl;
if (memcmp(codeBuf, kIpcMsgLogLine, 4) == 0) {
std::cout << "reading log line" << std::endl;
char lenBuf[4];
readStream(lenBuf, 4);
int len = bytesToInt(lenBuf, 4);
char* data = new char[len];
readStream(data, len);
QString line = QString::fromUtf8(data, len);
delete[] data;
readLogLine(line);
}
else {
std::cerr << "aborting, message invalid" << std::endl;
return;
}
} }
std::cout << "read done" << std::endl; int got = m_Socket->read(buffer, ask);
read += got;
std::cout << "> ask=" << ask << " got=" << got << " read=" << read
<< std::endl;
if (got == -1) {
std::cout << "socket ended, aborting" << std::endl;
return false;
} else if (length - read > 0) {
std::cout << "more remains, seek to " << got << std::endl;
buffer += got;
}
}
return true;
} }
bool IpcReader::readStream(char* buffer, int length) int IpcReader::bytesToInt(const char *buffer, int size) {
{ if (size == 1) {
std::cout << "reading stream" << std::endl; return (unsigned char)buffer[0];
} else if (size == 2) {
int read = 0; return (((unsigned char)buffer[0]) << 8) + (unsigned char)buffer[1];
while (read < length) { } else if (size == 4) {
int ask = length - read; return (((unsigned char)buffer[0]) << 24) +
if (m_Socket->bytesAvailable() < ask) { (((unsigned char)buffer[1]) << 16) +
std::cout << "buffer too short, waiting" << std::endl; (((unsigned char)buffer[2]) << 8) + (unsigned char)buffer[3];
m_Socket->waitForReadyRead(-1); } else {
} return 0;
}
int got = m_Socket->read(buffer, ask);
read += got;
std::cout << "> ask=" << ask << " got=" << got
<< " read=" << read << std::endl;
if (got == -1) {
std::cout << "socket ended, aborting" << std::endl;
return false;
}
else if (length - read > 0) {
std::cout << "more remains, seek to " << got << std::endl;
buffer += got;
}
}
return true;
}
int IpcReader::bytesToInt(const char *buffer, int size)
{
if (size == 1) {
return (unsigned char)buffer[0];
}
else if (size == 2) {
return
(((unsigned char)buffer[0]) << 8) +
(unsigned char)buffer[1];
}
else if (size == 4) {
return
(((unsigned char)buffer[0]) << 24) +
(((unsigned char)buffer[1]) << 16) +
(((unsigned char)buffer[2]) << 8) +
(unsigned char)buffer[3];
}
else {
return 0;
}
} }

View file

@ -18,32 +18,31 @@
#pragma once #pragma once
#include <QObject>
#include <QMutex> #include <QMutex>
#include <QObject>
class QTcpSocket; class QTcpSocket;
class IpcReader : public QObject class IpcReader : public QObject {
{ Q_OBJECT;
Q_OBJECT;
public: public:
IpcReader(QTcpSocket* socket); IpcReader(QTcpSocket *socket);
virtual ~IpcReader(); virtual ~IpcReader();
void start(); void start();
void stop(); void stop();
signals: signals:
void readLogLine(const QString& text); void readLogLine(const QString &text);
private: private:
bool readStream(char* buffer, int length); bool readStream(char *buffer, int length);
int bytesToInt(const char* buffer, int size); int bytesToInt(const char *buffer, int size);
private slots: private slots:
void read(); void read();
private: private:
QTcpSocket* m_Socket; QTcpSocket *m_Socket;
QMutex m_Mutex; QMutex m_Mutex;
}; };

View file

@ -2,11 +2,11 @@
* synergy -- mouse and keyboard sharing utility * synergy -- mouse and keyboard sharing utility
* Copyright (C) 2012-2016 Symless Ltd. * Copyright (C) 2012-2016 Symless Ltd.
* Copyright (C) 2008 Volker Lanz (vl@fidra.de) * Copyright (C) 2008 Volker Lanz (vl@fidra.de)
* *
* This package is free software; you can redistribute it and/or * This package is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
* found in the file LICENSE that should have accompanied this file. * found in the file LICENSE that should have accompanied this file.
* *
* This package is distributed in the hope that it will be useful, * This package is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
@ -23,222 +23,198 @@
// this table originally comes from Qt sources (gui/kernel/qkeysequence.cpp) // this table originally comes from Qt sources (gui/kernel/qkeysequence.cpp)
// and is heavily modified for QSynergy // and is heavily modified for QSynergy
static const struct static const struct {
{ int key;
int key; const char *name;
const char* name; } keyname[] = {{Qt::Key_Space, "Space"},
} keyname[] = {Qt::Key_Escape, "Escape"},
{ {Qt::Key_Tab, "Tab"},
{ Qt::Key_Space, "Space" }, {Qt::Key_Backtab, "LeftTab"},
{ Qt::Key_Escape, "Escape" }, {Qt::Key_Backspace, "BackSpace"},
{ Qt::Key_Tab, "Tab" }, {Qt::Key_Return, "Return"},
{ Qt::Key_Backtab, "LeftTab" }, {Qt::Key_Insert, "Insert"},
{ Qt::Key_Backspace, "BackSpace" }, {Qt::Key_Delete, "Delete"},
{ Qt::Key_Return, "Return" }, {Qt::Key_Pause, "Pause"},
{ Qt::Key_Insert, "Insert" }, {Qt::Key_Print, "Print"},
{ Qt::Key_Delete, "Delete" }, {Qt::Key_SysReq, "SysReq"},
{ Qt::Key_Pause, "Pause" }, {Qt::Key_Home, "Home"},
{ Qt::Key_Print, "Print" }, {Qt::Key_End, "End"},
{ Qt::Key_SysReq, "SysReq" }, {Qt::Key_Left, "Left"},
{ Qt::Key_Home, "Home" }, {Qt::Key_Up, "Up"},
{ Qt::Key_End, "End" }, {Qt::Key_Right, "Right"},
{ Qt::Key_Left, "Left" }, {Qt::Key_Down, "Down"},
{ Qt::Key_Up, "Up" }, {Qt::Key_PageUp, "PageUp"},
{ Qt::Key_Right, "Right" }, {Qt::Key_PageDown, "PageDown"},
{ Qt::Key_Down, "Down" }, {Qt::Key_CapsLock, "CapsLock"},
{ Qt::Key_PageUp, "PageUp" }, {Qt::Key_NumLock, "NumLock"},
{ Qt::Key_PageDown, "PageDown" }, {Qt::Key_ScrollLock, "ScrollLock"},
{ Qt::Key_CapsLock, "CapsLock" }, {Qt::Key_Menu, "Menu"},
{ Qt::Key_NumLock, "NumLock" }, {Qt::Key_Help, "Help"},
{ Qt::Key_ScrollLock, "ScrollLock" }, {Qt::Key_Enter, "KP_Enter"},
{ Qt::Key_Menu, "Menu" }, {Qt::Key_Clear, "Clear"},
{ Qt::Key_Help, "Help" },
{ Qt::Key_Enter, "KP_Enter" },
{ Qt::Key_Clear, "Clear" },
{ Qt::Key_Back, "WWWBack" }, {Qt::Key_Back, "WWWBack"},
{ Qt::Key_Forward, "WWWForward" }, {Qt::Key_Forward, "WWWForward"},
{ Qt::Key_Stop, "WWWStop" }, {Qt::Key_Stop, "WWWStop"},
{ Qt::Key_Refresh, "WWWRefresh" }, {Qt::Key_Refresh, "WWWRefresh"},
{ Qt::Key_VolumeDown, "AudioDown" }, {Qt::Key_VolumeDown, "AudioDown"},
{ Qt::Key_VolumeMute, "AudioMute" }, {Qt::Key_VolumeMute, "AudioMute"},
{ Qt::Key_VolumeUp, "AudioUp" }, {Qt::Key_VolumeUp, "AudioUp"},
{ Qt::Key_MediaPlay, "AudioPlay" }, {Qt::Key_MediaPlay, "AudioPlay"},
{ Qt::Key_MediaStop, "AudioStop" }, {Qt::Key_MediaStop, "AudioStop"},
{ Qt::Key_MediaPrevious,"AudioPrev" }, {Qt::Key_MediaPrevious, "AudioPrev"},
{ Qt::Key_MediaNext, "AudioNext" }, {Qt::Key_MediaNext, "AudioNext"},
{ Qt::Key_HomePage, "WWWHome" }, {Qt::Key_HomePage, "WWWHome"},
{ Qt::Key_Favorites, "WWWFavorites" }, {Qt::Key_Favorites, "WWWFavorites"},
{ Qt::Key_Search, "WWWSearch" }, {Qt::Key_Search, "WWWSearch"},
{ Qt::Key_Standby, "Sleep" }, {Qt::Key_Standby, "Sleep"},
{ Qt::Key_LaunchMail, "AppMail" }, {Qt::Key_LaunchMail, "AppMail"},
{ Qt::Key_LaunchMedia, "AppMedia" }, {Qt::Key_LaunchMedia, "AppMedia"},
{ Qt::Key_Launch0, "AppUser1" }, {Qt::Key_Launch0, "AppUser1"},
{ Qt::Key_Launch1, "AppUser2" }, {Qt::Key_Launch1, "AppUser2"},
{ Qt::Key_Select, "Select" }, {Qt::Key_Select, "Select"},
{ 0, 0 } {0, 0}};
};
KeySequence::KeySequence() : KeySequence::KeySequence() : m_Sequence(), m_Modifiers(0), m_IsValid(false) {}
m_Sequence(),
m_Modifiers(0), bool KeySequence::isMouseButton() const {
m_IsValid(false) return !m_Sequence.isEmpty() && m_Sequence.last() < Qt::Key_Space;
{
} }
bool KeySequence::isMouseButton() const QString KeySequence::toString() const {
{ QString result;
return !m_Sequence.isEmpty() && m_Sequence.last() < Qt::Key_Space;
for (int i = 0; i < m_Sequence.size(); i++) {
result += keyToString(m_Sequence[i]);
if (i != m_Sequence.size() - 1)
result += "+";
}
return result;
} }
QString KeySequence::toString() const bool KeySequence::appendMouseButton(int button) { return appendKey(button, 0); }
{
QString result;
for (int i = 0; i < m_Sequence.size(); i++) bool KeySequence::appendKey(int key, int modifiers) {
{ if (m_Sequence.size() == 4)
result += keyToString(m_Sequence[i]); return true;
if (i != m_Sequence.size() - 1)
result += "+";
}
return result;
}
bool KeySequence::appendMouseButton(int button)
{
return appendKey(button, 0);
}
bool KeySequence::appendKey(int key, int modifiers)
{
if (m_Sequence.size() == 4)
return true;
switch(key)
{
case Qt::Key_AltGr:
return false;
case Qt::Key_Control:
case Qt::Key_Alt:
case Qt::Key_Shift:
case Qt::Key_Meta:
case Qt::Key_Menu:
{
int mod = modifiers & (~m_Modifiers);
if (mod)
{
m_Sequence.append(mod);
m_Modifiers |= mod;
}
}
break;
default:
// see if we can handle this key, if not, don't accept it
if (keyToString(key).isEmpty())
break;
m_Sequence.append(key);
setValid(true);
return true;
}
switch (key) {
case Qt::Key_AltGr:
return false; return false;
}
void KeySequence::loadSettings(QSettings& settings) case Qt::Key_Control:
{ case Qt::Key_Alt:
sequence().clear(); case Qt::Key_Shift:
int num = settings.beginReadArray("keys"); case Qt::Key_Meta:
for (int i = 0; i < num; i++) case Qt::Key_Menu: {
{ int mod = modifiers & (~m_Modifiers);
settings.setArrayIndex(i); if (mod) {
sequence().append(settings.value("key", 0).toInt()); m_Sequence.append(mod);
m_Modifiers |= mod;
} }
settings.endArray(); } break;
setModifiers(0); default:
// see if we can handle this key, if not, don't accept it
if (keyToString(key).isEmpty())
break;
m_Sequence.append(key);
setValid(true); setValid(true);
return true;
}
return false;
} }
void KeySequence::saveSettings(QSettings& settings) const void KeySequence::loadSettings(QSettings &settings) {
{ sequence().clear();
settings.beginWriteArray("keys"); int num = settings.beginReadArray("keys");
for (int i = 0; i < sequence().size(); i++) for (int i = 0; i < num; i++) {
{ settings.setArrayIndex(i);
settings.setArrayIndex(i); sequence().append(settings.value("key", 0).toInt());
settings.setValue("key", sequence()[i]); }
} settings.endArray();
settings.endArray();
setModifiers(0);
setValid(true);
} }
QString KeySequence::keyToString(int key) void KeySequence::saveSettings(QSettings &settings) const {
{ settings.beginWriteArray("keys");
// nothing there? for (int i = 0; i < sequence().size(); i++) {
if (key == 0) settings.setArrayIndex(i);
return ""; settings.setValue("key", sequence()[i]);
}
settings.endArray();
}
// a hack to handle mouse buttons as if they were keys QString KeySequence::keyToString(int key) {
if (key < Qt::Key_Space) // nothing there?
{ if (key == 0)
switch(key)
{
case Qt::LeftButton: return "1";
case Qt::RightButton: return "2";
case Qt::MidButton: return "3";
}
return "4"; // qt only knows three mouse buttons, so assume it's an unknown fourth one
}
// modifiers?
if (key & Qt::ShiftModifier)
return "Shift";
if (key & Qt::ControlModifier)
return "Control";
if (key & Qt::AltModifier)
return "Alt";
if (key & Qt::MetaModifier)
return "Meta";
// treat key pad like normal keys (FIXME: we should have another lookup table for keypad keys instead)
key &= ~Qt::KeypadModifier;
// a printable 7 bit character?
if (key < 0x80 && key != Qt::Key_Space)
return QChar(key & 0x7f).toLower();
// a function key?
if (key >= Qt::Key_F1 && key <= Qt::Key_F35)
return QString::fromUtf8("F%1").arg(key - Qt::Key_F1 + 1);
// a special key?
int i=0;
while (keyname[i].name)
{
if (key == keyname[i].key)
return QString::fromUtf8(keyname[i].name);
i++;
}
// representable in ucs2?
if (key < 0x10000)
return QString("\\u%1").arg(QChar(key).toLower().unicode(), 4, 16, QChar('0'));
// give up, synergy probably won't handle this
return ""; return "";
// a hack to handle mouse buttons as if they were keys
if (key < Qt::Key_Space) {
switch (key) {
case Qt::LeftButton:
return "1";
case Qt::RightButton:
return "2";
case Qt::MidButton:
return "3";
}
return "4"; // qt only knows three mouse buttons, so assume it's an unknown
// fourth one
}
// modifiers?
if (key & Qt::ShiftModifier)
return "Shift";
if (key & Qt::ControlModifier)
return "Control";
if (key & Qt::AltModifier)
return "Alt";
if (key & Qt::MetaModifier)
return "Meta";
// treat key pad like normal keys (FIXME: we should have another lookup table
// for keypad keys instead)
key &= ~Qt::KeypadModifier;
// a printable 7 bit character?
if (key < 0x80 && key != Qt::Key_Space)
return QChar(key & 0x7f).toLower();
// a function key?
if (key >= Qt::Key_F1 && key <= Qt::Key_F35)
return QString::fromUtf8("F%1").arg(key - Qt::Key_F1 + 1);
// a special key?
int i = 0;
while (keyname[i].name) {
if (key == keyname[i].key)
return QString::fromUtf8(keyname[i].name);
i++;
}
// representable in ucs2?
if (key < 0x10000)
return QString("\\u%1").arg(QChar(key).toLower().unicode(), 4, 16,
QChar('0'));
// give up, synergy probably won't handle this
return "";
} }
bool KeySequence::operator==(const KeySequence& ks) const bool KeySequence::operator==(const KeySequence &ks) const {
{ return m_Sequence == ks.m_Sequence && m_Modifiers == ks.m_Modifiers &&
return m_Sequence == ks.m_Sequence && m_IsValid == ks.m_IsValid;
m_Modifiers == ks.m_Modifiers &&
m_IsValid == ks.m_IsValid;
} }

View file

@ -2,11 +2,11 @@
* synergy -- mouse and keyboard sharing utility * synergy -- mouse and keyboard sharing utility
* Copyright (C) 2012-2016 Symless Ltd. * Copyright (C) 2012-2016 Symless Ltd.
* Copyright (C) 2008 Volker Lanz (vl@fidra.de) * Copyright (C) 2008 Volker Lanz (vl@fidra.de)
* *
* This package is free software; you can redistribute it and/or * This package is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
* found in the file LICENSE that should have accompanied this file. * found in the file LICENSE that should have accompanied this file.
* *
* This package is distributed in the hope that it will be useful, * This package is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
@ -25,36 +25,34 @@
class QSettings; class QSettings;
class KeySequence class KeySequence {
{ public:
public: KeySequence();
KeySequence();
public: public:
QString toString() const; QString toString() const;
bool appendKey(int modifiers, int key); bool appendKey(int modifiers, int key);
bool appendMouseButton(int button); bool appendMouseButton(int button);
bool isMouseButton() const; bool isMouseButton() const;
bool valid() const { return m_IsValid; } bool valid() const { return m_IsValid; }
int modifiers() const { return m_Modifiers; } int modifiers() const { return m_Modifiers; }
void saveSettings(QSettings& settings) const; void saveSettings(QSettings &settings) const;
void loadSettings(QSettings& settings); void loadSettings(QSettings &settings);
const QList<int>& sequence() const { return m_Sequence; } const QList<int> &sequence() const { return m_Sequence; }
bool operator==(const KeySequence& ks) const; bool operator==(const KeySequence &ks) const;
private: private:
void setValid(bool b) { m_IsValid = b; } void setValid(bool b) { m_IsValid = b; }
void setModifiers(int i) { m_Modifiers = i; } void setModifiers(int i) { m_Modifiers = i; }
QList<int>& sequence() { return m_Sequence; } QList<int> &sequence() { return m_Sequence; }
private: private:
QList<int> m_Sequence; QList<int> m_Sequence;
int m_Modifiers; int m_Modifiers;
bool m_IsValid; bool m_IsValid;
static QString keyToString(int key); static QString keyToString(int key);
}; };
#endif #endif

View file

@ -2,11 +2,11 @@
* synergy -- mouse and keyboard sharing utility * synergy -- mouse and keyboard sharing utility
* Copyright (C) 2012-2016 Symless Ltd. * Copyright (C) 2012-2016 Symless Ltd.
* Copyright (C) 2008 Volker Lanz (vl@fidra.de) * Copyright (C) 2008 Volker Lanz (vl@fidra.de)
* *
* This package is free software; you can redistribute it and/or * This package is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
* found in the file LICENSE that should have accompanied this file. * found in the file LICENSE that should have accompanied this file.
* *
* This package is distributed in the hope that it will be useful, * This package is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
@ -18,128 +18,110 @@
#include "KeySequenceWidget.h" #include "KeySequenceWidget.h"
#include <iostream>
#include <QMouseEvent> #include <QMouseEvent>
#include <iostream>
KeySequenceWidget::KeySequenceWidget(QWidget* parent, const KeySequence& seq) : KeySequenceWidget::KeySequenceWidget(QWidget *parent, const KeySequence &seq)
QPushButton(parent), : QPushButton(parent), m_KeySequence(seq), m_BackupSequence(seq),
m_KeySequence(seq), m_Status(Stopped), m_MousePrefix("mousebutton("), m_MousePostfix(")"),
m_BackupSequence(seq), m_KeyPrefix("keystroke("), m_KeyPostfix(")") {
m_Status(Stopped), setFocusPolicy(Qt::NoFocus);
m_MousePrefix("mousebutton("), updateOutput();
m_MousePostfix(")"), }
m_KeyPrefix("keystroke("),
m_KeyPostfix(")") void KeySequenceWidget::setKeySequence(const KeySequence &seq) {
{ keySequence() = seq;
setFocusPolicy(Qt::NoFocus); backupSequence() = seq;
setStatus(Stopped);
updateOutput();
}
void KeySequenceWidget::mousePressEvent(QMouseEvent *event) {
event->accept();
if (status() == Stopped) {
startRecording();
return;
}
if (m_KeySequence.appendMouseButton(event->button()))
stopRecording();
updateOutput();
}
void KeySequenceWidget::startRecording() {
keySequence() = KeySequence();
setDown(true);
setFocus();
grabKeyboard();
setStatus(Recording);
}
void KeySequenceWidget::stopRecording() {
if (!keySequence().valid()) {
keySequence() = backupSequence();
updateOutput(); updateOutput();
}
setDown(false);
focusNextChild();
releaseKeyboard();
setStatus(Stopped);
emit keySequenceChanged();
} }
void KeySequenceWidget::setKeySequence(const KeySequence& seq) bool KeySequenceWidget::event(QEvent *event) {
{ if (status() == Recording) {
keySequence() = seq; switch (event->type()) {
backupSequence() = seq; case QEvent::KeyPress:
keyPressEvent(static_cast<QKeyEvent *>(event));
return true;
setStatus(Stopped); case QEvent::MouseButtonRelease:
updateOutput(); event->accept();
} return true;
void KeySequenceWidget::mousePressEvent(QMouseEvent* event) case QEvent::ShortcutOverride:
{ event->accept();
event->accept(); return true;
if (status() == Stopped) case QEvent::FocusOut:
{ stopRecording();
startRecording(); if (!valid()) {
return;
}
if (m_KeySequence.appendMouseButton(event->button()))
stopRecording();
updateOutput();
}
void KeySequenceWidget::startRecording()
{
keySequence() = KeySequence();
setDown(true);
setFocus();
grabKeyboard();
setStatus(Recording);
}
void KeySequenceWidget::stopRecording()
{
if (!keySequence().valid())
{
keySequence() = backupSequence(); keySequence() = backupSequence();
updateOutput(); updateOutput();
}
break;
default:
break;
} }
}
setDown(false); return QPushButton::event(event);
focusNextChild();
releaseKeyboard();
setStatus(Stopped);
emit keySequenceChanged();
} }
bool KeySequenceWidget::event(QEvent* event) void KeySequenceWidget::keyPressEvent(QKeyEvent *event) {
{ event->accept();
if (status() == Recording)
{
switch(event->type())
{
case QEvent::KeyPress:
keyPressEvent(static_cast<QKeyEvent*>(event));
return true;
case QEvent::MouseButtonRelease: if (status() == Stopped)
event->accept(); return;
return true;
case QEvent::ShortcutOverride: if (m_KeySequence.appendKey(event->key(), event->modifiers()))
event->accept(); stopRecording();
return true;
case QEvent::FocusOut: updateOutput();
stopRecording();
if (!valid())
{
keySequence() = backupSequence();
updateOutput();
}
break;
default:
break;
}
}
return QPushButton::event(event);
} }
void KeySequenceWidget::keyPressEvent(QKeyEvent* event) void KeySequenceWidget::updateOutput() {
{ QString s;
event->accept();
if (status() == Stopped) if (m_KeySequence.isMouseButton())
return; s = mousePrefix() + m_KeySequence.toString() + mousePostfix();
else
s = keyPrefix() + m_KeySequence.toString() + keyPostfix();
if (m_KeySequence.appendKey(event->key(), event->modifiers())) setText(s);
stopRecording();
updateOutput();
}
void KeySequenceWidget::updateOutput()
{
QString s;
if (m_KeySequence.isMouseButton())
s = mousePrefix() + m_KeySequence.toString() + mousePostfix();
else
s = keyPrefix() + m_KeySequence.toString() + keyPostfix();
setText(s);
} }

View file

@ -2,11 +2,11 @@
* synergy -- mouse and keyboard sharing utility * synergy -- mouse and keyboard sharing utility
* Copyright (C) 2012-2016 Symless Ltd. * Copyright (C) 2012-2016 Symless Ltd.
* Copyright (C) 2008 Volker Lanz (vl@fidra.de) * Copyright (C) 2008 Volker Lanz (vl@fidra.de)
* *
* This package is free software; you can redistribute it and/or * This package is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
* found in the file LICENSE that should have accompanied this file. * found in the file LICENSE that should have accompanied this file.
* *
* This package is distributed in the hope that it will be useful, * This package is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
@ -24,58 +24,56 @@
#include "KeySequence.h" #include "KeySequence.h"
class KeySequenceWidget : public QPushButton class KeySequenceWidget : public QPushButton {
{ Q_OBJECT
Q_OBJECT
public: public:
KeySequenceWidget(QWidget* parent, const KeySequence& seq = KeySequence()); KeySequenceWidget(QWidget *parent, const KeySequence &seq = KeySequence());
signals: signals:
void keySequenceChanged(); void keySequenceChanged();
public: public:
const QString& mousePrefix() const { return m_MousePrefix; } const QString &mousePrefix() const { return m_MousePrefix; }
const QString& mousePostfix() const { return m_MousePostfix; } const QString &mousePostfix() const { return m_MousePostfix; }
const QString& keyPrefix() const { return m_KeyPrefix; } const QString &keyPrefix() const { return m_KeyPrefix; }
const QString& keyPostfix() const { return m_KeyPostfix; } const QString &keyPostfix() const { return m_KeyPostfix; }
void setMousePrefix(const QString& s) { m_MousePrefix = s; } void setMousePrefix(const QString &s) { m_MousePrefix = s; }
void setMousePostfix(const QString& s) { m_MousePostfix = s; } void setMousePostfix(const QString &s) { m_MousePostfix = s; }
void setKeyPrefix(const QString& s) { m_KeyPrefix = s; } void setKeyPrefix(const QString &s) { m_KeyPrefix = s; }
void setKeyPostfix(const QString& s) { m_KeyPostfix = s; } void setKeyPostfix(const QString &s) { m_KeyPostfix = s; }
const KeySequence& keySequence() const { return m_KeySequence; } const KeySequence &keySequence() const { return m_KeySequence; }
const KeySequence& backupSequence() const { return m_BackupSequence; } const KeySequence &backupSequence() const { return m_BackupSequence; }
void setKeySequence(const KeySequence& seq); void setKeySequence(const KeySequence &seq);
bool valid() const { return keySequence().valid(); } bool valid() const { return keySequence().valid(); }
protected: protected:
void mousePressEvent(QMouseEvent*); void mousePressEvent(QMouseEvent *);
void keyPressEvent(QKeyEvent*); void keyPressEvent(QKeyEvent *);
bool event(QEvent* event); bool event(QEvent *event);
void appendToSequence(int key); void appendToSequence(int key);
void updateOutput(); void updateOutput();
void startRecording(); void startRecording();
void stopRecording(); void stopRecording();
KeySequence& keySequence() { return m_KeySequence; } KeySequence &keySequence() { return m_KeySequence; }
KeySequence& backupSequence() { return m_BackupSequence; } KeySequence &backupSequence() { return m_BackupSequence; }
private: private:
enum Status { Stopped, Recording }; enum Status { Stopped, Recording };
void setStatus(Status s) { m_Status = s; } void setStatus(Status s) { m_Status = s; }
Status status() const { return m_Status; } Status status() const { return m_Status; }
private: private:
KeySequence m_KeySequence; KeySequence m_KeySequence;
KeySequence m_BackupSequence; KeySequence m_BackupSequence;
Status m_Status; Status m_Status;
QString m_MousePrefix; QString m_MousePrefix;
QString m_MousePostfix; QString m_MousePostfix;
QString m_KeyPrefix; QString m_KeyPrefix;
QString m_KeyPostfix; QString m_KeyPostfix;
}; };
#endif #endif

View file

@ -17,255 +17,218 @@
#include "LicenseManager.h" #include "LicenseManager.h"
#include "AppConfig.h" #include "AppConfig.h"
#include <QDateTime>
#include <QLocale>
#include <QThread>
#include <QTimer>
#include <ctime> #include <ctime>
#include <stdexcept> #include <stdexcept>
#include <utility> #include <utility>
#include <QThread>
#include <QTimer>
#include <QDateTime>
#include <QLocale>
namespace { namespace {
std::string std::string getMaintenanceMessage(const SerialKey &serialKey) {
getMaintenanceMessage(const SerialKey& serialKey) auto expiration = QDateTime::fromTime_t(serialKey.getExpiration()).date();
{ QString message =
auto expiration = QDateTime::fromTime_t(serialKey.getExpiration()).date(); "The license key you used will only work with versions of Synergy "
QString message = "The license key you used will only work with versions of Synergy released before %1." "released before %1."
"<p>To use this version, you’ll need to renew your Synergy maintenance license. " "<p>To use this version, you’ll need to renew your Synergy maintenance "
"<a href=\"https://symless.com/synergy/account?source=gui\"" "license. "
"style=\"text-decoration: none; color: #4285F4;\">Renew today</a>.</p>"; "<a href=\"https://symless.com/synergy/account?source=gui\""
auto formatedDate = QLocale("en_US").toString(expiration, "MMM dd yyyy"); "style=\"text-decoration: none; color: #4285F4;\">Renew today</a>.</p>";
return message.arg(formatedDate).toStdString(); auto formatedDate = QLocale("en_US").toString(expiration, "MMM dd yyyy");
return message.arg(formatedDate).toStdString();
} }
void void checkSerialKey(const SerialKey &serialKey, bool acceptExpired) {
checkSerialKey(const SerialKey& serialKey, bool acceptExpired) if (serialKey.isMaintenance()) {
{ auto buildDate = QDateTime::fromString(__TIMESTAMP__).toTime_t();
if (serialKey.isMaintenance()) {
auto buildDate = QDateTime::fromString(__TIMESTAMP__).toTime_t();
if (buildDate > serialKey.getExpiration()) { if (buildDate > serialKey.getExpiration()) {
throw std::runtime_error(getMaintenanceMessage(serialKey)); throw std::runtime_error(getMaintenanceMessage(serialKey));
}
} }
}
if (!acceptExpired && serialKey.isExpired(::time(nullptr))) { if (!acceptExpired && serialKey.isExpired(::time(nullptr))) {
throw std::runtime_error("Serial key expired"); throw std::runtime_error("Serial key expired");
}
#ifdef SYNERGY_BUSINESS
if (!serialKey.isValid()) {
throw std::runtime_error("The serial key is not compatible with the "
"business version of Synergy.");
}
#endif
}
} // namespace
LicenseManager::LicenseManager(AppConfig *appConfig)
: m_AppConfig(appConfig), m_serialKey(appConfig->edition()),
m_registry(*appConfig) {}
void LicenseManager::setSerialKey(SerialKey serialKey, bool acceptExpired) {
checkSerialKey(serialKey, acceptExpired);
if (serialKey != m_serialKey) {
using std::swap;
swap(serialKey, m_serialKey);
m_AppConfig->setSerialKey(QString::fromStdString(m_serialKey.toString()));
emit showLicenseNotice(getLicenseNotice());
validateSerialKey();
m_registry.scheduleRegistration();
if (m_serialKey.edition() != serialKey.edition()) {
m_AppConfig->setEdition(m_serialKey.edition());
emit editionChanged(m_serialKey.edition());
} }
}
}
#ifdef SYNERGY_BUSINESS void LicenseManager::notifyUpdate(QString fromVersion,
if (!serialKey.isValid()) { QString toVersion) const {
throw std::runtime_error("The serial key is not compatible with the business version of Synergy."); if ((fromVersion == "Unknown") && (m_serialKey == SerialKey(kUnregistered))) {
return;
}
ActivationNotifier *notifier = new ActivationNotifier();
notifier->setUpdateInfo(fromVersion, toVersion,
QString::fromStdString(m_serialKey.toString()));
QThread *thread = new QThread();
connect(notifier, SIGNAL(finished()), thread, SLOT(quit()));
connect(notifier, SIGNAL(finished()), notifier, SLOT(deleteLater()));
connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater()));
notifier->moveToThread(thread);
thread->start();
QMetaObject::invokeMethod(notifier, "notifyUpdate", Qt::QueuedConnection);
}
Edition LicenseManager::activeEdition() const { return m_serialKey.edition(); }
QString LicenseManager::activeEditionName() const {
return getEditionName(activeEdition(), m_serialKey.isTrial());
}
const SerialKey &LicenseManager::serialKey() const { return m_serialKey; }
void LicenseManager::refresh() {
if (!m_AppConfig->serialKey().isEmpty()) {
try {
SerialKey serialKey(m_AppConfig->serialKey().toStdString());
setSerialKey(serialKey, true);
} catch (...) {
m_serialKey = SerialKey();
m_AppConfig->clearSerialKey();
} }
#endif }
if (!m_serialKey.isValid()) {
emit InvalidLicense();
}
} }
void LicenseManager::skipActivation() const {
notifyActivation("skip:unknown");
} }
QString LicenseManager::getEditionName(Edition const edition, bool trial) {
SerialKeyEdition KeyEdition(edition);
std::string name = KeyEdition.getDisplayName();
LicenseManager::LicenseManager(AppConfig* appConfig) : if (trial) {
m_AppConfig(appConfig), name += " (Trial)";
m_serialKey(appConfig->edition()), }
m_registry(*appConfig) {
return QString::fromUtf8(name.c_str(), static_cast<int>(name.size()));
} }
void void LicenseManager::notifyActivation(QString identity) const {
LicenseManager::setSerialKey(SerialKey serialKey, bool acceptExpired) ActivationNotifier *notifier = new ActivationNotifier();
{ notifier->setIdentity(identity);
checkSerialKey(serialKey, acceptExpired);
if (serialKey != m_serialKey) { QThread *thread = new QThread();
using std::swap; connect(notifier, SIGNAL(finished()), thread, SLOT(quit()));
swap (serialKey, m_serialKey); connect(notifier, SIGNAL(finished()), notifier, SLOT(deleteLater()));
m_AppConfig->setSerialKey(QString::fromStdString connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater()));
(m_serialKey.toString()));
emit showLicenseNotice(getLicenseNotice()); notifier->moveToThread(thread);
validateSerialKey(); thread->start();
m_registry.scheduleRegistration();
if (m_serialKey.edition() != serialKey.edition()) { QMetaObject::invokeMethod(notifier, "notify", Qt::QueuedConnection);
m_AppConfig->setEdition(m_serialKey.edition()); }
emit editionChanged(m_serialKey.edition());
} QString LicenseManager::getLicenseNotice() const {
QString Notice;
if (m_serialKey.isTemporary()) {
if (m_serialKey.isTrial()) {
Notice = getTrialNotice();
} else {
Notice = getTemporaryNotice();
} }
}
return Notice;
} }
void void LicenseManager::registerLicense() { m_registry.registerLicense(); }
LicenseManager::notifyUpdate(QString fromVersion, QString toVersion) const {
if ((fromVersion == "Unknown") QString LicenseManager::getTrialNotice() const {
&& (m_serialKey == SerialKey(kUnregistered))) { QString Notice;
return;
} if (m_serialKey.isExpired(::time(0))) {
Notice = "<html><head/><body><p>"
ActivationNotifier* notifier = new ActivationNotifier(); "Trial expired - "
notifier->setUpdateInfo (fromVersion, toVersion, "<a href=\"https://symless.com/synergy/purchase?source=gui\" "
QString::fromStdString(m_serialKey.toString())); "style=\"color: #FFFFFF;\">Buy now</a>"
"</p></body></html>";
QThread* thread = new QThread(); } else {
connect(notifier, SIGNAL(finished()), thread, SLOT(quit())); Notice = "<html><head/><body><p>"
connect(notifier, SIGNAL(finished()), notifier, SLOT(deleteLater())); "Trial expires in %1 day%2 - "
connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater())); "<a href=\"https://symless.com/synergy/purchase?source=gui\" "
"style=\"color: #FFFFFF;\">Buy now</a>"
notifier->moveToThread(thread); "</p></body></html>";
thread->start();
time_t daysLeft = m_serialKey.daysLeft(::time(0));
QMetaObject::invokeMethod(notifier, "notifyUpdate", Notice = Notice.arg(daysLeft).arg((daysLeft == 1) ? "" : "s");
Qt::QueuedConnection); }
}
return Notice;
Edition }
LicenseManager::activeEdition() const
{ QString LicenseManager::getTemporaryNotice() const {
return m_serialKey.edition(); QString Notice;
}
if (m_serialKey.isExpired(::time(0))) {
QString Notice = "<html><head/><body><p>"
LicenseManager::activeEditionName() const "License expired - "
{ "<a href=\"https://symless.com/synergy/purchase?source=gui\" "
return getEditionName(activeEdition(), m_serialKey.isTrial()); "style=\"color: #FFFFFF;\">Renew now</a>"
} "</p></body></html>";
} else if (m_serialKey.isExpiring(::time(0))) {
const SerialKey& Notice = "<html><head/><body><p>"
LicenseManager::serialKey() const "License expires in %1 day%2 - "
{ "<a href=\"https://symless.com/synergy/purchase?source=gui\" "
return m_serialKey; "style=\"color: #FFFFFF;\">Renew now</a>"
} "</p></body></html>";
void time_t daysLeft = m_serialKey.daysLeft(::time(0));
LicenseManager::refresh() Notice = Notice.arg(daysLeft).arg((daysLeft == 1) ? "" : "s");
{ }
if (!m_AppConfig->serialKey().isEmpty()) {
try { return Notice;
SerialKey serialKey (m_AppConfig->serialKey().toStdString()); }
setSerialKey(serialKey, true);
} catch (...) { void LicenseManager::validateSerialKey() const {
m_serialKey = SerialKey(); if (m_serialKey.isValid()) {
m_AppConfig->clearSerialKey(); if (m_serialKey.isTemporary()) {
} QTimer::singleShot(m_serialKey.getSpanLeft(), this,
} SLOT(validateSerialKey()));
if (!m_serialKey.isValid()) {
emit InvalidLicense();
}
}
void
LicenseManager::skipActivation() const
{
notifyActivation ("skip:unknown");
}
QString
LicenseManager::getEditionName(Edition const edition, bool trial)
{
SerialKeyEdition KeyEdition(edition);
std::string name = KeyEdition.getDisplayName();
if (trial) {
name += " (Trial)";
}
return QString::fromUtf8 (name.c_str(), static_cast<int>(name.size()));
}
void
LicenseManager::notifyActivation(QString identity) const
{
ActivationNotifier* notifier = new ActivationNotifier();
notifier->setIdentity(identity);
QThread* thread = new QThread();
connect(notifier, SIGNAL(finished()), thread, SLOT(quit()));
connect(notifier, SIGNAL(finished()), notifier, SLOT(deleteLater()));
connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater()));
notifier->moveToThread(thread);
thread->start();
QMetaObject::invokeMethod(notifier, "notify", Qt::QueuedConnection);
}
QString
LicenseManager::getLicenseNotice() const
{
QString Notice;
if (m_serialKey.isTemporary()){
if (m_serialKey.isTrial()){
Notice = getTrialNotice();
}
else{
Notice = getTemporaryNotice();
}
}
return Notice;
}
void
LicenseManager::registerLicense()
{
m_registry.registerLicense();
}
QString
LicenseManager::getTrialNotice() const
{
QString Notice;
if (m_serialKey.isExpired(::time(0))){
Notice = "<html><head/><body><p>"
"Trial expired - "
"<a href=\"https://symless.com/synergy/purchase?source=gui\" style=\"color: #FFFFFF;\">Buy now</a>"
"</p></body></html>";
}
else{
Notice = "<html><head/><body><p>"
"Trial expires in %1 day%2 - "
"<a href=\"https://symless.com/synergy/purchase?source=gui\" style=\"color: #FFFFFF;\">Buy now</a>"
"</p></body></html>";
time_t daysLeft = m_serialKey.daysLeft(::time(0));
Notice = Notice.arg (daysLeft).arg ((daysLeft == 1) ? "" : "s");
}
return Notice;
}
QString
LicenseManager::getTemporaryNotice() const
{
QString Notice;
if (m_serialKey.isExpired(::time(0))) {
Notice = "<html><head/><body><p>"
"License expired - "
"<a href=\"https://symless.com/synergy/purchase?source=gui\" style=\"color: #FFFFFF;\">Renew now</a>"
"</p></body></html>";
}
else if (m_serialKey.isExpiring(::time(0))) {
Notice = "<html><head/><body><p>"
"License expires in %1 day%2 - "
"<a href=\"https://symless.com/synergy/purchase?source=gui\" style=\"color: #FFFFFF;\">Renew now</a>"
"</p></body></html>";
time_t daysLeft = m_serialKey.daysLeft(::time(0));
Notice = Notice.arg (daysLeft).arg ((daysLeft == 1) ? "" : "s");
}
return Notice;
}
void
LicenseManager::validateSerialKey() const
{
if (m_serialKey.isValid()) {
if (m_serialKey.isTemporary()){
QTimer::singleShot(m_serialKey.getSpanLeft(), this, SLOT(validateSerialKey()));
}
}
else{
emit InvalidLicense();
} }
} else {
emit InvalidLicense();
}
} }

View file

@ -17,48 +17,47 @@
#pragma once #pragma once
#include <ActivationNotifier.h>
#include <QObject> #include <QObject>
#include <shared/EditionType.h> #include <shared/EditionType.h>
#include <shared/SerialKey.h> #include <shared/SerialKey.h>
#include <ActivationNotifier.h>
#include <utility> #include <utility>
#include "LicenseRegistry.h" #include "LicenseRegistry.h"
class AppConfig; class AppConfig;
class LicenseManager: public QObject class LicenseManager : public QObject {
{ Q_OBJECT
Q_OBJECT
public: public:
LicenseManager(AppConfig* appConfig); LicenseManager(AppConfig *appConfig);
void setSerialKey(SerialKey serialKey, bool acceptExpired = false); void setSerialKey(SerialKey serialKey, bool acceptExpired = false);
void refresh(); void refresh();
Edition activeEdition() const; Edition activeEdition() const;
QString activeEditionName() const; QString activeEditionName() const;
const SerialKey& serialKey() const; const SerialKey &serialKey() const;
void skipActivation() const; void skipActivation() const;
void notifyUpdate(QString fromVersion, QString toVersion) const; void notifyUpdate(QString fromVersion, QString toVersion) const;
static QString getEditionName(Edition edition, bool trial = false); static QString getEditionName(Edition edition, bool trial = false);
void notifyActivation(QString identity) const; void notifyActivation(QString identity) const;
QString getLicenseNotice() const; QString getLicenseNotice() const;
private: private:
AppConfig* m_AppConfig; AppConfig *m_AppConfig;
SerialKey m_serialKey; SerialKey m_serialKey;
LicenseRegistry m_registry; LicenseRegistry m_registry;
public slots: public slots:
void validateSerialKey() const; void validateSerialKey() const;
void registerLicense(); void registerLicense();
signals: signals:
void editionChanged (Edition) const; void editionChanged(Edition) const;
void InvalidLicense () const; void InvalidLicense() const;
void showLicenseNotice(const QString& notice) const; void showLicenseNotice(const QString &notice) const;
protected: protected:
QString getTrialNotice() const; QString getTrialNotice() const;
QString getTemporaryNotice() const; QString getTemporaryNotice() const;
}; };

View file

@ -14,92 +14,85 @@
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include <QNetworkReply>
#include <QJsonObject>
#include <QJsonDocument> #include <QJsonDocument>
#include <QJsonObject>
#include <QNetworkReply>
#include <QTimer> #include <QTimer>
#include "LicenseRegistry.h"
#include "AppConfig.h" #include "AppConfig.h"
#include "LicenseRegistry.h"
#include <QSysInfo> #include <QSysInfo>
LicenseRegistry::LicenseRegistry(AppConfig& config) : LicenseRegistry::LicenseRegistry(AppConfig &config) : m_config(config) {
m_config(config) connect(&m_timer, SIGNAL(timeout()), this, SLOT(registerLicense()));
{
connect(&m_timer, SIGNAL(timeout()), this, SLOT(registerLicense()));
} }
void LicenseRegistry::registerLicense() void LicenseRegistry::registerLicense() {
{ m_timer.stop();
m_timer.stop(); if (m_config.edition() == Edition::kBusiness) {
if (m_config.edition() == Edition::kBusiness) { const auto REGISTER_LICENSE_URL = m_config.getLicenseRegistryUrl();
const auto REGISTER_LICENSE_URL = m_config.getLicenseRegistryUrl(); const auto url = QUrl(REGISTER_LICENSE_URL);
const auto url = QUrl(REGISTER_LICENSE_URL);
auto request = QNetworkRequest(url); auto request = QNetworkRequest(url);
request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json"); request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");
m_manager.post(request, getRequestData()); m_manager.post(request, getRequestData());
connect(&m_manager, SIGNAL(finished(QNetworkReply*)), this, SLOT(handleResponse(QNetworkReply*))); connect(&m_manager, SIGNAL(finished(QNetworkReply *)), this,
SLOT(handleResponse(QNetworkReply *)));
}
}
void LicenseRegistry::handleResponse(QNetworkReply *reply) {
if (reply) {
const auto HOUR = (60 * 60); // seconds per hour
const auto DAY = (24 * HOUR); // seconds per day
const auto WEEK = (7 * DAY); // seconds per week
const auto currentTimestamp = time(nullptr);
if (reply->error() == QNetworkReply::NoError) {
m_config.setLicenseNextCheck(currentTimestamp + WEEK);
} else {
m_config.setLicenseNextCheck(currentTimestamp + HOUR);
} }
scheduleRegistration();
reply->deleteLater();
}
} }
void LicenseRegistry::handleResponse(QNetworkReply *reply) QByteArray LicenseRegistry::getRequestData() const {
{
if (reply) {
const auto HOUR = (60*60); //seconds per hour
const auto DAY = (24*HOUR);//seconds per day
const auto WEEK = (7*DAY); //seconds per week
const auto currentTimestamp = time(nullptr);
if(reply->error() == QNetworkReply::NoError) {
m_config.setLicenseNextCheck(currentTimestamp + WEEK);
}
else{
m_config.setLicenseNextCheck(currentTimestamp + HOUR);
}
scheduleRegistration();
reply->deleteLater();
}
}
QByteArray LicenseRegistry::getRequestData() const
{
#if QT_VERSION >= QT_VERSION_CHECK(5, 11, 0) #if QT_VERSION >= QT_VERSION_CHECK(5, 11, 0)
QString guid(QSysInfo::machineUniqueId()); QString guid(QSysInfo::machineUniqueId());
#else #else
QString guid; QString guid;
#endif #endif
QJsonObject data; QJsonObject data;
if (!guid.isEmpty()) { if (!guid.isEmpty()) {
data["guid"] = guid; data["guid"] = guid;
data["guid_type"] = "system"; data["guid_type"] = "system";
} } else {
else { data["guid"] = m_config.getGuid();
data["guid"] = m_config.getGuid(); data["guid_type"] = "synergy";
data["guid_type"] = "synergy"; }
}
data["key"] = m_config.serialKey(); data["key"] = m_config.serialKey();
data["is_server"] = m_config.getServerGroupChecked(); data["is_server"] = m_config.getServerGroupChecked();
return QJsonDocument(data).toJson(); return QJsonDocument(data).toJson();
} }
void LicenseRegistry::scheduleRegistration() void LicenseRegistry::scheduleRegistration() {
{ const auto nextCheck = m_config.getLicenseNextCheck();
const auto nextCheck = m_config.getLicenseNextCheck(); const auto currentTimestamp = static_cast<unsigned long long>(time(nullptr));
const auto currentTimestamp = static_cast<unsigned long long>(time(nullptr));
if (currentTimestamp >= nextCheck) { if (currentTimestamp >= nextCheck) {
registerLicense(); registerLicense();
} } else {
else { const auto interval =
const auto interval = (nextCheck - currentTimestamp) * 1000; //interval in milliseconds (nextCheck - currentTimestamp) * 1000; // interval in milliseconds
m_timer.setInterval(static_cast<int>(interval)); m_timer.setInterval(static_cast<int>(interval));
m_timer.setSingleShot(true); m_timer.setSingleShot(true);
m_timer.start(); m_timer.start();
} }
} }

View file

@ -16,29 +16,28 @@
*/ */
#pragma once #pragma once
#include <QNetworkAccessManager>
#include <QObject> #include <QObject>
#include <QTimer> #include <QTimer>
#include <QNetworkAccessManager>
class QNetworkReply; class QNetworkReply;
class AppConfig; class AppConfig;
class LicenseRegistry : public QObject class LicenseRegistry : public QObject {
{ Q_OBJECT
Q_OBJECT
public: public:
explicit LicenseRegistry(AppConfig& config); explicit LicenseRegistry(AppConfig &config);
void scheduleRegistration(); void scheduleRegistration();
public slots: public slots:
void registerLicense(); void registerLicense();
void handleResponse(QNetworkReply *reply); void handleResponse(QNetworkReply *reply);
private: private:
AppConfig& m_config; AppConfig &m_config;
QNetworkAccessManager m_manager; QNetworkAccessManager m_manager;
QTimer m_timer; QTimer m_timer;
QByteArray getRequestData() const; QByteArray getRequestData() const;
}; };

File diff suppressed because it is too large Load diff

View file

@ -19,23 +19,23 @@
#pragma once #pragma once
#include <QMainWindow> #include <QMainWindow>
#include <QSystemTrayIcon>
#include <QSettings>
#include <QProcess>
#include <QThread>
#include <QMutex> #include <QMutex>
#include <QProcess>
#include <QSettings>
#include <QSystemTrayIcon>
#include <QThread>
#include "ui_MainWindowBase.h" #include "ui_MainWindowBase.h"
#include "ActivationDialog.h"
#include "AppConfig.h"
#include "ClientConnection.h"
#include "ConfigWriter.h"
#include "Ipc.h"
#include "IpcClient.h"
#include "ServerConfig.h" #include "ServerConfig.h"
#include "ServerConnection.h" #include "ServerConnection.h"
#include "ClientConnection.h"
#include "AppConfig.h"
#include "VersionChecker.h" #include "VersionChecker.h"
#include "IpcClient.h"
#include "Ipc.h"
#include "ActivationDialog.h"
#include "ConfigWriter.h"
#include "TrayIcon.h" #include "TrayIcon.h"
@ -61,210 +61,203 @@ class SslCertificate;
class LicenseManager; class LicenseManager;
class Zeroconf; class Zeroconf;
class MainWindow : public QMainWindow, public Ui::MainWindowBase class MainWindow : public QMainWindow, public Ui::MainWindowBase {
{ Q_OBJECT
Q_OBJECT
friend class QSynergyApplication; friend class QSynergyApplication;
friend class SetupWizard; friend class SetupWizard;
friend class ActivationDialog; friend class ActivationDialog;
friend class SettingsDialog; friend class SettingsDialog;
friend class ServerConnection; friend class ServerConnection;
friend class ClientConnection; friend class ClientConnection;
public: public:
enum qSynergyState enum qSynergyState {
{ synergyDisconnected,
synergyDisconnected, synergyConnecting,
synergyConnecting, synergyConnected,
synergyConnected, synergyListening,
synergyListening, synergyPendingRetry
synergyPendingRetry };
};
enum qSynergyType enum qSynergyType { synergyClient, synergyServer };
{
synergyClient,
synergyServer
};
enum qLevel { enum qLevel { Error, Info };
Error,
Info
};
enum qRuningState { enum qRuningState { kStarted, kStopped };
kStarted,
kStopped
};
public: public:
#ifdef SYNERGY_ENTERPRISE #ifdef SYNERGY_ENTERPRISE
MainWindow(AppConfig& appConfig); MainWindow(AppConfig &appConfig);
#else #else
MainWindow(AppConfig& appConfig, MainWindow(AppConfig &appConfig, LicenseManager &licenseManager);
LicenseManager& licenseManager);
#endif #endif
~MainWindow(); ~MainWindow();
public: public:
void setVisible(bool visible); void setVisible(bool visible);
int synergyType() const { return m_pRadioGroupClient->isChecked() ? synergyClient : synergyServer; } int synergyType() const {
int synergyState() const { return m_SynergyState; } return m_pRadioGroupClient->isChecked() ? synergyClient : synergyServer;
QString hostname() const { return m_pLineEditHostname->text(); } }
QString configFilename(); int synergyState() const { return m_SynergyState; }
QString address() const; QString hostname() const { return m_pLineEditHostname->text(); }
QString appPath(const QString& name); QString configFilename();
void open(); QString address() const;
void clearLog(); QString appPath(const QString &name);
VersionChecker& versionChecker() { return m_VersionChecker; } void open();
ServerConfig& serverConfig() { return m_ServerConfig; } void clearLog();
void showConfigureServer(const QString& message); VersionChecker &versionChecker() { return m_VersionChecker; }
void showConfigureServer() { showConfigureServer(""); } ServerConfig &serverConfig() { return m_ServerConfig; }
void autoAddScreen(const QString name); void showConfigureServer(const QString &message);
void addZeroconfServer(const QString name); void showConfigureServer() { showConfigureServer(""); }
Zeroconf& zeroconf() { return *m_pZeroconf; } void autoAddScreen(const QString name);
void addZeroconfServer(const QString name);
Zeroconf &zeroconf() { return *m_pZeroconf; }
#ifndef SYNERGY_ENTERPRISE #ifndef SYNERGY_ENTERPRISE
LicenseManager& licenseManager() const; LicenseManager &licenseManager() const;
int raiseActivationDialog(); int raiseActivationDialog();
#endif #endif
void updateZeroconfService(); void updateZeroconfService();
public slots: public slots:
void setEdition(Edition edition); void setEdition(Edition edition);
#ifndef SYNERGY_ENTERPRISE #ifndef SYNERGY_ENTERPRISE
void InvalidLicense(); void InvalidLicense();
void showLicenseNotice(const QString& message); void showLicenseNotice(const QString &message);
#endif #endif
void appendLogRaw(const QString& text); void appendLogRaw(const QString &text);
void appendLogInfo(const QString& text); void appendLogInfo(const QString &text);
void appendLogDebug(const QString& text); void appendLogDebug(const QString &text);
void appendLogError(const QString& text); void appendLogError(const QString &text);
void startSynergy(); void startSynergy();
void retryStart(); // If the connection failed this will retry a startSynergy void retryStart(); // If the connection failed this will retry a startSynergy
void actionStart(); void actionStart();
void handleIdleService(const QString& text); void handleIdleService(const QString &text);
protected slots: protected slots:
void updateLocalFingerprint(); void updateLocalFingerprint();
void updateScreenName(); void updateScreenName();
void on_m_pRadioGroupServer_clicked(bool); void on_m_pRadioGroupServer_clicked(bool);
void on_m_pRadioGroupClient_clicked(bool); void on_m_pRadioGroupClient_clicked(bool);
void on_m_pButtonConfigureServer_clicked(); void on_m_pButtonConfigureServer_clicked();
bool on_m_pActionSave_triggered(); bool on_m_pActionSave_triggered();
void on_m_pActionAbout_triggered(); void on_m_pActionAbout_triggered();
void on_m_pActionHelp_triggered(); void on_m_pActionHelp_triggered();
void on_m_pActionSettings_triggered(); void on_m_pActionSettings_triggered();
void on_m_pActivate_triggered(); void on_m_pActivate_triggered();
void synergyFinished(int exitCode, QProcess::ExitStatus); void synergyFinished(int exitCode, QProcess::ExitStatus);
void trayActivated(QSystemTrayIcon::ActivationReason reason); void trayActivated(QSystemTrayIcon::ActivationReason reason);
void stopSynergy(); void stopSynergy();
void logOutput(); void logOutput();
void logError(); void logError();
void updateFound(const QString& version); void updateFound(const QString &version);
void saveSettings(); void saveSettings();
/// @brief Receives the signal that the auto config option has changed /// @brief Receives the signal that the auto config option has changed
void zeroConfToggled(); void zeroConfToggled();
protected: protected:
// TODO This should be properly using the ConfigWriter system. // TODO This should be properly using the ConfigWriter system.
QSettings& settings() { return GUI::Config::ConfigWriter::make()->settings(); } QSettings &settings() {
AppConfig& appConfig() { return *m_AppConfig; } return GUI::Config::ConfigWriter::make()->settings();
AppConfig const& appConfig() const { return *m_AppConfig; } }
QProcess* synergyProcess() { return m_pSynergy; } AppConfig &appConfig() { return *m_AppConfig; }
void setSynergyProcess(QProcess* p) { m_pSynergy = p; } AppConfig const &appConfig() const { return *m_AppConfig; }
void initConnections(); QProcess *synergyProcess() { return m_pSynergy; }
void createMenuBar(); void setSynergyProcess(QProcess *p) { m_pSynergy = p; }
void createStatusBar(); void initConnections();
void createTrayIcon(); void createMenuBar();
void loadSettings(); void createStatusBar();
void setIcon(qSynergyState state) const; void createTrayIcon();
void setSynergyState(qSynergyState state); void loadSettings();
bool checkForApp(int which, QString& app); void setIcon(qSynergyState state) const;
bool clientArgs(QStringList& args, QString& app); void setSynergyState(qSynergyState state);
bool serverArgs(QStringList& args, QString& app); bool checkForApp(int which, QString &app);
void setStatus(const QString& status); bool clientArgs(QStringList &args, QString &app);
void sendIpcMessage(qIpcMessageType type, const char* buffer, bool showErrors); bool serverArgs(QStringList &args, QString &app);
void updateFromLogLine(const QString& line); void setStatus(const QString &status);
QString getIPAddresses(); void sendIpcMessage(qIpcMessageType type, const char *buffer,
void stopService(); bool showErrors);
void stopDesktop(); void updateFromLogLine(const QString &line);
void changeEvent(QEvent* event); QString getIPAddresses();
void retranslateMenuBar(); void stopService();
void enableServer(bool enable); void stopDesktop();
void enableClient(bool enable); void changeEvent(QEvent *event);
void closeEvent(QCloseEvent* event) override; void retranslateMenuBar();
void enableServer(bool enable);
void enableClient(bool enable);
void closeEvent(QCloseEvent *event) override;
#if defined(Q_OS_WIN) #if defined(Q_OS_WIN)
bool isServiceRunning(QString name); bool isServiceRunning(QString name);
#else #else
bool isServiceRunning(); bool isServiceRunning();
#endif #endif
QString getProfileRootForArg(); QString getProfileRootForArg();
void checkConnected(const QString& line); void checkConnected(const QString &line);
void checkFingerprint(const QString& line); void checkFingerprint(const QString &line);
void checkSecureSocket(const QString& line); void checkSecureSocket(const QString &line);
#ifdef Q_OS_MAC #ifdef Q_OS_MAC
void checkOSXNotification(const QString& line); void checkOSXNotification(const QString &line);
#endif #endif
#ifndef SYNERGY_ENTERPRISE #ifndef SYNERGY_ENTERPRISE
void checkLicense(const QString& line); void checkLicense(const QString &line);
#endif #endif
QString getTimeStamp(); QString getTimeStamp();
void restartSynergy(); void restartSynergy();
void proofreadInfo(); void proofreadInfo();
void showEvent (QShowEvent*); void showEvent(QShowEvent *);
void secureSocket(bool secureSocket); void secureSocket(bool secureSocket);
void windowStateChanged(); void windowStateChanged();
private:
private:
#ifndef SYNERGY_ENTERPRISE #ifndef SYNERGY_ENTERPRISE
LicenseManager* m_LicenseManager; LicenseManager *m_LicenseManager;
bool m_ActivationDialogRunning; bool m_ActivationDialogRunning;
QStringList m_PendingClientNames; QStringList m_PendingClientNames;
#endif #endif
Zeroconf* m_pZeroconf; Zeroconf *m_pZeroconf;
AppConfig* m_AppConfig; AppConfig *m_AppConfig;
QProcess* m_pSynergy; QProcess *m_pSynergy;
int m_SynergyState; int m_SynergyState;
ServerConfig m_ServerConfig; ServerConfig m_ServerConfig;
bool m_AlreadyHidden; bool m_AlreadyHidden;
VersionChecker m_VersionChecker; VersionChecker m_VersionChecker;
IpcClient m_IpcClient; IpcClient m_IpcClient;
QMenuBar* m_pMenuBar; QMenuBar *m_pMenuBar;
QMenu* m_pMenuFile; QMenu *m_pMenuFile;
QMenu* m_pMenuEdit; QMenu *m_pMenuEdit;
QMenu* m_pMenuWindow; QMenu *m_pMenuWindow;
QMenu* m_pMenuHelp; QMenu *m_pMenuHelp;
QAbstractButton* m_pCancelButton; QAbstractButton *m_pCancelButton;
TrayIcon m_trayIcon; TrayIcon m_trayIcon;
qRuningState m_ExpectedRunningState; qRuningState m_ExpectedRunningState;
QMutex m_StopDesktopMutex; QMutex m_StopDesktopMutex;
bool m_SecureSocket; // brief Is the program running a secure socket protocol (SSL/TLS) bool m_SecureSocket; // brief Is the program running a secure socket protocol
QString m_SecureSocketVersion; // brief Contains the version of the Secure Socket currently active // (SSL/TLS)
ServerConnection m_serverConnection; QString m_SecureSocketVersion; // brief Contains the version of the Secure
ClientConnection m_clientConnection; // Socket currently active
ServerConnection m_serverConnection;
ClientConnection m_clientConnection;
void updateAutoConfigWidgets();
void updateWindowTitle();
void updateAutoConfigWidgets();
void updateWindowTitle();
private slots: private slots:
void on_m_pButtonApply_clicked(); void on_m_pButtonApply_clicked();
void on_windowShown(); void on_windowShown();
void on_m_pLabelComputerName_linkActivated(const QString &link); void on_m_pLabelComputerName_linkActivated(const QString &link);
void on_m_pLabelFingerprint_linkActivated(const QString& link); void on_m_pLabelFingerprint_linkActivated(const QString &link);
void on_m_pComboServerList_currentIndexChanged(const QString &arg1); void on_m_pComboServerList_currentIndexChanged(const QString &arg1);
void on_m_pButtonConnect_clicked(); void on_m_pButtonConnect_clicked();
void on_m_pButtonConnectToClient_clicked(); void on_m_pButtonConnectToClient_clicked();
signals: signals:
void windowShown(); void windowShown();
}; };

View file

@ -21,15 +21,11 @@
#include <QString> #include <QString>
enum class IconsTheme { enum class IconsTheme { ICONS_DARK, ICONS_LIGHT, ICONS_TEMPLATE };
ICONS_DARK,
ICONS_LIGHT,
ICONS_TEMPLATE
};
void requestOSXNotificationPermission(); void requestOSXNotificationPermission();
bool isOSXDevelopmentBuild(); bool isOSXDevelopmentBuild();
bool showOSXNotification(const QString& title, const QString& body); bool showOSXNotification(const QString &title, const QString &body);
bool isOSXInterfaceStyleDark(); bool isOSXInterfaceStyleDark();
IconsTheme getOSXIconsTheme(); IconsTheme getOSXIconsTheme();

View file

@ -18,11 +18,11 @@
#pragma once #pragma once
enum qProcessorArch { enum qProcessorArch {
kProcessorArchWin32, kProcessorArchWin32,
kProcessorArchWin64, kProcessorArchWin64,
kProcessorArchMac32, kProcessorArchMac32,
kProcessorArchMac64, kProcessorArchMac64,
kProcessorArchLinux32, kProcessorArchLinux32,
kProcessorArchLinux64, kProcessorArchLinux64,
kProcessorArchUnknown kProcessorArchUnknown
}; };

View file

@ -2,11 +2,11 @@
* synergy -- mouse and keyboard sharing utility * synergy -- mouse and keyboard sharing utility
* Copyright (C) 2012-2016 Symless Ltd. * Copyright (C) 2012-2016 Symless Ltd.
* Copyright (C) 2008 Volker Lanz (vl@fidra.de) * Copyright (C) 2008 Volker Lanz (vl@fidra.de)
* *
* This package is free software; you can redistribute it and/or * This package is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
* found in the file LICENSE that should have accompanied this file. * found in the file LICENSE that should have accompanied this file.
* *
* This package is distributed in the hope that it will be useful, * This package is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
@ -22,57 +22,44 @@
#include <QtCore> #include <QtCore>
#include <QtGui> #include <QtGui>
QSynergyApplication* QSynergyApplication::s_Instance = NULL; QSynergyApplication *QSynergyApplication::s_Instance = NULL;
QSynergyApplication::QSynergyApplication(int& argc, char** argv) : QSynergyApplication::QSynergyApplication(int &argc, char **argv)
QApplication(argc, argv), : QApplication(argc, argv), m_Translator(NULL) {
m_Translator(NULL) s_Instance = this;
{
s_Instance = this;
QFontDatabase::addApplicationFont(":/res/fonts/Arial.ttf"); QFontDatabase::addApplicationFont(":/res/fonts/Arial.ttf");
QFont Arial("Arial"); QFont Arial("Arial");
Arial.setPixelSize(13); Arial.setPixelSize(13);
Arial.setStyleHint(QFont::SansSerif); Arial.setStyleHint(QFont::SansSerif);
setFont(Arial); setFont(Arial);
} }
QSynergyApplication::~QSynergyApplication() QSynergyApplication::~QSynergyApplication() { delete m_Translator; }
{
void QSynergyApplication::commitData(QSessionManager &) {
foreach (QWidget *widget, topLevelWidgets()) {
MainWindow *mainWindow = qobject_cast<MainWindow *>(widget);
if (mainWindow)
mainWindow->saveSettings();
}
}
QSynergyApplication *QSynergyApplication::getInstance() { return s_Instance; }
void QSynergyApplication::switchTranslator(QString lang) {
if (m_Translator != NULL) {
removeTranslator(m_Translator);
delete m_Translator; delete m_Translator;
}
QResource locale(":/res/lang/gui_" + lang + ".qm");
m_Translator = new QTranslator();
m_Translator->load(locale.data(), locale.size());
installTranslator(m_Translator);
} }
void QSynergyApplication::commitData(QSessionManager&) void QSynergyApplication::setTranslator(QTranslator *translator) {
{ m_Translator = translator;
foreach(QWidget* widget, topLevelWidgets()) installTranslator(m_Translator);
{
MainWindow* mainWindow = qobject_cast<MainWindow*>(widget);
if (mainWindow)
mainWindow->saveSettings();
}
}
QSynergyApplication* QSynergyApplication::getInstance()
{
return s_Instance;
}
void QSynergyApplication::switchTranslator(QString lang)
{
if (m_Translator != NULL)
{
removeTranslator(m_Translator);
delete m_Translator;
}
QResource locale(":/res/lang/gui_" + lang + ".qm");
m_Translator = new QTranslator();
m_Translator->load(locale.data(), locale.size());
installTranslator(m_Translator);
}
void QSynergyApplication::setTranslator(QTranslator* translator)
{
m_Translator = translator;
installTranslator(m_Translator);
} }

View file

@ -2,11 +2,11 @@
* synergy -- mouse and keyboard sharing utility * synergy -- mouse and keyboard sharing utility
* Copyright (C) 2012-2016 Symless Ltd. * Copyright (C) 2012-2016 Symless Ltd.
* Copyright (C) 2008 Volker Lanz (vl@fidra.de) * Copyright (C) 2008 Volker Lanz (vl@fidra.de)
* *
* This package is free software; you can redistribute it and/or * This package is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
* found in the file LICENSE that should have accompanied this file. * found in the file LICENSE that should have accompanied this file.
* *
* This package is distributed in the hope that it will be useful, * This package is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
@ -24,24 +24,22 @@
class QSessionManager; class QSessionManager;
class QSynergyApplication : public QApplication class QSynergyApplication : public QApplication {
{ public:
public: QSynergyApplication(int &argc, char **argv);
QSynergyApplication(int& argc, char** argv); ~QSynergyApplication();
~QSynergyApplication();
public: public:
void commitData(QSessionManager& manager); void commitData(QSessionManager &manager);
void switchTranslator(QString lang); void switchTranslator(QString lang);
void setTranslator(QTranslator* translator); void setTranslator(QTranslator *translator);
static QSynergyApplication* getInstance(); static QSynergyApplication *getInstance();
private: private:
QTranslator* m_Translator; QTranslator *m_Translator;
static QSynergyApplication* s_Instance; static QSynergyApplication *s_Instance;
}; };
#endif #endif

View file

@ -17,12 +17,12 @@
#include "QUtility.h" #include "QUtility.h"
#include "ProcessorArch.h"
#include "CommandProcess.h" #include "CommandProcess.h"
#include "ProcessorArch.h"
#if defined(Q_OS_LINUX) #if defined(Q_OS_LINUX)
#include <QProcess>
#include <QFile> #include <QFile>
#include <QProcess>
#endif #endif
#if defined(Q_OS_WIN) #if defined(Q_OS_WIN)
@ -30,50 +30,45 @@
#include <Windows.h> #include <Windows.h>
#endif #endif
void setIndexFromItemData(QComboBox* comboBox, const QVariant& itemData) void setIndexFromItemData(QComboBox *comboBox, const QVariant &itemData) {
{ for (int i = 0; i < comboBox->count(); ++i) {
for (int i = 0; i < comboBox->count(); ++i) if (comboBox->itemData(i) == itemData) {
{ comboBox->setCurrentIndex(i);
if (comboBox->itemData(i) == itemData) return;
{
comboBox->setCurrentIndex(i);
return;
}
} }
}
} }
QString hash(const QString& string) QString hash(const QString &string) {
{ QByteArray data = string.toUtf8();
QByteArray data = string.toUtf8(); QByteArray hash = QCryptographicHash::hash(data, QCryptographicHash::Md5);
QByteArray hash = QCryptographicHash::hash(data, QCryptographicHash::Md5); return hash.toHex();
return hash.toHex();
} }
qProcessorArch getProcessorArch() qProcessorArch getProcessorArch() {
{
#if defined(Q_OS_WIN) #if defined(Q_OS_WIN)
SYSTEM_INFO systemInfo; SYSTEM_INFO systemInfo;
GetNativeSystemInfo(&systemInfo); GetNativeSystemInfo(&systemInfo);
switch (systemInfo.wProcessorArchitecture) { switch (systemInfo.wProcessorArchitecture) {
case PROCESSOR_ARCHITECTURE_INTEL: case PROCESSOR_ARCHITECTURE_INTEL:
return kProcessorArchWin32; return kProcessorArchWin32;
case PROCESSOR_ARCHITECTURE_IA64: case PROCESSOR_ARCHITECTURE_IA64:
return kProcessorArchWin64; return kProcessorArchWin64;
case PROCESSOR_ARCHITECTURE_AMD64: case PROCESSOR_ARCHITECTURE_AMD64:
return kProcessorArchWin64; return kProcessorArchWin64;
default: default:
return kProcessorArchUnknown; return kProcessorArchUnknown;
} }
#endif #endif
#if defined(Q_OS_LINUX) #if defined(Q_OS_LINUX)
#ifdef __i386__ #ifdef __i386__
return kProcessorArchLinux32; return kProcessorArchLinux32;
#else #else
return kProcessorArchLinux64; return kProcessorArchLinux64;
#endif #endif
#endif #endif
return kProcessorArchUnknown; return kProcessorArchUnknown;
} }

View file

@ -20,10 +20,10 @@
#include "ProcessorArch.h" #include "ProcessorArch.h"
#include <QComboBox> #include <QComboBox>
#include <QVariant>
#include <QCryptographicHash> #include <QCryptographicHash>
#include <QNetworkInterface> #include <QNetworkInterface>
#include <QVariant>
void setIndexFromItemData(QComboBox* comboBox, const QVariant& itemData); void setIndexFromItemData(QComboBox *comboBox, const QVariant &itemData);
QString hash(const QString& string); QString hash(const QString &string);
qProcessorArch getProcessorArch(); qProcessorArch getProcessorArch();

View file

@ -2,11 +2,11 @@
* synergy -- mouse and keyboard sharing utility * synergy -- mouse and keyboard sharing utility
* Copyright (C) 2012-2016 Symless Ltd. * Copyright (C) 2012-2016 Symless Ltd.
* Copyright (C) 2008 Volker Lanz (vl@fidra.de) * Copyright (C) 2008 Volker Lanz (vl@fidra.de)
* *
* This package is free software; you can redistribute it and/or * This package is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
* found in the file LICENSE that should have accompanied this file. * found in the file LICENSE that should have accompanied this file.
* *
* This package is distributed in the hope that it will be useful, * This package is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
@ -21,141 +21,124 @@
#include <QtCore> #include <QtCore>
#include <QtGui> #include <QtGui>
Screen::Screen() : Screen::Screen()
m_Pixmap(QPixmap(":res/icons/64x64/video-display.png")), : m_Pixmap(QPixmap(":res/icons/64x64/video-display.png")),
m_Swapped(false) m_Swapped(false) {
{ init();
init();
} }
Screen::Screen(const QString& name) : Screen::Screen(const QString &name)
m_Pixmap(QPixmap(":res/icons/64x64/video-display.png")), : m_Pixmap(QPixmap(":res/icons/64x64/video-display.png")),
m_Swapped(false) m_Swapped(false) {
{ init();
init(); setName(name);
setName(name);
} }
void Screen::init() void Screen::init() {
{ name().clear();
name().clear(); aliases().clear();
aliases().clear(); modifiers().clear();
modifiers().clear(); switchCorners().clear();
switchCorners().clear(); fixes().clear();
fixes().clear(); setSwitchCornerSize(0);
setSwitchCornerSize(0);
// m_Modifiers, m_SwitchCorners and m_Fixes are QLists we use like fixed-size arrays, // m_Modifiers, m_SwitchCorners and m_Fixes are QLists we use like fixed-size
// thus we need to make sure to fill them with the required number of elements. // arrays, thus we need to make sure to fill them with the required number of
for (int i = 0; i < NumModifiers; i++) // elements.
modifiers() << i; for (int i = 0; i < NumModifiers; i++)
modifiers() << i;
for (int i = 0; i < NumSwitchCorners; i++) for (int i = 0; i < NumSwitchCorners; i++)
switchCorners() << false; switchCorners() << false;
for (int i = 0; i < NumFixes; i++) for (int i = 0; i < NumFixes; i++)
fixes() << false; fixes() << false;
} }
void Screen::loadSettings(QSettings& settings) void Screen::loadSettings(QSettings &settings) {
{ setName(settings.value("name").toString());
setName(settings.value("name").toString());
if (name().isEmpty()) if (name().isEmpty())
return; return;
setSwitchCornerSize(settings.value("switchCornerSize").toInt()); setSwitchCornerSize(settings.value("switchCornerSize").toInt());
readSettings(settings, aliases(), "alias", QString("")); readSettings(settings, aliases(), "alias", QString(""));
readSettings(settings, modifiers(), "modifier", static_cast<int>(DefaultMod), NumModifiers); readSettings(settings, modifiers(), "modifier", static_cast<int>(DefaultMod),
readSettings(settings, switchCorners(), "switchCorner", false, NumSwitchCorners); NumModifiers);
readSettings(settings, fixes(), "fix", false, NumFixes); readSettings(settings, switchCorners(), "switchCorner", false,
NumSwitchCorners);
readSettings(settings, fixes(), "fix", false, NumFixes);
} }
void Screen::saveSettings(QSettings& settings) const void Screen::saveSettings(QSettings &settings) const {
{ settings.setValue("name", name());
settings.setValue("name", name());
if (name().isEmpty()) if (name().isEmpty())
return; return;
settings.setValue("switchCornerSize", switchCornerSize()); settings.setValue("switchCornerSize", switchCornerSize());
writeSettings(settings, aliases(), "alias"); writeSettings(settings, aliases(), "alias");
writeSettings(settings, modifiers(), "modifier"); writeSettings(settings, modifiers(), "modifier");
writeSettings(settings, switchCorners(), "switchCorner"); writeSettings(settings, switchCorners(), "switchCorner");
writeSettings(settings, fixes(), "fix"); writeSettings(settings, fixes(), "fix");
} }
QTextStream& Screen::writeScreensSection(QTextStream& outStream) const QTextStream &Screen::writeScreensSection(QTextStream &outStream) const {
{ outStream << "\t" << name() << ":" << endl;
for (int i = 0; i < modifiers().size(); i++)
if (modifier(i) != i)
outStream << "\t\t" << modifierName(i) << " = "
<< modifierName(modifier(i)) << endl;
for (int i = 0; i < fixes().size(); i++)
outStream << "\t\t" << fixName(i) << " = "
<< (fixes()[i] ? "true" : "false") << endl;
outStream << "\t\t"
<< "switchCorners = none ";
for (int i = 0; i < switchCorners().size(); i++)
if (switchCorners()[i])
outStream << "+" << switchCornerName(i) << " ";
outStream << endl;
outStream << "\t\t"
<< "switchCornerSize = " << switchCornerSize() << endl;
return outStream;
}
QTextStream &Screen::writeAliasesSection(QTextStream &outStream) const {
if (!aliases().isEmpty()) {
outStream << "\t" << name() << ":" << endl; outStream << "\t" << name() << ":" << endl;
for (int i = 0; i < modifiers().size(); i++) foreach (const QString &alias, aliases())
if (modifier(i) != i) outStream << "\t\t" << alias << endl;
outStream << "\t\t" << modifierName(i) << " = " << modifierName(modifier(i)) << endl; }
for (int i = 0; i < fixes().size(); i++) return outStream;
outStream << "\t\t" << fixName(i) << " = " << (fixes()[i] ? "true" : "false") << endl;
outStream << "\t\t" << "switchCorners = none ";
for (int i = 0; i < switchCorners().size(); i++)
if (switchCorners()[i])
outStream << "+" << switchCornerName(i) << " ";
outStream << endl;
outStream << "\t\t" << "switchCornerSize = " << switchCornerSize() << endl;
return outStream;
} }
QTextStream& Screen::writeAliasesSection(QTextStream& outStream) const bool Screen::operator==(const Screen &screen) const {
{ return m_Name == screen.m_Name && m_Aliases == screen.m_Aliases &&
if (!aliases().isEmpty()) m_Modifiers == screen.m_Modifiers &&
{ m_SwitchCorners == screen.m_SwitchCorners &&
outStream << "\t" << name() << ":" << endl; m_SwitchCornerSize == screen.m_SwitchCornerSize &&
m_Fixes == screen.m_Fixes && m_Swapped == screen.m_Swapped &&
foreach (const QString& alias, aliases()) m_isServer == screen.m_isServer;
outStream << "\t\t" << alias << endl;
}
return outStream;
} }
bool Screen::operator==(const Screen& screen) const QDataStream &operator<<(QDataStream &outStream, const Screen &screen) {
{ return outStream << screen.name() << screen.switchCornerSize()
return m_Name == screen.m_Name && << screen.aliases() << screen.modifiers()
m_Aliases == screen.m_Aliases && << screen.switchCorners() << screen.fixes()
m_Modifiers == screen.m_Modifiers && << screen.isServer();
m_SwitchCorners == screen.m_SwitchCorners &&
m_SwitchCornerSize == screen.m_SwitchCornerSize &&
m_Fixes == screen.m_Fixes &&
m_Swapped == screen.m_Swapped &&
m_isServer == screen.m_isServer;
} }
QDataStream& operator<<(QDataStream& outStream, const Screen& screen) QDataStream &operator>>(QDataStream &inStream, Screen &screen) {
{ return inStream >> screen.m_Name >> screen.m_SwitchCornerSize >>
return outStream screen.m_Aliases >> screen.m_Modifiers >> screen.m_SwitchCorners >>
<< screen.name() screen.m_Fixes >> screen.m_isServer;
<< screen.switchCornerSize()
<< screen.aliases()
<< screen.modifiers()
<< screen.switchCorners()
<< screen.fixes()
<< screen.isServer()
;
}
QDataStream& operator>>(QDataStream& inStream, Screen& screen)
{
return inStream
>> screen.m_Name
>> screen.m_SwitchCornerSize
>> screen.m_Aliases
>> screen.m_Modifiers
>> screen.m_SwitchCorners
>> screen.m_Fixes
>> screen.m_isServer
;
} }

View file

@ -2,11 +2,11 @@
* synergy -- mouse and keyboard sharing utility * synergy -- mouse and keyboard sharing utility
* Copyright (C) 2012-2016 Symless Ltd. * Copyright (C) 2012-2016 Symless Ltd.
* Copyright (C) 2008 Volker Lanz (vl@fidra.de) * Copyright (C) 2008 Volker Lanz (vl@fidra.de)
* *
* This package is free software; you can redistribute it and/or * This package is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
* found in the file LICENSE that should have accompanied this file. * found in the file LICENSE that should have accompanied this file.
* *
* This package is distributed in the hope that it will be useful, * This package is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
@ -20,9 +20,9 @@
#define SCREEN__H #define SCREEN__H
#include <QList>
#include <QPixmap> #include <QPixmap>
#include <QString> #include <QString>
#include <QList>
#include <QStringList> #include <QStringList>
#include "BaseConfig.h" #include "BaseConfig.h"
@ -32,75 +32,75 @@ class QTextStream;
class ScreenSettingsDialog; class ScreenSettingsDialog;
class Screen : public BaseConfig class Screen : public BaseConfig {
{ friend QDataStream &operator<<(QDataStream &outStream, const Screen &screen);
friend QDataStream& operator<<(QDataStream& outStream, const Screen& screen); friend QDataStream &operator>>(QDataStream &inStream, Screen &screen);
friend QDataStream& operator>>(QDataStream& inStream, Screen& screen); friend class ScreenSettingsDialog;
friend class ScreenSettingsDialog; friend class ScreenSetupModel;
friend class ScreenSetupModel; friend class ScreenSetupView;
friend class ScreenSetupView;
public: public:
Screen(); Screen();
Screen(const QString& name); Screen(const QString &name);
public: public:
const QPixmap& pixmap() const { return m_Pixmap; } const QPixmap &pixmap() const { return m_Pixmap; }
const QString& name() const { return m_Name; } const QString &name() const { return m_Name; }
const QStringList& aliases() const { return m_Aliases; } const QStringList &aliases() const { return m_Aliases; }
bool isNull() const { return m_Name.isEmpty(); } bool isNull() const { return m_Name.isEmpty(); }
int modifier(int m) const { return m_Modifiers[m] == DefaultMod ? m : m_Modifiers[m]; } int modifier(int m) const {
const QList<int>& modifiers() const { return m_Modifiers; } return m_Modifiers[m] == DefaultMod ? m : m_Modifiers[m];
bool switchCorner(int c) const { return m_SwitchCorners[c]; } }
const QList<bool>& switchCorners() const { return m_SwitchCorners; } const QList<int> &modifiers() const { return m_Modifiers; }
int switchCornerSize() const { return m_SwitchCornerSize; } bool switchCorner(int c) const { return m_SwitchCorners[c]; }
bool fix(Fix f) const { return m_Fixes[f]; } const QList<bool> &switchCorners() const { return m_SwitchCorners; }
const QList<bool>& fixes() const { return m_Fixes; } int switchCornerSize() const { return m_SwitchCornerSize; }
bool fix(Fix f) const { return m_Fixes[f]; }
const QList<bool> &fixes() const { return m_Fixes; }
void loadSettings(QSettings& settings); void loadSettings(QSettings &settings);
void saveSettings(QSettings& settings) const; void saveSettings(QSettings &settings) const;
QTextStream& writeScreensSection(QTextStream& outStream) const; QTextStream &writeScreensSection(QTextStream &outStream) const;
QTextStream& writeAliasesSection(QTextStream& outStream) const; QTextStream &writeAliasesSection(QTextStream &outStream) const;
bool swapped() const { return m_Swapped; } bool swapped() const { return m_Swapped; }
QString& name() { return m_Name; } QString &name() { return m_Name; }
void setName(const QString& name) { m_Name = name; } void setName(const QString &name) { m_Name = name; }
bool isServer() const { return m_isServer;} bool isServer() const { return m_isServer; }
void markAsServer() { m_isServer = true; } void markAsServer() { m_isServer = true; }
bool operator==(const Screen& screen) const; bool operator==(const Screen &screen) const;
protected: protected:
void init(); void init();
QStringList& aliases() { return m_Aliases; } QStringList &aliases() { return m_Aliases; }
void setModifier(int m, int n) { m_Modifiers[m] = n; } void setModifier(int m, int n) { m_Modifiers[m] = n; }
QList<int>& modifiers() { return m_Modifiers; } QList<int> &modifiers() { return m_Modifiers; }
void addAlias(const QString& alias) { m_Aliases.append(alias); } void addAlias(const QString &alias) { m_Aliases.append(alias); }
void setSwitchCorner(int c, bool on) { m_SwitchCorners[c] = on; } void setSwitchCorner(int c, bool on) { m_SwitchCorners[c] = on; }
QList<bool>& switchCorners() { return m_SwitchCorners; } QList<bool> &switchCorners() { return m_SwitchCorners; }
void setSwitchCornerSize(int val) { m_SwitchCornerSize = val; } void setSwitchCornerSize(int val) { m_SwitchCornerSize = val; }
void setFix(int f, bool on) { m_Fixes[f] = on; } void setFix(int f, bool on) { m_Fixes[f] = on; }
QList<bool>& fixes() { return m_Fixes; } QList<bool> &fixes() { return m_Fixes; }
void setSwapped(bool on) { m_Swapped = on; } void setSwapped(bool on) { m_Swapped = on; }
private: private:
QPixmap m_Pixmap; QPixmap m_Pixmap;
QString m_Name; QString m_Name;
QStringList m_Aliases; QStringList m_Aliases;
QList<int> m_Modifiers; QList<int> m_Modifiers;
QList<bool> m_SwitchCorners; QList<bool> m_SwitchCorners;
int m_SwitchCornerSize; int m_SwitchCornerSize;
QList<bool> m_Fixes; QList<bool> m_Fixes;
bool m_Swapped; bool m_Swapped;
bool m_isServer = false; bool m_isServer = false;
}; };
QDataStream& operator<<(QDataStream& outStream, const Screen& screen); QDataStream &operator<<(QDataStream &outStream, const Screen &screen);
QDataStream& operator>>(QDataStream& inStream, Screen& screen); QDataStream &operator>>(QDataStream &inStream, Screen &screen);
#endif #endif

View file

@ -28,33 +28,42 @@ namespace {
* @param size of the grid * @param size of the grid
* @return indexes for server neighbors * @return indexes for server neighbors
*/ */
std::array<int, 8> getNeighborsIndexes(int serverIndex, int width, int size) std::array<int, 8> getNeighborsIndexes(int serverIndex, int width, int size) {
{ const int UNSET = -1;
const int UNSET = -1; const int LEFT = 0;
const int LEFT = 0; const int RIGHT = 1;
const int RIGHT = 1; const int TOP = 2;
const int TOP = 2; const int BOTTOM = 3;
const int BOTTOM = 3; const int TOP_LEFT = 4;
const int TOP_LEFT = 4; const int TOP_RIGHT = 5;
const int TOP_RIGHT = 5; const int BOTTOM_RIGHT = 6;
const int BOTTOM_RIGHT = 6; const int BOTTOM_LEFT = 7;
const int BOTTOM_LEFT = 7;
std::array<int, 8> indexes = { UNSET }; std::array<int, 8> indexes = {UNSET};
if (serverIndex >= 0 && serverIndex < size) if (serverIndex >= 0 && serverIndex < size) {
{ indexes[LEFT] =
indexes[LEFT] = (serverIndex - 1) % width != width - 1 ? (serverIndex - 1) : UNSET; (serverIndex - 1) % width != width - 1 ? (serverIndex - 1) : UNSET;
indexes[RIGHT] = (serverIndex + 1) % width != 0 ? (serverIndex + 1) : UNSET; indexes[RIGHT] = (serverIndex + 1) % width != 0 ? (serverIndex + 1) : UNSET;
indexes[TOP] = (serverIndex - width) >= 0 ? (serverIndex - width) : UNSET; indexes[TOP] = (serverIndex - width) >= 0 ? (serverIndex - width) : UNSET;
indexes[BOTTOM] = (serverIndex + width) < size ? (serverIndex + width) : UNSET; indexes[BOTTOM] =
indexes[TOP_LEFT] = (indexes[TOP] != UNSET && indexes[LEFT] != UNSET) ? indexes[TOP] - 1 : UNSET; (serverIndex + width) < size ? (serverIndex + width) : UNSET;
indexes[TOP_RIGHT] = (indexes[TOP] != UNSET && indexes[RIGHT] != UNSET) ? indexes[TOP] + 1 : UNSET; indexes[TOP_LEFT] = (indexes[TOP] != UNSET && indexes[LEFT] != UNSET)
indexes[BOTTOM_RIGHT] = (indexes[BOTTOM] != UNSET && indexes[RIGHT] != UNSET) ? indexes[BOTTOM] + 1 : UNSET; ? indexes[TOP] - 1
indexes[BOTTOM_LEFT] = (indexes[BOTTOM] != UNSET && indexes[LEFT] != UNSET) ? indexes[BOTTOM] - 1 : UNSET; : UNSET;
} indexes[TOP_RIGHT] = (indexes[TOP] != UNSET && indexes[RIGHT] != UNSET)
? indexes[TOP] + 1
: UNSET;
indexes[BOTTOM_RIGHT] =
(indexes[BOTTOM] != UNSET && indexes[RIGHT] != UNSET)
? indexes[BOTTOM] + 1
: UNSET;
indexes[BOTTOM_LEFT] = (indexes[BOTTOM] != UNSET && indexes[LEFT] != UNSET)
? indexes[BOTTOM] - 1
: UNSET;
}
return indexes; return indexes;
} }
/** /**
@ -62,71 +71,54 @@ std::array<int, 8> getNeighborsIndexes(int serverIndex, int width, int size)
* @param screens list to find server * @param screens list to find server
* @return server index * @return server index
*/ */
int getServerIndex(const ScreenList& screens) int getServerIndex(const ScreenList &screens) {
{ int serverIndex = -1;
int serverIndex = -1;
for (int i = 0; i < screens.size(); ++i) for (int i = 0; i < screens.size(); ++i) {
{ if (screens[i].isServer()) {
if (screens[i].isServer()){ serverIndex = i;
serverIndex = i; break;
break;
}
} }
}
return serverIndex; return serverIndex;
} }
} //namespace } // namespace
ScreenList::ScreenList(int width) : ScreenList::ScreenList(int width) : QList<Screen>(), m_width(width) {}
QList<Screen>(),
m_width(width)
{
} void ScreenList::addScreenByPriority(const Screen &newScreen) {
int serverIndex = getServerIndex(*this);
auto indexes = getNeighborsIndexes(serverIndex, m_width, size());
void ScreenList::addScreenByPriority(const Screen& newScreen) bool isAdded = false;
{ for (const auto &index : indexes) {
int serverIndex = getServerIndex(*this); if (index >= 0 && index < size()) {
auto indexes = getNeighborsIndexes(serverIndex, m_width, size()); auto &screen = operator[](index);
if (screen.isNull()) {
bool isAdded = false; screen = newScreen;
for (const auto& index : indexes) isAdded = true;
{ break;
if (index >= 0 && index < size()) }
{
auto& screen = operator[](index);
if (screen.isNull())
{
screen = newScreen;
isAdded = true;
break;
}
}
} }
}
if (!isAdded) if (!isAdded) {
{ addScreenToFirstEmpty(newScreen);
addScreenToFirstEmpty(newScreen); }
}
void ScreenList::addScreenToFirstEmpty(const Screen &newScreen) {
for (int i = 0; i < size(); ++i) {
auto &screen = operator[](i);
if (screen.isNull()) {
screen = newScreen;
break;
} }
}
} }
void ScreenList::addScreenToFirstEmpty(const Screen& newScreen) bool ScreenList::operator==(const ScreenList &sc) const {
{ return m_width == sc.m_width && QList::operator==(sc);
for (int i = 0; i < size(); ++i)
{
auto& screen = operator[](i);
if (screen.isNull())
{
screen = newScreen;
break;
}
}
} }
bool ScreenList::operator==(const ScreenList& sc) const
{
return m_width == sc.m_width && QList::operator==(sc);
}

View file

@ -20,39 +20,36 @@
#include "Screen.h" #include "Screen.h"
class ScreenList : public QList<Screen> class ScreenList : public QList<Screen> {
{ int m_width = 5;
int m_width = 5;
public: public:
explicit ScreenList(int width = 5); explicit ScreenList(int width = 5);
/** /**
* @brief addScreenByPriority adds a new screen according to the following priority: * @brief addScreenByPriority adds a new screen according to the following
* 1.left side of the server * priority: 1.left side of the server 2.right side of the server 3.top 4.down
* 2.right side of the server * 5.top left-hand diagonally
* 3.top * 6.top right-hand diagonally
* 4.down * 7.bottom right-hand diagonally
* 5.top left-hand diagonally * 8.bottom left-hand diagonally
* 6.top right-hand diagonally * 9.In case all places from the list have already booked, place in any spare
* 7.bottom right-hand diagonally * place
* 8.bottom left-hand diagonally * @param newScreen
* 9.In case all places from the list have already booked, place in any spare place */
* @param newScreen void addScreenByPriority(const Screen &newScreen);
*/
void addScreenByPriority(const Screen& newScreen);
/** /**
* @brief addScreenToFirstEmpty adds screen into the first empty place * @brief addScreenToFirstEmpty adds screen into the first empty place
* @param newScreen * @param newScreen
*/ */
void addScreenToFirstEmpty(const Screen& newScreen); void addScreenToFirstEmpty(const Screen &newScreen);
/** /**
* @brief Returns true if screens are equal * @brief Returns true if screens are equal
* @param sc * @param sc
*/ */
bool operator==(const ScreenList& sc) const; bool operator==(const ScreenList &sc) const;
}; };
#endif // SCREENLIST_H #endif // SCREENLIST_H

Some files were not shown because too many files have changed in this diff Show more