summaryrefslogblamecommitdiffstats
path: root/src/client/connectwindow/connectwindow.cpp
blob: c77a5e67852debf58e1cf22f8f602f02bd48bb5d (plain) (tree)
1
2
3
4
5
6
7
8






                          
                            


                                  
                                    
                                   

                          



                      
                                                                                


                                
                                                               
 
                                    
                       

                               
                                     
 

                             

                                
                                                            
 

                                               
 

                                                                                       
                                                                             
 
                                                                                                         
 
                                    

                                                                                                          
 

                                                                                                    
 

                                                             
 
                                    

 

                                                                                
   
                                  
 
 

                                                                                
                                             
                                                                          
   
                                         
 
                                                      
 
                                  

                                                                
                                                                                                             

                                                       



                           
                                                          
            
                                                             
 
                         
                  
                                                                 

                      
                                                                                                       

                        
                                                                            

                               
                                                                               

                                       
                                                                                 

                       
                                                             

                       
                                                                       
                      
                         

                                                                    
                            
                                                                                             
                      


                                                                 


         
  


            
                                                                                


                                                              

                                                  
                                             


                                      
                                                       
              
                                                                 


                                            
                                                                                
                                              

           





                                              

                            


                                                
               
                     



                         
                                                                                


                                                    
                                                       
 

                         
                                      

 
                                                                                




                                                                                                
                                                                                 
 
                           
                       

                                      
                          
                                    
                             
                                                   

 
  


        

 















                                                                                          

 






                                     


 
                                                                                



                                             
                                     
 
                         
                                      
                               

                                                       



                                        
                             
                               
                
                            
         
                                    

 


                                                                        



                                                    
                                                            


                                                                                 
 
                                                                                


                                      
                                 



                     

                                                                   











                                                                              
 






                                                                                
   
                                                                                                                                                          
 



                                                                                                                                                              

 

                                                                                


                                                                                




                                                                                 

                       
 
                    
                                  
         
                                 


                                                                                                                                                                                  
                                             
 
                                            
 
                                              

                                            
         
 

 





                                                                       


 
                                                                                
                                                            

                    
                                                                  
 
                                     
 



                                                                                
                                                               
 
                      
                                    



                                                              
 
/*
 * connectwindow.cpp
 *
 *  Created on: 28.01.2013
 *      Author: sr
 */

#include <QNetworkInterface>
#include "../../shared/settings.h"
#include "../../shared/network.h"
#include "../../shared/util.h"
#include "../net/serverconnection.h"
#include "../clientapp/clientapp.h"
#include "connectwindow.h"
#include "ui_connect.h"

#define UDPBUFSIZ 9000
#define SALT_LEN 18

/***************************************************************************//**
 * Initialize Connection Window.
 * @param parent
 */
ConnectWindow::ConnectWindow(QWidget *parent) :	QWidget(parent)
{
	_ui = new Ui::ConnectWindow;
	_timerHide = 0;
	_state = Idle;
	_hashSslErrorCount = 0;
	_pendingConnection = nullptr;

	// Initialize the GUI
	_ui->setupUi(this);

	// Set window properties
	setWindowFlags(Qt::WindowStaysOnTopHint | Qt::Tool);

	// Set page 0 as default
	_ui->stackedWidget->setCurrentIndex(0);

	// Set actions of buttons
	connect(_ui->btn_connection, SIGNAL(clicked()), this, SLOT(onBtnConnection()));
	connect(_ui->btn_hide, SIGNAL(clicked()), this, SLOT(onBtnCancel()));

	connect(_ui->comboBox_rooms, SIGNAL(currentIndexChanged(int)), this, SLOT(onRoomSelection(int)));

	// React on discovery signal
	connect(&_serverDiscovery, SIGNAL(serverDetected(QString, quint16, QByteArray, QByteArray, bool)),
	        this, SLOT(onServerDetected(QString, quint16, QByteArray, QByteArray, bool)));

	/* finally the most requested feature: connect on press of the enter key */
	connect(_ui->lineEditName, SIGNAL(returnPressed()), _ui->btn_connection, SIGNAL(clicked()));

	/* by default don't show the manual connection box */
	_ui->box_manual->setVisible(false);

	this->updateUserInterface();
}

/***************************************************************************//**
 * @brief ConnectWindow::~ConnectWindow
 */
ConnectWindow::~ConnectWindow() {}



/***************************************************************************//**
 * Handle changes in state and update window.
 * Also changing TextLabel which shows the user what the program is doing.
 */
