summaryrefslogblamecommitdiffstats
path: root/src/server/connectionframe/connectionframe.cpp
blob: 75d24a4a48c5d2b1941b977f794abfbaff46b913 (plain) (tree)





















                                                                               
                             

                                                                             

                           
                                                                             


                                                                                

                                                                                                                 

                                   

                                                                                                                     




                                                                                        
 
                                                    
 





                                         


















                                                                                                          
                                            





                                                                     
                                                      

                                               















                                                      
                                  






                                   




                                









                                                                          




                               


                                                    

                                   

 




                                                      


                                                  







                                                                                               




                                                 
                             


                                                            
                                 
                                    

 


                                                                  








                                                                                                




                                                                                           




                                                           












                                                                                              


         



                                 





                                                                     



                             





                                                                  



                               


















                                                                           



                                   






                                                                       



                                      





                                                               



                               









                                                                                          



                      











                                                                                                



                                




                                                 
                                 

 



                             




                                             
                                 

 



                                                             
                                        




                                    
                                                                   
                    
                                                                








                                                                                           













                                                           

 
  


        



                                            
                                            
 






                                         
                             
                           
                                 

 




                                   







                                                                          



                                                     

                                                            
                                 

 




                                                     
                                                                            
 
                                 
 
/*
# Copyright (c) 2009 - OpenSLX Project, Computer Center University of Freiburg
#
# This program is free software distributed under the GPL version 2.
# See http://openslx.org/COPYING
#
# If you have any feedback please consult http://openslx.org/feedback and
# send your suggestions, praise, or complaints to feedback@openslx.org
#
# General information about OpenSLX can be found at http://openslx.org/
# -----------------------------------------------------------------------------
# src/gui/connectionFrame.cpp
# -----------------------------------------------------------------------------
*/


#include "connectionframe.h"
#include "../net/client.h"
#include <QPixmap>
#include <QImage>
#include <cassert>

static QString style_student(
	"QLabel{ background-color: #FFF; border-radius: 2px; color: black;} \
	QGroupBox { background-color: #AAA; margin: 2px; border-radius: 4px}"
);
static QString style_tutor(
	"QLabel{ background-color: #FFF; border-radius: 2px; color: black;} \
	QGroupBox { background-color: #70C670; margin: 2px; border-radius: 4px}"
);
static QString style_selectedStudent(
		"QLabel{ background-color: #FFF; border-radius: 2px; color: black; } \
		QGroupBox { background-color: #AAA; margin: 0px; border-radius: 4px; border: 2px solid #6C8CD5;}"
);
static QString style_selectedTutor(
		"QLabel{ background-color: #FFF; border-radius: 2px; color: black;} \
		QGroupBox { background-color: #70C670; margin: 0px;  border-radius: 4px; border: 2px solid #6C8CD5;}"
);
static QString style_disconnected(
		"QLabel{ background-color: #919191; color: black; } \
		QGroupBox { background-color: #7F7F7F; margin: 1px; border-radius: 4px}"
);

static QIcon *term = NULL, *cam = NULL, *eye = NULL;

/**
 * Initialize frame for connected client.
 * @param parent
 * @param width
 * @param height
 */
ConnectionFrame::ConnectionFrame(QWidget *parent, int width, int height) :
        QGroupBox(parent), _client(NULL), _timerId(0), _timerCounter(0), _selected(false), _isTutor(false)
{

	//defines the ui-stuff
	// load icons first
	if (term == NULL)
	{
		term = new QIcon(":terminal");
		cam = new QIcon(":cam32");
		eye = new QIcon(":eye");
	}

	//this->setAttribute(Qt::WA_OpaquePaintEvent);

	 _mainLayout = new QBoxLayout(QBoxLayout::TopToBottom, this);
	 _mainLayout->setSpacing(1);
	 _mainLayout->setMargin(3);
	 _mainLayout->setAlignment(Qt::AlignHCenter);
	 this->setStyleSheet(style_student);

	 _iconLayout = new QBoxLayout(QBoxLayout::RightToLeft, NULL);
	 _iconLayout->setSpacing(1);
	 _iconLayout->setMargin(3);

	 _lblUserName = new QLabel("Test", this);
	 _lblUserName->setAlignment(Qt::AlignHCenter);

	 _lblHostName = new QLabel("PC", this);
	 _lblHostName->setAlignment(Qt::AlignHCenter);

	 _icoCam = addIcon(cam);
	 _icoEye = addIcon(eye);

	 _iconLayout->addWidget(_icoCam);
	 _iconLayout->addWidget(_icoEye);
	 _iconLayout->addStretch();

	 //_layout->addWidget(_imgScreen);
	 _mainLayout->addLayout(_iconLayout);
	 _mainLayout->addStretch();
	 _mainLayout->addWidget(_lblUserName);
	 _mainLayout->addWidget(_lblHostName);
	 this->setLayout(_mainLayout);
	 this->setSize(width, height);
	 this->updateAppearance();
}

