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/gui/serverFileTransfert.cpp | |
| download | pvs-ce3329047d378a14006ce74ec273ac59e3375303.tar.gz pvs-ce3329047d378a14006ce74ec273ac59e3375303.tar.xz pvs-ce3329047d378a14006ce74ec273ac59e3375303.zip | |
initial import of latest svn version
Diffstat (limited to 'src/gui/serverFileTransfert.cpp')
| -rw-r--r-- | src/gui/serverFileTransfert.cpp | 265 |
1 files changed, 265 insertions, 0 deletions
diff --git a/src/gui/serverFileTransfert.cpp b/src/gui/serverFileTransfert.cpp new file mode 100644 index 0000000..22e268b --- /dev/null +++ b/src/gui/serverFileTransfert.cpp @@ -0,0 +1,265 @@ +/* +# Copyright (c) 2009 - 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/ +# ----------------------------------------------------------------------------- +# src/gui/serverFileTransfert.cpp +# This class manage any file transfert from and to server. +# ----------------------------------------------------------------------------- +*/ + +#include "serverFileTransfert.h" + +ServerFileTransfert::ServerFileTransfert(QWidget *parent): + QDialog(parent) +{ + setupUi(this); + _file = NULL; + _socket = NULL; + + connect(this, SIGNAL(finished(int)), this, SLOT(deleteLater())); +} + +ServerFileTransfert::~ServerFileTransfert() +{ +} + +void ServerFileTransfert::sendFileToHost(QString host) +{ + QString filename = QFileDialog::getOpenFileName(this, tr("Open File"), + QDir::homePath(), ""); + if (filename == "") + { + reject(); + return; + } + sendFileToHost(host, filename); +} + +void ServerFileTransfert::sendFileToHost(QString host, 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 + + // gui + filenameLabel->setText(filename); + progressBar->setValue(0); + progressBar->setMaximum(_bytesToWrite/div); + labelB->setText(formatSize(_bytesToWrite)); + connect(cancelButton, SIGNAL(clicked()), this, SLOT(close())); + + // open socket + _socket = new QTcpSocket(); + _socket->connectToHost(host, 29481); + if (_socket->isOpen()) + qDebug("connection open"); + else + qDebug("connection closed"); + 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))); + qDebug("connect is set"); +} + +void ServerFileTransfert::receiveFileFromHost(QTcpSocket* socket) +{ + + _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())); +} + +void ServerFileTransfert::sendHeader() +{ + qDebug("[%s] Sending header(1)...", metaObject()->className()); + QFileInfo info(_file->fileName()); + QString size = QString::number(_bytesToWrite); + QString header = "PVSMGR;" + info.fileName() + ";" + size + "\n"; + _socket->write(header.toLocal8Bit()); + connect(_socket, SIGNAL(readyRead()), this, SLOT(receiveAck())); + qDebug("[%s] Sending header...", metaObject()->className()); +} + +void ServerFileTransfert::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); + labelB->setText(formatSize(_bytesToRead)); + connect(cancelButton, SIGNAL(clicked()), this, SLOT(close())); + + sendAck(true); + show(); +} + +void ServerFileTransfert::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 ServerFileTransfert::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())); + this->show(); + qDebug("[%s] Sending file...", metaObject()->className()); + sendFile(); +} + +void ServerFileTransfert::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 ServerFileTransfert::receiveFile() +{ + qint64 bytesRead = _file->write(_socket->readAll()); + _bytesToRead -= bytesRead; + progressBar->setValue(progressBar->value() + bytesRead/div); + labelA->setText(formatSize(progressBar->value()*div)); +} + +void ServerFileTransfert::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 ServerFileTransfert::error(QAbstractSocket::SocketError error) +{ + qDebug("[%s] Socket error: %i", metaObject()->className(), error); + close(); +} + +QString ServerFileTransfert::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); +} |
