diff options
Diffstat (limited to 'src/gui/frame.cpp')
| -rw-r--r-- | src/gui/frame.cpp | 332 |
1 files changed, 332 insertions, 0 deletions
diff --git a/src/gui/frame.cpp b/src/gui/frame.cpp new file mode 100644 index 0000000..cb79643 --- /dev/null +++ b/src/gui/frame.cpp @@ -0,0 +1,332 @@ +/* +# 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/frame.cpp +# This is the drawingarea, it will be set to the suitable ConnectionFrame. +# Each instance of this class has is own VNCThread, this way is more simple +# to show, update and scale the image from the suitable client. Only the point +# on the image that need to be drawed or scaled will be processed. Thus the CPU +# performance will not be affected. The pvsmgr can manage in this way a lot of clients. +# ----------------------------------------------------------------------------- +*/ + +#include "frame.h" +#include <src/gui/mainWindow.h> +#include <iostream> +#include <QPixmap> + +Frame::Frame(const QString & text, QWidget * parent) : + QLabel(parent), _clientVNCThread(0) +{ + _clientVNCThread = NULL; + + X = 0; + Y = 0; + setBackgroundRole(QPalette::Base); + + setStyleSheet(QString::fromUtf8("QLabel{border-radius:10px;\n" + "background-color: rgb(150,150,150);}")); + + setAlignment(Qt::AlignCenter); + + setAutoFillBackground(true); + setFrameStyle(QFrame::StyledPanel | QFrame::Sunken); + + _isLocked = false; + _dozent = false; + _uy = _ux = 0; + + //QIcon icon; + //icon.addFile(QString::fromUtf8(), QSize(), QIcon::Normal, QIcon::Off); + button_closeUp = createToolButton(tr("View"), QIcon(":/restore"),SLOT(closeUp())); + button_foto = createToolButton(tr("Foto"), QIcon(":/photos"),SLOT(foto())); + button_lock = createToolButton(tr("Lock this client"), QIcon(":/lock"),SLOT(setLock())); + //button_unlock = createToolButton(tr("Unlock this client"), QIcon(":/lock"),SLOT(setLock())); + button_dozent = createToolButton(tr("Set as Superclient"), QIcon(":/dozent2"),SLOT(setDozent())); + + connect(this, SIGNAL(clicked()), this, SLOT(slotClicked())); + ip = ""; + setToolButtonListVisible(false); +} + +Frame::~Frame() +{ + if (_clientVNCThread) + { + disconnect(_clientVNCThread, SIGNAL(imageUpdated(int,int,int,int)), this, + SLOT(updateImage(int,int,int,int))); + disconnect(_clientVNCThread, SIGNAL(finished()), this, + SLOT(iamDown())); + if (_clientVNCThread->isRunning()) + { + _clientVNCThread->terminate = true; + _clientVNCThread->wait(_clientVNCThread->getUpdatefreq()+2000); + } + } +} + + +void Frame::setVNCThreadConnection(VNCClientThread * vncClientThread) +{ + // initialize the vncthread for this connection + //printf("Starting VNC thread for %s\n", ip.toUtf8().data()); + _clientVNCThread = vncClientThread; + + connect(_clientVNCThread, SIGNAL(imageUpdated(int,int,int,int)), this, + SLOT(updateImage(int,int,int,int)), Qt::BlockingQueuedConnection); + connect(_clientVNCThread, SIGNAL(finished()), this, + SLOT(iamDown())); + + // start the thread + if(!_clientVNCThread->terminate) + _clientVNCThread->start(); +} + +/* + * To stop the vncThreadConnection, we only disconnect all connected signals on _clientVNCThread + * We don't need here to terminate the thread, this will appear in vncconnection, because + * we have set this thread there (in vncconnection). + */ +void Frame::stopVNCThreadConnection() +{ + disconnect(_clientVNCThread, SIGNAL(imageUpdated(int,int,int,int)), this, + SLOT(updateImage(int,int,int,int))); + disconnect(_clientVNCThread, SIGNAL(finished()), this, + SLOT(iamDown())); +} + +void Frame::updateImage(int x, int y, int w, int h) +{ + if (_clientVNCThread == NULL) + return; + + if (_clientVNCThread->getSize() != size()) + { + // grow the update rectangle to avoid artifacts + x -= 3; + y -= 3; + w += 6; + h += 6; + + _clientImg = _clientVNCThread->getImage().copy(x, y, w, h); + + qreal sx = qreal(width()) / qreal(_clientVNCThread->getSize().width()); + qreal sy = qreal(height()) / qreal(_clientVNCThread->getSize().height()); + + x = qRound(qreal(x) * sx); + y = qRound(qreal(y) * sy); + w = qRound(qreal(w) * sx); + h = qRound(qreal(h) * sy); + } + else + { + _clientImg = _clientVNCThread->getImage().copy(x, y, w, h); + } + + _ux = w; + _uy = h; + repaint(x, y, w, h); // this will trigger the PaintEvent +} + +void Frame::iamDown() +{ + if (_clientVNCThread == NULL) return; + _clientVNCThread = NULL; + update(); +} + +void Frame::paintEvent(QPaintEvent *event) +{ + QPainter painter(this); + QRect r = event->rect(); + event->accept(); + + if (_clientImg.isNull()) + { + _clientImg = QImage(":/terminal"); + painter.drawImage(28,0, _clientImg.scaled(145,123, Qt::KeepAspectRatio, Qt::SmoothTransformation)); + setAlignment(Qt::AlignCenter); + return; + } + + if(_isLocked) + { + _clientImg = QImage(":/lock"); + painter.drawImage(28,0, _clientImg.scaled(145,123, Qt::KeepAspectRatio, Qt::SmoothTransformation)); + setAlignment(Qt::AlignCenter); + return; + } + + if (_clientVNCThread != NULL) + { + if (r.width() != _ux || r.height() != _uy) + { + _clientImg = _clientVNCThread->getImage(); // redraw complete image (e.g. on resize) + r = rect(); + } + else + { + _ux = -1; + } + + if (_clientVNCThread->getSize() == size()) + { + + painter.drawImage(r.topLeft(), _clientImg); // don't scale + } + else + { + QImage i = _clientImg.scaled(r.size(), Qt::IgnoreAspectRatio, Qt::SmoothTransformation); + painter.drawImage(r.topLeft(), i); + } + } + else + { + _clientImg = QImage(":/terminal"); + painter.drawImage(28,0, _clientImg.scaled(145,123, Qt::KeepAspectRatio, Qt::SmoothTransformation)); + setAlignment(Qt::AlignCenter); + } +} + +void Frame::slotClicked() +{ + //qDebug() << "clickableLabel :: Clicked, searching for" << ip; + + if (ip != "") { + for (int i=0; i<MainWindow::getConnectionList()->model->rowCount(QModelIndex()); i++) + { + if (MainWindow::getConnectionList()->model->index(i, 1, QModelIndex()).data(Qt::DisplayRole).toString() + .compare(ip) == 0) + { + MainWindow::getConnectionList()->selectRow(i); + MainWindow::getConnectionList()->setCurrentIndex(MainWindow::getConnectionList()->currentIndex()); + break; + } + } + } +} + +void Frame::mousePressEvent(QMouseEvent* event) +{ + emit clicked(); + if (event->button() == Qt::RightButton) + { + /*if (!_dummy) + DelDummy->setDisabled(true); + menu->exec(QCursor::pos());*/ + } + else + { + + } + QLabel::mousePressEvent(event); +} + +void Frame::mouseReleaseEvent ( QMouseEvent * event ) +{ + QLabel::mouseReleaseEvent(event); +} + +QToolButton* Frame::createToolButton(const QString &toolTip, const QIcon &icon, const char *member) + { + QToolButton *button = new QToolButton(this); + button->setToolTip(toolTip); + button->setIcon(icon); + button->setIconSize(QSize(15, 15)); + button->setStyleSheet(QString::fromUtf8("background-color: rgb(230, 230, 230);")); + addButton(button); + toolButtonList.append(button); + connect(button, SIGNAL(clicked()), this, member); + + return button; +} + +void Frame::addButton(QToolButton *button) +{ + button->move(X,Y); + Y += button->size().height()-5; +} + +void Frame::setToolButtonListVisible(bool visible) +{ + foreach (QToolButton* tb, toolButtonList) + tb->setVisible(visible); + if (visible && MainWindow::getConnectionWindow()->hasDozent && !_dozent) + button_dozent->setVisible(false);//At this time this button should only be visible on the dozent machine (the superclient). + +} + +void Frame::setLockStatus(bool lock) +{ + if (lock) + { + button_lock->setToolTip(tr("Unlock this client")); + //button_lock->setIcon() TODO + } + else + { + button_lock->setToolTip(tr("Lock this client")); + //button_lock->setIcon() TODO + } + _isLocked = lock; +} + +QImage Frame::getImageForFoto() +{ + return _clientVNCThread->getImage(); +} + +void Frame::closeUp() +{ + emit clicked(); + MainWindow::getWindow()->closeUp(); +} + +void Frame::foto() +{ + emit clicked(); + MainWindow::getWindow()->foto(); +} + +void Frame::setLock() +{ + if (!_dozent) + { + emit clicked(); + if (_isLocked) + MainWindow::getConnectionWindow()->unlockStations(); + else + MainWindow::getConnectionWindow()->lockStations(); + } + else + { + QString message = QString(tr("You can't lock a Superclient-machine.")); + QMessageBox::information(this, "PVS", message); + } +} + +void Frame::setDozent() +{ + if (_dozent) + { + button_dozent->setToolTip(tr("Set client as Superclient")); + _dozent = false; + MainWindow::getConnectionWindow()->hasDozent = false; + getConFrame()->setDozent(false); + } + else + { + button_dozent->setToolTip(tr("Unset client as Superclient")); + _dozent = true; + MainWindow::getConnectionWindow()->hasDozent = true; + getConFrame()->setDozent(true); + } +} |
