diff options
Diffstat (limited to 'src/server/mainwindow')
-rw-r--r-- | src/server/mainwindow/mainwindow.cpp | 237 | ||||
-rw-r--r-- | src/server/mainwindow/mainwindow.h | 53 | ||||
-rw-r--r-- | src/server/mainwindow/mainwindow.ui | 339 |
3 files changed, 474 insertions, 155 deletions
diff --git a/src/server/mainwindow/mainwindow.cpp b/src/server/mainwindow/mainwindow.cpp index f6ff566..e8247d0 100644 --- a/src/server/mainwindow/mainwindow.cpp +++ b/src/server/mainwindow/mainwindow.cpp @@ -16,11 +16,13 @@ // Self #include "mainwindow.h" // QT stuff -#include <QtWidgets> -#include <QFileDialog> #include <QSvgRenderer> #include <QPainter> #include <QImage> +#include <QMessageBox> +#include <QCloseEvent> +#include <QDialogButtonBox> +#include <QScreen> // Other custom UI elements #include "../serverapp/serverapp.h" #include "../clicklabel/clicklabel.h" @@ -32,16 +34,11 @@ #include "../net/listenserver.h" #include "../net/client.h" #include "../net/discoverylistener.h" -#include "../net/filedownloader.h" // Others #include "../../shared/settings.h" #include "../util/platform/screensaver.h" // Auto-generated ui class #include "ui_mainwindow.h" -#include "ui_reloadroom.h" - -#include <iostream> -#include <vector> #define sStrTutorNdef MainWindow::tr("No tutor defined.") #define sStrTutorOffline MainWindow::tr("Tutor is offline.") @@ -50,33 +47,24 @@ #define sStrDestNdef MainWindow::tr("Please select a projection destination.") #define sStrDestOffline MainWindow::tr("The projection destination is offline.") #define sStrSourceDestSame MainWindow::tr("Selected projection target is tutor.") -#define sStrClientOnline MainWindow::tr("Selected client is currently online.") #define sStrNoDestAv MainWindow::tr("No projection destination available.") -using std::vector; -using std::cout; -using std::endl; - /** * Initialize MainWindow and ListenServer. * @param ipListUrl * @param parent */ -MainWindow::MainWindow(QWidget* parent) : - QMainWindow(parent), ui(new Ui::MainWindow), _tbIconSize(24), _tbArea(Qt::LeftToolBarArea), - _lastClientCount(0) +MainWindow::MainWindow(QWidget* parent) + : QMainWindow(parent) + , ui(new Ui::MainWindow) + , _mode(Mode::Multicast) { qDebug() << "MainWindow(parent)"; - _mode = Mode::Multicast; - _streamingSource = 0; /* default value, these will be updated a room is loaded */ _tilesX = 10; _tilesY = 10; - _virtCols = 0; - _virtRows = 0; - _sessionNameWindow = new SessionNameWindow(this); _reloadWindow = new ReloadRoomWindow(this); _reloadWindow->setWindowTitle(tr("Reload Room")); @@ -114,26 +102,26 @@ MainWindow::MainWindow(QWidget* parent) : serverApp->setExam(false); // Close button in tool bar - connect(ui->action_Exit, SIGNAL(triggered()), this, SLOT(onButtonExit())); - connect(ui->action_TutorToAll, SIGNAL(triggered()), this, SLOT(onButtonTutorToAll())); - connect(ui->action_StudentToTutor, SIGNAL(triggered()), this, SLOT(onButtonStudentToTutor())); - connect(ui->action_StudentToTutorExclusive, SIGNAL(triggered()), this, SLOT(onButtonStudentToTutorExclusive())); - connect(ui->action_TutorToStudent, SIGNAL(triggered()), this, SLOT(onButtonTutorToStudent())); - connect(ui->action_StopProjection, SIGNAL(triggered()), this, SLOT(onButtonStopProjection())); - connect(ui->action_SetAsTutor, SIGNAL(triggered()), this, SLOT(onButtonSetAsTutor())); - connect(ui->action_SetAsTutor, SIGNAL(triggered()), this, SLOT(onButtonStopProjection())); - connect(ui->action_Lock, SIGNAL(toggled(bool)), this, SLOT(onButtonLock(bool))); - connect(ui->action_LockSingle, SIGNAL(triggered()), this, SLOT(onButtonLockSingle())); - connect(ui->action_Help, SIGNAL(triggered()), this, SLOT(onButtonHelp())); - connect(ui->actionReload_Room_Configuration, SIGNAL(triggered()), this, SLOT(onButtonReloadRoomConfig())); - connect(ui->action_DeleteClient, SIGNAL(triggered()), this, SLOT(onDeleteClient())); + connect(ui->action_Exit, &QAction::triggered, this, &MainWindow::onButtonExit); + connect(ui->action_TutorToAll, &QAction::triggered, this, &MainWindow::onButtonTutorToAll); + connect(ui->action_StudentToTutor, &QAction::triggered, this, &MainWindow::onButtonStudentToTutor); + connect(ui->action_StudentToTutorExclusive, &QAction::triggered, this, &MainWindow::onButtonStudentToTutorExclusive); + connect(ui->action_TutorToStudent, &QAction::triggered, this, &MainWindow::onButtonTutorToStudent); + connect(ui->action_StopProjection, &QAction::triggered, this, &MainWindow::onButtonStopProjection); + connect(ui->action_SetAsTutor, &QAction::triggered, this, &MainWindow::onButtonSetAsTutor); + connect(ui->action_SetAsTutor, &QAction::triggered, this, &MainWindow::onButtonStopProjection); + connect(ui->action_Lock, &QAction::toggled, this, &MainWindow::onButtonLock); + connect(ui->action_LockSingle, &QAction::triggered, this, &MainWindow::onButtonLockSingle); + connect(ui->action_Help, &QAction::triggered, this, &MainWindow::onButtonHelp); + connect(ui->actionReload_Room_Configuration, &QAction::triggered, this, &MainWindow::onButtonReloadRoomConfig); + connect(ui->action_DeleteClient, &QAction::triggered, this, &MainWindow::onDeleteClient); /* Stuff for the button lock */ //Setup a timeout _buttonLockTimer = new QTimer(this); _buttonLockTimer->setSingleShot(true); _buttonLockTimer->setInterval(BUTTON_BLOCK_TIME); - connect(_buttonLockTimer, SIGNAL(timeout()), this, SLOT(enableButtons())); + connect(_buttonLockTimer, &QTimer::timeout, this, &MainWindow::enableButtons); // Define the locking buttons _lockingButtons << ui->action_DeleteClient @@ -147,18 +135,18 @@ MainWindow::MainWindow(QWidget* parent) : << ui->action_StopProjection; // Clicking the session name label shows the edit field for it - connect(_sessionNameLabel, SIGNAL(clicked()), this, SLOT(onSessionNameClick())); + connect(_sessionNameLabel, &ClickLabel::clicked, this, &MainWindow::onSessionNameClick); // Listen to updates to the session name through the session name window - connect(_sessionNameWindow, SIGNAL(updateSessionName()), this, - SLOT(onSessionNameUpdate())); + connect(_sessionNameWindow, &SessionNameWindow::updateSessionName, + this, &MainWindow::onSessionNameUpdate); setAttribute(Qt::WA_QuitOnClose); setUnifiedTitleAndToolBarOnMac(true); this->showMaximized(); // show the Mainwindow maximized - _listenServer = new ListenServer(CLIENT_PORT); - connect(_listenServer, SIGNAL(newClient(Client*)), this, SLOT(onClientConnected(Client*))); - _discoveryListener = new DiscoveryListener(); + auto *ls = new ListenServer(CLIENT_PORT, this); + connect(ls, &ListenServer::newClient, this, &MainWindow::onClientConnected); + new DiscoveryListener(this); // Finally this->onSessionNameUpdate(); // Just make lable visible. @@ -175,8 +163,8 @@ void MainWindow::clientCountChanged() int clientCount = 0; - for (auto it = _clientFrames.begin(); it != _clientFrames.end(); ++it) { - Client* c = (*it)->client(); + for (auto * frame : _clientFrames) { + Client* c = frame->client(); if (c != nullptr) { bool b = c->isExamMode(); examClientCount += b ? 1 : 0; @@ -241,7 +229,7 @@ static int distance(QPoint a, QPoint b) * @param toIgnore, ignore this connectionframe when considering free slots * @return the free slot */ -QPoint MainWindow::closestFreeSlot(const QPoint preferredPixels, const ConnectionFrame* toIgnore) +QPoint MainWindow::closestFreeSlot(const QPoint &preferredPixels, const ConnectionFrame* toIgnore) { const bool pickFirstOne = ( preferredPixels == QPoint(-1, -1) ); const QSize& clientSize = serverApp->getCurrentRoom()->clientSize; @@ -250,11 +238,11 @@ QPoint MainWindow::closestFreeSlot(const QPoint preferredPixels, const Connectio memset(grid, 0, sizeof(bool) * size_t(_tilesX * _tilesY)); /* set everything to false */ /* fill grid */ - for (auto it = _clientFrames.begin(); it != _clientFrames.end(); ++it) { + for (auto * frame : _clientFrames) { - if (*it == toIgnore) { continue; } + if (frame == toIgnore) { continue; } - const QPoint p = (*it)->getGridPosition(); + const QPoint p = frame->getGridPosition(); for (int x = p.x(); x < p.x() + clientSize.width(); x++) { for (int y = p.y(); y < p.y() + clientSize.height(); y++) { @@ -323,7 +311,7 @@ void MainWindow::placeFrameInFreeSlot(ConnectionFrame* frame, QPoint preferredPi */ ConnectionFrame* MainWindow::createFrame(const QString &computerId, const QPoint* gridPosition, bool fromRoomplan) { - ConnectionFrame *cf = new ConnectionFrame(this, ui->frmRoom, fromRoomplan); + auto *cf = new ConnectionFrame(this, ui->frmRoom, fromRoomplan); if (gridPosition == nullptr) { placeFrameInFreeSlot(cf); } else { @@ -332,9 +320,9 @@ ConnectionFrame* MainWindow::createFrame(const QString &computerId, const QPoint cf->setComputerId(computerId); _clientFrames.append(cf); cf->show(); - connect(cf, SIGNAL(frameMoved(ConnectionFrame *)), this, SLOT(onFrameDropped(ConnectionFrame *))); - connect(cf, SIGNAL(clicked(ConnectionFrame *)), this, SLOT(onFrameClicked(ConnectionFrame *))); - connect(cf, SIGNAL(frameMoving(ConnectionFrame *)), this, SLOT(onFrameMoving(ConnectionFrame *))); + connect(cf, &ConnectionFrame::frameMoved, this, &MainWindow::onFrameDropped); + connect(cf, &ConnectionFrame::clicked, this, &MainWindow::onFrameClicked); + connect(cf, &ConnectionFrame::frameMoving, this, &MainWindow::onFrameMoving); return cf; } @@ -365,10 +353,10 @@ void MainWindow::tellClientCurrentSituation(Client* client) */ Client* MainWindow::getClientFromId(int id) { - for (QList<ConnectionFrame*>::iterator it(_clientFrames.begin()); it != _clientFrames.end(); ++it) { - if ((*it)->client() != nullptr) { - if ((*it)->client()->id() == id) - return (*it)->client(); + for (auto * frame : _clientFrames) { + if (frame->client() != nullptr) { + if (frame->client()->id() == id) + return frame->client(); } } return nullptr; @@ -382,9 +370,9 @@ Client* MainWindow::getClientFromId(int id) */ ConnectionFrame* MainWindow::getTutorFrame() { - for (QList<ConnectionFrame*>::iterator it(_clientFrames.begin()); it != _clientFrames.end(); ++it) { - if (((*it) != nullptr) && ((*it)->isTutor())) - return (*it); + for (auto * frame : _clientFrames) { + if ((frame != nullptr) && (frame->isTutor())) + return frame; } return nullptr; } @@ -397,9 +385,9 @@ ConnectionFrame* MainWindow::getTutorFrame() */ ConnectionFrame* MainWindow::getSelectedFrame() { - for (QList<ConnectionFrame*>::iterator it(_clientFrames.begin()); it != _clientFrames.end(); ++it) { - if (((*it) != nullptr) && ((*it)->isSelected())) - return (*it); + for (auto * frame : _clientFrames) { + if ((frame != nullptr) && (frame->isSelected())) + return frame; } return nullptr; } @@ -470,8 +458,8 @@ void MainWindow::resizeEvent(QResizeEvent* /* e */ ) const QSize& clientSize = room->clientSize; // Check if any frames have been moved beyond the room dimensions - for (auto it = _clientFrames.begin(); it != _clientFrames.end(); ++it) { - QPoint bounds = (*it)->getGridPosition(); + for (auto * frame : _clientFrames) { + QPoint bounds = frame->getGridPosition(); while (bounds.x() + clientSize.width() > newGridSize.width()) { newGridSize += QSize(1, 0); } @@ -499,16 +487,16 @@ void MainWindow::resizeEvent(QResizeEvent* /* e */ ) const int maxY = _tilesY - clientSize.height(); /* Bring back frames which are now out of the screen */ - for (auto it = _clientFrames.begin(); it != _clientFrames.end(); ++it) { - const QPoint gp = (*it)->getGridPosition(); + for (auto * frame : _clientFrames) { + const QPoint gp = frame->getGridPosition(); if ( gp.x() > maxX || gp.y() > maxY ) { - placeFrameInFreeSlot(*it, (*it)->pos()); + placeFrameInFreeSlot(frame, frame->pos()); } } /* Resize all connection windows */ - for (auto it = _clientFrames.begin(); it != _clientFrames.end(); ++it) { - (*it)->updateGeometry(); + for (auto * frame : _clientFrames) { + frame->updateGeometry(); } /* update background image label */ @@ -581,10 +569,10 @@ void MainWindow::reset(bool lock) } // Unlock all clients - for (QList<ConnectionFrame*>::iterator it(_clientFrames.begin()); it != _clientFrames.end(); ++it) { - if ((*it)->client() != nullptr) { - (*it)->client()->lockScreen(lock); - (*it)->client()->removeAttention(); + for (auto * frame : _clientFrames) { + if (frame->client() != nullptr) { + frame->client()->lockScreen(lock); + frame->client()->removeAttention(); } } @@ -596,6 +584,7 @@ void MainWindow::reset(bool lock) void MainWindow::onFrameMoving(ConnectionFrame* connectionFrame) { + // Get where the frame would be placed, and show a blue shadow in that spot QPoint slot = closestFreeSlot(connectionFrame->pos(), connectionFrame); _dropMarker->setGeometry(slot.x() * getTileWidthPx(), slot.y() * getTileHeightPx(), connectionFrame->width(), connectionFrame->height()); if (!_dropMarker->isVisible()) { @@ -612,11 +601,8 @@ void MainWindow::onFrameMoving(ConnectionFrame* connectionFrame) void MainWindow::onFrameDropped(ConnectionFrame* connectionFrame) { _dropMarker->hide(); - // if (_tilesX <= 0 || _tilesY <= 0) return; const QPoint preferredPixels = connectionFrame->pos(); placeFrameInFreeSlot(connectionFrame, preferredPixels); - - //resizeEvent(nullptr); } /** @@ -627,7 +613,7 @@ void MainWindow::onFrameClicked(ConnectionFrame* frame) { _dropMarker->hide(); ConnectionFrame *current = getSelectedFrame(); - // If same frame is clicked again,, do nothing + // If same frame is clicked again, do nothing if (current == frame) return; @@ -711,27 +697,27 @@ void MainWindow::startVncServerIfNecessary(int from) void MainWindow::onButtonReloadRoomConfig() { - connect(_reloadWindow->ui->buttonBox, SIGNAL(accepted()), this, SLOT(onReloadRoomOk())); - connect(_reloadWindow->ui->buttonBox, SIGNAL(rejected()), this, SLOT(onReloadRoomCancel())); + connect(_reloadWindow->buttonBox(), &QDialogButtonBox::accepted, this, &MainWindow::onReloadRoomOk); + connect(_reloadWindow->buttonBox(), &QDialogButtonBox::rejected, this, &MainWindow::onReloadRoomCancel); QList<QString> keyList = serverApp->getRooms().keys(); - for (QList<QString>::iterator it = keyList.begin(); it != keyList.end() ; it++) { - _reloadWindow->ui->roomList->addItem(*it); + for (const auto & it : keyList) { + _reloadWindow->addRoom(it); } _reloadWindow->show(); } void MainWindow::onReloadRoomCancel() { - disconnect(_reloadWindow->ui->buttonBox, SIGNAL(accepted()), this, SLOT(onReloadRoomOk())); - disconnect(_reloadWindow->ui->buttonBox, SIGNAL(rejected()), this, SLOT(onReloadRoomCancel())); - _reloadWindow->ui->roomList->clear(); + disconnect(_reloadWindow->buttonBox(), &QDialogButtonBox::accepted, this, &MainWindow::onReloadRoomOk); + disconnect(_reloadWindow->buttonBox(), &QDialogButtonBox::rejected, this, &MainWindow::onReloadRoomCancel); + _reloadWindow->clearRoomList(); _reloadWindow->hide(); } void MainWindow::reloadCurrentRoom() { /* delete old image */ - if (_backgroundImage != nullptr) {delete _backgroundImage; } + delete _backgroundImage; _backgroundImage = nullptr; const Room *room = serverApp->getCurrentRoom(); @@ -743,8 +729,8 @@ void MainWindow::reloadCurrentRoom() /* place connection frames */ for (auto it = room->clientPositions.begin(); it != room->clientPositions.end(); ++it) { - QString computerId = it.key(); - QPoint pos = it.value(); + const QString& computerId = it.key(); + const QPoint& pos = it.value(); ConnectionFrame *cf = createFrame(computerId, &pos, true); onFrameDropped(cf); @@ -765,7 +751,7 @@ void MainWindow::reloadCurrentRoom() qDebug() << "set background image path: " << imgPath; if (imgPath.endsWith("svg")) { /* render once with maximal screen size */ - const QSize &s = QApplication::desktop()->screenGeometry().size(); // ui->frmRoom->geometry().size(); + QSize s = QGuiApplication::screenAt(geometry().center())->size(); QSvgRenderer renderer(imgPath); _backgroundImage = new QImage(s, QImage::Format_ARGB32); _backgroundImage->fill(Qt::lightGray); /* background color */ @@ -785,7 +771,8 @@ void MainWindow::reloadCurrentRoom() void MainWindow::onReloadRoomOk() { - if (_reloadWindow->ui->roomList->currentItem() == nullptr) { + QString roomToReload = _reloadWindow->currentRoom(); + if (roomToReload.isEmpty()) { QMessageBox::critical(this, "Warning", tr("No item selected, please select room!"), 0, 1); return; } @@ -794,21 +781,20 @@ void MainWindow::onReloadRoomOk() "Note that all clients will be deleted."), QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes); if (ret == QMessageBox::Yes) { - disconnect(_reloadWindow->ui->buttonBox, SIGNAL(accepted()), this, SLOT(onReloadRoomOk())); - disconnect(_reloadWindow->ui->buttonBox, SIGNAL(rejected()), this, SLOT(onReloadRoomCancel())); + disconnect(_reloadWindow->buttonBox(), &QDialogButtonBox::accepted, this, &MainWindow::onReloadRoomOk); + disconnect(_reloadWindow->buttonBox(), &QDialogButtonBox::rejected, this, &MainWindow::onReloadRoomCancel); // Delete all clients. - for (QList<ConnectionFrame*>::iterator it = _clientFrames.begin(); it != _clientFrames.end(); it++) { - (*it)->hide(); - (*it)->deleteLater(); + for (auto * frame : _clientFrames) { + frame->hide(); + frame->deleteLater(); } _clientFrames.clear(); // Load new room configuration. - QString roomToReload = _reloadWindow->ui->roomList->currentItem()->data(0).toString(); serverApp->setCurrentRoom(roomToReload); reloadCurrentRoom(); - _reloadWindow->ui->roomList->clear(); + _reloadWindow->clearRoomList(); _reloadWindow->hide(); } @@ -865,9 +851,9 @@ void MainWindow::onButtonTutorToAll() } // Set all clients as watchers of tutor. Except for the tutors desired source, which hase to be none - for (QList<ConnectionFrame*>::iterator it(_clientFrames.begin()); it != _clientFrames.end(); ++it) - if ((*it)->client() != nullptr) - (*it)->client()->setDesiredProjectionSource((*it)->client() == getTutorFrame()->client() ? NO_SOURCE : getTutorFrame()->client()->id()); + for (auto * frame : _clientFrames) + if (frame->client() != nullptr) + frame->client()->setDesiredProjectionSource(frame->client() == getTutorFrame()->client() ? NO_SOURCE : getTutorFrame()->client()->id()); disableButtons(); _mode = Mode::Broadcast; @@ -914,7 +900,7 @@ void MainWindow::onButtonTutorToStudent() disableButtons(); int numClients = 0; - for (auto c : _clientFrames) { + for (auto * c : _clientFrames) { if (c->client() != nullptr && c->client()->desiredProjectionSource() == sourceClient->id()) { numClients++; } @@ -1036,10 +1022,10 @@ void MainWindow::onButtonLockSingle() client->lockScreen(newState); if (!newState) { // If no more clients are locked, reset button - for (QList<ConnectionFrame*>::iterator it(_clientFrames.begin()); it != _clientFrames.end(); ++it) { - if ((*it)->client() == nullptr) + for (auto * frame : _clientFrames) { + if (frame->client() == nullptr) continue; - if ((*it)->client()->isLocked()) + if (frame->client()->isLocked()) return; } ui->action_Lock->setChecked(false); @@ -1090,8 +1076,8 @@ void MainWindow::onButtonSetAsTutor() */ void MainWindow::onClientConnected(Client* client) { - connect(client, SIGNAL(authenticating(Client*, ClientLogin*)), this, SLOT(onClientAuthenticating(Client*, ClientLogin*))); - connect(client, SIGNAL(authenticated(Client*)), this, SLOT(onClientAuthenticated(Client*))); + connect(client, &Client::authenticating, this, &MainWindow::onClientAuthenticating); + connect(client, &Client::authenticated, this, &MainWindow::onClientAuthenticated); } /** @@ -1106,7 +1092,7 @@ void MainWindow::onClientConnected(Client* client) */ void MainWindow::onClientAuthenticating(Client* client, ClientLogin* request) { - disconnect(client, SIGNAL(authenticating(Client*, ClientLogin*)), this, SLOT(onClientAuthenticating(Client*, ClientLogin*))); + disconnect(client, &Client::authenticating, this, &MainWindow::onClientAuthenticating); /* copy examMode */ client->setExamMode(request->examMode); @@ -1117,8 +1103,8 @@ void MainWindow::onClientAuthenticating(Client* client, ClientLogin* request) int addnum = 1; do { inuse = false; - for (QList<ConnectionFrame*>::iterator it(_clientFrames.begin()); it != _clientFrames.end(); ++it) { - Client *c = (**it).client(); + for (auto * frame : _clientFrames) { + Client *c = frame->client(); if (c == nullptr) continue; if (!c->isAuthed()) @@ -1134,10 +1120,11 @@ void MainWindow::onClientAuthenticating(Client* client, ClientLogin* request) } } } while (inuse && addnum < 100); - if (inuse) + if (inuse) { request->accept = false; - else + } else { request->name = check; + } } /** @@ -1152,14 +1139,14 @@ void MainWindow::onClientAuthenticating(Client* client, ClientLogin* request) */ void MainWindow::onClientAuthenticated(Client* client) { - disconnect(client, SIGNAL(authenticated(Client*)), this, SLOT(onClientAuthenticated(Client*))); - connect(client, SIGNAL(vncServerStateChange(Client*)), this, SLOT(onVncServerStateChange(Client*))); - connect(client, SIGNAL(vncClientStateChange(Client*)), this, SLOT(onVncClientStateChange(Client*))); + disconnect(client, &Client::authenticated, this, &MainWindow::onClientAuthenticated); + connect(client, &Client::vncServerStateChange, this, &MainWindow::onVncServerStateChange); + connect(client, &Client::vncClientStateChange, this, &MainWindow::onVncClientStateChange); ConnectionFrame *existing = nullptr; ConnectionFrame *cf = nullptr; - for (QList<ConnectionFrame*>::iterator it(_clientFrames.begin()); it != _clientFrames.end(); ++it) { - if ((*it)->computerId() == client->ip()) { - existing = *it; + for (auto * frame : _clientFrames) { + if (frame->computerId() == client->ip()) { + existing = frame; } } @@ -1171,7 +1158,7 @@ void MainWindow::onClientAuthenticated(Client* client) } cf->assignClient(client); - connect(client, SIGNAL(disconnected()), this, SLOT(clientCountChanged())); + connect(client, &Client::disconnected, this, &MainWindow::clientCountChanged); tellClientCurrentSituation(client); clientCountChanged(); } @@ -1204,13 +1191,13 @@ void MainWindow::onVncServerStateChange(Client* client) client->lockScreen(false); } else { // VNC server stopped on some client or failed to start - reset local pending projection information - for (QList<ConnectionFrame*>::iterator it(_clientFrames.begin()); it != _clientFrames.end(); ++it) { - if ((*it)->client() != nullptr) { - if ((*it)->client()->desiredProjectionSource() == client->id()) { - (*it)->client()->setDesiredProjectionSource(NO_SOURCE); - (*it)->client()->stopVncClient(); + for (auto * frame : _clientFrames) { + if (frame->client() != nullptr) { + if (frame->client()->desiredProjectionSource() == client->id()) { + frame->client()->setDesiredProjectionSource(NO_SOURCE); + frame->client()->stopVncClient(); if (_mode == Mode::LockedUnicast) - (*it)->client()->lockScreen(true); + frame->client()->lockScreen(true); } } } @@ -1251,14 +1238,14 @@ void MainWindow::onVncClientStateChange(Client* client) * the new connect. */ bool serverHasWatchers = false; - for (QList<ConnectionFrame*>::iterator it(_clientFrames.begin()); it != _clientFrames.end(); ++it) - if ((*it)->client() != nullptr) - if ((*it)->client()->desiredProjectionSource() == client->projectionSource()) { + for (auto * frame : _clientFrames) + if (frame->client() != nullptr) + if (frame->client()->desiredProjectionSource() == client->projectionSource()) { serverHasWatchers = true; break; } - if ( !serverHasWatchers ) { + if (!serverHasWatchers) { Client* c = getClientFromId(client->projectionSource()); if (c != nullptr) c->stopVncServer(); diff --git a/src/server/mainwindow/mainwindow.h b/src/server/mainwindow/mainwindow.h index 86499af..d4967f8 100644 --- a/src/server/mainwindow/mainwindow.h +++ b/src/server/mainwindow/mainwindow.h @@ -1,9 +1,7 @@ -#ifndef _MAINWINDOW_H_ -#define _MAINWINDOW_H_ +#ifndef PVS_MAINWINDOW_H_ +#define PVS_MAINWINDOW_H_ -#include <QtWidgets> #include <QMainWindow> -#include "../net/client.h" class SessionNameWindow; class ConnectionFrame; @@ -11,6 +9,11 @@ class ListenServer; class DiscoveryListener; class HelpWindow; class ReloadRoomWindow; +class ClientLogin; +class Client; +class ClickLabel; + +class QLabel; namespace Ui { @@ -27,8 +30,8 @@ class MainWindow : public QMainWindow public: - MainWindow(QWidget *parent = 0); - ~MainWindow(); + explicit MainWindow(QWidget *parent = nullptr); + ~MainWindow() override; QRect calcFrameGeometry(ConnectionFrame* frame) const; @@ -38,24 +41,17 @@ private: Ui::MainWindow *ui; SessionNameWindow *_sessionNameWindow; HelpWindow *_helpWindow; - ReloadRoomWindow *_reloadWindow; - QLabel *_sessionNameLabel; - int _tbIconSize; - Qt::ToolBarArea _tbArea; + ReloadRoomWindow *_reloadWindow; + ClickLabel *_sessionNameLabel; int _tilesX; int _tilesY; QImage* _backgroundImage = nullptr; QLabel* _examModeLabel = nullptr; - - /* virtual columns to preserve the aspect ratio of the loaded room */ - int _virtCols; - int _virtRows; - // Button block stuff QTimer *_buttonLockTimer; QList<QAction*> _lockingButtons; - static const qint64 BUTTON_BLOCK_TIME = 2000; + static const qint64 BUTTON_BLOCK_TIME = 2000; // Management stuff enum class Mode @@ -66,19 +62,16 @@ private: LockedUnicast, None } _mode; - int _streamingSource; + int _streamingSource{}; QList<ConnectionFrame*> _clientFrames; QWidget *_dropMarker; - ListenServer *_listenServer; - DiscoveryListener *_discoveryListener; - int _lastClientCount; + int _lastClientCount{}; - QPoint closestFreeSlot(const QPoint preferredPixels, const ConnectionFrame* toIgnore); + QPoint closestFreeSlot(const QPoint &preferredPixels, const ConnectionFrame* toIgnore); void placeFrameInFreeSlot(ConnectionFrame* frame, QPoint preferred = QPoint(-1, -1)); ConnectionFrame* createFrame(const QString &computerId = QString(), const QPoint *gridPosition = nullptr, bool fromRoomplan = false); - void savePosition(ConnectionFrame *cf); void startVncServerIfNecessary(int from); void tellClientCurrentSituation(Client* client); void reset(bool lock = false); @@ -86,19 +79,19 @@ private: ConnectionFrame* getTutorFrame(); ConnectionFrame* getSelectedFrame(); - void closeEvent(QCloseEvent *e); - void changeEvent(QEvent *e); - void resizeEvent(QResizeEvent *e); - void mouseReleaseEvent(QMouseEvent* e); + void closeEvent(QCloseEvent *e) override; + void changeEvent(QEvent *e) override; + void resizeEvent(QResizeEvent *e) override; + void mouseReleaseEvent(QMouseEvent* e) override; int getTileWidthPx() const; int getTileHeightPx() const; - void updateContextButtonStates(); + void updateContextButtonStates(); void reloadCurrentRoom(); - void vncOneOnOne(bool exclusive); + void vncOneOnOne(bool exclusive); protected slots: void disableButtons(); @@ -126,8 +119,8 @@ protected slots: void onButtonExit(); void onButtonHelp(); // connection frame - void onFrameMoving(ConnectionFrame* frame); - void onFrameDropped(ConnectionFrame* frame); + void onFrameMoving(ConnectionFrame* frame); + void onFrameDropped(ConnectionFrame* frame); void onFrameClicked(ConnectionFrame* frame); // Net void onClientConnected(Client* client); diff --git a/src/server/mainwindow/mainwindow.ui b/src/server/mainwindow/mainwindow.ui new file mode 100644 index 0000000..62b92f7 --- /dev/null +++ b/src/server/mainwindow/mainwindow.ui @@ -0,0 +1,339 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>MainWindow</class> + <widget class="QMainWindow" name="MainWindow"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>846</width> + <height>801</height> + </rect> + </property> + <property name="windowTitle"> + <string notr="true">PVS2 Manager</string> + </property> + <property name="styleSheet"> + <string notr="true">QToolButton { + border-radius: 8px; + padding: 4px; + margin: 5px; + border: 1px solid #777; +} +QToolButton:enabled { +background-color: #f8f8f8; +border: 1px solid #555; +} +QToolButton:enabled:hover { + background: qradialgradient(cx: 0.4, cy: -0.1, +fx: 0.4, fy: -0.1, +radius: 1.35, stop: 0 #fff, stop: 1 #ddd); +} + +QToolButton:enabled:checked, +QToolButton:enabled:pressed { +background: qradialgradient(cx: 0.4, cy: -0.1, +fx: 0.4, fy: -0.1, +radius: 1.35, stop: 0 #888, stop: 1 #aaa); +} +QLabel#examModeLabel { + width: 71px; + margin: 5px; + border-radius: 8px; + background-color: rgb(170, 170, 170); +}</string> + </property> + <widget class="QWidget" name="centralWidget"> + <layout class="QVBoxLayout" name="verticalLayout"> + <property name="spacing"> + <number>0</number> + </property> + <property name="leftMargin"> + <number>0</number> + </property> + <property name="topMargin"> + <number>0</number> + </property> + <property name="rightMargin"> + <number>0</number> + </property> + <property name="bottomMargin"> + <number>0</number> + </property> + <item> + <layout class="QVBoxLayout" name="mainLayout"> + <property name="spacing"> + <number>3</number> + </property> + <item> + <widget class="QFrame" name="frmRoom"> + <property name="frameShape"> + <enum>QFrame::StyledPanel</enum> + </property> + <property name="frameShadow"> + <enum>QFrame::Sunken</enum> + </property> + <property name="lineWidth"> + <number>2</number> + </property> + <layout class="QHBoxLayout" name="horizontalLayout"> + <property name="spacing"> + <number>0</number> + </property> + <property name="leftMargin"> + <number>0</number> + </property> + <property name="topMargin"> + <number>0</number> + </property> + <property name="rightMargin"> + <number>0</number> + </property> + <property name="bottomMargin"> + <number>0</number> + </property> + <item> + <widget class="QLabel" name="imageLabel"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Maximum" vsizetype="Expanding"> + <horstretch>1</horstretch> + <verstretch>1</verstretch> + </sizepolicy> + </property> + <property name="lineWidth"> + <number>0</number> + </property> + <property name="text"> + <string/> + </property> + </widget> + </item> + </layout> + </widget> + </item> + </layout> + </item> + </layout> + </widget> + <widget class="QToolBar" name="toolBar"> + <property name="windowTitle"> + <string>toolBar</string> + </property> + <property name="layoutDirection"> + <enum>Qt::LeftToRight</enum> + </property> + <property name="autoFillBackground"> + <bool>true</bool> + </property> + <property name="movable"> + <bool>false</bool> + </property> + <property name="iconSize"> + <size> + <width>48</width> + <height>48</height> + </size> + </property> + <attribute name="toolBarArea"> + <enum>LeftToolBarArea</enum> + </attribute> + <attribute name="toolBarBreak"> + <bool>false</bool> + </attribute> + <addaction name="actionReload_Room_Configuration"/> + <addaction name="action_Lock"/> + <addaction name="action_LockSingle"/> + <addaction name="action_TutorToAll"/> + <addaction name="action_TutorToStudent"/> + <addaction name="action_StudentToTutor"/> + <addaction name="action_StudentToTutorExclusive"/> + <addaction name="action_SetAsTutor"/> + <addaction name="action_DeleteClient"/> + <addaction name="action_StopProjection"/> + <addaction name="separator"/> + <addaction name="action_Help"/> + <addaction name="action_Exit"/> + </widget> + <action name="action_Exit"> + <property name="icon"> + <iconset resource="../../pvsmgr.qrc"> + <normaloff>:/exit</normaloff> + <normalon>:/exit</normalon>:/exit</iconset> + </property> + <property name="text"> + <string>Exit</string> + </property> + <property name="toolTip"> + <string>Exit</string> + </property> + <property name="shortcut"> + <string>Ctrl+Q</string> + </property> + </action> + <action name="action_Lock"> + <property name="checkable"> + <bool>true</bool> + </property> + <property name="icon"> + <iconset resource="../../pvsmgr.qrc"> + <normaloff>:/lock</normaloff>:/lock</iconset> + </property> + <property name="text"> + <string>This will show a black screen on all connected clients, except the tutor's client.</string> + </property> + <property name="toolTip"> + <string>Lock/Unlock all clients</string> + </property> + <property name="shortcut"> + <string>Ctrl+A</string> + </property> + </action> + <action name="action_StudentToTutor"> + <property name="icon"> + <iconset resource="../../pvsmgr.qrc"> + <normaloff>:/student2tutor</normaloff>:/student2tutor</iconset> + </property> + <property name="text"> + <string>Stream currently selected client's screen content to the tutor's client.</string> + </property> + <property name="toolTip"> + <string>Student's Screen to Tutor</string> + </property> + </action> + <action name="action_StudentToTutorExclusive"> + <property name="icon"> + <iconset resource="../../pvsmgr.qrc"> + <normaloff>:/student2tutorextension</normaloff>:/student2tutorextension</iconset> + </property> + <property name="text"> + <string>Stream currently selected client's screen content to the tutor's client while showing a locked black screen on all other clients.</string> + </property> + <property name="toolTip"> + <string>Student's Screen to Tutor, others blanked</string> + </property> + </action> + <action name="action_TutorToStudent"> + <property name="icon"> + <iconset resource="../../pvsmgr.qrc"> + <normaloff>:/tutor2student</normaloff>:/tutor2student</iconset> + </property> + <property name="text"> + <string>Stream the tutor's screen contents to the currently selected client.</string> + </property> + <property name="toolTip"> + <string>Tutor's Screen to Student</string> + </property> + </action> + <action name="action_TutorToAll"> + <property name="icon"> + <iconset resource="../../pvsmgr.qrc"> + <normaloff>:/tutor2all</normaloff>:/tutor2all</iconset> + </property> + <property name="text"> + <string>Stream the tutor's screen contents to everyone.</string> + </property> + <property name="toolTip"> + <string>Tutor's Screen to Everyone</string> + </property> + </action> + <action name="action_StopProjection"> + <property name="icon"> + <iconset resource="../../pvsclient.qrc"> + <normaloff>:/reset</normaloff>:/reset</iconset> + </property> + <property name="text"> + <string>Unlock all clients, stop any running screen content streaming.</string> + </property> + <property name="toolTip"> + <string>Reset</string> + </property> + <property name="shortcut"> + <string>R</string> + </property> + </action> + <action name="action_SetAsTutor"> + <property name="icon"> + <iconset resource="../../pvsmgr.qrc"> + <normaloff>:/dozent</normaloff>:/dozent</iconset> + </property> + <property name="text"> + <string>Declare the currently selected client as tutor. The tutor will be excluded from screen locking and can be used as a fixed source/target for screen content streaming.</string> + </property> + <property name="toolTip"> + <string>Declare tutor</string> + </property> + <property name="shortcut"> + <string>T</string> + </property> + </action> + <action name="action_DeleteClient"> + <property name="icon"> + <iconset resource="../../pvsmgr.qrc"> + <normaloff>:/trash</normaloff>:/trash</iconset> + </property> + <property name="text"> + <string>Delete currently selected client. Only allowed for disconnected clients.</string> + </property> + <property name="toolTip"> + <string>Delete Client</string> + </property> + <property name="shortcut"> + <string>Del</string> + </property> + <property name="visible"> + <bool>true</bool> + </property> + </action> + <action name="action_Help"> + <property name="icon"> + <iconset resource="../../pvsmgr.qrc"> + <normaloff>:/helpme</normaloff>:/helpme</iconset> + </property> + <property name="text"> + <string>Show this help text.</string> + </property> + <property name="toolTip"> + <string>Help</string> + </property> + <property name="shortcut"> + <string>F1</string> + </property> + <property name="visible"> + <bool>true</bool> + </property> + </action> + <action name="actionReload_Room_Configuration"> + <property name="icon"> + <iconset resource="../../pvsmgr.qrc"> + <normaloff>:/reloadClassroom</normaloff>:/reloadClassroom</iconset> + </property> + <property name="text"> + <string>This shows a list of preconfigured rooms which you can load. This will reset the currently shown layout and disconnect all clients.</string> + </property> + <property name="toolTip"> + <string>Load a new room layout</string> + </property> + </action> + <action name="action_LockSingle"> + <property name="icon"> + <iconset resource="../../pvsmgr.qrc"> + <normaloff>:/lock-single</normaloff>:/lock-single</iconset> + </property> + <property name="text"> + <string>Lock or unlock the selected client only.</string> + </property> + <property name="toolTip"> + <string>Lock/Unlock single client</string> + </property> + <property name="shortcut"> + <string>L</string> + </property> + </action> + </widget> + <layoutdefault spacing="6" margin="11"/> + <resources> + <include location="../../pvsclient.qrc"/> + <include location="../../pvsmgr.qrc"/> + </resources> + <connections/> +</ui> |