summaryrefslogtreecommitdiffstats
path: root/src/gui/clientFileSendDialog.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/gui/clientFileSendDialog.cpp')
-rw-r--r--src/gui/clientFileSendDialog.cpp248
1 files changed, 248 insertions, 0 deletions
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();
+}