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





                          
                       
                            
                   



                                    
                         
                                                   
                                   
 


                       
                                                                                
         








                                                                              
                                                                                     
 
                                                

               
                                                          







                                                                                


                                                                              
   

                                                                                     

                                          
               
 
 
                          
                                          
                                                

                                                                    
         





                                                                                






                                                                              




                                                                                     

                    



                            
                    
 

                              
                                

                           
                                   


                                                                                                            
 
                                   
                                   

                                       
                                                 
                                                     


                                                                                                                  
 

                        
 
                                  
                                       
                                                                                            
                
                                                                  

                                                   
 
                                      
                                                                                          


                                                                                                
                                                                      

                                                       
 


                                                      
                                                                                        
                                               
 
                                                 
                                                                                                                        
 
                          

                                                             
                                                                                                       
 
                              
                                    

                                                                       
                         
                         
                                                                



                                                                            

 



                                                                             

                        

                                                           

                                                              
                                                                   
                                                           

                                                  
                                      

                                         
                                          




                                     
                                                                        
 
                                                                                 
                                    



                                                                                  
                                                                                           
                                                                                           


                                                                               




                                                                                




                                      
                   

 
  

           






                                                                                

                                   
                           


                               






                                                                                

                                   

                          


                               





                                                                                                          
 

                                                                         

                              
 
                            
 
                                             
 
                                       
                                                   
                               

         
                                                                    
 
                                                                                    
                                                                
                                         
                                           


                                                                  
                                               
                                                                                                 
                 

                                                                
 












                                                                                            
                                 
                                                 
                         
                 
                                 
         


                                                                      


                                                                                    







                                         

 
  


        
                                                                                


                                                                              

                           
                                    
                       

                                                        
                

                                                                                            
         

 
                                                                                




                                                                         
 
                       
                                    
                                                           
                                                         

                          
                                   
                                                    



                                                             

 



                                                                                

                              
                                
                                                
                           

                                                   
 

                                                
                                             

                           

 





                                                                                

                                                       

                                               
 
                                             

                                                     

                                            
          
                                  
                                                                                              



                                                    
                                                                                   
                                                                                                                                            
                                                                                                                                 
                                                                      
                                                                                                                     
                                                                                                                              

 


                                                                                





                                                    









                                                     



                                                                                
                       
 
                                                                                           
                                                                                                                



                                                             

 
                                                                                




                                  









                                                                                       


                      

                                     


                                                       
                                                                                

                                                       




                                                             
 










                                                                              

 
                                                        


                            
                                                     
                 
                                                                                                  

                                                                                             
         
                                  
 
 

                                
                                                                 
                                                       
                                                   
                                                                                                         
 
                                                                          
 


                                                                                          
 
 

                             
                                              
                                          
 
 
/*
 * toolbar.cpp
 *
 *  Created on: 21.01.2013
 *      Author: sr
 */
#include <QtAlgorithms>
#include <QNetworkInterface>
#include <QProcess>
#include "../../shared/settings.h"
#include "../net/serverconnection.h"
#include "../vnc/vncwindow.h"
#include "../vnc/vncserver.h"
#include "../util/util.h"
#include "../informationdialog/informationdialog.h"
#include "../clientapp/clientapp.h"

#include "toolbar.h"
#include "ui_toolbar.h"

/***************************************************************************//**
 * @brief
 *
 * Does exact teh same as Toolbar::Toolbar(QWidget *parent) but additionally
 * instantly tries to connect to a pvsmgr with the given sessionName.
 * @param sessionName The session to connect to.
 * @param parent If parent is 0, the new widget becomes a window. If parent is
 * another widget, this widget becomes a child window inside parent. The new
 * widget is deleted when its parent is deleted.
 */
Toolbar::Toolbar(const QByteArray sessionName, QWidget *parent)
	: QWidget(parent), _hideTimer(this), _blinkTimer(this), _beWatchedEye(":eye")
{
	qDebug() << "sessionName - constructor";
	init();

	_connectWindow->connectToSession(sessionName, "");
}