ConnectionFrame::~ConnectionFrame()
{
	//
}

/**
 * Add icon to connection frame.
 * @param icon
 * @return Pointer to new Icon.
 */
QLabel* ConnectionFrame::addIcon(const QIcon* icon)
{
	 QLabel *label = new QLabel(this);
	 label->setPixmap(icon->pixmap(24, 24, QIcon::Normal, QIcon::On));
	 label->setAttribute(Qt::WA_TranslucentBackground);
	 label->hide();
	 _icons.append(label);
	 return label;
}

/**
 * Set size of connectionFrame.
 * @param width
 * @param height
 */
void ConnectionFrame::setSize(int width, int height)
{
	this->resize(width, height);
	if (this->_client == NULL)
		showDefaultThumb();
}

/**
 * Assign client to connectionFrame.
 * Set hostName, userName and tutor status to display.
 * @param client
 */
void ConnectionFrame::assignClient(Client* client)
{
	assert(_client == NULL);
	connect( client, SIGNAL(disconnected()),
					 this, SLOT(onClientDisconnected()) );
	connect( client, SIGNAL(thumbUpdated(Client*, const QPixmap&)),
					 this, SLOT(onThumbUpdated(Client*, const QPixmap&)) );
	connect( client, SIGNAL(vncServerStateChange(Client*)),
					 this, SLOT(onVncServerStateChange(Client*)) );
	connect( client, SIGNAL(vncClientStateChange(Client*, int)),
					 this, SLOT(onVncClientStateChange(Client*, int)) );
	_client = client;
	_computerId = client->computerId();
	_lblHostName->setText(client->ip());
	_lblHostName->setToolTip(client->host());
	_lblUserName->setText(client->name());
	_lblUserName->show();
	showDefaultThumb();
	if (_timerId == 0)
		_timerId = startTimer(1000 + qrand() % 150);
	this->updateAppearance();
	_client->setTutor(_isTutor);
}

/**
 * Show default thumg instead of remote screen in connectionFrame.
 */
void ConnectionFrame::showDefaultThumb()
{
	const int width = this->width() - 6;
	const int height = this->height() - 8 - _lblHostName->height() - _lblUserName->height();
	_remoteScreen = term->pixmap(width, height, QIcon::Normal, QIcon::On);
	this->repaint();
	//_imgScreen->setPixmap(_remoteScreen);
}

/**
 * Handle mouse release event on frame.
 * Check if frame was clicked or moved, if not moved enough, the event is handled as click.
 * @param event
 */
void ConnectionFrame::mouseReleaseEvent(QMouseEvent* event)
{
	event->accept();
	if (event->button() == Qt::LeftButton)
	{
		QApplication::setOverrideCursor(QCursor(Qt::OpenHandCursor));
		// Only recognize a move if the distance is larger than _startDragDistance
		if ((this->pos() - _previousPosition).manhattanLength() > _startDragDistance )
		{
			qDebug("Moved");
			emit frameMoved(this);
		}
		else
		{
			qDebug("Clicked");
			move(_previousPosition);
			emit clicked(this);
		}
	}
}

/**
 * Handle if mouse reaches frame.
 * @param event
 */
void ConnectionFrame::enterEvent(QEvent* event)
{
	QApplication::setOverrideCursor(QCursor(Qt::OpenHandCursor));
	event->accept();
}

/**
 * Handle mouse leaves frame.
 * @param event
 */
void ConnectionFrame::leaveEvent(QEvent* event)
{
	QApplication::setOverrideCursor(QCursor(Qt::ArrowCursor));
	event->accept();
}

/**
 * Handle mouse press on frame.
 * @param event
 */
