Pool Video Switch v2
Software video switch for distributed remote display in a lecture environment
connectwindow.cpp
Go to the documentation of this file.
1 /*
2  * connectwindow.cpp
3  *
4  * Created on: 28.01.2013
5  * Author: sr
6  */
7 
8 #include <QNetworkInterface>
9 #include "../../shared/settings.h"
10 #include "../../shared/util.h"
11 #include "../net/serverconnection.h"
12 #include "../clientapp/clientapp.h"
13 #include "connectwindow.h"
14 #include "ui_connectwindow.h"
15 
16 #include <QCloseEvent>
17 
18 #define UDPBUFSIZ 9000
19 #define SALT_LEN 18
20 
21 namespace Ui {
22  class ConnectWindow;
23 }
24 
30 {
31  _ui = new Ui::ConnectWindow;
32  _timerHide = 0;
33  _state = Idle;
35  _pendingConnection = nullptr;
36 
37  // Initialize the GUI
38  _ui->setupUi(this);
39 
40  // Set window properties
41  setWindowFlags(Qt::WindowStaysOnTopHint | Qt::Tool);
42 
43  // Set page 0 as default
44  _ui->stackedWidget->setCurrentIndex(0);
45 
46  // Set actions of buttons
47  connect(_ui->btn_connection, &QPushButton::clicked, this, &ConnectWindow::onBtnConnection);
48  connect(_ui->btn_hide, &QPushButton::clicked, this, &ConnectWindow::onBtnHide);
49 
50  connect(_ui->comboBox_rooms, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &ConnectWindow::onRoomSelection);
51 
52  // React on discovery signal
54 
55  /* finally the most requested feature: connect on press of the enter key */
56  connect(_ui->lineEditName, &QLineEdit::returnPressed, this, &ConnectWindow::onBtnConnection);
57 
58  /* by default don't show the manual connection box */
59  _ui->box_manual->setVisible(false);
60 
61  this->updateUserInterface();
62 }
63 
68 
69 
70 
76 {
77  _ui->lineEditName->setEnabled(_state == Idle);
78 
79  if (_state == Connected) {
80  _ui->btn_connection->setEnabled(true);
81  _ui->btn_connection->setText(tr("&Disconnect"));
82  _ui->lblStatus->setText(tr("Connected to %1").arg(_currentSession.isEmpty() ? _currentIp : _currentSession));
83  _ui->lineEditName->setEnabled(false);
84  _ui->stackedWidget->setCurrentIndex(1);
85  return;
86  }
87 
88  if (_state != Idle)
89  _ui->btn_connection->setText(tr("&Stop"));
90  else
91  _ui->btn_connection->setText(tr("&Connect"));
92 
93  switch (_state) {
94  case Idle:
95  _ui->lblStatus->setText(tr("Ready to connect."));
96  break;
97  case Scanning:
98  _ui->lblStatus->setText(tr("Scanning for session %1.").arg(_currentSession.isEmpty() ? _currentIp : _currentSession));
99  break;
100  case Connecting:
101  _ui->lblStatus->setText(tr("Found session, connecting..."));
102  break;
103  case AwaitingChallenge:
104  _ui->lblStatus->setText(tr("Waiting for server challenge..."));
105  break;
107  _ui->lblStatus->setText(tr("Replied to challenge, sent own..."));
108  break;
109  case LoggingIn:
110  _ui->lblStatus->setText(tr("Logging in..."));
111  break;
112  case Connected:
113  break;
114  case InvalidCert:
115  _ui->lblStatus->setText(tr("Invalid certificate."));
116  break;
117  case InvalidSslHash:
118  _ui->lblStatus->setText(tr("Invalid TLS hash: %1.").arg(_hashSslErrorCount));
119  break;
120  default:
121  _ui->lblStatus->setText(tr("Unknown state :-("));
122  break;
123  }
124 }
125 
126 /*
127  * Overrides
128  */
129 
134 void ConnectWindow::timerEvent(QTimerEvent* event)
135 {
136  if (event->timerId() == _timerHide) {
137  killTimer(_timerHide);
138  _timerHide = 0;
139  this->hide();
140  _ui->stackedWidget->setCurrentIndex(0);
141  } else
142  // Unknown/Old timer id, kill it ??? PALM -> FACE
143  killTimer(event->timerId());
144 }
145 
150 void ConnectWindow::closeEvent(QCloseEvent *e)
151 {
152  e->ignore();
153  this->hide();
154 }
155 
157 {
158  /* reset to automatic connect window */
159  _ui->stackedWidget->setCurrentIndex(0);
160  _ui->comboBox_rooms->setCurrentIndex(0);
161  show();
162  showNormal();
163  activateWindow();
164  raise();
165 }
166 
171 void ConnectWindow::showEvent(QShowEvent* /* event */ )
172 {
173  activateWindow();
174  raise();
175  _ui->lineEditName->setFocus();
176 }
177 
184 void ConnectWindow::connectToSession(const QByteArray& sessionName, const QString &mgrIP)
185 {
186  if (_state != Idle)
187  return;
188  _currentSession = sessionName;
189  _currentIp = mgrIP;
190  _state = Scanning;
191  this->updateUserInterface();
192  _tryReconnect = true;
193  _serverDiscovery.start(sessionName, mgrIP);
194 }
195 
196 /*
197  * Slots
198  */
199 
200 
201 
203 {
204  qDebug() << "DoConnect()";
205  // Connect (scan for session)
206  // qDebug() << _ui->lineEditName->text().toUtf8();
207  int index = _ui->comboBox_rooms->currentIndex();
208  QString selectedMgrIP = _ui->comboBox_rooms->itemData(index).toString();
209 
210  if (selectedMgrIP == "manual_connection") {
211  qDebug() << "connect to sessionName by manual connection";
212  QByteArray sessionName = _ui->lineEditName->text().toUtf8();
213  connectToSession(sessionName, "");
214  } else {
215  qDebug() << "connect to mgrIP (through room selection) " << selectedMgrIP;
216  connectToSession("", selectedMgrIP);
217  }
218 }
219 
221 {
222  qDebug() << "DoDisconnect()";
223  _tryReconnect = false;
224  // Stop or disconnect
225  emit disconnect();
226  _state = Idle;
227 }
228 
229 
236 {
237  if (_timerHide) {
238  killTimer(_timerHide);
239  _timerHide = 0;
240  _ui->stackedWidget->setCurrentIndex(0);
241  }
242 
245 
246  if (_state != Idle) {
247  DoDisconnect();
248  } else {
249  DoConnect();
250  }
251  this->updateUserInterface();
252 }
253 
257 void ConnectWindow::setAvailableRooms(const QList<Room>& m)
258 {
259  _ui->comboBox_rooms->clear();
260  foreach (Room r, m) {
261  _ui->comboBox_rooms->addItem(r.name, r.mgr);
262  }
263  /* also add a pseudo-room "manual choice" */
264  _ui->comboBox_rooms->addItem(tr("Session Name..."), "manual_connection");
265 }
271 {
272  this->hide();
273 }
274 
278 {
279  QString sessionName = _ui->comboBox_rooms->itemData(index).toString();
280  if (sessionName == "manual_connection") {
281  qDebug() << "switch to manual connection";
282  _ui->box_manual->setVisible(true);
283  //this->setSize(QSize(300,200));
284  this->resize(300, 200);
285  } else {
286  _ui->box_manual->setVisible(false);
287  this->resize(300, 140);
288  }
289 }
290 
298 void ConnectWindow::onServerDetected(const QString& host, const quint16 port, const QByteArray& sessionName, const QByteArray& certHash, bool autoConnect)
299 {
300  _pendingConnection = new ServerConnection(host, port, sessionName, certHash, autoConnect);
302  connect(_pendingConnection, &ServerConnection::destroyed, this, &ConnectWindow::onConnectionClosed);
304 }
305 
306 
312 {
313  bool reset = (_state == Scanning);
314  if (state == InvalidSslHash)
316 
317  _state = state;
318  this->updateUserInterface();
319 
320  if (reset) {
321  _state = Scanning;
322  }
323  if (state == Connected) {
325  QObject::disconnect(_pendingConnection, &ServerConnection::destroyed, this, &ConnectWindow::onConnectionClosed);
327  _pendingConnection = nullptr;
328  _timerHide = startTimer(2000);
329  }
330 
331 }
332 
338 {
339  _pendingConnection = nullptr;
340 }
341 
346 {
347  _state = Idle;
348  this->updateUserInterface();
349  if (_tryReconnect) {
350  this->updateUserInterface();
352  }
353 }
Class for handling the client connection.
Definition: connectwindow.h:41
void onConnectionClosed(QObject *connection)
If connection is closed set _pendingConnection = nullptr.
int _hashSslErrorCount
Definition: connectwindow.h:66
void DoDisconnect()
actually disconnects the connection
QString mgr
Definition: room.h:7
void updateUserInterface()
Handle changes in state and update window.
QByteArray _currentSession
Definition: connectwindow.h:70
ConnectWindow(QWidget *parent=nullptr)
Initialize Connection Window.
void onBtnConnection()
Handle click on Connect/Disconnect button.
void stateChange(ConnectWindow::ConnectionState state)
void onServerDetected(const QString &host, quint16 port, const QByteArray &sessionName, const QByteArray &certHash, bool autoConnect)
ConnectWindow::onServerDetected.
void onRoomSelection(int index)
check if "manual_connection" is selected, then switch to manual connection page
void start(const QByteArray &sessionName, const QString &mgrIP)
start
ServerDiscovery _serverDiscovery
Definition: connectwindow.h:67
void disconnected(ServerConnection *connection)
~ConnectWindow() override
ConnectWindow::~ConnectWindow.
ConnectionState _state
Definition: connectwindow.h:69
ServerConnection * _pendingConnection
Definition: connectwindow.h:68
void setAvailableRooms(const QList< Room > &m)
set the available rooms.
void DoConnect()
actually connects the connection
QString name
Definition: room.h:8
void disconnect()
void onBtnHide()
Handle click on Cancel/Hide Button.
void closeEvent(QCloseEvent *e) override
Handle incoming closeEvent and hide window.
void connectToSession(const QByteArray &sessionName, const QString &mgrIP)
Public function connect to session.
void onConnectionDisconnected(ServerConnection *connection)
ConnectWindow::onConnectionDisconnected.
void connected(ServerConnection *connection)
void timerEvent(QTimerEvent *event) override
Called when a Qt timer fires; used for server discovery and auto-hiding the connect dialog...
void serverDetected(const QString &host, const quint16 port, const QByteArray &sessionName, const QByteArray &certHash, bool autoConnect)
Definition: room.h:6
void onConnectionStateChange(ConnectWindow::ConnectionState state)
Handle connection state changes and update member variables describing state.
void showEvent(QShowEvent *event) override
Gives the keyboard input focus to the input line.
Ui::ConnectWindow * _ui
Definition: connectwindow.h:65
QString _currentIp
Definition: connectwindow.h:71