summaryrefslogblamecommitdiffstats
path: root/src/client/connectwindow/connectwindow.cpp
blob: acb9e0921159ddac30752f3e095dea850f1d7b6a (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(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(_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()
{
    /* 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
 */

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

/** set the available rooms.
 *  If the list of rooms is empty, switches automatically to the "manual
 *  connection" page */
void ConnectWindow::setAvailableRooms(QList<Room> m) {
    if (!m.empty()) {
        _ui->comboBox_rooms->clear();
        foreach (Room r, m) {
            _ui->comboBox_rooms->addItem(tr("Room ") + r.name, r.mgr);
        }
        /* also add a pseudo-room "manual choice" */ 
        _ui->comboBox_rooms->addItem(tr("Session Name..."), "manual_connection");
    } else {
        _ui->stackedWidget->setCurrentIndex(1);
    }
}
/***************************************************************************//**
 * 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) {
    qDebug() << "onRoomSelection";
    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)
{
	_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);
	}
}

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 _connection = NULL.
 * @param connection
 */
void ConnectWindow::onConnectionClosed(QObject* connection)
{
	_connection = NULL;
}

/***************************************************************************//**
 * @brief ConnectWindow::onConnectionDisconnected
 */
void ConnectWindow::onConnectionDisconnected()
{
	_state = Idle;
	this->updateUserInterface();
	if (_tryReconnect) {
		this->updateUserInterface();
		connectToSession(_currentSession, _currentIp);
	}
}
void ConnectWindow::onBtnAdvanced() {
    if (_ui->stackedWidget->currentIndex()== 1) {
	    _ui->stackedWidget->setCurrentIndex(0);
    } else {
	    _ui->stackedWidget->setCurrentIndex(1);
    }
}