summaryrefslogblamecommitdiffstats
path: root/src/server/connectionframe/connectionframe.cpp
blob: b5b754fd712badff2450f2de83e2bc911ccf3d34 (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 QIcon *term = NULL, *cam = NULL, *eye = NULL;

static QString backgroundStyle("background-color: %1; margin: 1px; border: 1px solid black; border-radius: 6px");

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

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

	 _lblUserName = new QLabel("Test", this);
	 _lblUserName->setStyleSheet(QString::fromUtf8("background-color: white; color: black;"));
	 _lblUserName->setAlignment(Qt::AlignHCenter);
	 //_lblUsername->resize(_lblUsername->width(), _lblUsername->font().pixelSize());

	 _lblHostName = new QLabel("PC", this);
	 _lblHostName->setStyleSheet(QString::fromUtf8("background-color: white; color: black;"));
	 _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);
}

/**
 * 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());
	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(backgroundStyle.arg("rgb(140, 140, 170)"));
		else
			this->setStyleSheet(backgroundStyle.arg("rgb(140, 140, 140)"));
		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(backgroundStyle.arg("rgb(255, 220, 180)"));
	else if (_isTutor)
		this->setStyleSheet(backgroundStyle.arg("rgb(255, 180, 180)"));
	else if (_selected)
		this->setStyleSheet(backgroundStyle.arg("rgb(180, 180, 210)"));
	else
		this->setStyleSheet(backgroundStyle.arg("rgb(180, 180, 180)"));
}

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