diff options
| author | Fabian Schillinger | 2010-11-01 17:35:27 +0100 |
|---|---|---|
| committer | Fabian Schillinger | 2010-11-01 17:35:27 +0100 |
| commit | ea3fb17345e5f82db9f2e98a8062e95797700ace (patch) | |
| tree | 1da0d1a8ec9455364386af78762d0f6fed187824 /src/gui/frame.cpp | |
| parent | Process start/stop/view functionality (diff) | |
| parent | [PVSGUI] No X required for --help and --version (diff) | |
| download | pvs-ea3fb17345e5f82db9f2e98a8062e95797700ace.tar.gz pvs-ea3fb17345e5f82db9f2e98a8062e95797700ace.tar.xz pvs-ea3fb17345e5f82db9f2e98a8062e95797700ace.zip | |
Merge branch 'master' of openslx.org:pvs
Conflicts:
CMakeLists.txt
src/core/pvsConnectionManager.cpp
src/pvs.cpp
src/pvs.h
Diffstat (limited to 'src/gui/frame.cpp')
| -rw-r--r-- | src/gui/frame.cpp | 304 |
1 files changed, 292 insertions, 12 deletions
diff --git a/src/gui/frame.cpp b/src/gui/frame.cpp index cb79643..1b80c3d 100644 --- a/src/gui/frame.cpp +++ b/src/gui/frame.cpp @@ -18,11 +18,16 @@ # ----------------------------------------------------------------------------- */ +#include <src/input/inputEvent.h> +#include <src/input/inputHandlerChain.h> #include "frame.h" #include <src/gui/mainWindow.h> #include <iostream> #include <QPixmap> +#define MOUSE_MOTION_SEND_INTERVAL 100 /* msecs */ +#define SPECIAL_EVENT_WAIT_TIME 5000 /* msecs */ + Frame::Frame(const QString & text, QWidget * parent) : QLabel(parent), _clientVNCThread(0) { @@ -51,10 +56,30 @@ Frame::Frame(const QString & text, QWidget * parent) : 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())); + button_control = createToolButton(tr("Enable Remote Control"), QIcon(":/remotecontrol"), SLOT(remoteControlClicked())); + button_control->setCheckable(true); + button_control_all = createToolButton(tr("Remote Control All Clients"), QIcon(":/remotecontrolall"), SLOT(remoteControlAllClicked())); + button_control_all->setCheckable(true); connect(this, SIGNAL(clicked()), this, SLOT(slotClicked())); ip = ""; setToolButtonListVisible(false); + + _remoteControlEnabled = false; + _remoteControlToAll = false; + + _mouseMotionEventTimer = new QTimer(this); + _mouseMotionEventTimer->setInterval(MOUSE_MOTION_SEND_INTERVAL); + _mouseMotionEventTimer->setSingleShot(false); + connect(_mouseMotionEventTimer, SIGNAL(timeout()), this, SLOT(sendMouseMotionEvent())); + + _mousePositionChanged = true; + + _specialEventTimer = new QTimer(this); + _specialEventTimer->setInterval(SPECIAL_EVENT_WAIT_TIME); + _specialEventTimer->setSingleShot(true); + connect(_specialEventTimer, SIGNAL(timeout()), this, SLOT(showSpecialEventMenu())); + } Frame::~Frame() @@ -216,23 +241,45 @@ void Frame::slotClicked() void Frame::mousePressEvent(QMouseEvent* event) { - emit clicked(); - if (event->button() == Qt::RightButton) - { - /*if (!_dummy) - DelDummy->setDisabled(true); - menu->exec(QCursor::pos());*/ - } - else - { + if(!_remoteControlEnabled) + { + emit clicked(); + if (event->button() == Qt::RightButton) + { + /*if (!_dummy) + DelDummy->setDisabled(true); + menu->exec(QCursor::pos());*/ + } + else + { - } - QLabel::mousePressEvent(event); + } + QLabel::mousePressEvent(event); + } + else + { + event->accept(); + ConsoleLog writeLine("Captured remote control mousePressEvent"); + + updateMousePosition(event); + sendInputEvent(InputEvent::mousePressRelease(event->button(), event->buttons())); + } } void Frame::mouseReleaseEvent ( QMouseEvent * event ) { - QLabel::mouseReleaseEvent(event); + if(!_remoteControlEnabled) + { + QLabel::mouseReleaseEvent(event); + } + else + { + event->accept(); + ConsoleLog writeLine("Captured remote control mouseReleaseEvent"); + + updateMousePosition(event); + sendInputEvent(InputEvent::mousePressRelease(event->button(), event->buttons())); + } } QToolButton* Frame::createToolButton(const QString &toolTip, const QIcon &icon, const char *member) @@ -330,3 +377,236 @@ void Frame::setDozent() getConFrame()->setDozent(true); } } + +void Frame::remoteControlClicked() +{ + if(_remoteControlEnabled) + { + setMouseTracking(false); + _mouseMotionEventTimer->stop(); + button_control->setToolTip(tr("Enable Remote Control")); + _remoteControlEnabled = false; + button_control->setChecked(false); + releaseKeyboard(); + } + else + { + button_control->setToolTip(tr("Disable Remote Control")); + _remoteControlEnabled = true; + button_control->setChecked(true); + _mouseMotionEventTimer->start(); + setMouseTracking(true); + if(_mouseOver) + grabKeyboard(); + } +} + +void Frame::remoteControlAllClicked() +{ + if(_remoteControlToAll) + { + button_control_all->setToolTip(tr("Remote Control only this Client")); + button_control_all->setChecked(false); + _remoteControlToAll = false; + } + else + { + button_control_all->setToolTip(tr("Remote Control All Clients")); + button_control_all->setChecked(true); + _remoteControlToAll = true; + } +} + + + +void Frame::sendMouseMotionEvent() +{ + InputEvent evt = InputEvent::mouseMotion(_lastRecordedMousePosition.x(), _lastRecordedMousePosition.y()); + + if(!_mousePositionChanged) + return; + + _mousePositionChanged = false; + sendInputEvent(evt); +} + +void Frame::sendInputEvent(InputEvent const& evt) +{ + QString str; + eventToString(evt, str); + std::string evtStr = evt.toString(); + PVSMsg msg(PVSCOMMAND, "INPUTEVENT", str); + + if(_remoteControlEnabled) + { + if(_remoteControlToAll) + { + ConsoleLog writeLine(QString("sendInputEvent(%1) to one").arg(evtStr.c_str())); + PVSConnectionManager::getManager()->getServer()->sendToAll(msg); + } + else + { + ConsoleLog writeLine(QString("sendInputEvent(%1) to all").arg(evtStr.c_str())); + _cFrame->getConnection()->sendMessage(msg); + } + } + else + { + ConsoleLog writeLine("sendMouseMotionEvent() disabled"); + } +} + +void Frame::mouseMoveEvent(QMouseEvent* event) +{ + QPoint newPosition = rescalePosition(event->posF()); + if(newPosition != _lastRecordedMousePosition) { + _lastRecordedMousePosition = newPosition; + _mousePositionChanged = true; + ConsoleLog writeLine(QString("Mouse moved to (%1,%2)").arg(_lastRecordedMousePosition.x()).arg(_lastRecordedMousePosition.y())); + } +} + +QPoint Frame::rescalePosition(QPointF guipos) +{ + if(!_clientVNCThread) + return QPoint(); + + QSize s = size(); + QSize t = _clientVNCThread->getSize(); + qreal px, py; + px = guipos.x() * t.width() / (qreal)s.width(); + py = guipos.y() * t.height() / (qreal)s.height(); + return QPoint((int)px, (int)py); +} + +void Frame::updateMousePosition(QMouseEvent* event) +{ + QPoint oldPosition = _lastRecordedMousePosition; + _lastRecordedMousePosition = rescalePosition(event->posF()); + _mousePositionChanged = oldPosition != _lastRecordedMousePosition; + sendMouseMotionEvent(); +} + +void Frame::enterEvent(QEvent* event) +{ + _mouseOver = true; + if(_remoteControlEnabled) + { + grabKeyboard(); + } +} + +void Frame::leaveEvent(QEvent* event) +{ + _mouseOver = false; + if(_remoteControlEnabled) + { + releaseKeyboard(); + } +} + +void Frame::keyPressEvent(QKeyEvent* event) +{ + if(_remoteControlEnabled) + { + if(event->key() == Qt::Key_Menu) + { + qDebug("Menu has been pressed"); + if(!event->isAutoRepeat()) + _specialEventTimer->start(); + } + else + { + // The action of the keyboard may depend on the position of the pointer + sendMouseMotionEvent(); + sendInputEvent(InputEvent::keyboardPress(event->key(), event->modifiers())); + } + } + else + { + QLabel::keyPressEvent(event); + } +} + +void Frame::keyReleaseEvent(QKeyEvent* event) +{ + if(_remoteControlEnabled) + { + sendMouseMotionEvent(); + if(event->key() == Qt::Key_Menu) + { + if(!event->isAutoRepeat()) + { + qDebug("Menu has been released"); + if(_specialEventTimer->isActive()) + { + qDebug("Pressing key on client"); + // Pressing the key has been deferred, so do it now: + sendInputEvent(InputEvent::keyboardPress(event->key(), event->modifiers())); + } + sendInputEvent(InputEvent::keyboardRelease(event->key(), event->modifiers())); + _specialEventTimer->stop(); + } + } + else + { + // The action of the keyboard may depend on the position of the pointer + sendInputEvent(InputEvent::keyboardRelease(event->key(), event->modifiers())); + } + } + else + { + QLabel::keyReleaseEvent(event); + } +} + +bool Frame::event(QEvent* event) +{ + if(_remoteControlEnabled) + { + bool recognized; + switch(event->type()) + { + case QEvent::ShortcutOverride: + recognized = true; + event->accept(); + break; + case QEvent::KeyPress: + recognized = true; + keyPressEvent(static_cast<QKeyEvent*>(event)); + break; + case QEvent::KeyRelease: + recognized = true; + keyReleaseEvent(static_cast<QKeyEvent*>(event)); + break; + default: + recognized = false; + } + if(recognized && event->isAccepted()) + return true; + } + return QLabel::event(event); +} + +void Frame::showSpecialEventMenu() +{ + qDebug("Trying to show menu..."); + QMenu* menu = new QMenu(this); + QList<SpecialInputEventDescription> specialEvents = privileged_handler_chain::describe(); + QList<SpecialInputEventDescription>::iterator iter; + int i; + for(i = 0, iter = specialEvents.begin(); + iter != specialEvents.end(); + iter++, i++) + { + QAction* act = menu->addAction((*iter).descriptionString); + act->setData(i); + } + QAction* selected = menu->exec(QCursor::pos()); + if(selected) + { + int index = selected->data().toInt(); + sendInputEvent(specialEvents.at(index).toEvent()); + } + delete menu; +} |