/***************************************************************************//**
 * @brief Constructor of the Toolbar.
 *
 * Does exact the same as Toolbar::Toolbar(QWidget *parent) but additionally
 * instantly tries to connect to the pvsmgr in its room without sessionName.
 * @param autoConnect
 * @param parent If parent is 0, the new widget becomes a window. If parent is
 * another widget, this widget becomes a child window inside parent. The new
 * widget is deleted when its parent is deleted.
 */
Toolbar::Toolbar(const bool autoConnect, QWidget *parent)
	: QWidget(parent), _hideTimer(this), _blinkTimer(this), _beWatchedEye(":eye")
{
	qDebug() << "auto - constructor!";
	init();


	if (autoConnect) {
		// Try getting manager ip.
		QString mgrIp = identifyMgrIP();
		if (!mgrIp.isEmpty())
			_connectWindow->connectToSession("", mgrIp);
	}
}

/***************************************************************************//**
 * @brief  Constructor of the Toolbar.
 *
 * Constructs a widget which is a child of parent.
 * Initialize the GUI and sets up the menu, sets window properties, create the
 * VNC- and connect-window, connects the necessary signals, sets the UI's
 * position and configuires the timer for the UI to be hidden.
 * @param parent If parent is 0, the new widget becomes a window. If parent is
 * another widget, this widget becomes a child window inside parent. The new
 * widget is deleted when its parent is deleted.
 */
Toolbar::Toolbar(QWidget *parent)
	: QWidget(parent), _hideTimer(this), _blinkTimer(this), _beWatchedEye(":eye")
{
	init();
}
void Toolbar::exit()
{
	this->close();
	this->deleteLater();
	qApp->quit();
}
void Toolbar::init()
{
	_ui = new Ui::Toolbar;
	_connection = NULL;
	/* Initialize the GUI */
	_ui->setupUi(this);

	/* Set window properties */
	setWindowFlags(Qt::WindowStaysOnTopHint | Qt::X11BypassWindowManagerHint | Qt::FramelessWindowHint);
	setAttribute(Qt::WA_AlwaysShowToolTips);
	setAttribute(Qt::WA_QuitOnClose);

	/* Create the VNC Window */
	_vnc = new VncWindow(NULL);

	/* Create the connect window */
	_connectWindow = new ConnectWindow(NULL);
	_connectWindow->setAvailableRooms(myRooms());
	// Connect the signals
	connect(_connectWindow, SIGNAL(disconnect()), this, SLOT(onDoDisconnect()));
	connect(_connectWindow, SIGNAL(connected(ServerConnection*)), this, SLOT(onConnected(ServerConnection*)));

	/* Setup menu */
	initMenu();

	/* setup manager button */
	if (clientApp->isManagerPc()) {
		connect(_ui->btnManager, SIGNAL(toggled(bool)), this, SLOT(onBtnManager()));
	} else {
		setFixedWidth(width() - _ui->btnManager->width());
		_ui->btnManager->setVisible(false);
	}

	/* setup lock desktop button*/
	bool showLock = clientApp->getSettings()->value("showLockDesktopButton").toBool();
	if (showLock) {
		connect(_ui->btnLockDesktop, SIGNAL(clicked()), this, SLOT(onBtnLockDesktop()));
	} else {
		setFixedWidth(width() - _ui->btnLockDesktop->width());
		_ui->btnLockDesktop->setVisible(false);
	}

	/* hide attention button while disconnected */
	_ui->btnAttention->setVisible(false);

	connect(_ui->btnAttention, SIGNAL(toggled(bool)), this, SLOT(onBtnAttention()));
	_ui->btnAttention->setMaximumWidth(30);

	/* Connect the signals from vnc server */
	connect(VncServer::instance(), SIGNAL(started(int, QString&, QString&)), this, SLOT(onVncServerIsRunning(int)));

	/* Set position */
	const QDesktopWidget desktop;
	const QRect primaryScreen = desktop.screenGeometry();
	move(primaryScreen.left() + (primaryScreen.width() - this->width()) / 2 , primaryScreen.top());

	/* Setup hide timer */
	_hideTimer.setInterval(500);
	_hideTimer.setSingleShot(true);
	connect(&_hideTimer, SIGNAL(timeout()), this, SLOT(hideBar()));
	setVisible(true);
	activateWindow();
	_hideTimer.start(); // initially show PVS and hide later

	/* Setup blink timer */
	_blinkTimer.setInterval(500);
	connect(&_blinkTimer, SIGNAL(timeout()), this, SLOT(cameraBlink()));
}

