mirror of
https://github.com/qbittorrent/qBittorrent.git
synced 2024-11-28 13:28:50 +03:00
Merge pull request #13123 from glassez/handle-paused
Handle torrent "paused" state at application level
This commit is contained in:
commit
61770ad69e
10 changed files with 157 additions and 146 deletions
|
@ -2253,15 +2253,13 @@ void Session::exportTorrentFile(const TorrentHandle *torrent, TorrentExportFolde
|
|||
}
|
||||
}
|
||||
|
||||
void Session::generateResumeData(const bool final)
|
||||
void Session::generateResumeData()
|
||||
{
|
||||
for (TorrentHandleImpl *const torrent : asConst(m_torrents)) {
|
||||
if (!torrent->isValid()) continue;
|
||||
|
||||
if (!final && !torrent->needSaveResumeData()) continue;
|
||||
if (torrent->isPaused()) continue;
|
||||
|
||||
torrent->saveResumeData();
|
||||
if (torrent->needSaveResumeData())
|
||||
torrent->saveResumeData();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2273,10 +2271,10 @@ void Session::saveResumeData()
|
|||
|
||||
if (isQueueingSystemEnabled())
|
||||
saveTorrentsQueue();
|
||||
generateResumeData(true);
|
||||
generateResumeData();
|
||||
|
||||
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()) {
|
||||
LogMsg(tr("Error: Aborted saving resume data for %1 outstanding torrents.").arg(QString::number(m_numResumeData))
|
||||
, Log::CRITICAL);
|
||||
|
@ -3736,8 +3734,7 @@ void Session::handleTorrentMetadataReceived(TorrentHandleImpl *const torrent)
|
|||
|
||||
void Session::handleTorrentPaused(TorrentHandleImpl *const torrent)
|
||||
{
|
||||
if (!torrent->hasError() && !torrent->hasMissingFiles())
|
||||
torrent->saveResumeData();
|
||||
torrent->saveResumeData();
|
||||
emit torrentPaused(torrent);
|
||||
}
|
||||
|
||||
|
@ -4069,6 +4066,19 @@ bool Session::loadTorrentResumeData(const QByteArray &data, const TorrentInfo &m
|
|||
if (metadata.isValid())
|
||||
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());
|
||||
if (!hasMetadata && !root.dict_find("info-hash")) {
|
||||
// TODO: The following code is deprecated. Remove after several releases in 4.3.x.
|
||||
|
|
|
@ -533,7 +533,7 @@ namespace BitTorrent
|
|||
void readAlerts();
|
||||
void enqueueRefresh();
|
||||
void processShareLimits();
|
||||
void generateResumeData(bool final = false);
|
||||
void generateResumeData();
|
||||
void handleIPFilterParsed(int ruleCount);
|
||||
void handleIPFilterError();
|
||||
void handleDownloadFinished(const Net::DownloadResult &result);
|
||||
|
|
|
@ -49,6 +49,16 @@ namespace BitTorrent
|
|||
const qreal TorrentHandle::MAX_RATIO = 9999.;
|
||||
const int TorrentHandle::MAX_SEEDING_TIME = 525600;
|
||||
|
||||
bool TorrentHandle::isResumed() const
|
||||
{
|
||||
return !isPaused();
|
||||
}
|
||||
|
||||
qlonglong TorrentHandle::remainingSize() const
|
||||
{
|
||||
return wantedSize() - completedSize();
|
||||
}
|
||||
|
||||
void TorrentHandle::toggleSequentialDownload()
|
||||
{
|
||||
setSequentialDownload(!isSequentialDownload());
|
||||
|
|
|
@ -49,6 +49,12 @@ namespace BitTorrent
|
|||
class TrackerEntry;
|
||||
struct PeerAddress;
|
||||
|
||||
enum class TorrentOperatingMode
|
||||
{
|
||||
AutoManaged = 0,
|
||||
Forced = 1
|
||||
};
|
||||
|
||||
enum class TorrentState
|
||||
{
|
||||
Unknown = -1,
|
||||
|
@ -110,7 +116,6 @@ namespace BitTorrent
|
|||
virtual qlonglong totalSize() const = 0;
|
||||
virtual qlonglong wantedSize() const = 0;
|
||||
virtual qlonglong completedSize() const = 0;
|
||||
virtual qlonglong incompletedSize() const = 0;
|
||||
virtual qlonglong pieceLength() const = 0;
|
||||
virtual qlonglong wastedSize() const = 0;
|
||||
virtual QString currentTracker() const = 0;
|
||||
|
@ -195,7 +200,6 @@ namespace BitTorrent
|
|||
virtual TorrentInfo info() const = 0;
|
||||
virtual bool isSeed() const = 0;
|
||||
virtual bool isPaused() const = 0;
|
||||
virtual bool isResumed() const = 0;
|
||||
virtual bool isQueued() const = 0;
|
||||
virtual bool isForced() const = 0;
|
||||
virtual bool isChecking() const = 0;
|
||||
|
@ -267,7 +271,7 @@ namespace BitTorrent
|
|||
virtual void setSequentialDownload(bool enable) = 0;
|
||||
virtual void setFirstLastPiecePriority(bool enabled) = 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 forceReannounce(int index = -1) = 0;
|
||||
virtual void forceDHTAnnounce() = 0;
|
||||
|
@ -289,6 +293,9 @@ namespace BitTorrent
|
|||
|
||||
virtual QString createMagnetURI() const = 0;
|
||||
|
||||
bool isResumed() const;
|
||||
qlonglong remainingSize() const;
|
||||
|
||||
void toggleSequentialDownload();
|
||||
void toggleFirstLastPiecePriority();
|
||||
};
|
||||
|
|
|
@ -112,10 +112,12 @@ TorrentHandleImpl::TorrentHandleImpl(Session *session, const lt::torrent_handle
|
|||
, m_tags(params.tags)
|
||||
, m_ratioLimit(params.ratioLimit)
|
||||
, m_seedingTimeLimit(params.seedingTimeLimit)
|
||||
, m_operatingMode(params.forced ? TorrentOperatingMode::Forced : TorrentOperatingMode::AutoManaged)
|
||||
, m_hasSeedStatus(params.hasSeedStatus)
|
||||
, m_hasRootFolder(params.hasRootFolder)
|
||||
, m_hasFirstLastPiecePriority(params.firstLastPiecePriority)
|
||||
, m_useAutoTMM(params.savePath.isEmpty())
|
||||
, m_isStopped(params.paused)
|
||||
, m_ltAddTorrentParams(params.ltAddTorrentParams)
|
||||
{
|
||||
if (m_useAutoTMM)
|
||||
|
@ -220,11 +222,6 @@ qlonglong TorrentHandleImpl::completedSize() const
|
|||
return m_nativeStatus.total_wanted_done;
|
||||
}
|
||||
|
||||
qlonglong TorrentHandleImpl::incompletedSize() const
|
||||
{
|
||||
return (m_nativeStatus.total_wanted - m_nativeStatus.total_wanted_done);
|
||||
}
|
||||
|
||||
qlonglong TorrentHandleImpl::pieceLength() const
|
||||
{
|
||||
return m_torrentInfo.pieceLength();
|
||||
|
@ -298,11 +295,6 @@ QString TorrentHandleImpl::actualStorageLocation() const
|
|||
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)
|
||||
{
|
||||
if (enable)
|
||||
|
@ -466,7 +458,9 @@ bool TorrentHandleImpl::connectPeer(const PeerAddress &peerAddress)
|
|||
|
||||
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()
|
||||
|
@ -492,19 +486,18 @@ int TorrentHandleImpl::piecesHave() const
|
|||
|
||||
qreal TorrentHandleImpl::progress() const
|
||||
{
|
||||
if (!isChecking()) {
|
||||
if (!m_nativeStatus.total_wanted)
|
||||
return 0.;
|
||||
if (isChecking())
|
||||
return m_nativeStatus.progress;
|
||||
|
||||
if (m_nativeStatus.total_wanted_done == m_nativeStatus.total_wanted)
|
||||
return 1.;
|
||||
if (m_nativeStatus.total_wanted == 0)
|
||||
return 0.;
|
||||
|
||||
const qreal progress = static_cast<qreal>(m_nativeStatus.total_wanted_done) / m_nativeStatus.total_wanted;
|
||||
Q_ASSERT((progress >= 0.f) && (progress <= 1.f));
|
||||
return progress;
|
||||
}
|
||||
if (m_nativeStatus.total_wanted_done == m_nativeStatus.total_wanted)
|
||||
return 1.;
|
||||
|
||||
return m_nativeStatus.progress;
|
||||
const qreal progress = static_cast<qreal>(m_nativeStatus.total_wanted_done) / m_nativeStatus.total_wanted;
|
||||
Q_ASSERT((progress >= 0.f) && (progress <= 1.f));
|
||||
return progress;
|
||||
}
|
||||
|
||||
QString TorrentHandleImpl::category() const
|
||||
|
@ -629,19 +622,13 @@ TorrentInfo TorrentHandleImpl::info() const
|
|||
|
||||
bool TorrentHandleImpl::isPaused() const
|
||||
{
|
||||
return ((m_nativeStatus.flags & lt::torrent_flags::paused)
|
||||
&& !isAutoManaged());
|
||||
}
|
||||
|
||||
bool TorrentHandleImpl::isResumed() const
|
||||
{
|
||||
return !isPaused();
|
||||
return m_isStopped;
|
||||
}
|
||||
|
||||
bool TorrentHandleImpl::isQueued() const
|
||||
{
|
||||
return ((m_nativeStatus.flags & lt::torrent_flags::paused)
|
||||
&& isAutoManaged());
|
||||
// Torrent is Queued if it isn't in Paused state but paused internally
|
||||
return ((m_nativeStatus.flags & lt::torrent_flags::paused) && !isPaused());
|
||||
}
|
||||
|
||||
bool TorrentHandleImpl::isChecking() const
|
||||
|
@ -706,21 +693,13 @@ bool TorrentHandleImpl::isErrored() 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)
|
||||
|| (m_nativeStatus.state == lt::torrent_status::seeding));
|
||||
}
|
||||
|
||||
bool TorrentHandleImpl::isForced() const
|
||||
{
|
||||
return (!(m_nativeStatus.flags & lt::torrent_flags::paused)
|
||||
&& !isAutoManaged());
|
||||
return (!isPaused() && (m_operatingMode == TorrentOperatingMode::Forced));
|
||||
}
|
||||
|
||||
bool TorrentHandleImpl::isSequentialDownload() const
|
||||
|
@ -743,62 +722,49 @@ void TorrentHandleImpl::updateState()
|
|||
if (m_nativeStatus.state == lt::torrent_status::checking_resume_data) {
|
||||
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::allocating) {
|
||||
m_state = TorrentState::Allocating;
|
||||
}
|
||||
else if (isMoveInProgress()) {
|
||||
m_state = TorrentState::Moving;
|
||||
}
|
||||
else if (hasMissingFiles()) {
|
||||
m_state = TorrentState::MissingFiles;
|
||||
}
|
||||
else if (hasError()) {
|
||||
m_state = TorrentState::Error;
|
||||
}
|
||||
else if ((m_nativeStatus.state == lt::torrent_status::checking_files)
|
||||
&& (!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 if (isSeed()) {
|
||||
if (isPaused())
|
||||
m_state = TorrentState::PausedUploading;
|
||||
else if (m_session->isQueueingSystemEnabled() && isQueued())
|
||||
m_state = TorrentState::QueuedUploading;
|
||||
else if (isForced())
|
||||
m_state = TorrentState::ForcedUploading;
|
||||
else if (m_nativeStatus.upload_payload_rate > 0)
|
||||
m_state = TorrentState::Uploading;
|
||||
else
|
||||
m_state = TorrentState::StalledUploading;
|
||||
}
|
||||
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) {
|
||||
m_state = TorrentState::Allocating;
|
||||
}
|
||||
else if (isMoveInProgress()) {
|
||||
m_state = TorrentState::Moving;
|
||||
}
|
||||
else if (hasMissingFiles()) {
|
||||
m_state = TorrentState::MissingFiles;
|
||||
}
|
||||
else if (hasError()) {
|
||||
m_state = TorrentState::Error;
|
||||
}
|
||||
else if (m_session->isQueueingSystemEnabled() && isQueued() && !isChecking()) {
|
||||
m_state = isSeed() ? TorrentState::QueuedUploading : TorrentState::QueuedDownloading;
|
||||
}
|
||||
else {
|
||||
switch (m_nativeStatus.state) {
|
||||
case lt::torrent_status::finished:
|
||||
case lt::torrent_status::seeding:
|
||||
if (isForced())
|
||||
m_state = TorrentState::ForcedUploading;
|
||||
else
|
||||
m_state = m_nativeStatus.upload_payload_rate > 0 ? TorrentState::Uploading : TorrentState::StalledUploading;
|
||||
break;
|
||||
case lt::torrent_status::downloading_metadata:
|
||||
m_state = TorrentState::DownloadingMetadata;
|
||||
break;
|
||||
case lt::torrent_status::downloading:
|
||||
if (isForced())
|
||||
m_state = TorrentState::ForcedDownloading;
|
||||
else
|
||||
m_state = m_nativeStatus.download_payload_rate > 0 ? TorrentState::Downloading : TorrentState::StalledDownloading;
|
||||
break;
|
||||
default:
|
||||
qWarning("Unrecognized torrent status, should not happen!!! status was %d", m_nativeStatus.state);
|
||||
m_state = TorrentState::Unknown;
|
||||
}
|
||||
}
|
||||
if (isPaused())
|
||||
m_state = TorrentState::PausedDownloading;
|
||||
else if (m_nativeStatus.state == lt::torrent_status::downloading_metadata)
|
||||
m_state = TorrentState::DownloadingMetadata;
|
||||
else if (m_session->isQueueingSystemEnabled() && isQueued())
|
||||
m_state = TorrentState::QueuedDownloading;
|
||||
else if (isForced())
|
||||
m_state = TorrentState::ForcedDownloading;
|
||||
else if (m_nativeStatus.download_payload_rate > 0)
|
||||
m_state = TorrentState::Downloading;
|
||||
else
|
||||
m_state = TorrentState::StalledDownloading;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1206,6 +1172,7 @@ void TorrentHandleImpl::forceRecheck()
|
|||
if (!hasMetadata()) return;
|
||||
|
||||
m_nativeHandle.force_recheck();
|
||||
m_hasMissingFiles = false;
|
||||
m_unchecked = false;
|
||||
|
||||
if (isPaused()) {
|
||||
|
@ -1278,24 +1245,18 @@ void TorrentHandleImpl::applyFirstLastPiecePriority(const bool enabled, const QV
|
|||
|
||||
void TorrentHandleImpl::pause()
|
||||
{
|
||||
if (isPaused()) return;
|
||||
|
||||
setAutoManaged(false);
|
||||
m_nativeHandle.pause();
|
||||
|
||||
// Libtorrent doesn't emit a torrent_paused_alert when the
|
||||
// torrent is queued (no I/O)
|
||||
// We test on the cached m_nativeStatus
|
||||
if (isQueued())
|
||||
m_speedMonitor.reset();
|
||||
|
||||
if (!m_isStopped) {
|
||||
m_isStopped = true;
|
||||
m_session->handleTorrentPaused(this);
|
||||
}
|
||||
}
|
||||
|
||||
void TorrentHandleImpl::resume(bool forced)
|
||||
{
|
||||
resume_impl(forced);
|
||||
}
|
||||
|
||||
void TorrentHandleImpl::resume_impl(bool forced)
|
||||
void TorrentHandleImpl::resume(const TorrentOperatingMode mode)
|
||||
{
|
||||
if (hasError())
|
||||
m_nativeHandle.clear_error();
|
||||
|
@ -1305,9 +1266,22 @@ void TorrentHandleImpl::resume_impl(bool forced)
|
|||
m_nativeHandle.force_recheck();
|
||||
}
|
||||
|
||||
setAutoManaged(!forced);
|
||||
if (forced)
|
||||
if (m_isStopped) {
|
||||
// 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_operatingMode = mode;
|
||||
|
||||
if (m_isStopped) {
|
||||
m_isStopped = false;
|
||||
m_session->handleTorrentResumed(this);
|
||||
}
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
Q_UNUSED(p);
|
||||
|
||||
updateStatus();
|
||||
m_speedMonitor.reset();
|
||||
|
||||
m_session->handleTorrentPaused(this);
|
||||
}
|
||||
|
||||
void TorrentHandleImpl::handleTorrentResumedAlert(const lt::torrent_resumed_alert *p)
|
||||
{
|
||||
Q_UNUSED(p);
|
||||
|
||||
m_session->handleTorrentResumed(this);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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.save_path = Profile::instance()->toPortablePath(
|
||||
|
@ -1476,6 +1453,8 @@ void TorrentHandleImpl::handleSaveResumeDataAlert(const lt::save_resume_data_ale
|
|||
// === BEGIN DEPRECATED CODE === //
|
||||
const bool useDummyResumeData = !p;
|
||||
if (useDummyResumeData) {
|
||||
updateStatus();
|
||||
|
||||
resumeData["qBt-magnetUri"] = createMagnetURI().toStdString();
|
||||
// sequentialDownload needs to be stored in the
|
||||
// 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) {
|
||||
// Mismatching file size (files were probably moved)
|
||||
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 {
|
||||
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_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,
|
||||
// we should apply it now that we have metadata:
|
||||
if (m_hasFirstLastPiecePriority)
|
||||
|
|
|
@ -101,7 +101,6 @@ namespace BitTorrent
|
|||
qlonglong totalSize() const override;
|
||||
qlonglong wantedSize() const override;
|
||||
qlonglong completedSize() const override;
|
||||
qlonglong incompletedSize() const override;
|
||||
qlonglong pieceLength() const override;
|
||||
qlonglong wastedSize() const override;
|
||||
QString currentTracker() const override;
|
||||
|
@ -143,7 +142,6 @@ namespace BitTorrent
|
|||
TorrentInfo info() const override;
|
||||
bool isSeed() const override;
|
||||
bool isPaused() const override;
|
||||
bool isResumed() const override;
|
||||
bool isQueued() const override;
|
||||
bool isForced() const override;
|
||||
bool isChecking() const override;
|
||||
|
@ -209,7 +207,7 @@ namespace BitTorrent
|
|||
void setSequentialDownload(bool enable) override;
|
||||
void setFirstLastPiecePriority(bool enabled) override;
|
||||
void pause() override;
|
||||
void resume(bool forced = false) override;
|
||||
void resume(TorrentOperatingMode mode = TorrentOperatingMode::AutoManaged) override;
|
||||
void move(QString path) override;
|
||||
void forceReannounce(int index = -1) override;
|
||||
void forceDHTAnnounce() override;
|
||||
|
@ -270,9 +268,8 @@ namespace BitTorrent
|
|||
void handleTrackerReplyAlert(const lt::tracker_reply_alert *p);
|
||||
void handleTrackerWarningAlert(const lt::tracker_warning_alert *p);
|
||||
|
||||
void resume_impl(bool forced);
|
||||
bool isMoveInProgress() const;
|
||||
bool isAutoManaged() const;
|
||||
|
||||
void setAutoManaged(bool enable);
|
||||
|
||||
void adjustActualSavePath();
|
||||
|
@ -310,12 +307,14 @@ namespace BitTorrent
|
|||
QSet<QString> m_tags;
|
||||
qreal m_ratioLimit;
|
||||
int m_seedingTimeLimit;
|
||||
TorrentOperatingMode m_operatingMode;
|
||||
bool m_hasSeedStatus;
|
||||
bool m_fastresumeDataRejected = false;
|
||||
bool m_hasMissingFiles = false;
|
||||
bool m_hasRootFolder;
|
||||
bool m_hasFirstLastPiecePriority = false;
|
||||
bool m_useAutoTMM;
|
||||
bool m_isStopped;
|
||||
|
||||
bool m_unchecked = false;
|
||||
|
||||
|
|
|
@ -374,7 +374,7 @@ QString TransferListModel::displayValue(const BitTorrent::TorrentHandle *torrent
|
|||
case TR_AMOUNT_UPLOADED_SESSION:
|
||||
return unitString(torrent->totalPayloadUpload());
|
||||
case TR_AMOUNT_LEFT:
|
||||
return unitString(torrent->incompletedSize());
|
||||
return unitString(torrent->remainingSize());
|
||||
case TR_TIME_ELAPSED:
|
||||
return timeElapsedString(torrent->activeTime(), torrent->seedingTime());
|
||||
case TR_SAVE_PATH:
|
||||
|
@ -442,7 +442,7 @@ QVariant TransferListModel::internalValue(const BitTorrent::TorrentHandle *torre
|
|||
case TR_AMOUNT_UPLOADED_SESSION:
|
||||
return torrent->totalPayloadUpload();
|
||||
case TR_AMOUNT_LEFT:
|
||||
return torrent->incompletedSize();
|
||||
return torrent->remainingSize();
|
||||
case TR_TIME_ELAPSED:
|
||||
return !alt ? torrent->activeTime() : torrent->seedingTime();
|
||||
case TR_SAVE_PATH:
|
||||
|
|
|
@ -357,7 +357,7 @@ void TransferListWidget::startSelectedTorrents()
|
|||
void TransferListWidget::forceStartSelectedTorrents()
|
||||
{
|
||||
for (BitTorrent::TorrentHandle *const torrent : asConst(getSelectedTorrents()))
|
||||
torrent->resume(true);
|
||||
torrent->resume(BitTorrent::TorrentOperatingMode::Forced);
|
||||
}
|
||||
|
||||
void TransferListWidget::startVisibleTorrents()
|
||||
|
@ -965,14 +965,24 @@ void TransferListWidget::displayListMenu(const QPoint &)
|
|||
allSameSuperSeeding = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (!torrent->isForced())
|
||||
needsForce = true;
|
||||
else
|
||||
needsStart = true;
|
||||
|
||||
if (torrent->isPaused())
|
||||
needsStart = true;
|
||||
else
|
||||
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())
|
||||
needsPreview = true;
|
||||
|
||||
|
|
|
@ -119,7 +119,7 @@ QVariantMap serialize(const BitTorrent::TorrentHandle &torrent)
|
|||
{KEY_TORRENT_AMOUNT_UPLOADED, torrent.totalUpload()},
|
||||
{KEY_TORRENT_AMOUNT_DOWNLOADED_SESSION, torrent.totalPayloadDownload()},
|
||||
{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_MAX_RATIO, torrent.maxRatio()},
|
||||
{KEY_TORRENT_MAX_SEEDING_TIME, torrent.maxSeedingTime()},
|
||||
|
|
|
@ -888,7 +888,10 @@ void TorrentsController::setForceStartAction()
|
|||
|
||||
const bool value {parseBool(params()["value"], false)};
|
||||
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()
|
||||
|
|
Loading…
Reference in a new issue