diff --git a/src/gui/src/Screen.cpp b/src/gui/src/Screen.cpp index 3ec07caa6..c24129c92 100644 --- a/src/gui/src/Screen.cpp +++ b/src/gui/src/Screen.cpp @@ -131,6 +131,7 @@ QDataStream& operator<<(QDataStream& outStream, const Screen& screen) << screen.modifiers() << screen.switchCorners() << screen.fixes() + << screen.isServer() ; } @@ -143,5 +144,6 @@ QDataStream& operator>>(QDataStream& inStream, Screen& screen) >> screen.m_Modifiers >> screen.m_SwitchCorners >> screen.m_Fixes + >> screen.m_isServer ; } diff --git a/src/gui/src/Screen.h b/src/gui/src/Screen.h index 31bf42aba..a24159a4a 100644 --- a/src/gui/src/Screen.h +++ b/src/gui/src/Screen.h @@ -99,8 +99,6 @@ class Screen : public BaseConfig bool m_isServer = false; }; -typedef QList ScreenList; - QDataStream& operator<<(QDataStream& outStream, const Screen& screen); QDataStream& operator>>(QDataStream& inStream, Screen& screen); diff --git a/src/gui/src/ScreenList.cpp b/src/gui/src/ScreenList.cpp new file mode 100644 index 000000000..247f8481f --- /dev/null +++ b/src/gui/src/ScreenList.cpp @@ -0,0 +1,118 @@ +/* + * synergy -- mouse and keyboard sharing utility + * Copyright (C) 2012-2021 Symless Ltd. + * Copyright (C) 2008 Volker Lanz (vl@fidra.de) + * + * This package is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * found in the file LICENSE that should have accompanied this file. + * + * This package is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#include "ScreenList.h" + +#include + +namespace { + +/** + * @brief getNeightborIndexes returns indexes for server neighbors + * @param serverIndex server index + * @param width of the grid + * @param size of the grid + * @return indexes for server neighbors + */ +std::array getNeighborsIndexes(int serverIndex, int width, int size) +{ + enum{kLEFT, kRIGHT, kTOP, kBOTTOM, kTOP_LEFT, kTOP_RIGHT, kBOTTOM_RIGHT, kBOTTOM_LEFT}; + std::array indexes = { -1 }; + + if (serverIndex >= 0 && serverIndex < size) + { + indexes[kLEFT] = (serverIndex - 1) % width != width - 1 ? (serverIndex - 1) : -1;; + indexes[kRIGHT] = (serverIndex + 1) % width != 0 ? (serverIndex + 1) : -1; + indexes[kTOP] = (serverIndex - width) >= 0 ? (serverIndex - width) : -1; + indexes[kBOTTOM] = (serverIndex + width) < size ? (serverIndex + width) : -1; + indexes[kTOP_LEFT] = (indexes[kTOP] != - 1 && indexes[kLEFT] != -1) ? indexes[kTOP] - 1 : -1; + indexes[kTOP_RIGHT] = (indexes[kTOP] != -1 && indexes[kRIGHT] != -1) ? indexes[kTOP] + 1 : -1;; + indexes[kBOTTOM_RIGHT] = (indexes[kBOTTOM] != -1 && indexes[kRIGHT] != -1) ? indexes[kBOTTOM] + 1 : -1;; + indexes[kBOTTOM_LEFT] = (indexes[kBOTTOM] != -1 && indexes[kLEFT] != -1) ? indexes[kBOTTOM] - 1 : -1;; + } + + return indexes; +} + +/** + * @brief getServerIndex finds server and returns it's index + * @param screens list to find server + * @return server index + */ +int getServerIndex(const ScreenList& screens) +{ + int serverIndex = -1; + + for (int i = 0; i < screens.size(); ++i) + { + if (screens[i].isServer()){ + serverIndex = i; + break; + } + } + + return serverIndex; +} + +} //namespace + +ScreenList::ScreenList(int width) : + QList(), + m_width(width) +{ + +} + +void ScreenList::addScreenByPriority(const Screen& newScreen) +{ + int serverIndex = getServerIndex(*this); + auto indexes = getNeighborsIndexes(serverIndex, m_width, size()); + + bool isAdded = false; + for (const auto& index : indexes) + { + if (index >= 0 && index < size()) + { + auto& screen = operator[](index); + if (screen.isNull()) + { + screen = newScreen; + isAdded = true; + break; + } + } + } + + if (!isAdded) + { + 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; + } + } +} + diff --git a/src/gui/src/ScreenList.h b/src/gui/src/ScreenList.h new file mode 100644 index 000000000..bfc93b77d --- /dev/null +++ b/src/gui/src/ScreenList.h @@ -0,0 +1,52 @@ +/* + * synergy -- mouse and keyboard sharing utility + * Copyright (C) 2012-2021 Symless Ltd. + * Copyright (C) 2008 Volker Lanz (vl@fidra.de) + * + * This package is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * found in the file LICENSE that should have accompanied this file. + * + * This package is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#ifndef SCREENLIST_H +#define SCREENLIST_H + +#include "Screen.h" + +class ScreenList : public QList +{ + int m_width = 5; + +public: + explicit ScreenList(int width = 5); + + /** + * @brief addScreenByPriority adds a new screen according to the following priority: + * 1.left side of the server + * 2.right side of the server + * 3.top + * 4.down + * 5.top left-hand diagonally + * 6.top right-hand diagonally + * 7.bottom right-hand diagonally + * 8.bottom left-hand diagonally + * 9.In case all places from the list have already booked, place in any spare place + * @param newScreen + */ + void addScreenByPriority(const Screen& newScreen); + + /** + * @brief addScreenToFirstEmpty adds screen into the first empty place + * @param newScreen + */ + void addScreenToFirstEmpty(const Screen& newScreen); +}; + +#endif // SCREENLIST_H diff --git a/src/gui/src/ScreenSettingsDialog.h b/src/gui/src/ScreenSettingsDialog.h index ff0eb7beb..97232bde5 100644 --- a/src/gui/src/ScreenSettingsDialog.h +++ b/src/gui/src/ScreenSettingsDialog.h @@ -29,7 +29,7 @@ class QWidget; class QString; class Screen; -using ScreenList = QList; +class ScreenList; class ScreenSettingsDialog : public QDialog, public Ui::ScreenSettingsDialogBase { diff --git a/src/gui/src/ScreenSetupModel.cpp b/src/gui/src/ScreenSetupModel.cpp index a622436fe..9c2c280e8 100644 --- a/src/gui/src/ScreenSetupModel.cpp +++ b/src/gui/src/ScreenSetupModel.cpp @@ -143,13 +143,7 @@ bool ScreenSetupModel::dropMimeData(const QMimeData* data, Qt::DropAction action void ScreenSetupModel::addScreen(const Screen& newScreen) { - auto screenTest = std::find_if(m_Screens.begin(), m_Screens.end(), - [](const Screen& item) { return item.isNull(); }); - - if (screenTest != m_Screens.end()) - { - (*screenTest) = newScreen; - } + m_Screens.addScreenByPriority(newScreen); } bool ScreenSetupModel::isFull() const diff --git a/src/gui/src/ScreenSetupModel.h b/src/gui/src/ScreenSetupModel.h index 2bf5f3191..fee18cd4a 100644 --- a/src/gui/src/ScreenSetupModel.h +++ b/src/gui/src/ScreenSetupModel.h @@ -25,7 +25,7 @@ #include #include -#include "Screen.h" +#include "ScreenList.h" class ScreenSetupView; class ServerConfigDialog; diff --git a/src/gui/src/ServerConfig.cpp b/src/gui/src/ServerConfig.cpp index 652118d32..c98668286 100644 --- a/src/gui/src/ServerConfig.cpp +++ b/src/gui/src/ServerConfig.cpp @@ -44,7 +44,7 @@ const int serverDefaultIndex = 7; ServerConfig::ServerConfig(int numColumns, int numRows, AppConfig* appConfig, MainWindow* mainWindow) : - m_Screens(), + m_Screens(numColumns), m_NumColumns(numColumns), m_NumRows(numRows), m_pAppConfig(appConfig), @@ -429,6 +429,11 @@ bool ServerConfig::isScreenExists(const QString& screenName) const return isExists; } +void ServerConfig::addClient(const QString& clientName) +{ + m_Screens.addScreenByPriority(clientName); +} + void ServerConfig::setConfigFile(const QString& configFile) { m_pAppConfig->setConfigFile(configFile); diff --git a/src/gui/src/ServerConfig.h b/src/gui/src/ServerConfig.h index ea8614a5a..e69bda220 100644 --- a/src/gui/src/ServerConfig.h +++ b/src/gui/src/ServerConfig.h @@ -22,7 +22,7 @@ #include -#include "Screen.h" +#include "ScreenList.h" #include "BaseConfig.h" #include "Hotkey.h" #include "ConfigBase.h" @@ -86,6 +86,7 @@ class ServerConfig : public BaseConfig, public GUI::Config::ConfigBase bool getUseExternalConfig() const; bool isFull() const; bool isScreenExists(const QString& screenName) const; + void addClient(const QString& clientName); protected: QSettings& settings(); diff --git a/src/gui/src/ServerConnection.cpp b/src/gui/src/ServerConnection.cpp index 878c6c9f7..e82596102 100644 --- a/src/gui/src/ServerConnection.cpp +++ b/src/gui/src/ServerConnection.cpp @@ -82,7 +82,7 @@ void ServerConnection::addClient(const QString& clientName) void ServerConnection::configureClient(const QString& clientName) { auto& config = m_parent.serverConfig(); - config.addToFirstEmptyGrid(clientName); + config.addClient(clientName); ServerConfigDialog dlg(&m_parent, config); dlg.exec(); diff --git a/src/gui/src/validators/ScreenDuplicationsValidator.h b/src/gui/src/validators/ScreenDuplicationsValidator.h index 48deec244..a97d832fc 100644 --- a/src/gui/src/validators/ScreenDuplicationsValidator.h +++ b/src/gui/src/validators/ScreenDuplicationsValidator.h @@ -18,7 +18,7 @@ #ifndef SCREENDUPLICATIONSVALIDATOR_H #define SCREENDUPLICATIONSVALIDATOR_H -#include "Screen.h" +#include "ScreenList.h" #include "IStringValidator.h" namespace validators diff --git a/src/gui/src/validators/ScreenNameValidator.h b/src/gui/src/validators/ScreenNameValidator.h index bebe1284a..1a602a69e 100644 --- a/src/gui/src/validators/ScreenNameValidator.h +++ b/src/gui/src/validators/ScreenNameValidator.h @@ -18,7 +18,7 @@ #ifndef SCREENNAMEVALIDATOR_H #define SCREENNAMEVALIDATOR_H -#include "Screen.h" +#include "ScreenList.h" #include "LineEditValidator.h" namespace validators