/**
 * This function should be called once from the main init() function which in
 * turn should only be called by the constructor.
 **/
void Toolbar::initMenu()
{
	_menu = new QMenu(this);
	_acnConnect = new QAction(tr("&Connect..."), this);
	_acnDisconnect = new QAction(tr("&Disconnect"), this);
	_acnDisconnect->setEnabled(false);
	_acnInformation = new QAction(tr("&Information..."), this);
	_acnAbout = new QAction(tr("&What's this?"), this);
	_acnQuit = new QAction(tr("&Quit"), this);

	_menu->addAction(_acnConnect);
	_menu->addAction(_acnDisconnect);
	_menu->addSeparator();
	_menu->addAction(_acnInformation);
	_menu->addAction(_acnAbout);
	_menu->addSeparator();
	_menu->addAction(_acnQuit);
	_ui->cmdMenu->setMenu(_menu);

	/* only add a "quit"-button when the configuration allows it. */

	bool allow = clientApp->getSettings()->value("allowClientQuit").toBool();
	_acnQuit->setVisible(allow);

	// Connect the signals
	connect(_menu, SIGNAL(aboutToHide()), this, SLOT(hideBar()));
	connect(_acnConnect, SIGNAL(triggered()), _connectWindow, SLOT(doShow()));
	connect(_acnDisconnect, SIGNAL(triggered()), _connectWindow, SLOT(DoDisconnect()));
	connect(_acnInformation, SIGNAL(triggered()), this, SLOT(showInformationDialog()));
	connect(_acnAbout, SIGNAL(triggered()), this, SLOT(showAboutDialog()));
	connect(_acnQuit, SIGNAL(triggered()), this, SLOT(exit()));
}

/***************************************************************************//**
 * Destructor of the Toolbar. Destroys the widget. All this widget's children
 * are deleted first.
 */
Toolbar::~Toolbar()
{
	VncServer::instance()->stop();
	_vnc->deleteLater();
	_connectWindow->deleteLater();
	delete _ui;
}

/*
 * Override
 */

/***************************************************************************//**
 * This event is reimplemented to receive widget leave events. When the mouse
 * cursor leaves the widget, a timer gets started which, when timed out, hides
 * the Toolbar.
 * @param e The leave event (Mouse leaves widget's boundaries.)
 */
void Toolbar::leaveEvent(QEvent* e)
{
	_hideTimer.start();
	QWidget::leaveEvent(e);
}


/***************************************************************************//**
 * This event is reimplemented to receive widget enter events. When the mouse
 * cursor enters the widget, the timer  which, when timed out, hides
 * the Toolbar, gets stopped.
 * @param e The enter event (Mouse enters widget's boundaries.)
 */
void Toolbar::enterEvent(QEvent* e)
{
	_hideTimer.stop();
	showBar();
	QWidget::enterEvent(e);
}

/*
*  CFG to test this
*  http://git.openslx.org/tm-scripts.git/plain/server/modules/pvs2-freiburg/etc/xdg/openslx/pvs2client.ini
*
*/


/* returns a sorted list of available rooms.
 * (Available means that this client is configured to be in that room) */
