Christophe Dumez
17 years ago
13 changed files with 1657 additions and 1399 deletions
@ -0,0 +1,386 @@
@@ -0,0 +1,386 @@
|
||||
<ui version="4.0" > |
||||
<class>downloading</class> |
||||
<widget class="QWidget" name="downloading" > |
||||
<property name="geometry" > |
||||
<rect> |
||||
<x>0</x> |
||||
<y>0</y> |
||||
<width>811</width> |
||||
<height>453</height> |
||||
</rect> |
||||
</property> |
||||
<property name="windowTitle" > |
||||
<string>Search</string> |
||||
</property> |
||||
<layout class="QVBoxLayout" > |
||||
<item> |
||||
<layout class="QVBoxLayout" > |
||||
<property name="spacing" > |
||||
<number>6</number> |
||||
</property> |
||||
<property name="leftMargin" > |
||||
<number>0</number> |
||||
</property> |
||||
<property name="topMargin" > |
||||
<number>0</number> |
||||
</property> |
||||
<property name="rightMargin" > |
||||
<number>0</number> |
||||
</property> |
||||
<property name="bottomMargin" > |
||||
<number>0</number> |
||||
</property> |
||||
<item> |
||||
<layout class="QHBoxLayout" > |
||||
<property name="spacing" > |
||||
<number>6</number> |
||||
</property> |
||||
<property name="leftMargin" > |
||||
<number>0</number> |
||||
</property> |
||||
<property name="topMargin" > |
||||
<number>0</number> |
||||
</property> |
||||
<property name="rightMargin" > |
||||
<number>0</number> |
||||
</property> |
||||
<property name="bottomMargin" > |
||||
<number>0</number> |
||||
</property> |
||||
<item> |
||||
<spacer> |
||||
<property name="orientation" > |
||||
<enum>Qt::Horizontal</enum> |
||||
</property> |
||||
<property name="sizeHint" > |
||||
<size> |
||||
<width>40</width> |
||||
<height>20</height> |
||||
</size> |
||||
</property> |
||||
</spacer> |
||||
</item> |
||||
<item> |
||||
<widget class="QLabel" name="lbl_DLSpeed" > |
||||
<property name="text" > |
||||
<string>Total DL Speed:</string> |
||||
</property> |
||||
<property name="alignment" > |
||||
<set>Qt::AlignBottom|Qt::AlignLeading|Qt::AlignLeft</set> |
||||
</property> |
||||
</widget> |
||||
</item> |
||||
<item> |
||||
<widget class="QLCDNumber" name="LCD_DownSpeed" > |
||||
<property name="autoFillBackground" > |
||||
<bool>true</bool> |
||||
</property> |
||||
<property name="frameShadow" > |
||||
<enum>QFrame::Raised</enum> |
||||
</property> |
||||
<property name="smallDecimalPoint" > |
||||
<bool>false</bool> |
||||
</property> |
||||
<property name="numDigits" > |
||||
<number>6</number> |
||||
</property> |
||||
<property name="segmentStyle" > |
||||
<enum>QLCDNumber::Flat</enum> |
||||
</property> |
||||
<property name="value" stdset="0" > |
||||
<double>0.000000000000000</double> |
||||
</property> |
||||
<property name="intValue" stdset="0" > |
||||
<number>0</number> |
||||
</property> |
||||
</widget> |
||||
</item> |
||||
<item> |
||||
<widget class="QLabel" name="unitDL" > |
||||
<property name="text" > |
||||
<string>KiB/s</string> |
||||
</property> |
||||
<property name="alignment" > |
||||
<set>Qt::AlignBottom|Qt::AlignLeading|Qt::AlignLeft</set> |
||||
</property> |
||||
</widget> |
||||
</item> |
||||
<item> |
||||
<spacer> |
||||
<property name="orientation" > |
||||
<enum>Qt::Horizontal</enum> |
||||
</property> |
||||
<property name="sizeHint" > |
||||
<size> |
||||
<width>40</width> |
||||
<height>20</height> |
||||
</size> |
||||
</property> |
||||
</spacer> |
||||
</item> |
||||
<item> |
||||
<widget class="QLabel" name="label" > |
||||
<property name="text" > |
||||
<string>Session ratio: </string> |
||||
</property> |
||||
<property name="alignment" > |
||||
<set>Qt::AlignBottom|Qt::AlignLeading|Qt::AlignLeft</set> |
||||
</property> |
||||
</widget> |
||||
</item> |
||||
<item> |
||||
<widget class="QLCDNumber" name="LCD_Ratio" > |
||||
<property name="autoFillBackground" > |
||||
<bool>true</bool> |
||||
</property> |
||||
<property name="numDigits" > |
||||
<number>4</number> |
||||
</property> |
||||
<property name="segmentStyle" > |
||||
<enum>QLCDNumber::Flat</enum> |
||||
</property> |
||||
<property name="value" stdset="0" > |
||||
<double>1.000000000000000</double> |
||||
</property> |
||||
</widget> |
||||
</item> |
||||
<item> |
||||
<widget class="QLabel" name="lbl_ratio_icon" > |
||||
<property name="text" > |
||||
<string/> |
||||
</property> |
||||
</widget> |
||||
</item> |
||||
<item> |
||||
<spacer> |
||||
<property name="orientation" > |
||||
<enum>Qt::Horizontal</enum> |
||||
</property> |
||||
<property name="sizeHint" > |
||||
<size> |
||||
<width>40</width> |
||||
<height>20</height> |
||||
</size> |
||||
</property> |
||||
</spacer> |
||||
</item> |
||||
<item> |
||||
<widget class="QLabel" name="lbl_UPSpeed" > |
||||
<property name="text" > |
||||
<string>Total UP Speed:</string> |
||||
</property> |
||||
<property name="alignment" > |
||||
<set>Qt::AlignBottom|Qt::AlignLeading|Qt::AlignLeft</set> |
||||
</property> |
||||
</widget> |
||||
</item> |
||||
<item> |
||||
<widget class="QLCDNumber" name="LCD_UpSpeed" > |
||||
<property name="autoFillBackground" > |
||||
<bool>true</bool> |
||||
</property> |
||||
<property name="smallDecimalPoint" > |
||||
<bool>false</bool> |
||||
</property> |
||||
<property name="numDigits" > |
||||
<number>6</number> |
||||
</property> |
||||
<property name="segmentStyle" > |
||||
<enum>QLCDNumber::Flat</enum> |
||||
</property> |
||||
<property name="value" stdset="0" > |
||||
<double>0.000000000000000</double> |
||||
</property> |
||||
</widget> |
||||
</item> |
||||
<item> |
||||
<widget class="QLabel" name="unitUP" > |
||||
<property name="text" > |
||||
<string>KiB/s</string> |
||||
</property> |
||||
<property name="alignment" > |
||||
<set>Qt::AlignBottom|Qt::AlignLeading|Qt::AlignLeft</set> |
||||
</property> |
||||
</widget> |
||||
</item> |
||||
<item> |
||||
<spacer> |
||||
<property name="orientation" > |
||||
<enum>Qt::Horizontal</enum> |
||||
</property> |
||||
<property name="sizeHint" > |
||||
<size> |
||||
<width>40</width> |
||||
<height>20</height> |
||||
</size> |
||||
</property> |
||||
</spacer> |
||||
</item> |
||||
</layout> |
||||
</item> |
||||
<item> |
||||
<widget class="QTreeView" name="downloadList" > |
||||
<property name="minimumSize" > |
||||
<size> |
||||
<width>0</width> |
||||
<height>0</height> |
||||
</size> |
||||
</property> |
||||
<property name="contextMenuPolicy" > |
||||
<enum>Qt::CustomContextMenu</enum> |
||||
</property> |
||||
<property name="autoScroll" > |
||||
<bool>true</bool> |
||||
</property> |
||||
<property name="selectionMode" > |
||||
<enum>QAbstractItemView::ExtendedSelection</enum> |
||||
</property> |
||||
<property name="indentation" > |
||||
<number>1</number> |
||||
</property> |
||||
<property name="itemsExpandable" > |
||||
<bool>false</bool> |
||||
</property> |
||||
</widget> |
||||
</item> |
||||
</layout> |
||||
</item> |
||||
<item> |
||||
<widget class="QTabWidget" name="tabBottom" > |
||||
<property name="maximumSize" > |
||||
<size> |
||||
<width>16777215</width> |
||||
<height>142</height> |
||||
</size> |
||||
</property> |
||||
<property name="tabPosition" > |
||||
<enum>QTabWidget::West</enum> |
||||
</property> |
||||
<property name="currentIndex" > |
||||
<number>0</number> |
||||
</property> |
||||
<widget class="QWidget" name="log_tab" > |
||||
<attribute name="title" > |
||||
<string>Log</string> |
||||
</attribute> |
||||
<layout class="QVBoxLayout" > |
||||
<property name="spacing" > |
||||
<number>6</number> |
||||
</property> |
||||
<property name="leftMargin" > |
||||
<number>9</number> |
||||
</property> |
||||
<property name="topMargin" > |
||||
<number>9</number> |
||||
</property> |
||||
<property name="rightMargin" > |
||||
<number>9</number> |
||||
</property> |
||||
<property name="bottomMargin" > |
||||
<number>9</number> |
||||
</property> |
||||
<item> |
||||
<widget class="QTextBrowser" name="infoBar" > |
||||
<property name="sizePolicy" > |
||||
<sizepolicy vsizetype="Expanding" hsizetype="Expanding" > |
||||
<horstretch>0</horstretch> |
||||
<verstretch>0</verstretch> |
||||
</sizepolicy> |
||||
</property> |
||||
<property name="maximumSize" > |
||||
<size> |
||||
<width>16777215</width> |
||||
<height>120</height> |
||||
</size> |
||||
</property> |
||||
<property name="contextMenuPolicy" > |
||||
<enum>Qt::CustomContextMenu</enum> |
||||
</property> |
||||
</widget> |
||||
</item> |
||||
</layout> |
||||
</widget> |
||||
<widget class="QWidget" name="filter_tab" > |
||||
<attribute name="title" > |
||||
<string>IP filter</string> |
||||
</attribute> |
||||
<layout class="QVBoxLayout" > |
||||
<property name="spacing" > |
||||
<number>6</number> |
||||
</property> |
||||
<property name="leftMargin" > |
||||
<number>9</number> |
||||
</property> |
||||
<property name="topMargin" > |
||||
<number>9</number> |
||||
</property> |
||||
<property name="rightMargin" > |
||||
<number>9</number> |
||||
</property> |
||||
<property name="bottomMargin" > |
||||
<number>9</number> |
||||
</property> |
||||
<item> |
||||
<widget class="QTextBrowser" name="textBlockedUsers" > |
||||
<property name="maximumSize" > |
||||
<size> |
||||
<width>16777215</width> |
||||
<height>123</height> |
||||
</size> |
||||
</property> |
||||
</widget> |
||||
</item> |
||||
</layout> |
||||
</widget> |
||||
</widget> |
||||
</item> |
||||
</layout> |
||||
<action name="actionStart" > |
||||
<property name="text" > |
||||
<string>Start</string> |
||||
</property> |
||||
</action> |
||||
<action name="actionPause" > |
||||
<property name="text" > |
||||
<string>Pause</string> |
||||
</property> |
||||
</action> |
||||
<action name="actionDelete" > |
||||
<property name="text" > |
||||
<string>Delete</string> |
||||
</property> |
||||
</action> |
||||
<action name="actionClearLog" > |
||||
<property name="text" > |
||||
<string>Clear</string> |
||||
</property> |
||||
</action> |
||||
<action name="actionPreview_file" > |
||||
<property name="text" > |
||||
<string>Preview file</string> |
||||
</property> |
||||
</action> |
||||
<action name="actionSet_upload_limit" > |
||||
<property name="text" > |
||||
<string>Set upload limit</string> |
||||
</property> |
||||
</action> |
||||
<action name="actionSet_download_limit" > |
||||
<property name="text" > |
||||
<string>Set download limit</string> |
||||
</property> |
||||
</action> |
||||
<action name="actionDelete_Permanently" > |
||||
<property name="text" > |
||||
<string>Delete Permanently</string> |
||||
</property> |
||||
</action> |
||||
<action name="actionTorrent_Properties" > |
||||
<property name="text" > |
||||
<string>Torrent Properties</string> |
||||
</property> |
||||
</action> |
||||
</widget> |
||||
<resources/> |
||||
<connections/> |
||||
</ui> |
@ -0,0 +1,697 @@
@@ -0,0 +1,697 @@
|
||||
/*
|
||||
* Bittorrent Client using Qt4 and libtorrent. |
||||
* Copyright (C) 2006 Christophe Dumez |
||||
* |
||||
* 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
||||
* |
||||
* Contact : chris@qbittorrent.org |
||||
*/ |
||||
#include "downloadingTorrents.h" |
||||
#include "misc.h" |
||||
#include "properties_imp.h" |
||||
#include "bittorrent.h" |
||||
#include "allocationDlg.h" |
||||
#include "DLListDelegate.h" |
||||
#include "previewSelect.h" |
||||
#include "GUI.h" |
||||
|
||||
#include <QFile> |
||||
#include <QSettings> |
||||
#include <QStandardItemModel> |
||||
#include <QHeaderView> |
||||
#include <QTime> |
||||
#include <QMenu> |
||||
|
||||
DownloadingTorrents::DownloadingTorrents(QObject *parent, bittorrent *BTSession) { |
||||
setupUi(this); |
||||
this->BTSession = BTSession; |
||||
this->parent = parent; |
||||
delayedSorting = false; |
||||
nbTorrents = 0; |
||||
// Setting icons
|
||||
actionStart->setIcon(QIcon(QString::fromUtf8(":/Icons/skin/play.png"))); |
||||
actionPause->setIcon(QIcon(QString::fromUtf8(":/Icons/skin/pause.png"))); |
||||
actionDelete->setIcon(QIcon(QString::fromUtf8(":/Icons/skin/delete.png"))); |
||||
actionClearLog->setIcon(QIcon(QString::fromUtf8(":/Icons/skin/delete.png"))); |
||||
actionPreview_file->setIcon(QIcon(QString::fromUtf8(":/Icons/skin/preview.png"))); |
||||
actionSet_upload_limit->setIcon(QIcon(QString::fromUtf8(":/Icons/skin/seeding.png"))); |
||||
actionSet_download_limit->setIcon(QIcon(QString::fromUtf8(":/Icons/skin/downloading.png"))); |
||||
actionDelete_Permanently->setIcon(QIcon(QString::fromUtf8(":/Icons/skin/delete_perm.png"))); |
||||
actionTorrent_Properties->setIcon(QIcon(QString::fromUtf8(":/Icons/skin/properties.png"))); |
||||
// tabBottom->setTabIcon(0, QIcon(QString::fromUtf8(":/Icons/log.png")));
|
||||
// tabBottom->setTabIcon(1, QIcon(QString::fromUtf8(":/Icons/filter.png")));
|
||||
// Set default ratio
|
||||
lbl_ratio_icon->setPixmap(QPixmap(QString::fromUtf8(":/Icons/stare.png"))); |
||||
|
||||
// Set Download list model
|
||||
DLListModel = new QStandardItemModel(0,9); |
||||
DLListModel->setHeaderData(NAME, Qt::Horizontal, tr("Name", "i.e: file name")); |
||||
DLListModel->setHeaderData(SIZE, Qt::Horizontal, tr("Size", "i.e: file size")); |
||||
DLListModel->setHeaderData(PROGRESS, Qt::Horizontal, tr("Progress", "i.e: % downloaded")); |
||||
DLListModel->setHeaderData(DLSPEED, Qt::Horizontal, tr("DL Speed", "i.e: Download speed")); |
||||
DLListModel->setHeaderData(UPSPEED, Qt::Horizontal, tr("UP Speed", "i.e: Upload speed")); |
||||
DLListModel->setHeaderData(SEEDSLEECH, Qt::Horizontal, tr("Seeds/Leechs", "i.e: full/partial sources")); |
||||
DLListModel->setHeaderData(RATIO, Qt::Horizontal, tr("Ratio")); |
||||
DLListModel->setHeaderData(ETA, Qt::Horizontal, tr("ETA", "i.e: Estimated Time of Arrival / Time left")); |
||||
downloadList->setModel(DLListModel); |
||||
DLDelegate = new DLListDelegate(downloadList); |
||||
downloadList->setItemDelegate(DLDelegate); |
||||
// Hide hash column
|
||||
downloadList->hideColumn(HASH); |
||||
|
||||
connect(BTSession, SIGNAL(addedTorrent(QString, QTorrentHandle&, bool)), this, SLOT(torrentAdded(QString, QTorrentHandle&, bool))); |
||||
connect(BTSession, SIGNAL(duplicateTorrent(QString)), this, SLOT(torrentDuplicate(QString))); |
||||
connect(BTSession, SIGNAL(invalidTorrent(QString)), this, SLOT(torrentCorrupted(QString))); |
||||
connect(BTSession, SIGNAL(portListeningFailure()), this, SLOT(portListeningFailure())); |
||||
connect(BTSession, SIGNAL(peerBlocked(QString)), this, SLOT(addLogPeerBlocked(const QString))); |
||||
connect(BTSession, SIGNAL(fastResumeDataRejected(QString)), this, SLOT(addFastResumeRejectedAlert(QString))); |
||||
connect(BTSession, SIGNAL(aboutToDownloadFromUrl(QString)), this, SLOT(displayDownloadingUrlInfos(QString))); |
||||
connect(BTSession, SIGNAL(urlSeedProblem(QString, QString)), this, SLOT(addUrlSeedError(QString, QString))); |
||||
|
||||
// Load last columns width for download list
|
||||
if(!loadColWidthDLList()) { |
||||
downloadList->header()->resizeSection(0, 200); |
||||
} |
||||
// Make download list header clickable for sorting
|
||||
downloadList->header()->setClickable(true); |
||||
downloadList->header()->setSortIndicatorShown(true); |
||||
// Connecting Actions to slots
|
||||
connect(downloadList, SIGNAL(doubleClicked(const QModelIndex&)), this, SLOT(notifyTorrentDoubleClicked(const QModelIndex&))); |
||||
connect(downloadList->header(), SIGNAL(sectionPressed(int)), this, SLOT(sortDownloadList(int))); |
||||
connect(downloadList, SIGNAL(customContextMenuRequested(const QPoint&)), this, SLOT(displayDLListMenu(const QPoint&))); |
||||
connect(infoBar, SIGNAL(customContextMenuRequested(const QPoint&)), this, SLOT(displayInfoBarMenu(const QPoint&))); |
||||
// Actions
|
||||
connect(actionDelete, SIGNAL(triggered()), (GUI*)parent, SLOT(on_actionDelete_triggered())); |
||||
connect(actionPreview_file, SIGNAL(triggered()), (GUI*)parent, SLOT(on_actionPreview_file_triggered())); |
||||
connect(actionDelete_Permanently, SIGNAL(triggered()), (GUI*)parent, SLOT(on_actionDelete_Permanently_triggered())); |
||||
connect(actionTorrent_Properties, SIGNAL(triggered()), this, SLOT(propertiesSelection())); |
||||
// Set info Bar infos
|
||||
setInfoBar(tr("qBittorrent %1 started.", "e.g: qBittorrent v0.x started.").arg(QString::fromUtf8(""VERSION))); |
||||
setInfoBar(tr("Be careful, sharing copyrighted material without permission is against the law."), QString::fromUtf8("red")); |
||||
qDebug("Download tab built"); |
||||
} |
||||
|
||||
DownloadingTorrents::~DownloadingTorrents() { |
||||
saveColWidthDLList(); |
||||
delete DLDelegate; |
||||
delete DLListModel; |
||||
} |
||||
|
||||
|
||||
void DownloadingTorrents::notifyTorrentDoubleClicked(const QModelIndex& index) { |
||||
unsigned int row = index.row(); |
||||
QString hash = getHashFromRow(row); |
||||
emit torrentDoubleClicked(hash); |
||||
} |
||||
|
||||
void DownloadingTorrents::addLogPeerBlocked(QString ip) { |
||||
static unsigned short nbLines = 0; |
||||
++nbLines; |
||||
if(nbLines > 200) { |
||||
textBlockedUsers->clear(); |
||||
nbLines = 1; |
||||
} |
||||
textBlockedUsers->append(QString::fromUtf8("<font color='grey'>")+ QTime::currentTime().toString(QString::fromUtf8("hh:mm:ss")) + QString::fromUtf8("</font> - ")+tr("<font color='red'>%1</font> <i>was blocked</i>", "x.y.z.w was blocked").arg(ip)); |
||||
} |
||||
|
||||
unsigned int DownloadingTorrents::getNbTorrentsInList() const { |
||||
return nbTorrents; |
||||
} |
||||
|
||||
// Note: do not actually pause the torrent in BT session
|
||||
void DownloadingTorrents::pauseTorrent(QString hash) { |
||||
int row = getRowFromHash(hash); |
||||
Q_ASSERT(row != -1); |
||||
DLListModel->setData(DLListModel->index(row, DLSPEED), QVariant((double)0.0)); |
||||
DLListModel->setData(DLListModel->index(row, UPSPEED), QVariant((double)0.0)); |
||||
DLListModel->setData(DLListModel->index(row, ETA), QVariant((qlonglong)-1)); |
||||
DLListModel->setData(DLListModel->index(row, NAME), QIcon(QString::fromUtf8(":/Icons/skin/paused.png")), Qt::DecorationRole); |
||||
DLListModel->setData(DLListModel->index(row, SEEDSLEECH), QVariant(QString::fromUtf8("0/0"))); |
||||
QTorrentHandle h = BTSession->getTorrentHandle(hash); |
||||
Q_ASSERT(h.progress() <= 1. && h.progress() >= 0.); |
||||
DLListModel->setData(DLListModel->index(row, PROGRESS), QVariant((double)h.progress())); |
||||
setRowColor(row, QString::fromUtf8("red")); |
||||
} |
||||
|
||||
QString DownloadingTorrents::getHashFromRow(unsigned int row) const { |
||||
Q_ASSERT(row < (unsigned int)DLListModel->rowCount()); |
||||
return DLListModel->data(DLListModel->index(row, HASH)).toString(); |
||||
} |
||||
|
||||
void DownloadingTorrents::setBottomTabEnabled(unsigned int index, bool b){ |
||||
if(index and !b) |
||||
tabBottom->setCurrentIndex(0); |
||||
tabBottom->setTabEnabled(index, b); |
||||
} |
||||
|
||||
// Show torrent properties dialog
|
||||
void DownloadingTorrents::showProperties(const QModelIndex &index) { |
||||
int row = index.row(); |
||||
QString hash = DLListModel->data(DLListModel->index(row, HASH)).toString(); |
||||
QTorrentHandle h = BTSession->getTorrentHandle(hash); |
||||
properties *prop = new properties(this, BTSession, h); |
||||
connect(prop, SIGNAL(filteredFilesChanged(QString)), this, SLOT(updateFileSizeAndProgress(QString))); |
||||
prop->show(); |
||||
} |
||||
|
||||
void DownloadingTorrents::resumeTorrent(QString hash){ |
||||
int row = getRowFromHash(hash); |
||||
Q_ASSERT(row != -1); |
||||
DLListModel->setData(DLListModel->index(row, NAME), QVariant(QIcon(QString::fromUtf8(":/Icons/skin/connecting.png"))), Qt::DecorationRole); |
||||
setRowColor(row, QString::fromUtf8("grey")); |
||||
} |
||||
|
||||
// Remove a torrent from the download list but NOT from the BT Session
|
||||
void DownloadingTorrents::deleteTorrent(QString hash) { |
||||
int row = getRowFromHash(hash); |
||||
Q_ASSERT(row != -1); |
||||
DLListModel->removeRow(row); |
||||
--nbTorrents; |
||||
emit unfinishedTorrentsNumberChanged(nbTorrents); |
||||
} |
||||
|
||||
// Update Info Bar information
|
||||
void DownloadingTorrents::setInfoBar(QString info, QString color) { |
||||
static unsigned short nbLines = 0; |
||||
++nbLines; |
||||
// Check log size, clear it if too big
|
||||
if(nbLines > 200) { |
||||
infoBar->clear(); |
||||
nbLines = 1; |
||||
} |
||||
infoBar->append(QString::fromUtf8("<font color='grey'>")+ QTime::currentTime().toString(QString::fromUtf8("hh:mm:ss")) + QString::fromUtf8("</font> - <font color='") + color +QString::fromUtf8("'><i>") + info + QString::fromUtf8("</i></font>")); |
||||
} |
||||
|
||||
void DownloadingTorrents::addFastResumeRejectedAlert(QString name) { |
||||
setInfoBar(tr("Fast resume data was rejected for torrent %1, checking again...").arg(name), QString::fromUtf8("red")); |
||||
} |
||||
|
||||
void DownloadingTorrents::addUrlSeedError(QString url, QString msg) { |
||||
setInfoBar(tr("Url seed lookup failed for url: %1, message: %2").arg(url).arg(msg), QString::fromUtf8("red")); |
||||
} |
||||
|
||||
void DownloadingTorrents::on_actionSet_download_limit_triggered() { |
||||
QModelIndexList selectedIndexes = downloadList->selectionModel()->selectedIndexes(); |
||||
QModelIndex index; |
||||
QStringList hashes; |
||||
foreach(index, selectedIndexes) { |
||||
if(index.column() == NAME) { |
||||
// Get the file hash
|
||||
hashes << DLListModel->data(DLListModel->index(index.row(), HASH)).toString(); |
||||
} |
||||
} |
||||
Q_ASSERT(hashes.size() > 0); |
||||
new BandwidthAllocationDialog(this, false, BTSession, hashes); |
||||
} |
||||
|
||||
void DownloadingTorrents::on_actionSet_upload_limit_triggered() { |
||||
QModelIndexList selectedIndexes = downloadList->selectionModel()->selectedIndexes(); |
||||
QModelIndex index; |
||||
QStringList hashes; |
||||
foreach(index, selectedIndexes) { |
||||
if(index.column() == NAME) { |
||||
// Get the file hash
|
||||
hashes << DLListModel->data(DLListModel->index(index.row(), HASH)).toString(); |
||||
} |
||||
} |
||||
Q_ASSERT(hashes.size() > 0); |
||||
new BandwidthAllocationDialog(this, true, BTSession, hashes); |
||||
} |
||||
|
||||
// display properties of selected items
|
||||
void DownloadingTorrents::propertiesSelection(){ |
||||
QModelIndexList selectedIndexes = downloadList->selectionModel()->selectedIndexes(); |
||||
QModelIndex index; |
||||
foreach(index, selectedIndexes){ |
||||
if(index.column() == NAME){ |
||||
showProperties(index); |
||||
} |
||||
} |
||||
} |
||||
|
||||
void DownloadingTorrents::displayDLListMenu(const QPoint& pos) { |
||||
QMenu myDLLlistMenu(this); |
||||
QModelIndex index; |
||||
// Enable/disable pause/start action given the DL state
|
||||
QModelIndexList selectedIndexes = downloadList->selectionModel()->selectedIndexes(); |
||||
QSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent")); |
||||
QString previewProgram = settings.value(QString::fromUtf8("Options/Misc/PreviewProgram"), QString()).toString(); |
||||
bool has_pause = false, has_start = false, has_preview = false; |
||||
foreach(index, selectedIndexes) { |
||||
if(index.column() == NAME) { |
||||
// Get the file name
|
||||
QString hash = DLListModel->data(DLListModel->index(index.row(), HASH)).toString(); |
||||
// Get handle and pause the torrent
|
||||
QTorrentHandle h = BTSession->getTorrentHandle(hash); |
||||
if(!h.is_valid()) continue; |
||||
if(h.is_paused()) { |
||||
if(!has_start) { |
||||
myDLLlistMenu.addAction(actionStart); |
||||
has_start = true; |
||||
} |
||||
}else{ |
||||
if(!has_pause) { |
||||
myDLLlistMenu.addAction(actionPause); |
||||
has_pause = true; |
||||
} |
||||
} |
||||
if(!previewProgram.isEmpty() && BTSession->isFilePreviewPossible(hash) && !has_preview) { |
||||
myDLLlistMenu.addAction(actionPreview_file); |
||||
has_preview = true; |
||||
} |
||||
if(has_pause && has_start && has_preview) break; |
||||
} |
||||
} |
||||
myDLLlistMenu.addSeparator(); |
||||
myDLLlistMenu.addAction(actionDelete); |
||||
myDLLlistMenu.addAction(actionDelete_Permanently); |
||||
myDLLlistMenu.addSeparator(); |
||||
myDLLlistMenu.addAction(actionSet_download_limit); |
||||
myDLLlistMenu.addAction(actionSet_upload_limit); |
||||
myDLLlistMenu.addSeparator(); |
||||
myDLLlistMenu.addAction(actionTorrent_Properties); |
||||
// Call menu
|
||||
// XXX: why mapToGlobal() is not enough?
|
||||
myDLLlistMenu.exec(mapToGlobal(pos)+QPoint(10,55)); |
||||
} |
||||
|
||||
void DownloadingTorrents::on_actionClearLog_triggered() { |
||||
infoBar->clear(); |
||||
} |
||||
|
||||
QStringList DownloadingTorrents::getSelectedTorrents(bool only_one) const{ |
||||
QStringList res; |
||||
QModelIndex index; |
||||
QModelIndexList selectedIndexes = downloadList->selectionModel()->selectedIndexes(); |
||||
foreach(index, selectedIndexes) { |
||||
if(index.column() == NAME) { |
||||
// Get the file hash
|
||||
QString hash = DLListModel->data(DLListModel->index(index.row(), HASH)).toString(); |
||||
res << hash; |
||||
if(only_one) break; |
||||
} |
||||
} |
||||
return res; |
||||
} |
||||
|
||||
void DownloadingTorrents::updateRatio() { |
||||
char tmp[MAX_CHAR_TMP]; |
||||
// Update ratio info
|
||||
float ratio = 1.; |
||||
session_status sessionStatus = BTSession->getSessionStatus(); |
||||
if(sessionStatus.total_payload_download == 0) { |
||||
if(sessionStatus.total_payload_upload == 0) |
||||
ratio = 1.; |
||||
else |
||||
ratio = 10.; |
||||
}else{ |
||||
ratio = (double)sessionStatus.total_payload_upload / (double)sessionStatus.total_payload_download; |
||||
if(ratio > 10.) |
||||
ratio = 10.; |
||||
} |
||||
snprintf(tmp, MAX_CHAR_TMP, "%.1f", ratio); |
||||
LCD_Ratio->display(tmp); |
||||
if(ratio < 0.5) { |
||||
lbl_ratio_icon->setPixmap(QPixmap(QString::fromUtf8(":/Icons/unhappy.png"))); |
||||
}else{ |
||||
if(ratio > 1.0) { |
||||
lbl_ratio_icon->setPixmap(QPixmap(QString::fromUtf8(":/Icons/smile.png"))); |
||||
}else{ |
||||
lbl_ratio_icon->setPixmap(QPixmap(QString::fromUtf8(":/Icons/stare.png"))); |
||||
} |
||||
} |
||||
} |
||||
|
||||
void DownloadingTorrents::displayInfoBarMenu(const QPoint& pos) { |
||||
// Log Menu
|
||||
QMenu myLogMenu(this); |
||||
myLogMenu.addAction(actionClearLog); |
||||
// XXX: Why mapToGlobal() is not enough?
|
||||
myLogMenu.exec(mapToGlobal(pos)+QPoint(22,383)); |
||||
} |
||||
|
||||
void DownloadingTorrents::sortProgressColumnDelayed() { |
||||
if(delayedSorting) { |
||||
sortDownloadListFloat(PROGRESS, delayedSortingOrder); |
||||
qDebug("Delayed sorting of progress column"); |
||||
} |
||||
} |
||||
|
||||
// get information from torrent handles and
|
||||
// update download list accordingly
|
||||
void DownloadingTorrents::updateDlList() { |
||||
char tmp[MAX_CHAR_TMP]; |
||||
char tmp2[MAX_CHAR_TMP]; |
||||
// update global informations
|
||||
snprintf(tmp, MAX_CHAR_TMP, "%.1f", BTSession->getPayloadUploadRate()/1024.); |
||||
snprintf(tmp2, MAX_CHAR_TMP, "%.1f", BTSession->getPayloadDownloadRate()/1024.); |
||||
//BTSession->printPausedTorrents();
|
||||
LCD_UpSpeed->display(QString::fromUtf8(tmp)); // UP LCD
|
||||
LCD_DownSpeed->display(QString::fromUtf8(tmp2)); // DL LCD
|
||||
// browse handles
|
||||
QStringList unfinishedTorrents = BTSession->getUnfinishedTorrents(); |
||||
QString hash; |
||||
foreach(hash, unfinishedTorrents) { |
||||
QTorrentHandle h = BTSession->getTorrentHandle(hash); |
||||
if(!h.is_valid()){ |
||||
qDebug("We have an invalid handle for: %s", qPrintable(hash)); |
||||
continue; |
||||
} |
||||
try{ |
||||
QString hash = h.hash(); |
||||
int row = getRowFromHash(hash); |
||||
if(row == -1) { |
||||
qDebug("Info: Could not find filename in download list, adding it..."); |
||||
addTorrent(hash); |
||||
row = getRowFromHash(hash); |
||||
} |
||||
Q_ASSERT(row != -1); |
||||
// No need to update a paused torrent
|
||||
if(h.is_paused()) continue; |
||||
// Parse download state
|
||||
// Setting download state
|
||||
switch(h.state()) { |
||||
case torrent_status::finished: |
||||
case torrent_status::seeding: |
||||
qDebug("A torrent that was in download tab just finished, moving it to finished tab"); |
||||
BTSession->setUnfinishedTorrent(hash); |
||||
emit torrentFinished(hash); |
||||
deleteTorrent(hash); |
||||
continue; |
||||
case torrent_status::checking_files: |
||||
case torrent_status::queued_for_checking: |
||||
if(BTSession->getTorrentsToPauseAfterChecking().indexOf(hash) == -1) { |
||||
DLListModel->setData(DLListModel->index(row, NAME), QVariant(QIcon(QString::fromUtf8(":/Icons/time.png"))), Qt::DecorationRole); |
||||
setRowColor(row, QString::fromUtf8("grey")); |
||||
Q_ASSERT(h.progress() <= 1. && h.progress() >= 0.); |
||||
DLListModel->setData(DLListModel->index(row, PROGRESS), QVariant((double)h.progress())); |
||||
} |
||||
break; |
||||
case torrent_status::connecting_to_tracker: |
||||
if(h.download_payload_rate() > 0) { |
||||
// Display "Downloading" status when connecting if download speed > 0
|
||||
DLListModel->setData(DLListModel->index(row, ETA), QVariant((qlonglong)BTSession->getETA(hash))); |
||||
DLListModel->setData(DLListModel->index(row, NAME), QVariant(QIcon(QString::fromUtf8(":/Icons/skin/downloading.png"))), Qt::DecorationRole); |
||||
setRowColor(row, QString::fromUtf8("green")); |
||||
}else{ |
||||
DLListModel->setData(DLListModel->index(row, ETA), QVariant((qlonglong)-1)); |
||||
DLListModel->setData(DLListModel->index(row, NAME), QVariant(QIcon(QString::fromUtf8(":/Icons/skin/connecting.png"))), Qt::DecorationRole); |
||||
setRowColor(row, QString::fromUtf8("grey")); |
||||
} |
||||
Q_ASSERT(h.progress() <= 1. && h.progress() >= 0.); |
||||
DLListModel->setData(DLListModel->index(row, PROGRESS), QVariant((double)h.progress())); |
||||
DLListModel->setData(DLListModel->index(row, DLSPEED), QVariant((double)h.download_payload_rate())); |
||||
DLListModel->setData(DLListModel->index(row, UPSPEED), QVariant((double)h.upload_payload_rate())); |
||||
break; |
||||
case torrent_status::downloading: |
||||
case torrent_status::downloading_metadata: |
||||
if(h.download_payload_rate() > 0) { |
||||
DLListModel->setData(DLListModel->index(row, NAME), QVariant(QIcon(QString::fromUtf8(":/Icons/skin/downloading.png"))), Qt::DecorationRole); |
||||
DLListModel->setData(DLListModel->index(row, ETA), QVariant((qlonglong)BTSession->getETA(hash))); |
||||
setRowColor(row, QString::fromUtf8("green")); |
||||
}else{ |
||||
DLListModel->setData(DLListModel->index(row, NAME), QVariant(QIcon(QString::fromUtf8(":/Icons/skin/stalled.png"))), Qt::DecorationRole); |
||||
DLListModel->setData(DLListModel->index(row, ETA), QVariant((qlonglong)-1)); |
||||
setRowColor(row, QString::fromUtf8("black")); |
||||
} |
||||
Q_ASSERT(h.progress() <= 1. && h.progress() >= 0.); |
||||
DLListModel->setData(DLListModel->index(row, PROGRESS), QVariant((double)h.progress())); |
||||
DLListModel->setData(DLListModel->index(row, DLSPEED), QVariant((double)h.download_payload_rate())); |
||||
DLListModel->setData(DLListModel->index(row, UPSPEED), QVariant((double)h.upload_payload_rate())); |
||||
break; |
||||
default: |
||||
DLListModel->setData(DLListModel->index(row, ETA), QVariant((qlonglong)-1)); |
||||
} |
||||
DLListModel->setData(DLListModel->index(row, SEEDSLEECH), QVariant(misc::toQString(h.num_seeds(), true)+QString::fromUtf8("/")+misc::toQString(h.num_peers() - h.num_seeds(), true))); |
||||
DLListModel->setData(DLListModel->index(row, RATIO), QVariant(misc::toQString(BTSession->getRealRatio(hash)))); |
||||
}catch(invalid_handle e) { |
||||
continue; |
||||
} |
||||
} |
||||
} |
||||
|
||||
void DownloadingTorrents::addTorrent(QString hash) { |
||||
if(BTSession->isFinished(hash)){ |
||||
BTSession->setUnfinishedTorrent(hash); |
||||
} |
||||
QTorrentHandle h = BTSession->getTorrentHandle(hash); |
||||
int row = getRowFromHash(hash); |
||||
if(row != -1) return; |
||||
row = DLListModel->rowCount(); |
||||
// Adding torrent to download list
|
||||
DLListModel->insertRow(row); |
||||
DLListModel->setData(DLListModel->index(row, NAME), QVariant(h.name())); |
||||
DLListModel->setData(DLListModel->index(row, SIZE), QVariant((qlonglong)h.actual_size())); |
||||
DLListModel->setData(DLListModel->index(row, DLSPEED), QVariant((double)0.)); |
||||
DLListModel->setData(DLListModel->index(row, UPSPEED), QVariant((double)0.)); |
||||
DLListModel->setData(DLListModel->index(row, SEEDSLEECH), QVariant(QString::fromUtf8("0/0"))); |
||||
DLListModel->setData(DLListModel->index(row, ETA), QVariant((qlonglong)-1)); |
||||
DLListModel->setData(DLListModel->index(row, HASH), QVariant(hash)); |
||||
// Pause torrent if it was paused last time
|
||||
if(BTSession->isPaused(hash)) { |
||||
DLListModel->setData(DLListModel->index(row, NAME), QVariant(QIcon(QString::fromUtf8(":/Icons/skin/paused.png"))), Qt::DecorationRole); |
||||
setRowColor(row, QString::fromUtf8("red")); |
||||
}else{ |
||||
DLListModel->setData(DLListModel->index(row, NAME), QVariant(QIcon(QString::fromUtf8(":/Icons/skin/connecting.png"))), Qt::DecorationRole); |
||||
setRowColor(row, QString::fromUtf8("grey")); |
||||
} |
||||
++nbTorrents; |
||||
emit unfinishedTorrentsNumberChanged(nbTorrents); |
||||
} |
||||
|
||||
void DownloadingTorrents::sortDownloadListFloat(int index, Qt::SortOrder sortOrder) { |
||||
QList<QPair<int, double> > lines; |
||||
// insertion sorting
|
||||
unsigned int nbRows = DLListModel->rowCount(); |
||||
for(unsigned int i=0; i<nbRows; ++i) { |
||||
misc::insertSort(lines, QPair<int,double>(i, DLListModel->data(DLListModel->index(i, index)).toDouble()), sortOrder); |
||||
} |
||||
// Insert items in new model, in correct order
|
||||
unsigned int nbRows_old = lines.size(); |
||||
for(unsigned int row=0; row<nbRows_old; ++row) { |
||||
DLListModel->insertRow(DLListModel->rowCount()); |
||||
unsigned int sourceRow = lines[row].first; |
||||
unsigned int nbColumns = DLListModel->columnCount(); |
||||
for(unsigned int col=0; col<nbColumns; ++col) { |
||||
DLListModel->setData(DLListModel->index(nbRows_old+row, col), DLListModel->data(DLListModel->index(sourceRow, col))); |
||||
DLListModel->setData(DLListModel->index(nbRows_old+row, col), DLListModel->data(DLListModel->index(sourceRow, col), Qt::DecorationRole), Qt::DecorationRole); |
||||
DLListModel->setData(DLListModel->index(nbRows_old+row, col), DLListModel->data(DLListModel->index(sourceRow, col), Qt::ForegroundRole), Qt::ForegroundRole); |
||||
} |
||||
} |
||||
// Remove old rows
|
||||
DLListModel->removeRows(0, nbRows_old); |
||||
} |
||||
|
||||
void DownloadingTorrents::sortDownloadListString(int index, Qt::SortOrder sortOrder) { |
||||
QList<QPair<int, QString> > lines; |
||||
// Insertion sorting
|
||||
unsigned int nbRows = DLListModel->rowCount(); |
||||
for(unsigned int i=0; i<nbRows; ++i) { |
||||
misc::insertSortString(lines, QPair<int, QString>(i, DLListModel->data(DLListModel->index(i, index)).toString()), sortOrder); |
||||
} |
||||
// Insert items in new model, in correct order
|
||||
unsigned int nbRows_old = lines.size(); |
||||
for(unsigned int row=0; row<nbRows_old; ++row) { |
||||
DLListModel->insertRow(DLListModel->rowCount()); |
||||
unsigned int sourceRow = lines[row].first; |
||||
unsigned int nbColumns = DLListModel->columnCount(); |
||||
for(unsigned int col=0; col<nbColumns; ++col) { |
||||
DLListModel->setData(DLListModel->index(nbRows_old+row, col), DLListModel->data(DLListModel->index(sourceRow, col))); |
||||
DLListModel->setData(DLListModel->index(nbRows_old+row, col), DLListModel->data(DLListModel->index(sourceRow, col), Qt::DecorationRole), Qt::DecorationRole); |
||||
DLListModel->setData(DLListModel->index(nbRows_old+row, col), DLListModel->data(DLListModel->index(sourceRow, col), Qt::ForegroundRole), Qt::ForegroundRole); |
||||
} |
||||
} |
||||
// Remove old rows
|
||||
DLListModel->removeRows(0, nbRows_old); |
||||
} |
||||
|
||||
void DownloadingTorrents::sortDownloadList(int index, Qt::SortOrder startSortOrder, bool fromLoadColWidth) { |
||||
qDebug("Called sort download list"); |
||||
static Qt::SortOrder sortOrder = startSortOrder; |
||||
if(!fromLoadColWidth && downloadList->header()->sortIndicatorSection() == index) { |
||||
if(sortOrder == Qt::AscendingOrder) { |
||||
sortOrder = Qt::DescendingOrder; |
||||
}else{ |
||||
sortOrder = Qt::AscendingOrder; |
||||
} |
||||
} |
||||
QString sortOrderLetter; |
||||
if(sortOrder == Qt::AscendingOrder) |
||||
sortOrderLetter = QString::fromUtf8("a"); |
||||
else |
||||
sortOrderLetter = QString::fromUtf8("d"); |
||||
if(fromLoadColWidth) { |
||||
// XXX: Why is this needed?
|
||||
if(sortOrder == Qt::DescendingOrder) |
||||
downloadList->header()->setSortIndicator(index, Qt::AscendingOrder); |
||||
else |
||||
downloadList->header()->setSortIndicator(index, Qt::DescendingOrder); |
||||
} else { |
||||
downloadList->header()->setSortIndicator(index, sortOrder); |
||||
} |
||||
switch(index) { |
||||
case SIZE: |
||||
case ETA: |
||||
case UPSPEED: |
||||
case DLSPEED: |
||||
sortDownloadListFloat(index, sortOrder); |
||||
break; |
||||
case PROGRESS: |
||||
if(fromLoadColWidth) { |
||||
// Progress sorting must be delayed until files are checked (on startup)
|
||||
delayedSorting = true; |
||||
qDebug("Delayed sorting of the progress column"); |
||||
delayedSortingOrder = sortOrder; |
||||
}else{ |
||||
sortDownloadListFloat(index, sortOrder); |
||||
} |
||||
break; |
||||
default: |
||||
sortDownloadListString(index, sortOrder); |
||||
} |
||||
QSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent")); |
||||
settings.setValue(QString::fromUtf8("DownloadListSortedCol"), misc::toQString(index)+sortOrderLetter); |
||||
} |
||||
|
||||
// Save columns width in a file to remember them
|
||||
// (download list)
|
||||
void DownloadingTorrents::saveColWidthDLList() const{ |
||||
qDebug("Saving columns width in download list"); |
||||
QSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent")); |
||||
QStringList width_list; |
||||
unsigned int nbColumns = DLListModel->columnCount()-1; |
||||
for(unsigned int i=0; i<nbColumns; ++i) { |
||||
width_list << misc::toQString(downloadList->columnWidth(i)); |
||||
} |
||||
settings.setValue(QString::fromUtf8("DownloadListColsWidth"), width_list.join(QString::fromUtf8(" "))); |
||||
qDebug("Download list columns width saved"); |
||||
} |
||||
|
||||
// Load columns width in a file that were saved previously
|
||||
// (download list)
|
||||
bool DownloadingTorrents::loadColWidthDLList() { |
||||
qDebug("Loading columns width for download list"); |
||||
QSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent")); |
||||
QString line = settings.value(QString::fromUtf8("DownloadListColsWidth"), QString()).toString(); |
||||
if(line.isEmpty()) |
||||
return false; |
||||
QStringList width_list = line.split(QString::fromUtf8(" ")); |
||||
if(width_list.size() != DLListModel->columnCount()-1) { |
||||
qDebug("Corrupted values for download list columns sizes"); |
||||
return false; |
||||
} |
||||
unsigned int listSize = width_list.size(); |
||||
for(unsigned int i=0; i<listSize; ++i) { |
||||
downloadList->header()->resizeSection(i, width_list.at(i).toInt()); |
||||
} |
||||
// Loading last sorted column
|
||||
QString sortedCol = settings.value(QString::fromUtf8("DownloadListSortedCol"), QString()).toString(); |
||||
if(!sortedCol.isEmpty()) { |
||||
Qt::SortOrder sortOrder; |
||||
if(sortedCol.endsWith(QString::fromUtf8("d"))) |
||||
sortOrder = Qt::DescendingOrder; |
||||
else |
||||
sortOrder = Qt::AscendingOrder; |
||||
sortedCol = sortedCol.left(sortedCol.size()-1); |
||||
int index = sortedCol.toInt(); |
||||
sortDownloadList(index, sortOrder, true); |
||||
} |
||||
qDebug("Download list columns width loaded"); |
||||
return true; |
||||
} |
||||
|
||||
// Called when a torrent is added
|
||||
void DownloadingTorrents::torrentAdded(QString path, QTorrentHandle& h, bool fastResume) { |
||||
QString hash = h.hash(); |
||||
if(BTSession->isFinished(hash)) { |
||||
return; |
||||
} |
||||
int row = DLListModel->rowCount(); |
||||
// Adding torrent to download list
|
||||
DLListModel->insertRow(row); |
||||
DLListModel->setData(DLListModel->index(row, NAME), QVariant(h.name())); |
||||
DLListModel->setData(DLListModel->index(row, SIZE), QVariant((qlonglong)h.actual_size())); |
||||
DLListModel->setData(DLListModel->index(row, DLSPEED), QVariant((double)0.)); |
||||
DLListModel->setData(DLListModel->index(row, UPSPEED), QVariant((double)0.)); |
||||
DLListModel->setData(DLListModel->index(row, SEEDSLEECH), QVariant(QString::fromUtf8("0/0"))); |
||||
DLListModel->setData(DLListModel->index(row, RATIO), QVariant(misc::toQString(BTSession->getRealRatio(hash)))); |
||||
DLListModel->setData(DLListModel->index(row, ETA), QVariant((qlonglong)-1)); |
||||
DLListModel->setData(DLListModel->index(row, HASH), QVariant(hash)); |
||||
// Pause torrent if it was paused last time
|
||||
// Not using isPaused function because torrents are paused after checking now
|
||||
if(QFile::exists(misc::qBittorrentPath()+QString::fromUtf8("BT_backup")+QDir::separator()+hash+QString::fromUtf8(".paused"))) { |
||||
DLListModel->setData(DLListModel->index(row, NAME), QVariant(QIcon(QString::fromUtf8(":/Icons/skin/paused.png"))), Qt::DecorationRole); |
||||
setRowColor(row, QString::fromUtf8("red")); |
||||
}else{ |
||||
DLListModel->setData(DLListModel->index(row, NAME), QVariant(QIcon(QString::fromUtf8(":/Icons/skin/connecting.png"))), Qt::DecorationRole); |
||||
setRowColor(row, QString::fromUtf8("grey")); |
||||
} |
||||
if(!fastResume) { |
||||
setInfoBar(tr("'%1' added to download list.", "'/home/y/xxx.torrent' was added to download list.").arg(path)); |
||||
}else{ |
||||
setInfoBar(tr("'%1' resumed. (fast resume)", "'/home/y/xxx.torrent' was resumed. (fast resume)").arg(path)); |
||||
} |
||||
++nbTorrents; |
||||
emit unfinishedTorrentsNumberChanged(nbTorrents); |
||||
} |
||||
|
||||
// Called when trying to add a duplicate torrent
|
||||
void DownloadingTorrents::torrentDuplicate(QString path) { |
||||
setInfoBar(tr("'%1' is already in download list.", "e.g: 'xxx.avi' is already in download list.").arg(path)); |
||||
} |
||||
|
||||
void DownloadingTorrents::torrentCorrupted(QString path) { |
||||
setInfoBar(tr("Unable to decode torrent file: '%1'", "e.g: Unable to decode torrent file: '/home/y/xxx.torrent'").arg(path), QString::fromUtf8("red")); |
||||
setInfoBar(tr("This file is either corrupted or this isn't a torrent."),QString::fromUtf8("red")); |
||||
} |
||||
|
||||
void DownloadingTorrents::updateFileSizeAndProgress(QString hash) { |
||||
int row = getRowFromHash(hash); |
||||
Q_ASSERT(row != -1); |
||||
QTorrentHandle h = BTSession->getTorrentHandle(hash); |
||||
DLListModel->setData(DLListModel->index(row, SIZE), QVariant((qlonglong)h.actual_size())); |
||||
Q_ASSERT(h.progress() <= 1.); |
||||
DLListModel->setData(DLListModel->index(row, PROGRESS), QVariant((double)h.progress())); |
||||
} |
||||
|
||||
// Called when we couldn't listen on any port
|
||||
// in the given range.
|
||||
void DownloadingTorrents::portListeningFailure() { |
||||
setInfoBar(tr("Couldn't listen on any of the given ports."), QString::fromUtf8("red")); |
||||
} |
||||
|
||||
// Set the color of a row in data model
|
||||
void DownloadingTorrents::setRowColor(int row, QString color) { |
||||
unsigned int nbColumns = DLListModel->columnCount(); |
||||
for(unsigned int i=0; i<nbColumns; ++i) { |
||||
DLListModel->setData(DLListModel->index(row, i), QVariant(QColor(color)), Qt::ForegroundRole); |
||||
} |
||||
} |
||||
|
||||
// return the row of in data model
|
||||
// corresponding to the given the hash
|
||||
int DownloadingTorrents::getRowFromHash(QString hash) const{ |
||||
unsigned int nbRows = DLListModel->rowCount(); |
||||
for(unsigned int i=0; i<nbRows; ++i) { |
||||
if(DLListModel->data(DLListModel->index(i, HASH)) == hash) { |
||||
return i; |
||||
} |
||||
} |
||||
return -1; |
||||
} |
||||
|
||||
void DownloadingTorrents::displayDownloadingUrlInfos(QString url) { |
||||
setInfoBar(tr("Downloading '%1', please wait...", "e.g: Downloading 'xxx.torrent', please wait...").arg(url), QString::fromUtf8("black")); |
||||
} |
@ -0,0 +1,97 @@
@@ -0,0 +1,97 @@
|
||||
/*
|
||||
* Bittorrent Client using Qt4 and libtorrent. |
||||
* Copyright (C) 2006 Christophe Dumez |
||||
* |
||||
* 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
||||
* |
||||
* Contact : chris@qbittorrent.org |
||||
*/ |
||||
|
||||
#ifndef DOWNLOADINGTORRENTS_H |
||||
#define DOWNLOADINGTORRENTS_H |
||||
|
||||
#include "ui_download.h" |
||||
#include "qtorrenthandle.h" |
||||
|
||||
class QStandardItemModel; |
||||
class bittorrent; |
||||
class DLListDelegate; |
||||
|
||||
using namespace libtorrent; |
||||
|
||||
class DownloadingTorrents : public QWidget, public Ui::downloading{ |
||||
Q_OBJECT |
||||
private: |
||||
bittorrent *BTSession; |
||||
DLListDelegate *DLDelegate; |
||||
QStandardItemModel *DLListModel; |
||||
unsigned int nbTorrents; |
||||
bool delayedSorting; |
||||
Qt::SortOrder delayedSortingOrder; |
||||
QObject *parent; |
||||
|
||||
public: |
||||
DownloadingTorrents(QObject *parent, bittorrent *BTSession); |
||||
~DownloadingTorrents(); |
||||
// Methods
|
||||
bool loadColWidthDLList(); |
||||
int getRowFromHash(QString hash) const; |
||||
QString getHashFromRow(unsigned int row) const; |
||||
QStringList getSelectedTorrents(bool only_one=false) const; |
||||
unsigned int getNbTorrentsInList() const; |
||||
|
||||
signals: |
||||
void unfinishedTorrentsNumberChanged(unsigned int); |
||||
void torrentDoubleClicked(QString hash); |
||||
void torrentFinished(QString hash); |
||||
|
||||
protected slots: |
||||
void addLogPeerBlocked(QString); |
||||
void addFastResumeRejectedAlert(QString); |
||||
void addUrlSeedError(QString url, QString msg); |
||||
void on_actionSet_download_limit_triggered(); |
||||
void notifyTorrentDoubleClicked(const QModelIndex& index); |
||||
void on_actionSet_upload_limit_triggered(); |
||||
void displayDLListMenu(const QPoint& pos); |
||||
void on_actionClearLog_triggered(); |
||||
void displayInfoBarMenu(const QPoint& pos); |
||||
void addTorrent(QString hash); |
||||
void sortDownloadList(int index, Qt::SortOrder startSortOrder=Qt::AscendingOrder, bool fromLoadColWidth=false); |
||||
void sortDownloadListFloat(int index, Qt::SortOrder sortOrder); |
||||
void sortDownloadListString(int index, Qt::SortOrder sortOrder); |
||||
void saveColWidthDLList() const; |
||||
void torrentAdded(QString path, QTorrentHandle& h, bool fastResume); |
||||
void torrentDuplicate(QString path); |
||||
void torrentCorrupted(QString path); |
||||
void updateFileSizeAndProgress(QString hash); |
||||
void portListeningFailure(); |
||||
void setRowColor(int row, QString color); |
||||
void displayDownloadingUrlInfos(QString url); |
||||
void showProperties(const QModelIndex &index); |
||||
|
||||
public slots: |
||||
void updateDlList(); |
||||
void setInfoBar(QString info, QString color="black"); |
||||
void pauseTorrent(QString hash); |
||||
void resumeTorrent(QString hash); |
||||
void updateRatio(); |
||||
void deleteTorrent(QString hash); |
||||
void setBottomTabEnabled(unsigned int index, bool b); |
||||
void propertiesSelection(); |
||||
void sortProgressColumnDelayed(); |
||||
|
||||
}; |
||||
|
||||
#endif |
Loading…
Reference in new issue