* More exit tweaking to make shutdown faster

* Fixed active upload icon in Web UI
* Fixed text alignment in Web UI preferences dialog
* Fixes to ratio display in Web UI transfer list and properties panel
* Edited Queued/Paused/Checking icons so that they are the same for complete/incomplete torrents (easier to understand)
* Color torrents in UI transfer list as in qBittorrent < 2.0 (more easily understandable)
* Progress and size are now updated when files are filtered in torrent properties
This commit is contained in:
Christophe Dumez 2009-11-30 21:30:14 +00:00
parent 63be5ffc74
commit 4dc8959f67
20 changed files with 93 additions and 59 deletions

View File

@ -4,7 +4,7 @@
- FEATURE: Display more information regarding the torrent in its properties
- FEATURE: Various optimizations to save CPU and memory
- FEATURE: Folder scanning now works with CIFS and NFS mounted folders
- FEATURE: Speed up qBittorrent startup
- FEATURE: Speed up qBittorrent startup and shutdown
- FEATURE: Display per-torrent peer list
- FEATURE: Make sure torrent files are always sorted by name
- FEATURE: Seeds and Peers columns are now sortable

View File

@ -196,17 +196,21 @@ GUI::GUI(QWidget *parent, QStringList torrentCmdLine) : QMainWindow(parent), dis
GUI::~GUI() {
qDebug("GUI destruction");
hide();
// Async deletion of Bittorrent session as early as possible
// in order to speed up exit
session_proxy sp = BTSession->asyncDeletion();
// Delete other GUI objects
delete status_bar;
delete transferList;
delete guiUpdater;
if(rssWidget)
delete rssWidget;
delete searchEngine;
delete transferListFilters;
delete properties;
delete transferList;
delete hSplitter;
delete vSplitter;
delete guiUpdater;
qDebug("1");
if(systrayCreator) {
delete systrayCreator;
}
@ -214,19 +218,21 @@ GUI::~GUI() {
delete systrayIcon;
delete myTrayIconMenu;
}
qDebug("2");
localServer->close();
delete localServer;
delete tabs;
qDebug("3");
// Keyboard shortcuts
delete switchSearchShortcut;
delete switchSearchShortcut2;
delete switchTransferShortcut;
delete switchRSSShortcut;
qDebug("4");
// Delete BTSession objects
delete BTSession;
qDebug("5");
// May freeze for a few seconds after the next line
// because the Bittorrent session proxy will
// actually be deleted now and destruction
// becomes synchronous
qDebug("Exiting GUI destructor...");
}
void GUI::displayRSSTab(bool enable) {

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.3 KiB

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.3 KiB

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.9 KiB

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.9 KiB

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.3 KiB

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.3 KiB

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.1 KiB

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.1 KiB

After

Width:  |  Height:  |  Size: 3.2 KiB

View File

@ -63,7 +63,7 @@
enum ProxyType {HTTP=1, SOCKS5=2, HTTP_PW=3, SOCKS5_PW=4};
// Main constructor
Bittorrent::Bittorrent() : preAllocateAll(false), addInPause(false), ratio_limit(-1), UPnPEnabled(false), NATPMPEnabled(false), LSDEnabled(false), DHTEnabled(false), queueingEnabled(false), geoipDBLoaded(false) {
Bittorrent::Bittorrent() : preAllocateAll(false), addInPause(false), ratio_limit(-1), UPnPEnabled(false), NATPMPEnabled(false), LSDEnabled(false), DHTEnabled(false), queueingEnabled(false), geoipDBLoaded(false), exiting(false) {
resolve_countries = false;
// To avoid some exceptions
fs::path::default_name_check(fs::no_check);
@ -102,9 +102,9 @@ Bittorrent::Bittorrent() : preAllocateAll(false), addInPause(false), ratio_limit
qDebug("* BTSession constructed");
}
// Main destructor
Bittorrent::~Bittorrent() {
qDebug("BTSession deletion");
session_proxy Bittorrent::asyncDeletion() {
qDebug("Bittorrent session async deletion IN");
exiting = true;
// Do some BT related saving
saveDHTEntry();
saveSessionState();
@ -112,6 +112,22 @@ Bittorrent::~Bittorrent() {
// Delete session
session_proxy sp = s->abort();
delete s;
qDebug("Bittorrent session async deletion OUT");
return sp;
}
// Main destructor
Bittorrent::~Bittorrent() {
qDebug("BTSession destructor IN");
if(!exiting) {
// Do some BT related saving
saveDHTEntry();
saveSessionState();
saveFastResumeData();
// Delete session
session_proxy sp = s->abort();
delete s;
}
// Disable directory scanning
disableDirectoryScanning();
// Delete our objects
@ -129,7 +145,7 @@ Bittorrent::~Bittorrent() {
delete httpServer;
if(timerETA)
delete timerETA;
qDebug("Deleting session...");
qDebug("BTSession destructor OUT");
}
void Bittorrent::preAllocateAllFiles(bool b) {

View File

@ -120,6 +120,8 @@ private:
// Web UI
QPointer<HttpServer> httpServer;
QStringList url_skippingDlg;
// Fast exit (async)
bool exiting;
protected:
QString getSavePath(QString hash);
@ -163,6 +165,7 @@ public slots:
void downloadFromUrl(QString url);
void deleteTorrent(QString hash, bool delete_local_files = false);
void startUpTorrents();
session_proxy asyncDeletion();
/* Needed by Web UI */
void pauseAllTorrents();
void pauseTorrent(QString hash);

View File

@ -161,19 +161,11 @@ QVariantMap EventManager::getPropGeneralInfo(QString hash) const {
data["time_elapsed"] = elapsed_txt;
data["nb_connections"] = QString::number(h.num_connections())+" ("+tr("%1 max", "e.g. 10 max").arg(QString::number(h.connections_limit()))+")";
// Update ratio info
float ratio;
if(h.total_payload_download() == 0){
if(h.total_payload_upload() == 0)
ratio = 1.;
double ratio = BTSession->getRealRatio(h.hash());
if(ratio > 100.)
data["share_ratio"] = QString::fromUtf8("");
else
ratio = 10.; // Max ratio
}else{
ratio = (double)h.total_payload_upload()/(double)h.total_payload_download();
if(ratio > 10.){
ratio = 10.;
}
}
data["share_ratio"] = QString(QByteArray::number(ratio, 'f', 1));
data["share_ratio"] = QString(QByteArray::number(ratio, 'f', 1));
}
return data;
}
@ -210,7 +202,7 @@ void EventManager::modifiedTorrent(QTorrentHandle h)
case torrent_status::finished:
case torrent_status::seeding:
if(h.upload_payload_rate() > 0) {
event["state"] = QVariant("seeding");
event["state"] = QVariant("uploading");
} else {
event["state"] = QVariant("stalledUP");
}
@ -263,7 +255,7 @@ void EventManager::modifiedTorrent(QTorrentHandle h)
event["seed"] = QVariant(h.is_seed());
double ratio = BTSession->getRealRatio(hash);
if(ratio > 100.)
QString::fromUtf8("");
event["ratio"] = QString::fromUtf8("");
else
event["ratio"] = QVariant(QString::number(ratio, 'f', 1));
event["hash"] = QVariant(hash);

View File

@ -211,8 +211,10 @@ int main(int argc, char *argv[]){
}
int ret = app->exec();
delete window;
qDebug("app children: %d", app->children().size());
qDebug("GUI was deleted!");
qDebug("Deleting app...");
delete app;
qDebug("App was deleted! All good.");
return ret;
}

View File

@ -356,8 +356,8 @@ void PropertiesWidget::loadDynamicData() {
// Files progress
std::vector<size_type> fp;
h.file_progress(fp);
PropListModel->updateFilesProgress(fp);
PropListModel->updateFilesPriorities(h.file_priorities());
PropListModel->updateFilesProgress(fp);
}
} catch(invalid_handle e) {}
}

View File

@ -133,13 +133,13 @@ public:
Q_ASSERT(type == FOLDER);
qulonglong size = 0;
foreach(TreeItem* child, childItems) {
size += child->getSize();
if(child->getPriority() > 0)
size += child->getSize();
}
setSize(size);
}
void setProgress(qulonglong done) {
if(done == total_done) return;
total_done = done;
qulonglong size = getSize();
Q_ASSERT(total_done <= size);
@ -149,6 +149,7 @@ public:
else
progress = 1.;
Q_ASSERT(progress >= 0. && progress <= 1.);
//qDebug("setProgress(%s): %f", getName().toLocal8Bit().data(), progress);
itemData.replace(2, progress);
if(parentItem)
parentItem->updateProgress();
@ -169,9 +170,12 @@ public:
if(type == ROOT) return;
Q_ASSERT(type == FOLDER);
total_done = 0;
//qDebug("Folder %s is updating its progress", getName().toLocal8Bit().data());
foreach(TreeItem* child, childItems) {
total_done += child->getTotalDone();
if(child->getPriority() > 0)
total_done += child->getTotalDone();
}
//qDebug("Folder: total_done: %llu/%llu", total_done, getSize());
Q_ASSERT(total_done <= getSize());
setProgress(total_done);
}
@ -180,16 +184,24 @@ public:
return itemData.value(3).toInt();
}
void setPriority(int priority) {
if(getPriority() != priority) {
itemData.replace(3, priority);
void setPriority(int new_prio) {
int old_prio = getPriority();
if(old_prio != new_prio) {
itemData.replace(3, new_prio);
// Update parent
if(parentItem)
if(parentItem) {
if(new_prio == 0 || old_prio == 0) {
// Files got filtered or unfiltered
// Update parent size and progress
parentItem->updateSize();
parentItem->updateProgress();
}
parentItem->updatePriority();
}
}
// Update children
foreach(TreeItem* child, childItems) {
child->setPriority(priority);
child->setPriority(new_prio);
}
}

View File

@ -163,7 +163,7 @@ void TransferListWidget::addTorrent(QTorrentHandle& h) {
listModel->setData(listModel->index(row, TR_STATUS), STATE_PAUSED_DL);
listModel->setData(listModel->index(row, TR_NAME), QVariant(QIcon(QString::fromUtf8(":/Icons/skin/pausedDL.png"))), Qt::DecorationRole);
}
//setRowColor(row, QString::fromUtf8("red"));
setRowColor(row, QString::fromUtf8("red"));
}else{
if(h.is_seed()) {
listModel->setData(listModel->index(row, TR_NAME), QVariant(QIcon(QString::fromUtf8(":/Icons/skin/stalledUP.png"))), Qt::DecorationRole);
@ -172,7 +172,7 @@ void TransferListWidget::addTorrent(QTorrentHandle& h) {
listModel->setData(listModel->index(row, TR_NAME), QVariant(QIcon(QString::fromUtf8(":/Icons/skin/stalledDL.png"))), Qt::DecorationRole);
listModel->setData(listModel->index(row, TR_STATUS), STATE_STALLED_DL);
}
//setRowColor(row, QString::fromUtf8("grey"));
setRowColor(row, QApplication::palette().color(QPalette::WindowText));
}
// Select first torrent to be added
if(listModel->rowCount() == 1)
@ -184,12 +184,12 @@ void TransferListWidget::addTorrent(QTorrentHandle& h) {
}
}
/*void TransferListWidget::setRowColor(int row, QColor color) {
void TransferListWidget::setRowColor(int row, QColor color) {
unsigned int nbColumns = listModel->columnCount()-1;
for(unsigned int i=0; i<nbColumns; ++i) {
listModel->setData(listModel->index(row, i), QVariant(color), Qt::ForegroundRole);
}
}*/
}
void TransferListWidget::deleteTorrent(int row, bool refresh_list) {
listModel->removeRow(row);
@ -216,7 +216,7 @@ void TransferListWidget::pauseTorrent(int row, bool refresh_list) {
}
listModel->setData(listModel->index(row, TR_SEEDS), QVariant(0.0));
listModel->setData(listModel->index(row, TR_PEERS), QVariant(0.0));
//setRowColor(row, QString::fromUtf8("red"));
setRowColor(row, QString::fromUtf8("red"));
if(refresh_list)
refreshList();
}
@ -236,6 +236,7 @@ void TransferListWidget::resumeTorrent(int row, bool refresh_list) {
listModel->setData(listModel->index(row, TR_NAME), QVariant(QIcon(":/Icons/skin/stalledDL.png")), Qt::DecorationRole);
listModel->setData(listModel->index(row, TR_STATUS), STATE_STALLED_DL);
}
setRowColor(row, QApplication::palette().color(QPalette::WindowText));
if(refresh_list)
refreshList();
}
@ -312,7 +313,7 @@ int TransferListWidget::updateTorrent(int row) {
listModel->setData(listModel->index(row, TR_UPSPEED), QVariant((double)0.));
listModel->setData(listModel->index(row, TR_SEEDS), QVariant(0.0));
listModel->setData(listModel->index(row, TR_PEERS), QVariant(0.0));
//setRowColor(row, QString::fromUtf8("grey"));
setRowColor(row, QString::fromUtf8("grey"));
return s;
}
}
@ -340,7 +341,7 @@ int TransferListWidget::updateTorrent(int row) {
}
listModel->setData(listModel->index(row, TR_PROGRESS), QVariant((double)h.progress()));
listModel->setData(listModel->index(row, TR_ETA), QVariant((qlonglong)-1));
//setRowColor(row, QString::fromUtf8("grey"));
setRowColor(row, QString::fromUtf8("grey"));
break;
case torrent_status::downloading:
case torrent_status::downloading_metadata:
@ -348,12 +349,12 @@ int TransferListWidget::updateTorrent(int row) {
listModel->setData(listModel->index(row, TR_NAME), QVariant(QIcon(QString::fromUtf8(":/Icons/skin/downloading.png"))), Qt::DecorationRole);
listModel->setData(listModel->index(row, TR_ETA), QVariant((qlonglong)BTSession->getETA(hash)));
s = STATE_DOWNLOADING;
//setRowColor(row, QString::fromUtf8("green"));
setRowColor(row, QString::fromUtf8("green"));
}else{
listModel->setData(listModel->index(row, TR_NAME), QVariant(QIcon(QString::fromUtf8(":/Icons/skin/stalledDL.png"))), Qt::DecorationRole);
listModel->setData(listModel->index(row, TR_ETA), QVariant((qlonglong)-1));
s = STATE_STALLED_DL;
//setRowColor(row, QApplication::palette().color(QPalette::WindowText));
setRowColor(row, QApplication::palette().color(QPalette::WindowText));
}
listModel->setData(listModel->index(row, TR_DLSPEED), QVariant((double)h.download_payload_rate()));
listModel->setData(listModel->index(row, TR_PROGRESS), QVariant((double)h.progress()));
@ -363,9 +364,11 @@ int TransferListWidget::updateTorrent(int row) {
if(h.upload_payload_rate() > 0) {
s = STATE_SEEDING;
listModel->setData(listModel->index(row, TR_NAME), QVariant(QIcon(QString::fromUtf8(":/Icons/skin/uploading.png"))), Qt::DecorationRole);
setRowColor(row, "orange");
} else {
s = STATE_STALLED_UP;
listModel->setData(listModel->index(row, TR_NAME), QVariant(QIcon(QString::fromUtf8(":/Icons/skin/stalledUP.png"))), Qt::DecorationRole);
setRowColor(row, QApplication::palette().color(QPalette::WindowText));
}
}
// Common to both downloads and uploads
@ -389,11 +392,11 @@ void TransferListWidget::setFinished(QTorrentHandle &h) {
if(h.is_paused()) {
listModel->setData(listModel->index(row, TR_NAME), QIcon(":/Icons/skin/pausedUP.png"), Qt::DecorationRole);
listModel->setData(listModel->index(row, TR_STATUS), STATE_PAUSED_UP);
//setRowColor(row, "red");
setRowColor(row, "red");
}else{
listModel->setData(listModel->index(row, TR_NAME), QVariant(QIcon(":/Icons/skin/stalledUP.png")), Qt::DecorationRole);
listModel->setData(listModel->index(row, TR_STATUS), STATE_STALLED_UP);
//setRowColor(row, "orange");
setRowColor(row, QApplication::palette().color(QPalette::WindowText));
}
listModel->setData(listModel->index(row, TR_ETA), QVariant((qlonglong)-1));
listModel->setData(listModel->index(row, TR_DLSPEED), QVariant((double)0.));

View File

@ -84,7 +84,7 @@ protected slots:
#endif
void toggleSelectedTorrentsSequentialDownload();
void toggleSelectedFirstLastPiecePrio();
//void setRowColor(int row, QColor color);
void setRowColor(int row, QColor color);
public slots:
void refreshList();

View File

@ -14,10 +14,10 @@
<div style="padding-left: 30px;">
<table>
<tr>
<td style="vertical-align: bottom;"><input type="checkbox" id="up_limit_checkbox" onClick="updateUpLimitEnabled();"/></td><td style="text-align: right; padding-right: 3px;">_(Upload:)</td><td><input type="text" id="up_limit_value" style="width: 4em;"/>&nbsp;&nbsp;_(KiB/s)</td>
<td style="vertical-align: bottom;"><input type="checkbox" id="up_limit_checkbox" onClick="updateUpLimitEnabled();"/></td><td style="padding-right: 3px;">_(Upload:)</td><td><input type="text" id="up_limit_value" style="width: 4em;"/>&nbsp;&nbsp;_(KiB/s)</td>
</tr>
<tr>
<td style="vertical-align: bottom;"><input type="checkbox" id="dl_limit_checkbox" onClick="updateDlLimitEnabled();"/></td><td style="text-align: right; padding-right: 3px;">_(Download:)</td><td><input type="text" id="dl_limit_value" style="width: 4em;"/>&nbsp;&nbsp;_(KiB/s)</td>
<td style="vertical-align: bottom;"><input type="checkbox" id="dl_limit_checkbox" onClick="updateDlLimitEnabled();"/></td><td style="padding-right: 3px;">_(Download:)</td><td><input type="text" id="dl_limit_value" style="width: 4em;"/>&nbsp;&nbsp;_(KiB/s)</td>
</tr>
</table>
</div>
@ -28,13 +28,13 @@
<div style="padding-left: 30px;">
<table>
<tr>
<td style="vertical-align: bottom;"><input type="checkbox" id="max_connec_checkbox" onClick="updateMaxConnecEnabled();"/></td><td style="text-align: right; padding-right: 3px;">_(Global maximum number of connections:)</td><td><input type="text" id="max_connec_value" style="width: 4em;"/></td>
<td style="vertical-align: bottom;"><input type="checkbox" id="max_connec_checkbox" onClick="updateMaxConnecEnabled();"/></td><td style="padding-right: 3px;">_(Global maximum number of connections:)</td><td><input type="text" id="max_connec_value" style="width: 4em;"/></td>
</tr>
<tr>
<td style="vertical-align: bottom;"><input type="checkbox" id="max_connec_per_torrent_checkbox" onClick="updateMaxConnecPerTorrentEnabled();" style="margin-bottom: -2px;"/></td><td style="text-align: right; padding-right: 3px;">_(Maximum number of connections per torrent:)</td><td><input type="text" id="max_connec_per_torrent_value" style="width: 4em;"/></td>
<td style="vertical-align: bottom;"><input type="checkbox" id="max_connec_per_torrent_checkbox" onClick="updateMaxConnecPerTorrentEnabled();" style="margin-bottom: -2px;"/></td><td style="padding-right: 3px;">_(Maximum number of connections per torrent:)</td><td><input type="text" id="max_connec_per_torrent_value" style="width: 4em;"/></td>
</tr>
<tr>
<td style="vertical-align: bottom;"><input type="checkbox" id="max_uploads_per_torrent_checkbox" onClick="updateMaxUploadsPerTorrentEnabled();" style="margin-bottom: -2px;"/></td><td style="text-align: right; padding-right: 3px;">_(Maximum number of upload slots per torrent:)</td><td><input type="text" id="max_uploads_per_torrent_value" style="width: 4em;"/></td>
<td style="vertical-align: bottom;"><input type="checkbox" id="max_uploads_per_torrent_checkbox" onClick="updateMaxUploadsPerTorrentEnabled();" style="margin-bottom: -2px;"/></td><td style="padding-right: 3px;">_(Maximum number of upload slots per torrent:)</td><td><input type="text" id="max_uploads_per_torrent_value" style="width: 4em;"/></td>
</tr>
</table>
</div>
@ -45,7 +45,7 @@
<div style="padding-left: 30px;">
<table>
<tr>
<td style="vertical-align: bottom;"><input type="checkbox" id="dht_checkbox"/></td><td style="text-align: right;">_(Enable DHT network (decentralized))</td>
<td style="vertical-align: bottom;"><input type="checkbox" id="dht_checkbox"/></td><td>_(Enable DHT network (decentralized))</td>
</tr>
</table>
</div>
@ -226,4 +226,4 @@ loadPreferences = function() {
loadPreferences();
</script>
</body>
</html>
</html>

View File

@ -194,21 +194,21 @@ var dynamicTable = new Class ({
}
break;
case 'completed':
if(status == "seeding" || status == "stalledUP" || status == "checkingUP" || status == "pausedUP" || status == "queuedUP") {
if(status == "uploading" || status == "stalledUP" || status == "checkingUP" || status == "pausedUP" || status == "queuedUP") {
tr.removeClass("invisible");
} else {
tr.addClass("invisible");
}
break;
case 'active':
if(status == "downloading" || status == "seeding") {
if(status == "downloading" || status == "uploading") {
tr.removeClass("invisible");
} else {
tr.addClass("invisible");
}
break;
case 'inactive':
if(status != "downloading" && status != "seeding") {
if(status != "downloading" && status != "uploading") {
tr.removeClass("invisible");
} else {
tr.addClass("invisible");