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/pvsgui.cpp | |
download | pvs-ce3329047d378a14006ce74ec273ac59e3375303.tar.gz pvs-ce3329047d378a14006ce74ec273ac59e3375303.tar.xz pvs-ce3329047d378a14006ce74ec273ac59e3375303.zip |
initial import of latest svn version
Diffstat (limited to 'src/pvsgui.cpp')
-rw-r--r-- | src/pvsgui.cpp | 444 |
1 files changed, 444 insertions, 0 deletions
diff --git a/src/pvsgui.cpp b/src/pvsgui.cpp new file mode 100644 index 0000000..25f1cd6 --- /dev/null +++ b/src/pvsgui.cpp @@ -0,0 +1,444 @@ +/* + # 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/ + # ----------------------------------------------------------------------------- + # pvsClientGUI.cpp + # - main loop for pvs client GUI. + # - draws toolbar and system tray icon. + # - uses DBUS to communicate with pvs client. + # ----------------------------------------------------------------------------- + */ + +#include "pvsgui.h" + +PVSGUI::PVSGUI(QWidget *parent) : + QWidget(parent) +{ + setupUi(this); + + _menu = new QMenu(this); + _hostMenu = new QMenu(tr("Connect"), this); + _hosts = new QHash<QString, QAction*> (); + _vncViewer = new ClientVNCViewer(); + _chatDialog = new ClientChatDialog(); + _configDialog = new ClientConfigDialog(); + _infoDialog = new ClientInfoDialog(); + _aboutDialog = new AboutDialog(); + + _hostMenu->setEnabled(false); + hostButton->setEnabled(false); + + setupMenu(); + + if (QSystemTrayIcon::isSystemTrayAvailable()) + { + qDebug("[%s] System tray available.", metaObject()->className()); + _trayIcon = new QSystemTrayIcon(QIcon(":cam_off32.svg"), this); + _trayIcon->setContextMenu(_menu); + _trayIcon->setVisible(true); + _chatDialog->setTrayIcon(_trayIcon); + } + else + _trayIcon = NULL; + + // connect to D-Bus and get interface + QDBusConnection dbus = QDBusConnection::sessionBus(); + dbus.registerObject("/", this); + dbus.registerService("org.openslx.pvsgui"); + _ifaceDBus = new OrgOpenslxPvsInterface("org.openslx.pvs", "/", dbus, this); + _ifaceDBus->start(); // start pvs if not running + + // get available hosts + QDBusPendingReply<QStringList> reply0 = _ifaceDBus->getAvailableHosts(); + reply0.waitForFinished(); + QStringList hosts = reply0.value(); + if (reply0.isValid() && !hosts.isEmpty()) + foreach (QString host, hosts) + addHost(host); + + // already connected? + QDBusPendingReply<QString> reply1 = _ifaceDBus->isConnected(); + reply1.waitForFinished(); + QString host = reply1.value(); + if (reply1.isValid() && host != "") + connected(host); + else + disconnected(); + + if (dbus.isConnected()) + qDebug("[%s] Connection to DBus successful!", metaObject()->className()); + + // TODO: perhaps this can go if fadi does his work + // check if vnc is allowed and setup checkbox + QFile file(QDir::toNativeSeparators(QDir::homePath() + "/.pvs/.allow")); + if (file.open(QIODevice::ReadOnly | QIODevice::Text)) + { + QTextStream in(&file); + QString line = in.readLine(); + if (line == "1") + vncCheckBox->setChecked(true); + file.close(); + } + + // listen on port 29481 for incoming file transfers + _serverSocket = new QTcpServer(); + _serverSocket->listen(QHostAddress::Any, 29481); + connect(_serverSocket, SIGNAL(newConnection()), this, SLOT(receiveFile())); + + // signals & slots - menu + connect(_disconnectAction, SIGNAL(triggered()), this, SLOT(pvsDisconnect())); + connect(_startChatAction, SIGNAL(triggered()), _chatDialog, SLOT(open())); + connect(_sendFileAction, SIGNAL(triggered()), this, SLOT(sendFile())); + connect(_configAction, SIGNAL(triggered()), _configDialog, SLOT(open())); + connect(_showInfoAction, SIGNAL(triggered()), _infoDialog, SLOT(open())); + connect(_aboutAction, SIGNAL(triggered()), _aboutDialog, SLOT(open())); + connect(_quitAction, SIGNAL(triggered()), qApp, SLOT(quit())); + connect(_configDialog, SIGNAL(configChanged()), this, SLOT(updateConfig())); + + // signals & slots - toolbar + connect(_menu, SIGNAL(aboutToHide()), this, SLOT(hide())); + connect(_hostMenu, SIGNAL(aboutToHide()), this, SLOT(hide())); + connect(_hostMenu, SIGNAL(triggered(QAction*)), this, + SLOT(pvsConnect(QAction*))); + connect(vncCheckBox, SIGNAL(stateChanged(int)), this, + SLOT(setVncAllow(int))); + + // signals & slots - dbus + connect(_ifaceDBus, SIGNAL(showMessage(QString, QString, bool)), this, + SLOT(showMessage(QString, QString, bool))); + connect(_ifaceDBus, SIGNAL(connected(QString)), this, + SLOT(connected(QString))); + connect(_ifaceDBus, SIGNAL(disconnected()), this, SLOT(disconnected())); + connect(_ifaceDBus, SIGNAL(addHost(QString)), this, SLOT(addHost(QString))); + connect(_ifaceDBus, SIGNAL(delHost(QString)), this, SLOT(delHost(QString))); + + // show toolbar + setWindowFlags(Qt::WindowStaysOnTopHint | Qt::X11BypassWindowManagerHint); + setAttribute(Qt::WA_AlwaysShowToolTips); + updateConfig(); + setVisible(true); + hide(); +} + +PVSGUI::~PVSGUI() +{ + _ifaceDBus->quit(); +} + +//////////////////////////////////////////////////////////////////////////////// +// Public + +void PVSGUI::updateConfig() +{ + if (_settings.value("Display/location").isNull()) + setLocation(POSITION_TOP_CENTER); + else + setLocation(_settings.value("Display/location").toInt()); +} + +//////////////////////////////////////////////////////////////////////////////// +// Protected + +void PVSGUI::leaveEvent(QEvent * e) +{ + if (!_menu->isVisible() && !_hostMenu->isVisible()) + hide(true); + QWidget::leaveEvent(e); +} + +void PVSGUI::enterEvent(QEvent * e) +{ + hide(false); + QWidget::enterEvent(e); +} + +void PVSGUI::mousePressEvent(QMouseEvent *event) +{ + QApplication::setOverrideCursor(QCursor(Qt::ClosedHandCursor)); + _clickPoint = event->pos(); +} + +void PVSGUI::mouseReleaseEvent(QMouseEvent *event) +{ + QApplication::setOverrideCursor(QCursor(Qt::ArrowCursor)); +} + +void PVSGUI::mouseMoveEvent(QMouseEvent *event) +{ + if (event->globalX() - _clickPoint.x() >= 0 && event->globalX() + - _clickPoint.x() + width() <= QApplication::desktop()->width()) + { + move(event->globalX() - _clickPoint.x(), y()); + } +} + +//////////////////////////////////////////////////////////////////////////////// +// Private + +void PVSGUI::setupMenu() +{ + // setup actions + _disconnectAction = new QAction(tr("&Disconnect"), this); + _startChatAction = new QAction(tr("C&hat"), this); + _sendFileAction = new QAction(tr("&Send File"), this); + _configAction = new QAction(tr("&Config"), this); + _showInfoAction = new QAction(tr("&Information"), this); + _aboutAction = new QAction(tr("&About"), this); + _quitAction = new QAction(tr("&Quit"), this); + + // setup menu + _menu->addMenu(_hostMenu); + _menu->addAction(_disconnectAction); + _menu->addAction(_showInfoAction); + _menu->addSeparator(); + _menu->addAction(_startChatAction); + _menu->addAction(_sendFileAction); + _menu->addSeparator(); + _menu->addAction(_configAction); + _menu->addAction(_aboutAction); + _menu->addSeparator(); + _menu->addAction(_quitAction); + + pvsButton->setMenu(_menu); + hostButton->setMenu(_hostMenu); +} + +void PVSGUI::setLocation(int location) +{ + _location = location; + switch (_location) + { + case POSITION_TOP_LEFT: + move(0, 0); + break; + case POSITION_TOP_CENTER: + move((QApplication::desktop()->width() - width()) / 2, 0); + break; + case POSITION_TOP_RIGHT: + move(QApplication::desktop()->width() - width(), 0); + break; + case POSITION_BOTTOM_LEFT: + move(0, QApplication::desktop()->height() - height()); + break; + case POSITION_BOTTOM_CENTER: + move((QApplication::desktop()->width() - width()) / 2, + QApplication::desktop()->height() - height()); + break; + case POSITION_BOTTOM_RIGHT: + move(QApplication::desktop()->width() - width(), + QApplication::desktop()->height() - height()); + break; + default: + break; + } +} + +void PVSGUI::hide(bool b) +{ + if (b) + { + if (_location <= POSITION_TOP_RIGHT) + move(x(), 2 - height()); + else + move(x(), QApplication::desktop()->height() - 2); + } + else + { + if (_location <= POSITION_TOP_RIGHT) + move(x(), 0); + else + move(x(), QApplication::desktop()->height() - height()); + } +} + +void PVSGUI::hide() +{ + if (!_menu->isVisible() && !_hostMenu->isVisible()) + hide(true); +} + +void PVSGUI::pvsConnect(QAction *action) +{ + QString host = action->text(); + action->setChecked(false); // we set it manually + + // already connected? + if (host == hostButton->text()) + { + action->setChecked(true); + return; + } + + // ask user for passwd + bool ok = false; + QString passwd = QInputDialog::getText(0, tr("PVS Connection"), tr( + "Please enter password (If not needed leave blank):"), + QLineEdit::Password, QString(), &ok); + + if (ok) + { + _ifaceDBus->pvsConnect(host, passwd); // send via dbus + _passwd = passwd; // TODO: we have to ask the backend for passwd! + qDebug("[%s] Host '%s' send via DBus.", metaObject()->className(), + qPrintable(host)); + } +} + +void PVSGUI::pvsDisconnect() +{ + QMessageBox::StandardButton result = QMessageBox::question(0, tr( + "PVS Connection"), tr("Are you sure you want to disconnect?"), + QMessageBox::Ok | QMessageBox::Cancel, QMessageBox::Ok); + + if (result == QMessageBox::Ok) + _ifaceDBus->pvsDisconnect(); +} + +void PVSGUI::showMessage(QString title, QString msg, bool useDialog) +{ + if (!isVisible()) + return; + + // show balloon message if supported, otherwise show message dialog + if (!useDialog && _trayIcon && QSystemTrayIcon::supportsMessages()) + _trayIcon->showMessage(title, msg, QSystemTrayIcon::Information, 10000); + else + QMessageBox::about(0, title, msg); +} + +void PVSGUI::connected(QString host) +{ + statusLabel->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=\" color:#00aa00;\">Online</span></p></body></html>"); + showMessage(tr("PVS connection"), tr("Connected to ") + host); + if (_hosts->contains(host)) + _hosts->value(host)->setChecked(true); + hostButton->setText(host); + _disconnectAction->setEnabled(true); + _startChatAction->setEnabled(true); + _sendFileAction->setEnabled(true); + _showInfoAction->setEnabled(true); + _infoDialog->setHost(host); + _infoDialog->setPasswd(_passwd); + + if (_trayIcon) + { + _trayIcon->setIcon(QIcon(":cam_on32.svg")); + _trayIcon->setToolTip(tr("Connected to ") + host); + } +} + +void PVSGUI::disconnected() +{ + statusLabel->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=\" color:#ff0000;\">Offline</span></p></body></html>"); + showMessage(tr("PVS connection"), tr("Disconnected")); + if (_hosts->contains(hostButton->text())) + _hosts->value(hostButton->text())->setChecked(false); + hostButton->setText("-"); + _disconnectAction->setEnabled(false); + _startChatAction->setEnabled(false); + _sendFileAction->setEnabled(false); + _showInfoAction->setEnabled(false); + _passwd = ""; + if (_trayIcon) + { + _trayIcon->setIcon(QIcon(":cam_off32.svg")); + _trayIcon->setToolTip(tr("Disconnected")); + } + _vncViewer->close(); +} + +void PVSGUI::addHost(QString host) +{ + // avoid duplicates + if (_hosts->contains(host)) + return; + + QAction *action = _hostMenu->addAction(host); + action->setCheckable(true); + _hosts->insert(host, action); + + if (!_hosts->isEmpty()) + { + _hostMenu->setEnabled(true); + hostButton->setEnabled(true); + } + + if (hostButton->text() == "-") + showMessage(tr("PVS Connection"), tr("New host available: ") + host); +} + +void PVSGUI::delHost(QString host) +{ + if (_hosts->contains(host)) + { + _hostMenu->removeAction(_hosts->value(host)); + _hosts->remove(host); + } + + if (_hosts->isEmpty()) + { + _hostMenu->setEnabled(false); + hostButton->setEnabled(false); + } +} + +// TODO: perhaps this can go if fadi does his work +void PVSGUI::setVncAllow(int i) +{ + QFile file(QDir::toNativeSeparators(QDir::homePath() + "/.pvs/.allow")); + if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) + return; + + QTextStream out(&file); + if (i == 0) + out << 0; + else + out << 1; + + file.close(); +} + +void PVSGUI::sendFile() +{ + ClientFileSendDialog *d = new ClientFileSendDialog(); + d->open(); +} + +void PVSGUI::receiveFile() +{ + QTcpSocket *socket = _serverSocket->nextPendingConnection(); + ClientFileReceiveDialog *d = new ClientFileReceiveDialog(socket); + d->open(); +} + +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +// Main + +int main(int argc, char *argv[]) +{ + QApplication app(argc, argv); + app.setOrganizationName("openslx"); + app.setOrganizationDomain("openslx.org"); + app.setApplicationName("pvsgui"); + + // use system locale as language to translate gui + QTranslator translator; + translator.load(":pvsgui"); + app.installTranslator(&translator); + + PVSGUI pvsgui; + + return app.exec(); +} |