Browse Source

Merge pull request #13123 from glassez/handle-paused

Handle torrent "paused" state at application level
adaptive-webui-19844
Vladimir Golovnev 4 years ago committed by GitHub
parent
commit
61770ad69e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 24
      src/base/bittorrent/session.cpp
  2. 2
      src/base/bittorrent/session.h
  3. 10
      src/base/bittorrent/torrenthandle.cpp
  4. 13
      src/base/bittorrent/torrenthandle.h
  5. 176
      src/base/bittorrent/torrenthandleimpl.cpp
  6. 9
      src/base/bittorrent/torrenthandleimpl.h
  7. 4
      src/gui/transferlistmodel.cpp
  8. 12
      src/gui/transferlistwidget.cpp
  9. 2
      src/webui/api/serialize/serialize_torrent.cpp
  10. 5
      src/webui/api/torrentscontroller.cpp

24
src/base/bittorrent/session.cpp

@ -2253,14 +2253,12 @@ void Session::exportTorrentFile(const TorrentHandle *torrent, TorrentExportFolde
} }
} }
void Session::generateResumeData(const bool final) void Session::generateResumeData()
{ {
for (TorrentHandleImpl *const torrent : asConst(m_torrents)) { for (TorrentHandleImpl *const torrent : asConst(m_torrents)) {
if (!torrent->isValid()) continue; if (!torrent->isValid()) continue;
if (!final && !torrent->needSaveResumeData()) continue; if (torrent->needSaveResumeData())
if (torrent->isPaused()) continue;
torrent->saveResumeData(); torrent->saveResumeData();
} }
} }
@ -2273,10 +2271,10 @@ void Session::saveResumeData()
if (isQueueingSystemEnabled()) if (isQueueingSystemEnabled())
saveTorrentsQueue(); saveTorrentsQueue();
generateResumeData(true); generateResumeData();
while (m_numResumeData > 0) { while (m_numResumeData > 0) {
const std::vector<lt::alert *> alerts = getPendingAlerts(lt::seconds(30)); const std::vector<lt::alert *> alerts = getPendingAlerts(lt::seconds {30});
if (alerts.empty()) { if (alerts.empty()) {
LogMsg(tr("Error: Aborted saving resume data for %1 outstanding torrents.").arg(QString::number(m_numResumeData)) LogMsg(tr("Error: Aborted saving resume data for %1 outstanding torrents.").arg(QString::number(m_numResumeData))
, Log::CRITICAL); , Log::CRITICAL);
@ -3736,7 +3734,6 @@ void Session::handleTorrentMetadataReceived(TorrentHandleImpl *const torrent)
void Session::handleTorrentPaused(TorrentHandleImpl *const torrent) void Session::handleTorrentPaused(TorrentHandleImpl *const torrent)
{ {
if (!torrent->hasError() && !torrent->hasMissingFiles())
torrent->saveResumeData(); torrent->saveResumeData();
emit torrentPaused(torrent); emit torrentPaused(torrent);
} }
@ -4069,6 +4066,19 @@ bool Session::loadTorrentResumeData(const QByteArray &data, const TorrentInfo &m
if (metadata.isValid()) if (metadata.isValid())
p.ti = metadata.nativeInfo(); p.ti = metadata.nativeInfo();
torrentParams.paused = (p.flags & lt::torrent_flags::paused) && !(p.flags & lt::torrent_flags::auto_managed);
if (!torrentParams.paused) {
// If torrent has "stop_when_ready" flag set then it is actually "stopped"
// but temporarily "resumed" to perform some service jobs (e.g. checking)
torrentParams.paused = !!(p.flags & lt::torrent_flags::stop_when_ready);
}
else {
// Fix inconsistent state when "paused" torrent has "stop_when_ready" flag set
p.flags &= ~lt::torrent_flags::stop_when_ready;
}
torrentParams.forced = !(p.flags & lt::torrent_flags::paused) && !(p.flags & lt::torrent_flags::auto_managed);
const bool hasMetadata = (p.ti && p.ti->is_valid()); const bool hasMetadata = (p.ti && p.ti->is_valid());
if (!hasMetadata && !root.dict_find("info-hash")) { if (!hasMetadata && !root.dict_find("info-hash")) {
// TODO: The following code is deprecated. Remove after several releases in 4.3.x. // TODO: The following code is deprecated. Remove after several releases in 4.3.x.

2
src/base/bittorrent/session.h

@ -533,7 +533,7 @@ namespace BitTorrent
void readAlerts(); void readAlerts();
void enqueueRefresh(); void enqueueRefresh();
void processShareLimits(); void processShareLimits();
void generateResumeData(bool final = false); void generateResumeData();
void handleIPFilterParsed(int ruleCount); void handleIPFilterParsed(int ruleCount);
void handleIPFilterError(); void handleIPFilterError();
void handleDownloadFinished(const Net::DownloadResult &result); void handleDownloadFinished(const Net::DownloadResult &result);

10
src/base/bittorrent/torrenthandle.cpp

@ -49,6 +49,16 @@ namespace BitTorrent
const qreal TorrentHandle::MAX_RATIO = 9999.; const qreal TorrentHandle::MAX_RATIO = 9999.;
const int TorrentHandle::MAX_SEEDING_TIME = 525600; const int TorrentHandle::MAX_SEEDING_TIME = 525600;
bool TorrentHandle::isResumed() const
{
return !isPaused();
}
qlonglong TorrentHandle::remainingSize() const
{
return wantedSize() - completedSize();
}
void TorrentHandle::toggleSequentialDownload() void TorrentHandle::toggleSequentialDownload()
{ {
setSequentialDownload(!isSequentialDownload()); setSequentialDownload(!isSequentialDownload());

13
src/base/bittorrent/torrenthandle.h

@ -49,6 +49,12 @@ namespace BitTorrent
class TrackerEntry; class TrackerEntry;
struct PeerAddress; struct PeerAddress;
enum class TorrentOperatingMode
{
AutoManaged = 0,
Forced = 1
};
enum class TorrentState enum class TorrentState
{ {
Unknown = -1, Unknown = -1,
@ -110,7 +116,6 @@ namespace BitTorrent
virtual qlonglong totalSize() const = 0; virtual qlonglong totalSize() const = 0;
virtual qlonglong wantedSize() const = 0; virtual qlonglong wantedSize() const = 0;
virtual qlonglong completedSize() const = 0; virtual qlonglong completedSize() const = 0;
virtual qlonglong incompletedSize() const = 0;
virtual qlonglong pieceLength() const = 0; virtual qlonglong pieceLength() const = 0;
virtual qlonglong wastedSize() const = 0; virtual qlonglong wastedSize() const = 0;
virtual QString currentTracker() const = 0; virtual QString currentTracker() const = 0;
@ -195,7 +200,6 @@ namespace BitTorrent
virtual TorrentInfo info() const = 0; virtual TorrentInfo info() const = 0;
virtual bool isSeed() const = 0; virtual bool isSeed() const = 0;
virtual bool isPaused() const = 0; virtual bool isPaused() const = 0;
virtual bool isResumed() const = 0;
virtual bool isQueued() const = 0; virtual bool isQueued() const = 0;
virtual bool isForced() const = 0; virtual bool isForced() const = 0;
virtual bool isChecking() const = 0; virtual bool isChecking() const = 0;
@ -267,7 +271,7 @@ namespace BitTorrent
virtual void setSequentialDownload(bool enable) = 0; virtual void setSequentialDownload(bool enable) = 0;
virtual void setFirstLastPiecePriority(bool enabled) = 0; virtual void setFirstLastPiecePriority(bool enabled) = 0;
virtual void pause() = 0; virtual void pause() = 0;
virtual void resume(bool forced = false) = 0; virtual void resume(TorrentOperatingMode mode = TorrentOperatingMode::AutoManaged) = 0;
virtual void move(QString path) = 0; virtual void move(QString path) = 0;
virtual void forceReannounce(int index = -1) = 0; virtual void forceReannounce(int index = -1) = 0;
virtual void forceDHTAnnounce() = 0; virtual void forceDHTAnnounce() = 0;
@ -289,6 +293,9 @@ namespace BitTorrent
virtual QString createMagnetURI() const = 0; virtual QString createMagnetURI() const = 0;
bool isResumed() const;
qlonglong remainingSize() const;
void toggleSequentialDownload(); void toggleSequentialDownload();
void toggleFirstLastPiecePriority(); void toggleFirstLastPiecePriority();
}; };

176
src/base/bittorrent/torrenthandleimpl.cpp

@ -112,10 +112,12 @@ TorrentHandleImpl::TorrentHandleImpl(Session *session, const lt::torrent_handle
, m_tags(params.tags) , m_tags(params.tags)
, m_ratioLimit(params.ratioLimit) , m_ratioLimit(params.ratioLimit)
, m_seedingTimeLimit(params.seedingTimeLimit) , m_seedingTimeLimit(params.seedingTimeLimit)
, m_operatingMode(params.forced ? TorrentOperatingMode::Forced : TorrentOperatingMode::AutoManaged)
, m_hasSeedStatus(params.hasSeedStatus) , m_hasSeedStatus(params.hasSeedStatus)
, m_hasRootFolder(params.hasRootFolder) , m_hasRootFolder(params.hasRootFolder)
, m_hasFirstLastPiecePriority(params.firstLastPiecePriority) , m_hasFirstLastPiecePriority(params.firstLastPiecePriority)
, m_useAutoTMM(params.savePath.isEmpty()) , m_useAutoTMM(params.savePath.isEmpty())
, m_isStopped(params.paused)
, m_ltAddTorrentParams(params.ltAddTorrentParams) , m_ltAddTorrentParams(params.ltAddTorrentParams)
{ {
if (m_useAutoTMM) if (m_useAutoTMM)
@ -220,11 +222,6 @@ qlonglong TorrentHandleImpl::completedSize() const
return m_nativeStatus.total_wanted_done; return m_nativeStatus.total_wanted_done;
} }
qlonglong TorrentHandleImpl::incompletedSize() const
{
return (m_nativeStatus.total_wanted - m_nativeStatus.total_wanted_done);
}
qlonglong TorrentHandleImpl::pieceLength() const qlonglong TorrentHandleImpl::pieceLength() const
{ {
return m_torrentInfo.pieceLength(); return m_torrentInfo.pieceLength();
@ -298,11 +295,6 @@ QString TorrentHandleImpl::actualStorageLocation() const
return QString::fromStdString(m_nativeStatus.save_path); return QString::fromStdString(m_nativeStatus.save_path);
} }
bool TorrentHandleImpl::isAutoManaged() const
{
return static_cast<bool>(m_nativeStatus.flags & lt::torrent_flags::auto_managed);
}
void TorrentHandleImpl::setAutoManaged(const bool enable) void TorrentHandleImpl::setAutoManaged(const bool enable)
{ {
if (enable) if (enable)
@ -466,7 +458,9 @@ bool TorrentHandleImpl::connectPeer(const PeerAddress &peerAddress)
bool TorrentHandleImpl::needSaveResumeData() const bool TorrentHandleImpl::needSaveResumeData() const
{ {
return m_nativeHandle.need_save_resume_data(); if (m_isStopped && !(m_nativeStatus.flags & lt::torrent_flags::auto_managed))
return false;
return m_nativeStatus.need_save_resume;
} }
void TorrentHandleImpl::saveResumeData() void TorrentHandleImpl::saveResumeData()
@ -492,8 +486,10 @@ int TorrentHandleImpl::piecesHave() const
qreal TorrentHandleImpl::progress() const qreal TorrentHandleImpl::progress() const
{ {
if (!isChecking()) { if (isChecking())
if (!m_nativeStatus.total_wanted) return m_nativeStatus.progress;
if (m_nativeStatus.total_wanted == 0)
return 0.; return 0.;
if (m_nativeStatus.total_wanted_done == m_nativeStatus.total_wanted) if (m_nativeStatus.total_wanted_done == m_nativeStatus.total_wanted)
@ -502,9 +498,6 @@ qreal TorrentHandleImpl::progress() const
const qreal progress = static_cast<qreal>(m_nativeStatus.total_wanted_done) / m_nativeStatus.total_wanted; const qreal progress = static_cast<qreal>(m_nativeStatus.total_wanted_done) / m_nativeStatus.total_wanted;
Q_ASSERT((progress >= 0.f) && (progress <= 1.f)); Q_ASSERT((progress >= 0.f) && (progress <= 1.f));
return progress; return progress;
}
return m_nativeStatus.progress;
} }
QString TorrentHandleImpl::category() const QString TorrentHandleImpl::category() const
@ -629,19 +622,13 @@ TorrentInfo TorrentHandleImpl::info() const
bool TorrentHandleImpl::isPaused() const bool TorrentHandleImpl::isPaused() const
{ {
return ((m_nativeStatus.flags & lt::torrent_flags::paused) return m_isStopped;
&& !isAutoManaged());
}
bool TorrentHandleImpl::isResumed() const
{
return !isPaused();
} }
bool TorrentHandleImpl::isQueued() const bool TorrentHandleImpl::isQueued() const
{ {
return ((m_nativeStatus.flags & lt::torrent_flags::paused) // Torrent is Queued if it isn't in Paused state but paused internally
&& isAutoManaged()); return ((m_nativeStatus.flags & lt::torrent_flags::paused) && !isPaused());
} }
bool TorrentHandleImpl::isChecking() const bool TorrentHandleImpl::isChecking() const
@ -706,21 +693,13 @@ bool TorrentHandleImpl::isErrored() const
bool TorrentHandleImpl::isSeed() const bool TorrentHandleImpl::isSeed() const
{ {
// Affected by bug http://code.rasterbar.com/libtorrent/ticket/402
//bool result;
//result = m_nativeHandle.is_seed());
//return result;
// May suffer from approximation problems
//return (progress() == 1.);
// This looks safe
return ((m_nativeStatus.state == lt::torrent_status::finished) return ((m_nativeStatus.state == lt::torrent_status::finished)
|| (m_nativeStatus.state == lt::torrent_status::seeding)); || (m_nativeStatus.state == lt::torrent_status::seeding));
} }
bool TorrentHandleImpl::isForced() const bool TorrentHandleImpl::isForced() const
{ {
return (!(m_nativeStatus.flags & lt::torrent_flags::paused) return (!isPaused() && (m_operatingMode == TorrentOperatingMode::Forced));
&& !isAutoManaged());
} }
bool TorrentHandleImpl::isSequentialDownload() const bool TorrentHandleImpl::isSequentialDownload() const
@ -743,24 +722,6 @@ void TorrentHandleImpl::updateState()
if (m_nativeStatus.state == lt::torrent_status::checking_resume_data) { if (m_nativeStatus.state == lt::torrent_status::checking_resume_data) {
m_state = TorrentState::CheckingResumeData; m_state = TorrentState::CheckingResumeData;
} }
else if (isPaused()) {
if (isMoveInProgress()) {
m_state = TorrentState::Moving;
}
else if (hasMissingFiles()) {
m_state = TorrentState::MissingFiles;
}
else if (hasError()) {
m_state = TorrentState::Error;
}
else {
m_state = isSeed() ? TorrentState::PausedUploading : TorrentState::PausedDownloading;
}
}
else {
if (m_nativeStatus.state == lt::torrent_status::checking_files) {
m_state = m_hasSeedStatus ? TorrentState::CheckingUploading : TorrentState::CheckingDownloading;
}
else if (m_nativeStatus.state == lt::torrent_status::allocating) { else if (m_nativeStatus.state == lt::torrent_status::allocating) {
m_state = TorrentState::Allocating; m_state = TorrentState::Allocating;
} }
@ -773,32 +734,37 @@ void TorrentHandleImpl::updateState()
else if (hasError()) { else if (hasError()) {
m_state = TorrentState::Error; m_state = TorrentState::Error;
} }
else if (m_session->isQueueingSystemEnabled() && isQueued() && !isChecking()) { else if ((m_nativeStatus.state == lt::torrent_status::checking_files)
m_state = isSeed() ? TorrentState::QueuedUploading : TorrentState::QueuedDownloading; && (!isPaused() || (m_nativeStatus.flags & lt::torrent_flags::auto_managed)
|| !(m_nativeStatus.flags & lt::torrent_flags::paused))) {
// If the torrent is not just in the "checking" state, but is being actually checked
m_state = m_hasSeedStatus ? TorrentState::CheckingUploading : TorrentState::CheckingDownloading;
} }
else { else if (isSeed()) {
switch (m_nativeStatus.state) { if (isPaused())
case lt::torrent_status::finished: m_state = TorrentState::PausedUploading;
case lt::torrent_status::seeding: else if (m_session->isQueueingSystemEnabled() && isQueued())
if (isForced()) m_state = TorrentState::QueuedUploading;
else if (isForced())
m_state = TorrentState::ForcedUploading; m_state = TorrentState::ForcedUploading;
else if (m_nativeStatus.upload_payload_rate > 0)
m_state = TorrentState::Uploading;
else else
m_state = m_nativeStatus.upload_payload_rate > 0 ? TorrentState::Uploading : TorrentState::StalledUploading; m_state = TorrentState::StalledUploading;
break; }
case lt::torrent_status::downloading_metadata: else {
if (isPaused())
m_state = TorrentState::PausedDownloading;
else if (m_nativeStatus.state == lt::torrent_status::downloading_metadata)
m_state = TorrentState::DownloadingMetadata; m_state = TorrentState::DownloadingMetadata;
break; else if (m_session->isQueueingSystemEnabled() && isQueued())
case lt::torrent_status::downloading: m_state = TorrentState::QueuedDownloading;
if (isForced()) else if (isForced())
m_state = TorrentState::ForcedDownloading; m_state = TorrentState::ForcedDownloading;
else if (m_nativeStatus.download_payload_rate > 0)
m_state = TorrentState::Downloading;
else else
m_state = m_nativeStatus.download_payload_rate > 0 ? TorrentState::Downloading : TorrentState::StalledDownloading; m_state = TorrentState::StalledDownloading;
break;
default:
qWarning("Unrecognized torrent status, should not happen!!! status was %d", m_nativeStatus.state);
m_state = TorrentState::Unknown;
}
}
} }
} }
@ -1206,6 +1172,7 @@ void TorrentHandleImpl::forceRecheck()
if (!hasMetadata()) return; if (!hasMetadata()) return;
m_nativeHandle.force_recheck(); m_nativeHandle.force_recheck();
m_hasMissingFiles = false;
m_unchecked = false; m_unchecked = false;
if (isPaused()) { if (isPaused()) {
@ -1278,24 +1245,18 @@ void TorrentHandleImpl::applyFirstLastPiecePriority(const bool enabled, const QV
void TorrentHandleImpl::pause() void TorrentHandleImpl::pause()
{ {
if (isPaused()) return;
setAutoManaged(false); setAutoManaged(false);
m_nativeHandle.pause(); m_nativeHandle.pause();
// Libtorrent doesn't emit a torrent_paused_alert when the m_speedMonitor.reset();
// torrent is queued (no I/O)
// We test on the cached m_nativeStatus
if (isQueued())
m_session->handleTorrentPaused(this);
}
void TorrentHandleImpl::resume(bool forced) if (!m_isStopped) {
{ m_isStopped = true;
resume_impl(forced); m_session->handleTorrentPaused(this);
}
} }
void TorrentHandleImpl::resume_impl(bool forced) void TorrentHandleImpl::resume(const TorrentOperatingMode mode)
{ {
if (hasError()) if (hasError())
m_nativeHandle.clear_error(); m_nativeHandle.clear_error();
@ -1305,9 +1266,22 @@ void TorrentHandleImpl::resume_impl(bool forced)
m_nativeHandle.force_recheck(); m_nativeHandle.force_recheck();
} }
setAutoManaged(!forced); if (m_isStopped) {
if (forced) // Torrent may have been temporarily resumed to perform checking files
// so we have to ensure it will not pause after checking is done.
m_nativeHandle.unset_flags(lt::torrent_flags::stop_when_ready);
}
setAutoManaged(mode == TorrentOperatingMode::AutoManaged);
if (mode == TorrentOperatingMode::Forced)
m_nativeHandle.resume(); m_nativeHandle.resume();
m_operatingMode = mode;
if (m_isStopped) {
m_isStopped = false;
m_session->handleTorrentResumed(this);
}
} }
void TorrentHandleImpl::moveStorage(const QString &newPath, const MoveStorageMode mode) void TorrentHandleImpl::moveStorage(const QString &newPath, const MoveStorageMode mode)
@ -1442,18 +1416,11 @@ void TorrentHandleImpl::handleTorrentFinishedAlert(const lt::torrent_finished_al
void TorrentHandleImpl::handleTorrentPausedAlert(const lt::torrent_paused_alert *p) void TorrentHandleImpl::handleTorrentPausedAlert(const lt::torrent_paused_alert *p)
{ {
Q_UNUSED(p); Q_UNUSED(p);
updateStatus();
m_speedMonitor.reset();
m_session->handleTorrentPaused(this);
} }
void TorrentHandleImpl::handleTorrentResumedAlert(const lt::torrent_resumed_alert *p) void TorrentHandleImpl::handleTorrentResumedAlert(const lt::torrent_resumed_alert *p)
{ {
Q_UNUSED(p); Q_UNUSED(p);
m_session->handleTorrentResumed(this);
} }
void TorrentHandleImpl::handleSaveResumeDataAlert(const lt::save_resume_data_alert *p) void TorrentHandleImpl::handleSaveResumeDataAlert(const lt::save_resume_data_alert *p)
@ -1463,7 +1430,17 @@ void TorrentHandleImpl::handleSaveResumeDataAlert(const lt::save_resume_data_ale
m_ltAddTorrentParams = p->params; m_ltAddTorrentParams = p->params;
} }
updateStatus(); if (!m_isStopped) {
// Torrent can be actually "running" but temporarily "paused" to perform some
// service jobs behind the scenes so we need to restore it as "running"
if (m_operatingMode == TorrentOperatingMode::AutoManaged) {
m_ltAddTorrentParams.flags |= lt::torrent_flags::auto_managed;
}
else {
m_ltAddTorrentParams.flags &= ~lt::torrent_flags::paused;
m_ltAddTorrentParams.flags &= ~lt::torrent_flags::auto_managed;
}
}
m_ltAddTorrentParams.added_time = addedTime().toSecsSinceEpoch(); m_ltAddTorrentParams.added_time = addedTime().toSecsSinceEpoch();
m_ltAddTorrentParams.save_path = Profile::instance()->toPortablePath( m_ltAddTorrentParams.save_path = Profile::instance()->toPortablePath(
@ -1476,6 +1453,8 @@ void TorrentHandleImpl::handleSaveResumeDataAlert(const lt::save_resume_data_ale
// === BEGIN DEPRECATED CODE === // // === BEGIN DEPRECATED CODE === //
const bool useDummyResumeData = !p; const bool useDummyResumeData = !p;
if (useDummyResumeData) { if (useDummyResumeData) {
updateStatus();
resumeData["qBt-magnetUri"] = createMagnetURI().toStdString(); resumeData["qBt-magnetUri"] = createMagnetURI().toStdString();
// sequentialDownload needs to be stored in the // sequentialDownload needs to be stored in the
// resume data if there is no metadata, otherwise they won't be // resume data if there is no metadata, otherwise they won't be
@ -1516,7 +1495,7 @@ void TorrentHandleImpl::handleFastResumeRejectedAlert(const lt::fastresume_rejec
if (p->error.value() == lt::errors::mismatching_file_size) { if (p->error.value() == lt::errors::mismatching_file_size) {
// Mismatching file size (files were probably moved) // Mismatching file size (files were probably moved)
m_hasMissingFiles = true; m_hasMissingFiles = true;
LogMsg(tr("File sizes mismatch for torrent '%1', pausing it.").arg(name()), Log::CRITICAL); LogMsg(tr("File sizes mismatch for torrent '%1'. Cannot proceed further.").arg(name()), Log::CRITICAL);
} }
else { else {
LogMsg(tr("Fast resume data was rejected for torrent '%1'. Reason: %2. Checking again...") LogMsg(tr("Fast resume data was rejected for torrent '%1'. Reason: %2. Checking again...")
@ -1619,13 +1598,6 @@ void TorrentHandleImpl::handleMetadataReceivedAlert(const lt::metadata_received_
m_hasRootFolder = false; m_hasRootFolder = false;
m_session->handleTorrentMetadataReceived(this); m_session->handleTorrentMetadataReceived(this);
if (isPaused()) {
// XXX: Unfortunately libtorrent-rasterbar does not send a torrent_paused_alert
// and the torrent can be paused when metadata is received
m_speedMonitor.reset();
m_session->handleTorrentPaused(this);
}
// If first/last piece priority was specified when adding this torrent, // If first/last piece priority was specified when adding this torrent,
// we should apply it now that we have metadata: // we should apply it now that we have metadata:
if (m_hasFirstLastPiecePriority) if (m_hasFirstLastPiecePriority)

9
src/base/bittorrent/torrenthandleimpl.h

@ -101,7 +101,6 @@ namespace BitTorrent
qlonglong totalSize() const override; qlonglong totalSize() const override;
qlonglong wantedSize() const override; qlonglong wantedSize() const override;
qlonglong completedSize() const override; qlonglong completedSize() const override;
qlonglong incompletedSize() const override;
qlonglong pieceLength() const override; qlonglong pieceLength() const override;
qlonglong wastedSize() const override; qlonglong wastedSize() const override;
QString currentTracker() const override; QString currentTracker() const override;
@ -143,7 +142,6 @@ namespace BitTorrent
TorrentInfo info() const override; TorrentInfo info() const override;
bool isSeed() const override; bool isSeed() const override;
bool isPaused() const override; bool isPaused() const override;
bool isResumed() const override;
bool isQueued() const override; bool isQueued() const override;
bool isForced() const override; bool isForced() const override;
bool isChecking() const override; bool isChecking() const override;
@ -209,7 +207,7 @@ namespace BitTorrent
void setSequentialDownload(bool enable) override; void setSequentialDownload(bool enable) override;
void setFirstLastPiecePriority(bool enabled) override; void setFirstLastPiecePriority(bool enabled) override;
void pause() override; void pause() override;
void resume(bool forced = false) override; void resume(TorrentOperatingMode mode = TorrentOperatingMode::AutoManaged) override;
void move(QString path) override; void move(QString path) override;
void forceReannounce(int index = -1) override; void forceReannounce(int index = -1) override;
void forceDHTAnnounce() override; void forceDHTAnnounce() override;
@ -270,9 +268,8 @@ namespace BitTorrent
void handleTrackerReplyAlert(const lt::tracker_reply_alert *p); void handleTrackerReplyAlert(const lt::tracker_reply_alert *p);
void handleTrackerWarningAlert(const lt::tracker_warning_alert *p); void handleTrackerWarningAlert(const lt::tracker_warning_alert *p);
void resume_impl(bool forced);
bool isMoveInProgress() const; bool isMoveInProgress() const;
bool isAutoManaged() const;
void setAutoManaged(bool enable); void setAutoManaged(bool enable);
void adjustActualSavePath(); void adjustActualSavePath();
@ -310,12 +307,14 @@ namespace BitTorrent
QSet<QString> m_tags; QSet<QString> m_tags;
qreal m_ratioLimit; qreal m_ratioLimit;
int m_seedingTimeLimit; int m_seedingTimeLimit;
TorrentOperatingMode m_operatingMode;
bool m_hasSeedStatus; bool m_hasSeedStatus;
bool m_fastresumeDataRejected = false; bool m_fastresumeDataRejected = false;
bool m_hasMissingFiles = false; bool m_hasMissingFiles = false;
bool m_hasRootFolder; bool m_hasRootFolder;
bool m_hasFirstLastPiecePriority = false; bool m_hasFirstLastPiecePriority = false;
bool m_useAutoTMM; bool m_useAutoTMM;
bool m_isStopped;
bool m_unchecked = false; bool m_unchecked = false;

4
src/gui/transferlistmodel.cpp

@ -374,7 +374,7 @@ QString TransferListModel::displayValue(const BitTorrent::TorrentHandle *torrent
case TR_AMOUNT_UPLOADED_SESSION: case TR_AMOUNT_UPLOADED_SESSION:
return unitString(torrent->totalPayloadUpload()); return unitString(torrent->totalPayloadUpload());
case TR_AMOUNT_LEFT: case TR_AMOUNT_LEFT:
return unitString(torrent->incompletedSize()); return unitString(torrent->remainingSize());
case TR_TIME_ELAPSED: case TR_TIME_ELAPSED:
return timeElapsedString(torrent->activeTime(), torrent->seedingTime()); return timeElapsedString(torrent->activeTime(), torrent->seedingTime());
case TR_SAVE_PATH: case TR_SAVE_PATH:
@ -442,7 +442,7 @@ QVariant TransferListModel::internalValue(const BitTorrent::TorrentHandle *torre
case TR_AMOUNT_UPLOADED_SESSION: case TR_AMOUNT_UPLOADED_SESSION:
return torrent->totalPayloadUpload(); return torrent->totalPayloadUpload();
case TR_AMOUNT_LEFT: case TR_AMOUNT_LEFT:
return torrent->incompletedSize(); return torrent->remainingSize();
case TR_TIME_ELAPSED: case TR_TIME_ELAPSED:
return !alt ? torrent->activeTime() : torrent->seedingTime(); return !alt ? torrent->activeTime() : torrent->seedingTime();
case TR_SAVE_PATH: case TR_SAVE_PATH:

12
src/gui/transferlistwidget.cpp

@ -357,7 +357,7 @@ void TransferListWidget::startSelectedTorrents()
void TransferListWidget::forceStartSelectedTorrents() void TransferListWidget::forceStartSelectedTorrents()
{ {
for (BitTorrent::TorrentHandle *const torrent : asConst(getSelectedTorrents())) for (BitTorrent::TorrentHandle *const torrent : asConst(getSelectedTorrents()))
torrent->resume(true); torrent->resume(BitTorrent::TorrentOperatingMode::Forced);
} }
void TransferListWidget::startVisibleTorrents() void TransferListWidget::startVisibleTorrents()
@ -965,14 +965,24 @@ void TransferListWidget::displayListMenu(const QPoint &)
allSameSuperSeeding = false; allSameSuperSeeding = false;
} }
} }
if (!torrent->isForced()) if (!torrent->isForced())
needsForce = true; needsForce = true;
else else
needsStart = true; needsStart = true;
if (torrent->isPaused()) if (torrent->isPaused())
needsStart = true; needsStart = true;
else else
needsPause = true; needsPause = true;
if (torrent->isErrored() || torrent->hasMissingFiles()) {
// If torrent is in "errored" or "missing files" state
// it cannot keep further processing until you restart it.
needsStart = true;
needsForce = true;
}
if (torrent->hasMetadata()) if (torrent->hasMetadata())
needsPreview = true; needsPreview = true;

2
src/webui/api/serialize/serialize_torrent.cpp

@ -119,7 +119,7 @@ QVariantMap serialize(const BitTorrent::TorrentHandle &torrent)
{KEY_TORRENT_AMOUNT_UPLOADED, torrent.totalUpload()}, {KEY_TORRENT_AMOUNT_UPLOADED, torrent.totalUpload()},
{KEY_TORRENT_AMOUNT_DOWNLOADED_SESSION, torrent.totalPayloadDownload()}, {KEY_TORRENT_AMOUNT_DOWNLOADED_SESSION, torrent.totalPayloadDownload()},
{KEY_TORRENT_AMOUNT_UPLOADED_SESSION, torrent.totalPayloadUpload()}, {KEY_TORRENT_AMOUNT_UPLOADED_SESSION, torrent.totalPayloadUpload()},
{KEY_TORRENT_AMOUNT_LEFT, torrent.incompletedSize()}, {KEY_TORRENT_AMOUNT_LEFT, torrent.remainingSize()},
{KEY_TORRENT_AMOUNT_COMPLETED, torrent.completedSize()}, {KEY_TORRENT_AMOUNT_COMPLETED, torrent.completedSize()},
{KEY_TORRENT_MAX_RATIO, torrent.maxRatio()}, {KEY_TORRENT_MAX_RATIO, torrent.maxRatio()},
{KEY_TORRENT_MAX_SEEDING_TIME, torrent.maxSeedingTime()}, {KEY_TORRENT_MAX_SEEDING_TIME, torrent.maxSeedingTime()},

5
src/webui/api/torrentscontroller.cpp

@ -888,7 +888,10 @@ void TorrentsController::setForceStartAction()
const bool value {parseBool(params()["value"], false)}; const bool value {parseBool(params()["value"], false)};
const QStringList hashes {params()["hashes"].split('|')}; const QStringList hashes {params()["hashes"].split('|')};
applyToTorrents(hashes, [value](BitTorrent::TorrentHandle *const torrent) { torrent->resume(value); }); applyToTorrents(hashes, [value](BitTorrent::TorrentHandle *const torrent)
{
torrent->resume(value ? BitTorrent::TorrentOperatingMode::Forced : BitTorrent::TorrentOperatingMode::AutoManaged);
});
} }
void TorrentsController::deleteAction() void TorrentsController::deleteAction()

Loading…
Cancel
Save