@ -126,6 +126,7 @@ TorrentHandleImpl::TorrentHandleImpl(Session *session, const lt::torrent_handle
, m_hasSeedStatus ( params . hasSeedStatus )
, m_hasSeedStatus ( params . hasSeedStatus )
, m_hasRootFolder ( params . hasRootFolder )
, m_hasRootFolder ( params . hasRootFolder )
, m_useAutoTMM ( params . savePath . isEmpty ( ) )
, m_useAutoTMM ( params . savePath . isEmpty ( ) )
, m_hasFirstLastPiecePriority ( params . firstLastPiecePriority )
, m_ltAddTorrentParams ( params . ltAddTorrentParams )
, m_ltAddTorrentParams ( params . ltAddTorrentParams )
{
{
if ( m_useAutoTMM )
if ( m_useAutoTMM )
@ -134,23 +135,14 @@ TorrentHandleImpl::TorrentHandleImpl(Session *session, const lt::torrent_handle
updateStatus ( ) ;
updateStatus ( ) ;
m_hash = InfoHash ( m_nativeStatus . info_hash ) ;
m_hash = InfoHash ( m_nativeStatus . info_hash ) ;
// NB: the following two if statements are present because we don't want
if ( hasMetadata ( ) ) {
// to set either sequential download or first/last piece priority to false
applyFirstLastPiecePriority ( m_hasFirstLastPiecePriority ) ;
// if their respective flags in data are false when a torrent is being
// resumed. This is because, in that circumstance, this constructor is
if ( ! params . restored ) {
// called with those flags set to false, even if the torrent was set to
// download sequentially or have first/last piece priority enabled when
// its resume data was saved. These two settings are restored later. But
// if we set them to false now, both will erroneously not be restored.
if ( ! params . restored | | params . sequential )
setSequentialDownload ( params . sequential ) ;
if ( ! params . restored | | params . firstLastPiecePriority )
setFirstLastPiecePriority ( params . firstLastPiecePriority ) ;
if ( ! params . restored & & hasMetadata ( ) ) {
if ( filesCount ( ) = = 1 )
if ( filesCount ( ) = = 1 )
m_hasRootFolder = false ;
m_hasRootFolder = false ;
}
}
}
// TODO: Remove the following upgrade code in v.4.4
// TODO: Remove the following upgrade code in v.4.4
// == BEGIN UPGRADE CODE ==
// == BEGIN UPGRADE CODE ==
@ -749,21 +741,7 @@ bool TorrentHandleImpl::isSequentialDownload() const
bool TorrentHandleImpl : : hasFirstLastPiecePriority ( ) const
bool TorrentHandleImpl : : hasFirstLastPiecePriority ( ) const
{
{
if ( ! hasMetadata ( ) )
return m_hasFirstLastPiecePriority ;
return m_needsToSetFirstLastPiecePriority ;
const std : : vector < lt : : download_priority_t > filePriorities = nativeHandle ( ) . get_file_priorities ( ) ;
for ( int i = 0 ; i < static_cast < int > ( filePriorities . size ( ) ) ; + + i ) {
if ( filePriorities [ i ] < = lt : : download_priority_t { 0 } )
continue ;
const TorrentInfo : : PieceRange extremities = info ( ) . filePieces ( i ) ;
const lt : : download_priority_t firstPiecePrio = nativeHandle ( ) . piece_priority ( lt : : piece_index_t { extremities . first ( ) } ) ;
const lt : : download_priority_t lastPiecePrio = nativeHandle ( ) . piece_priority ( lt : : piece_index_t { extremities . last ( ) } ) ;
return ( ( firstPiecePrio = = lt : : download_priority_t { 7 } ) & & ( lastPiecePrio = = lt : : download_priority_t { 7 } ) ) ;
}
return false ;
}
}
TorrentState TorrentHandleImpl : : state ( ) const
TorrentState TorrentHandleImpl : : state ( ) const
@ -1245,17 +1223,24 @@ void TorrentHandleImpl::setSequentialDownload(const bool enable)
void TorrentHandleImpl : : setFirstLastPiecePriority ( const bool enabled )
void TorrentHandleImpl : : setFirstLastPiecePriority ( const bool enabled )
{
{
setFirstLastPiecePriorityImpl ( enabled ) ;
if ( m_hasFirstLastPiecePriority = = enabled )
return ;
m_hasFirstLastPiecePriority = enabled ;
if ( hasMetadata ( ) )
applyFirstLastPiecePriority ( enabled ) ;
LogMsg ( tr ( " Download first and last piece first: %1, torrent: '%2' " )
. arg ( ( enabled ? tr ( " On " ) : tr ( " Off " ) ) , name ( ) ) ) ;
saveResumeData ( ) ;
}
}
void TorrentHandleImpl : : setFirstLastPiecePriorityImpl ( const bool enabled , const QVector < DownloadPriority > & updatedFilePrio )
void TorrentHandleImpl : : applyFirstLastPiecePriority ( const bool enabled , const QVector < DownloadPriority > & updatedFilePrio )
{
{
// Download first and last pieces first for every file in the torrent
Q_ASSERT ( hasMetadata ( ) ) ;
if ( ! hasMetadata ( ) ) {
// Download first and last pieces first for every file in the torrent
m_needsToSetFirstLastPiecePriority = enabled ;
return ;
}
const std : : vector < lt : : download_priority_t > filePriorities = ! updatedFilePrio . isEmpty ( ) ? toLTDownloadPriorities ( updatedFilePrio )
const std : : vector < lt : : download_priority_t > filePriorities = ! updatedFilePrio . isEmpty ( ) ? toLTDownloadPriorities ( updatedFilePrio )
: nativeHandle ( ) . get_file_priorities ( ) ;
: nativeHandle ( ) . get_file_priorities ( ) ;
@ -1281,11 +1266,6 @@ void TorrentHandleImpl::setFirstLastPiecePriorityImpl(const bool enabled, const
}
}
m_nativeHandle . prioritize_pieces ( piecePriorities ) ;
m_nativeHandle . prioritize_pieces ( piecePriorities ) ;
LogMsg ( tr ( " Download first and last piece first: %1, torrent: '%2' " )
. arg ( ( enabled ? tr ( " On " ) : tr ( " Off " ) ) , name ( ) ) ) ;
saveResumeData ( ) ;
}
}
void TorrentHandleImpl : : pause ( )
void TorrentHandleImpl : : pause ( )
@ -1500,10 +1480,9 @@ void TorrentHandleImpl::handleSaveResumeDataAlert(const lt::save_resume_data_ale
const bool useDummyResumeData = ! p ;
const bool useDummyResumeData = ! p ;
if ( useDummyResumeData ) {
if ( useDummyResumeData ) {
resumeData [ " qBt-magnetUri " ] = createMagnetURI ( ) . toStdString ( ) ;
resumeData [ " qBt-magnetUri " ] = createMagnetURI ( ) . toStdString ( ) ;
// Both firstLastPiecePriority and sequential need 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
// restored if qBittorrent quits before the metadata are retrieved:
// restored if qBittorrent quits before the metadata are retrieved:
resumeData [ " qBt-firstLastPiecePriority " ] = hasFirstLastPiecePriority ( ) ;
resumeData [ " qBt-sequential " ] = isSequentialDownload ( ) ;
resumeData [ " qBt-sequential " ] = isSequentialDownload ( ) ;
resumeData [ " qBt-addedTime " ] = addedTime ( ) . toSecsSinceEpoch ( ) ;
resumeData [ " qBt-addedTime " ] = addedTime ( ) . toSecsSinceEpoch ( ) ;
@ -1518,6 +1497,7 @@ void TorrentHandleImpl::handleSaveResumeDataAlert(const lt::save_resume_data_ale
resumeData [ " qBt-name " ] = m_name . toStdString ( ) ;
resumeData [ " qBt-name " ] = m_name . toStdString ( ) ;
resumeData [ " qBt-seedStatus " ] = m_hasSeedStatus ;
resumeData [ " qBt-seedStatus " ] = m_hasSeedStatus ;
resumeData [ " qBt-hasRootFolder " ] = m_hasRootFolder ;
resumeData [ " qBt-hasRootFolder " ] = m_hasRootFolder ;
resumeData [ " qBt-firstLastPiecePriority " ] = m_hasFirstLastPiecePriority ;
m_session - > handleTorrentResumeDataReady ( this , resumeDataPtr ) ;
m_session - > handleTorrentResumeDataReady ( this , resumeDataPtr ) ;
}
}
@ -1649,12 +1629,10 @@ void TorrentHandleImpl::handleMetadataReceivedAlert(const lt::metadata_received_
m_session - > handleTorrentPaused ( this ) ;
m_session - > handleTorrentPaused ( this ) ;
}
}
// If first/last piece priority was specified when adding this torrent, we can set it
// If first/last piece priority was specified when adding this torrent,
// now that we have metadata:
// we should apply it now that we have metadata:
if ( m_needsToSetFirstLastPiecePriority ) {
if ( m_hasFirstLastPiecePriority )
setFirstLastPiecePriority ( true ) ;
applyFirstLastPiecePriority ( true ) ;
m_needsToSetFirstLastPiecePriority = false ;
}
}
}
void TorrentHandleImpl : : handlePerformanceAlert ( const lt : : performance_alert * p ) const
void TorrentHandleImpl : : handlePerformanceAlert ( const lt : : performance_alert * p ) const
@ -1898,9 +1876,6 @@ void TorrentHandleImpl::prioritizeFiles(const QVector<DownloadPriority> &priorit
if ( ! hasMetadata ( ) ) return ;
if ( ! hasMetadata ( ) ) return ;
if ( priorities . size ( ) ! = filesCount ( ) ) return ;
if ( priorities . size ( ) ! = filesCount ( ) ) return ;
// Save first/last piece first option state
const bool firstLastPieceFirst = hasFirstLastPiecePriority ( ) ;
// Reset 'm_hasSeedStatus' if needed in order to react again to
// Reset 'm_hasSeedStatus' if needed in order to react again to
// 'torrent_finished_alert' and eg show tray notifications
// 'torrent_finished_alert' and eg show tray notifications
const QVector < qreal > progress = filesProgress ( ) ;
const QVector < qreal > progress = filesProgress ( ) ;
@ -1918,8 +1893,8 @@ void TorrentHandleImpl::prioritizeFiles(const QVector<DownloadPriority> &priorit
m_nativeHandle . prioritize_files ( toLTDownloadPriorities ( priorities ) ) ;
m_nativeHandle . prioritize_files ( toLTDownloadPriorities ( priorities ) ) ;
// Restore first/last piece first option if necessary
// Restore first/last piece first option if necessary
if ( firstLastPieceFirst )
if ( m_hasFirstLastPiecePriority )
setFirstLastPiecePriorityImpl ( true , priorities ) ;
applyFirstLastPiecePriority ( true , priorities ) ;
}
}
QVector < qreal > TorrentHandleImpl : : availableFileFractions ( ) const
QVector < qreal > TorrentHandleImpl : : availableFileFractions ( ) const