QList<Room> Toolbar::myRooms()
{

	QList<Room> myRooms;

	auto conf = clientApp->getSettings();

	if (!conf->contains("rooms")) {
		qDebug() << "Invalid config file!";
		return myRooms;
	}

	QStringList roomNames = conf->value("rooms").toStringList();

	/* go through all rooms and check if this client is a member of the room. */
	auto localAddresses = QNetworkInterface::allAddresses();
	for (auto roomName : roomNames) {
		conf->beginGroup(roomName);
		if (conf->contains("name")) {
			roomName = conf->value("name").toString();
		}
		if (!conf->contains("mgrIP")) {
			qDebug() << "Room " << roomName << " has no mgrIP: Invalid config file!";
		}
		QString mgrIP = conf->value("mgrIP").toString();
		int priority = conf->value("priority").toInt();

		if (mgrIP.length() != 0) {
			foreach (const QHostAddress & address, localAddresses) {
				int size = conf->beginReadArray("client");
				for (int j = 0; j < size; ++j) {
					conf->setArrayIndex(j);
					QString ip = conf->value("ip").toString();
					if (address != QHostAddress(QHostAddress::LocalHost)
							  && ip == address.toString() ) {
						/* add this room to the list */
						Room r(roomName, mgrIP, priority);
						myRooms << r;
						break;
					}
				}
				conf->endArray();
			}
		}
		conf->endGroup();
	}
	/* sort */
	qStableSort(myRooms.begin(), myRooms.end(), qGreater<Room>());
	return myRooms;
}
/** Identifies the responsible manager for this client by searching through the
 * configuration file. The manager whose room has the highest priority is chosen. */
QString Toolbar::identifyMgrIP()
{
	QList<Room> rooms = myRooms();
	if (!rooms.empty()) {
		return rooms.first().mgr;
	} else {
		return "";
	}
}

/*
 * Slots
 */

/***************************************************************************//**
 * A slot for changing the camera icon. This slot should be called permanently
 * if the vnc server is recording  the screen.
 */
void Toolbar::cameraBlink()
{
	static bool showEye = false;
	if (!showEye) {
		_ui->icon_cam->setPixmap(_beWatchedEye);
		showEye = true;
	} else {
		_ui->icon_cam->setPixmap(QPixmap()); // set empty pixmap for blinking effect
		showEye = false;
	}
}

/***************************************************************************//**
 * A slot for the VncServerIsRunning signal. This slot will change the UI
 * according to the state fo the VncServer.
 * @param[in] port Indicates the state of the VncServer.
 */
void Toolbar::onVncServerIsRunning(int port)
{
	if (port > 0) {
		_blinkTimer.start();
		_ui->lblStatus->setStyleSheet("color:red");
		_ui->lblStatus->setText(tr("Streaming"));
		showBar();
	}	else {
		_blinkTimer.stop();
		_ui->icon_cam->setPixmap(QPixmap());
		_ui->lblStatus->setStyleSheet("color:green");
		_ui->lblStatus->setText(tr("Online"));
		hideBar();
	}
}

/***************************************************************************//**
 * A slot for the onDisconnected signal of the ConnectWindow. This slot will
 * change the UI according to the state fo the connection.
 */
void Toolbar::onDisconnected()
{
	if (_connection != NULL)
		_connection->blockSignals(true);
	_connection = NULL;
	_ui->lblStatus->setStyleSheet("color:red");
	_ui->lblStatus->setText(tr("Offline"));

	this->_acnConnect->setEnabled(true);
	this->_acnDisconnect->setEnabled(false);
	_ui->btnAttention->setVisible(false);
	onBtnAttention();
	_hideTimer.start();
}

/***************************************************************************//**
 * A slot for the onConnected signal of the ConnectWindow. This slot will
 * change the UI according to the state of the connection and connect the
 * relevant signals and slots.
 * @param connection Pointer to the ServerConnection
 */
void Toolbar::onConnected(ServerConnection* connection)
{
	this->_acnConnect->setEnabled(false);
	this->_acnDisconnect->setEnabled(true);

	_ui->btnAttention->setChecked(false);
	_ui->lblStatus->setStyleSheet("color:green");
	_ui->lblStatus->setText(tr("Online"));
	/* connected, show button */
	_ui->btnAttention->setVisible(true);
	//
	if (_connection != NULL) {
		disconnect(_connection, SIGNAL(disconnected()), this, SLOT(onDisconnected()));
		_connection->blockSignals(true);
		_connection->disconnectFromServer();
	}
	_connection = connection;
	connect(_connection, SIGNAL(disconnected()), this, SLOT(onDisconnected()));
	connect(_connection, SIGNAL(openVnc(const QString&, int, const QString&, bool, bool, const QString&, const int, const QByteArray&)),
	        _vnc, SLOT(open(const QString&, int, const QString&, bool, bool, const QString&, const int, const QByteArray&)));
	connect(_connection, SIGNAL(closeVnc()), _vnc, SLOT(close()));
	connect(_connection, SIGNAL(attentionChanged(const bool)), this, SLOT(onServerAttentionChanged(const bool)));
	connect(_vnc, SIGNAL(running(const bool, const int)), _connection, SLOT(onVncViewerStartStop(const bool, const int)));
}

