diff options
Diffstat (limited to 'src/gui/clientFileSendDialog.cpp')
| -rw-r--r-- | src/gui/clientFileSendDialog.cpp | 248 |
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(); +} |
