summaryrefslogblamecommitdiffstats
path: root/src/client/connectwindow/connectwindow.cpp
blob: 34087add1fa445de7fb4a51d3bed1cfe9aaa0230 (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 "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;
	_connected = false;
	_timerHide = 0;
	_connection = NULL;
	_state = Idle;
	_hashSslErrorCount = 0;

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

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

	// 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(onBtnHide()));

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

	this->updateState();
}

/***************************************************************************//**
 * @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::updateState()
{
	_ui->lineEditName->setEnabled(_state == Idle && !_connected);

	if (_connected)
	{
		_ui->btn_connection->setEnabled(true);
		_ui->btn_connection->setText(tr("&Disconnect"));
		_ui->lblStatus->setText(tr("Connected to %1").arg(_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; please enter session name."));
		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 Ssl hash: %1.").arg(_hashSslErrorCount));
		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();
}

/***************************************************************************//**
 * Gives the keyboard input focus to the input line.
 * @param event
 */
void ConnectWindow::showEvent(QShowEvent* event)
{
	_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)
{
	if (_connected || _state != Idle)
		return;
	_state = Scanning;
	this->updateState();
	_serverDiscovery.start(_ui->lineEditName->text().toUtf8());
}

/*
 * Slots
 */

/***************************************************************************//**
 * 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 (_connected || _state != Idle)
	{
		// Stop or disconnect
		emit disconnect();
		_state = Idle;
		this->updateState();
	}
	else
	{
		//  Connect (scan for session)
		connectToSession(_ui->lineEditName->text().toUtf8());
	}
}

/***************************************************************************//**
 * Handle click on Cancel/Hide Button.
 * Just hide the window.
 */
void ConnectWindow::onBtnHide()
{
	this->hide();
}


/***************************************************************************//**
 * @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)
{
	_connection = new ServerConnection(host, port, sessionName, certHash);
	connect(_connection, SIGNAL(stateChange(ConnectWindow::ConnectionState)), this, SLOT(onConnectionStateChange(ConnectWindow::ConnectionState)));
	connect(_connection, SIGNAL(destroyed(QObject*)), this, SLOT(onConnectionClosed(QObject*)));
	connect(_connection, SIGNAL(disconnected()), this, SLOT(onConnectionDisconnected()));
}


/***************************************************************************//**
 * 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;
	this->updateState();

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

		_connected = true;
		this->updateState();

		_connection = NULL;
		_timerHide = startTimer(2000);
	}
}

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

/***************************************************************************//**
 * @brief ConnectWindow::onConnectionDisconnected
 */
void ConnectWindow::onConnectionDisconnected()
{
	_connected = false;
	this->updateState();
}