You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
307 lines
11 KiB
307 lines
11 KiB
/*************************************************************************** |
|
* Copyright (C) 2008 by Oliver Groß * |
|
* z.o.gross@gmx.de * |
|
* * |
|
* This program is free software; you can redistribute it and/or modify * |
|
* it under the terms of the GNU General Public License as published by * |
|
* the Free Software Foundation; either version 2 of the License, or * |
|
* (at your option) any later version. * |
|
* * |
|
* This program is distributed in the hope that it will be useful, * |
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of * |
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * |
|
* GNU General Public License for more details. * |
|
* * |
|
* You should have received a copy of the GNU General Public License * |
|
* along with this program; if not, write to the * |
|
* Free Software Foundation, Inc., * |
|
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * |
|
***************************************************************************/ |
|
#include "ctransfermanager.h" |
|
#include "ctransferthread.h" |
|
#include "csocketmanager.h" |
|
#include "qtransferlistmodel.h" |
|
#include "cworker.h" |
|
#include "cconnectiondialog.h" |
|
|
|
#include <QDebug> |
|
#include <QStatusBar> |
|
|
|
#include <QFileInfo> |
|
#include <QDataStream> |
|
#include <QTcpServer> |
|
#include <QTcpSocket> |
|
|
|
#include <QMenuBar> |
|
#include <QMenu> |
|
#include <QToolBar> |
|
#include <QListView> |
|
#include <QFileDialog> |
|
#include <QApplication> |
|
#include <QMessageBox> |
|
|
|
namespace qftrans { |
|
CTransferManager::CTransferManager(QWidget * parent) : QMainWindow(parent), |
|
m_ActAsServer(false), |
|
m_Connected(false), |
|
m_DestinationDir(QDir::homePath()), |
|
m_TransferThread(NULL) |
|
// m_SelectedTransfer(NULL) |
|
{ |
|
setupUi(); |
|
} |
|
|
|
// TODO ~CTransferManager() |
|
CTransferManager::~CTransferManager() { |
|
cleanupThread(); |
|
} |
|
|
|
void CTransferManager::openFile() { |
|
QStringList files = QFileDialog::getOpenFileNames(this, |
|
tr("Select one or more files to open"), |
|
QDir::homePath()); |
|
|
|
TransferData * newUpload = NULL; |
|
QFileInfo fileInfo; |
|
|
|
foreach (QString i, files) { |
|
fileInfo.setFile(i); |
|
newUpload = new TransferData; |
|
newUpload->fileDir = fileInfo.absolutePath(); |
|
newUpload->fileName = fileInfo.fileName(); |
|
newUpload->size = fileInfo.size(); |
|
newUpload->transfered = 0; |
|
newUpload->status = TS_SUSPENDED; |
|
newUpload->lastHeader = HT_ANNOUNCE; |
|
newUpload->localFile = true; |
|
|
|
addTransfer(newUpload); |
|
// emit uploadAddRequested(newUpload); |
|
} |
|
} |
|
|
|
void CTransferManager::setDestinationDir() { |
|
QString selectedDir = QFileDialog::getExistingDirectory(this, tr("Select a directory to save downloaded files"), m_DestinationDir); |
|
if (!selectedDir.isEmpty()) { |
|
m_DestinationDir = selectedDir; |
|
|
|
emit destinationDirChanged(m_DestinationDir); |
|
} |
|
} |
|
|
|
void CTransferManager::requestServerThread() { |
|
if (!m_ConnectionDialog->execute(true)) |
|
return; |
|
|
|
createThread(); |
|
|
|
m_ActAsServer = true; |
|
m_TransferThread->start(); |
|
} |
|
|
|
void CTransferManager::requestClientThread() { |
|
if (!m_ConnectionDialog->execute(false)) |
|
return; |
|
|
|
createThread(); |
|
|
|
m_ActAsServer = false; |
|
m_TransferThread->start(); |
|
} |
|
|
|
void CTransferManager::setupConnection() { |
|
connect(m_TransferThread->socketManager(), SIGNAL(connectionChanged(bool)), this, SLOT(updateConnectionState(bool))); |
|
|
|
connect(this, SIGNAL(setupConnectionRequested(bool, quint16, QString &)), |
|
m_TransferThread->socketManager(), SLOT(setup(bool, quint16, QString &))); |
|
|
|
QString host = m_ActAsServer ? "0.0.0.0" : m_ConnectionDialog->host(); |
|
|
|
emit setupConnectionRequested(m_ActAsServer, m_ConnectionDialog->port(), host); |
|
} |
|
|
|
void CTransferManager::cleanupThread() { |
|
if (m_TransferThread) { |
|
m_TransferThread->quit(); |
|
m_TransferThread->deleteLater(); |
|
} |
|
m_TransferThread = NULL; |
|
statusBar()->showMessage(tr("disconnected")); |
|
} |
|
|
|
void CTransferManager::restartSelected() { |
|
QModelIndexList selectedIndexes = m_TransferView->selectionModel()->selectedIndexes(); |
|
|
|
foreach (QModelIndex i, selectedIndexes) { |
|
emit uploadAddRequested(static_cast<TransferData *>(i.internalPointer())); |
|
} |
|
|
|
// emit uploadAddRequested(m_SelectedTransfer); |
|
} |
|
|
|
void CTransferManager::cancelSelected() { |
|
QModelIndexList selectedIndexes = m_TransferView->selectionModel()->selectedIndexes(); |
|
|
|
foreach (QModelIndex i, selectedIndexes) { |
|
if (static_cast<TransferData *>(i.internalPointer())->localFile) |
|
emit uploadRemoveRequested(static_cast<TransferData *>(i.internalPointer())); |
|
else |
|
emit downloadRemoveRequested(static_cast<TransferData *>(i.internalPointer())); |
|
} |
|
/* if (m_SelectedTransfer->localFile) |
|
emit uploadRemoveRequested(m_SelectedTransfer); |
|
else |
|
emit downloadRemoveRequested(m_SelectedTransfer);*/ |
|
} |
|
|
|
inline void CTransferManager::setupUi() { |
|
setWindowTitle(tr("QFTrans")); |
|
|
|
QMenu * currentMenu; |
|
QToolBar * currentToolBar = addToolBar("Main"); |
|
|
|
currentMenu = menuBar()->addMenu(tr("&File")); |
|
m_FileOpen = currentMenu->addAction(tr("&Open..."), this, SLOT(openFile())); |
|
currentMenu->addAction(tr("Set destination directory..."), this, SLOT(setDestinationDir())); |
|
|
|
currentToolBar->addActions(currentMenu->actions()); |
|
|
|
currentMenu->addSeparator(); |
|
currentMenu->addAction(tr("&Quit"), this, SLOT(close())); |
|
|
|
currentToolBar->addSeparator(); |
|
|
|
currentMenu = menuBar()->addMenu(tr("&Connection")); |
|
m_ConnectionAsServer = currentMenu->addAction(tr("Act as &server"), this, SLOT(requestServerThread())); |
|
m_ConnectionAsClient = currentMenu->addAction(tr("Act as &client"), this, SLOT(requestClientThread())); |
|
currentMenu->addSeparator(); |
|
m_ConnectionDisconnect = currentMenu->addAction(tr("&Disconnect"), this, SLOT(cleanupThread())); |
|
|
|
currentToolBar->addActions(currentMenu->actions()); |
|
currentToolBar->addSeparator(); |
|
|
|
currentMenu = menuBar()->addMenu(tr("&Transfer")); |
|
m_TransferRestartAction = currentMenu->addAction(tr("(Re)&Start"), this, SLOT(restartSelected())); |
|
m_TransferCancelAction = currentMenu->addAction(tr("&Cancel"), this, SLOT(cancelSelected())); |
|
|
|
m_TransferRestartAction->setEnabled(false); |
|
m_TransferCancelAction->setEnabled(false); |
|
|
|
currentToolBar->addActions(currentMenu->actions()); |
|
|
|
currentMenu = menuBar()->addMenu(tr("&Help")); |
|
currentMenu->addAction(tr("&About"), this, SLOT(about())); |
|
currentMenu->addAction(tr("About &Qt"), qApp, SLOT(aboutQt())); |
|
|
|
m_TransferView = new QListView(this); |
|
m_TransferView->setSelectionMode(QAbstractItemView::ExtendedSelection); |
|
setCentralWidget(m_TransferView); |
|
|
|
QTransferListModel * listModel = new QTransferListModel(&m_Data); |
|
|
|
connect(this, SIGNAL(transferRemoved(TransferData *)), listModel, SIGNAL(layoutChanged())); |
|
connect(this, SIGNAL(transferAdded(TransferData *)), listModel, SIGNAL(layoutChanged())); |
|
|
|
m_TransferView->setModel(listModel); |
|
|
|
connect(m_TransferView->selectionModel(), SIGNAL(selectionChanged(const QItemSelection &, const QItemSelection &)), |
|
this, SLOT(handleSelectionChanged(const QItemSelection &))); |
|
|
|
updateConnectionState(false); |
|
|
|
m_ConnectionDialog = new CConnectionDialog(this); |
|
} |
|
|
|
void CTransferManager::updateConnectionState(bool connected) { |
|
m_Connected = connected; |
|
if (connected) { |
|
connectToWorker(m_TransferThread->socketManager()->worker()); |
|
statusBar()->showMessage(tr("connected")); |
|
} |
|
else |
|
statusBar()->showMessage(m_TransferThread ? tr("waiting") : tr("disconnected")); |
|
|
|
m_FileOpen->setEnabled(connected); |
|
m_ConnectionAsServer->setDisabled(connected); |
|
m_ConnectionAsClient->setDisabled(connected); |
|
m_ConnectionDisconnect->setEnabled(connected); |
|
} |
|
|
|
// TODO cleanup() |
|
void CTransferManager::cleanup() { |
|
} |
|
|
|
void CTransferManager::connectToWorker(CWorker * worker) { |
|
worker->setDestinationDir(m_DestinationDir); |
|
|
|
connect(this, SIGNAL(destinationDirChanged(QString &)), worker, SLOT(setDestinationDir(QString &))); |
|
|
|
connect(worker, SIGNAL(downloadAdded(TransferData *)), this, SLOT(addTransfer(TransferData *))); |
|
|
|
QTransferListModel * model = dynamic_cast<QTransferListModel *>(m_TransferView->model()); |
|
|
|
connect(worker, SIGNAL(downloadUpdated(TransferData *)), model, SLOT(updateEntry(TransferData *))); |
|
connect(worker, SIGNAL(uploadUpdated(TransferData *)), model, SLOT(updateEntry(TransferData *))); |
|
|
|
connect(this, SIGNAL(uploadAddRequested(TransferData *)), worker, SLOT(addUpload(TransferData *))); |
|
// connect(this, SIGNAL(uploadRestartRequested(TransferData *)), worker, SLOT(startUpload(TransferData *))); |
|
connect(this, SIGNAL(uploadRemoveRequested(TransferData *)), worker, SLOT(removeUpload(TransferData *))); |
|
|
|
connect(this, SIGNAL(downloadRemoveRequested(TransferData *)), worker, SLOT(removeDownload(TransferData *))); |
|
} |
|
|
|
void CTransferManager::handleSelectionChanged(const QItemSelection & selected) { |
|
QModelIndexList selectedIndexes = selected.indexes(); |
|
// if (selectedIndexes.isEmpty()) |
|
// m_SelectedTransfer = NULL; |
|
// else |
|
// m_SelectedTransfer = static_cast<TransferData *>(selectedIndexes[0].internalPointer()); |
|
// |
|
m_TransferRestartAction->setDisabled(selectedIndexes.isEmpty()); |
|
m_TransferCancelAction->setDisabled(selectedIndexes.isEmpty()); |
|
|
|
/* m_TransferRestartAction->setEnabled(m_SelectedTransfer && m_SelectedTransfer->localFile); |
|
m_TransferCancelAction->setEnabled(m_SelectedTransfer && m_SelectedTransfer->status != TS_FINISHED);*/ |
|
} |
|
|
|
void CTransferManager::addTransfer(TransferData * transfer) { |
|
m_Data << transfer; |
|
emit transferAdded(transfer); |
|
} |
|
|
|
// TODO proper handle removing transfer |
|
void CTransferManager::removeTransfer(TransferData * transfer) { |
|
int index = m_Data.indexOf(transfer); |
|
if (index != -1) { |
|
m_Data.removeAt(index); |
|
|
|
emit transferRemoved(transfer); |
|
} |
|
delete transfer; |
|
} |
|
|
|
inline void CTransferManager::createThread() { |
|
cleanupThread(); |
|
|
|
qDebug() << "main thread" << QThread::currentThreadId(); |
|
m_TransferThread = new CTransferThread(); |
|
|
|
connect(m_TransferThread, SIGNAL(terminated()), this, SLOT(cleanupThread())); |
|
// connect(m_TransferThread, SIGNAL(finished()), m_TransferThread, SLOT(deleteLater())); |
|
|
|
connect(m_TransferThread, SIGNAL(socketManagerReady()), this, SLOT(setupConnection())); |
|
} |
|
|
|
void CTransferManager::updateStatusBar(const QString & message) { |
|
if (message.isEmpty()) { |
|
if (m_Connected) |
|
statusBar()->showMessage(tr("connected")); |
|
else |
|
statusBar()->showMessage(m_TransferThread ? tr("waiting") : tr("disconnected")); |
|
} |
|
} |
|
|
|
void CTransferManager::about() { |
|
QMessageBox::about(this, tr("About"), tr("This is a still unfancy \"peer-to-peer\"-like file transfer tool.")); |
|
} |
|
}
|
|
|