diff --git a/src/gui/transferlistmodel.cpp b/src/gui/transferlistmodel.cpp index 0298db047..83508d6f9 100644 --- a/src/gui/transferlistmodel.cpp +++ b/src/gui/transferlistmodel.cpp @@ -193,6 +193,7 @@ QVariant TransferListModel::headerData(const int section, const Qt::Orientation case TR_INFOHASH_V1: return tr("Info Hash v1", "i.e: torrent info hash v1"); case TR_INFOHASH_V2: return tr("Info Hash v2", "i.e: torrent info hash v2"); case TR_REANNOUNCE: return tr("Reannounce In", "Indicates the time until next trackers reannounce"); + case TR_PERCENT_SELECTED: return tr("Selected", "Percentage of selected data to download"); case TR_PRIVATE: return tr("Private", "Flags private torrents"); default: return {}; } @@ -201,6 +202,7 @@ QVariant TransferListModel::headerData(const int section, const Qt::Orientation { switch (section) { + case TR_PERCENT_SELECTED: return tr("Wanted / Total size, indicates percentage of selected data to download"); case TR_POPULARITY: return tr("Ratio / Time Active (in months), indicates how popular the torrent is"); default: return {}; } @@ -441,6 +443,8 @@ QString TransferListModel::displayValue(const BitTorrent::Torrent *torrent, cons return hashString(torrent->infoHash().v2()); case TR_REANNOUNCE: return reannounceString(torrent->nextAnnounce()); + case TR_PERCENT_SELECTED: + return torrent->hasMetadata() ? (QString::number((static_cast(torrent->wantedSize()) * 100) / torrent->totalSize(), 'f', 2) + u'%') : tr("N/A"); case TR_PRIVATE: return privateString(torrent->isPrivate(), torrent->hasMetadata()); } @@ -526,6 +530,8 @@ QVariant TransferListModel::internalValue(const BitTorrent::Torrent *torrent, co return torrent->nextAnnounce(); case TR_PRIVATE: return (torrent->hasMetadata() ? torrent->isPrivate() : QVariant()); + case TR_PERCENT_SELECTED: + return torrent->hasMetadata() ? ((static_cast(torrent->wantedSize()) * 100) / torrent->totalSize()) : 0; } return {}; diff --git a/src/gui/transferlistmodel.h b/src/gui/transferlistmodel.h index 306beee0b..04f0b155d 100644 --- a/src/gui/transferlistmodel.h +++ b/src/gui/transferlistmodel.h @@ -87,6 +87,7 @@ public: TR_INFOHASH_V2, TR_REANNOUNCE, TR_PRIVATE, + TR_PERCENT_SELECTED, NB_COLUMNS }; diff --git a/src/gui/transferlistsortmodel.cpp b/src/gui/transferlistsortmodel.cpp index 782aead74..7a2eb13b0 100644 --- a/src/gui/transferlistsortmodel.cpp +++ b/src/gui/transferlistsortmodel.cpp @@ -204,10 +204,11 @@ int TransferListSortModel::compare(const QModelIndex &left, const QModelIndex &r return customCompare(leftValue.toLongLong(), rightValue.toLongLong()); case TransferListModel::TR_AVAILABILITY: + case TransferListModel::TR_PERCENT_SELECTED: + case TransferListModel::TR_POPULARITY: case TransferListModel::TR_PROGRESS: case TransferListModel::TR_RATIO: case TransferListModel::TR_RATIO_LIMIT: - case TransferListModel::TR_POPULARITY: return customCompare(leftValue.toReal(), rightValue.toReal()); case TransferListModel::TR_STATUS: diff --git a/src/gui/transferlistwidget.cpp b/src/gui/transferlistwidget.cpp index 6fb71bfaa..4f15b34a6 100644 --- a/src/gui/transferlistwidget.cpp +++ b/src/gui/transferlistwidget.cpp @@ -192,6 +192,7 @@ TransferListWidget::TransferListWidget(IGUIApplication *app, QWidget *parent) setColumnHidden(TransferListModel::TR_TOTAL_SIZE, true); setColumnHidden(TransferListModel::TR_REANNOUNCE, true); setColumnHidden(TransferListModel::TR_PRIVATE, true); + setColumnHidden(TransferListModel::TR_PERCENT_SELECTED, true); } //Ensure that at least one column is visible at all times diff --git a/src/webui/www/private/scripts/dynamicTable.js b/src/webui/www/private/scripts/dynamicTable.js index 032a79a1e..43c9364a1 100644 --- a/src/webui/www/private/scripts/dynamicTable.js +++ b/src/webui/www/private/scripts/dynamicTable.js @@ -1140,12 +1140,14 @@ window.qBittorrent.DynamicTable ??= (() => { this.newColumn("infohash_v2", "", "QBT_TR(Info Hash v2)QBT_TR[CONTEXT=TransferListModel]", 100, false); this.newColumn("reannounce", "", "QBT_TR(Reannounce In)QBT_TR[CONTEXT=TransferListModel]", 100, false); this.newColumn("private", "", "QBT_TR(Private)QBT_TR[CONTEXT=TransferListModel]", 100, false); + this.newColumn("percent_selected", "", "QBT_TR(Selected)QBT_TR[CONTEXT=TransferListModel]", 100, false); this.columns["state_icon"].dataProperties[0] = "state"; this.columns["name"].dataProperties.push("state"); this.columns["num_seeds"].dataProperties.push("num_complete"); this.columns["num_leechs"].dataProperties.push("num_incomplete"); this.columns["time_active"].dataProperties.push("seeding_time"); + this.columns["percent_selected"].dataProperties = ["has_metadata", "size", "total_size"]; this.initColumnsFunctions(); } @@ -1549,6 +1551,51 @@ window.qBittorrent.DynamicTable ??= (() => { td.textContent = string; td.title = string; }; + + // percent_selected + this.columns["percent_selected"].updateTd = function(td, row) { + const hasMetadata = this.getRowValue(row, 0); + if (!hasMetadata) { + td.textContent = "QBT_TR(N/A)QBT_TR[CONTEXT=TrackerListWidget]"; + td.title = "QBT_TR(N/A)QBT_TR[CONTEXT=TrackerListWidget]"; + return; + } + const size = this.getRowValue(row, 1); + const totalSize = this.getRowValue(row, 2); + if (totalSize <= 0) { + td.textContent = "QBT_TR(N/A)QBT_TR[CONTEXT=TrackerListWidget]"; + td.title = "QBT_TR(N/A)QBT_TR[CONTEXT=TrackerListWidget]"; + return; + } + const percent = (size / totalSize) * 100; + const value = `${window.qBittorrent.Misc.toFixedPointString(percent, 2)}%`; + td.textContent = value; + td.title = value; + }; + + this.columns["percent_selected"].compareRows = function(row1, row2) { + const hasMetadata1 = this.getRowValue(row1, 0); + const hasMetadata2 = this.getRowValue(row2, 0); + + if (hasMetadata1 && !hasMetadata2) + return -1; + if (!hasMetadata1 && hasMetadata2) + return 1; + + const size1 = this.getRowValue(row1, 1); + const totalSize1 = this.getRowValue(row1, 2); + if (totalSize1 <= 0) + return 1; + const ratio1 = (size1 / totalSize1) * 100; + + const size2 = this.getRowValue(row2, 1); + const totalSize2 = this.getRowValue(row2, 2); + if (totalSize2 <= 0) + return -1; + const ratio2 = (size2 / totalSize2) * 100; + + return compareNumbers(ratio1, ratio2); + }; } applyFilter(row, filterName, category, tag, trackerHost, filterTerms) {