summaryrefslogtreecommitdiffstats
path: root/src/pvsgui.cpp
diff options
context:
space:
mode:
authorSebastian2010-05-12 19:42:27 +0200
committerSebastian2010-05-12 19:42:27 +0200
commitce3329047d378a14006ce74ec273ac59e3375303 (patch)
tree782430f270b4c7aca1b35d5b7813518e3797c555 /src/pvsgui.cpp
downloadpvs-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.cpp444
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();
+}