void ConnectWindow::updateUserInterface()
{
	_ui->lineEditName->setEnabled(_state == Idle);

	if (_state == Connected) {
		_ui->btn_connection->setEnabled(true);
		_ui->btn_connection->setText(tr("&Disconnect"));
		_ui->lblStatus->setText(tr("Connected to %1").arg(clientApp->connection()->getPeerAdress()));
		_ui->lineEditName->setEnabled(false);
		_ui->stackedWidget->setCurrentIndex(1);
		return;
	}

	if (_state != Idle)
		_ui->btn_connection->setText(tr("&Stop"));
	else
		_ui->btn_connection->setText(tr("&Connect"));

	switch (_state) {
	case Idle:
		_ui->lblStatus->setText(tr("Ready to connect."));
		break;
	case Scanning:
		_ui->lblStatus->setText(tr("Scanning for session %1.").arg(_ui->lineEditName->text()));
		break;
	case Connecting:
		_ui->lblStatus->setText(tr("Found session, connecting..."));
		break;
	case AwaitingChallenge:
		_ui->lblStatus->setText(tr("Waiting for server challenge..."));
		break;
	case AwaitingChallengeResponse:
		_ui->lblStatus->setText(tr("Replied to challenge, sent own..."));
		break;
	case LoggingIn:
		_ui->lblStatus->setText(tr("Logging in..."));
		break;
	case Connected:
		_ui->lblStatus->setText(tr("Connection established!"));
		break;
	case InvalidCert:
		_ui->lblStatus->setText(tr("Invalid certificate."));
		break;
	case InvalidSslHash:
		_ui->lblStatus->setText(tr("Invalid TLS hash: %1.").arg(_hashSslErrorCount));
		break;
	default:
		_ui->lblStatus->setText(tr("Unknown state :-("));
		break;
	}
}

/*
 * Overrides
 */

/***************************************************************************//**
 * Called when a Qt timer fires; used for server discovery and
 * auto-hiding the connect dialog.
 */
void ConnectWindow::timerEvent(QTimerEvent* event)
{
	if (event->timerId() == _timerHide) {
		killTimer(_timerHide);
		_timerHide = 0;
		this->hide();
		_ui->stackedWidget->setCurrentIndex(0);
	} else
		// Unknown/Old timer id, kill it ??? PALM -> FACE
		killTimer(event->timerId());
}

/***************************************************************************//**
 * Handle incoming closeEvent and hide window.
 * @param e
 */
void ConnectWindow::closeEvent(QCloseEvent *e)
{
	e->ignore();
	this->hide();
}

void ConnectWindow::doShow()
{
	/* reset to automatic connect window */
	_ui->stackedWidget->setCurrentIndex(0);
	_ui->comboBox_rooms->setCurrentIndex(0);
	show();
	showNormal();
	activateWindow();
	raise();
}

/***************************************************************************//**
 * Gives the keyboard input focus to the input line.
 * @param event
 */
void ConnectWindow::showEvent(QShowEvent* /* event */ )
{
	activateWindow();
	raise();
	_ui->lineEditName->setFocus();
}

/***************************************************************************//**
 * Public function connect to session.
 * Check if currently connected to server,
 *							if not --> connect to given sessionName.
 * @param sessionName
 */
void ConnectWindow::connectToSession(const QByteArray sessionName, QString mgrIP)
{
	if (_state != Idle)
		return;
	_currentSession = sessionName;
	_currentIp = mgrIP;
	_state = Scanning;
	this->updateUserInterface();
	_tryReconnect = true;
	_serverDiscovery.start(sessionName, mgrIP);
}

/*
 * Slots
 */



void ConnectWindow::DoConnect()
{
	qDebug() << "DoConnect()";
	//  Connect (scan for session)
	// qDebug() << _ui->lineEditName->text().toUtf8();
	int index = _ui->comboBox_rooms->currentIndex();
	QString selectedMgrIP = _ui->comboBox_rooms->itemData(index).toString();

	if (selectedMgrIP == "manual_connection") {
		qDebug() << "connect to sessionName by manual connection";
		QByteArray sessionName = _ui->lineEditName->text().toUtf8();
		connectToSession(sessionName, "");
	} else {
		qDebug() << "connect to mgrIP (through room selection) " << selectedMgrIP;
		connectToSession("", selectedMgrIP);
	}
}

void ConnectWindow::DoDisconnect()
{
	qDebug() << "DoDisconnect()";
	_tryReconnect = false;
	// Stop or disconnect
	emit disconnect();
	_state = Idle;
}


