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

12 years ago
12 years ago
12 years ago
12 years ago
12 years ago
12 years ago
12 years ago
12 years ago
12 years ago
12 years ago
12 years ago
  1. /***************************************************************************
  2. * Copyright (C) 2008 by Oliver Groß *
  3. * z.o.gross@gmx.de *
  4. * *
  5. * This program is free software; you can redistribute it and/or modify *
  6. * it under the terms of the GNU General Public License as published by *
  7. * the Free Software Foundation; either version 2 of the License, or *
  8. * (at your option) any later version. *
  9. * *
  10. * This program is distributed in the hope that it will be useful, *
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of *
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
  13. * GNU General Public License for more details. *
  14. * *
  15. * You should have received a copy of the GNU General Public License *
  16. * along with this program; if not, write to the *
  17. * Free Software Foundation, Inc., *
  18. * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
  19. ***************************************************************************/
  20. #include "ctransfermanager.h"
  21. #include "ctransferthread.h"
  22. #include "csocketmanager.h"
  23. #include "qtransferlistmodel.h"
  24. #include "cworker.h"
  25. #include "cconnectiondialog.h"
  26. #include <QDebug>
  27. #include <QStatusBar>
  28. #include <QFileInfo>
  29. #include <QDataStream>
  30. #include <QTcpServer>
  31. #include <QTcpSocket>
  32. #include <QMenuBar>
  33. #include <QMenu>
  34. #include <QToolBar>
  35. #include <QListView>
  36. #include <QFileDialog>
  37. #include <QApplication>
  38. #include <QMessageBox>
  39. namespace qftrans {
  40. CTransferManager::CTransferManager(QWidget * parent) : QMainWindow(parent),
  41. m_ActAsServer(false),
  42. m_Connected(false),
  43. m_DestinationDir(QDir::homePath()),
  44. m_TransferThread(NULL)
  45. // m_SelectedTransfer(NULL)
  46. {
  47. setupUi();
  48. }
  49. // TODO ~CTransferManager()
  50. CTransferManager::~CTransferManager() {
  51. cleanupThread();
  52. }
  53. void CTransferManager::openFile() {
  54. QStringList files = QFileDialog::getOpenFileNames(this,
  55. tr("Select one or more files to open"),
  56. QDir::homePath());
  57. TransferData * newUpload = NULL;
  58. QFileInfo fileInfo;
  59. foreach (QString i, files) {
  60. fileInfo.setFile(i);
  61. newUpload = new TransferData;
  62. newUpload->fileDir = fileInfo.absolutePath();
  63. newUpload->fileName = fileInfo.fileName();
  64. newUpload->size = fileInfo.size();
  65. newUpload->transfered = 0;
  66. newUpload->status = TS_SUSPENDED;
  67. newUpload->lastHeader = HT_ANNOUNCE;
  68. newUpload->localFile = true;
  69. addTransfer(newUpload);
  70. // emit uploadAddRequested(newUpload);
  71. }
  72. }
  73. void CTransferManager::setDestinationDir() {
  74. QString selectedDir = QFileDialog::getExistingDirectory(this, tr("Select a directory to save downloaded files"), m_DestinationDir);
  75. if (!selectedDir.isEmpty()) {
  76. m_DestinationDir = selectedDir;
  77. emit destinationDirChanged(m_DestinationDir);
  78. }
  79. }
  80. void CTransferManager::requestServerThread() {
  81. if (!m_ConnectionDialog->execute(true))
  82. return;
  83. createThread();
  84. m_ActAsServer = true;
  85. m_TransferThread->start();
  86. }
  87. void CTransferManager::requestClientThread() {
  88. if (!m_ConnectionDialog->execute(false))
  89. return;
  90. createThread();
  91. m_ActAsServer = false;
  92. m_TransferThread->start();
  93. }
  94. void CTransferManager::setupConnection() {
  95. connect(m_TransferThread->socketManager(), SIGNAL(connectionChanged(bool)), this, SLOT(updateConnectionState(bool)));
  96. connect(this, SIGNAL(setupConnectionRequested(bool, quint16, QString &)),
  97. m_TransferThread->socketManager(), SLOT(setup(bool, quint16, QString &)));
  98. QString host = m_ActAsServer ? "0.0.0.0" : m_ConnectionDialog->host();
  99. emit setupConnectionRequested(m_ActAsServer, m_ConnectionDialog->port(), host);
  100. }
  101. void CTransferManager::cleanupThread() {
  102. if (m_TransferThread) {
  103. m_TransferThread->quit();
  104. m_TransferThread->deleteLater();
  105. }
  106. m_TransferThread = NULL;
  107. statusBar()->showMessage(tr("disconnected"));
  108. }
  109. void CTransferManager::restartSelected() {
  110. QModelIndexList selectedIndexes = m_TransferView->selectionModel()->selectedIndexes();
  111. foreach (QModelIndex i, selectedIndexes) {
  112. emit uploadAddRequested(static_cast<TransferData *>(i.internalPointer()));
  113. }
  114. // emit uploadAddRequested(m_SelectedTransfer);
  115. }
  116. void CTransferManager::cancelSelected() {
  117. QModelIndexList selectedIndexes = m_TransferView->selectionModel()->selectedIndexes();
  118. foreach (QModelIndex i, selectedIndexes) {
  119. if (static_cast<TransferData *>(i.internalPointer())->localFile)
  120. emit uploadRemoveRequested(static_cast<TransferData *>(i.internalPointer()));
  121. else
  122. emit downloadRemoveRequested(static_cast<TransferData *>(i.internalPointer()));
  123. }
  124. /* if (m_SelectedTransfer->localFile)
  125. emit uploadRemoveRequested(m_SelectedTransfer);
  126. else
  127. emit downloadRemoveRequested(m_SelectedTransfer);*/
  128. }
  129. inline void CTransferManager::setupUi() {
  130. setWindowTitle(tr("QFTrans"));
  131. QMenu * currentMenu;
  132. QToolBar * currentToolBar = addToolBar("Main");
  133. currentMenu = menuBar()->addMenu(tr("&File"));
  134. m_FileOpen = currentMenu->addAction(tr("&Open..."), this, SLOT(openFile()));
  135. currentMenu->addAction(tr("Set destination directory..."), this, SLOT(setDestinationDir()));
  136. currentToolBar->addActions(currentMenu->actions());
  137. currentMenu->addSeparator();
  138. currentMenu->addAction(tr("&Quit"), this, SLOT(close()));
  139. currentToolBar->addSeparator();
  140. currentMenu = menuBar()->addMenu(tr("&Connection"));
  141. m_ConnectionAsServer = currentMenu->addAction(tr("Act as &server"), this, SLOT(requestServerThread()));
  142. m_ConnectionAsClient = currentMenu->addAction(tr("Act as &client"), this, SLOT(requestClientThread()));
  143. currentMenu->addSeparator();
  144. m_ConnectionDisconnect = currentMenu->addAction(tr("&Disconnect"), this, SLOT(cleanupThread()));
  145. currentToolBar->addActions(currentMenu->actions());
  146. currentToolBar->addSeparator();
  147. currentMenu = menuBar()->addMenu(tr("&Transfer"));
  148. m_TransferRestartAction = currentMenu->addAction(tr("(Re)&Start"), this, SLOT(restartSelected()));
  149. m_TransferCancelAction = currentMenu->addAction(tr("&Cancel"), this, SLOT(cancelSelected()));
  150. m_TransferRestartAction->setEnabled(false);
  151. m_TransferCancelAction->setEnabled(false);
  152. currentToolBar->addActions(currentMenu->actions());
  153. currentMenu = menuBar()->addMenu(tr("&Help"));
  154. currentMenu->addAction(tr("&About"), this, SLOT(about()));
  155. currentMenu->addAction(tr("About &Qt"), qApp, SLOT(aboutQt()));
  156. m_TransferView = new QListView(this);
  157. m_TransferView->setSelectionMode(QAbstractItemView::ExtendedSelection);
  158. setCentralWidget(m_TransferView);
  159. QTransferListModel * listModel = new QTransferListModel(&m_Data);
  160. connect(this, SIGNAL(transferRemoved(TransferData *)), listModel, SIGNAL(layoutChanged()));
  161. connect(this, SIGNAL(transferAdded(TransferData *)), listModel, SIGNAL(layoutChanged()));
  162. m_TransferView->setModel(listModel);
  163. connect(m_TransferView->selectionModel(), SIGNAL(selectionChanged(const QItemSelection &, const QItemSelection &)),
  164. this, SLOT(handleSelectionChanged(const QItemSelection &)));
  165. updateConnectionState(false);
  166. m_ConnectionDialog = new CConnectionDialog(this);
  167. }
  168. void CTransferManager::updateConnectionState(bool connected) {
  169. m_Connected = connected;
  170. if (connected) {
  171. connectToWorker(m_TransferThread->socketManager()->worker());
  172. statusBar()->showMessage(tr("connected"));
  173. }
  174. else
  175. statusBar()->showMessage(m_TransferThread ? tr("waiting") : tr("disconnected"));
  176. m_FileOpen->setEnabled(connected);
  177. m_ConnectionAsServer->setDisabled(connected);
  178. m_ConnectionAsClient->setDisabled(connected);
  179. m_ConnectionDisconnect->setEnabled(connected);
  180. }
  181. // TODO cleanup()
  182. void CTransferManager::cleanup() {
  183. }
  184. void CTransferManager::connectToWorker(CWorker * worker) {
  185. worker->setDestinationDir(m_DestinationDir);
  186. connect(this, SIGNAL(destinationDirChanged(QString &)), worker, SLOT(setDestinationDir(QString &)));
  187. connect(worker, SIGNAL(downloadAdded(TransferData *)), this, SLOT(addTransfer(TransferData *)));
  188. QTransferListModel * model = dynamic_cast<QTransferListModel *>(m_TransferView->model());
  189. connect(worker, SIGNAL(downloadUpdated(TransferData *)), model, SLOT(updateEntry(TransferData *)));
  190. connect(worker, SIGNAL(uploadUpdated(TransferData *)), model, SLOT(updateEntry(TransferData *)));
  191. connect(this, SIGNAL(uploadAddRequested(TransferData *)), worker, SLOT(addUpload(TransferData *)));
  192. // connect(this, SIGNAL(uploadRestartRequested(TransferData *)), worker, SLOT(startUpload(TransferData *)));
  193. connect(this, SIGNAL(uploadRemoveRequested(TransferData *)), worker, SLOT(removeUpload(TransferData *)));
  194. connect(this, SIGNAL(downloadRemoveRequested(TransferData *)), worker, SLOT(removeDownload(TransferData *)));
  195. }
  196. void CTransferManager::handleSelectionChanged(const QItemSelection & selected) {
  197. QModelIndexList selectedIndexes = selected.indexes();
  198. // if (selectedIndexes.isEmpty())
  199. // m_SelectedTransfer = NULL;
  200. // else
  201. // m_SelectedTransfer = static_cast<TransferData *>(selectedIndexes[0].internalPointer());
  202. //
  203. m_TransferRestartAction->setDisabled(selectedIndexes.isEmpty());
  204. m_TransferCancelAction->setDisabled(selectedIndexes.isEmpty());
  205. /* m_TransferRestartAction->setEnabled(m_SelectedTransfer && m_SelectedTransfer->localFile);
  206. m_TransferCancelAction->setEnabled(m_SelectedTransfer && m_SelectedTransfer->status != TS_FINISHED);*/
  207. }
  208. void CTransferManager::addTransfer(TransferData * transfer) {
  209. m_Data << transfer;
  210. emit transferAdded(transfer);
  211. }
  212. // TODO proper handle removing transfer
  213. void CTransferManager::removeTransfer(TransferData * transfer) {
  214. int index = m_Data.indexOf(transfer);
  215. if (index != -1) {
  216. m_Data.removeAt(index);
  217. emit transferRemoved(transfer);
  218. }
  219. delete transfer;
  220. }
  221. inline void CTransferManager::createThread() {
  222. cleanupThread();
  223. qDebug() << "main thread" << QThread::currentThreadId();
  224. m_TransferThread = new CTransferThread();
  225. connect(m_TransferThread, SIGNAL(terminated()), this, SLOT(cleanupThread()));
  226. // connect(m_TransferThread, SIGNAL(finished()), m_TransferThread, SLOT(deleteLater()));
  227. connect(m_TransferThread, SIGNAL(socketManagerReady()), this, SLOT(setupConnection()));
  228. }
  229. void CTransferManager::updateStatusBar(const QString & message) {
  230. if (message.isEmpty()) {
  231. if (m_Connected)
  232. statusBar()->showMessage(tr("connected"));
  233. else
  234. statusBar()->showMessage(m_TransferThread ? tr("waiting") : tr("disconnected"));
  235. }
  236. }
  237. void CTransferManager::about() {
  238. QMessageBox::about(this, tr("About"), tr("This is a still unfancy \"peer-to-peer\"-like file transfer tool."));
  239. }
  240. }