diff options
| author | Sebastian | 2010-05-12 19:42:27 +0200 |
|---|---|---|
| committer | Sebastian | 2010-05-12 19:42:27 +0200 |
| commit | ce3329047d378a14006ce74ec273ac59e3375303 (patch) | |
| tree | 782430f270b4c7aca1b35d5b7813518e3797c555 /src/gui | |
| download | pvs-ce3329047d378a14006ce74ec273ac59e3375303.tar.gz pvs-ce3329047d378a14006ce74ec273ac59e3375303.tar.xz pvs-ce3329047d378a14006ce74ec273ac59e3375303.zip | |
initial import of latest svn version
Diffstat (limited to 'src/gui')
52 files changed, 10782 insertions, 0 deletions
diff --git a/src/gui/aboutDialog.cpp b/src/gui/aboutDialog.cpp new file mode 100644 index 0000000..a52f70b --- /dev/null +++ b/src/gui/aboutDialog.cpp @@ -0,0 +1,58 @@ +/* + # Copyright (c) 2009, 2010 - 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/ + # ----------------------------------------------------------------------------- + # aboutDialog.cpp + # - shows about dialog + # ----------------------------------------------------------------------------- + */ + +#include "aboutDialog.h" +#include "src/version.h" + +AboutDialog::AboutDialog(QWidget *parent) : + QDialog(parent) +{ + setupUi(this); + + // set version + QString version = tr("Version: ") + (VERSION_STRING); + label_version->setText(version); + + // read authors and write to textEdit + QString authors = ""; + QFile f1(":/AUTHORS"); + if (f1.open(QIODevice::ReadOnly | QIODevice::Text)) + { + QTextStream in(&f1); + authors = in.readAll(); + f1.close(); + } + plainTextEdit_authors->insertPlainText(authors); + plainTextEdit_authors->moveCursor(QTextCursor::Start); + + // read translation and write to textEdit + QString translation = ""; + QFile f2(":/TRANSLATION"); + if (f2.open(QIODevice::ReadOnly | QIODevice::Text)) + { + QTextStream in(&f2); + translation = in.readAll(); + f2.close(); + } + plainTextEdit_translation->insertPlainText(translation); + plainTextEdit_translation->moveCursor(QTextCursor::Start); + +} + +AboutDialog::~AboutDialog() +{ +} diff --git a/src/gui/aboutDialog.h b/src/gui/aboutDialog.h new file mode 100644 index 0000000..5f0489a --- /dev/null +++ b/src/gui/aboutDialog.h @@ -0,0 +1,30 @@ +/* + # Copyright (c) 2009, 2010 - 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/ + */ + +#ifndef ABOUTDIALOG_H_ +#define ABOUTDIALOG_H_ + +#include <QtGui> +#include "ui_aboutDialog.h" + +class AboutDialog: public QDialog, private Ui::AboutDialogClass +{ +Q_OBJECT + +public: + AboutDialog(QWidget *parent = 0); + ~AboutDialog(); + +}; + +#endif /* ABOUTDIALOG_H_ */ diff --git a/src/gui/clientChatDialog.cpp b/src/gui/clientChatDialog.cpp new file mode 100644 index 0000000..7c32790 --- /dev/null +++ b/src/gui/clientChatDialog.cpp @@ -0,0 +1,298 @@ +/* + # Copyright (c) 2009, 2010 - 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/ + # ----------------------------------------------------------------------------- + # clientChatDialog.cpp + # - graphical chat interface + # ----------------------------------------------------------------------------- + */ + +#include "clientChatDialog.h" + +ClientChatDialog::ClientChatDialog(QWidget *parent) : + QDialog(parent) +{ + _trayIcon = NULL; + _nickname = ""; + + setupUi(this); + setAcceptDrops(true); + connect(pushButton, SIGNAL(clicked()), this, SLOT(send())); + + // connect to D-Bus and get interface + QDBusConnection dbus = QDBusConnection::sessionBus(); + dbus.registerObject("/chat", this); + dbus.registerService("org.openslx.pvsgui"); + _ifaceDBus = new OrgOpenslxPvsInterface("org.openslx.pvs", "/", dbus, this); + connect(_ifaceDBus, SIGNAL(chat_receive(QString, QString, QString)), this, + SLOT(receive(QString, QString, QString))); + + // add first tab for public messages + tabWidget->clear(); + QTextEdit *t = new QTextEdit(); + t->setReadOnly(true); + tabWidget->addTab(t, "@all"); + _hash = new QHash<QString, QTextEdit*> (); + _hash->insert(tabWidget->tabText(0), t); + + // already connected? + QDBusPendingReply<QString> reply = _ifaceDBus->isConnected(); + reply.waitForFinished(); + if (reply.isValid() && reply.value() != "") + { + // get available nicknames if already connected + QDBusPendingReply<QStringList> reply1 = _ifaceDBus->chat_getNicknames(); + reply1.waitForFinished(); + QStringList nicknames = reply1.value(); + if (reply1.isValid() && !nicknames.isEmpty()) + listWidget->addItems(nicknames); + + connected(); + } + else + disconnected(); + + // setup menu + _menu = new QMenu(); + _sendFileAction = new QAction(tr("&Send File..."), this); + _menu->addAction(_sendFileAction); + + connect(listWidget, SIGNAL(doubleClicked(QModelIndex)), this, + SLOT(addTab(QModelIndex))); + connect(tabWidget, SIGNAL(tabCloseRequested(int)), this, + SLOT(removeTab(int))); + connect(tabWidget, SIGNAL(currentChanged(int)), this, SLOT(removeIcon(int))); + connect(listWidget, SIGNAL(customContextMenuRequested(QPoint)), this, + SLOT(showMenu(QPoint))); + connect(_sendFileAction, SIGNAL(triggered()), this, + SLOT(sendFile())); + + connect(_ifaceDBus, SIGNAL(chat_client_add(QString)), this, + SLOT(addClient(QString))); + connect(_ifaceDBus, SIGNAL(chat_client_remove(QString)), this, + SLOT(removeClient(QString))); + connect(_ifaceDBus, SIGNAL(disconnected()), listWidget, + SLOT(clear())); + connect(_ifaceDBus, SIGNAL(connected(QString)), this, + SLOT(connected())); + connect(_ifaceDBus, SIGNAL(disconnected()), this, + SLOT(disconnected())); + + lineEdit->setFocus(); +} + +ClientChatDialog::~ClientChatDialog() +{ +} + +//////////////////////////////////////////////////////////////////////////////// +// Public + +void ClientChatDialog::setTrayIcon(QSystemTrayIcon *trayIcon) +{ + _trayIcon = trayIcon; + // FIXME: messageClicked() is always emitted, not only on chat msg + //connect(_trayIcon, SIGNAL(messageClicked()), this, SLOT(open())); +} + +//////////////////////////////////////////////////////////////////////////////// +// Protected + +void ClientChatDialog::dragEnterEvent(QDragEnterEvent *event) +{ + if (event->mimeData()->hasUrls()) + event->accept(); +} + +void ClientChatDialog::dropEvent(QDropEvent *event) +{ + event->accept(); + sendFile(event->mimeData()->urls().first().toLocalFile()); +} + +//////////////////////////////////////////////////////////////////////////////// +// Private + +void ClientChatDialog::send() +{ + QString msg = lineEdit->text(); + if (msg != "") + { + QString nick_to = tabWidget->tabText(tabWidget->currentIndex()); + _ifaceDBus->chat_send(nick_to, _nickname, msg); + lineEdit->clear(); + lineEdit->setFocus(); + + qDebug("[%s] S %s -> %s : %s", metaObject()->className(), + qPrintable(_nickname), qPrintable(nick_to), qPrintable(msg)); + } +} + +void ClientChatDialog::receive(QString nick_from, QString nick_to, QString msg) +{ + qDebug("[%s] R %s <- %s : %s", metaObject()->className(), + qPrintable(nick_to), qPrintable(nick_from), qPrintable(msg)); + + if (nick_to == tabWidget->tabText(0) || nick_from == _nickname) + printMsg(nick_from, msg, getTab(nick_to)); // public message or own msg + else + printMsg(nick_from, msg, getTab(nick_from)); // private message +} + +void ClientChatDialog::addTab(QModelIndex i) +{ + QString text = i.data().toString(); + if (_hash->contains(text)) + tabWidget->setCurrentWidget(_hash->value(text)); + else + { + QTextEdit *t = new QTextEdit(); + t->setReadOnly(true); + tabWidget->setCurrentIndex(tabWidget->addTab(t, text)); + _hash->insert(text, t); + } + lineEdit->setFocus(); +} + +void ClientChatDialog::removeTab(int i) +{ + if (i != 0) + { + _hash->remove(tabWidget->tabText(i)); + tabWidget->removeTab(i); + lineEdit->setFocus(); + } +} + +void ClientChatDialog::addClient(QString nick) +{ + listWidget->addItem(nick); + printEvent("-> " + nick + tr(" has joined the chat.")); +} + +void ClientChatDialog::removeClient(QString nick) +{ + delete listWidget->findItems(nick, Qt::MatchExactly).first(); + printEvent("<- " + nick + tr(" has left the chat.")); +} + +void ClientChatDialog::removeIcon(int i) +{ + tabWidget->setTabIcon(i, QIcon()); +} + +void ClientChatDialog::showMenu(QPoint p) +{ + _menu->popup(listWidget->mapToGlobal(p)); +} + +void ClientChatDialog::sendFile() +{ + ClientFileSendDialog *d = new ClientFileSendDialog(this); + d->open(listWidget->currentItem()->text()); +} + +void ClientChatDialog::sendFile(QString filename) +{ + if (tabWidget->currentIndex() == 0 || filename == "") + return; + + // ask user + QString nick = tabWidget->tabText(tabWidget->currentIndex()); + QMessageBox::StandardButton result = QMessageBox::question(0, + tr("PVS File Transfer"), + tr("Send file '") + filename + tr("' to ") + nick + "?", + QMessageBox::Ok | QMessageBox::Cancel, QMessageBox::Ok); + + if (result != QMessageBox::Ok) + return; + + ClientFileSendDialog *d = new ClientFileSendDialog(this); + d->open(nick, filename); +} + +void ClientChatDialog::connected() +{ + // get current users name from backend + QDBusPendingReply<QString> reply = _ifaceDBus->chat_getNickname(); + reply.waitForFinished(); + if (reply.isValid()) + { + _nickname = reply.value(); + pushButton->setEnabled(true); + printEvent("!!! " + tr("Connected.")); + } + + qDebug("[%s] Nickname: '%s'", metaObject()->className(), + qPrintable(_nickname)); +} + +void ClientChatDialog::disconnected() +{ + pushButton->setEnabled(false); + printEvent("!!! " + tr("Disconnected.")); +} + +QTextEdit* ClientChatDialog::getTab(QString text) +{ + if (!_hash->contains(text)) + { + QTextEdit *t = new QTextEdit(); + t->setReadOnly(true); + tabWidget->addTab(t, text); + _hash->insert(text, t); + } + lineEdit->setFocus(); + return _hash->value(text); +} + +void ClientChatDialog::printMsg(QString nick_from, QString msg, QTextEdit *t) +{ + // move cursor at the end + t->moveCursor(QTextCursor::End); + + // print time + t->setTextColor(QColor(0, 100, 0)); + t->append("[" + QTime::currentTime().toString("hh:mm") + "] "); + + // print nickname + t->setTextColor(QColor(0, 0, 255)); + t->insertPlainText("<" + nick_from + "> "); + + // print message + t->setTextColor(QColor(0, 0, 0)); + t->insertPlainText(msg); + + // show icon if not current tab + if (tabWidget->currentIndex() != tabWidget->indexOf(t)) + tabWidget->setTabIcon(tabWidget->indexOf(t), QIcon(":chat_msg16.svg")); + + // show balloon message if supported and chat-dialog is not visible + if (!isVisible() && _trayIcon && QSystemTrayIcon::supportsMessages()) + _trayIcon->showMessage(tr("Message from <") + nick_from + ">", msg, + QSystemTrayIcon::Information, 20000); +} + +void ClientChatDialog::printEvent(QString msg) +{ + QTextEdit *t = _hash->value(tabWidget->tabText(0)); + + // move cursor at the end + t->moveCursor(QTextCursor::End); + + t->setTextColor(QColor(150, 150, 150)); + + // print time + t->append("[" + QTime::currentTime().toString("hh:mm") + "] "); + + // print message + t->insertPlainText(msg); +} diff --git a/src/gui/clientChatDialog.h b/src/gui/clientChatDialog.h new file mode 100644 index 0000000..42bbb75 --- /dev/null +++ b/src/gui/clientChatDialog.h @@ -0,0 +1,63 @@ +/* + # Copyright (c) 2009, 2010 - 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/ + */ + +#ifndef CLIENTCHATDIALOG_H_ +#define CLIENTCHATDIALOG_H_ + +#include <QtGui> +#include "pvsinterface.h" +#include "clientFileSendDialog.h" +#include "ui_clientChatDialog.h" + +class ClientChatDialog: public QDialog, private Ui::ClientChatDialogClass +{ +Q_OBJECT + +public: + ClientChatDialog(QWidget *parent = 0); + ~ClientChatDialog(); + void setTrayIcon(QSystemTrayIcon *trayIcon); + +private Q_SLOTS: + void send(); + void receive(QString nick_from, QString nick_to, QString msg); + void addTab(QModelIndex i); + void removeTab(int i); + void addClient(QString nick); + void removeClient(QString nick); + void showMenu(QPoint p); + void removeIcon(int i); + void sendFile(); + void sendFile(QString filename); + void connected(); + void disconnected(); + +protected: + void dragEnterEvent(QDragEnterEvent *event); + void dropEvent(QDropEvent *event); + +private: + QTextEdit* getTab(QString text); + void printMsg(QString nick_from, QString msg, QTextEdit *t); + void printEvent(QString msg); + + OrgOpenslxPvsInterface *_ifaceDBus; + QHash<QString, QTextEdit*> *_hash; + QSystemTrayIcon *_trayIcon; + QString _nickname; + QMenu *_menu; + QAction *_sendFileAction; + +}; + +#endif /* CLIENTCHATDIALOG_H_ */ diff --git a/src/gui/clientConfigDialog.cpp b/src/gui/clientConfigDialog.cpp new file mode 100644 index 0000000..76b4f5e --- /dev/null +++ b/src/gui/clientConfigDialog.cpp @@ -0,0 +1,105 @@ +/* + # Copyright (c) 2009, 2010 - 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/ + # ----------------------------------------------------------------------------- + # clientConfigDialog.cpp + # - graphical interface + # - all configuration used by pvs/pvsgui is done here + # ----------------------------------------------------------------------------- + */ + +#include "clientConfigDialog.h" + +ClientConfigDialog::ClientConfigDialog(QWidget *parent) : + QDialog(parent) +{ + setupUi(this); + connect(this, SIGNAL(accepted()), this, SLOT(writeSettings())); + connect(radioButtonOtherRO, SIGNAL(clicked()), this, + SLOT(checkPermissions())); + +} + +ClientConfigDialog::~ClientConfigDialog() +{ + +} + +//////////////////////////////////////////////////////////////////////////////// +// Public + +void ClientConfigDialog::open() +{ + readSettings(); + setVisible(true); +} + +void ClientConfigDialog::readSettings() +{ + if (_settings.value("Display/location").isNull()) + comboBox->setCurrentIndex(1); + else + comboBox->setCurrentIndex(_settings.value("Display/location").toInt()); + + if (_settings.value("Permissions/vnc_lecturer").toString() == "rw") + radioButtonLecturerRW->setChecked(true); + else if (_settings.value("Permissions/vnc_lecturer").toString() == "ro") + radioButtonLecturerRO->setChecked(true); + else + radioButtonLecturerNO->setChecked(true); + if (_settings.value("Permissions/vnc_other").toString() == "rw") + radioButtonOtherRW->setChecked(true); + else if (_settings.value("Permissions/vnc_other").toString() == "ro") + radioButtonOtherRO->setChecked(true); + else + radioButtonOtherNO->setChecked(true); + checkBoxAllowChat->setChecked( + _settings.value("Permissions/allow_chat").toBool()); + checkBoxAllowFiletransfer->setChecked(_settings.value( + "Permissions/allow_filetransfer").toBool()); + + qDebug("[%s] Setting read from: '%s'", metaObject()->className(), + qPrintable(_settings.fileName())); +} + +void ClientConfigDialog::writeSettings() +{ + _settings.setValue("Display/location", comboBox->currentIndex()); + if (radioButtonLecturerRW->isChecked()) + _settings.setValue("Permissions/vnc_lecturer", "rw"); + else if (radioButtonLecturerRO->isChecked()) + _settings.setValue("Permissions/vnc_lecturer", "ro"); + else + _settings.setValue("Permissions/vnc_lecturer", "no"); + if (radioButtonOtherRW->isChecked()) + _settings.setValue("Permissions/vnc_other", "rw"); + else if (radioButtonOtherRO->isChecked()) + _settings.setValue("Permissions/vnc_other", "ro"); + else + _settings.setValue("Permissions/vnc_other", "no"); + _settings.setValue("Permissions/allow_chat", checkBoxAllowChat->isChecked()); + _settings.setValue("Permissions/allow_filetransfer", + checkBoxAllowFiletransfer->isChecked()); + _settings.sync(); + emit configChanged(); + + qDebug("[%s] Settings written to: '%s'.", metaObject()->className(), + qPrintable(_settings.fileName())); +} + +//////////////////////////////////////////////////////////////////////////////// +// Private + +void ClientConfigDialog::checkPermissions() +{ + if (radioButtonLecturerNO->isChecked() && radioButtonOtherRO->isChecked()) + radioButtonLecturerRO->setChecked(true); +} diff --git a/src/gui/clientConfigDialog.h b/src/gui/clientConfigDialog.h new file mode 100644 index 0000000..706bd8a --- /dev/null +++ b/src/gui/clientConfigDialog.h @@ -0,0 +1,44 @@ +/* + # Copyright (c) 2009, 2010 - 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/ + */ + +#ifndef CLIENTCONFIGDIALOG_H_ +#define CLIENTCONFIGDIALOG_H_ + +#include <QtGui> +#include "ui_clientConfigDialog.h" + +class ClientConfigDialog: public QDialog, private Ui::ClientConfigDialogClass +{ +Q_OBJECT + +public: + ClientConfigDialog(QWidget *parent = 0); + ~ClientConfigDialog(); + +public Q_SLOTS: + void open(); + void readSettings(); + void writeSettings(); + +Q_SIGNALS: + void configChanged(); + +private Q_SLOTS: + void checkPermissions(); + +private: + QSettings _settings; + +}; + +#endif /* CLIENTCONFIGDIALOG_H_ */ diff --git a/src/gui/clientFileReceiveDialog.cpp b/src/gui/clientFileReceiveDialog.cpp new file mode 100644 index 0000000..669ca81 --- /dev/null +++ b/src/gui/clientFileReceiveDialog.cpp @@ -0,0 +1,181 @@ +/* + # Copyright (c) 2009, 2010 - 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/ + # ----------------------------------------------------------------------------- + # clientFileReceiveDialog.cpp + # - filechooser and progress dialog + # ----------------------------------------------------------------------------- + */ + +#include "clientFileReceiveDialog.h" + +ClientFileReceiveDialog::ClientFileReceiveDialog(QTcpSocket *socket, QWidget *parent) : + QDialog(parent) +{ + setupUi(this); + + _file = NULL; + _bytesToRead = 0; + _socket = socket; + + connect(_socket, SIGNAL(readyRead()), this, SLOT(receiveHeader())); + connect(_socket, SIGNAL(disconnected()), this, SLOT(close())); + connect(_socket, SIGNAL(error(QAbstractSocket::SocketError)), + this, SLOT(error(QAbstractSocket::SocketError))); + + qDebug("[%s] New Connection: %s", metaObject()->className(), + qPrintable(_socket->peerAddress().toString())); + + connect(this, SIGNAL(finished(int)), this, SLOT(deleteLater())); +} + +ClientFileReceiveDialog::~ClientFileReceiveDialog() +{ + _socket->deleteLater(); + qDebug("[%s] Deleted!", metaObject()->className()); +} + +//////////////////////////////////////////////////////////////////////////////// +// Private + +void ClientFileReceiveDialog::receiveHeader() +{ + // parse header + QString header = QString::fromUtf8(_socket->readLine()); + QStringList args = header.split(";"); + QString nick = args[0]; + QString filename = args[1]; + _bytesToRead = args[2].toLongLong(); + div = 1 + _bytesToRead / 1000000000; // bc. progressBar supports only int + + qDebug("[%s] Received header.", metaObject()->className()); + + // ask user + QMessageBox::StandardButton result = QMessageBox::question(0, + tr("PVS File Transfer"),tr("User '") + nick + + tr("' would like to send you a file: ") + filename + + " (" + formatSize(_bytesToRead) + ").", + QMessageBox::Ok | QMessageBox::Cancel, QMessageBox::Ok); + + if (result != QMessageBox::Ok) + { + sendAck(false); + return; + } + + // open file + QString saveAs = QFileDialog::getSaveFileName(this, tr("Open File"), + QDir::homePath() + QDir::separator() + filename, ""); + if (saveAs == "") + { + sendAck(false); + return; + } + _file = new QFile(saveAs); + _file->open(QIODevice::WriteOnly); + + // gui + filenameLabel->setText(saveAs); + progressBar->setValue(0); + progressBar->setMaximum(_bytesToRead/div); + labelNick->setText(nick); + labelB->setText(formatSize(_bytesToRead)); + connect(cancelButton, SIGNAL(clicked()), this, SLOT(close())); + + sendAck(true); + show(); +} + +void ClientFileReceiveDialog::sendAck(bool b) +{ + disconnect(_socket, SIGNAL(readyRead()), this, SLOT(receiveHeader())); + + if (b) + { + QString ack = QString("ok\n"); + _socket->write(ack.toUtf8()); + qDebug("[%s] Sending ack...", metaObject()->className()); + connect(_socket, SIGNAL(readyRead()), this, SLOT(receiveFile())); + } + else + { + QString ack = QString("no\n"); + _socket->write(ack.toUtf8()); + qDebug("[%s] Sending nack!!!", metaObject()->className()); + close(); + } +} + +void ClientFileReceiveDialog::receiveFile() +{ + qint64 bytesRead = _file->write(_socket->readAll()); + _bytesToRead -= bytesRead; + progressBar->setValue(progressBar->value() + bytesRead/div); + labelA->setText(formatSize(progressBar->value()*div)); +} + +void ClientFileReceiveDialog::close() +{ + if (_file && _file->isOpen()) + { + _file->flush(); + _file->close(); + qDebug("[%s] File closed.", metaObject()->className()); + } + + if (_socket && _socket->isOpen()) + { + disconnect(_socket, SIGNAL(readyRead()), this, SLOT(receiveHeader())); + disconnect(_socket, SIGNAL(readyRead()), this, SLOT(receiveFile())); + disconnect(_socket, SIGNAL(disconnected()), this, SLOT(close())); + 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())); + + if (_bytesToRead == 0) + { + accept(); + QMessageBox::information(0, tr("PVS - File Transfer"), + tr("File Transfer complete.")); + } + else + { + reject(); + QMessageBox::warning(0, tr("PVS - File Transfer"), + tr("File Transfer canceled!")); + } +} + +void ClientFileReceiveDialog::error(QAbstractSocket::SocketError error) +{ + if (error == QAbstractSocket::RemoteHostClosedError) + qDebug("[%s] Socket closed by remote host.", metaObject()->className()); + else + qDebug("[%s] Socket error: %i", metaObject()->className(), error); + + close(); +} + +QString ClientFileReceiveDialog::formatSize(qint64 size) +{ + if (size >= 1000000000) // GB + return QString("%1GB").arg((qreal)size / 1000000000, 0, 'f',1); + else if (size >= 1000000) // MB + return QString("%1MB").arg((qreal)size / 1000000, 0, 'f',1); + else if (size >= 1000) // KB + return QString("%1KB").arg((qreal)size / 1000, 0, 'f',1); + else // B + return QString("%1B").arg((qreal)size, 0, 'f',1); +} diff --git a/src/gui/clientFileReceiveDialog.h b/src/gui/clientFileReceiveDialog.h new file mode 100644 index 0000000..c13d7b7 --- /dev/null +++ b/src/gui/clientFileReceiveDialog.h @@ -0,0 +1,47 @@ +/* + # Copyright (c) 2009, 2010 - 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/ + */ + +#ifndef CLIENTFILERECEIVEDIALOG_H_ +#define CLIENTFILERECEIVEDIALOG_H_ + +#include <QtGui> +#include <QtNetwork> +#include "ui_clientFileReceiveDialog.h" + +class ClientFileReceiveDialog: public QDialog, + private Ui::ClientFileReceiveDialogClass +{ +Q_OBJECT + +public: + ClientFileReceiveDialog(QTcpSocket *socket, QWidget *parent = 0); + ~ClientFileReceiveDialog(); + +private Q_SLOTS: + void receiveHeader(); + void receiveFile(); + void close(); + void error(QAbstractSocket::SocketError error); + +private: + void sendAck(bool b); + QString formatSize(qint64 size); + + QTcpSocket *_socket; + QFile *_file; + qint64 _bytesToRead; + int div; + +}; + +#endif /* CLIENTFILERECEIVEDIALOG_H_ */ diff --git a/src/gui/clientFileSendDialog.cpp b/src/gui/clientFileSendDialog.cpp new file mode 100644 index 0000000..ccb44b3 --- /dev/null +++ b/src/gui/clientFileSendDialog.cpp @@ -0,0 +1,248 @@ +/* + # Copyright (c) 2009, 2010 - 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/ + # ----------------------------------------------------------------------------- + # clientFileSendDialog.cpp + # - filechooser and progress dialog + # ----------------------------------------------------------------------------- + */ + +#include "clientFileSendDialog.h" + +ClientFileSendDialog::ClientFileSendDialog(QWidget *parent) : + QDialog(parent) +{ + setupUi(this); + + _file = NULL; + _socket = NULL; + _clientNicklistDialog = new ClientNicklistDialog(this); + + // connect to D-Bus and get interface + QDBusConnection dbus = QDBusConnection::sessionBus(); + dbus.registerObject("/filesend", this); + dbus.registerService("org.openslx.pvsgui"); + _ifaceDBus = new OrgOpenslxPvsInterface("org.openslx.pvs", "/", dbus, this); + + // get current users name from backend + QDBusPendingReply<QString> reply = _ifaceDBus->chat_getNickname(); + reply.waitForFinished(); + if (reply.isValid()) + _nickname = reply.value(); + else + _nickname = "unknown"; + + connect(this, SIGNAL(finished(int)), this, SLOT(deleteLater())); +} + +ClientFileSendDialog::~ClientFileSendDialog() +{ + qDebug("[%s] Deleted!", metaObject()->className()); +} + +//////////////////////////////////////////////////////////////////////////////// +// Public + +void ClientFileSendDialog::open() +{ + // get nick of remote user + int result = _clientNicklistDialog->exec(); + if (result == 0) // User canceled + { + reject(); + return; + } + open(_clientNicklistDialog->getNick()); +} + +void ClientFileSendDialog::open(QString nick) +{ + QString filename = QFileDialog::getOpenFileName(this, tr("Open File"), + QDir::homePath(), ""); + if (filename == "") + { + reject(); + return; + } + open(nick, filename); +} + +void ClientFileSendDialog::open(QString nick, QString filename) +{ + // open file + _file = new QFile(filename); + _file->open(QIODevice::ReadOnly); + _bytesToWrite = _file->size(); + div = 1 + _bytesToWrite / 1000000000; // bc. progressBar supports only int + + // get host from backend + QString host = ""; + QDBusPendingReply<QString> reply = _ifaceDBus->getIpByNick(nick); + reply.waitForFinished(); + if (reply.isValid()) + host = reply.value(); + else // DBus Error, hostname + qDebug("[%s] D-Bus ERROR, no hostname available!", metaObject()->className()); + + // gui + filenameLabel->setText(filename); + progressBar->setValue(0); + progressBar->setMaximum(_bytesToWrite/div); + labelNick->setText(nick); + labelB->setText(formatSize(_bytesToWrite)); + connect(cancelButton, SIGNAL(clicked()), this, SLOT(close())); + + // open socket + _socket = new QTcpSocket(); + _socket->connectToHost(host, 29481); + qDebug("[%s] Remote host: %s", metaObject()->className(), qPrintable(host)); + + connect(_socket, SIGNAL(connected()), this, SLOT(sendHeader())); + connect(_socket, SIGNAL(disconnected()), this, SLOT(close())); + connect(_socket, SIGNAL(error(QAbstractSocket::SocketError)), + this, SLOT(error(QAbstractSocket::SocketError))); +} + +//////////////////////////////////////////////////////////////////////////////// +// Private + +void ClientFileSendDialog::sendHeader() +{ + QFileInfo info(_file->fileName()); + QString size = QString::number(_bytesToWrite); + QString header = _nickname + ";" + info.fileName() + ";" + size + "\n"; + _socket->write(header.toLocal8Bit()); + connect(_socket, SIGNAL(readyRead()), this, SLOT(receiveAck())); + qDebug("[%s] Sending header...", metaObject()->className()); +} + +void ClientFileSendDialog::receiveAck() +{ + QString ack = QString::fromUtf8(_socket->readLine()); + if (ack != "ok\n") + { + qDebug("[%s] Received nack!", metaObject()->className()); + close(); + return; + } + qDebug("[%s] Received ack.", metaObject()->className()); + + disconnect(_socket, SIGNAL(readyRead()), this, SLOT(receiveAck())); + connect(_socket, SIGNAL(bytesWritten(qint64)), this, SLOT(sendFile())); + show(); + qDebug("[%s] Sending file...", metaObject()->className()); + sendFile(); +} + +void ClientFileSendDialog::sendFile() +{ + if (_bytesToWrite == 0) + { + qDebug("[%s] Transfer completed.", metaObject()->className()); + close(); // finished + } + else + { + qint64 bytesWritten = _socket->write(_file->read(1024)); // data left + _bytesToWrite -= bytesWritten; + progressBar->setValue(progressBar->value() + bytesWritten/div); + labelA->setText(formatSize(progressBar->value()*div)); + } +} + +void ClientFileSendDialog::close() +{ + 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())); + + if (_bytesToWrite == 0) + { + accept(); + QMessageBox::information(0, tr("PVS - File Transfer"), + tr("File Transfer complete.")); + } + else + { + reject(); + QMessageBox::warning(0, tr("PVS - File Transfer"), + tr("File Transfer canceled!")); + } +} + +void ClientFileSendDialog::error(QAbstractSocket::SocketError error) +{ + qDebug("[%s] Socket error: %i", metaObject()->className(), error); + close(); +} + +QString ClientFileSendDialog::formatSize(qint64 size) +{ + if (size >= 1000000000) // GB + return QString("%1GB").arg((qreal)size / 1000000000, 0, 'f',1); + else if (size >= 1000000) // MB + return QString("%1MB").arg((qreal)size / 1000000, 0, 'f',1); + else if (size >= 1000) // KB + return QString("%1KB").arg((qreal)size / 1000, 0, 'f',1); + else // B + return QString("%1B").arg((qreal)size, 0, 'f',1); +} + +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + +ClientNicklistDialog::ClientNicklistDialog(QWidget *parent) : + QDialog(parent) +{ + setupUi(this); + + // connect to D-Bus and get interface + QDBusConnection dbus = QDBusConnection::sessionBus(); + dbus.registerObject("/nicklist", this); + dbus.registerService("org.openslx.pvsgui"); + _ifaceDBus = new OrgOpenslxPvsInterface("org.openslx.pvs", "/", dbus, this); + + // get available nicknames + QDBusPendingReply<QStringList> reply = _ifaceDBus->chat_getNicknames(); + reply.waitForFinished(); + QStringList nicknames = reply.value(); + if (!reply.isValid() || nicknames.isEmpty()) // DBus Error, nicknames + qDebug("[%s] D-Bus ERROR, no nicknames available!", metaObject()->className()); + + listWidget->addItems(nicknames); + listWidget->setCurrentRow(0); +} + +ClientNicklistDialog::~ClientNicklistDialog() +{ + +} + +QString ClientNicklistDialog::getNick() +{ + return listWidget->currentItem()->text(); +} diff --git a/src/gui/clientFileSendDialog.h b/src/gui/clientFileSendDialog.h new file mode 100644 index 0000000..d8afc3a --- /dev/null +++ b/src/gui/clientFileSendDialog.h @@ -0,0 +1,76 @@ +/* + # Copyright (c) 2009, 2010 - 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/ + */ + +#ifndef CLIENTFILESENDDIALOG_H_ +#define CLIENTFILESENDDIALOG_H_ + +#include <QtGui> +#include <QtNetwork> +#include "pvsinterface.h" +#include "ui_clientFileSendDialog.h" +#include "ui_clientNicklistDialog.h" + +class ClientNicklistDialog: public QDialog, + private Ui::ClientNicklistDialogClass +{ +Q_OBJECT + +public: + ClientNicklistDialog(QWidget *parent = 0); + ~ClientNicklistDialog(); + + QString getNick(); + +private: + OrgOpenslxPvsInterface *_ifaceDBus; + +}; + +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + +class ClientFileSendDialog: public QDialog, + private Ui::ClientFileSendDialogClass +{ +Q_OBJECT + +public: + ClientFileSendDialog(QWidget *parent = 0); + ~ClientFileSendDialog(); + + void open(); + void open(QString nick); + void open(QString nick, QString filename); + +private Q_SLOTS: + void sendHeader(); + void receiveAck(); + void sendFile(); + void close(); + void error(QAbstractSocket::SocketError error); + +private: + QString formatSize(qint64 size); + + QTcpSocket *_socket; + QFile *_file; + qint64 _bytesToWrite; + int div; + + ClientNicklistDialog *_clientNicklistDialog; + OrgOpenslxPvsInterface *_ifaceDBus; + QString _nickname; + +}; + +#endif /* CLIENTFILESENDDIALOG_H_ */ diff --git a/src/gui/clientInfoDialog.cpp b/src/gui/clientInfoDialog.cpp new file mode 100644 index 0000000..02a6fd8 --- /dev/null +++ b/src/gui/clientInfoDialog.cpp @@ -0,0 +1,60 @@ +/* + # Copyright (c) 2009, 2010 - 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/ + # ----------------------------------------------------------------------------- + # clientInfoDialog.cpp + # - shows big info dialog (connected host and passwd) + # ----------------------------------------------------------------------------- + */ + +#include "clientInfoDialog.h" + +ClientInfoDialog::ClientInfoDialog(QWidget *parent) : + QDialog(parent) +{ + setupUi(this); +} + +ClientInfoDialog::~ClientInfoDialog() +{ + +} + +//////////////////////////////////////////////////////////////////////////////// +// Public + +void ClientInfoDialog::setHost(QString host) +{ + hostLabel->setText("<!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:'DejaVu Sans'; font-size:9pt; " + "font-weight:400; font-style:normal;\"><p style=\" margin-top:0px; " + "margin-bottom:0px; margin-left:0px; margin-right:0px; " + "-qt-block-indent:0; text-indent:0px;\"><span style=\" " + "font-size:72pt; font-weight:600; color:#0000ff;\">" + + host + "</span></p></body></html>"); +} + +void ClientInfoDialog::setPasswd(QString passwd) +{ + passwdLabel->setText("<!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:'DejaVu Sans'; font-size:9pt; " + "font-weight:400; font-style:normal;\"><p style=\" margin-top:0px; " + "margin-bottom:0px; margin-left:0px; margin-right:0px; " + "-qt-block-indent:0; text-indent:0px;\"><span style=\" " + "font-size:48pt; font-weight:600; color:#ff0000;\">" + + passwd + "</span></p></body></html>"); +} diff --git a/src/gui/clientInfoDialog.h b/src/gui/clientInfoDialog.h new file mode 100644 index 0000000..770b5b7 --- /dev/null +++ b/src/gui/clientInfoDialog.h @@ -0,0 +1,32 @@ +/* + # Copyright (c) 2009, 2010 - 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/ + */ + +#ifndef CLIENTINFODIALOG_H_ +#define CLIENTINFODIALOG_H_ + +#include <QtGui> +#include "ui_clientInfoDialog.h" + +class ClientInfoDialog: public QDialog, private Ui::InfoDialogClass +{ +Q_OBJECT + +public: + ClientInfoDialog(QWidget *parent = 0); + ~ClientInfoDialog(); + + void setHost(QString host); + void setPasswd(QString passwd); +}; + +#endif /* CLIENTINFODIALOG_H_ */ diff --git a/src/gui/clientVNCViewer.cpp b/src/gui/clientVNCViewer.cpp new file mode 100644 index 0000000..d6a218b --- /dev/null +++ b/src/gui/clientVNCViewer.cpp @@ -0,0 +1,273 @@ +/* + # Copyright (c) 2009, 2010 - 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/ + # ----------------------------------------------------------------------------- + # clientVNCViewer.cpp + # - connetct to vnc server and show remote screen (window/full) + # ----------------------------------------------------------------------------- + */ + +#include "clientVNCViewer.h" + +ClientVNCViewer::ClientVNCViewer(QWidget *parent) : + QDialog(parent), _thread(0), _viewOnly(true), _buttonMask(0) +{ + // connect to D-Bus and get interface + QDBusConnection dbus = QDBusConnection::sessionBus(); + dbus.registerObject("/vnc", this); + dbus.registerService("org.openslx.pvsgui"); + _ifaceDBus = new OrgOpenslxPvsInterface("org.openslx.pvs", "/", dbus, this); + connect(_ifaceDBus, SIGNAL(project(QString, int, QString, bool, bool, int)), + this, SLOT(open(QString, int, QString, bool, bool, int))); + connect(_ifaceDBus, SIGNAL(unproject()), this, SLOT(close())); +} + +ClientVNCViewer::~ClientVNCViewer() +{ + close(); +} + +//////////////////////////////////////////////////////////////////////////////// +// Public + +void ClientVNCViewer::open(QString host, int port, QString passwd, bool fs, + bool mode, int quality) +{ + // start thread for vnc-updates + _thread = new VNCClientThread(host, port, passwd, quality); + _thread->start(); + //_rfbclient = _thread->getRfbClient(); + //installEventFilter(this); + setMouseTracking(true); // get mouse events even when there is no mousebutton pressed + setFocusPolicy(Qt::WheelFocus); //needed?!? + + setAttribute(Qt::WA_OpaquePaintEvent); + + // smooth transformation? + if (mode) + _mode = Qt::SmoothTransformation; + else + _mode = Qt::FastTransformation; + + // fullscreen? + if (fs) + { + setWindowFlags(Qt::WindowStaysOnTopHint); + showFullScreen(); + activateWindow(); + raise(); + } + else + showNormal(); + + connect(this, SIGNAL(rejected()), this, SLOT(close())); + connect(_thread, SIGNAL(imageUpdated(int,int,int,int)), this, + SLOT(updateImage(int,int,int,int)), Qt::BlockingQueuedConnection); +} + +void ClientVNCViewer::close() +{ + setVisible(false); + if (_thread) + { + disconnect(_thread, SIGNAL(imageUpdated(int,int,int,int)), this, + SLOT(updateImage(int,int,int,int))); + + _thread->terminate = true; + _thread->wait(1000); + delete _thread; + _thread = NULL; + } + disconnect(this, SIGNAL(rejected()), this, SLOT(close())); +} + +void ClientVNCViewer::updateImage(int x, int y, int w, int h) +{ + if (_thread->getSize() != size()) // scaling needed? + { + // grow the update rectangle to avoid artifacts + x -= 1; + y -= 1; + w += 2; + h += 2; + + _img = _thread->getImage().copy(x, y, w, h); + + qreal sx = qreal(width()) / qreal(_thread->getSize().width()); + qreal sy = qreal(height()) / qreal(_thread->getSize().height()); + + x = qRound(qreal(x) * sx); + y = qRound(qreal(y) * sy); + w = qRound(qreal(w) * sx); + h = qRound(qreal(h) * sy); + } + else + { + _img = _thread->getImage().copy(x, y, w, h); + } + + repaint(x, y, w, h); +} + +//////////////////////////////////////////////////////////////////////////////// +// Protected + +void ClientVNCViewer::paintEvent(QPaintEvent *event) +{ + if (_img.isNull()) + return; + + QPainter painter(this); + QRect r = event->rect(); + + if (r == rect()) + _img = _thread->getImage(); // redraw complete image (e.g. on resize) + + if (_thread->getSize() == size()) + { + painter.drawImage(r.topLeft(), _img); // don't scale + } + else + { + QImage i = _img.scaled(r.size(), Qt::IgnoreAspectRatio, _mode); + painter.drawImage(r.topLeft(), i); + } + event->accept(); +} +//returns true if event was processed +/*bool ClientVNCViewer::event(QEvent *event) +{ + switch (event->type()) { + case QEvent::KeyPress: + case QEvent::KeyRelease: + + keyEventHandler(static_cast<QKeyEvent*>(event)); + return true; + break; + case QEvent::MouseButtonDblClick: + case QEvent::MouseButtonPress: + case QEvent::MouseButtonRelease: + case QEvent::MouseMove: + mouseEventHandler(static_cast<QMouseEvent*>(event)); + return true; + break; + case QEvent::Wheel: + wheelEventHandler(static_cast<QWheelEvent*>(event)); + return true; + break; + default: + return false; + } +}*/ + +//handles mouseevents +void ClientVNCViewer::mouseEventHandler(QMouseEvent *e) +{ + if (e->type() != QEvent::MouseMove) { + if ((e->type() == QEvent::MouseButtonPress) || + (e->type() == QEvent::MouseButtonDblClick)) { + if (e->button() & Qt::LeftButton) + _buttonMask |= 0x01; + if (e->button() & Qt::MidButton) + _buttonMask |= 0x02; + if (e->button() & Qt::RightButton) + _buttonMask |= 0x04; + } else if (e->type() == QEvent::MouseButtonRelease) { + if (e->button() & Qt::LeftButton) + _buttonMask &= 0xfe; + if (e->button() & Qt::MidButton) + _buttonMask &= 0xfd; + if (e->button() & Qt::RightButton) + _buttonMask &= 0xfb; + } + } + qreal sx = qreal(width()) / qreal(_thread->getSize().width()); + qreal sy = qreal(height()) / qreal(_thread->getSize().height()); + _thread->mouseEvent(qRound(e->x() / sx), qRound(e->y() / sy), _buttonMask); +} + +//handles mousewheel +void ClientVNCViewer::wheelEventHandler(QWheelEvent *event) +{ + int eb = 0; + if (event->delta() < 0) + eb |= 0x10; + else + eb |= 0x8; + + qreal sx = qreal(width()) / qreal(_thread->getSize().width()); + qreal sy = qreal(height()) / qreal(_thread->getSize().height()); + const int x = qRound(event->x() / sx); + const int y = qRound(event->y() / sy); + + _thread->mouseEvent(x, y, eb | _buttonMask); + _thread->mouseEvent(x, y, _buttonMask); +} + +//Handles keypress +void ClientVNCViewer::keyEventHandler(QKeyEvent *e) +{ + rfbKeySym k = e->nativeVirtualKey(); + + // do not handle Key_Backtab separately because the Shift-modifier + // is already enabled + if (e->key() == Qt::Key_Backtab) { + k = XK_Tab; + } + + const bool pressed = (e->type() == QEvent::KeyPress); + + // handle modifiers + if (k == XK_Shift_L || k == XK_Control_L || k == XK_Meta_L || k == XK_Alt_L) { + if (pressed) { + _modkeys[k] = true; + } else if (_modkeys.contains(k)) { + _modkeys.remove(k); + } else { + unpressModifiers(); + } + } + + if (k) { + _thread->keyEvent(k, pressed); + } +} + +//removes modifier keys which have been pressed +void ClientVNCViewer::unpressModifiers() +{ + const QList<unsigned int> keys = _modkeys.keys(); + QList<unsigned int>::const_iterator it = keys.constBegin(); + while (it != keys.end()) { + _thread->keyEvent(*it, false); + it++; + } + _modkeys.clear(); +} + +//(QT Function) Filters events, if _viewOnly is set, true is returned and the event is ignored +//TODO use this function when implementing viewonly switch +bool ClientVNCViewer::eventFilter(QObject *obj, QEvent *event) +{ + if (_viewOnly) { + if (event->type() == QEvent::KeyPress || + event->type() == QEvent::KeyRelease || + event->type() == QEvent::MouseButtonDblClick || + event->type() == QEvent::MouseButtonPress || + event->type() == QEvent::MouseButtonRelease || + event->type() == QEvent::Wheel || + event->type() == QEvent::MouseMove) + return true; + } + + return false; + //return RemoteView::eventFilter(obj, event); +} diff --git a/src/gui/clientVNCViewer.h b/src/gui/clientVNCViewer.h new file mode 100644 index 0000000..6ff9c33 --- /dev/null +++ b/src/gui/clientVNCViewer.h @@ -0,0 +1,67 @@ +/* + # Copyright (c) 2009, 2010 - 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/ + */ + +#ifndef CLIENTVNCVIEWER_H_ +#define CLIENTVNCVIEWER_H_ + +#include <QtGui> +#include <QMouseEvent> +#include "pvsinterface.h" +#include "../util/vncClientThread.h" + +// Definition of key modifier mask constants +#define KMOD_Alt_R 0x01 +#define KMOD_Alt_L 0x02 +#define KMOD_Meta_L 0x04 +#define KMOD_Control_L 0x08 +#define KMOD_Shift_L 0x10 + +class ClientVNCViewer: public QDialog +{ +Q_OBJECT + +public: + ClientVNCViewer(QWidget *parent = 0); + virtual ~ClientVNCViewer(); + +public Q_SLOTS: + void open(QString host, int port, QString passwd, bool fullscreen = false, + bool smoothTransformation = false, int quality = 0); + void close(); + void updateImage(int x, int y, int w, int h); + +protected: + void paintEvent(QPaintEvent *event); + //bool event(QEvent *event); + //bool eventFilter(QObject *obj, QEvent *event); + +private: + VNCClientThread *_thread; + //rfbClient *_rfbclient; + QImage _img; + bool _viewOnly; + int _buttonMask; + QMap<unsigned int, bool> _modkeys; + bool eventFilter(QObject *obj, QEvent *event); + void keyEventHandler(QKeyEvent *e); + void unpressModifiers(); + void wheelEventHandler(QWheelEvent *event); + void mouseEventHandler(QMouseEvent *event); + + + Qt::TransformationMode _mode; + + OrgOpenslxPvsInterface *_ifaceDBus; +}; + +#endif /* CLIENTVNCVIEWER_H_ */ diff --git a/src/gui/connectionDialog.cpp b/src/gui/connectionDialog.cpp new file mode 100644 index 0000000..8c5b743 --- /dev/null +++ b/src/gui/connectionDialog.cpp @@ -0,0 +1,216 @@ +#include "connectionDialog.h" + +ConnectionDialog::ConnectionDialog(MainWindow* newParent, const Glib::ustring& title) + : buttonOK("OK"), + buttonCancel("Cancel") + +{ + set_default_size(300, 100); + if (newParent) + myParent = newParent; + else + ; // handle errors + + set_title(title); + buttonOK.signal_clicked().connect(sigc::mem_fun(*this, &ConnectionDialog::on_button_ok_click)); + buttonCancel.signal_clicked().connect(sigc::mem_fun(*this, &ConnectionDialog::on_button_cancel_click)); + + + windowBox.pack_start(contentBox, Gtk::PACK_SHRINK); + windowBox.pack_start(buttonBox, Gtk::PACK_SHRINK); + buttonBox.pack_end(buttonOK, Gtk::PACK_SHRINK); + buttonBox.pack_end(buttonCancel, Gtk::PACK_SHRINK); + + + add(windowBox); + show_all_children(); +} + +ConnectionDialog::~ConnectionDialog() +{} + +void ConnectionDialog::on_button_ok_click() +{ + hide(); +} + +void ConnectionDialog::on_button_cancel_click() +{ + hide(); +} + + + +PasswordDialog::PasswordDialog(MainWindow* newParent, const Glib::ustring& title, QString* newTargetPW) + : ConnectionDialog(newParent, title), + frameIP(*newTargetPW), + targetPW(newTargetPW) + +{ + *newTargetPW = ""; + entryPW.signal_activate().connect(sigc::mem_fun(*this, &PasswordDialog::on_enter_password)); + + frameIP.add(entryPW); + contentBox.add(frameIP); + + show_all_children(); + +} + +PasswordDialog::~PasswordDialog() +{} + +void PasswordDialog::on_button_ok_click() +{ + if (password != "") // there was a password set by pressing enter in the pw-entry + { + *targetPW = password; + ConnectionDialog::on_button_ok_click(); + } + else // it was just typed or not supplied + { + *targetPW = entryPW.get_text(); + if (*targetPW != "") + ConnectionDialog::on_button_ok_click(); + + } + +} + +void PasswordDialog::on_button_cancel_click() +{ + *targetPW = ""; + ConnectionDialog::on_button_cancel_click(); +} + +void PasswordDialog::on_enter_password() +{ + password = entryPW.get_text(); + if (password != "") + on_button_ok_click(); +} + +NewConDialog::NewConDialog(MainWindow* newParent, const Glib::ustring& title) + : ConnectionDialog(newParent, title), + frameIP("Host"), + framePW("Password"), + buttonFromFile("From File") +{ + entryIP.signal_activate().connect(sigc::mem_fun(*this, &NewConDialog::on_enter_IP)); + entryPW.signal_activate().connect(sigc::mem_fun(*this, &NewConDialog::on_enter_password)); + buttonFromFile.signal_clicked().connect(sigc::mem_fun(*this, &NewConDialog::on_button_fromFile_click)); + + frameIP.add(entryIP); + framePW.add(entryPW); + contentBox.add(frameIP); + contentBox.add(framePW); + contentBox.add(buttonFromFile); + show_all_children(); +} + +NewConDialog::~NewConDialog() +{} + +void NewConDialog::on_enter_password() +{ + if (entryIP.get_text() != "") // if the IP/hostname was already supplied, we proceed without putting the focus + // back on the IP field. + // we also proceed if theres no password given, because theres either no password + // needed or the password dialog will take care of that later on + on_button_ok_click(); + else + entryIP.grab_focus(); +} + +void NewConDialog::on_enter_IP() +{ + if (entryIP.get_text() != "") + { + if (entryPW.get_text() == "") // if no password was supplied we put the focus on the password + entryPW.grab_focus(); + else + on_button_ok_click(); + } + else + return; +} + + +void NewConDialog::on_button_ok_click() +{ + connection_IP = entryIP.get_text(); + if (connection_IP != "") // we only proceed if the IP/hostname field isnt empty + { + connection_password = entryPW.get_text(); + QString infoLine; + infoLine = connection_IP; + if (connection_password.length() > 0) // if the password was supplied, we assemble the string + // with the necessary information + { + infoLine.append(" "); + infoLine.append(connection_password); + } + + // VNCConnectInfo* newCon = getConInfo(infoLine); + +// myParent->addConnection(newCon); + + ConnectionDialog::on_button_ok_click(); + } +} + +void NewConDialog::on_button_fromFile_click() +{ +// myParent->readClientsFromFile(); + ConnectionDialog::on_button_ok_click(); +} + + + + + + + + + + + + + + + +MessageDialog::MessageDialog(MainWindow* newParent, const Glib::ustring& title, QString* newMessage) + : ConnectionDialog(newParent, title), + frameMsg("Message") +{ + message = newMessage; + entryMsg.signal_activate().connect(sigc::mem_fun(*this, &MessageDialog::on_enter_message)); + + frameMsg.add(entryMsg); + + contentBox.add(frameMsg); + + show_all_children(); +} + +MessageDialog::~MessageDialog() +{} + +void MessageDialog::on_enter_message() +{ + if (entryMsg.get_text() != "") + { + on_button_ok_click(); + } +} + + +void MessageDialog::on_button_ok_click() +{ + if (entryMsg.get_text().empty()) + return; + + *message = entryMsg.get_text(); + + ConnectionDialog::on_button_ok_click(); +} diff --git a/src/gui/connectionDialog.h b/src/gui/connectionDialog.h new file mode 100644 index 0000000..8f268d4 --- /dev/null +++ b/src/gui/connectionDialog.h @@ -0,0 +1,123 @@ +#ifndef _CONNECTIONDIALOG_H_ +#define _CONNECTIONDIALOG_H_ +#include <src/gui/mainWindow.h> +//#include <src/core/pvsCore.h> +//#include <src/util/pvsUtil.h> + + +class MainWindow; + +/** ConnectionDialog + * Abstract base class for dialogs + */ + +class ConnectionDialog : public Gtk::Window +{ + +public: + ConnectionDialog(MainWindow* newParent, const Glib::ustring& title); + ~ConnectionDialog(); + +protected: + + virtual void on_button_ok_click(); // callback for ok button + virtual void on_button_cancel_click(); // callback for cancel button + + Gtk::VBox contentBox; // box containing the individual content of the dialogs + Gtk::HBox buttonBox; // box containing the shared buttons (ok & cancel) of the dialogs + Gtk::VBox windowBox; // box containing content and button boxes + Gtk::Button buttonOK; // the ok button + Gtk::Button buttonCancel; // the cancel button + MainWindow* myParent; // pointer to the parenting window + +}; + + +/** PasswordDialog + * dialog with the sole purpose to ask for a password (if requested) + */ + + +class PasswordDialog : public ConnectionDialog +{ + +public: + + PasswordDialog(MainWindow* newParent, const Glib::ustring& title, QString* newTargetPW); // the PasswordDialog constructor takes a pointer to a string for the sole + // reason that it is not connected to the connection that asks for a password and therefore cannot tell the user to which + // connection it belongs. So the connection puts the hostname in the string which the pointer is pointing to for the password + // dialog to read out and show to the user. The string is then overwritten with the password the user entered and then used + // inside the connection to feed the password request. + ~PasswordDialog(); + +protected: + + void on_enter_password(); + void on_button_ok_click(); + void on_button_cancel_click(); + + Gtk::Frame frameIP; + Gtk::Entry entryPW; + +private: + QString password, *targetPW; +}; + +/** NewConDialog + * dialog to open up a new connection to a vnc server + * offers the options + * * to enter a password to not come up + * with a password dialog later + * * to read prefab connections from a file + */ + + +class NewConDialog : public ConnectionDialog +{ + +public: + NewConDialog(MainWindow* newParent, const Glib::ustring& title); + ~NewConDialog(); + +protected: + + void on_enter_password(); // callback when enter was hit in the password text field. + void on_enter_IP(); // callback when enter was hit in the IP/Host text field + + void on_button_ok_click(); // ok button callback + void on_button_fromFile_click();// read-from-file button callback + + Gtk::Frame frameIP; // just a frame around the IP text field + Gtk::Frame framePW; // the same for the pw field + Gtk::Button buttonFromFile; // button to read out a file + Gtk::Entry entryIP; // text field for the IP/Hostname + Gtk::Entry entryPW; // text field for the password (optional) + +private: + QString connection_password; + QString connection_IP; +}; + +class MessageDialog : public ConnectionDialog +{ + +public: + MessageDialog(MainWindow* newParent, const Glib::ustring& title, QString* newMessage); + ~MessageDialog(); + +protected: + + void on_enter_message(); // callback when enter was hit in the text field. + + void on_button_ok_click(); // ok button callback + void on_button_fromFile_click();// read-from-file button callback + + Gtk::Frame frameMsg; // just a frame around the text + Gtk::Entry entryMsg; // text field for the message + +private: + QString * message; +}; + + +#endif diff --git a/src/gui/connectionFrame.cpp b/src/gui/connectionFrame.cpp new file mode 100644 index 0000000..e889991 --- /dev/null +++ b/src/gui/connectionFrame.cpp @@ -0,0 +1,557 @@ +/* +# 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 <src/gui/connectionFrame.h> +#include <src/gui/dialog.h> +#include <src/gui/mainWindow.h> +#include <iostream> +extern "C" +{ +#include <rfb/rfbclient.h> +} +#include <src/core/pvsConnectionManager.h> + + +ConnectionFrame::ConnectionFrame(QWidget *parent) : + QGroupBox(parent) +{ + + //defines the ui-stuff + + _gL = new QGridLayout(this); + _gL->setSpacing(6); + _gL->setMargin(1); + + _split = new QSplitter(this); + _split->setOrientation(Qt::Vertical); + + _frame = new Frame("", _split); + _frame->setConFrame(this); + _split->addWidget(_frame); + + _conFrameTaskbar = new QWidget(_split); + _conFrameTaskbar->setMaximumHeight(30); + + _gLayout = new QGridLayout(_conFrameTaskbar); + _gLayout->setMargin(0); + _gLayout->setSpacing(0); + + _hLayoutInCfTaskbar = new QHBoxLayout(); + + _username = new QLabel(_conFrameTaskbar); + _username->setStyleSheet(QString::fromUtf8("background-color: rgb(150, 150, 168);")); + _username->setAlignment(Qt::AlignLeft); + + _hLayoutInCfTaskbar->addWidget(_username); + + _dozentContaimner = new QLabel(_conFrameTaskbar); + _dozentContaimner->setStyleSheet(QString::fromUtf8("background-color: rgb(150, 150, 168);")); + _dozentContaimner->setAlignment(Qt::AlignRight); + _dozentContaimner->setMaximumSize(QSize(20, 20)); + _dozentContaimner->setScaledContents(true); + + _hLayoutInCfTaskbar->addWidget(_dozentContaimner); + + _dozentContaimner->setDisabled(true); + + _status = new QLabel(_conFrameTaskbar); + _status->setStyleSheet(QString::fromUtf8("background-color: rgb(150, 150, 168);")); + _status->setAlignment(Qt::AlignRight); + _status->setMaximumSize(QSize(22, 21)); + + _hLayoutInCfTaskbar->addWidget(_status); + + _gLayout->addLayout(_hLayoutInCfTaskbar, 0, 0, 1, 1); + _split->addWidget(_conFrameTaskbar); + + _gL->addWidget(_split, 0, 0, 1, 1); + + this->setLayout(_gL); + + setInitSize(190,168); + + initFrame(); + + nat_height = 0; + nat_width = 0; + _ratio = 100; + overSized = false; + _fullscreen = false; + _closeup = false; + active = false; + _isOnProjekt = false; + isClientOnline = true; + + //slots and signals + + DelDummy = new QAction(tr("&Remove dummy..."),this); + connect(DelDummy, SIGNAL(triggered()), this, SLOT(delDummy())); + lockClient = new QAction(tr("&Lock Client(s)"),this); + connect(lockClient, SIGNAL(triggered()), this, SLOT(on_lock())); + uLockClient = new QAction(tr("&Unlock Client(s)"),this); + connect(uLockClient, SIGNAL(triggered()), this, SLOT(on_unlock())); + /*invertlockClient = new QAction(tr("&Invertlock Client(s)"),this); + connect(invertlockClient, SIGNAL(triggered()), this, SLOT(on_lock_invert())); + LockAllClient = new QAction(tr("&Lock all Client(s)"),this); + connect(LockAllClient, SIGNAL(triggered()), this, SLOT(on_lock_all())); + uLockAllClient = new QAction(tr("&Unlock all Client(s)"),this); + connect(uLockAllClient, SIGNAL(triggered()), this, SLOT(on_unlock_all()));*/ + msgLockClient = new QAction(tr("&MsgLock Client(s)"),this); + connect(msgLockClient, SIGNAL(triggered()), this, SLOT(on_lock_with_message())); + msgLockAllClient = new QAction(tr("&MsgLock all Client(s)"),this); + connect(msgLockAllClient, SIGNAL(triggered()), this, SLOT(on_lock_all_with_message())); + msgClient = new QAction(tr("&Message Client(s)"),this); + connect(msgClient, SIGNAL(triggered()), this, SLOT(on_message())); + project = new QAction(tr("&Projection"),this); + connect(project, SIGNAL(triggered()), this, SLOT(on_projection())); + uproject = new QAction(tr("&Unprojection"),this); + connect(uproject, SIGNAL(triggered()), this, SLOT(on_unprojection())); + /*rHelp = new QAction(tr("&Remote Help"),this); + connect(rHelp, SIGNAL(triggered()), this, SLOT(on_remoteHelp()));*/ + + //connect(_frame, SIGNAL(clicked()), this, SLOT(on_click())); + + //menu entries + + menu = new QMenu(this); + menu->addAction(DelDummy); + menu->addSeparator(); + menu->addAction(lockClient); + menu->addAction(uLockClient); + /*menu->addAction(invertlockClient); + menu->addAction(LockAllClient); + menu->addAction(uLockAllClient);*/ + menu->addAction(msgLockClient); + menu->addAction(msgLockAllClient); + menu->addAction(msgClient); + menu->addAction(project); + menu->addAction(uproject); + //menu->addAction(rHelp); + + this->show(); +} + +ConnectionFrame::~ConnectionFrame() +{ + +} + +QString ConnectionFrame::getTitle() // get frame title +{ + return title(); +} + +void ConnectionFrame::setTheTitle(QString title) // set frame title +{ + if (title.isNull()) return; + setTitle(title); +} + +QString ConnectionFrame::getTaskbarTitle() // get taskbar title +{ + if (!_username->text().isNull()) + return _username->text(); + else + return _myConnection->getIp(); +} + +void ConnectionFrame::setTaskbarTitle(QString title) // set taskbar title +{ + _username->setText(title); + _frame->ip = title; +} + +void ConnectionFrame::setInitSize(int w, int h) +{ + resize(w, h); + _frame->resize(w, h); + _conFrameTaskbar->resize(w, h); + prev_height = h; + prev_width = w; + init_w = w; + init_h = h; +} + +void ConnectionFrame::Resize(int w, int h) +{ + resize(w, h); + _frame->resize(w, h); +} + +void ConnectionFrame::initFrame() +{ + _clientStatus = QPixmap(":/offline"); + _clientDozent = QPixmap(":/dozent2"); + _dozentContaimner->setPixmap(_clientDozent.scaled(3*_dozentContaimner->size()/4, + Qt::KeepAspectRatio, Qt::SmoothTransformation)); +} + + +void ConnectionFrame::setConnection(PVSClient* newConnection) +{ + if (newConnection) + { + _myConnection = newConnection; + _myConnection->setConnectionFrame(this); + const QString userName = QString( + _myConnection->getUserName().toUtf8().data()); + if (_myConnection->getVNCConnection() && _myConnection->getVNCConnection()->getVNCClientThread()) + { + _myConnection->getVNCConnection()->setFrame(this); + _frame->setVNCThreadConnection(_myConnection->getVNCConnection()->getVNCClientThread()); + setActive(true); + setToolTip(userName); + setTitle(userName); + } + else + { + setToolTip(userName); + setTitle(userName); + } + } + +} + +/* + * We set a new VNCConnection to the pvsmgr with a new quality. + * To do this, that is very easy. At this point we have already a ruuning + * Connection between the server an the client. This connection is controlled in a thread. + * So we disconnect all Qt-Signals on this thread and we terminate the thread. + * After do this we have to set a new thread(VNCClientThread) and connect the signals again. + * + * When you want to read about this, please check the developper's book. + */ +void ConnectionFrame::resetConnectionWithQuality(int quality) +{ + if (getFrame()) + { + _myConnection->getVNCConnection()->reInitClientWithQuality(quality); + getFrame()->stopVNCThreadConnection(); + getFrame()->setVNCThreadConnection(_myConnection->getVNCConnection()->getVNCClientThread()); + getFrame()->update(); + } +} + +void ConnectionFrame::delDummy() +{ + MainWindow::getConnectionWindow()->removeFromList(this); +} + +void ConnectionFrame::on_projection() +{ + MainWindow::getConnectionList()->on_projection(); +} + +void ConnectionFrame::on_unprojection() +{ + MainWindow::getConnectionList()->on_unprojection(); +} + +void ConnectionFrame::on_lock() +{ + if (_myConnection->getVNCConnection()) + MainWindow::getConnectionWindow()->lockStation(_myConnection); +} + +void ConnectionFrame::on_unlock() +{ + if (_myConnection->getVNCConnection()) + MainWindow::getConnectionWindow()->unlockStation(_myConnection); +} + +void ConnectionFrame::on_message() +{ + Dialog msgD; + QString myString = NULL; + int result = msgD.exec(); + + if (result == 1) + { + myString = MainWindow::getWindow()->getMsgDialog(); + if(!myString.isEmpty()) + MainWindow::getConnectionWindow()->messageStations("BROADCAST",myString); + } +} + +void ConnectionFrame::on_lock_with_message() +{ + Dialog msgD; + QString myString = NULL; + int result = msgD.exec(); + + if(result == 1) + { + myString = MainWindow::getWindow()->getMsgDialog(); + if(!myString.isEmpty()) + { + MainWindow::getConnectionWindow()->lockStationsWithMessage(myString); + } + } +} + +void ConnectionFrame::on_lock_all_with_message() +{ + QString myString = NULL; + Dialog msgD; + int result = msgD.exec(); + + if(result == 1) + { + myString = MainWindow::getWindow()->getMsgDialog(); + if(!myString.isEmpty()) + { + MainWindow::getConnectionWindow()->lockAllStationsWithMessage(myString); + } + } +} + +void ConnectionFrame::on_lock_all() +{ + MainWindow::getConnectionWindow()->lockAllStations(); +} + +void ConnectionFrame::on_unlock_all() +{ + MainWindow::getConnectionWindow()->unlockAllStations(); +} + +void ConnectionFrame::on_lock_invert() +{ + //MainWindow::getConnectionWindow()->lockInvertStations(); +} + +void ConnectionFrame::on_remoteHelp() +{ + +} + +void ConnectionFrame::setIgnoreRatio(bool ignore) +{ + ignore_ratio = ignore; +} + +void ConnectionFrame::setFullscreen(bool fs) +{ + _fullscreen = fs; + setIgnoreRatio(!fs); +} + +void ConnectionFrame::setCloseup(bool cu) +{ + _closeup = cu; + setIgnoreRatio(false); +} + +void ConnectionFrame::setInteractive(bool doit) +{ + viewOnly = !doit; +} + +void ConnectionFrame::setActive(bool activate) +{ + active = activate; +} + +void ConnectionFrame::setDummy(bool dummy) +{ + _dummy = dummy; + if (_dummy) + { + _clientStatus = QPixmap(0, 0); //ein leeres Pixmap erstellen + _clientStatus.fill(Qt::white); // benöigt bevor man drin zeichen + _clientStatus = QPixmap(":/offline"); + _status->setMaximumSize(QSize(30, 30)); + _status->setPixmap(_clientStatus.scaled(29,27, + Qt::KeepAspectRatio, Qt::SmoothTransformation)); + //_status->setPixmap(clientStatus.scaled(3*_status->size()/4, + // Qt::KeepAspectRatio, Qt::SmoothTransformation)); + //setConnection(NULL); + } + else + { + _clientStatus = QPixmap(0, 0); //ein leeres Pixmap erstellen + _clientStatus.fill(Qt::white); // benöigt bevor man drin zeichen + _clientStatus = QPixmap(":/online"); + _status->setMaximumSize(QSize(30, 30)); + _status->setPixmap(_clientStatus.scaled(29,27, + Qt::KeepAspectRatio, Qt::SmoothTransformation)); + //_status->setPixmap(clientStatus.scaled(3*_status->size()/4, + // Qt::KeepAspectRatio, Qt::SmoothTransformation)); + } + // } +} + +void ConnectionFrame::setFrameRate(int newRate) +{ + //newRate = 5000; +} + +void ConnectionFrame::mouseReleaseEvent ( QMouseEvent * e ) +{ + if (e->button() == Qt::LeftButton) + { + QPoint relPoint = mapToParent(e->pos()); + QRect r = MainWindow::getConnectionWindow()->frameGeometry(); + /* + * We don't want to move the client in a position where we can't catch it again! + */ + if (relPoint.x() > r.width() || relPoint.y() > r.height() || + relPoint.x() < 0 || relPoint.y() < 0) + move(_previousPoint); + QApplication::setOverrideCursor(QCursor(Qt::OpenHandCursor)); + } +} + +void ConnectionFrame::enterEvent ( QEvent * event ) +{ + update(); + QApplication::setOverrideCursor(QCursor(Qt::OpenHandCursor)); + if (!_dummy) + _frame->setToolButtonListVisible(true); +} + +void ConnectionFrame::leaveEvent ( QEvent * event ) +{ + QApplication::setOverrideCursor(QCursor(Qt::ArrowCursor)); + if (!_dummy) + _frame->setToolButtonListVisible(false); +} + +void ConnectionFrame::mousePressEvent(QMouseEvent *event) +{ + if (event->button() == Qt::RightButton) + { + if (!_dummy) + { + DelDummy->setDisabled(true); + menu->exec(QCursor::pos()); + } + else + { + foreach (QAction* a, menu->actions()) + a->setDisabled(true); + DelDummy->setDisabled(false); + menu->exec(QCursor::pos()); + } + } + else + { + _clickPoint = event->pos(); + _previousPoint = pos(); + QApplication::setOverrideCursor(QCursor(Qt::ClosedHandCursor)); + } + /* + * On click, the window have to be on the top-level. + */ + activateWindow(); + raise(); + update(); +} + +void ConnectionFrame::mouseMoveEvent(QMouseEvent *event) +{ + QApplication::setOverrideCursor(QCursor(Qt::ClosedHandCursor)); + move(mapToParent(event->pos()-_clickPoint)); +} + +void ConnectionFrame::paintCloseUp(int w, int h) +{ + + + if (!_frame->image().isNull()) + { + /*this->setFixedWidth(w); + _conFrameTaskbar->setMaximumWidth(w); + resize(w, h);*/ + resizeComponent(w, h); + setMaximumSize(w,h); + resize(w, h); + } + else + { + std::cout << "pixel is NULL" << std::endl; + } + +} + +void ConnectionFrame::resizeComponent(int w, int h) +{ + int th = (h*_conFrameTaskbar->width())/w; + int uh = (h*_username->width())/w; + _conFrameTaskbar->setMaximumSize(w, th); + _conFrameTaskbar->resize(w, th); + _username->setMaximumSize(w, uh); + _username->resize(w,uh); +} + +void ConnectionFrame::setSource() +{ + _clientStatus = QPixmap(0, 0); //ein leeres Pixmap erstellen + _clientStatus.fill(Qt::white); // benöigt bevor man drin zeichen + _clientStatus = QPixmap(":/source"); + _status->setMaximumSize(QSize(62, 30)); + _status->setPixmap(_clientStatus.scaled(61,29, + Qt::KeepAspectRatio, Qt::SmoothTransformation)); + _isOnProjekt = true; +} + +void ConnectionFrame::setTarget() +{ + _clientStatus = QPixmap(0, 0); //ein leeres Pixmap erstellen + _clientStatus.fill(Qt::white); // benöigt bevor man drin zeichen + _clientStatus = QPixmap(":/target"); + _status->setMaximumSize(QSize(62, 30)); + _status->setPixmap(_clientStatus.scaled(61,29, + Qt::KeepAspectRatio, Qt::SmoothTransformation)); +} + +void ConnectionFrame::setUnproject() +{ + _clientStatus = QPixmap(0, 0); //ein leeres Pixmap erstellen + _clientStatus.fill(Qt::white); // benöigt bevor man drin zeichen + _clientStatus = QPixmap(":/online"); + _status->setMaximumSize(QSize(30, 30)); + _status->setPixmap(_clientStatus.scaled(29,27, + Qt::KeepAspectRatio, Qt::SmoothTransformation)); + _isOnProjekt = false; +} + +void ConnectionFrame::setDozent(bool isDozent) +{ + if (isDozent) + _dozentContaimner->setDisabled(false); + else + _dozentContaimner->setDisabled(true); +} + +void ConnectionFrame::on_click() +{ + //std::cout << "HALLO! WAS?" << std::endl; +} + +const QPixmap* ConnectionFrame::getFramePixmap() +{ + if (_frame == NULL) return NULL; + return _frame->pixmap(); +} + +Frame* ConnectionFrame::getFrame() +{ + if(_myConnection && _myConnection->getVNCConnection()) return _frame; + return NULL; +}; + +//Frame* ConnectionFrame::_frame = NULL; diff --git a/src/gui/connectionFrame.h b/src/gui/connectionFrame.h new file mode 100644 index 0000000..a199102 --- /dev/null +++ b/src/gui/connectionFrame.h @@ -0,0 +1,199 @@ +#ifndef _CONNECTIONFRAME_H_ +#define _CONNECTIONFRAME_H_ +#include <QtGui> +#include <fstream> +#include <iostream> +#include <QImage> +#include <QPixmap> +#include <QLabel> +#include <src/core/pvsClient.h> +#include <src/gui/frame.h> +//#include <src/gui/mainWindow.h> +#include <src/gui/dialog.h> +extern "C" +{ +#include <rfb/rfbclient.h> +} + +#define PROFILE +#include <src/util/timeUtil.h> + +/** + * Container for the drawable area that shows the corresponding servers desktop + * + */ + +class PVSClient; +class VNCConnection; +class ConnectionWindow; +class Frame; +class Dialog; +class MainWindow; + +class ConnectionFrame : public QGroupBox +{ + + Q_OBJECT + +public: + ConnectionFrame(QWidget* parent=0); // on width and height being zero, defaults values are used + virtual ~ConnectionFrame(); + + QString getTitle(); + void setTheTitle(QString title); + QString getTaskbarTitle(); + void setTaskbarTitle(QString title); + void setInitSize(int w, int h); + void Resize(int w, int h); + void initFrame(); + + int getPrevWidth(){return prev_width;}; + void setPrevWidth(int w){prev_width = w;} + int getPrevHeight(){return prev_height;}; + void setPrevHeight(int h){prev_height = h;} + + void setConnection(PVSClient* newConnection); + void resetConnectionWithQuality(int quality); + PVSClient* getConnection() + { + return _myConnection; + } + ; + //bool drawFrame(); // call to ask for a redraw of the frames content + void setIgnoreRatio(bool ignore); // sets wether it should force square on the content or not + void setFullscreen(bool fs); // toggles wether this frame is requested to shown fullscreen or not + bool getFullscreen() + { + return _fullscreen; + } + ; // returns wether the frame is fullscreen (or requested to be) or not + void setCloseup(bool cu); // toggles wether this frame is requested to shown fullscreen or not + bool getCloseup() + { + return _closeup; + } + ; // returns wether the frame is fullscreen (or requested to be) or not + + void setInteractive(bool doit); + float getRatio() + { + return _ratio; + } + ; // returns the native ratio of the source buffer (h/w) + void setRatio(int newRatio) + { + _ratio = newRatio; + } + ; + bool getOversized() + { + return overSized; + } + ; // returns wether the frame is reasonably wider than other frames (e.g. dual screen displays) + void setOversized(bool over) + { + overSized = over; + } + ; + void setActive(bool activate); + bool getActive() + { + return active; + } + ; + void setDummy(bool dummy); + bool isDummy() + { + return _dummy; + } + ; + bool isOnProjekt() + { + return _isOnProjekt; + } + ; + void setFrameRate(int newRate); + bool isClientOnline; + void paintCloseUp(int w, int h); + void resizeComponent(int w, int h); + void setSource(); + void setTarget(); + void setUnproject(); + void setDozent(bool isDozent); + const QPixmap* getFramePixmap(); + Frame* getFrame(); + int init_w, init_h; + +public Q_SLOTS: + virtual void delDummy(); + virtual void on_projection(); + virtual void on_unprojection(); + virtual void on_lock(); + virtual void on_unlock(); + virtual void on_message(); + virtual void on_lock_with_message(); + virtual void on_lock_all_with_message(); + virtual void on_lock_all(); + virtual void on_unlock_all(); + virtual void on_lock_invert(); + virtual void on_remoteHelp(); + virtual void on_click(); + +protected: + //virtual void paintEvent(QPaintEvent *event); + void mouseReleaseEvent ( QMouseEvent * e ); + virtual void enterEvent ( QEvent * event ); + virtual void leaveEvent ( QEvent * event ); + void mousePressEvent(QMouseEvent *event); + void mouseMoveEvent(QMouseEvent *event); + //void mouseReleaseEvent ( QMouseEvent * event ); + +private: + + Frame *_frame; + //clickableLabel *frame; + QSplitter *_split; + QGridLayout* _gL; + QLabel* _username; + QLabel* _status; + QLabel* _dozentContaimner; + QWidget* _conFrameTaskbar; + QGridLayout* _gLayout; + QHBoxLayout* _hLayoutInCfTaskbar; + + PVSClient* _myConnection; + QPixmap _clientPix; + QPixmap _clientStatus; + QPixmap _clientDozent; + int nat_height, nat_width; // native height and width of the source buffer + int cu_height, cu_width; + int prev_height, prev_width; + // uint8_t prev_buttonMask; /* bits 0-7 are buttons 1-8, 0=up, 1=down */ + int _ratio; + bool _dummy; + bool ignore_ratio, overSized, first; + bool _fullscreen, _closeup, _isOnProjekt; + + bool viewOnly, active; + rfbClient* myClient; + + QMenu *menu; + QAction *DelDummy; + QAction *lockClient ; + QAction *uLockClient ; + /*QAction *invertlockClient ; + QAction *LockAllClient ; + QAction *uLockAllClient ;*/ + QAction *msgLockAllClient ; + QAction *msgClient ; + QAction *msgLockClient ; + QAction *project ; + QAction *uproject ; + //QAction *rHelp ; + + + QPoint _clickPoint; + QPoint _previousPoint; +}; + +#endif diff --git a/src/gui/connectionList.cpp b/src/gui/connectionList.cpp new file mode 100644 index 0000000..2f9829e --- /dev/null +++ b/src/gui/connectionList.cpp @@ -0,0 +1,603 @@ +/* +# 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/connectionList.cpp +# ----------------------------------------------------------------------------- +*/ + +#include <QtGui> +#include <iostream> +#include "connectionList.h" +#include <src/gui/dialog.h> +//#include <src/gui/projectionDialog.h> +//#include "mainWindow.h" +#define COL_FULLNAME 0 +#define COL_IP 1 +#define COL_USERNAME 2 + +ConnectionList::ConnectionList(QWidget *parent): + QTableView(parent) +{ + /*Das Modelfestlegen, wo die Clientname angezeigt werden.*/ + model = new QStandardItemModel(0,3,this); //Leere Tabelle mit einer Spalte erstellen + model->setHeaderData(0, Qt::Horizontal, tr("Name")); //Spalte name definieren + model->setHeaderData(1, Qt::Horizontal, tr("IP")); //IP-column will be hide + model->setHeaderData(2, Qt::Horizontal, tr("Username")); + setModel(model); + this->setColumnHidden(1, true); + this->setColumnHidden(2, true); + + QItemSelectionModel *selectionModel = new QItemSelectionModel(model); + setSelectionModel(selectionModel); + QHeaderView *headerView = horizontalHeader(); + headerView->setStretchLastSection(true); + /*Das popup einstellen*/ + preparePopup(); + + _useUserName = true; + + setEditTriggers(QAbstractItemView::NoEditTriggers); //Die Einträge in der Tabelle werden nicht editierbar. + setSelectionMode(QAbstractItemView::ExtendedSelection); //Damit mehere Einträge selektierbar werden. + + resizeColumnToContents(0); + clientindex = 0; + isOnProjection = false; //No projection on progress now! + projSourceName = ""; //The projection source name is empty. +} + +ConnectionList::~ConnectionList() +{ +} + +void ConnectionList::preparePopup() +{ + + /*Aktion definieren*/ + /* a1 = new QAction(tr("&Remove Clients (debug)"),model); + connect(a1, SIGNAL(triggered()), this, SLOT(on_removeClient())); + a2 = new QAction(tr("&Request VNC-Window"),model); + connect(a2, SIGNAL(triggered()), this, SLOT(on_vnc_add())); + a3 = new QAction(tr("&Remove VNC-Window"),model); + connect(a3, SIGNAL(triggered()), this, SLOT(on_vnc_remove()));*/ + _lockClient = new QAction(tr("&Lock Client(s)"),model); + connect(_lockClient, SIGNAL(triggered()), this, SLOT(on_lock())); + _uLockClient = new QAction(tr("&Unlock Client(s)"),model); + connect(_uLockClient, SIGNAL(triggered()), this, SLOT(on_unlock())); + /* invertlockClient = new QAction(tr("&Invertlock Client(s)"),model); + connect(invertlockClient, SIGNAL(triggered()), this, SLOT(on_lock_invert())); + LockAllClient = new QAction(tr("&Lock all Client(s)"),model); + connect(LockAllClient, SIGNAL(triggered()), this, SLOT(on_lock_all())); + uLockAllClient = new QAction(tr("&Unlock all Client(s)"),model); + connect(uLockAllClient, SIGNAL(triggered()), this, SLOT(on_unlock_all()));*/ + _msgLockClient = new QAction(tr("&MsgLock Client(s)"),model); + connect(_msgLockClient, SIGNAL(triggered()), this, SLOT(on_lock_with_message())); + _msgLockAllClient = new QAction(tr("&MsgLock all Client(s)"),model); + connect(_msgLockAllClient, SIGNAL(triggered()), this, SLOT(on_lock_all_with_message())); + _msgClient = new QAction(tr("&Message Client(s)"),model); + connect(_msgClient, SIGNAL(triggered()), this, SLOT(on_message())); + //msgClient = createToolbarButton(tr("&Message Client(s)"), SLOT(on_message())); + _project = new QAction(tr("&Projection"),model); + connect(_project, SIGNAL(triggered()), this, SLOT(on_projection())); + _uproject = new QAction(tr("&Unprojection"),model); + connect(_uproject, SIGNAL(triggered()), this, SLOT(on_unprojection())); + /* rHelp = new QAction(tr("&Remote Help"),model); + connect(rHelp, SIGNAL(triggered()), this, SLOT(on_remoteHelp()));*/ + + /*Menü definieren*/ + _popupMenu = new QMenu(this); + + /*Aktionen in Menü aufnehmen*/ + /* menu->addAction(a1); + menu->addAction(a2); + menu->addAction(a3);*/ + _popupMenu->addAction(_lockClient); + _popupMenu->addAction(_uLockClient); + /* menu->addAction(invertlockClient); + menu->addAction(LockAllClient); + menu->addAction(uLockAllClient);*/ + _popupMenu->addAction(_msgLockClient); + _popupMenu->addAction(_msgLockAllClient); + _popupMenu->addAction(_msgClient); + _popupMenu->addAction(_project); + _popupMenu->addAction(_uproject); + // menu->addAction(rHelp); + +} + +QAction* ConnectionList::createToolbarButton(const QString &name, const char *slot) +{ + QAction *action = new QAction(name, model); + connect(action, SIGNAL(triggered()), this, slot); + _popupMenu->addAction(action); + + return action; +} + +void ConnectionList::mouseReleaseEvent(QMouseEvent * e ) +{ + // setCurrentIndex ( currentIndex () ); + if (e->button() == Qt::RightButton) + { + if (model->rowCount(QModelIndex()) > 0) + foreach (QAction *a, _popupMenu->actions()) + { + a->setDisabled(false); + } + else + foreach (QAction *a, _popupMenu->actions()) + { + a->setDisabled(true); + } + _popupMenu->exec(QCursor::pos()); + } +} + +void ConnectionList::onAddClient(PVSClient* newConnection) +{ + if (newConnection) + { + //clientindex = model->rowCount(QModelIndex())+1; + model->insertRow(clientindex, QModelIndex()); + //QString uname = newConnection->getPVSClientConnection()->getNameUser(); + QString uname = newConnection->getLoginName(); + if (_useUserName) + { + QString username = newConnection->getUserName(); + QString ip = newConnection->getIp(); + model->setData(model->index(clientindex, COL_FULLNAME, QModelIndex()),username); + model->setData(model->index(clientindex, COL_IP, QModelIndex()),ip); + model->setData(model->index(clientindex, COL_USERNAME, QModelIndex()),uname); + newConnection->getConnectionFrame()->setTaskbarTitle(ip); + addClientToList(username); + } + else + { + QString desktopname = QString(newConnection->getDesktopName().toUtf8().data()); + QString ip = newConnection->getIp(); + model->setData(model->index(clientindex, COL_FULLNAME, QModelIndex()),desktopname); + model->setData(model->index(clientindex, COL_IP, QModelIndex()),ip); + model->setData(model->index(clientindex, COL_USERNAME, QModelIndex()),uname); + } + setCurrentIndex(model->index(clientindex, 0)); + on_vnc_add(); // triggert the automatic vnc request! + setCurrentIndex(model->index(-1, 0)); + newConnection->setClientindex(clientindex); + clientindex++; + } +} + +void ConnectionList::onRemoveClient(PVSClient* newCon) +{ + if (newCon && model->rowCount(QModelIndex()) > 0) + { + QString host = newCon->getIp(); + for (int i=0; i<model->rowCount(QModelIndex()); i++) + { + if (model->index(i, 1, QModelIndex()).data(Qt::DisplayRole).toString() + .compare(host) == 0) + { + removeClientToList(model->index(i, 1, QModelIndex()).data(Qt::DisplayRole).toString()); + model->removeRow(i, QModelIndex()); + clientindex--; + break; + } + } + /* + * We have to check, if this disconnected client is involved in a projection process. + * If true, we have to unproject it, this will unproject the others clients that becomme + * the projection. + */ + if (targetList.contains(host) || sourceList.contains(host)) + unproject(host); + + + } +} + +void ConnectionList::addClientToList(QString clientname) +{ + if (!_clientNames.contains(clientname)) + _clientNames.append(clientname); +} + +void ConnectionList::removeClientToList(QString clientname) +{ + if (_clientNames.contains(clientname)) + { + _clientNames.removeOne(clientname); + } +} + +void ConnectionList::onUpdateClient(PVSClient* newConnection) +{ + + if (model->rowCount(QModelIndex()) > 0) + { + for (int i=0; i<model->rowCount(QModelIndex()); i++) + { + if (model->index(i, 1, QModelIndex()).data(Qt::DisplayRole).toString() + .compare(newConnection->getIp()) == 0) + { + if (_useUserName) + { + newConnection->getConnectionFrame()->setTheTitle(newConnection->getUserName()); + model->setData(model->index(i, COL_FULLNAME, QModelIndex()),newConnection->getUserName()); + } + else + { + newConnection->getConnectionFrame()->setTheTitle(newConnection->getDesktopName()); + model->setData(model->index(i, COL_FULLNAME, QModelIndex()),newConnection->getDesktopName()); + } + break; + } + } + } + else + { + // something went awfully wrong! + } +} + +bool ConnectionList::useUserName() +{ + return _useUserName; +} + +bool ConnectionList::useUserName(bool use) +{ + + if (use != _useUserName) + { + _useUserName = use; + } + return useUserName(); +} + +void ConnectionList::on_vnc_add() +{ + MainWindow::getConnectionWindow()->addVNC(); +} + +void ConnectionList::on_vnc_remove() +{ + MainWindow::getConnectionWindow()->removeVNC(); +} + +void ConnectionList::unproject(QString source) +{ + if (sourceList.contains(source)) + { + QList<QString> target; + if (sourceMap.contains(source)) + { + QString item; + foreach (item, sourceMap.value(source)) + { + MainWindow::getConnectionWindow()->unprojectStations(item); //Nur target must be unproject + targetList.removeOne(item); + } + sourceMap.take(source); + } + MainWindow::getConnectionWindow()->unprojectStations(source); //the source schould be too unprojected. + sourceList.removeOne(source); + } + else + { + MainWindow::getConnectionWindow()->unprojectStations(source); //unproject a target + targetList.removeOne(source); + } + /*if (targetList.size() == 1) + targetList.clear();*/ +} + +void ConnectionList::on_projection() +{ + if(model->rowCount(QModelIndex())>1) + { + std::list<QString>* cuList = getSelectedClients(); + + if (targetList.size() == (model->rowCount(QModelIndex())-1)) + { + QString message = QString(tr("No Target is available for a projection!\nPerform an unprojection to get a target.")); + QMessageBox::information(this, "PVS", message); + } + else if(cuList->size() == 1) + { + QString source = cuList->front(); + if (targetList.contains(source)) + { + QString message = QString(tr("This source is already in a projection process involved.\n You can perform a unprojection on it to get it free.")); + QMessageBox::information(this, "PVS", message); + } + else + { + ProjectionDialog projDialog; + int result = projDialog.exec(); + + if(result == 1) + { + if(projectList.size()>0) + { + QList<QString> list; + QString item; + foreach(item, projectList) + { + list.append(item); + } + sourceMap.insert(projSourceName, list); + if (!sourceList.contains(source)) + sourceList.append(source); + MainWindow::getConnectionWindow()->projectStations(projSourceName); + } + else + ConsoleLog writeError( "Strange...the selected target aren't be transmitted to the MainWindow."); + } + else + ; // :( + } + } + else if(cuList->size() > 1) + { + QString message = QString(tr("To perform a projection you have to select only one source in a list with more than one index!")); + QMessageBox::information(this, "PVS", message); + } + } + else + { + QString message = QString(tr("To perform a projection you have to select only one source in a list with more than one index!")); + QMessageBox::information(this, "PVS", message); + } +} + +void ConnectionList::on_unprojection() +{ + if(model->rowCount(QModelIndex())>1) + { + std::list<QString>* cuList = getSelectedClients(); + if(cuList->size() == 1) + { + QString source = cuList->front(); + unproject(source); + } + else + { + QString message = QString(tr("An unprojection is only possible on a selected source that is involved in a projection process, in a list with more than one index!")); + QMessageBox::information(this, "PVS", message); + } + } + else + { + QString message = QString(tr("An unprojection is only possible on a selected source that is involved in a projection process, in a list with more than one index!")); + QMessageBox::information(this, "PVS", message); + } +} + +void ConnectionList::on_remoteHelp() +{ + if(model->rowCount(QModelIndex())>1) + { + std::list<QString>* cuList = getSelectedClients(); + + if (targetList.size() == (model->rowCount(QModelIndex())-1)) + { + QString message = QString(tr("No Target is available for remote Help!\nPerform an unprojection or remove remote help to get a target.")); + QMessageBox::information(this, "PVS", message); + } + else if(cuList->size() == 1) + { + QString source = cuList->front(); + if (targetList.contains(source)) + { + QString message = QString(tr("This source is already in a projection or remote Help process involved.\n You can perform a unprojection or remove remote Help on it to get it free.")); + QMessageBox::information(this, "PVS", message); + } + else + { + ProjectionDialog projDialog; + int result = projDialog.exec(); + + if(result == 1) + { + if(projectList.size() > 0 && projectList.size() < 2) + { + QList<QString> list; + QString item; + foreach(item, projectList) + { + list.append(item); + } + sourceMap.insert(projSourceName, list); + MainWindow::getConnectionWindow()->remoteHelp(projSourceName); + } + else + ConsoleLog writeError( "Strange...the selected targets aren't be transmitted to the MainWindow."); + } + else + ; // :( + } + } + } + else + { + QString message = QString(tr("To perform a projection you have to select only one source in a list with more than one index!")); + QMessageBox::information(this, "PVS", message); + } +} + +void ConnectionList::on_lock() +{ + MainWindow::getConnectionWindow()->lockStations(); +} + +void ConnectionList::on_unlock() +{ + MainWindow::getConnectionWindow()->unlockStations(); +} + +void ConnectionList::on_message() +{ + Dialog msgD; + QString myString = NULL; + int result = msgD.exec(); + + if (result == 1) + { + myString = MainWindow::getWindow()->getMsgDialog(); + if(!myString.isEmpty()) + MainWindow::getConnectionWindow()->messageStations("BROADCAST",myString); + } + +} + +void ConnectionList::on_lock_with_message() +{ + Dialog msgD; + QString myString = NULL; + int result = msgD.exec(); + + if(result == 1) + { + myString = MainWindow::getWindow()->getMsgDialog(); + if(!myString.isEmpty()) + { + MainWindow::getConnectionWindow()->lockStationsWithMessage(myString); + } + } +} + +void ConnectionList::on_lock_all_with_message() +{ + QString myString = NULL; + Dialog msgD; + int result = msgD.exec(); + + if(result == 1) + { + myString = MainWindow::getWindow()->getMsgDialog(); + if(!myString.isEmpty()) + { + MainWindow::getConnectionWindow()->lockAllStationsWithMessage(myString); + } + } +} + + +void ConnectionList::on_lock_all() +{ + MainWindow::getConnectionWindow()->lockAllStations(); +} +void ConnectionList::on_unlock_all() +{ + MainWindow::getConnectionWindow()->unlockAllStations(); +} + +void ConnectionList::on_unproject_all() +{ + MainWindow::getConnectionWindow()->unprojectAllStations(); +} + + +void ConnectionList::on_lock_invert() +{ + MainWindow::getConnectionWindow()->lockInvertStations(); +} + + +void ConnectionList::on_removeClient() +{ + QTableView *temp = static_cast<QTableView*>(this); + QItemSelectionModel *selectionModel = temp->selectionModel(); + + QModelIndexList indexes = selectionModel->selectedRows(); + removeClient(indexes); +} + +void ConnectionList::removeClient(QModelIndexList indexes) +{ + + QModelIndex index; + + foreach(index, indexes) + { + int row = currentIndex().row(); + QString current = model->index(row, 0).data(Qt::DisplayRole).toString(); + removeClientToList(current); + model->removeRow(row, QModelIndex()); + } +} + +std::list<QString>* ConnectionList::getSelectedClients(bool isClickOnWindow) +{ + + std::list<QString>* currentList = new std::list<QString>; + + + QTableView *temp = static_cast<QTableView*>(this); + QItemSelectionModel *selectionModel = temp->selectionModel(); + QModelIndexList indexes = selectionModel->selectedIndexes(); + QModelIndex index; + if (indexes.size() > 0) + { + foreach (index, indexes) + { + QString current = model->index(index.row(), 1).data(Qt::DisplayRole).toString(); + currentList->push_back(current); + } + } + + return currentList; +} + +void ConnectionList::setProjectProporties(QString source) +{ + projSourceName = source; // The source for this projection + sourceList.append(source); // The list for all source in pvsmgr +} + +QList<QString> ConnectionList::getTargetToDisplay(QString source) +{ + displayList.clear(); + projectList.clear(); + + for (int i=0; i<model->rowCount(QModelIndex()); i++) + { + QString item = model->index(i, 1, QModelIndex()).data(Qt::DisplayRole).toString(); + if (item.compare(source) != 0 && !targetList.contains(item) && !sourceList.contains(item)) + { + displayList.append(item); + } + } + + return displayList; + +} + +void ConnectionList::addTargetToProjectList(QString name) +{ + if (!targetList.contains(name)) + { + projectList.append(name); + targetList .append(name); + } +} + +QList<QString> ConnectionList::getTargetForTheProject(QString source) +{ + QList<QString> target; + if(sourceMap.contains(source)){ + target = sourceMap.value(source); + } + return target; +} + + + +bool ConnectionList::isOnProjection = false; diff --git a/src/gui/connectionList.h b/src/gui/connectionList.h new file mode 100644 index 0000000..50d8924 --- /dev/null +++ b/src/gui/connectionList.h @@ -0,0 +1,134 @@ +#ifndef _CONNECTIONLIST_H_ +#define _CONNECTIONLIST_H_ + +#include <QtGui> +#include <src/core/pvsClient.h> +#include <QTableView> +#include <QObject> +#include <QMap> +#include <QItemSelection> +#include <src/gui/mainWindow.h> +#include <src/gui/dialog.h> +#include <src/gui/projectionDialog.h> + +class PVSClient; + +//class QAbstractItemView; + + +/** + * The Sidebar showing the connected servers + * also used to determine to which connection + * contextual actions should be applied + */ + +class QVBoxLayout; +class QSortFilterProxyModel; +class QAbstractItemModel; +class QAbstractItemView; +class QItemSelectionModel; +class MainWindow; +class Dialog; +class ProjectionDialog; +//class ConnectionList; + +class ConnectionList: public QTableView +{ + Q_OBJECT + +public: + ConnectionList(QWidget *parent=0); + ~ ConnectionList(); + + void onAddClient(PVSClient* newConnection); // called if a new connection is added + void onUpdateClient(PVSClient* newConnection); // update the username*/ + void addClientToList(QString clientname); + void onRemoveClient(PVSClient* newCon); + void removeClientToList(QString clientname); + QList<QString> getClientist() + { + return _clientNames; + }; + // void updateAllClients(); + bool useUserName(); + bool useUserName(bool use); + QList<QString> projectList; + QList<QString> targetList; + QList<QString> displayList; + QList<QString> sourceList; + QMap<QString, QList<QString> > sourceMap; + QString projSourceName; + std::list<QString>* getSelectedClients(bool isClickOnWindow=false); // returns the currently selected clients + //void setTargetToDisplay(QString source); // return the list for the projection + void setProjectProporties(QString source); + QList<QString> getTargetToDisplay(QString source); + void addTargetToProjectList(QString name); + QList<QString> getTargetForTheProject(QString source); + QList<QString>getTargetToProject() + { + return projectList; + } + // void removeFromList(PVSConnection* newConnection); // called if a connection is removed + // void setMultipleSelection(bool on); + + QAbstractItemModel *model; + +private: + QItemSelectionModel *_selectionModel; + QList<QString> _clientNames; + + int clientindex; //Index of clientname in the list. + + static bool isOnProjection; + + QMenu *_popupMenu; // in der PopupMenu + /*Die Aktionen in der PopupMenu*/ + /* QAction *a1 ; + QAction *a2 ; + QAction *a3 ;*/ + QAction *_lockClient ; + QAction *_uLockClient ; + /*QAction *invertlockClient ; + QAction *LockAllClient ; + QAction *uLockAllClient ;*/ + QAction *_msgLockClient ; + QAction *_msgLockAllClient ; + QAction *_msgClient ; + QAction *_project ; + QAction *_uproject ; + // QAction *rHelp ; + + void preparePopup(); + void unproject(QString source); + QAction* createToolbarButton(const QString &name, const char *slot); + +public slots: + //Signal handlers: + + virtual void on_projection(); + virtual void on_unprojection(); + virtual void on_lock(); + virtual void on_unlock(); + virtual void on_message(); + virtual void on_lock_with_message(); + virtual void on_lock_all_with_message(); + virtual void on_lock_all(); + virtual void on_unlock_all(); + virtual void on_unproject_all(); + virtual void on_lock_invert(); + virtual void on_remoteHelp(); + void on_vnc_add(); + void on_vnc_remove(); + void on_removeClient(); + void removeClient(QModelIndexList indexes); + /*virtual void on_menu_file_remove_connection();*/ + +signals: + void selectionChanged (const QItemSelection &selected); + +protected: + bool _useUserName; + virtual void mouseReleaseEvent (QMouseEvent * e ); +}; + +#endif diff --git a/src/gui/connectionWindow.cpp b/src/gui/connectionWindow.cpp new file mode 100644 index 0000000..cf51051 --- /dev/null +++ b/src/gui/connectionWindow.cpp @@ -0,0 +1,763 @@ +/* + # 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/connectionWindow.cpp + # ----------------------------------------------------------------------------- + */ + +#include "connectionWindow.h" +#include <src/core/pvsConnectionManager.h> +#include <src/gui/mainWindow.h> + +ConnectionWindow::ConnectionWindow(QWidget *parent) : + QWidget(parent) { + + //initialize the position for the frame in the clientView + posX = 4; + posY = 4; + + _closeupFrame = NULL; + hasDozent = false; // at the begin we don't have a dozent machine + + QPalette newPalette = palette(); + newPalette.setColor(QPalette::Window, Qt::white); + setPalette(newPalette); + + newDummy = new QAction(tr("&Add a dummy..."), this); // set a dummy + connect(newDummy, SIGNAL(triggered()), this, SLOT(addDummy())); + + menu = new QMenu(this); + menu->addAction(newDummy); + + setAcceptDrops(true); //drag&drop should be enabled +} + +ConnectionWindow::~ConnectionWindow() { + // +} + +void ConnectionWindow::addFrame(ConnectionFrame *cF) { + bool found = false; + foreach (ConnectionFrame* cFr, AllFrameOnWindow) + { + if (QString::compare(cF->getTaskbarTitle(), cFr->getTaskbarTitle(), Qt::CaseInsensitive) == 0) + { + QPoint cuP = currentPosition(cFr); + cF->move(cuP); + AllFrameOnWindow.append(cF); + AllFrameOnWindow.removeOne(cFr); //we don't need this dummy any more + cFr->deleteLater(); + found = true; + return; + } + } + + /* If the Frame don't belong to the profile + * we have to move it at the default position for now. + * The user can move this later to his favorite position. + */ + if (!found) + { + foreach (clientLocation cur, ClientLocationList) + { + if (QString::compare(cF->getTaskbarTitle(), cur.first, Qt::CaseInsensitive) == 0) + { + cF->move(cur.second); + found = true; + return; + } + } + } + + if (!found) + cF->move(10, 10); +} + +void ConnectionWindow::addFrameBySettings(QString client, QPoint pos) { + clientLocation cur(client, pos); + ClientLocationList.append(cur); +} + +void ConnectionWindow::showFrameFromSettings() { + foreach (clientLocation cur, ClientLocationList) + { + ConnectionFrame* dummy = new ConnectionFrame( + MainWindow::getConnectionWindow()); + AllFrameOnWindow.append(dummy); + dummy->setTheTitle("[No name]"); + dummy->setTaskbarTitle(cur.first); + dummy->setDummy(true); + dummy->move(cur.second); + } +} + +void ConnectionWindow::addDummy() { //function to add a dummy + ConnectionFrame* dummy = new ConnectionFrame( + MainWindow::getConnectionWindow()); + dummy->setTheTitle("[No name]"); + dummy->setTaskbarTitle("[0.0.0.0]"); + QPoint p = QPoint(10, 10);//the default move position, when created a dummy screen + AllFrameOnWindow.append(dummy); + clientLocation cur("[No name]", p); + ClientLocationList.append(cur); + dummy->setDummy(true); + dummy->move(p); + dummy->setStyleSheet(QString::fromUtf8( + "background-color: rgb(150, 150, 168);")); +} + +void ConnectionWindow::mousePressEvent(QMouseEvent *event) { //catch the mouse press event + if (event->button() == Qt::RightButton) + menu->exec(QCursor::pos()); +} + +QPoint ConnectionWindow::currentPosition(ConnectionFrame* cF) { + QPoint pos = QPoint(10, 10); + clientLocation cur; + foreach (cur, ClientLocationList) + { + if (QString::compare(cF->getTaskbarTitle(), cur.first, Qt::CaseInsensitive) == 0) + return cur.second; + } + return pos; +} + +int ConnectionWindow::itemAt(ConnectionFrame* cf) +{ + for (int i = AllFrameOnWindow.size() - 1; i >= 0; --i) + { + ConnectionFrame* item = AllFrameOnWindow.at(i); + if (cf->pos().x() == item->pos().x() && cf->pos().y() == item->pos().y()) + return i; + } + return -1; +} + +void ConnectionWindow::removeFromList(ConnectionFrame* cF) { + //dummyList.removeOne(cF); + if(AllFrameOnWindow.contains(cF)) + AllFrameOnWindow.removeOne(cF); + cF->deleteLater(); +} + +void ConnectionWindow::onChangeConnections() { + + //clear the view + if (!frameList.empty()) { + ConnectionFrame* tmpIt; + foreach (tmpIt, frameList) + { + if (tmpIt != currentSingleFrame) + tmpIt->setActive(false); + tmpIt->hide(); + } + } + +} + +bool ConnectionWindow::projectStations(QString sname) { + QString password, hostname; + int port, quality; + ConsoleLog writeLine(QString("Projecting from: ").append(sname)); + //TODO add method parameter for this + quality = 0; + + QList<QString> projectList = + MainWindow::getConnectionList()->getTargetForTheProject(sname); + + if (!projectList.isEmpty()) { + PVSClient* tmpSrcConnection = + PVSConnectionManager::getManager()->getClientFromIp(sname); + if (tmpSrcConnection) { + if (!tmpSrcConnection->getVNCAllowed()) { + ConsoleLog writeError(QString("VNC is not allowed on Projection Source: ").append(sname)); + ConsoleLog writeError(QString("Trying to start VNC-Server on Client: ").append(sname)); + tmpSrcConnection->setProject(true); + return false; + } + password = tmpSrcConnection->getPassword(); + port = tmpSrcConnection->getPort(); + hostname = sname; + tmpSrcConnection->getConnectionFrame()->setSource(); + ConsoleLog writeError (QString("port: ").append(int2String(port))); + ConsoleLog writeError (QString("passwort: ").append(password)); + ConsoleLog writeError (QString("pr-sourcename: ").append(sname)); + + } + else + { + return false; + } + + ConsoleLog writeError (QString("port as int: ").append(port)); + ConsoleLog writeError (QString("port as String: ").append(int2String(port))); + + QString item; + foreach (item, projectList) + { + PVSClient* tmpConnection = PVSConnectionManager::getManager()->getClientFromIp(item); + if (tmpConnection) + { + ConsoleLog writeError (QString("sending vnc data to: ").append(tmpConnection->getIp())); + tmpConnection->sendMessage(PVSCOMMAND,"PROJECT", hostname + " " + int2String(port) + " " + password + " " + int2String(quality)); + tmpConnection->getConnectionFrame()->setTarget(); + } + else + { + // scream in agony + } + } + } + return true; +} + +bool ConnectionWindow::remoteHelp(QString sname) { + + //TODO Finish this... + QString password, hostname; + int port; + + PVSClient* tmpSrcConnection = + PVSConnectionManager::getManager()->getClientFromIp(sname); + QList<QString> projectList = + MainWindow::getConnectionList()->getTargetForTheProject(sname); + if (tmpSrcConnection) { + if (!tmpSrcConnection->getVNCAllowed()) { + tmpSrcConnection->requestVNCConnect(); + tmpSrcConnection->setProject(true); + return false; + } + password = tmpSrcConnection->getRWPassword(); + port = tmpSrcConnection->getPort(); + hostname = sname; + tmpSrcConnection->getConnectionFrame()->setSource(); + } else { + return false; + } + + QString item; + foreach (item, projectList) + { + PVSClient + * tmpConnection = + PVSConnectionManager::getManager()->getClientFromIp(item); + if (tmpConnection) { + ConsoleLog writeError(QString("sending vnc data to: ").append( + tmpConnection->getIp())); + tmpConnection->sendMessage(PVSCOMMAND, "PROJECT", hostname + + " " + int2String(port) + " " + password); + tmpConnection->getConnectionFrame()->setTarget(); + } else { + // scream in agony + } + } + return true; + +} + + + +bool ConnectionWindow::lockStations() { + if (std::list<QString>* lockList = MainWindow::getConnectionList()->getSelectedClients()) { + if (!lockList->empty()) { + for (std::list<QString>::iterator tmpIt = lockList->begin(); tmpIt + != lockList->end(); tmpIt++) { + PVSClient + * tmpConnection = + PVSConnectionManager::getManager()->getClientFromIp( + (*tmpIt).toUtf8().data()); + if (tmpConnection->getConnectionFrame()->getFrame()) + { + // we don't want to lock the dozent machine + if (tmpConnection && !tmpConnection->getConnectionFrame()->getFrame()->isDozent() + && !tmpConnection->getConnectionFrame()->isOnProjekt()) + lockStation(tmpConnection); + else { + // scream in agony + } + } + } + } + delete lockList; + } + return true; +} + +void ConnectionWindow::lockStation(PVSClient* pvsCon) { + if (pvsCon->getVNCConnection()) + { + pvsCon->getConnectionFrame()->getFrame()->setLockStatus(true); + // we call the update to force Qt to paint the lockicon on the frame + pvsCon->getConnectionFrame()->getFrame()->update(); + pvsCon->sendMessage(PVSCOMMAND, "LOCKSTATION", ""); + } +} + +bool ConnectionWindow::unlockStations() { + if (std::list<QString>* unlockList = MainWindow::getConnectionList()->getSelectedClients()) { + if (!unlockList->empty()) { + for (std::list<QString>::iterator tmpIt = unlockList->begin(); tmpIt + != unlockList->end(); tmpIt++) { + PVSClient + * tmpConnection = + PVSConnectionManager::getManager()->getClientFromIp( + (*tmpIt).toUtf8().data()); + if (tmpConnection && tmpConnection->getConnectionFrame()->getFrame() && + tmpConnection->getVNCConnection()) { + tmpConnection->getConnectionFrame()->getFrame()->setLockStatus(false); + tmpConnection->getConnectionFrame()->getFrame()->update(); // we call the update to force Qt to paint the lock on the frame + tmpConnection->sendMessage(PVSCOMMAND, "UNLOCKSTATION", ""); + } else { + // scream in agony + } + } + } + delete unlockList; + } + return true; +} + +void ConnectionWindow::unlockStation(PVSClient* pvsCon) { + if (pvsCon->getVNCConnection()) + { + pvsCon->getConnectionFrame()->getFrame()->setLockStatus(false); + // we call the update to force Qt to paint the lockicon on the frame + pvsCon->getConnectionFrame()->getFrame()->update(); + pvsCon->sendMessage(PVSCOMMAND, "UNLOCKSTATION", ""); + } +} + +bool ConnectionWindow::lockAllStations() +{ + if (!hasDozent) + { + QString message = QString(tr("You have to set a Superclient-machine before performing this action.")); + QMessageBox::information(this, "PVS", message); + return false; + } + std::list<PVSClient*> listAll = + PVSConnectionManager::getManager()->getConnections(); + for (std::list<PVSClient*>::iterator it = listAll.begin(); it + != listAll.end(); it++) + { + if (*it == NULL || (*it)->getConnectionFrame() == NULL) continue; + // we don't want to lock the superclient machine + if ((*it)->getConnectionFrame()->getFrame() && + !(*it)->getConnectionFrame()->getFrame()->isDozent() && + (*it)->getVNCConnection()) + (*it)->sendMessage(PVSCOMMAND, "LOCKSTATION", ""); + else if (!(*it)->getConnectionFrame()->getFrame()) + ConsoleLog writeError(QString("The Frame connection from client: "). + append((*it)->getConnectionFrame()->getTaskbarTitle()). + append(QString(" is corrupted. Reconned the client it again."))); + } + return true; +} + +bool ConnectionWindow::unlockAllStations() { + std::list<PVSClient*> listAll = + PVSConnectionManager::getManager()->getConnections(); + for (std::list<PVSClient*>::iterator it = listAll.begin(); it + != listAll.end(); it++) + { + if ((*it)->getVNCConnection()) + { + (*it)->getConnectionFrame()->getFrame()->setLockStatus(false); + (*it)->getConnectionFrame()->getFrame()->update(); // we call the update to force Qt to repaint the frame + (*it)->sendMessage(PVSCOMMAND, "UNLOCKSTATION", ""); + } + // otherwise this will get scattered all over the place + } + return true; +} + +bool ConnectionWindow::unprojectStations(QString sname) { + PVSClient* tmpConnection = + PVSConnectionManager::getManager()->getClientFromIp(sname); + if (tmpConnection && tmpConnection->getVNCConnection()) { + tmpConnection->sendMessage(PVSCOMMAND, "UNPROJECT", ""); + tmpConnection->getConnectionFrame()->setUnproject(); + } else { + // scream in agony + } + + return true; +} + +bool ConnectionWindow::unprojectAllStations() { + std::list<PVSClient*> listAll = + PVSConnectionManager::getManager()->getConnections(); + for (std::list<PVSClient*>::iterator it = listAll.begin(); it + != listAll.end(); it++) + { + if ((*it)->getVNCConnection()) + { + (*it)->sendMessage(PVSCOMMAND, "UNPROJECT", ""); + (*it)->getConnectionFrame()->setUnproject(); + } + } + return true; +} + +bool ConnectionWindow::lockInvertStations() { + // ok, this method is highly imperformant i guess + // we're going thru all existing connections, and if they dont equal one of the selected (another loop) + // we lock them... + if (std::list<QString>* lockList = MainWindow::getConnectionList()->getSelectedClients()) { + std::list<PVSClient*> listAll = + PVSConnectionManager::getManager()->getConnections(); + bool skip = false; + for (std::list<PVSClient*>::iterator it = listAll.begin(); it + != listAll.end(); it++) { + if (!lockList->empty()) { + for (std::list<QString>::iterator tmpIt = lockList->begin(); tmpIt + != lockList->end(); tmpIt++) { + PVSClient + * tmpConnection = + PVSConnectionManager::getManager()->getClientFromIp( + (*tmpIt).toUtf8().data()); + if (tmpConnection == (*it)) { + skip = true; + break; + } + } + } + if (!skip) + (*it)->sendMessage(PVSCOMMAND, "LOCKSTATION", "");//TODO define some standard to grab this from... + // otherwise this will get scattered all over the place + } + delete lockList; + } + return true; +} + +void ConnectionWindow::lockInvertStation(PVSClient* pvsCon) { + pvsCon->sendMessage(PVSCOMMAND, "LOCKSTATION", ""); +} + +bool ConnectionWindow::messageStations(QString ident, QString message) { + if (std::list<QString>* messageList = MainWindow::getConnectionList()->getSelectedClients()) { + if (!messageList->empty()) { + for (std::list<QString>::iterator tmpIt = messageList->begin(); tmpIt + != messageList->end(); tmpIt++) { + PVSClient + * tmpConnection = + PVSConnectionManager::getManager()->getClientFromIp( + (*tmpIt).toUtf8().data()); + // we don't want to lock the dozent machine + if (tmpConnection && tmpConnection->getConnectionFrame()->getFrame() && + !tmpConnection->getConnectionFrame()->getFrame()->isDozent()) + { + messageStation(ident, message, tmpConnection); + } else { + // scream in agony + } + } + } + delete messageList; + } + return true; +} + +void ConnectionWindow::messageStation(QString ident, QString message, + PVSClient* pvsCon) { + pvsCon->sendMessage(PVSMESSAGE, ident, message); +} + +bool ConnectionWindow::lockStationsWithMessage(QString message) +{ + if (!hasDozent) + { + QString message = QString(tr("You have to set a Superclient-machine before performing this action.")); + QMessageBox::information(this, "PVS", message); + return false; + } + if (std::list<QString>* messageList = MainWindow::getConnectionList()->getSelectedClients()) { + if (!messageList->empty()) { + for (std::list<QString>::iterator tmpIt = messageList->begin(); tmpIt + != messageList->end(); tmpIt++) { + PVSClient + * tmpConnection = + PVSConnectionManager::getManager()->getClientFromIp( + (*tmpIt).toUtf8().data()); + // we don't want to lock the dozent machine + if (tmpConnection && !tmpConnection->getConnectionFrame()->getFrame()->isDozent()) + { + lockStationsWithMessage(message, tmpConnection); + + } else { + // scream in agony + } + } + } + delete messageList; + } + return true; +} + +void ConnectionWindow::lockStationsWithMessage(QString message, + PVSClient* pvsCon) +{ + pvsCon->sendMessage(PVSCOMMAND, "LOCKSTATION", message); +} + +bool ConnectionWindow::lockAllStationsWithMessage(QString message) { + + if (!hasDozent) + { + QString message = QString(tr("You have to set a Superclient-machine before performing this action.")); + QMessageBox::information(this, "PVS", message); + return false; + } + std::list<PVSClient*> listAll = + PVSConnectionManager::getManager()->getConnections(); + for (std::list<PVSClient*>::iterator it = listAll.begin(); it + != listAll.end(); it++) + { + if ((*it) && !(*it)->getConnectionFrame()->getFrame()->isDozent()) // we don't want to lock the dozent machine + (*it)->sendMessage(PVSCOMMAND, "LOCKSTATION", message); + } + return true; +} + +void ConnectionWindow::addConnection(PVSClient* newCon) { + if (newCon) { + // QList<QString> ClientList= MainWindow::getConnectionList()->getClientist(); + + //Check if this client already in the list, before we add it. + //We don't want to have two clients with the same names. + //We comments it for test. + /*if (!ClientList.contains(newCon->getHostString())) + {*/ + onVNCAdd(newCon); + MainWindow::getConnectionList()->onAddClient(newCon); + /* + * We check if the pvsmgr run a lockAll on the already connected + * clients. If yes, we lock the new conencted client too. + */ + if (MainWindow::getWindow()->isLockAllStatus() && newCon->getConnectionFrame()->getFrame()) + { + newCon->getConnectionFrame()->getFrame()->setLockStatus(true); + // we call the update to force Qt to paint the lockicon on the frame + newCon->getConnectionFrame()->getFrame()->update(); + lockStation(newCon); + } + //} + } +} + +void ConnectionWindow::removeConnection(PVSClient* newCon) { + if (newCon == NULL) return; + ConnectionFrame* frame = newCon->getConnectionFrame(); + if (frame != NULL) + { + removeFromList(frame); + //frame->deleteLater(); + } + MainWindow::getConnectionList()->onRemoveClient(newCon); +} + +void ConnectionWindow::onView() { + if (std::list<QString>* selectedClient = MainWindow::getConnectionList()->getSelectedClients()) { + if (!selectedClient->empty()) { + if (selectedClient->size() == 1) + ;//TODO + + } + } +} + +void ConnectionWindow::updateConnection(PVSClient* newCon) { + if (newCon) { + MainWindow::getConnectionList()->onUpdateClient(newCon); + } +} + +void ConnectionWindow::addVNC() { + if (std::list<QString>* vncAddList = MainWindow::getConnectionList()->getSelectedClients()) { + if (!vncAddList->empty()) { + for (std::list<QString>::iterator tmpIt = vncAddList->begin(); tmpIt + != vncAddList->end(); tmpIt++) { + PVSClient + * tmpConnection = + PVSConnectionManager::getManager()->getClientFromIp( + (*tmpIt).toUtf8().data()); + if (tmpConnection) { + tmpConnection->requestVNCConnect(); + } else { + // scream in agony + } + } + } + } +} + +void ConnectionWindow::onVNCAdd(PVSClient* newCon) { + + if (!newCon->getConnectionFrame()) { + ConnectionFrame* newFrame = newConFrame(newCon); + newFrame->setConnection(newCon); + newFrame->setTaskbarTitle(newFrame->getTaskbarTitle()); + newFrame->setDummy(false); + newFrame->setFrameRate(500); + addFrame(newFrame); + if (!frameList.contains(newFrame)) + frameList.append(newFrame); + if (!AllFrameOnWindow.contains(newFrame)) + AllFrameOnWindow.append(newFrame); + newFrame->show(); + } else + // now we have already a pvsconnection, we should set the existing vncconnection to it + newCon->getConnectionFrame()->setConnection(newCon); + // addFrame(newFrame); +} + +void ConnectionWindow::removeVNC() { + std::list<QString>* vncRemoveList = + MainWindow::getConnectionList()->getSelectedClients(); + + // if(!vncRemoveList->empty()) + // { + for (std::list<QString>::iterator tmpIt = vncRemoveList->begin(); tmpIt + != vncRemoveList->end(); tmpIt++) { + PVSClient* tmpConnection = + PVSConnectionManager::getManager()->getClientFromIp( + (*tmpIt).toUtf8().data()); + if (tmpConnection) { + if (tmpConnection->getVNCConnection()) { + ConnectionFrame* tmpFrame = + tmpConnection->getVNCConnection()->getFrame(); + if (tmpFrame) { + frameList.removeOne(tmpFrame); + onChangeConnections(); + tmpFrame->setConnection(NULL); + tmpFrame->initFrame(); + //delete tmpFrame; + } + tmpConnection->shutDownVNC(); + } + } else { + // scream in agony + } + } + // + // } +} + +void ConnectionWindow::onRemoveConnection() { + if (std::list<QString>* removeList = MainWindow::getConnectionList()->getSelectedClients()) { + if (!removeList->empty()) { + for (std::list<QString>::iterator tmpIt = removeList->begin(); tmpIt + != removeList->end(); tmpIt++) { + PVSClient + * tmpConnection = + PVSConnectionManager::getManager()->getClientFromIp( + (*tmpIt).toUtf8().data()); + if (tmpConnection) { + // removal should start from the CM, so hes linking back to the ConnectionWindow::onConnectionRemoved() method + // to finish the removal procedure here + PVSConnectionManager::getManager()->removeConnection( + tmpConnection); + } else { + // scream in agony + } + } + // onChangeConnections(); + } + delete removeList; + return; + } +} + +void ConnectionWindow::onConnectionRemoved(PVSClient* newConnection) { + + + if (newConnection->getVNCConnection()) + + // check for associated frames! + if (newConnection->getVNCConnection()) { + ConnectionFrame* tmpFrame = + newConnection->getVNCConnection()->getFrame(); + // now handle the case that the client disconnects while we are in fullscreen mode + // the vncconnection would be cut nevertheless, so this: + if (tmpFrame) { + frameList.removeOne(tmpFrame); + // now handle the case that the client disconnects while we are in fullscreen mode + // the vncconnection would be cut nevertheless, so this: + if (tmpFrame == currentSingleFrame) { + currentSingleFrame = NULL; + } + + // no longer needed + delete tmpFrame; + newConnection->getVNCConnection()->setFrame(NULL); + } + } +} + +void ConnectionWindow::setSize(int width, int height, bool forceSquare) { + if (height >= 100 && width >= 100) { + MainWindow::getWindow()->setPrevWidth(width); + MainWindow::getWindow()->setPrevHeight(height); + } + + ignoreRatio = forceSquare; + + if (!frameList.empty()) { + ConnectionFrame* item; + foreach (item, frameList) + { + item->setIgnoreRatio(ignoreRatio); + } + } +} + +void ConnectionWindow::getCloseupSize(int &width, int &height) { + if (!onCloseup) { + width = height = 0; + return; + } + + width = 150; + height = 150; +} + +bool ConnectionWindow::getShowDummies() { + return _showDummies; +} + +void ConnectionWindow::setShowDummies(bool show) { + +} + +ConnectionFrame* ConnectionWindow::newConFrame(PVSClient* newConnection) { + if (newConnection->getConnectionFrame()) { + return NULL; + } + ConnectionFrame* temp = new ConnectionFrame( + MainWindow::getConnectionWindow()); + if (!temp) { + return NULL; + } + return temp; +} + +void ConnectionWindow::setCloseupFrame(ConnectionFrame* cFrame) { + _closeupFrame = cFrame; +} + +ConnectionFrame* ConnectionWindow::getCloseupFrame() { + if (_closeupFrame) + return _closeupFrame; + + return NULL; +} + diff --git a/src/gui/connectionWindow.h b/src/gui/connectionWindow.h new file mode 100644 index 0000000..81b5033 --- /dev/null +++ b/src/gui/connectionWindow.h @@ -0,0 +1,125 @@ +#ifndef _CONNECTIONWINDOW_H_ +#define _CONNECTIONWINDOW_H_ + +#include <QtGui> +#include <src/gui/connectionFrame.h> +#include <src/gui/connectionList.h> +#include <src/gui/mainWindow.h> +#include <list> +#include <iostream> +#include <math.h> +#include <QSettings> +#define FRAME_DELAY 1000 // to comply with the standard value in the gui + + +typedef std::pair<QString, QPoint> clientLocation; +typedef QList<clientLocation> clientLocationList; + +class ConnectionList; +class PVSClient; +class PVSConnectionManager; +class MainWindow; +class ConnectionFrame; +class QDragEnterEvent; +class QDropEvent; + + +class ConnectionWindow : public QWidget +{ + Q_OBJECT +public: + enum FILLORDER + { + ROW, + COLUMN, + SQUARE, + }; + + enum VIEWSTYLE + { + FULLSCREEN, + TABLE, + }; + + + + ConnectionWindow(QWidget *parent=0); + ~ConnectionWindow(); + void addFrame(ConnectionFrame *conFrame); + void addFrameBySettings(QString client, QPoint pos); + void showFrameFromSettings(); + void onChangeConnections(); // if connections are added or removed, this method makes sure the window changes accordingly + void addConnection(PVSClient* newCon); // handle newly connected clients (forward to con-list) + void removeConnection(PVSClient* newCon); // Remove client on disconnect + void onView(); + void updateConnection(PVSClient* newCon); // update stuff like username etc on a present connection + void addVNC(); + void onVNCAdd(PVSClient* newCon); + void removeVNC(); + void onRemoveConnection(); // tells the PVSConnectionManager to remove the connections that are marked in the sidebar + void onConnectionRemoved(PVSClient* newConnection); // does some cleanup and tells the gui elements that this connection is removed + void setSize(int width, int height, bool forceSquare); // tell the frames to use this size settings + void getCloseupSize(int &width, int &height); + bool getShowDummies(); + void setShowDummies(bool show); + QList<ConnectionFrame*> dummyList; + QList<ConnectionFrame*> AllFrameOnWindow; + QList<ConnectionFrame*> getAllFrameOnWindow() + { + return AllFrameOnWindow; + } + void removeFromList(ConnectionFrame* cF); + + bool remoteHelp(QString sname); + bool projectStations(QString sname); + bool unprojectStations(QString sname); + bool lockStations(); + void lockStation(PVSClient* pvsCon); + bool unlockStations(); + void unlockStation(PVSClient* pvsCon); + bool lockAllStations(); + bool unlockAllStations(); + bool unprojectAllStations(); + bool lockInvertStations(); + void lockInvertStation(PVSClient* pvsCon); + bool messageStations(QString ident, QString message); + void messageStation(QString ident, QString message, PVSClient* pvsCon); + bool lockStationsWithMessage(QString message); + void lockStationsWithMessage(QString message, PVSClient* pvsCon); + bool lockAllStationsWithMessage(QString message); + + void setCloseupFrame(ConnectionFrame* cFrame); + int itemAt(ConnectionFrame* cf); + ConnectionFrame* getCloseupFrame(); + QList<ConnectionFrame*> getFrameList(){ return frameList; }; + clientLocationList ClientLocationList; + bool hasDozent; //if a Dozent machine is available this will be set to true else false + //Frame position in the window + int posX; + int posY; + +public Q_SLOTS: + void addDummy(); + + +protected: + QList<ConnectionFrame*> frameList; // list of all connected frames + void mousePressEvent(QMouseEvent *event); + +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; + QPoint currentPosition (ConnectionFrame* cF); + QMenu *menu; + QAction *newDummy; + bool ignoreRatio; // wether the native ratio should be ignored or not + bool onFullscreen; // wether on fullscreen or not + bool onCloseup; // wether on closeup or not + int defaultWidth, defaultHeight; // obvious + unsigned int frameRate; // also obvious*/ + bool _showDummies; + +}; + +#endif diff --git a/src/gui/dialog.cpp b/src/gui/dialog.cpp new file mode 100644 index 0000000..3c9b7a2 --- /dev/null +++ b/src/gui/dialog.cpp @@ -0,0 +1,74 @@ +/* +# 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/ +# ----------------------------------------------------------------------------- +# dialog.cpp + Dialog to get message to send to client +# ----------------------------------------------------------------------------- +*/ + +#include "dialog.h" +#include "ui_dialog.h" +#include <src/gui/mainWindow.h> + +Dialog::Dialog(QWidget *parent) : + QDialog(parent), + dui(new Ui::MsgDialog) +{ + dui->setupUi(this); + + dui->send->setDisabled(true); + + setWindowTitle(tr("Enter the Text for the client(s)")); + + connect( dui->send, SIGNAL( clicked()), this, SLOT( send())); + connect( dui->cancel, SIGNAL( clicked()), this, SLOT( NotSend())); + connect(dui->message, SIGNAL(textChanged()), this, SLOT(textchange())); +} + +Dialog::~Dialog() +{ + delete dui; +} + +void Dialog::send() +{ + QString mesge = dui->message->toPlainText(); + MainWindow::getWindow()->setMsgDialog(mesge); + dui->message->clear(); + emit accept(); +} + +void Dialog::NotSend() +{ + dui->message->clear(); + emit reject(); +} + +void Dialog::textchange() +{ + QString message = dui->message->toPlainText(); + if(message.length()>0) + dui->send->setDisabled(false); + else + dui->send->setDisabled(true); +} + +void Dialog::changeEvent(QEvent *e) +{ + QDialog::changeEvent(e); + switch (e->type()) { + case QEvent::LanguageChange: + dui->retranslateUi(this); + break; + default: + break; + } +} diff --git a/src/gui/dialog.h b/src/gui/dialog.h new file mode 100644 index 0000000..689cbb4 --- /dev/null +++ b/src/gui/dialog.h @@ -0,0 +1,33 @@ +#ifndef DIALOG_H +#define DIALOG_H + +#include <QDialog> +#include <QtGui> +//#include <src/gui/mainWindow.h> + + +namespace Ui { + class MsgDialog; +} + +class MainWindow; + +class Dialog : public QDialog { + Q_OBJECT +public: + Dialog(QWidget *parent = 0); + ~Dialog(); + +protected: + void changeEvent(QEvent *e); + +private: + Ui::MsgDialog *dui; + +private slots: + void send(); + void NotSend(); + void textchange(); +}; + +#endif // DIALOG_H 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); + } +} diff --git a/src/gui/frame.h b/src/gui/frame.h new file mode 100644 index 0000000..3004e0c --- /dev/null +++ b/src/gui/frame.h @@ -0,0 +1,90 @@ +#ifndef FRAME_H_ +#define FRAME_H_ + +#include <QtGui> +#include "../util/vncClientThread.h" + +class VNCClientThread; +class ConnectionWindow; +class ConnectionFrame; +class MainWindow; + +class Frame: public QLabel +{ + Q_OBJECT + +public: + Frame(const QString & text, QWidget * parent = 0 ); + virtual ~Frame(); + void setVNCThreadConnection(VNCClientThread * VNCclientThread); + void stopVNCThreadConnection(); + VNCClientThread * getVNCClientThread() + { + return _clientVNCThread; + } + void setConFrame (ConnectionFrame* cf) + { + _cFrame = cf; + } + ConnectionFrame* getConFrame() + { + return _cFrame; + } + void setToolButtonListVisible(bool visible); + void setLockStatus(bool lock); + bool getLockStatus() + { + return _isLocked; + } + bool isDozent() + { + return _dozent; + } + int X,Y; + + QString ip; + QToolButton* button_closeUp; + QToolButton* button_foto; + QToolButton* button_lock; + QToolButton* button_unlock; + QToolButton* button_dozent; + QList<QToolButton*> toolButtonList; + +public Q_SLOTS: + void updateImage(int x, int y, int w, int h); + void iamDown(); + void slotClicked(); + QImage image() + { + return _clientImg; + }; + void setImage(QImage img) + { + _clientImg = img; + }; + QImage getImageForFoto(); + void closeUp(); + void foto(); + void setLock(); + //void unlock(); + void setDozent(); + +signals: + void clicked(); +protected: + void paintEvent(QPaintEvent *event); + void mousePressEvent ( QMouseEvent * event ); + void mouseReleaseEvent ( QMouseEvent * event ); + +private: + QToolButton* createToolButton(const QString &toolTip, const QIcon &icon, const char *member); + void addButton(QToolButton *button); + VNCClientThread *_clientVNCThread; + ConnectionFrame *_cFrame; + QImage _clientImg; + bool _isLocked; + bool _dozent; + int _ux, _uy; +}; + +#endif /* FRAME_H_ */ diff --git a/src/gui/mainWindow.cpp b/src/gui/mainWindow.cpp new file mode 100644 index 0000000..eb15e82 --- /dev/null +++ b/src/gui/mainWindow.cpp @@ -0,0 +1,1205 @@ +/* + # 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/ + # ----------------------------------------------------------------------------- + # mainWindow.cpp + This is the Main class for the pvsManager. The GUI is contructed here. + # ----------------------------------------------------------------------------- + */ + +#include <QtGui> +#include <QFileDialog> +#include <src/gui/mainWindow.h> +using namespace std; + +// setting the IF-DEF Block for the touchgui and the normal gui, for later use + +#ifdef MAINWINDOW_USE_TOUCHGUI +#include "ui_mainwindowtouch.h" +#endif + +#ifdef MAINWINDOW_USE_NORMALGUI +#include "ui_mainwindow.h" +#endif + +#include <src/gui/connectionList.h> +#include <src/gui/connectionWindow.h> +#include <src/gui/profileDialog.h> +//#include <src/gui/dialog.h> +#include <src/core/pvsConnectionManager.h> +#include <iostream> + +MainWindow::MainWindow(QWidget *parent) : + QMainWindow(parent), ui(new Ui::MainWindow) + +{ + + ui->setupUi(this); + + ui->horizontalSlider->setValue(100); + ui->label_2->setText("100"); + + ui->separator->setVisible(false); + + myself = this; + conWin = new ConnectionWindow(ui->widget); + ui->VconWinLayout->addWidget(conWin); + conList = new ConnectionList(ui->ClWidget); + ui->ClientGLayout->addWidget(conList); + + bgimage = false; + + _aboutDialog = new AboutDialog(this); + + PVSConnectionManager::getManager(); + + //set the maximum width for list content + ui->ClWidget->setMaximumWidth(160); + + ui->pvsLog->setReadOnly(true); + ui->pvsLog->hide(); + + onToggleLog(false); + // add ourself to the log listeners, so we can output them too + ConsoleLog addListener(this, &MainWindow::on_log_line); + + _firstResize = 1; + _oldRatio = "100"; + _isThumbnailrate = false; + is_closeup = false; + is_fullscreen = false; + _isLockAll = false; + locked = false; + + /* + * _sessionName: The session name for this Connection + * _pwdCon: Password needed to connect to the session with the name _sessionName + */ + _pwdCon = PVSConnectionManager::getManager()->setNeedPassword(false); + _sessionName = PVSConnectionManager::getManager()->getSessionName(); + + ui->setPassword->setCheckState(Qt::Checked); + +#ifdef MAINWINDOW_USE_TOUCHGUI //only used for the touchgui + + // define the slots we want to use + connect(ui->comboBox_touch1, SIGNAL(currentIndexChanged(int)), this, SLOT(combobox1(int))); // Combobox 1 verknüpfen mit IndexChangend Signal + connect(ui->comboBox_touch1, SIGNAL(currentIndexChanged(int)), this, SLOT(setindexback())); + + + connect(ui->pushButton, SIGNAL(clicked()), this, SLOT(createProfile())); // profile button + connect(ui->pushButton_2, SIGNAL(clicked()), this, SLOT(clientlisthide())); // clienlist button + + // toolbar slots + connect(ui->actionresetall, SIGNAL(triggered()), this, SLOT(resetall())); + connect(ui->actionLocksingle, SIGNAL(triggered()), this, SLOT(locksingle())); + connect(ui->actionUnlocksingle, SIGNAL(triggered()), this, SLOT(unlocksingle())); + connect(ui->actionProjection, SIGNAL(triggered()), this, SLOT(projecttoolbar())); + connect(ui->actionUnprojection, SIGNAL(triggered()), this, SLOT(unprojecttoolbar())); + connect(ui->actionDozent, SIGNAL(triggered()), this, SLOT(setdozenttoolbar())); + + // Ui specific settings + + ui->ClWidget->hide(); + ui->progressBar->hide(); + ui->pvsLog->hide(); + + +#endif + + + // toolbar and actions in pvsmgr + connect(ui->action_Exit, SIGNAL(triggered()), this, SLOT(close())); + ui->action_Exit->setStatusTip(tr("Exit")); + connect(ui->action_Disconnect, SIGNAL(triggered()), this, SLOT(disconnect())); + ui->action_Disconnect->setStatusTip(tr("Remove the vnc-Connection for the selected client(s)")); + ui->action_Disconnect->setVisible(false);//we need it only for debug + connect(ui->actionView, SIGNAL(triggered()), this, SLOT(closeUp())); + ui->actionView->setStatusTip(tr("Show the selected client in the whole window")); + connect(ui->actionFoto, SIGNAL(triggered()), this, SLOT(foto())); + connect(ui->actionLock, SIGNAL(triggered()), this, SLOT(lockalltoolbar())); + connect(ui->actionChat, SIGNAL(triggered()), this, SLOT(startChatDialog())); + 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->actionShow_Username, SIGNAL(triggered()), this, SLOT(showusername())); + connect(ui->actionShow_Hostname_IP, SIGNAL(triggered()), this, SLOT(showip())); + connect(ui->actionShow_Fullname, SIGNAL(triggered()), this, SLOT(showname())); + connect(ui->horizontalSlider, SIGNAL(valueChanged (int)), this, SLOT(changeRatio(int))); + connect(ui->setPassword, SIGNAL(stateChanged (int)), this, SLOT(setPasswordForConnection(int))); + connect(ui->vncQuality, SIGNAL(currentIndexChanged (int)), this, SLOT(setVNCQuality(int))); + connect(ui->thumbStatus, SIGNAL(currentIndexChanged(int)), this, SLOT(changeStatus(int))); + connect(ui->actionShow_Log, SIGNAL(toggled(bool)), this, SLOT(setLogConsoleDisabled(bool))); + connect(ui->actionShow_Network, SIGNAL(toggled(bool)), this, SLOT(onToggleLog(bool))); + connect(ui->actionShow_Chat, SIGNAL(toggled(bool)), this, SLOT(onToggleLog(bool))); + connect(ui->actionShow_Terminal, SIGNAL(toggled(bool)), this, SLOT(onToggleLog(bool))); + connect(ui->actionShow_Normal, SIGNAL(toggled(bool)), this, SLOT(onToggleLog(bool))); + connect(ui->actionShow_Error, SIGNAL(toggled(bool)), this, SLOT(onToggleLog(bool))); + connect(ui->actionAbout_pvs, SIGNAL(triggered()), _aboutDialog, SLOT(open())); + + loadSettings(); //we load the appliocation settings + + setUnifiedTitleAndToolBarOnMac(true); + statusBar()->showMessage(tr("The pvs manager")); + this->showMaximized(); // show the Mainwindow maximized + + // listen on port 29481 for incoming file transfers + _serverSocket = new QTcpServer(); + _serverSocket->listen(QHostAddress::Any, 29481); + connect(_serverSocket, SIGNAL(newConnection()), this, SLOT(incomingFile())); + + +} + +MainWindow::~MainWindow() +{ + delete ui; +} + +/* + * This signal is received when the mainwindow is going to be closed. + * We have to check if the the chat-dialog is open. In this case we close + * this dialog and accept the event, the rest will be execute from Qt. + * Qt will be call the destroyer ~MainWindow(). + */ +void MainWindow::closeEvent(QCloseEvent *e) +{ + if (sChatDialog.isVisible()) + sChatDialog.close(); + e->accept(); +} + +MainWindow* MainWindow::getWindow() // catches the window +{ + + if (myself) + { + return myself; + } + else + { + return myself = new MainWindow; + } +} + +ConnectionWindow* MainWindow::getConnectionWindow() // catches the ConnectionWindow +{ + if (conWin) + { + return conWin; + } + else + { + conWin = new ConnectionWindow; + return conWin; + } +} + +ConnectionList* MainWindow::getConnectionList() // catches the ConnectionList +{ + if (conList) + return conList; + else + { + conList = new ConnectionList; + return conList; + } +} + +int MainWindow::getConnectionWindowWidth() // returns the width of the ConnectionWindow +{ + return ui->widget->width(); +} + +int MainWindow::getConnectionWindowHeight() // returns the height of the CoonectionWindow +{ + return ui->widget->height(); +} + +QStringList MainWindow::getProfilList() // loads the profile list +{ + QSettings settings("openslx", "pvsmgr"); + profilList = settings.childGroups(); + return profilList; +} + +#ifdef MAINWINDOW_USE_NORMALGUI +void MainWindow::addProfileInMenu(QString name) +{ + QAction* action = new QAction(name,this); + ui->menuLoad_profile->addAction(action); + connect(ui->menuLoad_profile, SIGNAL(triggered(QAction*)), this, SLOT(loadProfile(QAction*))); + _mapProfileToAction.insert(name, action); +} + +void MainWindow::removeProfileInMenu(QString name) +{ + if (_mapProfileToAction.contains(name)) + { + QAction* action = _mapProfileToAction.value(name); + ui->menuLoad_profile->removeAction(action); + _mapProfileToAction.take(name); + } + +} + +#endif +void MainWindow::loadSettings() +{ + QSettings settings("openslx", "pvsmgr"); + QString current = settings.value("current", "default").toString(); + currentProfi = current; + _profilName = current; + + //When no profile is available, we define a default one whith 9 dummy screens + 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); + + QString title = "PVSmgr - "; + title.append(_profilName); + title.append(" ["+_sessionName + " : "); + title.append(_pwdCon+"]"); + setWindowTitle(title); + } + else + { + QString title = "PVSmgr - "; + title.append(_profilName); + title.append(" ["+_sessionName + " : "); + title.append(_pwdCon+"]"); + setWindowTitle(title); + settings.beginGroup(current); + QStringList keys = settings.childKeys(); + for (int i=0; i<keys.size(); i++) + { + QString profil = current; + profil = profil.append("/").append(keys.at(i)); + QPoint pos = settings.value(keys.at(i)).toPoint(); + MainWindow::getConnectionWindow()->addFrameBySettings(keys.at(i), pos); + } + } + + MainWindow::getConnectionWindow()->showFrameFromSettings(); +#ifdef MAINWINDOW_USE_NORMALGUI + foreach (QString profile, getProfilList()) + addProfileInMenu(profile); +#endif +} + +void MainWindow::loadProfile(QAction* actiontriggered) +{ + QString profilename = actiontriggered->text(); + loadSettings(profilename); +} + +void MainWindow::loadSettings(QString profilname) // loads the current profile +{ + QList<ConnectionFrame*> AllFrameOnWindow = + MainWindow::getConnectionWindow()->getAllFrameOnWindow(); + + if (AllFrameOnWindow.size() > 0) + { + _profilName = profilname; + MainWindow::getConnectionWindow()->ClientLocationList.clear(); + QSettings settings("openslx", "pvsmgr"); + settings.setValue("current", _profilName); + ConnectionFrame* cFrame; + foreach (cFrame, AllFrameOnWindow) + { + if (cFrame->isDummy()) + { + AllFrameOnWindow.removeOne(cFrame); + MainWindow::getConnectionWindow()->removeFromList(cFrame); + cFrame->deleteLater(); + } + } + settings.beginGroup(_profilName); + QStringList keys = settings.childKeys(); + int rest = AllFrameOnWindow.size(); + int init = 1; + for (int i = 0; i < keys.size(); i++) + { + if (init <= rest) + { + ConnectionFrame* cF = AllFrameOnWindow.at(i); + QString profil = _profilName; + profil = profil.append("/").append(cF->getTaskbarTitle()); + if (!cF->isDummy()) + cF->move(settings.value(keys.at(i)).toPoint()); + else + cF->move(settings.value(profil, QPoint(10,(10+(5*i)))).toPoint()); + + init += 1; + } + else + { + MainWindow::getConnectionWindow()->addFrameBySettings( + keys.at(i), settings.value(keys.at(i)).toPoint()); + } + } + + MainWindow::getConnectionWindow()->showFrameFromSettings(); + + QString title = "PVSmgr - "; + title.append(_profilName); + title.append(" ["+_sessionName + " : "); + title.append(_pwdCon+"]"); + setWindowTitle(title); + } +} + +void MainWindow::saveSettings(QString profilname) +{ + QList<ConnectionFrame*> AllFrameOnWindow = + MainWindow::getConnectionWindow()->getAllFrameOnWindow(); + QSettings settings("openslx", "pvsmgr"); + settings.setValue("current", profilname); + settings.setValue("size", QString("%1").arg(AllFrameOnWindow.size())); + + for (int i = 0; i < AllFrameOnWindow.size(); i++) + { + ConnectionFrame* current = AllFrameOnWindow.at(i); + QString profil = ""; + profil = settings.value("current").toString().append("/"); + if (!current->isDummy()) + profil.append(QString(current->getTaskbarTitle())); + else + profil.append(QString("%1").arg(i + 1)); + settings.setValue(profil, current->pos()); + } +#ifdef MAINWINDOW_USE_NORMALGUI +addProfileInMenu(profilname); +#endif +} + +void MainWindow::removeProfil(QString profilname) +{ + QSettings settings("openslx", "pvsmgr"); + settings.remove(profilname); +#ifdef MAINWINDOW_USE_NORMALGUI +removeProfileInMenu(profilname); +#endif +} + +void MainWindow::addConnection(PVSClient* newCon) +{ + conWin->addConnection(newCon); + if (!_chatListClients.contains(newCon->getUserName())) + { + _chatListClients.append(newCon->getUserName()); + sChatDialog.chat_client_add(newCon->getUserName()); + sChatDialog.chat_nicklist_update(); + } + // sChatDialog->chat_nicklist_update(newCon->getUserName()); +} + +void MainWindow::removeConnection(PVSClient* newCon) +{ + conWin->removeConnection(newCon); + if (_chatListClients.contains(newCon->getUserName())) + { + _chatListClients.removeOne(newCon->getUserName()); + sChatDialog.chat_client_remove(newCon->getUserName()); + sChatDialog.chat_nicklist_update(); + } +} + +void MainWindow::onConnectionFailed(QString host) +{ +#ifdef never + // code is voided because the info-management will be overhauled sometime + + if (pwDiag) // assume this thing failed after the pw-question... so a wrong password, ey? + + { + onPasswordFailed(host); + return; + } + + QString caption, secondary; + if (host != "") + { + caption = ("PVSConnection with hostname \""); + caption.append(host); + caption.append("\" failed."); + secondary = "PVSConnection attempt for this hostname failed.Maybe the host is not prepared to accept vnc connections. Please make sure hostname and (if needed) password are correct."; + } + else + { + caption = "No IP given"; + secondary = "PVSConnection attempt for this host failed. There was either no or an errorous Hostname given."; + } + QMessageBox::information(*this, caption, secondary); + /* Gtk::MessageDialog dialog(*this, Glib::ustring(caption)); + dialog.set_secondary_text(secondary); + dialog.run();*/ +#endif +} + +void MainWindow::onConnectionTerminated(PVSClient* newConnection) +{ +#ifdef never + // code is voided because the info-management will be overhauled sometime + + QString host; + if (newConnection) + { + host = newConnection->getIp(); // copy hostname for message + } + else + host = "spooky unknown"; + + // now inform + QString caption, secondary; + + caption = "Hostname \""; + caption.append(host); + caption.append("\" terminated connection."); + secondary = "The server has closed the connection to your client."; + + QMessageBox::information(*this, caption, secondary); + /*Gtk::MessageDialog dialog(*this, Glib::ustring(caption)); + dialog.set_secondary_text(secondary); + dialog.run();*/ +#endif +} + +void MainWindow::onConnectionRemoved(PVSClient* newConnection) +{ + // TODO this would be the place to handle the rest of the fullscreen issue + conWin->onConnectionRemoved(newConnection); +} + +void MainWindow::onPasswordFailed(QString Qhost) +{ +#ifdef never + // code is voided because the info-management will be overhauled sometime + QString caption, secondary; + if (Qhost != "") + { + caption = "Hostname \""; + caption.append(Qhost); + caption.append("\" refused password."); + secondary = "You have entered no or a wrong password."; + } + else + return; // unknown connection was terminated? too spooky + QMessageBox::information(*this, caption, secondary); + /* Gtk::MessageDialog dialog(*this, Glib::ustring(caption)); + dialog.set_secondary_text(secondary); + Gtk::Main::run(dialog);*/ +#endif +} + +void MainWindow::sendChatMsg(PVSMsg myMsg) +{ + PVSConnectionManager::getManager()->onChat(myMsg); +} + +void MainWindow::receiveChatMsg(QString nick_from, QString nick_to, QString msg) +{ + sChatDialog.chat_receive(nick_from, nick_to, msg); +} + +int MainWindow::getPrevWidth() // PVSConnectionManager::getManager()->getPrevWidth() +{ + return prev_width; +} + +void MainWindow::setPrevWidth(int newWidth) +{ + if (newWidth > 100) + prev_width = newWidth; + else + prev_width = 100; +} + +int MainWindow::getPrevHeight() +{ + return prev_height; +} + +void MainWindow::setPrevHeight(int newHeight) +{ + if (newHeight > 100) + prev_height = newHeight; + else + prev_height = 100; +} + +void MainWindow::changeEvent(QEvent *e) +{ + QMainWindow::changeEvent(e); + switch (e->type()) + { + case QEvent::LanguageChange: + ui->retranslateUi(this); + break; + default: + break; + } +} + +/* + * The resize Event is called when the mainwindow is resized! + * Whe need this event to resize the Frame on the Connectionwindow. + * The Frames are resized proportionally to the new size of the mainwindow. + * But this Function is called by Qt 3 times before the whole + * mainwdow is constructed. We can only resize the Frame on Window and + * get the initial size of the Connectionwindow after this 3 times. + */ +void MainWindow::resizeEvent(QResizeEvent *event) +{ + + if (bgimage == true){ + repaintbackgroundpicture(); // repaint the backgroundpicture scaled to the window size + } + + if (_firstResize == 3) + { + QSize oldSize = event->oldSize(); + _initW = ui->widget->width(); + _initH = ui->widget->height(); + _firstResize++; + } + std::list<QString>* selectedClients = + MainWindow::getConnectionList()->getSelectedClients(); + if (is_closeup && selectedClients->size() == 1) + { + PVSClient* pvsClient = + PVSConnectionManager::getManager()->getClientFromIp( + selectedClients->front().toStdString().c_str()); + pvsClient->getConnectionFrame()->paintCloseUp(ui->widget->width(), + ui->widget->height()); + } + else if (!is_closeup && _firstResize > 3) + { + int ratio_w = (ui->widget->width()*100)/_initW; + int ratio_h = (ui->widget->height()*100)/_initH; + foreach (ConnectionFrame* cf, getConnectionWindow()->getFrameList()) + { + /*int margin = ui->widget->style()->pixelMetric(QStyle::PM_DefaultTopLevelMargin); + int x = ui->widget->width() - margin; + int y = ui->widget->height() - margin; + updatePos(cf, x, y);*/ + int w = (cf->init_w * ratio_w) / 100; + int h = (cf->init_h * ratio_h) / 100; + cf->paintCloseUp(w,h); + } + } + + if (_firstResize < 3) + _firstResize++; +} + +void MainWindow::updatePos(ConnectionFrame* cf, int x, int y) +{ + int posx = (x*cf->pos().x())/_initW; + int posy = (y*cf->pos().y())/_initH; + cf->move(posx, posy); + /*QSize size = cf->sizeHint(); + cf->setGeometry(x - size.rwidth(), y - size.rheight(), + size.rwidth(), size.rheight());*/ +} + +void MainWindow::on_log_line(LogEntry consoleEntry) +{ + ConsoleLogger::LOG_LEVEL level = consoleEntry.getLevel(); + if (level == ConsoleLogger::LOG_ERROR && !showError) + return; + if (level == ConsoleLogger::LOG_NORMAL && !showNormal) + return; + if (level == ConsoleLogger::LOG_NETWORK && !showNetwork) + return; + if (level == ConsoleLogger::LOG_TERMINAL && !showTerminal) + return; + if (level == ConsoleLogger::LOG_CHAT && !showChat) + return; + + ui->pvsLog->insertPlainText(consoleEntry.getLine()); + +} + +void MainWindow::onToggleLog(bool showtime) +{ + if (showtime) + ;//to kill the system warning due "unused variable" + showError = ui->actionShow_Error->isChecked(); + showTerminal = ui->actionShow_Terminal->isChecked(); + showNetwork = ui->actionShow_Network->isChecked(); + showChat = ui->actionShow_Chat->isChecked(); + showNormal = ui->actionShow_Normal->isChecked(); + //showAtAll = ui->logAtAllAction->get_active(); + + + ConsoleLog dump2Listener(this, &MainWindow::on_log_line); +} + +void MainWindow::setLogConsoleDisabled(bool visible) +{ + if (!visible) + ui->pvsLog->hide(); + else + ui->pvsLog->show(); +} + +/*void MainWindow::close() +{ + //sChatDialog.close(); + QApplication::closeAllWindows(); +}*/ + +void MainWindow::disconnect() +{ + conWin->removeVNC(); +} + +void MainWindow::lockUnlockAll() +{ + if (_isLockAll) + { + //ui->actionLock set icon to unlock + MainWindow::getConnectionWindow()->unlockAllStations(); + _isLockAll = false; + } + else + { + //ui->actionLock set icon to lock + MainWindow::getConnectionWindow()->lockAllStations(); + _isLockAll = true; //tell the manager all the clients are locked + } +} + +void MainWindow::closeUp() +{ + std::list<QString>* selectedClients = + MainWindow::getConnectionList()->getSelectedClients(); + if (!is_closeup) + { + if (selectedClients->size() == 1) + { + PVSClient + * pvsClient = + PVSConnectionManager::getManager()->getClientFromIp( + selectedClients->front().toStdString().c_str()); + _framePosOnCloseUp = pvsClient->getConnectionFrame()->pos();//get the actualy position before run closeup + if (pvsClient->getVNCConnection()) + { + conWin->setCloseupFrame(pvsClient->getConnectionFrame()); + _updatefreq = pvsClient->getConnectionFrame()->getFrame()->getVNCClientThread()->getUpdatefreq(); + pvsClient->getConnectionFrame()->getFrame()->getVNCClientThread()->setUpdatefreq(50); + pvsClient->getConnectionFrame()->move(5,5); + pvsClient->getConnectionFrame()->setWindowFlags(Qt::WindowStaysOnTopHint); + pvsClient->getConnectionFrame()->raise(); + pvsClient->getConnectionFrame()->paintCloseUp(ui->widget->width(),ui->widget->height()); + + is_closeup = true; + conWin->setCloseupFrame(pvsClient->getConnectionFrame()); + } + } + else + { + QString + message = + QString( + tr( + "This operation can only be performed for one selected Client!")); + QMessageBox::information(this, "PVS", message); + } + } + else if (conWin->getCloseupFrame()) + { + /*PVSClient* pvsClient = + PVSConnectionManager::getManager()->getClientFromIp( + selectedClients->front().toStdString().c_str());*/ + conWin->getCloseupFrame()->setWindowFlags(Qt::Widget); + conWin->getCloseupFrame()->paintCloseUp(conWin->getCloseupFrame()->getPrevWidth(), conWin->getCloseupFrame()->getPrevHeight()); + conWin->getCloseupFrame()->move(_framePosOnCloseUp);//back to the position before the closeup + if (conWin->getCloseupFrame()->getConnection()->getVNCConnection()) + conWin->getCloseupFrame()->getFrame()->getVNCClientThread()->setUpdatefreq(_updatefreq); + + is_closeup = false; + conWin->setCloseupFrame(NULL); + } +} + +void MainWindow::foto() // makes a screenshot of the selected client +{ + std::list<QString>* selectedClients = + MainWindow::getConnectionList()->getSelectedClients(); + if (selectedClients->size() > 0) + { + QString format = "png"; + for (std::list<QString>::iterator tmpIt = selectedClients->begin(); tmpIt + != selectedClients->end(); tmpIt++) + { + + QString path = QDir::homePath().append("/").append(*tmpIt).append( + ".png"); + PVSClient + * pvsClient = + PVSConnectionManager::getManager()->getClientFromIp( + (*tmpIt).toUtf8().data()); + if (pvsClient->getVNCConnection()) + { + const QImage img = pvsClient->getConnectionFrame()->getFrame()->getImageForFoto(); + if (!img.isNull()) + img.save(path, format.toAscii()); + } + else printf("Cannot save screen: Image is null.\n"); + } + } + else + { + QString + message = + QString( + tr( + "This operation can only be performed for at least one selected Client!")); + QMessageBox::information(this, "PVS", message); + } +} + +void MainWindow::createProfile() +{ + profileDialog proDiag; + proDiag.exec(); +} + +void MainWindow::showusername() +{ + MainWindow::getConnectionList()->setColumnHidden(2, false); + MainWindow::getConnectionList()->setColumnHidden(0, true); + MainWindow::getConnectionList()->setColumnHidden(1, true); +} + +void MainWindow::showname() +{ + MainWindow::getConnectionList()->setColumnHidden(0, false); + MainWindow::getConnectionList()->setColumnHidden(1, true); + MainWindow::getConnectionList()->setColumnHidden(2, true); +} + +void MainWindow::showip() +{ + MainWindow::getConnectionList()->setColumnHidden(1, false); + MainWindow::getConnectionList()->setColumnHidden(2, true); + MainWindow::getConnectionList()->setColumnHidden(0, true); +} + +void MainWindow::incomingFile() +{ + QTcpSocket *socket = _serverSocket->nextPendingConnection(); + ServerFileTransfert* sft = new ServerFileTransfert(this); + sft->receiveFileFromHost(socket); +} + +void MainWindow::changeRatio(int ratio) // needed the change the size of the vnc-screens +{ + + if (!_isThumbnailrate) + { + QString str; + str.append(QString("%1").arg(ratio)); + ui->label_2->setText(str); + + std::list<QString>* selClients = getConnectionList()->getSelectedClients(); + if (selClients->size() > 0) + { + for (std::list<QString>::iterator client = selClients->begin(); client + != selClients->end(); client++) + { + PVSClient* pvsClient = + PVSConnectionManager::getManager()->getClientFromIp( + (*client).toUtf8().data()); + ConnectionFrame *frame = pvsClient->getConnectionFrame(); + int w = (frame->init_w * ratio) / 100; + int h = (frame->init_h * ratio) / 100; + frame->setPrevWidth(w); + frame->setPrevHeight(h); + frame->paintCloseUp(w, h); + frame->setRatio(ratio); + } + } + else + { + QList<ConnectionFrame *> frameList = + MainWindow::getConnectionWindow()->getFrameList(); + ConnectionFrame *frame; + foreach(frame, frameList) + { + int w = (frame->init_w * ratio) / 100; + int h = (frame->init_h * ratio) / 100; + frame->setPrevWidth(w); + frame->setPrevHeight(h); + frame->paintCloseUp(w, h); + } + } + } + else + { + int updatefreq = (ratio*500)/100; + QString str; + str.append(QString("%1").arg(updatefreq)); + ui->label_2->setText(str); + std::list<QString>* selClients = getConnectionList()->getSelectedClients(); + if (selClients->size() > 0) + { + for (std::list<QString>::iterator client = selClients->begin(); client + != selClients->end(); client++) + { + PVSClient* pvsClient = + PVSConnectionManager::getManager()->getClientFromIp( + (*client).toUtf8().data()); + if (pvsClient->getVNCConnection()) + pvsClient->getConnectionFrame()->getFrame()->getVNCClientThread()->setUpdatefreq(updatefreq); + } + } + else + { + std::list<PVSClient*> clients = PVSConnectionManager::getManager()->getConnections(); + foreach (PVSClient* client, clients) + { + if (client->getVNCConnection()) + client->getConnectionFrame()->getFrame()->getVNCClientThread()->setUpdatefreq(updatefreq); + } + } + + } +} + +/* + * We can change the status for the action that we want to assign to the thumbnails. + * The actions are to be perform over the horizontalslider from QSlider only on the not dummies clients. + * The dummies clients aren't involved. + * We distingue two status: + * -Thumbnailratio:hier we can change the ratio of the thumbnails. + * -Thumbnailrate:we change the rate of the VNCClientThread of the frames. These actions are perform on the selected clients. + * If no clients are selected, we change the ratio of the whole clients on the clientlist * + */ +void MainWindow::changeStatus(int index) +{ + QString status = ui->thumbStatus->currentText (); + + if (status == "Thumbnailratio") + { + _isThumbnailrate = false; + ui->label_3->setText("%"); + std::list<QString>* selClients = getConnectionList()->getSelectedClients(); + if (selClients->size() == 1) + { + PVSClient* pvsClient = + PVSConnectionManager::getManager()->getClientFromIp( + selClients->front().toStdString().c_str()); + int ratio = pvsClient->getConnectionFrame()->getRatio(); + ui->label_2->setText(QString::number(ratio)); + ui->horizontalSlider->setValue(ratio); + } + else + { + ui->label_2->setText("100"); + ui->horizontalSlider->setValue(100); + } + + } + else if (status == "Thumbnailrate") + { + _isThumbnailrate = true; + ui->label_3->setText("ms"); + std::list<QString>* selClients = getConnectionList()->getSelectedClients(); + if (selClients->size() == 1) + { + PVSClient* pvsClient = + PVSConnectionManager::getManager()->getClientFromIp( + selClients->front().toStdString().c_str()); + if (pvsClient->getVNCConnection()) + { + int updatefreq = pvsClient->getConnectionFrame()->getFrame()->getVNCClientThread()->getUpdatefreq(); + int showfreq = (updatefreq*100)/500; + ui->label_2->setText(QString::number(updatefreq)); + ui->horizontalSlider->setValue(showfreq); + } + } + else + { + ui->label_2->setText("500"); + ui->horizontalSlider->setValue(100); + } + } +} + + +/* + * Going to run a new vncthread with quality: quality + */ +void MainWindow::setVNCQuality(int quality) +{ + std::list<QString>* selClients = getConnectionList()->getSelectedClients(); + if (selClients->size() > 0) + { + for (std::list<QString>::iterator client = selClients->begin(); client + != selClients->end(); client++) + { + PVSClient* pvsClient = + PVSConnectionManager::getManager()->getClientFromIp( + (*client).toUtf8().data()); + pvsClient->getConnectionFrame()->resetConnectionWithQuality(quality); + pvsClient->getConnectionFrame()->update(); + } + } + else + { + QList<ConnectionFrame*> FrameList = MainWindow::getConnectionWindow()->getFrameList(); + foreach(ConnectionFrame* frame, FrameList) + { + frame->resetConnectionWithQuality(quality); + frame->update(); + } + } + +} + + +void MainWindow::setPasswordForConnection(int enabled) +{ + if(enabled == 0)//the checkbox isn't checked, so no passowrd needed, we remove it in the titlebar + { + QString dummy = PVSConnectionManager::getManager()->setNeedPassword(false); + _sessionName = PVSConnectionManager::getManager()->getSessionName(); + QString title = "PVSmgr - "; + title.append(_profilName); + title.append(" ["+_sessionName + " : ]"); + setWindowTitle(title); + } + else if (enabled == 2) //password is needed, we show it in the titlebar + { + _pwdCon = PVSConnectionManager::getManager()->setNeedPassword(true); + _sessionName = PVSConnectionManager::getManager()->getSessionName(); + QString title = "PVSmgr - "; + title.append(_profilName); + title.append(" ["+_sessionName + " : "); + title.append(_pwdCon+"]"); + setWindowTitle(title); + } +} +//#endif + + +void MainWindow::setindexback() //sets the index of the combobox back +{ +#ifdef MAINWINDOW_USE_TOUCHGUI + ui->comboBox_touch1->setCurrentIndex(0); +#endif +} + +void MainWindow::clientlisthide() // hide or show the clientlist +{ + + if (locked1 == false) + { + ui->ClWidget->show(); + locked1 = true; + } + + else + { + ui->ClWidget->hide(); + locked1 = false; + } + +} + + +void MainWindow::lockalltoolbar() // locks all if a dozent is set +{ + + + if (locked == false) + { + if (MainWindow::getConnectionWindow()->hasDozent) + { + MainWindow::getConnectionList()->on_lock_all(); + locked = true; + } + else + { + QString message = QString(tr("You have to set a Superclient-machine before performing this action.")); + QMessageBox::information(this, "PVS", message); + } + } + + else + { + MainWindow::getConnectionList()->on_unlock_all(); + locked = false; + } + +} + +void MainWindow::locksingle() // locks a single client +{ + + MainWindow::getConnectionList()->on_lock(); + +} + +void MainWindow::unlocksingle() // unlocks a single client +{ + + MainWindow::getConnectionList()->on_unlock(); + +} + + +void MainWindow::combobox1(int menuindex1) // defines the functions to call from the combobox +{ + switch (menuindex1) + // index comes from the slot definition + { + case 1: + // Lock all + MainWindow::getConnectionList()->on_lock_all(); + break; + + case 2: + // UnLock all + MainWindow::getConnectionList()->on_unlock_all(); + break; + + case 3: + // UnProject all + MainWindow::getConnectionList()->on_unproject_all(); + break; + + case 4: + //Background Picture + backgroundpicture(); + break; + } +} + +void MainWindow::resetall() // unlock and unproject all in toolbar + { + MainWindow::getConnectionList()->on_unlock_all(); + MainWindow::getConnectionList()->on_unproject_all(); + } + + +void MainWindow::projecttoolbar() // projection from toolbar button + { + + MainWindow::getConnectionList()->on_projection(); + + } +void MainWindow::unprojecttoolbar() // unproject all in toolbar + { + + MainWindow::getConnectionList()->on_unprojection(); + + } + +void MainWindow::backgroundpicture() + { + + + fileName = QFileDialog::getOpenFileName(this, + tr("Open Image"), "/home", tr("Image Files (*.png *.jpg *.svg)")); // user chooses a file + + QImage img(""+fileName+""); // set image + QString test("/tmp/test.png"); // set path for saving the scaled picture + QImage img2 = img.scaled(ui->widget->size(),Qt::IgnoreAspectRatio,Qt::FastTransformation); // scale it + + img2.save(""+test+""); // save it + + ui->widget->setStyleSheet("background-image: url(/tmp/test.png);background-repeat:no-repeat; background-position:center;"); //set the picture as background + foreach (ConnectionFrame* cf, MainWindow::getConnectionWindow()->getAllFrameOnWindow()) + { + cf->setStyleSheet(QString::fromUtf8("background-color: rgb(150, 150, 168);")); + } + + bgimage=true; // for the resize event, set background true + + + } + +void MainWindow::repaintbackgroundpicture() // same as backgroundpicture but called when mainwindow is resized + { + + QImage img("/tmp/test.png"); + QString test("/tmp/test.png"); + QImage img2 = img.scaled(ui->widget->size(),Qt::IgnoreAspectRatio,Qt::FastTransformation); + + img2.save(""+test+""); + + ui->widget->setStyleSheet("background-image: url(/tmp/test.png);background-repeat:no-repeat; background-position:center;"); + + + } + +void MainWindow::setdozenttoolbar() // set the dozents pc which is not locked with lockedall +{ + + std::list<QString>* selectedClients = + MainWindow::getConnectionList()->getSelectedClients(); + + if (selectedClients->size() == 1) + { + + PVSClient* pvsClient = + PVSConnectionManager::getManager()->getClientFromIp( + selectedClients->front().toStdString().c_str()); + if (pvsClient->getVNCConnection()) + pvsClient->getConnectionFrame()->getFrame()->setDozent(); + } + +} + +void MainWindow::startChatDialog() +{ + if (!sChatDialog.isVisible()) + sChatDialog.show(); //show the chat dialog + else + sChatDialog.raise();//show the chat dialog on top level +} + + + +MainWindow* MainWindow::myself = NULL; +ConnectionList* MainWindow::conList = NULL; +ConnectionWindow* MainWindow::conWin = NULL; +bool MainWindow::_isLockAll = false; diff --git a/src/gui/mainWindow.h b/src/gui/mainWindow.h new file mode 100644 index 0000000..00bd927 --- /dev/null +++ b/src/gui/mainWindow.h @@ -0,0 +1,200 @@ +#ifndef _MAINWINDOW_H_ +#define _MAINWINDOW_H_ + +#include <QtGui> +#include <QtNetwork> +#include <QMainWindow> +#include <QFileDialog> +#include <src/gui/connectionList.h> +#include <src/util/consoleLogger.h> +#include <src/gui/connectionWindow.h> +#include <src/gui/profileDialog.h> +//#include <src/gui/dialog.h> +#include <src/core/pvsClient.h> +#include <src/core/pvsConnectionManager.h> +#include "src/gui/aboutDialog.h" +#include "src/gui/serverChatDialog.h" +#include <src/gui/serverFileTransfert.h> + + +namespace Ui +{ +class MainWindow; +} + + +class PVSClient; +class ConnectionList; +class ConnectionWindow; +class profileDialog; +class ServerChatDialog; +//class Dialog; + + +class MainWindow : public QMainWindow +{ + friend class PVSConnectionManager; + + Q_OBJECT + + +public: + MainWindow(QWidget *parent = 0); + ~MainWindow(); + + //singleton methods + static MainWindow* getWindow(); + static ConnectionWindow* getConnectionWindow(); + static ConnectionList* getConnectionList(); + + ServerChatDialog sChatDialog; + + + int getConnectionWindowWidth(); + int getConnectionWindowHeight(); + int x,y; + QImage img; + QImage img2; + QString test; + QStringList profilList; + QStringList getProfilList(); + void addProfileInMenu(QString name); + void removeProfileInMenu(QString name); + QString currentProfi; + QString getCurrentProfi() + { + return currentProfi; + } + void loadSettings(); + void loadSettings(QString profilname); + void saveSettings(QString profilname); + void removeProfil(QString profilname); + + // connection add/remove and dialog methods + void addConnection(PVSClient* newCon); + void removeConnection(PVSClient* newCon); + //ConnectionFrame* getNewFrame(); + void onConnectionFailed(QString host = ""); + void onConnectionTerminated(PVSClient* newConnection); + void onConnectionRemoved(PVSClient* newConnection); + void onPasswordFailed(QString Qhost = ""); + + void sendChatMsg(PVSMsg myMsg); + void receiveChatMsg(QString nick_from, QString nick_to, QString msg); + + // view mode related methods + unsigned int getGlobalFrameRate(); + void setGlobalFrameRate(unsigned int newRate); + int getPrevWidth(); + void setPrevWidth(int newWidth); + int getPrevHeight(); + void setPrevHeight(int newHeight); + + // int createMsgDiag(); + void setMsgDialog(QString msgd){msgDialog = msgd;}; + QString getMsgDialog(){return msgDialog;}; + + bool isLockAllStatus() + { + return _isLockAll; + } + + void appendLogMsg(); + + + +protected: + void closeEvent(QCloseEvent *e); + void changeEvent(QEvent *e); + void resizeEvent(QResizeEvent *event); //We need this to resize the frame in the window when window are resized. + void updatePos(ConnectionFrame* cf, int x, int y); + virtual void on_log_line(LogEntry consoleEntry); + + + + +private: + Ui::MainWindow *ui; + static ConnectionWindow* conWin; + static ConnectionList* conList; + //Dialog messageDiag; + static MainWindow* myself; + QString _pwdCon; + QString _sessionName; + QString _profilName; + + QStringList _chatListClients; + + + + /*ConnectionDialog* myConDiag; + ConnectionDialog* pwDiag; + ConnectionDialog* messageDiag;*/ + + AboutDialog *_aboutDialog; + + QString msgDialog; + bool bgimage; + bool locked, locked1; + bool force_square; + bool is_fullscreen; + bool is_closeup; + static bool _isLockAll; + bool showError, showNormal, showNetwork, showTerminal, showChat, showAtAll; + bool isDozent; + QString fileName; + + int _initW, _initH, _firstResize; + + unsigned int updateRate, frameRate; + int prev_width, prev_height, menuindex1, menuindex2; + + QTcpServer *_serverSocket; + QPoint _framePosOnCloseUp; + + bool _isThumbnailrate; + int _updatefreq; + QString _oldRatio; + + QMenu* _profileMenuList; + QMap<QString, QAction*> _mapProfileToAction; + +public slots: + void loadProfile(QAction* actiontriggered); + void setindexback(); + //void setindexback2(); + void lockalltoolbar(); + void resetall(); + void locksingle(); + void unlocksingle(); + void clientlisthide(); + void projecttoolbar(); + void unprojecttoolbar(); + void closeUp(); + void foto(); + void backgroundpicture(); + void repaintbackgroundpicture(); + void setdozenttoolbar(); + void startChatDialog(); + +private slots: + void onToggleLog(bool showtime); + void setLogConsoleDisabled(bool visible); + //void close(); + void disconnect(); + void lockUnlockAll(); + void createProfile(); + void showusername(); + void showname(); + void showip(); + void incomingFile(); + void changeRatio(int ratio); + void changeStatus (int index); + void setVNCQuality(int quality); + 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 +}; + + +#endif diff --git a/src/gui/profileDialog.cpp b/src/gui/profileDialog.cpp new file mode 100644 index 0000000..2cbc155 --- /dev/null +++ b/src/gui/profileDialog.cpp @@ -0,0 +1,179 @@ +/* + # 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/ + # ----------------------------------------------------------------------------- + # profileDialog.cpp + # - GUI to define the profile. + # ----------------------------------------------------------------------------- + */ + +#include "profileDialog.h" +#include "ui_profileDialog.h" +#include <src/gui/mainWindow.h> +#include <iostream> + +profileDialog::profileDialog(QWidget * parent): + QDialog(parent), + uidiag(new Ui::Dialog) +{ + uidiag->setupUi(this); + content = new QTableView(uidiag->widget); + uidiag->gridLayout->addWidget(content); + + /*Das Modelfestlegen, wo die Clientname angezeigt werden.*/ + model = new QStandardItemModel(0,1,content); //Leere Tabelle mit einer Spalte erstellen + model->setHeaderData(0, Qt::Horizontal, tr("Profile")); //Spalte name definieren + content->setModel(model); + + QItemSelectionModel *selectionModel = new QItemSelectionModel(model); + content->setSelectionModel(selectionModel); + QHeaderView *headerView = content->horizontalHeader(); + headerView->setStretchLastSection(true); + + content->setEditTriggers(QAbstractItemView::NoEditTriggers); //Die Einträge in der Tabelle werden nicht editierbar. + content->setSelectionMode(QAbstractItemView::ExtendedSelection); //Damit mehere Einträge selektierbar werden. + + content->resizeColumnToContents(0); + + + + uidiag->add->setDisabled(true); + uidiag->edit->setDisabled(true); + uidiag->edit->setVisible(false); + uidiag->remove->setDisabled(true); + uidiag->load->setDisabled(true); + uidiag->lineEdit->setDisabled(true); + + setUpProfile(); + + connect(uidiag->add, SIGNAL(clicked ()), this, SLOT(AddProfile())); + connect(uidiag->new_2, SIGNAL(clicked ()), this, SLOT(onNew())); + connect(uidiag->load, SIGNAL(clicked ()), this, SLOT(onLoad())); + connect(uidiag->remove, SIGNAL(clicked ()), this, SLOT(removeProfile())); + connect(uidiag->close, SIGNAL(clicked ()), this, SLOT(accept())); + connect(content, SIGNAL(clicked(const QModelIndex)), this, SLOT(selectionChange(const QModelIndex))); + //show(); + +} + +profileDialog::~profileDialog() +{ + // TODO Auto-generated destructor stub +} + +void profileDialog::setUpProfile() +{ + QStringList list = MainWindow::getWindow()->getProfilList(); + for (int i=0; i<list.size(); i++) + { + model->insertRow(0, QModelIndex()); + model->setData(model->index(0, 0, QModelIndex()),list.at(i)); + } +} + +void profileDialog::AddProfile() +{ + QString name = QString(uidiag->lineEdit->text()); + if (!ProfilList.contains(name)) + { + if (!name.isEmpty()) + { + model->insertRow(0, QModelIndex()); + model->setData(model->index(0, 0, QModelIndex()),name); + ProfilList.append(name); + MainWindow::getWindow()->saveSettings(name); + uidiag->lineEdit->setText(""); + } + else + { + QString message = QString(tr("This field can't be empty.")); + QMessageBox::information(this, "PVS", message); + } + } + else + { + QString message = QString(tr("This name is already in the list.")); + QMessageBox::information(this, "PVS", message); + } +} + +void profileDialog::removeProfile() +{ + QTableView *temp = static_cast<QTableView*>(content); + QItemSelectionModel *selectionModel = temp->selectionModel(); + + QModelIndexList indexes = selectionModel->selectedRows(); + QModelIndex index; + + foreach(index, indexes) + { + int row = content->currentIndex().row(); + QString current = model->index(content->currentIndex().row(), 0).data(Qt::DisplayRole).toString(); + model->removeRow(row, QModelIndex()); + ProfilList.removeOne(current); + MainWindow::getWindow()->removeProfil(current); + } + + + /* if (temp->model()->rowCount()<=0) + {*/ + uidiag->remove->setDisabled(true); + uidiag->edit->setDisabled(true); + uidiag->add->setDisabled(true); + uidiag->load->setDisabled(true); + //} +} + +void profileDialog::onNew() +{ + uidiag->add->setDisabled(false); + uidiag->lineEdit->setDisabled(false); + uidiag->lineEdit->setFocus(); +} + +void profileDialog::onLoad() +{ + QTableView *temp = static_cast<QTableView*>(content); + QItemSelectionModel *selectionModel = temp->selectionModel(); + + QModelIndexList indexes = selectionModel->selectedRows(); + QModelIndex index; + if (indexes.size()>1) + { + QMessageBox::information(this, "PVS", tr("You can only load one profile at time")); + } + else if(indexes.size() == 1) + { + foreach(index, indexes) + { + //int row = content->currentIndex().row(); + QString current = model->index(content->currentIndex().row(), 0).data(Qt::DisplayRole).toString(); + MainWindow::getWindow()->loadSettings(current); + } + } + + emit accept(); +} + +void profileDialog::selectionChange(const QModelIndex & index) +{ + uidiag->remove->setDisabled(false); + uidiag->edit->setDisabled(false); + uidiag->add->setDisabled(false); + uidiag->load->setDisabled(false); + +} + +void profileDialog::close() +{ + close(); +} + + diff --git a/src/gui/profileDialog.h b/src/gui/profileDialog.h new file mode 100644 index 0000000..5caebfa --- /dev/null +++ b/src/gui/profileDialog.h @@ -0,0 +1,46 @@ +#ifndef PROFILEDIALOG_H_ +#define PROFILEDIALOG_H_ + +#include <QtGui> +#include <QDialog> +#include <src/gui/mainWindow.h> + +namespace Ui +{ +class Dialog; +} + +class MainWindow; + +class profileDialog : public QDialog +{ + Q_OBJECT + +public: + profileDialog(QWidget * parent = 0); + virtual ~profileDialog(); + + void setUpProfile(); + + + +signals: + void selectionChanged (const QItemSelection &selected); + +private: + Ui::Dialog *uidiag; + QTableView *content; + QAbstractItemModel *model; + QItemSelectionModel *selectionModel; + QList<QString> ProfilList; + +private Q_SLOTS: + void AddProfile(); + void removeProfile(); + void onNew(); + void onLoad(); + void selectionChange(const QModelIndex & index); + void close(); +}; + +#endif /* PROFILEDIALOG_H_ */ diff --git a/src/gui/projectionDialog.cpp b/src/gui/projectionDialog.cpp new file mode 100644 index 0000000..c091f54 --- /dev/null +++ b/src/gui/projectionDialog.cpp @@ -0,0 +1,140 @@ +/* +# 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/ +# ----------------------------------------------------------------------------- +# projectionDialog.cpp + Dialog to select client for the projection +# ----------------------------------------------------------------------------- +*/ + +#include "projectionDialog.h" +#include "ui_projectionDialog.h" +#include <src/gui/mainWindow.h> +#include <QtGui> +#include <iostream> + +ProjectionDialog::ProjectionDialog(QWidget *parent) : + QDialog(parent), + pui(new Ui::projectionDialog) +{ + pui->setupUi(this); + this->setWindowTitle(tr("Target for Projection")); + + source = MainWindow::getConnectionList()->getSelectedClients()->front(); + setupContent(MainWindow::getWindow()->getConnectionList()->getTargetToDisplay(source)); + + pui->send->setDisabled(true); + + connect( pui->send, SIGNAL( clicked() ), this, SLOT( sendListToProject() ) ); + connect( pui->cancel, SIGNAL( clicked() ), this, SLOT( cancelProject() ) ); + connect( pui->checkBox, SIGNAL( clicked() ), this, SLOT( selectAll() ) ); +} + +ProjectionDialog::~ProjectionDialog() +{ + delete pui; + QCheckBox* cbox; + foreach(cbox, checkList) + { + disconnect( cbox, SIGNAL( clicked() ), this, SLOT( sendState() ) ); + } +} + +void ProjectionDialog::setupContent(QList<QString> content) +{ + if (!content.isEmpty()) + { + QString item; + foreach(item, content) + { + QCheckBox *checkbox = new QCheckBox(item,this); + pui->verticalLayout_2->addWidget(checkbox); + checkList.push_back(checkbox); + connect( checkbox, SIGNAL( clicked() ), this, SLOT( sendState() ) ); + } + } + else + { + QLabel *textInfo = new QLabel(this); + textInfo->setText("No Target available"); + pui->verticalLayout_2->addWidget(textInfo); + pui->checkBox->setDisabled(true); + } +} + +void ProjectionDialog::sendListToProject() +{ + MainWindow::getConnectionList()->setProjectProporties(source); + QCheckBox* cbox; + + foreach(cbox, checkList) + { + if (cbox->isChecked()) + { + MainWindow::getConnectionList()->addTargetToProjectList(cbox->text()); + } + } + emit accept(); +} + +void ProjectionDialog::cancelProject() +{ + emit reject(); +} + +void ProjectionDialog::sendState() +{ + QCheckBox* cbox; + bool set = false; + + foreach(cbox, checkList) + { + if (cbox->isChecked()) + { + pui->send->setDisabled(false); + set = true; + break; + } + } + + if (!set) + pui->send->setDisabled(true); + +} + +void ProjectionDialog::selectAll() +{ + if(pui->checkBox->isChecked()) + { + QCheckBox* cbox; + foreach(cbox, checkList) + cbox->setChecked(true); + pui->send->setDisabled(false); + } + else + { + QCheckBox* cbox; + foreach(cbox, checkList) + cbox->setChecked(false); + pui->send->setDisabled(true); + } +} + +void ProjectionDialog::changeEvent(QEvent *e) +{ + QDialog::changeEvent(e); + switch (e->type()) { + case QEvent::LanguageChange: + pui->retranslateUi(this); + break; + default: + break; + } +} diff --git a/src/gui/projectionDialog.h b/src/gui/projectionDialog.h new file mode 100644 index 0000000..842d255 --- /dev/null +++ b/src/gui/projectionDialog.h @@ -0,0 +1,46 @@ +/* + * projectionDialog.h + * + * Created on: 28.02.2010 + * Author: achillenana + */ + +#ifndef PROJECTIONDIALOG_H_ +#define PROJECTIONDIALOG_H_ + +#include <QDialog> +#include <QCheckBox> +//#include <src/gui/mainWindow.h> + + +class MainWindow; + +namespace Ui { + class projectionDialog; +} + +class ProjectionDialog : public QDialog { + Q_OBJECT +public: + ProjectionDialog(QWidget *parent = 0); + ~ProjectionDialog(); + + void setupContent(QList<QString> content); + +protected: + void changeEvent(QEvent *e); + +private: + Ui::projectionDialog *pui; + std::list<QCheckBox *> checkList; + QString source; + +private slots: + void sendListToProject(); + void cancelProject(); + void sendState(); + void selectAll(); +}; + + +#endif /* PROJECTIONDIALOG_H_ */ diff --git a/src/gui/serverChatDialog.cpp b/src/gui/serverChatDialog.cpp new file mode 100644 index 0000000..ec1f299 --- /dev/null +++ b/src/gui/serverChatDialog.cpp @@ -0,0 +1,281 @@ +/* + # Copyright (c) 2009, 2010 - 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/ + # ----------------------------------------------------------------------------- + # serverChatDialog.cpp + # - graphical chat interface for the pvsmgr + # ----------------------------------------------------------------------------- + */ + +#include "serverChatDialog.h" +#include <src/gui/mainWindow.h> +#include "ui_serverChatDialog.h" + +ServerChatDialog::ServerChatDialog(QWidget *parent) : + QDialog(parent), uichat(new Ui::ServerChatDialogClass) +{ + uichat->setupUi(this); + _nickname = "PVSMGR"; + connect(uichat->pushButton, SIGNAL(clicked()), this, SLOT(chat_send())); + + // add first tab for public messages + uichat->tabWidget->clear(); + QTextEdit *t = new QTextEdit(); + t->setReadOnly(true); + uichat->tabWidget->addTab(t, "@all"); + _hash = new QHash<QString, QTextEdit*> (); + _hash->insert(uichat->tabWidget->tabText(0), t); + + // setup menu + _menu = new QMenu(); + _sendFileAction = new QAction(tr("&Send File..."), this); + _menu->addAction(_sendFileAction); + + connect(uichat->listWidget, SIGNAL(doubleClicked(QModelIndex)), this, + SLOT(addTab(QModelIndex))); + connect(uichat->tabWidget, SIGNAL(tabCloseRequested(int)), this, + SLOT(removeTab(int))); + connect(uichat->tabWidget, SIGNAL(currentChanged(int)), this, SLOT(removeIcon(int))); + connect(uichat->listWidget, SIGNAL(customContextMenuRequested(QPoint)), this, + SLOT(showMenu(QPoint))); + connect(_sendFileAction, SIGNAL(triggered()), this, SLOT(sendFile())); + + this->setAcceptDrops(true); +} + +ServerChatDialog::~ServerChatDialog() +{ +} + +void ServerChatDialog::setTrayIcon(QSystemTrayIcon *trayIcon) +{ + // _trayIcon = trayIcon; + // FIXME: messageClicked() is always emitted, not only on chat msg + //connect(_trayIcon, SIGNAL(messageClicked()), this, SLOT(open())); +} + +//////////////////////////////////////////////////////////////////////////////// +// Slots + +void ServerChatDialog::open() +{ + uichat->lineEdit->setFocus(); + setVisible(true); +} + +void ServerChatDialog::chat_receive(QString nick_from, QString nick_to, + QString msg) +{ + qDebug("[%s] R %s <- %s : %s", metaObject()->className(), + qPrintable(nick_to), qPrintable(nick_from), qPrintable(msg)); + + if (nick_to == uichat->tabWidget->tabText(0)) + showMsg(nick_from, msg, getTab(nick_to)); // public message or own msg + else + { + if (nick_to == "PVSMGR") + showMsg(nick_from, msg, getTab(nick_from)); // private message + else if (nick_from == "PVSMGR") + showMsg(nick_from, msg, getTab(nick_to)); // private message + } +} + +void ServerChatDialog::chat_send() +{ + QString msg = uichat->lineEdit->text(); + if (msg != "") + { + msg = "PVSMGR:"+ msg; + QString nick_to = uichat->tabWidget->tabText(uichat->tabWidget->currentIndex()); + PVSMsg myMsg(PVSMESSAGE, nick_to, msg, 0); + MainWindow::getWindow()->sendChatMsg(myMsg); + uichat->lineEdit->clear(); + uichat->lineEdit->setFocus(); + + qDebug("[%s] S %s -> %s : %s", metaObject()->className(), + qPrintable(_nickname), qPrintable(nick_to), qPrintable(msg)); + + } +} + +void ServerChatDialog::chat_nicklist_update() +{ + uichat->listWidget->clear(); + uichat->listWidget->addItems(_nickList); +} + +void ServerChatDialog::chat_client_add(QString nick) +{ + if (!_nickList.contains(nick)) + _nickList.append(nick); + showEvent("-> " + nick + tr(" has joined the chat.")); +} + +void ServerChatDialog::chat_client_remove(QString nick) +{ + _nickList.removeOne(nick); + showEvent("<- " + nick + tr(" has left the chat.")); +} + +void ServerChatDialog::addTab(QModelIndex i) +{ + QString text = i.data().toString(); + if (_hash->contains(text)) + { + uichat->tabWidget->setCurrentWidget(_hash->value(text)); + } + else + { + QTextEdit *t = new QTextEdit(); + t->setReadOnly(true); + uichat->tabWidget->setCurrentIndex(uichat->tabWidget->addTab(t, text)); + _hash->insert(text, t); + } + uichat->lineEdit->setFocus(); +} + +void ServerChatDialog::removeTab(int i) +{ + if (i != 0) + { + _tabList.removeOne(_hash->value(uichat->tabWidget->tabText(i))); + _hash->remove(uichat->tabWidget->tabText(i)); + uichat->tabWidget->removeTab(i); + uichat->lineEdit->setFocus(); + } +} + +void ServerChatDialog::removeIcon(int i) +{ + uichat->tabWidget->setTabIcon(i, QIcon()); +} + +//////////////////////////////////////////////////////////////////////////////// +// Private + +QTextEdit* ServerChatDialog::getTab(QString text) +{ + if (!_hash->contains(text)) + { + QTextEdit *t = new QTextEdit(); + t->setReadOnly(true); + uichat->tabWidget->addTab(t, text); + _hash->insert(text, t); + _tabList.append(t); + } + uichat->lineEdit->setFocus(); + return _hash->value(text); +} + +void ServerChatDialog::showMsg(QString nick_from, QString msg, QTextEdit *t) +{ + // move cursor at the end + t->moveCursor(QTextCursor::End); + + // print time + if (nick_from == "PVSMGR") + t->setTextColor(QColor(0, 100, 100)); + else + t->setTextColor(QColor(0, 100, 0)); + t->append("[" + QTime::currentTime().toString("hh:mm") + "] "); + + // print nickname + if (nick_from == "PVSMGR") + t->setTextColor(QColor(0, 100, 255)); + else + t->setTextColor(QColor(0, 0, 255)); + t->insertPlainText("<" + nick_from + "> "); + + // print message + if (nick_from == "PVSMGR") + t->setTextColor(QColor(100, 100, 100)); + else + t->setTextColor(QColor(0, 0, 0)); + t->insertPlainText(msg); + + // show icon if not current tab + if (uichat->tabWidget->currentIndex() != uichat->tabWidget->indexOf(t)) + uichat->tabWidget->setTabIcon(uichat->tabWidget->indexOf(t), QIcon(":chat_msg16.svg")); +} + +void ServerChatDialog::showMenu(QPoint p) +{ + _menu->popup(uichat->listWidget->mapToGlobal(p)); +} + +void ServerChatDialog::sendFile() +{ + ServerFileTransfert* sft = new ServerFileTransfert(this); + QString cTab = uichat->listWidget->currentItem()->text(); + QString hostIP = PVSConnectionManager::getManager()->getClientFromUsername(cTab)->getIp(); + if (hostIP != "") + sft->sendFileToHost(hostIP); +} + +void ServerChatDialog::sendFile(QString filename) +{ + if (uichat->tabWidget->currentIndex() == 0 || filename == "") + return; + + // ask user + QString nick = uichat->tabWidget->tabText(uichat->tabWidget->currentIndex()); + QMessageBox::StandardButton result = QMessageBox::question(0, + tr("PVS File Transfer with ")+nick, + tr("Send file '") + filename + tr("' to ") + nick + "?", + QMessageBox::Ok | QMessageBox::Cancel, QMessageBox::Ok); + + if (result != QMessageBox::Ok) + return; + + ServerFileTransfert* sft = new ServerFileTransfert(this); + QString hostIP = PVSConnectionManager::getManager()->getClientFromUsername(nick)->getIp(); + if (hostIP != "") + sft->sendFileToHost(hostIP, filename); +} + + +void ServerChatDialog::showEvent(QString msg) +{ + QTextEdit *t = _hash->value(uichat->tabWidget->tabText(0)); + + // move cursor at the end + t->moveCursor(QTextCursor::End); + + t->setTextColor(QColor(150, 150, 150)); + + // print time + t->append("[" + QTime::currentTime().toString("hh:mm") + "] "); + + // print message + t->insertPlainText(msg); +} + +void ServerChatDialog::dragEnterEvent(QDragEnterEvent *event) +{ + event->accept(); +} + +void ServerChatDialog::dragMoveEvent(QDragMoveEvent *event) +{ + event->accept(); +} + +void ServerChatDialog::dragLeaveEvent(QDragLeaveEvent *event) +{ + event->accept(); +} + +void ServerChatDialog::dropEvent(QDropEvent *event) +{ + event->accept(); + if (event->mimeData()->hasUrls()) + sendFile(event->mimeData()->urls()[0].toLocalFile()); +} diff --git a/src/gui/serverChatDialog.h b/src/gui/serverChatDialog.h new file mode 100644 index 0000000..728af05 --- /dev/null +++ b/src/gui/serverChatDialog.h @@ -0,0 +1,67 @@ +#ifndef SERVERCHATDIALOG_H_ +#define SERVERCHATDIALOG_H_ + +#include <QtGui> +#include <src/gui/serverFileTransfert.h> +#include "pvsinterface.h" + +class MainWindow; + +namespace Ui +{ + class ServerChatDialogClass; +} + +class ServerChatDialog: public QDialog +{ + Q_OBJECT + +public: + ServerChatDialog(QWidget *parent = 0); + ~ServerChatDialog(); + void setTrayIcon(QSystemTrayIcon *trayIcon); + void chat_nicklist_update(); + void chat_client_add(QString nick); + void chat_client_remove(QString nick); + +public Q_SLOTS: + void open(); + void chat_receive(QString nick_from, QString nick_to, QString msg); + void chat_send(); + + +private Q_SLOTS: + void addTab(QModelIndex i); + void sendFile(); + void showMenu(QPoint p); + void removeTab(int i); + void removeIcon(int i); + +private: + Ui::ServerChatDialogClass *uichat; + QTextEdit* getTab(QString text); + void showMsg(QString nick_from, QString msg, QTextEdit *t); + void sendFile(QString filename); + void showEvent(QString msg); + + QList<QTextEdit *> _tabList; + + QHash<QString, QTextEdit*> *_hash; + + QString _nickname; + QStringList _nickList; + + QMenu* _menu; + QAction* _sendFileAction; + +protected: + void dragEnterEvent(QDragEnterEvent *event); + void dragMoveEvent(QDragMoveEvent *event); + void dragLeaveEvent(QDragLeaveEvent *event); + void dropEvent(QDropEvent *event); + +}; + + + +#endif /* SERVERCHATDIALOG_H_ */ diff --git a/src/gui/serverFileTransfert.cpp b/src/gui/serverFileTransfert.cpp new file mode 100644 index 0000000..22e268b --- /dev/null +++ b/src/gui/serverFileTransfert.cpp @@ -0,0 +1,265 @@ +/* +# 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/serverFileTransfert.cpp +# This class manage any file transfert from and to server. +# ----------------------------------------------------------------------------- +*/ + +#include "serverFileTransfert.h" + +ServerFileTransfert::ServerFileTransfert(QWidget *parent): + QDialog(parent) +{ + setupUi(this); + _file = NULL; + _socket = NULL; + + connect(this, SIGNAL(finished(int)), this, SLOT(deleteLater())); +} + +ServerFileTransfert::~ServerFileTransfert() +{ +} + +void ServerFileTransfert::sendFileToHost(QString host) +{ + QString filename = QFileDialog::getOpenFileName(this, tr("Open File"), + QDir::homePath(), ""); + if (filename == "") + { + reject(); + return; + } + sendFileToHost(host, filename); +} + +void ServerFileTransfert::sendFileToHost(QString host, QString filename) +{ + // open file + _file = new QFile(filename); + _file->open(QIODevice::ReadOnly); + _bytesToWrite = _file->size(); + div = 1 + _bytesToWrite / 1000000000; // bc. progressBar supports only int + + // get host from backend + + // gui + filenameLabel->setText(filename); + progressBar->setValue(0); + progressBar->setMaximum(_bytesToWrite/div); + labelB->setText(formatSize(_bytesToWrite)); + connect(cancelButton, SIGNAL(clicked()), this, SLOT(close())); + + // open socket + _socket = new QTcpSocket(); + _socket->connectToHost(host, 29481); + if (_socket->isOpen()) + qDebug("connection open"); + else + qDebug("connection closed"); + qDebug("[%s] Remote host: %s", metaObject()->className(), qPrintable(host)); + + connect(_socket, SIGNAL(connected()), this, SLOT(sendHeader())); + connect(_socket, SIGNAL(disconnected()), this, SLOT(close())); + connect(_socket, SIGNAL(error(QAbstractSocket::SocketError)), + this, SLOT(error(QAbstractSocket::SocketError))); + qDebug("connect is set"); +} + +void ServerFileTransfert::receiveFileFromHost(QTcpSocket* socket) +{ + + _bytesToRead = 0; + _socket = socket; + + connect(_socket, SIGNAL(readyRead()), this, SLOT(receiveHeader())); + connect(_socket, SIGNAL(disconnected()), this, SLOT(close())); + connect(_socket, SIGNAL(error(QAbstractSocket::SocketError)), + this, SLOT(error(QAbstractSocket::SocketError))); + + qDebug("[%s] New Connection: %s", metaObject()->className(), + qPrintable(_socket->peerAddress().toString())); +} + +void ServerFileTransfert::sendHeader() +{ + qDebug("[%s] Sending header(1)...", metaObject()->className()); + QFileInfo info(_file->fileName()); + QString size = QString::number(_bytesToWrite); + QString header = "PVSMGR;" + info.fileName() + ";" + size + "\n"; + _socket->write(header.toLocal8Bit()); + connect(_socket, SIGNAL(readyRead()), this, SLOT(receiveAck())); + qDebug("[%s] Sending header...", metaObject()->className()); +} + +void ServerFileTransfert::receiveHeader() +{ + // parse header + QString header = QString::fromUtf8(_socket->readLine()); + QStringList args = header.split(";"); + QString nick = args[0]; + QString filename = args[1]; + _bytesToRead = args[2].toLongLong(); + div = 1 + _bytesToRead / 1000000000; // bc. progressBar supports only int + + qDebug("[%s] Received header.", metaObject()->className()); + + // ask user + QMessageBox::StandardButton result = QMessageBox::question(0, + tr("PVS File Transfer"),tr("User '") + nick + + tr("' would like to send you a file: ") + filename + + " (" + formatSize(_bytesToRead) + ").", + QMessageBox::Ok | QMessageBox::Cancel, QMessageBox::Ok); + + if (result != QMessageBox::Ok) + { + sendAck(false); + return; + } + + // open file + QString saveAs = QFileDialog::getSaveFileName(this, tr("Open File"), + QDir::homePath() + QDir::separator() + filename, ""); + if (saveAs == "") + { + sendAck(false); + return; + } + _file = new QFile(saveAs); + _file->open(QIODevice::WriteOnly); + + // gui + filenameLabel->setText(saveAs); + progressBar->setValue(0); + progressBar->setMaximum(_bytesToRead/div); + labelB->setText(formatSize(_bytesToRead)); + connect(cancelButton, SIGNAL(clicked()), this, SLOT(close())); + + sendAck(true); + show(); +} + +void ServerFileTransfert::sendAck(bool b) +{ + disconnect(_socket, SIGNAL(readyRead()), this, SLOT(receiveHeader())); + + if (b) + { + QString ack = QString("ok\n"); + _socket->write(ack.toUtf8()); + qDebug("[%s] Sending ack...", metaObject()->className()); + connect(_socket, SIGNAL(readyRead()), this, SLOT(receiveFile())); + } + else + { + QString ack = QString("no\n"); + _socket->write(ack.toUtf8()); + qDebug("[%s] Sending nack!!!", metaObject()->className()); + close(); + } +} + +void ServerFileTransfert::receiveAck() +{ + QString ack = QString::fromUtf8(_socket->readLine()); + if (ack != "ok\n") + { + qDebug("[%s] Received nack!", metaObject()->className()); + close(); + return; + } + qDebug("[%s] Received ack.", metaObject()->className()); + + disconnect(_socket, SIGNAL(readyRead()), this, SLOT(receiveAck())); + connect(_socket, SIGNAL(bytesWritten(qint64)), this, SLOT(sendFile())); + this->show(); + qDebug("[%s] Sending file...", metaObject()->className()); + sendFile(); +} + +void ServerFileTransfert::sendFile() +{ + if (_bytesToWrite == 0) + { + qDebug("[%s] Transfer completed.", metaObject()->className()); + close(); // finished + } + else + { + qint64 bytesWritten = _socket->write(_file->read(1024)); // data left + _bytesToWrite -= bytesWritten; + progressBar->setValue(progressBar->value() + bytesWritten/div); + labelA->setText(formatSize(progressBar->value()*div)); + } +} + +void ServerFileTransfert::receiveFile() +{ + qint64 bytesRead = _file->write(_socket->readAll()); + _bytesToRead -= bytesRead; + progressBar->setValue(progressBar->value() + bytesRead/div); + labelA->setText(formatSize(progressBar->value()*div)); +} + +void ServerFileTransfert::close() +{ + 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())); + + if (_bytesToWrite == 0) + { + accept(); + QMessageBox::information(0, tr("PVS - File Transfer"), + tr("File Transfer complete.")); + } + else + { + reject(); + QMessageBox::warning(0, tr("PVS - File Transfer"), + tr("File Transfer canceled!")); + } +} + +void ServerFileTransfert::error(QAbstractSocket::SocketError error) +{ + qDebug("[%s] Socket error: %i", metaObject()->className(), error); + close(); +} + +QString ServerFileTransfert::formatSize(qint64 size) +{ + if (size >= 1000000000) // GB + return QString("%1GB").arg((qreal)size / 1000000000, 0, 'f',1); + else if (size >= 1000000) // MB + return QString("%1MB").arg((qreal)size / 1000000, 0, 'f',1); + else if (size >= 1000) // KB + return QString("%1KB").arg((qreal)size / 1000, 0, 'f',1); + else // B + return QString("%1B").arg((qreal)size, 0, 'f',1); +} diff --git a/src/gui/serverFileTransfert.h b/src/gui/serverFileTransfert.h new file mode 100644 index 0000000..96b30e5 --- /dev/null +++ b/src/gui/serverFileTransfert.h @@ -0,0 +1,52 @@ +#ifndef SERVERFILETRANSFERT_H_ +#define SERVERFILETRANSFERT_H_ + + +#include <QtGui> +#include <QtNetwork> +#include "ui_clientFileSendDialog.h" + +/*namespace Ui +{ + class ClientFileSendDialogClass; +}*/ + +class ServerFileTransfert: public QDialog, + private Ui::ClientFileSendDialogClass + +{ + Q_OBJECT + +public: + ServerFileTransfert (QWidget *parent=0); + ~ServerFileTransfert (); + + void sendFileToHost(QString host); + void sendFileToHost(QString host, QString filename); + void receiveFileFromHost(QTcpSocket* socket); + + //Ui::ClientFileSendDialogClass* uitr; + +private Q_SLOTS: + void sendHeader(); + void receiveHeader(); + void receiveAck(); + void sendFile(); + void receiveFile(); + void close(); + void error(QAbstractSocket::SocketError error); + +private: + void sendAck(bool b); + QString formatSize(qint64 size); + + QTcpSocket *_socket; + QFile *_file; + qint64 _bytesToWrite; + qint64 _bytesToRead; + int div; + +}; + + +#endif /* SERVERFILETRANSFERT_H_ */ diff --git a/src/gui/ui/aboutDialog.ui b/src/gui/ui/aboutDialog.ui new file mode 100644 index 0000000..07d9852 --- /dev/null +++ b/src/gui/ui/aboutDialog.ui @@ -0,0 +1,251 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>AboutDialogClass</class> + <widget class="QDialog" name="AboutDialogClass"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>460</width> + <height>363</height> + </rect> + </property> + <property name="windowTitle"> + <string>PVS - About</string> + </property> + <property name="windowIcon"> + <iconset resource="../../../pvsgui.qrc"> + <normaloff>:/cam32.svg</normaloff>:/cam32.svg</iconset> + </property> + <property name="locale"> + <locale language="English" country="UnitedStates"/> + </property> + <layout class="QVBoxLayout" name="verticalLayout_2"> + <item> + <layout class="QHBoxLayout" name="horizontalLayout_2"> + <item> + <spacer name="horizontalSpacer_2"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>40</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + <item> + <widget class="QLabel" name="label_7"> + <property name="text"> + <string/> + </property> + <property name="pixmap"> + <pixmap resource="../../../pvsgui.qrc">:/cam32.svg</pixmap> + </property> + </widget> + </item> + <item> + <widget class="QLabel" name="label_5"> + <property name="text"> + <string notr="true"><!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:'DejaVu Sans'; font-size:9pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:24pt; font-weight:600;">PVS</span></p></body></html></string> + </property> + </widget> + </item> + <item> + <spacer name="horizontalSpacer_3"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>40</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + </layout> + </item> + <item> + <layout class="QHBoxLayout" name="horizontalLayout_3"> + <item> + <spacer name="horizontalSpacer_4"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>40</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + <item> + <widget class="QLabel" name="label_version"> + <property name="text"> + <string notr="true">Version: xx.xx.xx</string> + </property> + </widget> + </item> + <item> + <spacer name="horizontalSpacer_5"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>40</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + </layout> + </item> + <item> + <widget class="QTabWidget" name="tabWidget"> + <property name="currentIndex"> + <number>0</number> + </property> + <widget class="QWidget" name="tab"> + <attribute name="title"> + <string>About</string> + </attribute> + <layout class="QVBoxLayout" name="verticalLayout"> + <item> + <widget class="QLabel" name="label_2"> + <property name="text"> + <string notr="true">Pool Video Switch</string> + </property> + </widget> + </item> + <item> + <widget class="QLabel" name="label_3"> + <property name="text"> + <string notr="true">feedback@openslx.org</string> + </property> + </widget> + </item> + <item> + <widget class="QLabel" name="label_4"> + <property name="text"> + <string notr="true">(c) 2009-2010, OpenSLX Project, University of Freiburg</string> + </property> + </widget> + </item> + <item> + <widget class="QLabel" name="label"> + <property name="text"> + <string notr="true"><a href="http://lab.openslx.org/projects/pvs">http://lab.openslx.org/projects/pvs</a></string> + </property> + <property name="openExternalLinks"> + <bool>true</bool> + </property> + </widget> + </item> + <item> + <widget class="QLabel" name="label_6"> + <property name="text"> + <string><a href="http://www.gnu.org/licenses/gpl-2.0.txt">License: GNU General Public License Version 2</a></string> + </property> + <property name="openExternalLinks"> + <bool>true</bool> + </property> + </widget> + </item> + </layout> + </widget> + <widget class="QWidget" name="tab_1"> + <attribute name="title"> + <string>Authors</string> + </attribute> + <layout class="QVBoxLayout" name="verticalLayout_3"> + <item> + <widget class="QPlainTextEdit" name="plainTextEdit_authors"> + <property name="lineWrapMode"> + <enum>QPlainTextEdit::NoWrap</enum> + </property> + <property name="readOnly"> + <bool>true</bool> + </property> + <property name="plainText"> + <string/> + </property> + <property name="centerOnScroll"> + <bool>false</bool> + </property> + </widget> + </item> + </layout> + </widget> + <widget class="QWidget" name="tab_2"> + <attribute name="title"> + <string>Translation</string> + </attribute> + <layout class="QVBoxLayout" name="verticalLayout_4"> + <item> + <widget class="QPlainTextEdit" name="plainTextEdit_translation"> + <property name="readOnly"> + <bool>true</bool> + </property> + </widget> + </item> + </layout> + </widget> + </widget> + </item> + <item> + <layout class="QHBoxLayout" name="horizontalLayout"> + <item> + <spacer name="horizontalSpacer"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>40</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + <item> + <widget class="QDialogButtonBox" name="buttonBox"> + <property name="standardButtons"> + <set>QDialogButtonBox::Close</set> + </property> + </widget> + </item> + </layout> + </item> + </layout> + </widget> + <resources> + <include location="../../../pvsgui.qrc"/> + </resources> + <connections> + <connection> + <sender>buttonBox</sender> + <signal>rejected()</signal> + <receiver>AboutDialogClass</receiver> + <slot>reject()</slot> + <hints> + <hint type="sourcelabel"> + <x>388</x> + <y>351</y> + </hint> + <hint type="destinationlabel"> + <x>109</x> + <y>333</y> + </hint> + </hints> + </connection> + </connections> +</ui> diff --git a/src/gui/ui/clientChatDialog.ui b/src/gui/ui/clientChatDialog.ui new file mode 100644 index 0000000..43f64a9 --- /dev/null +++ b/src/gui/ui/clientChatDialog.ui @@ -0,0 +1,121 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>ClientChatDialogClass</class> + <widget class="QDialog" name="ClientChatDialogClass"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>641</width> + <height>659</height> + </rect> + </property> + <property name="windowTitle"> + <string>PVS - Chat </string> + </property> + <property name="windowIcon"> + <iconset resource="../../../pvsgui.qrc"> + <normaloff>:/cam32.svg</normaloff>:/cam32.svg</iconset> + </property> + <property name="locale"> + <locale language="English" country="UnitedStates"/> + </property> + <layout class="QVBoxLayout" name="verticalLayout_2"> + <item> + <widget class="QSplitter" name="splitter"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Expanding" vsizetype="Expanding"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <widget class="QListWidget" name="listWidget"> + <property name="maximumSize"> + <size> + <width>150</width> + <height>16777215</height> + </size> + </property> + <property name="contextMenuPolicy"> + <enum>Qt::CustomContextMenu</enum> + </property> + <property name="sortingEnabled"> + <bool>true</bool> + </property> + </widget> + <widget class="QTabWidget" name="tabWidget"> + <property name="tabPosition"> + <enum>QTabWidget::South</enum> + </property> + <property name="tabsClosable"> + <bool>true</bool> + </property> + <widget class="QWidget" name="tab"> + <attribute name="title"> + <string notr="true">@all</string> + </attribute> + <layout class="QVBoxLayout" name="verticalLayout"/> + </widget> + </widget> + </widget> + </item> + <item> + <widget class="QLineEdit" name="lineEdit"/> + </item> + <item> + <layout class="QHBoxLayout" name="horizontalLayout"> + <item> + <spacer name="horizontalSpacer"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>40</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + <item> + <widget class="QPushButton" name="pushButton"> + <property name="text"> + <string>&Send</string> + </property> + <property name="autoDefault"> + <bool>false</bool> + </property> + <property name="default"> + <bool>true</bool> + </property> + </widget> + </item> + </layout> + </item> + </layout> + </widget> + <resources> + <include location="../../../pvsgui.qrc"/> + </resources> + <connections> + <connection> + <sender>lineEdit</sender> + <signal>returnPressed()</signal> + <receiver>pushButton</receiver> + <slot>click()</slot> + <hints> + <hint type="sourcelabel"> + <x>252</x> + <y>560</y> + </hint> + <hint type="destinationlabel"> + <x>529</x> + <y>589</y> + </hint> + </hints> + </connection> + </connections> +</ui> diff --git a/src/gui/ui/clientConfigDialog.ui b/src/gui/ui/clientConfigDialog.ui new file mode 100644 index 0000000..3262b6b --- /dev/null +++ b/src/gui/ui/clientConfigDialog.ui @@ -0,0 +1,280 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>ClientConfigDialogClass</class> + <widget class="QDialog" name="ClientConfigDialogClass"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>438</width> + <height>257</height> + </rect> + </property> + <property name="windowTitle"> + <string>PVS - Configuration</string> + </property> + <property name="windowIcon"> + <iconset resource="../../../pvsgui.qrc"> + <normaloff>:/cam32.svg</normaloff>:/cam32.svg</iconset> + </property> + <property name="locale"> + <locale language="English" country="UnitedStates"/> + </property> + <layout class="QVBoxLayout" name="verticalLayout"> + <item> + <widget class="QTabWidget" name="tabWidget"> + <property name="tabPosition"> + <enum>QTabWidget::North</enum> + </property> + <property name="currentIndex"> + <number>0</number> + </property> + <widget class="QWidget" name="tabPermissions"> + <attribute name="title"> + <string>Permissions</string> + </attribute> + <layout class="QVBoxLayout" name="verticalLayout_6"> + <item> + <layout class="QHBoxLayout" name="horizontalLayout"> + <item> + <widget class="QGroupBox" name="groupBox"> + <property name="title"> + <string>Allow vnc access to lecturer?</string> + </property> + <property name="flat"> + <bool>true</bool> + </property> + <property name="checkable"> + <bool>false</bool> + </property> + <layout class="QVBoxLayout" name="verticalLayout_4"> + <item> + <widget class="QRadioButton" name="radioButtonLecturerRW"> + <property name="text"> + <string>Full access</string> + </property> + <property name="checked"> + <bool>true</bool> + </property> + </widget> + </item> + <item> + <widget class="QRadioButton" name="radioButtonLecturerRO"> + <property name="text"> + <string>View only</string> + </property> + </widget> + </item> + <item> + <widget class="QRadioButton" name="radioButtonLecturerNO"> + <property name="text"> + <string>None</string> + </property> + </widget> + </item> + </layout> + </widget> + </item> + <item> + <widget class="Line" name="line_2"> + <property name="orientation"> + <enum>Qt::Vertical</enum> + </property> + </widget> + </item> + <item> + <widget class="QGroupBox" name="groupBox_2"> + <property name="title"> + <string>Allow vnc access to other?</string> + </property> + <property name="flat"> + <bool>true</bool> + </property> + <layout class="QVBoxLayout" name="verticalLayout_2"> + <item> + <widget class="QRadioButton" name="radioButtonOtherRW"> + <property name="text"> + <string>Full access</string> + </property> + </widget> + </item> + <item> + <widget class="QRadioButton" name="radioButtonOtherRO"> + <property name="text"> + <string>View only</string> + </property> + <property name="checked"> + <bool>true</bool> + </property> + </widget> + </item> + <item> + <widget class="QRadioButton" name="radioButtonOtherNO"> + <property name="text"> + <string>None</string> + </property> + <property name="checked"> + <bool>false</bool> + </property> + </widget> + </item> + </layout> + </widget> + </item> + </layout> + </item> + <item> + <widget class="Line" name="line"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + </widget> + </item> + <item> + <layout class="QVBoxLayout" name="verticalLayout_5"> + <item> + <widget class="QCheckBox" name="checkBoxAllowChat"> + <property name="text"> + <string>Accept chat messages</string> + </property> + <property name="checked"> + <bool>true</bool> + </property> + </widget> + </item> + <item> + <widget class="QCheckBox" name="checkBoxAllowFiletransfer"> + <property name="text"> + <string>Accept file transfers</string> + </property> + <property name="checked"> + <bool>true</bool> + </property> + </widget> + </item> + </layout> + </item> + </layout> + </widget> + <widget class="QWidget" name="tabDisplay"> + <attribute name="title"> + <string>Display</string> + </attribute> + <layout class="QVBoxLayout" name="verticalLayout_3"> + <item> + <widget class="QComboBox" name="comboBox"> + <item> + <property name="text"> + <string>Top Left</string> + </property> + </item> + <item> + <property name="text"> + <string>Top Center</string> + </property> + </item> + <item> + <property name="text"> + <string>Top Right</string> + </property> + </item> + <item> + <property name="text"> + <string>Bottom Left</string> + </property> + </item> + <item> + <property name="text"> + <string>Bottom Center</string> + </property> + </item> + <item> + <property name="text"> + <string>Bottom Right</string> + </property> + </item> + </widget> + </item> + </layout> + </widget> + </widget> + </item> + <item> + <widget class="QDialogButtonBox" name="buttonBox"> + <property name="standardButtons"> + <set>QDialogButtonBox::Cancel|QDialogButtonBox::Save</set> + </property> + </widget> + </item> + </layout> + </widget> + <resources> + <include location="../../../pvsgui.qrc"/> + </resources> + <connections> + <connection> + <sender>buttonBox</sender> + <signal>accepted()</signal> + <receiver>ClientConfigDialogClass</receiver> + <slot>accept()</slot> + <hints> + <hint type="sourcelabel"> + <x>62</x> + <y>274</y> + </hint> + <hint type="destinationlabel"> + <x>4</x> + <y>37</y> + </hint> + </hints> + </connection> + <connection> + <sender>buttonBox</sender> + <signal>rejected()</signal> + <receiver>ClientConfigDialogClass</receiver> + <slot>reject()</slot> + <hints> + <hint type="sourcelabel"> + <x>195</x> + <y>274</y> + </hint> + <hint type="destinationlabel"> + <x>233</x> + <y>32</y> + </hint> + </hints> + </connection> + <connection> + <sender>radioButtonOtherRW</sender> + <signal>clicked()</signal> + <receiver>radioButtonLecturerRW</receiver> + <slot>click()</slot> + <hints> + <hint type="sourcelabel"> + <x>87</x> + <y>167</y> + </hint> + <hint type="destinationlabel"> + <x>198</x> + <y>56</y> + </hint> + </hints> + </connection> + <connection> + <sender>radioButtonLecturerNO</sender> + <signal>clicked()</signal> + <receiver>radioButtonOtherNO</receiver> + <slot>click()</slot> + <hints> + <hint type="sourcelabel"> + <x>149</x> + <y>106</y> + </hint> + <hint type="destinationlabel"> + <x>84</x> + <y>219</y> + </hint> + </hints> + </connection> + </connections> +</ui> diff --git a/src/gui/ui/clientFileReceiveDialog.ui b/src/gui/ui/clientFileReceiveDialog.ui new file mode 100644 index 0000000..af3a135 --- /dev/null +++ b/src/gui/ui/clientFileReceiveDialog.ui @@ -0,0 +1,134 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>ClientFileReceiveDialogClass</class> + <widget class="QDialog" name="ClientFileReceiveDialogClass"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>208</width> + <height>108</height> + </rect> + </property> + <property name="windowTitle"> + <string>PVS - File Transfer</string> + </property> + <property name="windowIcon"> + <iconset resource="../../../pvsgui.qrc"> + <normaloff>:/cam32.svg</normaloff>:/cam32.svg</iconset> + </property> + <layout class="QVBoxLayout" name="verticalLayout"> + <item> + <widget class="QLabel" name="filenameLabel"> + <property name="text"> + <string/> + </property> + </widget> + </item> + <item> + <widget class="QProgressBar" name="progressBar"> + <property name="value"> + <number>0</number> + </property> + </widget> + </item> + <item> + <layout class="QHBoxLayout" name="horizontalLayout_2"> + <item> + <widget class="QLabel" name="label"> + <property name="text"> + <string>Receiving from:</string> + </property> + </widget> + </item> + <item> + <widget class="QLabel" name="labelNick"> + <property name="text"> + <string>unknown</string> + </property> + </widget> + </item> + <item> + <spacer name="horizontalSpacer_2"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>40</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + </layout> + </item> + <item> + <layout class="QHBoxLayout" name="horizontalLayout"> + <item> + <widget class="QLabel" name="labelA"> + <property name="text"> + <string>0</string> + </property> + </widget> + </item> + <item> + <widget class="QLabel" name="label_2"> + <property name="text"> + <string>/</string> + </property> + </widget> + </item> + <item> + <widget class="QLabel" name="labelB"> + <property name="text"> + <string>0</string> + </property> + </widget> + </item> + <item> + <spacer name="horizontalSpacer"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>40</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + <item> + <widget class="QPushButton" name="cancelButton"> + <property name="text"> + <string>&Cancel</string> + </property> + </widget> + </item> + </layout> + </item> + </layout> + </widget> + <resources> + <include location="../../../pvsgui.qrc"/> + </resources> + <connections> + <connection> + <sender>cancelButton</sender> + <signal>clicked()</signal> + <receiver>ClientFileReceiveDialogClass</receiver> + <slot>reject()</slot> + <hints> + <hint type="sourcelabel"> + <x>220</x> + <y>242</y> + </hint> + <hint type="destinationlabel"> + <x>345</x> + <y>270</y> + </hint> + </hints> + </connection> + </connections> +</ui> diff --git a/src/gui/ui/clientFileSendDialog.ui b/src/gui/ui/clientFileSendDialog.ui new file mode 100644 index 0000000..d2d9c75 --- /dev/null +++ b/src/gui/ui/clientFileSendDialog.ui @@ -0,0 +1,134 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>ClientFileSendDialogClass</class> + <widget class="QDialog" name="ClientFileSendDialogClass"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>186</width> + <height>108</height> + </rect> + </property> + <property name="windowTitle"> + <string>PVS - File Transfer</string> + </property> + <property name="windowIcon"> + <iconset resource="../../../pvsgui.qrc"> + <normaloff>:/cam32.svg</normaloff>:/cam32.svg</iconset> + </property> + <layout class="QVBoxLayout" name="verticalLayout"> + <item> + <widget class="QLabel" name="filenameLabel"> + <property name="text"> + <string/> + </property> + </widget> + </item> + <item> + <widget class="QProgressBar" name="progressBar"> + <property name="value"> + <number>0</number> + </property> + </widget> + </item> + <item> + <layout class="QHBoxLayout" name="horizontalLayout_2"> + <item> + <widget class="QLabel" name="label"> + <property name="text"> + <string>Sending to:</string> + </property> + </widget> + </item> + <item> + <widget class="QLabel" name="labelNick"> + <property name="text"> + <string>unknown</string> + </property> + </widget> + </item> + <item> + <spacer name="horizontalSpacer_2"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>40</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + </layout> + </item> + <item> + <layout class="QHBoxLayout" name="horizontalLayout"> + <item> + <widget class="QLabel" name="labelA"> + <property name="text"> + <string>0</string> + </property> + </widget> + </item> + <item> + <widget class="QLabel" name="label_2"> + <property name="text"> + <string>/</string> + </property> + </widget> + </item> + <item> + <widget class="QLabel" name="labelB"> + <property name="text"> + <string>0</string> + </property> + </widget> + </item> + <item> + <spacer name="horizontalSpacer"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>40</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + <item> + <widget class="QPushButton" name="cancelButton"> + <property name="text"> + <string>&Cancel</string> + </property> + </widget> + </item> + </layout> + </item> + </layout> + </widget> + <resources> + <include location="../../../pvsgui.qrc"/> + </resources> + <connections> + <connection> + <sender>cancelButton</sender> + <signal>clicked()</signal> + <receiver>ClientFileSendDialogClass</receiver> + <slot>reject()</slot> + <hints> + <hint type="sourcelabel"> + <x>116</x> + <y>61</y> + </hint> + <hint type="destinationlabel"> + <x>38</x> + <y>55</y> + </hint> + </hints> + </connection> + </connections> +</ui> diff --git a/src/gui/ui/clientInfoDialog.ui b/src/gui/ui/clientInfoDialog.ui new file mode 100644 index 0000000..a186641 --- /dev/null +++ b/src/gui/ui/clientInfoDialog.ui @@ -0,0 +1,60 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>InfoDialogClass</class> + <widget class="QDialog" name="InfoDialogClass"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>312</width> + <height>203</height> + </rect> + </property> + <property name="windowTitle"> + <string>PVS - Information</string> + </property> + <property name="windowIcon"> + <iconset resource="../../../pvsgui.qrc"> + <normaloff>:/cam32.svg</normaloff>:/cam32.svg</iconset> + </property> + <property name="styleSheet"> + <string notr="true">QDialog { + background-color: white; +}</string> + </property> + <layout class="QVBoxLayout" name="verticalLayout"> + <item> + <widget class="QLabel" name="hostLabel"> + <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:'DejaVu Sans'; font-size:9pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:72pt; font-weight:600; color:#0000ff;">HOST</span></p></body></html></string> + </property> + <property name="alignment"> + <set>Qt::AlignCenter</set> + </property> + </widget> + </item> + <item> + <widget class="QLabel" name="passwdLabel"> + <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:'DejaVu Sans'; font-size:9pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:48pt; font-weight:600; color:#ff0000;">PASSWD</span></p></body></html></string> + </property> + <property name="alignment"> + <set>Qt::AlignCenter</set> + </property> + </widget> + </item> + </layout> + </widget> + <resources> + <include location="../../../pvsgui.qrc"/> + </resources> + <connections/> +</ui> diff --git a/src/gui/ui/clientNicklistDialog.ui b/src/gui/ui/clientNicklistDialog.ui new file mode 100644 index 0000000..afd84f1 --- /dev/null +++ b/src/gui/ui/clientNicklistDialog.ui @@ -0,0 +1,110 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>ClientNicklistDialogClass</class> + <widget class="QDialog" name="ClientNicklistDialogClass"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>264</width> + <height>396</height> + </rect> + </property> + <property name="windowTitle"> + <string>PVS - Users</string> + </property> + <property name="windowIcon"> + <iconset resource="../../../pvsgui.qrc"> + <normaloff>:/cam32.svg</normaloff>:/cam32.svg</iconset> + </property> + <layout class="QVBoxLayout" name="verticalLayout"> + <item> + <widget class="QLabel" name="label"> + <property name="text"> + <string>Select user:</string> + </property> + </widget> + </item> + <item> + <widget class="QListWidget" name="listWidget"/> + </item> + <item> + <layout class="QHBoxLayout" name="horizontalLayout"> + <item> + <spacer name="horizontalSpacer"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>40</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + <item> + <widget class="QDialogButtonBox" name="buttonBox"> + <property name="standardButtons"> + <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set> + </property> + </widget> + </item> + </layout> + </item> + </layout> + </widget> + <resources> + <include location="../../../pvsgui.qrc"/> + </resources> + <connections> + <connection> + <sender>buttonBox</sender> + <signal>accepted()</signal> + <receiver>ClientNicklistDialogClass</receiver> + <slot>accept()</slot> + <hints> + <hint type="sourcelabel"> + <x>258</x> + <y>390</y> + </hint> + <hint type="destinationlabel"> + <x>373</x> + <y>526</y> + </hint> + </hints> + </connection> + <connection> + <sender>buttonBox</sender> + <signal>rejected()</signal> + <receiver>ClientNicklistDialogClass</receiver> + <slot>reject()</slot> + <hints> + <hint type="sourcelabel"> + <x>258</x> + <y>390</y> + </hint> + <hint type="destinationlabel"> + <x>428</x> + <y>525</y> + </hint> + </hints> + </connection> + <connection> + <sender>listWidget</sender> + <signal>doubleClicked(QModelIndex)</signal> + <receiver>ClientNicklistDialogClass</receiver> + <slot>accept()</slot> + <hints> + <hint type="sourcelabel"> + <x>88</x> + <y>120</y> + </hint> + <hint type="destinationlabel"> + <x>27</x> + <y>375</y> + </hint> + </hints> + </connection> + </connections> +</ui> diff --git a/src/gui/ui/clientToolbar.ui b/src/gui/ui/clientToolbar.ui new file mode 100644 index 0000000..5a59c5f --- /dev/null +++ b/src/gui/ui/clientToolbar.ui @@ -0,0 +1,214 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>ClientToolbarClass</class> + <widget class="QWidget" name="ClientToolbarClass"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>577</width> + <height>28</height> + </rect> + </property> + <property name="windowTitle"> + <string>Form</string> + </property> + <property name="styleSheet"> + <string notr="true">QFrame { + background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #f6f7fa, stop: 1 #dadbde); + border-radius: 0px; +} +QLabel { + background-color: none; +} +/* QPushButton */ +QPushButton { + background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #f6f7fa, stop: 1 #dadbde); + border: 2px solid #8f8f91; + border-radius: 4px; + min-width: 80px; +} +QPushButton:hover { + border: 2px solid rgb(0, 170, 255); +} +QPushButton:pressed { + background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #dadbde, stop: 1 #f6f7fa); +} +QPushButton::menu-indicator { + image: url(:/darrow16.svg); +} +/* QCheckBox */ +QCheckBox { +} +QCheckBox::indicator { + background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #f6f7fa, stop: 1 #dadbde); + border: 2px solid #8f8f91; + border-radius: 4px; + width: 16px; + height: 16px; +} +QCheckBox::indicator:unchecked { +} +QCheckBox::indicator:unchecked:hover { + border: 2px solid rgb(0, 170, 255); +} +QCheckBox::indicator:unchecked:pressed { + background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #dadbde, stop: 1 #f6f7fa); +} +QCheckBox::indicator:checked { + image: url(:/ok16.svg); +} +QCheckBox::indicator:checked:hover { + border: 2px solid rgb(0, 170, 255); +} +QCheckBox::indicator:checked:pressed { + background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #dadbde, stop: 1 #f6f7fa); +} +</string> + </property> + <layout class="QHBoxLayout" name="horizontalLayout_2"> + <property name="margin"> + <number>0</number> + </property> + <item> + <widget class="QFrame" name="frame"> + <property name="frameShape"> + <enum>QFrame::StyledPanel</enum> + </property> + <property name="frameShadow"> + <enum>QFrame::Raised</enum> + </property> + <layout class="QHBoxLayout" name="horizontalLayout"> + <item> + <widget class="QPushButton" name="pvsButton"> + <property name="toolTip"> + <string>Menu</string> + </property> + <property name="text"> + <string notr="true">Menu</string> + </property> + </widget> + </item> + <item> + <spacer name="horizontalSpacer"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>20</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + <item> + <widget class="QLabel" name="label_2"> + <property name="text"> + <string>Host:</string> + </property> + </widget> + </item> + <item> + <widget class="QPushButton" name="hostButton"> + <property name="toolTip"> + <string>Click to connect</string> + </property> + <property name="text"> + <string>-</string> + </property> + </widget> + </item> + <item> + <widget class="QLabel" name="statusLabel"> + <property name="text"> + <string notr="true"><!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:'DejaVu Sans'; font-size:9pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" color:#ff0000;">Offline</span></p></body></html></string> + </property> + </widget> + </item> + <item> + <spacer name="horizontalSpacer_3"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>20</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + <item> + <widget class="QCheckBox" name="vncCheckBox"> + <property name="minimumSize"> + <size> + <width>0</width> + <height>0</height> + </size> + </property> + <property name="toolTip"> + <string>Enable/Disable VNC only for this session</string> + </property> + <property name="text"> + <string>Allow VNC</string> + </property> + </widget> + </item> + <item> + <spacer name="horizontalSpacer_2"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>20</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + <item> + <widget class="QLabel" name="label"> + <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:'DejaVu Sans'; font-size:9pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt; font-weight:600; font-style:italic; color:#0055ff;">Pool Video Switch</span></p></body></html></string> + </property> + </widget> + </item> + <item> + <widget class="QLabel" name="label_3"> + <property name="maximumSize"> + <size> + <width>16</width> + <height>16</height> + </size> + </property> + <property name="text"> + <string/> + </property> + <property name="pixmap"> + <pixmap resource="../../../pvsgui.qrc">:/cam32.svg</pixmap> + </property> + <property name="scaledContents"> + <bool>true</bool> + </property> + </widget> + </item> + </layout> + </widget> + </item> + </layout> + </widget> + <resources> + <include location="../../../pvsgui.qrc"/> + </resources> + <connections/> +</ui> diff --git a/src/gui/ui/dialog.ui b/src/gui/ui/dialog.ui new file mode 100644 index 0000000..ec16160 --- /dev/null +++ b/src/gui/ui/dialog.ui @@ -0,0 +1,66 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>MsgDialog</class> + <widget class="QDialog" name="MsgDialog"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>400</width> + <height>193</height> + </rect> + </property> + <property name="windowTitle"> + <string>Dialog</string> + </property> + <widget class="QWidget" name="layoutWidget"> + <property name="geometry"> + <rect> + <x>20</x> + <y>20</y> + <width>351</width> + <height>171</height> + </rect> + </property> + <layout class="QVBoxLayout" name="verticalLayout"> + <item> + <widget class="QTextEdit" name="message"/> + </item> + <item> + <layout class="QHBoxLayout" name="horizontalLayout"> + <item> + <spacer name="horizontalSpacer"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>108</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + <item> + <widget class="QPushButton" name="cancel"> + <property name="text"> + <string>Cancel</string> + </property> + </widget> + </item> + <item> + <widget class="QPushButton" name="send"> + <property name="text"> + <string>Send</string> + </property> + </widget> + </item> + </layout> + </item> + </layout> + </widget> + </widget> + <layoutdefault spacing="6" margin="11"/> + <resources/> + <connections/> +</ui> diff --git a/src/gui/ui/mainwindow.ui b/src/gui/ui/mainwindow.ui new file mode 100644 index 0000000..eb49d1b --- /dev/null +++ b/src/gui/ui/mainwindow.ui @@ -0,0 +1,540 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>MainWindow</class> + <widget class="QMainWindow" name="MainWindow"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>838</width> + <height>607</height> + </rect> + </property> + <property name="windowTitle"> + <string>PVSmgr</string> + </property> + <widget class="QWidget" name="centralWidget"> + <layout class="QGridLayout" name="gridLayout"> + <item row="0" column="0"> + <widget class="QScrollArea" name="scrollArea"> + <property name="styleSheet"> + <string>border-color: rgb(0, 0, 0);</string> + </property> + <property name="widgetResizable"> + <bool>true</bool> + </property> + <widget class="QWidget" name="scrollAreaWidgetContents"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>776</width> + <height>534</height> + </rect> + </property> + <layout class="QGridLayout" name="gridLayout_2"> + <item row="0" column="0"> + <layout class="QVBoxLayout" name="verticalLayout"> + <item> + <layout class="QHBoxLayout" name="horizontalLayout"> + <item> + <widget class="QLabel" name="label"> + <property name="text"> + <string>VNC quality</string> + </property> + </widget> + </item> + <item> + <widget class="QComboBox" name="vncQuality"> + <item> + <property name="text"> + <string>HIGH</string> + </property> + </item> + <item> + <property name="text"> + <string>MEDIUM</string> + </property> + </item> + <item> + <property name="text"> + <string>LOW</string> + </property> + </item> + </widget> + </item> + <item> + <widget class="Line" name="separator"> + <property name="orientation"> + <enum>Qt::Vertical</enum> + </property> + </widget> + </item> + <item> + <widget class="QCheckBox" name="setPassword"> + <property name="text"> + <string>Set password</string> + </property> + </widget> + </item> + <item> + <widget class="Line" name="line"> + <property name="orientation"> + <enum>Qt::Vertical</enum> + </property> + </widget> + </item> + <item> + <widget class="QComboBox" name="thumbStatus"> + <item> + <property name="text"> + <string>Thumbnailratio</string> + </property> + </item> + <item> + <property name="text"> + <string>Thumbnailrate</string> + </property> + </item> + </widget> + </item> + <item> + <widget class="QSlider" name="horizontalSlider"> + <property name="minimum"> + <number>25</number> + </property> + <property name="maximum"> + <number>200</number> + </property> + <property name="singleStep"> + <number>25</number> + </property> + <property name="pageStep"> + <number>25</number> + </property> + <property name="value"> + <number>25</number> + </property> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="tickPosition"> + <enum>QSlider::TicksBothSides</enum> + </property> + <property name="tickInterval"> + <number>0</number> + </property> + </widget> + </item> + <item> + <widget class="QLabel" name="label_2"> + <property name="text"> + <string> 0</string> + </property> + </widget> + </item> + <item> + <widget class="QLabel" name="label_3"> + <property name="text"> + <string>%</string> + </property> + </widget> + </item> + </layout> + </item> + <item> + <widget class="QSplitter" name="splitter_2"> + <property name="orientation"> + <enum>Qt::Vertical</enum> + </property> + <widget class="QSplitter" name="splitter"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <widget class="QWidget" name="ClWidget" native="true"> + <property name="minimumSize"> + <size> + <width>150</width> + <height>240</height> + </size> + </property> + <property name="styleSheet"> + <string>background-color: rgb(255, 255, 255);</string> + </property> + <layout class="QGridLayout" name="gridLayout_5"> + <item row="0" column="0"> + <layout class="QGridLayout" name="ClientGLayout"/> + </item> + </layout> + </widget> + <widget class="QWidget" name="widget" native="true"> + <property name="styleSheet"> + <string>background-color: rgb(150, 150, 150);</string> + </property> + <layout class="QGridLayout" name="gridLayout_4"> + <item row="0" column="0"> + <layout class="QVBoxLayout" name="VconWinLayout"/> + </item> + </layout> + </widget> + </widget> + <widget class="QTextEdit" name="pvsLog"/> + </widget> + </item> + </layout> + </item> + </layout> + </widget> + </widget> + </item> + </layout> + </widget> + <widget class="QMenuBar" name="menuBar"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>838</width> + <height>28</height> + </rect> + </property> + <widget class="QMenu" name="menu_File"> + <property name="title"> + <string>&File</string> + </property> + <widget class="QMenu" name="menuLoad_profile"> + <property name="title"> + <string>Load profile </string> + </property> + </widget> + <addaction name="action_Disconnect"/> + <addaction name="separator"/> + <addaction name="actionCreate_profile"/> + <addaction name="separator"/> + <addaction name="menuLoad_profile"/> + <addaction name="separator"/> + <addaction name="action_Exit"/> + </widget> + <widget class="QMenu" name="menuClients"> + <property name="title"> + <string>&Clients</string> + </property> + <addaction name="actionShow_Fullname"/> + <addaction name="actionShow_Hostname_IP"/> + <addaction name="actionShow_Username"/> + <addaction name="separator"/> + <addaction name="actionVNC_Placeholders"/> + </widget> + <widget class="QMenu" name="menuLogging"> + <property name="title"> + <string>&Logging</string> + </property> + <addaction name="actionShow_Log"/> + <addaction name="separator"/> + <addaction name="actionShow_Normal"/> + <addaction name="actionShow_Error"/> + <addaction name="actionShow_Network"/> + <addaction name="actionShow_Terminal"/> + <addaction name="actionShow_Chat"/> + </widget> + <widget class="QMenu" name="menu_Help"> + <property name="title"> + <string>&Help</string> + </property> + <addaction name="actionAbout_pvs"/> + </widget> + <addaction name="menu_File"/> + <addaction name="menuClients"/> + <addaction name="menuLogging"/> + <addaction name="menu_Help"/> + </widget> + <widget class="QStatusBar" name="statusBar"/> + <widget class="QToolBar" name="toolBar"> + <property name="maximumSize"> + <size> + <width>129000</width> + <height>12900</height> + </size> + </property> + <property name="windowTitle"> + <string>toolBar</string> + </property> + <property name="layoutDirection"> + <enum>Qt::LeftToRight</enum> + </property> + <property name="autoFillBackground"> + <bool>true</bool> + </property> + <property name="movable"> + <bool>true</bool> + </property> + <property name="toolButtonStyle"> + <enum>Qt::ToolButtonIconOnly</enum> + </property> + <property name="floatable"> + <bool>false</bool> + </property> + <attribute name="toolBarArea"> + <enum>LeftToolBarArea</enum> + </attribute> + <attribute name="toolBarBreak"> + <bool>false</bool> + </attribute> + <addaction name="action_Exit"/> + <addaction name="action_Disconnect"/> + <addaction name="actionFoto"/> + <addaction name="actionView"/> + <addaction name="actionLock"/> + <addaction name="actionChat"/> + </widget> + <action name="actionShow_Username"> + <property name="checkable"> + <bool>false</bool> + </property> + <property name="text"> + <string>Show Username</string> + </property> + <property name="shortcut"> + <string>Ctrl+3</string> + </property> + </action> + <action name="actionShow_Hostname_IP"> + <property name="checkable"> + <bool>false</bool> + </property> + <property name="text"> + <string>Show IP</string> + </property> + <property name="shortcut"> + <string>Ctrl+2</string> + </property> + </action> + <action name="actionVNC_Placeholders"> + <property name="checkable"> + <bool>true</bool> + </property> + <property name="text"> + <string>VNC-Placeholders</string> + </property> + </action> + <action name="actionShow_Log"> + <property name="checkable"> + <bool>true</bool> + </property> + <property name="checked"> + <bool>false</bool> + </property> + <property name="text"> + <string>Show Log</string> + </property> + <property name="shortcut"> + <string>Ctrl+L</string> + </property> + </action> + <action name="actionShow_Normal"> + <property name="checkable"> + <bool>true</bool> + </property> + <property name="text"> + <string>Show Normal</string> + </property> + <property name="shortcut"> + <string>Ctrl+O</string> + </property> + </action> + <action name="actionShow_Error"> + <property name="checkable"> + <bool>true</bool> + </property> + <property name="text"> + <string>Show Error</string> + </property> + <property name="shortcut"> + <string>Ctrl+E</string> + </property> + </action> + <action name="actionShow_Network"> + <property name="checkable"> + <bool>true</bool> + </property> + <property name="text"> + <string>Show Network</string> + </property> + <property name="shortcut"> + <string>Ctrl+N</string> + </property> + </action> + <action name="actionShow_Terminal"> + <property name="checkable"> + <bool>true</bool> + </property> + <property name="text"> + <string>Show Terminal</string> + </property> + <property name="shortcut"> + <string>Ctrl+T</string> + </property> + </action> + <action name="actionShow_Chat"> + <property name="checkable"> + <bool>true</bool> + </property> + <property name="text"> + <string>Show Chat</string> + </property> + <property name="shortcut"> + <string>Ctrl+G</string> + </property> + </action> + <action name="actionAbout_pvs"> + <property name="text"> + <string>About pvs</string> + </property> + <property name="shortcut"> + <string>Ctrl+P</string> + </property> + </action> + <action name="action100_x_100"> + <property name="checkable"> + <bool>true</bool> + </property> + <property name="text"> + <string>100 x 100</string> + </property> + </action> + <action name="action200_x_200"> + <property name="checkable"> + <bool>true</bool> + </property> + <property name="text"> + <string>200 x 200</string> + </property> + </action> + <action name="action500_x_500"> + <property name="checkable"> + <bool>true</bool> + </property> + <property name="text"> + <string>500 x 500</string> + </property> + </action> + <action name="action_Disconnect"> + <property name="icon"> + <iconset resource="../../../pvsmgr.qrc"> + <normaloff>:/logout</normaloff>:/logout</iconset> + </property> + <property name="text"> + <string>&Disconnect</string> + </property> + <property name="shortcut"> + <string>Ctrl+W</string> + </property> + </action> + <action name="action_Exit"> + <property name="icon"> + <iconset resource="../../../pvsmgr.qrc"> + <normaloff>:/exit</normaloff> + <normalon>:/exit</normalon>:/exit</iconset> + </property> + <property name="text"> + <string>&Exit</string> + </property> + <property name="toolTip"> + <string>Exit</string> + </property> + <property name="shortcut"> + <string>Ctrl+Q</string> + </property> + </action> + <action name="actionFoto"> + <property name="icon"> + <iconset resource="../../../pvsmgr.qrc"> + <normaloff>:/photos</normaloff>:/photos</iconset> + </property> + <property name="text"> + <string>Foto</string> + </property> + <property name="toolTip"> + <string>Foto</string> + </property> + <property name="shortcut"> + <string>Ctrl+F</string> + </property> + </action> + <action name="actionView"> + <property name="icon"> + <iconset resource="../../../pvsmgr.qrc"> + <normaloff>:/restore</normaloff>:/restore</iconset> + </property> + <property name="text"> + <string>view</string> + </property> + <property name="toolTip"> + <string>View</string> + </property> + <property name="shortcut"> + <string>Ctrl+V</string> + </property> + </action> + <action name="actionLock"> + <property name="icon"> + <iconset resource="../../../pvsmgr.qrc"> + <normaloff>:/lock</normaloff>:/lock</iconset> + </property> + <property name="text"> + <string>lock</string> + </property> + <property name="toolTip"> + <string>Lock or Unlock all Clients</string> + </property> + <property name="shortcut"> + <string>Ctrl+A</string> + </property> + </action> + <action name="actionCreate_profile"> + <property name="icon"> + <iconset resource="../../../pvsmgr.qrc"> + <normaloff>:/profile</normaloff>:/profile</iconset> + </property> + <property name="text"> + <string>Profile &manager</string> + </property> + <property name="shortcut"> + <string>Ctrl+M</string> + </property> + </action> + <action name="actionShow_Fullname"> + <property name="text"> + <string>Show Name</string> + </property> + <property name="shortcut"> + <string>Ctrl+1</string> + </property> + </action> + <action name="actionChat"> + <property name="icon"> + <iconset resource="../../../pvsmgr.qrc"> + <normaloff>:/chat</normaloff>:/chat</iconset> + </property> + <property name="text"> + <string>Chat</string> + </property> + <property name="toolTip"> + <string>Start Chat with client(s)</string> + </property> + <property name="shortcut"> + <string>Ctrl+D</string> + </property> + </action> + <action name="dummy"> + <property name="text"> + <string>-</string> + </property> + </action> + </widget> + <layoutdefault spacing="6" margin="11"/> + <resources> + <include location="../../../pvsmgr.qrc"/> + </resources> + <connections/> +</ui> diff --git a/src/gui/ui/mainwindowtouch.ui b/src/gui/ui/mainwindowtouch.ui new file mode 100644 index 0000000..9030b17 --- /dev/null +++ b/src/gui/ui/mainwindowtouch.ui @@ -0,0 +1,645 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>MainWindow</class> + <widget class="QMainWindow" name="MainWindow"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>1349</width> + <height>768</height> + </rect> + </property> + <property name="windowTitle"> + <string>PVSmgr</string> + </property> + <widget class="QWidget" name="centralWidget"> + <layout class="QGridLayout" name="gridLayout"> + <item row="0" column="0"> + <widget class="QScrollArea" name="scrollArea"> + <property name="styleSheet"> + <string>border-color: rgb(0, 0, 0);</string> + </property> + <property name="widgetResizable"> + <bool>true</bool> + </property> + <widget class="QWidget" name="scrollAreaWidgetContents"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>1327</width> + <height>658</height> + </rect> + </property> + <layout class="QGridLayout" name="gridLayout_3"> + <item row="0" column="0"> + <layout class="QHBoxLayout" name="horizontalLayout"> + <item> + <widget class="QComboBox" name="comboBox_touch1"> + <property name="font"> + <font> + <pointsize>15</pointsize> + </font> + </property> + <item> + <property name="text"> + <string>All</string> + </property> + </item> + <item> + <property name="text"> + <string>Lock</string> + </property> + </item> + <item> + <property name="text"> + <string>Unlock</string> + </property> + </item> + <item> + <property name="text"> + <string>Unproject</string> + </property> + </item> + <item> + <property name="text"> + <string>Backgroundimage</string> + </property> + </item> + </widget> + </item> + <item> + <widget class="Line" name="line_5"> + <property name="orientation"> + <enum>Qt::Vertical</enum> + </property> + </widget> + </item> + <item> + <widget class="QLabel" name="label"> + <property name="text"> + <string>VNC-Quality</string> + </property> + </widget> + </item> + <item> + <widget class="QComboBox" name="vncQuality"> + <property name="font"> + <font> + <pointsize>15</pointsize> + </font> + </property> + <item> + <property name="text"> + <string>HIGH</string> + </property> + </item> + <item> + <property name="text"> + <string>MEDIUM</string> + </property> + </item> + <item> + <property name="text"> + <string>LOW</string> + </property> + </item> + </widget> + </item> + <item> + <widget class="Line" name="line_3"> + <property name="orientation"> + <enum>Qt::Vertical</enum> + </property> + </widget> + </item> + <item> + <widget class="QPushButton" name="pushButton_2"> + <property name="font"> + <font> + <pointsize>15</pointsize> + </font> + </property> + <property name="text"> + <string>ClientList</string> + </property> + </widget> + </item> + <item> + <widget class="Line" name="line_2"> + <property name="orientation"> + <enum>Qt::Vertical</enum> + </property> + </widget> + </item> + <item> + <widget class="QPushButton" name="pushButton"> + <property name="font"> + <font> + <pointsize>15</pointsize> + </font> + </property> + <property name="text"> + <string>Profile</string> + </property> + </widget> + </item> + <item> + <widget class="Line" name="line_4"> + <property name="orientation"> + <enum>Qt::Vertical</enum> + </property> + </widget> + </item> + <item> + <widget class="QProgressBar" name="progressBar"> + <property name="styleSheet"> + <string>border-color: rgb(0, 0, 0);</string> + </property> + <property name="value"> + <number>0</number> + </property> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + </widget> + </item> + <item> + <widget class="Line" name="separator"> + <property name="orientation"> + <enum>Qt::Vertical</enum> + </property> + </widget> + </item> + <item> + <widget class="QCheckBox" name="setPassword"> + <property name="font"> + <font> + <pointsize>15</pointsize> + </font> + </property> + <property name="text"> + <string>setPassword</string> + </property> + </widget> + </item> + <item> + <widget class="Line" name="line"> + <property name="orientation"> + <enum>Qt::Vertical</enum> + </property> + </widget> + </item> + <item> + <widget class="QComboBox" name="thumbStatus"> + <property name="font"> + <font> + <pointsize>15</pointsize> + </font> + </property> + <item> + <property name="text"> + <string>Thumbnailratio</string> + </property> + </item> + <item> + <property name="text"> + <string>Thumbnailrate</string> + </property> + </item> + </widget> + </item> + <item> + <widget class="QSlider" name="horizontalSlider"> + <property name="minimum"> + <number>25</number> + </property> + <property name="maximum"> + <number>200</number> + </property> + <property name="singleStep"> + <number>25</number> + </property> + <property name="pageStep"> + <number>25</number> + </property> + <property name="value"> + <number>25</number> + </property> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="tickPosition"> + <enum>QSlider::TicksBothSides</enum> + </property> + <property name="tickInterval"> + <number>0</number> + </property> + </widget> + </item> + <item> + <widget class="QLabel" name="label_2"> + <property name="text"> + <string> 0</string> + </property> + </widget> + </item> + <item> + <widget class="QLabel" name="label_3"> + <property name="text"> + <string>%</string> + </property> + </widget> + </item> + </layout> + </item> + <item row="1" column="0"> + <widget class="QSplitter" name="splitter_2"> + <property name="orientation"> + <enum>Qt::Vertical</enum> + </property> + <widget class="QSplitter" name="splitter"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <widget class="QWidget" name="ClWidget" native="true"> + <property name="minimumSize"> + <size> + <width>150</width> + <height>240</height> + </size> + </property> + <property name="styleSheet"> + <string>background-color: rgb(255, 255, 255);</string> + </property> + <layout class="QGridLayout" name="gridLayout_5"> + <item row="0" column="0"> + <layout class="QGridLayout" name="ClientGLayout"/> + </item> + </layout> + </widget> + <widget class="QWidget" name="widget" native="true"> + <property name="styleSheet"> + <string>background-color: rgb(150, 150, 150);</string> + </property> + <layout class="QGridLayout" name="gridLayout_4"> + <item row="0" column="0"> + <layout class="QVBoxLayout" name="VconWinLayout"/> + </item> + </layout> + </widget> + </widget> + <widget class="QTextEdit" name="pvsLog"/> + </widget> + </item> + </layout> + </widget> + </widget> + </item> + </layout> + </widget> + <widget class="QStatusBar" name="statusBar"/> + <widget class="QToolBar" name="toolBar"> + <property name="enabled"> + <bool>true</bool> + </property> + <property name="maximumSize"> + <size> + <width>129000</width> + <height>12900</height> + </size> + </property> + <property name="font"> + <font> + <pointsize>15</pointsize> + <kerning>true</kerning> + </font> + </property> + <property name="windowTitle"> + <string>toolBar</string> + </property> + <property name="layoutDirection"> + <enum>Qt::LeftToRight</enum> + </property> + <property name="autoFillBackground"> + <bool>true</bool> + </property> + <property name="movable"> + <bool>false</bool> + </property> + <property name="iconSize"> + <size> + <width>50</width> + <height>50</height> + </size> + </property> + <property name="toolButtonStyle"> + <enum>Qt::ToolButtonIconOnly</enum> + </property> + <property name="floatable"> + <bool>false</bool> + </property> + <attribute name="toolBarArea"> + <enum>TopToolBarArea</enum> + </attribute> + <attribute name="toolBarBreak"> + <bool>false</bool> + </attribute> + <addaction name="action_Exit"/> + <addaction name="separator"/> + <addaction name="actionFoto"/> + <addaction name="separator"/> + <addaction name="actionView"/> + <addaction name="separator"/> + <addaction name="actionProjection"/> + <addaction name="separator"/> + <addaction name="actionUnprojection"/> + <addaction name="separator"/> + <addaction name="actionLocksingle"/> + <addaction name="separator"/> + <addaction name="actionUnlocksingle"/> + <addaction name="separator"/> + <addaction name="actionLock"/> + <addaction name="separator"/> + <addaction name="actionresetall"/> + <addaction name="separator"/> + <addaction name="actionDozent"/> + </widget> + <action name="actionShow_Username"> + <property name="checkable"> + <bool>false</bool> + </property> + <property name="text"> + <string>Show Username</string> + </property> + </action> + <action name="actionShow_Hostname_IP"> + <property name="checkable"> + <bool>false</bool> + </property> + <property name="text"> + <string>Show Hostname/IP</string> + </property> + </action> + <action name="actionVNC_Placeholders"> + <property name="checkable"> + <bool>true</bool> + </property> + <property name="text"> + <string>VNC-Placeholders</string> + </property> + </action> + <action name="actionShow_Log"> + <property name="checkable"> + <bool>true</bool> + </property> + <property name="checked"> + <bool>false</bool> + </property> + <property name="text"> + <string>Show Log</string> + </property> + </action> + <action name="actionShow_Normal"> + <property name="checkable"> + <bool>true</bool> + </property> + <property name="text"> + <string>Show Normal</string> + </property> + </action> + <action name="actionShow_Error"> + <property name="checkable"> + <bool>true</bool> + </property> + <property name="text"> + <string>Show Error</string> + </property> + </action> + <action name="actionShow_Network"> + <property name="checkable"> + <bool>true</bool> + </property> + <property name="text"> + <string>Show Network</string> + </property> + </action> + <action name="actionShow_Terminal"> + <property name="checkable"> + <bool>true</bool> + </property> + <property name="text"> + <string>Show Terminal</string> + </property> + </action> + <action name="actionShow_Chat"> + <property name="checkable"> + <bool>true</bool> + </property> + <property name="text"> + <string>Show Chat</string> + </property> + </action> + <action name="actionAbout_pvs"> + <property name="text"> + <string>About pvs</string> + </property> + </action> + <action name="action100_x_100"> + <property name="checkable"> + <bool>true</bool> + </property> + <property name="text"> + <string>100 x 100</string> + </property> + </action> + <action name="action200_x_200"> + <property name="checkable"> + <bool>true</bool> + </property> + <property name="text"> + <string>200 x 200</string> + </property> + </action> + <action name="action500_x_500"> + <property name="checkable"> + <bool>true</bool> + </property> + <property name="text"> + <string>500 x 500</string> + </property> + </action> + <action name="action_Disconnect"> + <property name="icon"> + <iconset resource="../../../pvsmgr.qrc"> + <normaloff>:/logout</normaloff>:/logout</iconset> + </property> + <property name="text"> + <string>&Disconnect</string> + </property> + <property name="shortcut"> + <string>Ctrl+W</string> + </property> + </action> + <action name="action_Exit"> + <property name="icon"> + <iconset resource="../../../pvsmgr.qrc"> + <normaloff>:/exit</normaloff> + <normalon>:/exit</normalon>:/exit</iconset> + </property> + <property name="text"> + <string>&Exit</string> + </property> + <property name="shortcut"> + <string>Ctrl+Q</string> + </property> + </action> + <action name="actionFoto"> + <property name="icon"> + <iconset resource="../../../pvsmgr.qrc"> + <normaloff>:/photos</normaloff>:/photos</iconset> + </property> + <property name="text"> + <string>Foto</string> + </property> + <property name="toolTip"> + <string>Foto</string> + </property> + </action> + <action name="actionView"> + <property name="icon"> + <iconset resource="../../../pvsmgr.qrc"> + <normaloff>:/restore</normaloff>:/restore</iconset> + </property> + <property name="text"> + <string>view</string> + </property> + <property name="toolTip"> + <string>View</string> + </property> + </action> + <action name="actionLock"> + <property name="icon"> + <iconset resource="../../../pvsmgr.qrc"> + <normaloff>:/lock</normaloff>:/lock</iconset> + </property> + <property name="text"> + <string>lock</string> + </property> + <property name="toolTip"> + <string>Lock All Clients</string> + </property> + </action> + <action name="actionCreate_profile"> + <property name="icon"> + <iconset resource="../../../pvsmgr.qrc"> + <normaloff>:/profile</normaloff>:/profile</iconset> + </property> + <property name="text"> + <string>Create profile</string> + </property> + </action> + <action name="actionresetall"> + <property name="icon"> + <iconset> + <activeon>:/icons/reset.png</activeon> + </iconset> + </property> + <property name="text"> + <string>resetall</string> + </property> + <property name="toolTip"> + <string>Reset Projections and Locks</string> + </property> + <property name="shortcut"> + <string>Ctrl+R</string> + </property> + </action> + <action name="actionLocksingle"> + <property name="icon"> + <iconset resource="../../../pvsmgr.qrc"> + <normaloff>:/icons/locksingle.png</normaloff>:/icons/locksingle.png</iconset> + </property> + <property name="text"> + <string>locksingle</string> + </property> + <property name="toolTip"> + <string>Locks a Single Target</string> + </property> + </action> + <action name="actionUnlocksingle"> + <property name="icon"> + <iconset resource="../../../pvsmgr.qrc"> + <normaloff>:/icons/unlocksingle.png</normaloff>:/icons/unlocksingle.png</iconset> + </property> + <property name="text"> + <string>unlocksingle</string> + </property> + <property name="toolTip"> + <string>Unlocks a single target</string> + </property> + </action> + <action name="actionProjection"> + <property name="icon"> + <iconset resource="../../../pvsmgr.qrc"> + <normaloff>:/icons/projection.png</normaloff>:/icons/projection.png</iconset> + </property> + <property name="text"> + <string>projection</string> + </property> + <property name="toolTip"> + <string>Projects a single target</string> + </property> + </action> + <action name="actionUnprojection"> + <property name="icon"> + <iconset resource="../../../pvsmgr.qrc"> + <normaloff>:/icons/unprojection.png</normaloff>:/icons/unprojection.png</iconset> + </property> + <property name="text"> + <string>unprojection</string> + </property> + <property name="toolTip"> + <string>Unprojects a single target</string> + </property> + </action> + <action name="actionDozent"> + <property name="icon"> + <iconset resource="../../../pvsmgr.qrc"> + <normaloff>:/dozent2</normaloff>:/dozent2</iconset> + </property> + <property name="text"> + <string>dozent</string> + </property> + <property name="toolTip"> + <string>Select Tutor PC</string> + </property> + </action> + <action name="actionShow_Fullname"> + <property name="text"> + <string>Show Name</string> + </property> + </action> + <action name="actionChat"> + <property name="icon"> + <iconset resource="../../../pvsmgr.qrc"> + <normaloff>:/chat</normaloff>:/chat</iconset> + </property> + <property name="text"> + <string>Chat</string> + </property> + <property name="toolTip"> + <string>Start chat with client(s)</string> + </property> + <property name="shortcut"> + <string>Ctrl+D</string> + </property> + </action> + </widget> + <layoutdefault spacing="6" margin="11"/> + <resources> + <include location="../../../pvsmgr.qrc"/> + </resources> + <connections/> +</ui> diff --git a/src/gui/ui/profileDialog.ui b/src/gui/ui/profileDialog.ui new file mode 100644 index 0000000..3302a56 --- /dev/null +++ b/src/gui/ui/profileDialog.ui @@ -0,0 +1,179 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>Dialog</class> + <widget class="QDialog" name="Dialog"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>332</width> + <height>485</height> + </rect> + </property> + <property name="windowTitle"> + <string>ProfileDialog</string> + </property> + <layout class="QGridLayout" name="gridLayout_3"> + <item row="0" column="0"> + <layout class="QVBoxLayout" name="verticalLayout_2"> + <item> + <widget class="QSplitter" name="splitter"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <widget class="QWidget" name="widget" native="true"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Preferred" vsizetype="Preferred"> + <horstretch>1</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="styleSheet"> + <string>background-color: rgb(255, 255, 255);</string> + </property> + <layout class="QGridLayout" name="gridLayout_2"> + <item row="0" column="0"> + <layout class="QGridLayout" name="gridLayout"/> + </item> + </layout> + </widget> + <widget class="QWidget" name="layoutWidget_2"> + <layout class="QVBoxLayout" name="verticalLayout"> + <item> + <widget class="QPushButton" name="remove"> + <property name="text"> + <string>&Remove</string> + </property> + </widget> + </item> + <item> + <spacer name="verticalSpacer_6"> + <property name="orientation"> + <enum>Qt::Vertical</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>20</width> + <height>40</height> + </size> + </property> + </spacer> + </item> + <item> + <spacer name="verticalSpacer"> + <property name="orientation"> + <enum>Qt::Vertical</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>20</width> + <height>18</height> + </size> + </property> + </spacer> + </item> + <item> + <widget class="QPushButton" name="edit"> + <property name="text"> + <string>&Edit</string> + </property> + </widget> + </item> + <item> + <spacer name="verticalSpacer_5"> + <property name="orientation"> + <enum>Qt::Vertical</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>20</width> + <height>40</height> + </size> + </property> + </spacer> + </item> + <item> + <spacer name="verticalSpacer_2"> + <property name="orientation"> + <enum>Qt::Vertical</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>20</width> + <height>18</height> + </size> + </property> + </spacer> + </item> + <item> + <widget class="QPushButton" name="new_2"> + <property name="text"> + <string>&New</string> + </property> + </widget> + </item> + <item> + <spacer name="verticalSpacer_4"> + <property name="orientation"> + <enum>Qt::Vertical</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>20</width> + <height>40</height> + </size> + </property> + </spacer> + </item> + <item> + <widget class="QPushButton" name="load"> + <property name="text"> + <string>&Load</string> + </property> + </widget> + </item> + <item> + <spacer name="verticalSpacer_3"> + <property name="orientation"> + <enum>Qt::Vertical</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>20</width> + <height>218</height> + </size> + </property> + </spacer> + </item> + </layout> + </widget> + </widget> + </item> + <item> + <layout class="QHBoxLayout" name="horizontalLayout_2"> + <item> + <widget class="QLineEdit" name="lineEdit"/> + </item> + <item> + <widget class="QPushButton" name="add"> + <property name="text"> + <string>Add</string> + </property> + </widget> + </item> + </layout> + </item> + <item> + <widget class="QPushButton" name="close"> + <property name="text"> + <string>Close</string> + </property> + </widget> + </item> + </layout> + </item> + </layout> + </widget> + <resources/> + <connections/> +</ui> diff --git a/src/gui/ui/projectionDialog.ui b/src/gui/ui/projectionDialog.ui new file mode 100644 index 0000000..17cdf05 --- /dev/null +++ b/src/gui/ui/projectionDialog.ui @@ -0,0 +1,98 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>projectionDialog</class> + <widget class="QDialog" name="projectionDialog"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>234</width> + <height>282</height> + </rect> + </property> + <property name="windowTitle"> + <string>Dialog</string> + </property> + <layout class="QGridLayout" name="gridLayout_2"> + <item row="1" column="0"> + <widget class="QFrame" name="frame"> + <property name="styleSheet"> + <string notr="true">QFrame{ +border-color: rgb(0, 0, 0); +border: 1px outset black; +}</string> + </property> + <property name="frameShape"> + <enum>QFrame::StyledPanel</enum> + </property> + <property name="frameShadow"> + <enum>QFrame::Sunken</enum> + </property> + <layout class="QGridLayout" name="gridLayout"> + <item row="0" column="0"> + <layout class="QVBoxLayout" name="verticalLayout_2"/> + </item> + </layout> + </widget> + </item> + <item row="2" column="0"> + <layout class="QVBoxLayout" name="verticalLayout"> + <item> + <widget class="QCheckBox" name="checkBox"> + <property name="text"> + <string>Select all</string> + </property> + </widget> + </item> + <item> + <layout class="QHBoxLayout" name="horizontalLayout"> + <item> + <spacer name="horizontalSpacer"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>108</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + <item> + <widget class="QPushButton" name="cancel"> + <property name="text"> + <string>Cancel</string> + </property> + </widget> + </item> + <item> + <widget class="QPushButton" name="send"> + <property name="text"> + <string>Project</string> + </property> + </widget> + </item> + </layout> + </item> + </layout> + </item> + <item row="0" column="0"> + <widget class="QLabel" name="label"> + <property name="maximumSize"> + <size> + <width>16777215</width> + <height>15</height> + </size> + </property> + <property name="text"> + <string>Select Target for projection</string> + </property> + </widget> + </item> + </layout> + </widget> + <layoutdefault spacing="6" margin="11"/> + <resources/> + <connections/> +</ui> diff --git a/src/gui/ui/serverChatDialog.ui b/src/gui/ui/serverChatDialog.ui new file mode 100644 index 0000000..973d803 --- /dev/null +++ b/src/gui/ui/serverChatDialog.ui @@ -0,0 +1,121 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>ServerChatDialogClass</class> + <widget class="QDialog" name="ServerChatDialogClass"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>641</width> + <height>659</height> + </rect> + </property> + <property name="windowTitle"> + <string>PVSmgr - Chat </string> + </property> + <property name="windowIcon"> + <iconset resource="../../../pvsgui.qrc"> + <normaloff>:/cam32.svg</normaloff>:/cam32.svg</iconset> + </property> + <property name="locale"> + <locale language="English" country="UnitedStates"/> + </property> + <layout class="QVBoxLayout" name="verticalLayout_2"> + <item> + <widget class="QSplitter" name="splitter"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Expanding" vsizetype="Expanding"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <widget class="QListWidget" name="listWidget"> + <property name="maximumSize"> + <size> + <width>150</width> + <height>16777215</height> + </size> + </property> + <property name="contextMenuPolicy"> + <enum>Qt::CustomContextMenu</enum> + </property> + <property name="sortingEnabled"> + <bool>true</bool> + </property> + </widget> + <widget class="QTabWidget" name="tabWidget"> + <property name="tabPosition"> + <enum>QTabWidget::South</enum> + </property> + <property name="tabsClosable"> + <bool>true</bool> + </property> + <widget class="QWidget" name="tab"> + <attribute name="title"> + <string notr="true">@all</string> + </attribute> + <layout class="QVBoxLayout" name="verticalLayout"/> + </widget> + </widget> + </widget> + </item> + <item> + <widget class="QLineEdit" name="lineEdit"/> + </item> + <item> + <layout class="QHBoxLayout" name="horizontalLayout"> + <item> + <spacer name="horizontalSpacer"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>40</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + <item> + <widget class="QPushButton" name="pushButton"> + <property name="text"> + <string>&Send</string> + </property> + <property name="autoDefault"> + <bool>false</bool> + </property> + <property name="default"> + <bool>true</bool> + </property> + </widget> + </item> + </layout> + </item> + </layout> + </widget> + <resources> + <include location="../../../pvsgui.qrc"/> + </resources> + <connections> + <connection> + <sender>lineEdit</sender> + <signal>returnPressed()</signal> + <receiver>pushButton</receiver> + <slot>click()</slot> + <hints> + <hint type="sourcelabel"> + <x>252</x> + <y>560</y> + </hint> + <hint type="destinationlabel"> + <x>529</x> + <y>589</y> + </hint> + </hints> + </connection> + </connections> +</ui> diff --git a/src/gui/ui/startdialog.ui b/src/gui/ui/startdialog.ui new file mode 100644 index 0000000..8001862 --- /dev/null +++ b/src/gui/ui/startdialog.ui @@ -0,0 +1,195 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>Test</class> + <widget class="QDialog" name="Test"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>367</width> + <height>300</height> + </rect> + </property> + <property name="windowTitle"> + <string>Dialog</string> + </property> + <widget class="QDialogButtonBox" name="buttonBox"> + <property name="geometry"> + <rect> + <x>20</x> + <y>250</y> + <width>341</width> + <height>32</height> + </rect> + </property> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="standardButtons"> + <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set> + </property> + </widget> + <widget class="QWidget" name="gridLayoutWidget"> + <property name="geometry"> + <rect> + <x>60</x> + <y>10</y> + <width>301</width> + <height>231</height> + </rect> + </property> + <layout class="QGridLayout" name="gridLayout"> + <item row="1" column="0"> + <widget class="QCheckBox" name="checkBox"> + <property name="toolTip"> + <string>Zur Bedienung mit Tastatur und Maus</string> + </property> + <property name="text"> + <string>Standard-Oberfläche</string> + </property> + </widget> + </item> + <item row="3" column="0"> + <widget class="QCheckBox" name="checkBox_2"> + <property name="toolTip"> + <string>Zur Bedienung an einem Touchscreen</string> + </property> + <property name="text"> + <string>Touchscreen-Oberfläche</string> + </property> + </widget> + </item> + <item row="2" column="0"> + <widget class="Line" name="line"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + </widget> + </item> + <item row="0" column="0"> + <widget class="Line" name="line_2"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + </widget> + </item> + <item row="4" column="0"> + <widget class="Line" name="line_3"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + </widget> + </item> + </layout> + </widget> + <widget class="KIconButton" name="kiconbutton"> + <property name="geometry"> + <rect> + <x>0</x> + <y>150</y> + <width>51</width> + <height>41</height> + </rect> + </property> + <property name="styleSheet"> + <string notr="true">background-image: url(:icons/touch.jpg);</string> + </property> + </widget> + <widget class="KIconButton" name="kiconbutton_2"> + <property name="geometry"> + <rect> + <x>0</x> + <y>60</y> + <width>51</width> + <height>41</height> + </rect> + </property> + <property name="styleSheet"> + <string notr="true">background-image: url(:icons/keyboard.jpg);</string> + </property> + </widget> + </widget> + <customwidgets> + <customwidget> + <class>KIconButton</class> + <extends>QPushButton</extends> + <header>kicondialog.h</header> + </customwidget> + </customwidgets> + <tabstops> + <tabstop>buttonBox</tabstop> + <tabstop>kiconbutton_2</tabstop> + <tabstop>checkBox_2</tabstop> + <tabstop>checkBox</tabstop> + <tabstop>kiconbutton</tabstop> + </tabstops> + <resources> + <include location="startdialog.qrc"/> + </resources> + <connections> + <connection> + <sender>buttonBox</sender> + <signal>accepted()</signal> + <receiver>Test</receiver> + <slot>accept()</slot> + <hints> + <hint type="sourcelabel"> + <x>248</x> + <y>254</y> + </hint> + <hint type="destinationlabel"> + <x>157</x> + <y>274</y> + </hint> + </hints> + </connection> + <connection> + <sender>buttonBox</sender> + <signal>rejected()</signal> + <receiver>Test</receiver> + <slot>reject()</slot> + <hints> + <hint type="sourcelabel"> + <x>316</x> + <y>260</y> + </hint> + <hint type="destinationlabel"> + <x>286</x> + <y>274</y> + </hint> + </hints> + </connection> + <connection> + <sender>checkBox</sender> + <signal>toggled(bool)</signal> + <receiver>checkBox_2</receiver> + <slot>setDisabled(bool)</slot> + <hints> + <hint type="sourcelabel"> + <x>180</x> + <y>81</y> + </hint> + <hint type="destinationlabel"> + <x>180</x> + <y>169</y> + </hint> + </hints> + </connection> + <connection> + <sender>checkBox_2</sender> + <signal>toggled(bool)</signal> + <receiver>checkBox</receiver> + <slot>setDisabled(bool)</slot> + <hints> + <hint type="sourcelabel"> + <x>180</x> + <y>169</y> + </hint> + <hint type="destinationlabel"> + <x>180</x> + <y>81</y> + </hint> + </hints> + </connection> + </connections> +</ui> diff --git a/src/gui/ui/touchgui.ui b/src/gui/ui/touchgui.ui new file mode 100644 index 0000000..05d7614 --- /dev/null +++ b/src/gui/ui/touchgui.ui @@ -0,0 +1,322 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>PVSMainWindow</class> + <widget class="QMainWindow" name="PVSMainWindow"> + <property name="windowModality"> + <enum>Qt::NonModal</enum> + </property> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>800</width> + <height>600</height> + </rect> + </property> + <property name="minimumSize"> + <size> + <width>800</width> + <height>600</height> + </size> + </property> + <property name="maximumSize"> + <size> + <width>800</width> + <height>600</height> + </size> + </property> + <property name="cursor"> + <cursorShape>PointingHandCursor</cursorShape> + </property> + <property name="windowTitle"> + <string>MainWindow</string> + </property> + <widget class="QWidget" name="centralWidget"> + <widget class="QWidget" name="horizontalLayoutWidget"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>801</width> + <height>41</height> + </rect> + </property> + <layout class="QHBoxLayout" name="ButtonList"> + <item> + <widget class="QComboBox" name="AllUsersBox"> + <property name="font"> + <font> + <pointsize>15</pointsize> + </font> + </property> + <item> + <property name="text"> + <string>Alle</string> + </property> + </item> + <item> + <property name="text"> + <string>Sperren/entsperren</string> + </property> + </item> + <item> + <property name="text"> + <string>Beamerbild verteilen</string> + </property> + </item> + </widget> + </item> + <item> + <widget class="QComboBox" name="MarkedUsersBox"> + <property name="font"> + <font> + <pointsize>15</pointsize> + </font> + </property> + <item> + <property name="text"> + <string>Auswahl</string> + </property> + </item> + <item> + <property name="text"> + <string>Aktualisieren</string> + </property> + </item> + <item> + <property name="text"> + <string>Sperren/Entsperren</string> + </property> + </item> + <item> + <property name="text"> + <string>Einzelansicht</string> + </property> + </item> + <item> + <property name="text"> + <string>Einzelhilfe</string> + </property> + </item> + </widget> + </item> + <item> + <widget class="QPushButton" name="PropertyButton"> + <property name="font"> + <font> + <pointsize>15</pointsize> + </font> + </property> + <property name="text"> + <string>Einstellungen</string> + </property> + </widget> + </item> + <item> + <widget class="QPushButton" name="ExitButton"> + <property name="font"> + <font> + <pointsize>15</pointsize> + </font> + </property> + <property name="text"> + <string>Beenden</string> + </property> + </widget> + </item> + </layout> + </widget> + <widget class="QWidget" name="horizontalLayoutWidget_2"> + <property name="geometry"> + <rect> + <x>0</x> + <y>530</y> + <width>801</width> + <height>31</height> + </rect> + </property> + <layout class="QHBoxLayout" name="Slider"> + <item> + <widget class="QPushButton" name="NavigateLeft"> + <property name="text"> + <string><-</string> + </property> + </widget> + </item> + <item> + <widget class="QSlider" name="horizontalSlider"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + </widget> + </item> + <item> + <widget class="QPushButton" name="NavigateRight"> + <property name="text"> + <string>-></string> + </property> + </widget> + </item> + </layout> + </widget> + <widget class="QWidget" name="ClWidget" native="true"> + <property name="geometry"> + <rect> + <x>0</x> + <y>40</y> + <width>151</width> + <height>481</height> + </rect> + </property> + <property name="minimumSize"> + <size> + <width>150</width> + <height>240</height> + </size> + </property> + <property name="styleSheet"> + <string>background-color: rgb(255, 255, 255);</string> + </property> + <layout class="QGridLayout" name="gridLayout_5"> + <item row="0" column="0"> + <layout class="QGridLayout" name="ClientGLayout"/> + </item> + </layout> + </widget> + <widget class="QWidget" name="widget" native="true"> + <property name="geometry"> + <rect> + <x>160</x> + <y>40</y> + <width>631</width> + <height>481</height> + </rect> + </property> + <property name="styleSheet"> + <string>background-color: rgb(150, 150, 150);</string> + </property> + <layout class="QGridLayout" name="gridLayout_4"> + <item row="0" column="0"> + <layout class="QVBoxLayout" name="VconWinLayout"/> + </item> + </layout> + </widget> + </widget> + <widget class="QMenuBar" name="menuBar"> + <property name="enabled"> + <bool>true</bool> + </property> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>800</width> + <height>24</height> + </rect> + </property> + <widget class="QMenu" name="menuTestApp"> + <property name="title"> + <string>Datei</string> + </property> + <addaction name="actionDisconnect"/> + <addaction name="actionBeenden"/> + </widget> + <widget class="QMenu" name="menuAnsicht"> + <property name="title"> + <string>Ansicht</string> + </property> + <addaction name="actionVollbild"/> + </widget> + <widget class="QMenu" name="menuHilfe"> + <property name="title"> + <string>Hilfe</string> + </property> + <addaction name="actionGibts_noch_keine"/> + </widget> + <widget class="QMenu" name="menuLogging"> + <property name="title"> + <string>Logging</string> + </property> + </widget> + <addaction name="menuTestApp"/> + <addaction name="menuAnsicht"/> + <addaction name="menuHilfe"/> + <addaction name="menuLogging"/> + </widget> + <action name="actionBeenden"> + <property name="text"> + <string>Beenden</string> + </property> + <property name="shortcut"> + <string>Alt+B</string> + </property> + </action> + <action name="actionGibts_noch_keine"> + <property name="text"> + <string>Version</string> + </property> + </action> + <action name="actionVollbild"> + <property name="text"> + <string>Vollbild</string> + </property> + </action> + <action name="actionDisconnect"> + <property name="text"> + <string>Disconnect</string> + </property> + </action> + </widget> + <layoutdefault spacing="6" margin="11"/> + <resources/> + <connections> + <connection> + <sender>actionBeenden</sender> + <signal>activated()</signal> + <receiver>PVSMainWindow</receiver> + <slot>close()</slot> + <hints> + <hint type="sourcelabel"> + <x>-1</x> + <y>-1</y> + </hint> + <hint type="destinationlabel"> + <x>399</x> + <y>299</y> + </hint> + </hints> + </connection> + <connection> + <sender>ExitButton</sender> + <signal>clicked()</signal> + <receiver>PVSMainWindow</receiver> + <slot>close()</slot> + <hints> + <hint type="sourcelabel"> + <x>109</x> + <y>129</y> + </hint> + <hint type="destinationlabel"> + <x>299</x> + <y>199</y> + </hint> + </hints> + </connection> + <connection> + <sender>actionVollbild</sender> + <signal>activated()</signal> + <receiver>PVSMainWindow</receiver> + <slot>showMaximized()</slot> + <hints> + <hint type="sourcelabel"> + <x>-1</x> + <y>-1</y> + </hint> + <hint type="destinationlabel"> + <x>399</x> + <y>299</y> + </hint> + </hints> + </connection> + </connections> +</ui> |
