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

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

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

	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(_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();
}

void ConnectWindow::doShow()
{
	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
 */

/***************************************************************************//**
 * 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)
	{
		_tryReconnect = false;
		// Stop or disconnect
		emit disconnect();
		_state = Idle;
		this->updateUserInterface();
	}
	else
	{
		//  Connect (scan for session)
		// qDebug() << _ui->lineEditName->text().toUtf8();
		connectToSession(_ui->lineEditName->text().toUtf8(), NULL);
	}
}

/***************************************************************************//**
 * 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, bool autoConnect)
{
	_connection = new ServerConnection(host, port, sessionName, certHash, autoConnect);
	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->updateUserInterface();

	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);

		this->updateUserInterface();

		_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()
{
	_state = Idle;
	this->updateUserInterface();
	if (_tryReconnect)
		connectToSession(_ui->lineEditName->text().toUtf8(), NULL);
}