mirror of
https://github.com/qbittorrent/qBittorrent.git
synced 2024-11-27 03:39:39 +03:00
- Disabled file prioritizing for seeding torrents
- Added file prioritizing to Web UI
This commit is contained in:
parent
d4524993ee
commit
aeb2c06e0f
10 changed files with 106 additions and 52 deletions
|
@ -111,23 +111,7 @@ QList<QVariantMap> EventManager::getPropFilesInfo(QString hash) const {
|
||||||
}
|
}
|
||||||
file["size"] = misc::friendlyUnit((double)fi->size);
|
file["size"] = misc::friendlyUnit((double)fi->size);
|
||||||
file["progress"] = fp[i]/(double)fi->size;
|
file["progress"] = fp[i]/(double)fi->size;
|
||||||
switch(priorities[i]) {
|
file["priority"] = priorities[i];
|
||||||
case IGNORED:
|
|
||||||
file["priority"] = tr("Ignored");
|
|
||||||
break;
|
|
||||||
case NORMAL:
|
|
||||||
file["priority"] = tr("Normal", "Normal (priority)");
|
|
||||||
break;
|
|
||||||
case HIGH:
|
|
||||||
file["priority"] = tr("High", "High (priority)");
|
|
||||||
break;
|
|
||||||
case MAXIMUM:
|
|
||||||
file["priority"] = tr("Maximum", "Maximum (priority)");
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
qDebug("Unhandled priority, setting NORMAL, priority was %d", priorities[i]);
|
|
||||||
file["priority"] = tr("Normal", "Normal (priority)");
|
|
||||||
}
|
|
||||||
files << file;
|
files << file;
|
||||||
++i;
|
++i;
|
||||||
}
|
}
|
||||||
|
|
|
@ -310,6 +310,15 @@ void HttpConnection::respondCommand(QString command)
|
||||||
emit resumeTorrent(parser.post("hash"));
|
emit resumeTorrent(parser.post("hash"));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if(command == "setFilePrio") {
|
||||||
|
QString hash = parser.post("hash");
|
||||||
|
int file_id = parser.post("id").toInt();
|
||||||
|
int priority = parser.post("priority").toInt();
|
||||||
|
QTorrentHandle h = BTSession->getTorrentHandle(hash);
|
||||||
|
if(h.is_valid()) {
|
||||||
|
h.file_priority(file_id, priority);
|
||||||
|
}
|
||||||
|
}
|
||||||
if(command == "pause") {
|
if(command == "pause") {
|
||||||
emit pauseTorrent(parser.post("hash"));
|
emit pauseTorrent(parser.post("hash"));
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -74,7 +74,7 @@ PropertiesWidget::PropertiesWidget(QWidget *parent, GUI* main_window, TransferLi
|
||||||
// Set Properties list model
|
// Set Properties list model
|
||||||
PropListModel = new TorrentFilesModel();
|
PropListModel = new TorrentFilesModel();
|
||||||
filesList->setModel(PropListModel);
|
filesList->setModel(PropListModel);
|
||||||
PropDelegate = new PropListDelegate(0);
|
PropDelegate = new PropListDelegate(this);
|
||||||
filesList->setItemDelegate(PropDelegate);
|
filesList->setItemDelegate(PropDelegate);
|
||||||
|
|
||||||
// QActions
|
// QActions
|
||||||
|
@ -229,7 +229,6 @@ void PropertiesWidget::loadTorrentInfos(QTorrentHandle &_h) {
|
||||||
// List files in torrent
|
// List files in torrent
|
||||||
PropListModel->clear();
|
PropListModel->clear();
|
||||||
PropListModel->setupModelData(h.get_torrent_info());
|
PropListModel->setupModelData(h.get_torrent_info());
|
||||||
PropListModel->updateFilesPriorities(h.file_priorities());
|
|
||||||
// Expand first item if possible
|
// Expand first item if possible
|
||||||
filesList->expand(PropListModel->index(0, 0));
|
filesList->expand(PropListModel->index(0, 0));
|
||||||
} catch(invalid_handle e) {
|
} catch(invalid_handle e) {
|
||||||
|
@ -359,6 +358,7 @@ void PropertiesWidget::loadDynamicData() {
|
||||||
std::vector<size_type> fp;
|
std::vector<size_type> fp;
|
||||||
h.file_progress(fp);
|
h.file_progress(fp);
|
||||||
PropListModel->updateFilesProgress(fp);
|
PropListModel->updateFilesProgress(fp);
|
||||||
|
PropListModel->updateFilesPriorities(h.file_priorities());
|
||||||
}
|
}
|
||||||
} catch(invalid_handle e) {}
|
} catch(invalid_handle e) {}
|
||||||
}
|
}
|
||||||
|
@ -550,13 +550,17 @@ void PropertiesWidget::deleteSelectedUrlSeeds(){
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool PropertiesWidget::savePiecesPriorities() {
|
bool PropertiesWidget::applyPriorities() {
|
||||||
qDebug("Saving pieces priorities");
|
qDebug("Saving pieces priorities");
|
||||||
std::vector<int> priorities = PropListModel->getFilesPriorities(h.get_torrent_info().num_files());
|
std::vector<int> priorities = PropListModel->getFilesPriorities(h.get_torrent_info().num_files());
|
||||||
bool first_last_piece_first = false;
|
bool first_last_piece_first = false;
|
||||||
|
// Save first/last piece first option state
|
||||||
if(h.first_last_piece_first())
|
if(h.first_last_piece_first())
|
||||||
first_last_piece_first = true;
|
first_last_piece_first = true;
|
||||||
|
// Prioritize the files
|
||||||
|
qDebug("prioritize files: %d", priorities[0]);
|
||||||
h.prioritize_files(priorities);
|
h.prioritize_files(priorities);
|
||||||
|
// Restore first/last piece first option if necessary
|
||||||
if(first_last_piece_first)
|
if(first_last_piece_first)
|
||||||
h.prioritize_first_last_piece(true);
|
h.prioritize_first_last_piece(true);
|
||||||
return true;
|
return true;
|
||||||
|
@ -592,7 +596,6 @@ void PropertiesWidget::on_changeSavePathButton_clicked() {
|
||||||
|
|
||||||
void PropertiesWidget::filteredFilesChanged() {
|
void PropertiesWidget::filteredFilesChanged() {
|
||||||
if(h.is_valid()) {
|
if(h.is_valid()) {
|
||||||
savePiecesPriorities();
|
applyPriorities();
|
||||||
transferList->updateTorrentSizeAndProgress(h.hash());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -76,7 +76,7 @@ private:
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
QPushButton* getButtonFromIndex(int index);
|
QPushButton* getButtonFromIndex(int index);
|
||||||
bool savePiecesPriorities();
|
bool applyPriorities();
|
||||||
|
|
||||||
protected slots:
|
protected slots:
|
||||||
void loadTorrentInfos(QTorrentHandle &h);
|
void loadTorrentInfos(QTorrentHandle &h);
|
||||||
|
|
|
@ -41,6 +41,7 @@
|
||||||
#include <QProgressBar>
|
#include <QProgressBar>
|
||||||
#include <QApplication>
|
#include <QApplication>
|
||||||
#include "misc.h"
|
#include "misc.h"
|
||||||
|
#include "propertieswidget.h"
|
||||||
|
|
||||||
// Defines for properties list columns
|
// Defines for properties list columns
|
||||||
enum PropColumn {NAME, SIZE, PROGRESS, PRIORITY};
|
enum PropColumn {NAME, SIZE, PROGRESS, PRIORITY};
|
||||||
|
@ -49,11 +50,14 @@ enum PropPriority {IGNORED=0, NORMAL=1, HIGH=2, MAXIMUM=7};
|
||||||
class PropListDelegate: public QItemDelegate {
|
class PropListDelegate: public QItemDelegate {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
|
private:
|
||||||
|
PropertiesWidget *properties;
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void filteredFilesChanged() const;
|
void filteredFilesChanged() const;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
PropListDelegate(QObject *parent=0) : QItemDelegate(parent){
|
PropListDelegate(PropertiesWidget* properties=0, QObject *parent=0) : QItemDelegate(parent), properties(properties){
|
||||||
}
|
}
|
||||||
|
|
||||||
~PropListDelegate(){}
|
~PropListDelegate(){}
|
||||||
|
@ -116,6 +120,10 @@ public:
|
||||||
QWidget* createEditor(QWidget *parent, const QStyleOptionViewItem &/* option */, const QModelIndex & index) const {
|
QWidget* createEditor(QWidget *parent, const QStyleOptionViewItem &/* option */, const QModelIndex & index) const {
|
||||||
qDebug("CreateEditor called");
|
qDebug("CreateEditor called");
|
||||||
if(index.column() != PRIORITY) return 0;
|
if(index.column() != PRIORITY) return 0;
|
||||||
|
if(properties) {
|
||||||
|
QTorrentHandle h = properties->getCurrentTorrent();
|
||||||
|
if(!h.is_valid() || h.is_seed()) return 0;
|
||||||
|
}
|
||||||
QComboBox* editor = new QComboBox(parent);
|
QComboBox* editor = new QComboBox(parent);
|
||||||
editor->setFocusPolicy(Qt::StrongFocus);
|
editor->setFocusPolicy(Qt::StrongFocus);
|
||||||
editor->addItem(tr("Ignored"));
|
editor->addItem(tr("Ignored"));
|
||||||
|
|
|
@ -470,7 +470,9 @@ void QTorrentHandle::set_max_connections(int val) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void QTorrentHandle::prioritize_files(std::vector<int> v) {
|
void QTorrentHandle::prioritize_files(std::vector<int> v) {
|
||||||
|
// Does not do anything for seeding torrents
|
||||||
Q_ASSERT(h.is_valid());
|
Q_ASSERT(h.is_valid());
|
||||||
|
Q_ASSERT(v.size() == (unsigned int)h.get_torrent_info().num_files());
|
||||||
h.prioritize_files(v);
|
h.prioritize_files(v);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -528,6 +530,7 @@ void QTorrentHandle::move_storage(QString new_path) const {
|
||||||
|
|
||||||
void QTorrentHandle::file_priority(int index, int priority) const {
|
void QTorrentHandle::file_priority(int index, int priority) const {
|
||||||
Q_ASSERT(h.is_valid());
|
Q_ASSERT(h.is_valid());
|
||||||
|
if(is_seed()) return;
|
||||||
h.file_priority(index, priority);
|
h.file_priority(index, priority);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -279,6 +279,7 @@ public:
|
||||||
|
|
||||||
void updateFilesPriorities(std::vector<int> fprio) {
|
void updateFilesPriorities(std::vector<int> fprio) {
|
||||||
for(unsigned int i=0; i<fprio.size(); ++i) {
|
for(unsigned int i=0; i<fprio.size(); ++i) {
|
||||||
|
qDebug("Called updateFilesPriorities with %d", fprio[i]);
|
||||||
files_index[i]->setPriority(fprio[i]);
|
files_index[i]->setPriority(fprio[i]);
|
||||||
}
|
}
|
||||||
emit layoutChanged();
|
emit layoutChanged();
|
||||||
|
@ -287,6 +288,7 @@ public:
|
||||||
std::vector<int> getFilesPriorities(unsigned int nbFiles) const {
|
std::vector<int> getFilesPriorities(unsigned int nbFiles) const {
|
||||||
std::vector<int> prio;
|
std::vector<int> prio;
|
||||||
for(unsigned int i=0; i<nbFiles; ++i) {
|
for(unsigned int i=0; i<nbFiles; ++i) {
|
||||||
|
qDebug("Called getFilesPriorities: %d", files_index[i]->getPriority());
|
||||||
prio.push_back(files_index[i]->getPriority());
|
prio.push_back(files_index[i]->getPriority());
|
||||||
}
|
}
|
||||||
return prio;
|
return prio;
|
||||||
|
|
|
@ -259,6 +259,23 @@ int TransferListWidget::updateTorrent(int row) {
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
|
// Connected_seeds*100000+total_seeds*10 (if total_seeds is available)
|
||||||
|
// Connected_seeds*100000+1 (if total_seeds is unavailable)
|
||||||
|
qulonglong seeds = h.num_seeds()*1000000;
|
||||||
|
if(h.num_complete() >= h.num_seeds())
|
||||||
|
seeds += h.num_complete()*10;
|
||||||
|
else
|
||||||
|
seeds += 1;
|
||||||
|
listModel->setData(listModel->index(row, TR_SEEDS), QVariant(seeds));
|
||||||
|
qulonglong peers = (h.num_peers()-h.num_seeds())*1000000;
|
||||||
|
if(h.num_incomplete() >= (h.num_peers()-h.num_seeds()))
|
||||||
|
peers += h.num_incomplete()*10;
|
||||||
|
else
|
||||||
|
peers += 1;
|
||||||
|
listModel->setData(listModel->index(row, TR_PEERS), QVariant(peers));
|
||||||
|
// Update torrent size. It changes when files are filtered from torrent properties
|
||||||
|
// or Web UI
|
||||||
|
listModel->setData(listModel->index(row, TR_SIZE), QVariant((qlonglong)h.actual_size()));
|
||||||
// Queueing code
|
// Queueing code
|
||||||
if(!h.is_seed() && BTSession->isQueueingEnabled()) {
|
if(!h.is_seed() && BTSession->isQueueingEnabled()) {
|
||||||
listModel->setData(listModel->index(row, TR_PRIORITY), QVariant((int)h.queue_position()));
|
listModel->setData(listModel->index(row, TR_PRIORITY), QVariant((int)h.queue_position()));
|
||||||
|
@ -293,20 +310,7 @@ int TransferListWidget::updateTorrent(int row) {
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Connected_seeds*100000+total_seeds*10 (if total_seeds is available)
|
|
||||||
// Connected_seeds*100000+1 (if total_seeds is unavailable)
|
|
||||||
qulonglong seeds = h.num_seeds()*1000000;
|
|
||||||
if(h.num_complete() >= h.num_seeds())
|
|
||||||
seeds += h.num_complete()*10;
|
|
||||||
else
|
|
||||||
seeds += 1;
|
|
||||||
listModel->setData(listModel->index(row, TR_SEEDS), QVariant(seeds));
|
|
||||||
qulonglong peers = (h.num_peers()-h.num_seeds())*1000000;
|
|
||||||
if(h.num_incomplete() >= (h.num_peers()-h.num_seeds()))
|
|
||||||
peers += h.num_incomplete()*10;
|
|
||||||
else
|
|
||||||
peers += 1;
|
|
||||||
listModel->setData(listModel->index(row, TR_PEERS), QVariant(peers));
|
|
||||||
if(h.is_paused()) {
|
if(h.is_paused()) {
|
||||||
if(h.is_seed())
|
if(h.is_seed())
|
||||||
return STATE_PAUSED_UP;
|
return STATE_PAUSED_UP;
|
||||||
|
@ -1098,10 +1102,3 @@ void TransferListWidget::applyFilter(int f) {
|
||||||
selectionModel()->setCurrentIndex(proxyModel->index(0, TR_NAME), QItemSelectionModel::SelectCurrent|QItemSelectionModel::Rows);
|
selectionModel()->setCurrentIndex(proxyModel->index(0, TR_NAME), QItemSelectionModel::SelectCurrent|QItemSelectionModel::Rows);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TransferListWidget::updateTorrentSizeAndProgress(QString hash) {
|
|
||||||
int row = getRowFromHash(hash);
|
|
||||||
Q_ASSERT(row != -1);
|
|
||||||
QTorrentHandle h = BTSession->getTorrentHandle(hash);
|
|
||||||
listModel->setData(listModel->index(row, TR_SIZE), QVariant((qlonglong)h.actual_size()));
|
|
||||||
listModel->setData(listModel->index(row, TR_PROGRESS), QVariant((double)h.progress()));
|
|
||||||
}
|
|
||||||
|
|
|
@ -108,7 +108,6 @@ public slots:
|
||||||
void hidePriorityColumn(bool hide);
|
void hidePriorityColumn(bool hide);
|
||||||
void displayDLHoSMenu(const QPoint&);
|
void displayDLHoSMenu(const QPoint&);
|
||||||
void applyFilter(int f);
|
void applyFilter(int f);
|
||||||
void updateTorrentSizeAndProgress(QString hash);
|
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void currentTorrentChanged(QTorrentHandle &h);
|
void currentTorrentChanged(QTorrentHandle &h);
|
||||||
|
|
|
@ -13,6 +13,49 @@
|
||||||
</span>
|
</span>
|
||||||
|
|
||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
|
var round1 = function(val){return Math.round(val*10)/10};
|
||||||
|
var waitingTorrentFiles=false;
|
||||||
|
var current_hash = "";
|
||||||
|
|
||||||
|
var setFilePriority = function(id, priority) {
|
||||||
|
if(current_hash == "") return;
|
||||||
|
new Request({url: '/command/setFilePrio', method: 'post', data: {'hash': current_hash, 'id': id, 'priority': priority}}).send();
|
||||||
|
}
|
||||||
|
|
||||||
|
var createPriorityCombo = function(id, selected_prio) {
|
||||||
|
var select = new Element('select');
|
||||||
|
select.set('id', 'comboPrio'+id);
|
||||||
|
select.addEvent('change', function(e){
|
||||||
|
var new_prio = $('comboPrio'+id).get('value');
|
||||||
|
setFilePriority(id, new_prio);
|
||||||
|
});
|
||||||
|
var opt = new Element("option");
|
||||||
|
opt.set('value', '0')
|
||||||
|
opt.set('html', "_(Ignored)");
|
||||||
|
if(selected_prio == 0)
|
||||||
|
opt.setAttribute('selected', '');
|
||||||
|
opt.injectInside(select);
|
||||||
|
opt = new Element("option");
|
||||||
|
opt.set('value', '1')
|
||||||
|
opt.set('html', "_(Normal)");
|
||||||
|
if(selected_prio == 1)
|
||||||
|
opt.setAttribute('selected', '');
|
||||||
|
opt.injectInside(select);
|
||||||
|
opt = new Element("option");
|
||||||
|
opt.set('value', '2')
|
||||||
|
opt.set('html', "_(High)");
|
||||||
|
if(selected_prio == 2)
|
||||||
|
opt.setAttribute('selected', '');
|
||||||
|
opt.injectInside(select);
|
||||||
|
opt = new Element("option");
|
||||||
|
opt.set('value', '7')
|
||||||
|
opt.set('html', "_(Maximum)");
|
||||||
|
if(selected_prio == 7)
|
||||||
|
opt.setAttribute('selected', '');
|
||||||
|
opt.injectInside(select);
|
||||||
|
return select;
|
||||||
|
}
|
||||||
|
|
||||||
var filesDynTable = new Class ({
|
var filesDynTable = new Class ({
|
||||||
|
|
||||||
initialize: function(){
|
initialize: function(){
|
||||||
|
@ -46,7 +89,13 @@
|
||||||
tds[i].set('html', '');
|
tds[i].set('html', '');
|
||||||
tds[i].adopt(new ProgressBar(row[i].toFloat(), {width:80}));
|
tds[i].adopt(new ProgressBar(row[i].toFloat(), {width:80}));
|
||||||
} else {
|
} else {
|
||||||
tds[i].set('html', row[i]);
|
if(i==3) {
|
||||||
|
tds[i].getChildren('select').set('value', row[i]);
|
||||||
|
//tds[i].set('html', '');
|
||||||
|
//tds[i].adopt(createPriorityCombo(id,row[i]));
|
||||||
|
} else {
|
||||||
|
tds[i].set('html', row[i]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
@ -67,17 +116,17 @@
|
||||||
if(i==2) {
|
if(i==2) {
|
||||||
td.adopt(new ProgressBar(row[i].toFloat(), {width:80}));
|
td.adopt(new ProgressBar(row[i].toFloat(), {width:80}));
|
||||||
} else {
|
} else {
|
||||||
td.set('html', row[i]);
|
if(i == 3) {
|
||||||
|
td.adopt(createPriorityCombo(id,row[i]));
|
||||||
|
} else {
|
||||||
|
td.set('html', row[i]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
td.injectInside(tr);
|
td.injectInside(tr);
|
||||||
}
|
}
|
||||||
tr.injectInside(this.table);
|
tr.injectInside(this.table);
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
var round1 = function(val){return Math.round(val*10)/10};
|
|
||||||
var waitingTorrentFiles=false;
|
|
||||||
var current_hash = "";
|
|
||||||
|
|
||||||
var loadTorrentFilesData = function() {
|
var loadTorrentFilesData = function() {
|
||||||
if(!$defined($('filesTable'))) {
|
if(!$defined($('filesTable'))) {
|
||||||
|
|
Loading…
Reference in a new issue