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 | |
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')
-rw-r--r-- | src/gui/clientConfigDialog.cpp | 28 | ||||
-rw-r--r-- | src/gui/clientConfigDialog.h | 3 | ||||
-rw-r--r-- | src/gui/clientFileReceiveDialog.cpp | 95 | ||||
-rw-r--r-- | src/gui/clientFileReceiveDialog.h | 14 | ||||
-rw-r--r-- | src/gui/clientFileSendDialog.cpp | 201 | ||||
-rw-r--r-- | src/gui/clientFileSendDialog.h | 21 | ||||
-rw-r--r-- | src/gui/connectionWindow.h | 3 | ||||
-rw-r--r-- | src/gui/frame.cpp | 304 | ||||
-rw-r--r-- | src/gui/frame.h | 29 | ||||
-rw-r--r-- | src/gui/mainWindow.cpp | 54 | ||||
-rw-r--r-- | src/gui/mainWindow.h | 1 | ||||
-rw-r--r-- | src/gui/multicastConfigDialog.cpp | 170 | ||||
-rw-r--r-- | src/gui/multicastConfigDialog.h | 38 | ||||
-rw-r--r-- | src/gui/ui/clientConfigDialog.ui | 64 | ||||
-rw-r--r-- | src/gui/ui/clientFileReceiveDialog.ui | 11 | ||||
-rw-r--r-- | src/gui/ui/clientFileSendDialog.ui | 15 | ||||
-rw-r--r-- | src/gui/ui/clientNicklistDialog.ui | 7 | ||||
-rw-r--r-- | src/gui/ui/mainwindow.ui | 15 | ||||
-rw-r--r-- | src/gui/ui/mainwindowtouch.ui | 11 | ||||
-rw-r--r-- | src/gui/ui/multicastConfigDialog.ui | 156 |
20 files changed, 1174 insertions, 66 deletions
diff --git a/src/gui/clientConfigDialog.cpp b/src/gui/clientConfigDialog.cpp index 0ee5908..b7ba407 100644 --- a/src/gui/clientConfigDialog.cpp +++ b/src/gui/clientConfigDialog.cpp @@ -16,20 +16,33 @@ # ----------------------------------------------------------------------------- */ +#include <QtDebug> +#include <QNetworkInterface> +#include <QStandardItemModel> #include "clientConfigDialog.h" +#include <cerrno> +#include <cstdlib> +#include <cstring> +#include <src/net/pvsNetworkInterfaceListModel.h> + +using namespace std; ClientConfigDialog::ClientConfigDialog(QWidget *parent) : - QDialog(parent) + QDialog(parent), + _interfaceListModel(0) { setupUi(this); connect(this, SIGNAL(accepted()), this, SLOT(writeSettings())); connect(radioButtonOtherRO, SIGNAL(clicked()), this, SLOT(checkPermissions())); + _interfaceListModel = new PVSNetworkInterfaceListModel(this); + interfaceList->setModel(_interfaceListModel); + interfaceList->setModelColumn(0); + connect(reloadInterfaceListButton, SIGNAL(clicked()), _interfaceListModel, SLOT(reloadInterfaceList())); // connect to D-Bus and get interface QDBusConnection dbus = QDBusConnection::sessionBus(); _ifaceDBus = new OrgOpenslxPvsInterface("org.openslx.pvs", "/", dbus, this); - } ClientConfigDialog::~ClientConfigDialog() @@ -53,7 +66,14 @@ void ClientConfigDialog::readSettings() else comboBox->setCurrentIndex(_settings.value("Display/location").toInt()); - QDBusPendingReply<QString> reply = _ifaceDBus->getConfigValue("Permissions/vnc_lecturer"); + QDBusPendingReply<QString> reply = _ifaceDBus->getConfigValue("multicast/interface"); + reply.waitForFinished(); + if (reply.isValid()) + { + interfaceList->setEditText(reply.value()); + } + + reply = _ifaceDBus->getConfigValue("Permissions/vnc_lecturer"); reply.waitForFinished(); if (reply.isValid()) { @@ -86,7 +106,6 @@ void ClientConfigDialog::readSettings() reply.waitForFinished(); if (reply.isValid()) checkBoxAllowFiletransfer->setChecked(reply.value() == "T"); - } void ClientConfigDialog::writeSettings() @@ -110,6 +129,7 @@ void ClientConfigDialog::writeSettings() QString(checkBoxAllowChat->isChecked() ? "T" : "F")); _ifaceDBus->setConfigValue("Permissions/allow_filetransfer", QString(checkBoxAllowFiletransfer->isChecked() ? "T" : "F")); + _ifaceDBus->setConfigValue("multicast/interface", interfaceList->currentText()); _settings.sync(); emit configChanged(); diff --git a/src/gui/clientConfigDialog.h b/src/gui/clientConfigDialog.h index 98da54f..fd7529e 100644 --- a/src/gui/clientConfigDialog.h +++ b/src/gui/clientConfigDialog.h @@ -18,6 +18,8 @@ #include "pvsinterface.h" #include "ui_clientConfigDialog.h" +class QAbstractItemModel; + class ClientConfigDialog: public QDialog, private Ui::ClientConfigDialogClass { Q_OBJECT @@ -40,6 +42,7 @@ private Q_SLOTS: private: OrgOpenslxPvsInterface *_ifaceDBus; QSettings _settings; + QAbstractItemModel* _interfaceListModel; }; diff --git a/src/gui/clientFileReceiveDialog.cpp b/src/gui/clientFileReceiveDialog.cpp index 669ca81..fc6a1a3 100644 --- a/src/gui/clientFileReceiveDialog.cpp +++ b/src/gui/clientFileReceiveDialog.cpp @@ -16,6 +16,9 @@ */ #include "clientFileReceiveDialog.h" +#include <pvsinterface.h> +#include <QFileInfo> +#include <limits.h> ClientFileReceiveDialog::ClientFileReceiveDialog(QTcpSocket *socket, QWidget *parent) : QDialog(parent) @@ -37,9 +40,44 @@ ClientFileReceiveDialog::ClientFileReceiveDialog(QTcpSocket *socket, QWidget *pa connect(this, SIGNAL(finished(int)), this, SLOT(deleteLater())); } +ClientFileReceiveDialog::ClientFileReceiveDialog(QString const& sender, qulonglong transferID, + QString const& filename, qulonglong size, OrgOpenslxPvsInterface* ifaceDBus, QWidget* parent) +{ + setupUi(this); + + _transferID = transferID; + _filename = filename; + _ifaceDBus = ifaceDBus; + _bytesToRead = size; + _socket = 0; + _file = 0; + div = 1; + while((size / div) > INT_MAX) + { + div <<= 1; + } + + connect(ifaceDBus, SIGNAL(incomingMulticastTransferStarted(qulonglong)), SLOT(mcastTransferStarted(qulonglong))); + connect(ifaceDBus, SIGNAL(incomingMulticastTransferProgress(qulonglong, qulonglong, qulonglong)), + SLOT(mcastTransferProgress(qulonglong, qulonglong, qulonglong))); + connect(ifaceDBus, SIGNAL(incomingMulticastTransferFinished(qulonglong)), SLOT(mcastTransferFinished(qulonglong))); + connect(ifaceDBus, SIGNAL(incomingMulticastTransferFailed(qulonglong, QString)), SLOT(mcastTransferFailed(qulonglong, QString))); + connect(cancelButton, SIGNAL(clicked()), SLOT(cancelTransfer())); + + qDebug("[%s] New multicast incoming transfer: %s from %s", metaObject()->className(), + filename.toLocal8Bit().constData(), sender.toLocal8Bit().constData()); + + + filenameLabel->setText(QFileInfo(filename).baseName()); + labelNick->setText(sender); + progressBar->setRange(0, 0); +} + + ClientFileReceiveDialog::~ClientFileReceiveDialog() { - _socket->deleteLater(); + if(_socket) + _socket->deleteLater(); qDebug("[%s] Deleted!", metaObject()->className()); } @@ -168,6 +206,61 @@ void ClientFileReceiveDialog::error(QAbstractSocket::SocketError error) close(); } +void ClientFileReceiveDialog::mcastTransferStarted(qulonglong transferID) +{ + if(transferID != _transferID) + return; +} + +void ClientFileReceiveDialog::mcastTransferProgress(qulonglong transferID, qulonglong bytes, qulonglong of) +{ + if(transferID != _transferID) + return; + + progressBar->setRange(0, of); + progressBar->setValue(bytes); + + labelA->setText(formatSize(bytes)); + labelB->setText(formatSize(of)); +} + +void ClientFileReceiveDialog::mcastTransferFinished(qulonglong transferID) +{ + if(transferID != _transferID) + return; + + QString filename = QFileDialog::getSaveFileName(this, tr("Where should I save %1?").arg(_filename), _filename); + QFile* file = new QFile(_filename); + if(filename.isNull() || filename.isEmpty()) + { + file->remove(); + } + else + { + if(!file->rename(filename)) + { + QMessageBox::warning(this, tr("Could not rename file"), tr("Failed to rename %1 to %2").arg(_filename).arg(filename)); + } + } + accept(); + deleteLater(); +} + +void ClientFileReceiveDialog::mcastTransferFailed(qulonglong transferID, QString reason) +{ + if(transferID != _transferID) + return; + + QMessageBox::warning(this, tr("File transfer failed"), tr("File transfer failed for the following reason:\n%1").arg(reason)); + reject(); + deleteLater(); +} + +void ClientFileReceiveDialog::cancelTransfer() +{ + _ifaceDBus->cancelIncomingMulticastTransfer(_transferID); +} + QString ClientFileReceiveDialog::formatSize(qint64 size) { if (size >= 1000000000) // GB diff --git a/src/gui/clientFileReceiveDialog.h b/src/gui/clientFileReceiveDialog.h index c13d7b7..c9ed220 100644 --- a/src/gui/clientFileReceiveDialog.h +++ b/src/gui/clientFileReceiveDialog.h @@ -18,6 +18,8 @@ #include <QtNetwork> #include "ui_clientFileReceiveDialog.h" +class OrgOpenslxPvsInterface; + class ClientFileReceiveDialog: public QDialog, private Ui::ClientFileReceiveDialogClass { @@ -25,6 +27,7 @@ Q_OBJECT public: ClientFileReceiveDialog(QTcpSocket *socket, QWidget *parent = 0); + ClientFileReceiveDialog(QString const& sender, qulonglong transferID, QString const& basename, qulonglong size, OrgOpenslxPvsInterface* ifaceDBus, QWidget* parent = 0); ~ClientFileReceiveDialog(); private Q_SLOTS: @@ -33,6 +36,13 @@ private Q_SLOTS: void close(); void error(QAbstractSocket::SocketError error); + // multicast: + void mcastTransferStarted(qulonglong transferID); + void mcastTransferProgress(qulonglong transferID, qulonglong bytes, qulonglong of); + void mcastTransferFinished(qulonglong transferID); + void mcastTransferFailed(qulonglong transferID, QString reason); + void cancelTransfer(); + private: void sendAck(bool b); QString formatSize(qint64 size); @@ -42,6 +52,10 @@ private: qint64 _bytesToRead; int div; + // multicast: + OrgOpenslxPvsInterface* _ifaceDBus; + QString _filename; + qulonglong _transferID; }; #endif /* CLIENTFILERECEIVEDIALOG_H_ */ diff --git a/src/gui/clientFileSendDialog.cpp b/src/gui/clientFileSendDialog.cpp index b4512c0..93da725 100644 --- a/src/gui/clientFileSendDialog.cpp +++ b/src/gui/clientFileSendDialog.cpp @@ -22,6 +22,10 @@ ClientFileSendDialog::ClientFileSendDialog(QWidget *parent) : { setupUi(this); + _transferID = 0; + _error = false; + _isMulticast = false; + _file = NULL; _socket = NULL; _clientNicklistDialog = new ClientNicklistDialog(this); @@ -58,7 +62,15 @@ void ClientFileSendDialog::open() reject(); return; } - open(_clientNicklistDialog->getNick()); + + if (_clientNicklistDialog->isSendToAll()) + { + sendToAll(); + } + else + { + open(_clientNicklistDialog->getNick()); + } } void ClientFileSendDialog::open(QString nick) @@ -73,6 +85,70 @@ void ClientFileSendDialog::open(QString nick) open(nick, filename); } +void ClientFileSendDialog::sendToAll() +{ + QString filename = QFileDialog::getOpenFileName(this, tr("Send File"), QDir::homePath(), ""); + if (filename == "") + { + reject(); + return; + } + sendToAll(filename); +} + +void ClientFileSendDialog::sendToAll(QString filename) +{ + _isMulticast = true; + + connect(_ifaceDBus, SIGNAL(outgoingMulticastTransferStarted(qulonglong)), SLOT(multicastTransferStarted(qulonglong))); + connect(_ifaceDBus, SIGNAL(outgoingMulticastTransferProgress(qulonglong,qulonglong,qulonglong)), SLOT(multicastTransferProgress(qulonglong, qulonglong, qulonglong))); + connect(_ifaceDBus, SIGNAL(outgoingMulticastTransferFinished(qulonglong)), SLOT(multicastTransferFinished(qulonglong))); + connect(_ifaceDBus, SIGNAL(outgoingMulticastTransferFailed(qulonglong, QString const&)), SLOT(multicastTransferFailed(qulonglong, QString const&))); + + filenameLabel->setText(filename); + progressBar->setRange(0, 0); + labelNick->setText(tr("all")); + labelStatus->setText(tr("Waiting to start")); + + QString errorMessage("Backend error"); + + // We need to jump through a lot of hoops because this call is prone to time out, and + // QtDBus does not support specifying timeouts in generated interfaces. + QDBusMessage call = QDBusMessage::createMethodCall("org.openslx.pvs", "/", "org.openslx.pvs", "createMulticastTransfer"); + call << filename; + + QDBusMessage reply = _ifaceDBus->connection().call(call, QDBus::Block, 5000); + if (reply.type() == QDBusMessage::ErrorMessage) + { + QMessageBox::critical(this, tr("File Send error"), tr("Error communicating with backend: %1: %2").arg(reply.errorName()).arg(reply.errorMessage())); + reject(); + return; + } + else if (reply.type() == QDBusMessage::InvalidMessage) + { + QMessageBox::critical(this, tr("File Send error"), tr("Something went wrong while communicating with backend, but I don't know what.")); + reject(); + return; + } + else if (reply.type() == QDBusMessage::ReplyMessage) + { + QList<QVariant> args = reply.arguments(); + bool created = args.at(0).toBool(); + _transferID = args.at(1).toULongLong(); + QString errorMessage = args.at(2).toString(); + if (!created) + { + QMessageBox::critical(this, tr("File Send error"), tr("Could not create a multicast transfer: %1").arg(errorMessage)); + reject(); + return; + } + } + + connect(cancelButton, SIGNAL(clicked()), SLOT(canceled())); + + show(); +} + void ClientFileSendDialog::open(QString nick, QString filename) { // open file @@ -127,6 +203,8 @@ void ClientFileSendDialog::receiveAck() QString ack = QString::fromUtf8(_socket->readLine()); if (ack != "ok\n") { + _error = true; + _reason = tr("Receiver declined"); qDebug("[%s] Received nack!", metaObject()->className()); close(); return; @@ -158,27 +236,30 @@ void ClientFileSendDialog::sendFile() void ClientFileSendDialog::close() { - if (_file && _file->isOpen()) - { - _file->close(); - qDebug("[%s] File closed.", metaObject()->className()); - } - - if (_socket && _socket->isOpen()) + if (!_isMulticast) { - disconnect(_socket, SIGNAL(readyRead()), this, SLOT(receiveAck())); - disconnect(_socket, SIGNAL(bytesWritten(qint64)), this, SLOT(sendFile())); - disconnect(_socket, SIGNAL(disconnected()), this, SLOT(close())); - disconnect(_socket, SIGNAL(connected()), this, SLOT(sendHeader())); - disconnect(_socket, SIGNAL(error(QAbstractSocket::SocketError)), - this, SLOT(error(QAbstractSocket::SocketError))); - _socket->disconnectFromHost(); - qDebug("[%s] Connection closed.", metaObject()->className()); + if (_file && _file->isOpen()) + { + _file->close(); + qDebug("[%s] File closed.", metaObject()->className()); + } + + if (_socket && _socket->isOpen()) + { + disconnect(_socket, SIGNAL(readyRead()), this, SLOT(receiveAck())); + disconnect(_socket, SIGNAL(bytesWritten(qint64)), this, SLOT(sendFile())); + disconnect(_socket, SIGNAL(disconnected()), this, SLOT(close())); + disconnect(_socket, SIGNAL(connected()), this, SLOT(sendHeader())); + disconnect(_socket, SIGNAL(error(QAbstractSocket::SocketError)), + this, SLOT(error(QAbstractSocket::SocketError))); + _socket->disconnectFromHost(); + qDebug("[%s] Connection closed.", metaObject()->className()); + } } - disconnect(cancelButton, SIGNAL(clicked()), this, SLOT(close())); + disconnect(cancelButton, SIGNAL(clicked()), this, SLOT(canceled())); - if (_bytesToWrite == 0) + if (!_error) { accept(); QMessageBox::information(0, tr("PVS - File Transfer"), @@ -188,12 +269,26 @@ void ClientFileSendDialog::close() { reject(); QMessageBox::warning(0, tr("PVS - File Transfer"), - tr("File Transfer canceled!")); + tr("File Transfer canceled: %1").arg(_reason)); } } +void ClientFileSendDialog::canceled() +{ + if(_isMulticast) + { + _ifaceDBus->cancelOutgoingMulticastTransfer(_transferID); + } + + _error = true; + _reason = tr("You clicked 'Cancel'"); + close(); +} + void ClientFileSendDialog::error(QAbstractSocket::SocketError error) { + _error = true; + _reason = tr("Socket Error"); qDebug("[%s] Socket error: %i", metaObject()->className(), error); close(); } @@ -210,6 +305,55 @@ QString ClientFileSendDialog::formatSize(qint64 size) return QString("%1B").arg((qreal)size, 0, 'f',1); } +void ClientFileSendDialog::multicastTransferStarted(qulonglong transferID) +{ + qDebug() << "multicastTransferStarted(" << transferID << ")"; + if (transferID != _transferID) + { + return; + } + labelStatus->setText("Started"); +} + +void ClientFileSendDialog::multicastTransferProgress(qulonglong transferID, qulonglong bytes, qulonglong of) +{ + qDebug() << "multicastTransferProgress(" << transferID << bytes << of << ")"; + if (transferID != _transferID) + { + return; + } + + if(bytes < of) + { + labelStatus->setText("Transferring"); + progressBar->setRange(0, of); + progressBar->setValue(bytes); + } + else + { + labelStatus->setText("Waiting to finish"); + progressBar->setRange(0, 0); + } + + labelA->setText(formatSize(bytes)); + labelB->setText(formatSize(of)); +} + +void ClientFileSendDialog::multicastTransferFinished(quint64 transferID) +{ + qDebug() << "multicastTransferFinished(" << transferID << ")"; + qDebug("[%s] MulticastTransfer finished", metaObject()->className()); + close(); +} + +void ClientFileSendDialog::multicastTransferFailed(quint64 transferID, QString const& reason) +{ + qDebug() << "multicastTransferFailed(" << transferID << reason << ")"; + _error = true; + _reason = reason; + close(); +} + //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// @@ -233,6 +377,25 @@ ClientNicklistDialog::ClientNicklistDialog(QWidget *parent) : listWidget->addItems(nicknames); listWidget->setCurrentRow(0); + + connect(sendToAllCheckBox, SIGNAL(stateChanged(int)), SLOT(sendToAllStateChanged(int))); + + sendToAllCheckBox->setCheckState(Qt::Unchecked); + _isSendToAll = false; +} + +void ClientNicklistDialog::sendToAllStateChanged(int state) +{ + if (state) + { + listWidget->setEnabled(false); + _isSendToAll = true; + } + else + { + listWidget->setEnabled(true); + _isSendToAll = false; + } } ClientNicklistDialog::~ClientNicklistDialog() diff --git a/src/gui/clientFileSendDialog.h b/src/gui/clientFileSendDialog.h index d8afc3a..7abdcc7 100644 --- a/src/gui/clientFileSendDialog.h +++ b/src/gui/clientFileSendDialog.h @@ -30,9 +30,17 @@ public: ~ClientNicklistDialog(); QString getNick(); + bool isSendToAll() const + { + return _isSendToAll; + } + +private Q_SLOTS: + void sendToAllStateChanged(int state); private: OrgOpenslxPvsInterface *_ifaceDBus; + bool _isSendToAll; }; @@ -51,14 +59,22 @@ public: void open(); void open(QString nick); void open(QString nick, QString filename); + void sendToAll(); + void sendToAll(QString filename); private Q_SLOTS: void sendHeader(); void receiveAck(); void sendFile(); void close(); + void canceled(); void error(QAbstractSocket::SocketError error); + void multicastTransferStarted(qulonglong transferID); + void multicastTransferProgress(qulonglong transferID, qulonglong bytes, qulonglong of); + void multicastTransferFinished(qulonglong transferID); + void multicastTransferFailed(qulonglong transferID, QString const& reason); + private: QString formatSize(qint64 size); @@ -71,6 +87,11 @@ private: OrgOpenslxPvsInterface *_ifaceDBus; QString _nickname; + quint64 _transferID; + bool _error; + QString _reason; + bool _isMulticast; + }; #endif /* CLIENTFILESENDDIALOG_H_ */ diff --git a/src/gui/connectionWindow.h b/src/gui/connectionWindow.h index e7d0177..55442db 100644 --- a/src/gui/connectionWindow.h +++ b/src/gui/connectionWindow.h @@ -9,6 +9,7 @@ #include <iostream> #include <math.h> #include <QSettings> +#include <QPointer> #define FRAME_DELAY 1000 // to comply with the standard value in the gui @@ -110,7 +111,7 @@ protected: private: ConnectionFrame* newConFrame(PVSClient* newConnection); // returns a new frame for the given connection ConnectionFrame* currentSingleFrame; // pointer to the frame thats currently in FullScreen - ConnectionFrame* _closeupFrame; + QPointer<ConnectionFrame> _closeupFrame; QPoint currentPosition (ConnectionFrame* cF); QMenu *menu; QAction *newDummy; 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; +} diff --git a/src/gui/frame.h b/src/gui/frame.h index 3004e0c..8271670 100644 --- a/src/gui/frame.h +++ b/src/gui/frame.h @@ -8,6 +8,7 @@ class VNCClientThread; class ConnectionWindow; class ConnectionFrame; class MainWindow; +class InputEvent; class Frame: public QLabel { @@ -48,8 +49,13 @@ public: QToolButton* button_lock; QToolButton* button_unlock; QToolButton* button_dozent; + QToolButton* button_control; + QToolButton* button_control_all; QList<QToolButton*> toolButtonList; + bool _remoteControlEnabled; + bool _remoteControlToAll; + public Q_SLOTS: void updateImage(int x, int y, int w, int h); void iamDown(); @@ -68,13 +74,24 @@ public Q_SLOTS: void setLock(); //void unlock(); void setDozent(); +private Q_SLOTS: + void remoteControlClicked(); + void remoteControlAllClicked(); + void sendMouseMotionEvent(); + void showSpecialEventMenu(); signals: - void clicked(); + void clicked(); protected: void paintEvent(QPaintEvent *event); void mousePressEvent ( QMouseEvent * event ); void mouseReleaseEvent ( QMouseEvent * event ); + void mouseMoveEvent ( QMouseEvent * event ); + void enterEvent(QEvent* event); + void leaveEvent(QEvent* event); + void keyPressEvent(QKeyEvent* event); + void keyReleaseEvent(QKeyEvent* event); + bool event(QEvent* event); private: QToolButton* createToolButton(const QString &toolTip, const QIcon &icon, const char *member); @@ -85,6 +102,16 @@ private: bool _isLocked; bool _dozent; int _ux, _uy; + + // for remote control: + QPoint _lastRecordedMousePosition; + bool _mousePositionChanged; + QTimer* _mouseMotionEventTimer; + bool _mouseOver; + QTimer* _specialEventTimer; + QPoint rescalePosition(QPointF guiPosition); + void updateMousePosition(QMouseEvent* event); + void sendInputEvent(InputEvent const&); }; #endif /* FRAME_H_ */ diff --git a/src/gui/mainWindow.cpp b/src/gui/mainWindow.cpp index 815f001..b6878e8 100644 --- a/src/gui/mainWindow.cpp +++ b/src/gui/mainWindow.cpp @@ -16,7 +16,10 @@ #include <QtGui> #include <QFileDialog> +#include <QBuffer> +#include <QDataStream> #include <src/gui/mainWindow.h> +#include <src/net/mcast/McastConfiguration.h> using namespace std; // setting the IF-DEF Block for the touchgui and the normal gui, for later use @@ -35,6 +38,7 @@ using namespace std; #include <src/gui/processesDialog.h> //#include <src/gui/dialog.h> #include <src/core/pvsConnectionManager.h> +#include <src/gui/multicastConfigDialog.h> #include <iostream> MainWindow::MainWindow(QWidget *parent) : @@ -133,6 +137,7 @@ MainWindow::MainWindow(QWidget *parent) : ui->actionFoto->setStatusTip(tr("Make a screenshot for the selected client(s)")); ui->actionLock->setStatusTip(tr("Lock or Unlock all Clients")); connect(ui->actionCreate_profile, SIGNAL(triggered()), this, SLOT(createProfile())); + connect(ui->actionConfigure_Network, SIGNAL(triggered()), this, SLOT(configureNetwork())); connect(ui->actionShowProcesses, SIGNAL(triggered()), this, SLOT(showProcesses())); ui->actionShowProcesses->setStatusTip(tr("Show Processes of the selected Client")); connect(ui->actionStartProcess, SIGNAL(triggered()), this, SLOT(startProcess())); @@ -163,7 +168,6 @@ MainWindow::MainWindow(QWidget *parent) : _serverSocket = new QTcpServer(); _serverSocket->listen(QHostAddress::Any, 29481); connect(_serverSocket, SIGNAL(newConnection()), this, SLOT(incomingFile())); - } MainWindow::~MainWindow() @@ -270,24 +274,24 @@ void MainWindow::loadSettings() if (current.compare("default") == 0) { setWindowTitle("PVSmgr - Default"); - QPoint pos1 = settings.value("default/1", QPoint(0, 0)).toPoint(); - MainWindow::getConnectionWindow()->addFrameBySettings("1", pos1); - QPoint pos2 = settings.value("default/2", QPoint(194, 0)).toPoint(); - MainWindow::getConnectionWindow()->addFrameBySettings("2", pos2); - QPoint pos3 = settings.value("default/3", QPoint(388, 0)).toPoint(); - MainWindow::getConnectionWindow()->addFrameBySettings("3", pos3); - QPoint pos4 = settings.value("default/4", QPoint(582, 0)).toPoint(); - MainWindow::getConnectionWindow()->addFrameBySettings("4", pos4); - QPoint pos5 = settings.value("default/5", QPoint(0, 173)).toPoint(); - MainWindow::getConnectionWindow()->addFrameBySettings("5", pos5); - QPoint pos6 = settings.value("default/6", QPoint(194, 173)).toPoint(); - MainWindow::getConnectionWindow()->addFrameBySettings("6", pos6); - QPoint pos7 = settings.value("default/7", QPoint(388, 173)).toPoint(); - MainWindow::getConnectionWindow()->addFrameBySettings("7", pos7); - QPoint pos8 = settings.value("default/8", QPoint(582, 173)).toPoint(); - MainWindow::getConnectionWindow()->addFrameBySettings("8", pos8); - QPoint pos9 = settings.value("default/9", QPoint(293, 346)).toPoint(); - MainWindow::getConnectionWindow()->addFrameBySettings("9", pos9); +// QPoint pos1 = settings.value("default/1", QPoint(0, 0)).toPoint(); +// MainWindow::getConnectionWindow()->addFrameBySettings("1", pos1); +// QPoint pos2 = settings.value("default/2", QPoint(194, 0)).toPoint(); +// MainWindow::getConnectionWindow()->addFrameBySettings("2", pos2); +// QPoint pos3 = settings.value("default/3", QPoint(388, 0)).toPoint(); +// MainWindow::getConnectionWindow()->addFrameBySettings("3", pos3); +// QPoint pos4 = settings.value("default/4", QPoint(582, 0)).toPoint(); +// MainWindow::getConnectionWindow()->addFrameBySettings("4", pos4); +// QPoint pos5 = settings.value("default/5", QPoint(0, 173)).toPoint(); +// MainWindow::getConnectionWindow()->addFrameBySettings("5", pos5); +// QPoint pos6 = settings.value("default/6", QPoint(194, 173)).toPoint(); +// MainWindow::getConnectionWindow()->addFrameBySettings("6", pos6); +// QPoint pos7 = settings.value("default/7", QPoint(388, 173)).toPoint(); +// MainWindow::getConnectionWindow()->addFrameBySettings("7", pos7); +// QPoint pos8 = settings.value("default/8", QPoint(582, 173)).toPoint(); +// MainWindow::getConnectionWindow()->addFrameBySettings("8", pos8); +// QPoint pos9 = settings.value("default/9", QPoint(293, 346)).toPoint(); +// MainWindow::getConnectionWindow()->addFrameBySettings("9", pos9); QString title = "PVSmgr - "; title.append(_profilName); @@ -1277,6 +1281,18 @@ void MainWindow::startChatDialog() sChatDialog.raise();//show the chat dialog on top level } +void MainWindow::configureNetwork() +{ + PVSServer* server = PVSConnectionManager::getManager()->getServer(); + McastConfiguration mc(*(server->getMulticastConfiguration())); + MulticastConfigDialog* mcd = new MulticastConfigDialog(&mc, this); + int result = mcd->exec(); + if(result == QDialog::Accepted) + { + server->multicastReconfigure(&mc); + } +} + MainWindow* MainWindow::myself = NULL; ConnectionList* MainWindow::conList = NULL; ConnectionWindow* MainWindow::conWin = NULL; diff --git a/src/gui/mainWindow.h b/src/gui/mainWindow.h index 2ab62f8..28f82f7 100644 --- a/src/gui/mainWindow.h +++ b/src/gui/mainWindow.h @@ -204,6 +204,7 @@ private slots: void setPasswordForConnection(int enabled); void combobox1(int menuindex1); // Funktion um index der combobox auszulesen und weiterzuverarbeiten s. Ticker 671 //void combobox2(int menuindex2); // Funktion um index der combobox auszulesen und weiterzuverarbeiten + void configureNetwork(); }; diff --git a/src/gui/multicastConfigDialog.cpp b/src/gui/multicastConfigDialog.cpp new file mode 100644 index 0000000..ff370c7 --- /dev/null +++ b/src/gui/multicastConfigDialog.cpp @@ -0,0 +1,170 @@ +#include <QValidator> +#include <QIntValidator> +#include <QHostAddress> +#include <QPushButton> +#include "multicastConfigDialog.h" +#include <src/net/mcast/McastConfiguration.h> +// #include "multicastValidators.h" + +MulticastConfigDialog::MulticastConfigDialog(QWidget* parent) : + QDialog(parent) +{ + setupUi(); +} + +MulticastConfigDialog::MulticastConfigDialog(McastConfiguration* config, + QWidget *parent) : + QDialog(parent) +{ + setupUi(); + _config = config; + + _ui.groupAddressEdit->setText(config->multicastAddress()); + _ui.dataPortEdit->setText(QString::number(config->multicastUDPPortBase())); + + connect(_ui.buttonBox, SIGNAL(accepted()), this, SLOT(dialogAccepted())); + connect(_ui.buttonBox, SIGNAL(rejected()), this, SLOT(reject())); +} + +void MulticastConfigDialog::setupUi() +{ + _ui.setupUi(this); + + QIntValidator* portValidator = new QIntValidator(1024, 65535, this); + _ui.dataPortEdit->setValidator(portValidator); + + connect(_ui.groupAddressEdit, SIGNAL(textChanged(QString const&)), this, + SLOT(validateGroupAddress(QString const&))); + connect(_ui.dataPortEdit, SIGNAL(textChanged(QString const&)), this, + SLOT(validateDataPort(QString const&))); + + connect(_ui.buttonBox, SIGNAL(accepted()), this, SLOT(dialogAccepted())); + connect(_ui.buttonBox, SIGNAL(rejected()), this, SLOT(reject())); + + validateGroupAddress(_ui.groupAddressEdit->text()); + validateDataPort(_ui.dataPortEdit->text()); +} + +MulticastConfigDialog::~MulticastConfigDialog() +{ +} + +void MulticastConfigDialog::dialogAccepted() +{ + QHostAddress addr; + bool addressParses = addr.setAddress(_ui.groupAddressEdit->text()); + _config->multicastAddress(_ui.groupAddressEdit->text()); + quint16 port = _ui.dataPortEdit->text().toInt(); + _config->multicastUDPPortBase(port); + _config->multicastDPort(port + 1); + _config->multicastSPort(port + 2); + _config->multicastRate(_ui.rateSpinbox->value() * 1024); + accept(); +} + +void MulticastConfigDialog::setError(QWidget* widget, + QLabel* errorMessageLabel, QString text) +{ + if (errorMessageLabel) + errorMessageLabel->setText(QString( + "<span style=\"font-weight: 600; color: #880000;\">") + text + + "</span>"); + if (widget) + widget->setStyleSheet("background-color: #ffcccc;"); +} + +void MulticastConfigDialog::setOK(QWidget* widget, QLabel* errorMessageLabel) +{ + if (errorMessageLabel) + errorMessageLabel->setText(QString( + "<span style=\"font-weight: 600; color: #008800;\">") + + tr("OK") + "</span>"); + if (widget) + widget->setStyleSheet("background-color: #ccffcc;"); +} + +void MulticastConfigDialog::validateGroupAddress(QString const& input) +{ + QHostAddress a; + + _isAddressValid = false; + + if (!a.setAddress(input)) + { + setError(_ui.groupAddressEdit, _ui.groupAddressMessage, tr( + "Not a valid IP Address")); + revalidateButtons(); + return; + } + + // check if it is IPv4 + if (a.protocol() != QAbstractSocket::IPv4Protocol) + { + setError(_ui.groupAddressEdit, _ui.groupAddressMessage, tr( + "Not a valid IPv4 Address")); + revalidateButtons(); + return; + } + + // check if it is a valid multicast address + quint32 addr = a.toIPv4Address(); + if ((addr & 0xf0000000) != 0xe0000000) + { + setError(_ui.groupAddressEdit, _ui.groupAddressMessage, tr( + "Not an IPv4 multicast address")); + revalidateButtons(); + return; + } + + _isAddressValid = true; + setOK(_ui.groupAddressEdit, _ui.groupAddressMessage); + revalidateButtons(); +} + +void MulticastConfigDialog::validateDataPort(QString const& input) +{ + bool ok; + int p = input.toInt(&ok, 0); + + _isPortValid = false; + + if (!ok) + { + setError(_ui.dataPortEdit, _ui.dataPortMessage, tr("Not a number")); + revalidateButtons(); + return; + } + + if (p < 0) + { + setError(_ui.dataPortEdit, _ui.dataPortMessage, tr("Must be positive")); + revalidateButtons(); + return; + } + + if (p < 1024) + { + setError(_ui.dataPortEdit, _ui.dataPortMessage, tr( + "Must not be a privileged port")); + revalidateButtons(); + return; + } + + if (p > 65535) + { + setError(_ui.dataPortEdit, _ui.dataPortMessage, tr( + "Port number too large")); + revalidateButtons(); + return; + } + + _isPortValid = true; + setOK(_ui.dataPortEdit, _ui.dataPortMessage); + revalidateButtons(); +} + +void MulticastConfigDialog::revalidateButtons() +{ + _ui.buttonBox->button(QDialogButtonBox::Ok)->setEnabled(_isAddressValid + && _isPortValid); +} diff --git a/src/gui/multicastConfigDialog.h b/src/gui/multicastConfigDialog.h new file mode 100644 index 0000000..6421813 --- /dev/null +++ b/src/gui/multicastConfigDialog.h @@ -0,0 +1,38 @@ +#ifndef MULTICASTCONFIGDIALOG_H +#define MULTICASTCONFIGDIALOG_H + +#include <QtGui/QDialog> +#include <QPointer> +#include "ui_multicastConfigDialog.h" +#include <pvsinterface.h> + +class McastConfiguration; + +class MulticastConfigDialog : public QDialog +{ + Q_OBJECT + +public: + MulticastConfigDialog(QWidget* parent = 0); + MulticastConfigDialog(McastConfiguration* dbusIface, QWidget *parent = 0); + ~MulticastConfigDialog(); + +private: + Ui::MulticastConfigDialogClass _ui; + McastConfiguration* _config; + bool _isAddressValid; + bool _isPortValid; + + void setupUi(); + + void setError(QWidget* input, QLabel* messageLabel, QString text); + void setOK(QWidget* input, QLabel* messageLabel); + void revalidateButtons(); + +private slots: + void dialogAccepted(); + void validateGroupAddress(QString const&); + void validateDataPort(QString const&); +}; + +#endif // MULTICASTCONFIGDIALOG_H diff --git a/src/gui/ui/clientConfigDialog.ui b/src/gui/ui/clientConfigDialog.ui index 3262b6b..bb4bdc9 100644 --- a/src/gui/ui/clientConfigDialog.ui +++ b/src/gui/ui/clientConfigDialog.ui @@ -6,8 +6,8 @@ <rect> <x>0</x> <y>0</y> - <width>438</width> - <height>257</height> + <width>445</width> + <height>266</height> </rect> </property> <property name="windowTitle"> @@ -27,7 +27,7 @@ <enum>QTabWidget::North</enum> </property> <property name="currentIndex"> - <number>0</number> + <number>2</number> </property> <widget class="QWidget" name="tabPermissions"> <attribute name="title"> @@ -197,6 +197,64 @@ </item> </layout> </widget> + <widget class="QWidget" name="networkTab"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Preferred" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="autoFillBackground"> + <bool>false</bool> + </property> + <attribute name="title"> + <string>Network</string> + </attribute> + <layout class="QFormLayout" name="formLayout"> + <item row="2" column="1"> + <widget class="QComboBox" name="interfaceList"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Expanding" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="editable"> + <bool>true</bool> + </property> + <property name="insertPolicy"> + <enum>QComboBox::NoInsert</enum> + </property> + <property name="frame"> + <bool>true</bool> + </property> + </widget> + </item> + <item row="2" column="0"> + <widget class="QLabel" name="label"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Expanding" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string>Network Interface</string> + </property> + <property name="alignment"> + <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> + </property> + </widget> + </item> + <item row="3" column="1"> + <widget class="QPushButton" name="reloadInterfaceListButton"> + <property name="text"> + <string>Reload List</string> + </property> + </widget> + </item> + </layout> + </widget> </widget> </item> <item> diff --git a/src/gui/ui/clientFileReceiveDialog.ui b/src/gui/ui/clientFileReceiveDialog.ui index af3a135..a137def 100644 --- a/src/gui/ui/clientFileReceiveDialog.ui +++ b/src/gui/ui/clientFileReceiveDialog.ui @@ -6,8 +6,8 @@ <rect> <x>0</x> <y>0</y> - <width>208</width> - <height>108</height> + <width>528</width> + <height>117</height> </rect> </property> <property name="windowTitle"> @@ -61,6 +61,13 @@ </property> </spacer> </item> + <item> + <widget class="QLabel" name="labelStatus"> + <property name="text"> + <string/> + </property> + </widget> + </item> </layout> </item> <item> diff --git a/src/gui/ui/clientFileSendDialog.ui b/src/gui/ui/clientFileSendDialog.ui index d2d9c75..85462ba 100644 --- a/src/gui/ui/clientFileSendDialog.ui +++ b/src/gui/ui/clientFileSendDialog.ui @@ -6,8 +6,8 @@ <rect> <x>0</x> <y>0</y> - <width>186</width> - <height>108</height> + <width>528</width> + <height>144</height> </rect> </property> <property name="windowTitle"> @@ -33,7 +33,7 @@ </widget> </item> <item> - <layout class="QHBoxLayout" name="horizontalLayout_2"> + <layout class="QHBoxLayout" name="horizontalLayout"> <item> <widget class="QLabel" name="label"> <property name="text"> @@ -61,10 +61,17 @@ </property> </spacer> </item> + <item> + <widget class="QLabel" name="labelStatus"> + <property name="text"> + <string/> + </property> + </widget> + </item> </layout> </item> <item> - <layout class="QHBoxLayout" name="horizontalLayout"> + <layout class="QHBoxLayout" name="horizontalLayout_2"> <item> <widget class="QLabel" name="labelA"> <property name="text"> diff --git a/src/gui/ui/clientNicklistDialog.ui b/src/gui/ui/clientNicklistDialog.ui index afd84f1..3679b55 100644 --- a/src/gui/ui/clientNicklistDialog.ui +++ b/src/gui/ui/clientNicklistDialog.ui @@ -29,6 +29,13 @@ <widget class="QListWidget" name="listWidget"/> </item> <item> + <widget class="QCheckBox" name="sendToAllCheckBox"> + <property name="text"> + <string>Send to &all</string> + </property> + </widget> + </item> + <item> <layout class="QHBoxLayout" name="horizontalLayout"> <item> <spacer name="horizontalSpacer"> diff --git a/src/gui/ui/mainwindow.ui b/src/gui/ui/mainwindow.ui index 285d0f2..d444092 100644 --- a/src/gui/ui/mainwindow.ui +++ b/src/gui/ui/mainwindow.ui @@ -243,9 +243,16 @@ </property> <addaction name="actionAbout_pvs"/> </widget> + <widget class="QMenu" name="menuNetwork"> + <property name="title"> + <string>Network</string> + </property> + <addaction name="actionConfigure_Network"/> + </widget> <addaction name="menu_File"/> <addaction name="menuClients"/> <addaction name="menuLogging"/> + <addaction name="menuNetwork"/> <addaction name="menu_Help"/> </widget> <widget class="QStatusBar" name="statusBar"/> @@ -533,6 +540,14 @@ <string>-</string> </property> </action> + <action name="actionConfigure_Network"> + <property name="text"> + <string>&Configure...</string> + </property> + <property name="toolTip"> + <string>Configure Network Parameters</string> + </property> + </action> <action name="actionShowProcesses"> <property name="icon"> <iconset resource="../../../pvsmgr.qrc"> diff --git a/src/gui/ui/mainwindowtouch.ui b/src/gui/ui/mainwindowtouch.ui index ae1d0cf..ea6f01e 100644 --- a/src/gui/ui/mainwindowtouch.ui +++ b/src/gui/ui/mainwindowtouch.ui @@ -365,6 +365,8 @@ <addaction name="actionresetall"/> <addaction name="separator"/> <addaction name="actionDozent"/> + <addaction name="separator"/> + <addaction name="actionConfigure_Network"/> <addaction name="actionShowProcesses"/> <addaction name="actionStartProcess"/> </widget> @@ -638,6 +640,15 @@ <string>Ctrl+D</string> </property> </action> + <action name="actionConfigure_Network"> + <property name="icon"> + <iconset resource="../../../pvsmgr.qrc"> + <normaloff>:/netconf</normaloff>:/netconf</iconset> + </property> + <property name="text"> + <string>Configure Network...</string> + </property> + </action> <action name="actionShowProcesses"> <property name="icon"> <iconset resource="../../../pvsmgr.qrc"> diff --git a/src/gui/ui/multicastConfigDialog.ui b/src/gui/ui/multicastConfigDialog.ui new file mode 100644 index 0000000..1ddf02c --- /dev/null +++ b/src/gui/ui/multicastConfigDialog.ui @@ -0,0 +1,156 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>MulticastConfigDialogClass</class> + <widget class="QDialog" name="MulticastConfigDialogClass"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>331</width> + <height>314</height> + </rect> + </property> + <property name="sizePolicy"> + <sizepolicy hsizetype="MinimumExpanding" vsizetype="MinimumExpanding"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="windowTitle"> + <string>PVS - Multicast Configuration</string> + </property> + <layout class="QVBoxLayout" name="verticalLayout"> + <item> + <widget class="QLabel" name="label_3"> + <property name="sizePolicy"> + <sizepolicy hsizetype="MinimumExpanding" vsizetype="Minimum"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Sans Serif'; font-size:9pt; font-weight:400; font-style:normal;"> +<table style="-qt-table-type: root; margin-top:4px; margin-bottom:4px; margin-left:4px; margin-right:4px;"> +<tr> +<td style="border: none;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">You need to specify connection parameters for multicast messaging on your network. These parameters will automatically be distributed to client computers, so you need to assign them only once.</p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">You will probably want to assign an address from the <span style=" text-decoration: underline;">239.0.0.0/8</span> &quot;Administratively Scoped&quot; range.</p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-weight:600;">Do not assign arbitrary numbers without checking with your network administrator!</span></p></td></tr></table></body></html></string> + </property> + <property name="wordWrap"> + <bool>true</bool> + </property> + </widget> + </item> + <item> + <layout class="QGridLayout" name="gridLayout"> + <item row="0" column="0"> + <widget class="QLabel" name="label"> + <property name="text"> + <string>Multicast Group Address</string> + </property> + <property name="alignment"> + <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> + </property> + </widget> + </item> + <item row="0" column="1"> + <widget class="QLineEdit" name="groupAddressEdit"> + <property name="inputMask"> + <string notr="true">009.009.009.009; </string> + </property> + <property name="text"> + <string>...</string> + </property> + </widget> + </item> + <item row="1" column="0" colspan="2"> + <widget class="QLabel" name="groupAddressMessage"> + <property name="text"> + <string><span style=" font-weight:600; color:#008800;">OK</span></string> + </property> + <property name="alignment"> + <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> + </property> + </widget> + </item> + <item row="2" column="0"> + <widget class="QLabel" name="label_2"> + <property name="text"> + <string>Data Port (1024-65535)</string> + </property> + <property name="alignment"> + <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> + </property> + </widget> + </item> + <item row="2" column="1"> + <widget class="QLineEdit" name="dataPortEdit"> + <property name="inputMask"> + <string notr="true">00009; </string> + </property> + <property name="maxLength"> + <number>5</number> + </property> + </widget> + </item> + <item row="3" column="0" colspan="2"> + <widget class="QLabel" name="dataPortMessage"> + <property name="text"> + <string><span style=" font-weight:600; color:#008800;">OK</span></string> + </property> + <property name="alignment"> + <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> + </property> + </widget> + </item> + <item row="4" column="0"> + <widget class="QLabel" name="label_4"> + <property name="text"> + <string>Transmission Rate</string> + </property> + <property name="alignment"> + <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> + </property> + </widget> + </item> + <item row="4" column="1"> + <widget class="QSpinBox" name="rateSpinbox"> + <property name="sizePolicy"> + <sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="suffix"> + <string> KiB/s</string> + </property> + <property name="maximum"> + <number>10240</number> + </property> + <property name="singleStep"> + <number>10</number> + </property> + <property name="value"> + <number>100</number> + </property> + </widget> + </item> + </layout> + </item> + <item> + <widget class="QDialogButtonBox" name="buttonBox"> + <property name="standardButtons"> + <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set> + </property> + </widget> + </item> + </layout> + </widget> + <layoutdefault spacing="6" margin="11"/> + <resources/> + <connections/> +</ui> |