void ConnectionFrame::mousePressEvent(QMouseEvent *event)
{
	if (event->button() == Qt::RightButton)
	{
		// Menu...
	}
	else
	{
	    _clickPoint = event->pos();
	    _previousPosition  = this->pos();
	    QApplication::setOverrideCursor(QCursor(Qt::ClosedHandCursor));
	}
	// On click, the window has to be on the top-level.
	activateWindow();
	raise();
	update();
	event->accept();
}

/**
 * Hanle mouse movement over frame.
 * @param event
 */
void ConnectionFrame::mouseMoveEvent(QMouseEvent *event)
{
	QApplication::setOverrideCursor(QCursor(Qt::ClosedHandCursor));
	move(mapToParent(event->pos()-_clickPoint));
	event->accept();
}

/**
 * Handle double click event on frame.
 * @param event
 */
void ConnectionFrame::mouseDoubleClickEvent(QMouseEvent* event)
{
	emit doubleClicked(this);
	event->accept();
}

/**
 * Draw remote screen in frame.
 * @param event
 */
void ConnectionFrame::paintEvent(QPaintEvent *event)
{
	QGroupBox::paintEvent(event);
	if (_remoteScreen.isNull())
		return;
	QPainter painter(this);
	painter.drawPixmap((this->width() - _remoteScreen.width()) / 2, 4, _remoteScreen);
	event->accept();
}

/**
 * Handle timer event.
 * @param event
 */
void ConnectionFrame::timerEvent(QTimerEvent* event)
{
	if (_client == NULL)
		return;
	++_timerCounter;
	if (_client->isActiveVncServer() && _timerCounter % 5 != 0)
		return;
	const int width = this->width() - 8;
	const int height = this->height() - 9 - _lblHostName->height() - _lblUserName->height();
	_client->requestThumb(width, height);
}

/**
 * Set frame as selected or not.
 * @param selected
 */
void ConnectionFrame::setSelection(bool selected)
{
	if (_selected == selected)
		return;
	_selected = selected;
	this->updateAppearance();
}

/**
 * Set tutor status of frame.
 * @param b
 */
void ConnectionFrame::setTutor(bool b)
{
	if (_isTutor != b && _client != NULL)
		_client->setTutor(b);
	_isTutor = b;
	this->updateAppearance();
}

/**
 * Update appearence of frame.
 * Check tutor status, vnc status and set background or icon.
 */
void ConnectionFrame::updateAppearance()
{
	if (_client == NULL)
	{
		// Unconnected Frame
		if (_selected)
			this->setStyleSheet(style_selectedStudent);
		else
			this->setStyleSheet(style_disconnected);
		for (QList<QLabel*>::iterator it(_icons.begin()); it != _icons.end(); ++it)
			(**it).hide();
		return;
	}
	_icoCam->setVisible(_client->isActiveVncServer());
	_icoEye->setVisible(_client->isActiveVncClient());

	// Normal client, no special stuff active

	if (_selected && _isTutor){
		this->setStyleSheet(style_selectedTutor);
	}
	else if (_isTutor){
		this->setStyleSheet(style_tutor);
	}
	else if (_selected){
		this->setStyleSheet(style_selectedStudent);

	}
	else{
		this->setStyleSheet(style_student);

	}
}

/*
 * Slots
 */

/**
 * Handle if client was disconnected.
 * Kill timer and set appearence to default.
 */
void ConnectionFrame::onClientDisconnected()
{
	if (_timerId != 0)
	{
		killTimer(_timerId);
		_timerId = 0;
	}
	_client = NULL;
	_lblUserName->setText(QString());
	_lblUserName->hide();
	showDefaultThumb();
	this->updateAppearance();
}

/**
 * Update thumb of specific client.
 * @param client
 * @param thumb
 */
void ConnectionFrame::onThumbUpdated(Client* client, const QPixmap& thumb)
{
	assert(client == _client);
	_remoteScreen = thumb;
	//_imgScreen->setPixmap(_remoteScreen);
	this->repaint();
}

/**
 * Update appearence if vnc server state has changed.
 * @param client
 */
void ConnectionFrame::onVncServerStateChange(Client* client)
{
	this->updateAppearance();
}

/**
 * Update appearence if vnc client state has changed.
 * @param client
 * @param lastSource
 */
void ConnectionFrame::onVncClientStateChange(Client* client, int lastSource)
{
	this->updateAppearance();
}