diff options
Diffstat (limited to 'src/gui/clientFileReceiveDialog.cpp')
| -rw-r--r-- | src/gui/clientFileReceiveDialog.cpp | 181 |
1 files changed, 181 insertions, 0 deletions
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); +} |