/***************************************************************************//**
 *
 */
void Toolbar::onDoDisconnect()
{
	if (_connection != NULL)
		_connection->disconnectFromServer();
}

void Toolbar::onServerAttentionChanged(const bool on)
{
	_ui->btnAttention->setChecked(on);
	if (on) {
		showBar();
	} else {
		hideBar();
	}
}

/***************************************************************************//**
 * This slot hides the toolbar. Places the toolbar hidden behind the edge of the
 * screen just showing 2 pixels.
 */
void Toolbar::hideBar()
{
	// Don't hide window if any menu is open or VNC Server is running from this client.
	if (_menu->isVisible() || _ui->btnAttention->isChecked() || VncServer::instance()->isVncServerRunning())
		return;
	const QDesktopWidget desktop;
	const QRect primaryScreen = desktop.screenGeometry();
	move(x(), primaryScreen.top() + 2 - height());
}

/***************************************************************************//**
 * @brief Toolbar::showAboutDialog
 */
void Toolbar::showAboutDialog()
{
	QMessageBox msgBox(
	    QMessageBox::NoIcon,
	    tr("About PVS Client"),
	    tr("The PVS - client is part of a software system for managing the "\
	       "virtual data traffic within the computer pools, between the tutor's "\
	       "and student's PCs. It has been developed to simplify the information "\
	       "traffic in seminars and general eLearning."),
	    QMessageBox::NoButton,
	    this,
	    Qt::Dialog | Qt::MSWindowsFixedSizeDialogHint | Qt::WindowStaysOnTopHint);
	msgBox.setIconPixmap(QIcon(":cam32.svg").pixmap(64, 64));
	msgBox.exec();
}

void Toolbar::showInformationDialog()
{
	InformationDialog* d = new InformationDialog();
	d->exec();
}
/***************************************************************************//**
 * This slot shows the toolbar. Used after a hideBar().
 */
void Toolbar::showBar()
{
	const QDesktopWidget desktop;
	const QRect primaryScreen = desktop.screenGeometry();
	move(x(), primaryScreen.top());
}

void Toolbar::onBtnAttention()
{
	const bool on = _connection != NULL && _ui->btnAttention->isChecked();
	if (on != _ui->btnAttention->isChecked()) {
		_ui->btnAttention->setChecked(on);
		return;
	}
	if (_connection != NULL) {
		_connection->sendAttention(on);
	}
}

/** call script to switch to workspace of the manager */
void Toolbar::onBtnManager()
{
	QProcess switchP;
	const bool on = _ui->btnManager->isChecked();
	if (on) {
		switchP.start("/bin/sh", QStringList() << "/opt/openslx/pvs2/switchToManager.sh");
	} else {
		switchP.start("/bin/sh", QStringList() << "/opt/openslx/pvs2/switchBack.sh");
	}
	switchP.waitForFinished();
}

void Toolbar::onBtnLockDesktop()
{
	if (this->lockDesktopP.state() == QProcess::NotRunning) {
		_ui->btnLockDesktop->setEnabled(false);
		_ui->btnManager->setEnabled(false);
		this->lockDesktopP.start("/bin/sh", QStringList() << "/opt/openslx/pvs2/lockDesktop.sh");

		QTimer::singleShot(2 * 1000, this, SLOT(enableLockBtn()));

	} else {
		qDebug() << "trying to use lockDesktop-process while it is still running";
	}
}

void Toolbar::enableLockBtn()
{
	_ui->btnLockDesktop->setEnabled(true);
	_ui->btnManager->setEnabled(true);
}