summaryrefslogtreecommitdiffstats
path: root/src/gui/clientFileReceiveDialog.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/gui/clientFileReceiveDialog.cpp')
-rw-r--r--src/gui/clientFileReceiveDialog.cpp181
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);
+}