/***************************************************************************//**
 * Handle click on Connect/Disconnect button.
 * If already connected --> Stop/disconnect.
 * Else scanning for given sessionId.
 */
void ConnectWindow::onBtnConnection()
{
	if (_timerHide) {
		killTimer(_timerHide);
		_timerHide = 0;
		_ui->stackedWidget->setCurrentIndex(0);
	}

	if (_serverDiscovery.isActive())
		_serverDiscovery.stop();

	if (_state != Idle) {
		DoDisconnect();
	} else {
		DoConnect();
	}
	this->updateUserInterface();
}

/** set the available rooms.
 *  If the list of rooms is empty, switches automatically to the "manual
 *  connection" page */
void ConnectWindow::setAvailableRooms(QList<Room> m)
{
	_ui->comboBox_rooms->clear();
	foreach (Room r, m) {
		_ui->comboBox_rooms->addItem(r.name, r.mgr);
	}
	/* also add a pseudo-room "manual choice" */
	_ui->comboBox_rooms->addItem(tr("Session Name..."), "manual_connection");
}
/***************************************************************************//**
 * Handle click on Cancel/Hide Button.
 * Just hide the window.
 */
void ConnectWindow::onBtnCancel()
{
	this->hide();
}

/** check if "manual_connection" is selected, then switch to manual
 * connection page */
void ConnectWindow::onRoomSelection(int index)
{
	QString sessionName = _ui->comboBox_rooms->itemData(index).toString();
	if (sessionName == "manual_connection") {
		qDebug() << "switch to manual connection";
		_ui->box_manual->setVisible(true);
		//this->setSize(QSize(300,200));
		this->resize(300, 200);
	} else {
		_ui->box_manual->setVisible(false);
		this->resize(300, 140);
	}
}

/***************************************************************************//**
 * @brief ConnectWindow::onServerDetected
 * @param host
 * @param port
 * @param sessionName
 * @param certHash
 */
void ConnectWindow::onServerDetected(const QString& host, const quint16 port, const QByteArray& sessionName, const QByteArray& certHash, bool autoConnect)
{
	_pendingConnection = new ServerConnection(host, port, sessionName, certHash, autoConnect);
	connect(_pendingConnection, SIGNAL(stateChange(ConnectWindow::ConnectionState)), this, SLOT(onConnectionStateChange(ConnectWindow::ConnectionState)));
	connect(_pendingConnection, SIGNAL(destroyed(QObject*)), this, SLOT(onConnectionClosed(QObject*)));
	connect(_pendingConnection, SIGNAL(disconnected(ServerConnection*)), this, SLOT(onConnectionDisconnected(ServerConnection*)));
}


/***************************************************************************//**
 * Handle connection state changes and update member variables describing state.
 * @param state
 */
void ConnectWindow::onConnectionStateChange(ConnectWindow::ConnectionState state)
{
	bool reset = (_state == Scanning);
	if (state == InvalidSslHash)
		++_hashSslErrorCount;

	_state = state;

	if (reset) {
		_state = Scanning;
	}
	if (state == Connected) {
		QObject::disconnect(_pendingConnection, SIGNAL(stateChange(ConnectWindow::ConnectionState)), this, SLOT(onConnectionStateChange(ConnectWindow::ConnectionState)));
		QObject::disconnect(_pendingConnection, SIGNAL(destroyed(QObject*)), this, SLOT(onConnectionClosed(QObject*)));
		emit connected(_pendingConnection);
		_pendingConnection = nullptr;

		this->updateUserInterface();

		_timerHide = startTimer(2000);
	} else {
		this->updateUserInterface();
	}

}

void ConnectWindow::onComboBox_keyPressed(QKeyEvent* e)
{
	qDebug() << "key released";
	if (e->key() == Qt::Key_Enter || e->key() == Qt::Key_Return ) {
		qDebug() << "enter pressed";
	}

}

/***************************************************************************//**
 * If connection is closed set _pendingConnection = nullptr.
 * @param connection
 */
void ConnectWindow::onConnectionClosed(QObject* /* connection */ )
{
	_pendingConnection = nullptr;
}

/***************************************************************************//**
 * @brief ConnectWindow::onConnectionDisconnected
 */
void ConnectWindow::onConnectionDisconnected(ServerConnection*)
{
	_state = Idle;
	this->updateUserInterface();
	if (_tryReconnect) {
		this->updateUserInterface();
		connectToSession(_currentSession, _currentIp);
	}
}