summaryrefslogblamecommitdiffstats
path: root/src/server/connectionframe/connectionframe.cpp
blob: 7d9376c7f7206239cebf613be631137791b002df (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");

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

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

void ConnectionFrame::setSize(int width, int height)
{
	this->resize(width, height);
}

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

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

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

void ConnectionFrame::enterEvent(QEvent* event)
{
	QApplication::setOverrideCursor(QCursor(Qt::OpenHandCursor));
	event->accept();
}

void ConnectionFrame::leaveEvent(QEvent* event)
{
	QApplication::setOverrideCursor(QCursor(Qt::ArrowCursor));
	event->accept();
}

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

void ConnectionFrame::mouseMoveEvent(QMouseEvent *event)
{
	QApplication::setOverrideCursor(QCursor(Qt::ClosedHandCursor));
	move(mapToParent(event->pos()-_clickPoint));
	event->accept();
}

void ConnectionFrame::mouseDoubleClickEvent(QMouseEvent* event)
{
	emit doubleClicked(this);
	event->accept();
}

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

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

void ConnectionFrame::setSelection(bool selected)
{
	if (_selected == selected)
		return;
	_selected = selected;
	this->updateAppearance();
}

void ConnectionFrame::setTutor(bool b)
{
	if (_isTutor != b && _client != NULL)
		_client->setTutor(b);
	_isTutor = b;
	this->updateAppearance();
}

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

void ConnectionFrame::onClientDisconnected()
{
	if (_timerId != 0)
	{
		killTimer(_timerId);
		_timerId = 0;
	}
	_client = NULL;
	_lblUserName->setText(QString());
	showDefaultThumb();
	this->updateAppearance();
}

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

void ConnectionFrame::onVncServerStateChange(Client* client)
{
	this->updateAppearance();
}

void ConnectionFrame::onVncClientStateChange(Client* client, int lastSource)
{
	this->updateAppearance();
}