@ -328,6 +328,24 @@ QVector<BitTorrent::Torrent *> TransferListWidget::getVisibleTorrents() const
return torrents ;
return torrents ;
}
}
void TransferListWidget : : setSelectedTorrentsLocation ( )
{
const QVector < BitTorrent : : Torrent * > torrents = getSelectedTorrents ( ) ;
if ( torrents . isEmpty ( ) ) return ;
const QString oldLocation = torrents [ 0 ] - > savePath ( ) ;
const QString newLocation = QFileDialog : : getExistingDirectory ( this , tr ( " Choose save path " ) , oldLocation ,
( QFileDialog : : DontConfirmOverwrite | QFileDialog : : ShowDirsOnly | QFileDialog : : HideNameFilterDetails ) ) ;
if ( newLocation . isEmpty ( ) | | ! QDir ( newLocation ) . exists ( ) ) return ;
// Actually move storage
for ( BitTorrent : : Torrent * const torrent : torrents )
{
torrent - > setAutoTMMEnabled ( false ) ;
torrent - > setSavePath ( Utils : : Fs : : expandPathAbs ( newLocation ) ) ;
}
}
void TransferListWidget : : pauseAllTorrents ( )
void TransferListWidget : : pauseAllTorrents ( )
{
{
for ( BitTorrent : : Torrent * const torrent : asConst ( BitTorrent : : Session : : instance ( ) - > torrents ( ) ) )
for ( BitTorrent : : Torrent * const torrent : asConst ( BitTorrent : : Session : : instance ( ) - > torrents ( ) ) )
@ -644,6 +662,18 @@ void TransferListWidget::setSelectedTorrentsSuperSeeding(const bool enabled) con
}
}
}
}
void TransferListWidget : : setSelectedTorrentsSequentialDownload ( const bool enabled ) const
{
for ( BitTorrent : : Torrent * const torrent : asConst ( getSelectedTorrents ( ) ) )
torrent - > setSequentialDownload ( enabled ) ;
}
void TransferListWidget : : setSelectedFirstLastPiecePrio ( const bool enabled ) const
{
for ( BitTorrent : : Torrent * const torrent : asConst ( getSelectedTorrents ( ) ) )
torrent - > setFirstLastPiecePriority ( enabled ) ;
}
void TransferListWidget : : setSelectedAutoTMMEnabled ( const bool enabled ) const
void TransferListWidget : : setSelectedAutoTMMEnabled ( const bool enabled ) const
{
{
for ( BitTorrent : : Torrent * const torrent : asConst ( getSelectedTorrents ( ) ) )
for ( BitTorrent : : Torrent * const torrent : asConst ( getSelectedTorrents ( ) ) )
@ -818,6 +848,8 @@ void TransferListWidget::displayListMenu(const QPoint &)
connect ( actionTopQueuePos , & QAction : : triggered , this , & TransferListWidget : : topQueuePosSelectedTorrents ) ;
connect ( actionTopQueuePos , & QAction : : triggered , this , & TransferListWidget : : topQueuePosSelectedTorrents ) ;
auto * actionBottomQueuePos = new QAction ( UIThemeManager : : instance ( ) - > getIcon ( " go-bottom " ) , tr ( " Move to bottom " , " i.e. Move to bottom of the queue " ) , listMenu ) ;
auto * actionBottomQueuePos = new QAction ( UIThemeManager : : instance ( ) - > getIcon ( " go-bottom " ) , tr ( " Move to bottom " , " i.e. Move to bottom of the queue " ) , listMenu ) ;
connect ( actionBottomQueuePos , & QAction : : triggered , this , & TransferListWidget : : bottomQueuePosSelectedTorrents ) ;
connect ( actionBottomQueuePos , & QAction : : triggered , this , & TransferListWidget : : bottomQueuePosSelectedTorrents ) ;
auto * actionSetTorrentPath = new QAction ( UIThemeManager : : instance ( ) - > getIcon ( " inode-directory " ) , tr ( " Set location... " ) , listMenu ) ;
connect ( actionSetTorrentPath , & QAction : : triggered , this , & TransferListWidget : : setSelectedTorrentsLocation ) ;
auto * actionForceRecheck = new QAction ( UIThemeManager : : instance ( ) - > getIcon ( " document-edit-verify " ) , tr ( " Force recheck " ) , listMenu ) ;
auto * actionForceRecheck = new QAction ( UIThemeManager : : instance ( ) - > getIcon ( " document-edit-verify " ) , tr ( " Force recheck " ) , listMenu ) ;
connect ( actionForceRecheck , & QAction : : triggered , this , & TransferListWidget : : recheckSelectedTorrents ) ;
connect ( actionForceRecheck , & QAction : : triggered , this , & TransferListWidget : : recheckSelectedTorrents ) ;
auto * actionForceReannounce = new QAction ( UIThemeManager : : instance ( ) - > getIcon ( " document-edit-verify " ) , tr ( " Force reannounce " ) , listMenu ) ;
auto * actionForceReannounce = new QAction ( UIThemeManager : : instance ( ) - > getIcon ( " document-edit-verify " ) , tr ( " Force reannounce " ) , listMenu ) ;
@ -836,6 +868,12 @@ void TransferListWidget::displayListMenu(const QPoint &)
connect ( actionSuperSeedingMode , & QAction : : triggered , this , & TransferListWidget : : setSelectedTorrentsSuperSeeding ) ;
connect ( actionSuperSeedingMode , & QAction : : triggered , this , & TransferListWidget : : setSelectedTorrentsSuperSeeding ) ;
auto * actionRename = new QAction ( UIThemeManager : : instance ( ) - > getIcon ( " edit-rename " ) , tr ( " Rename... " ) , listMenu ) ;
auto * actionRename = new QAction ( UIThemeManager : : instance ( ) - > getIcon ( " edit-rename " ) , tr ( " Rename... " ) , listMenu ) ;
connect ( actionRename , & QAction : : triggered , this , & TransferListWidget : : renameSelectedTorrent ) ;
connect ( actionRename , & QAction : : triggered , this , & TransferListWidget : : renameSelectedTorrent ) ;
auto * actionSequentialDownload = new TriStateAction ( tr ( " Download in sequential order " ) , listMenu ) ;
connect ( actionSequentialDownload , & QAction : : triggered , this , & TransferListWidget : : setSelectedTorrentsSequentialDownload ) ;
auto * actionFirstLastPiecePrio = new TriStateAction ( tr ( " Download first and last pieces first " ) , listMenu ) ;
connect ( actionFirstLastPiecePrio , & QAction : : triggered , this , & TransferListWidget : : setSelectedFirstLastPiecePrio ) ;
auto * actionAutoTMM = new TriStateAction ( tr ( " Automatic Torrent Management " ) , listMenu ) ;
connect ( actionAutoTMM , & QAction : : triggered , this , & TransferListWidget : : setSelectedAutoTMMEnabled ) ;
auto * actionEditTracker = new QAction ( UIThemeManager : : instance ( ) - > getIcon ( " edit-rename " ) , tr ( " Edit trackers... " ) , listMenu ) ;
auto * actionEditTracker = new QAction ( UIThemeManager : : instance ( ) - > getIcon ( " edit-rename " ) , tr ( " Edit trackers... " ) , listMenu ) ;
connect ( actionEditTracker , & QAction : : triggered , this , & TransferListWidget : : editTorrentTrackers ) ;
connect ( actionEditTracker , & QAction : : triggered , this , & TransferListWidget : : editTorrentTrackers ) ;
// End of actions
// End of actions
@ -848,6 +886,8 @@ void TransferListWidget::displayListMenu(const QPoint &)
bool sequentialDownloadMode = false , prioritizeFirstLast = false ;
bool sequentialDownloadMode = false , prioritizeFirstLast = false ;
bool oneHasMetadata = false , oneNotSeed = false ;
bool oneHasMetadata = false , oneNotSeed = false ;
bool allSameCategory = true ;
bool allSameCategory = true ;
bool allSameAutoTMM = true ;
bool firstAutoTMM = false ;
QString firstCategory ;
QString firstCategory ;
bool first = true ;
bool first = true ;
TagSet tagsInAny ;
TagSet tagsInAny ;
@ -871,6 +911,7 @@ void TransferListWidget::displayListMenu(const QPoint &)
if ( first )
if ( first )
{
{
firstAutoTMM = torrent - > isAutoTMMEnabled ( ) ;
tagsInAll = torrentTags ;
tagsInAll = torrentTags ;
}
}
else
else
@ -878,6 +919,9 @@ void TransferListWidget::displayListMenu(const QPoint &)
tagsInAll . intersect ( torrentTags ) ;
tagsInAll . intersect ( torrentTags ) ;
}
}
if ( firstAutoTMM ! = torrent - > isAutoTMMEnabled ( ) )
allSameAutoTMM = false ;
if ( torrent - > hasMetadata ( ) )
if ( torrent - > hasMetadata ( ) )
oneHasMetadata = true ;
oneHasMetadata = true ;
if ( ! torrent - > isSeed ( ) )
if ( ! torrent - > isSeed ( ) )
@ -937,7 +981,7 @@ void TransferListWidget::displayListMenu(const QPoint &)
if ( oneHasMetadata & & oneNotSeed & & ! allSameSequentialDownloadMode
if ( oneHasMetadata & & oneNotSeed & & ! allSameSequentialDownloadMode
& & ! allSamePrioFirstlast & & ! allSameSuperSeeding & & ! allSameCategory
& & ! allSamePrioFirstlast & & ! allSameSuperSeeding & & ! allSameCategory
& & needsStart & & needsForce & & needsPause & & needsPreview
& & needsStart & & needsForce & & needsPause & & needsPreview & & ! allSameAutoTMM
& & hasInfohashV1 & & hasInfohashV2 )
& & hasInfohashV1 & & hasInfohashV2 )
{
{
break ;
break ;
@ -953,10 +997,36 @@ void TransferListWidget::displayListMenu(const QPoint &)
listMenu - > addSeparator ( ) ;
listMenu - > addSeparator ( ) ;
listMenu - > addAction ( actionDelete ) ;
listMenu - > addAction ( actionDelete ) ;
listMenu - > addSeparator ( ) ;
listMenu - > addSeparator ( ) ;
listMenu - > addAction ( actionSetTorrentPath ) ;
if ( selectedIndexes . size ( ) = = 1 )
if ( selectedIndexes . size ( ) = = 1 )
listMenu - > addAction ( actionRename ) ;
listMenu - > addAction ( actionRename ) ;
listMenu - > addAction ( actionEditTracker ) ;
listMenu - > addAction ( actionEditTracker ) ;
// Category Menu
QStringList categories = BitTorrent : : Session : : instance ( ) - > categories ( ) ;
std : : sort ( categories . begin ( ) , categories . end ( ) , Utils : : Compare : : NaturalLessThan < Qt : : CaseInsensitive > ( ) ) ;
QMenu * categoryMenu = listMenu - > addMenu ( UIThemeManager : : instance ( ) - > getIcon ( " view-categories " ) , tr ( " Category " ) ) ;
categoryMenu - > addAction ( UIThemeManager : : instance ( ) - > getIcon ( " list-add " ) , tr ( " New... " , " New category... " )
, this , & TransferListWidget : : askNewCategoryForSelection ) ;
categoryMenu - > addAction ( UIThemeManager : : instance ( ) - > getIcon ( " edit-clear " ) , tr ( " Reset " , " Reset category " )
, this , [ this ] ( ) { setSelectionCategory ( " " ) ; } ) ;
categoryMenu - > addSeparator ( ) ;
for ( const QString & category : asConst ( categories ) )
{
const QString escapedCategory = QString ( category ) . replace ( ' & ' , " && " ) ; // avoid '&' becomes accelerator key
QAction * categoryAction = categoryMenu - > addAction ( UIThemeManager : : instance ( ) - > getIcon ( " inode-directory " ) , escapedCategory
, this , [ this , category ] ( ) { setSelectionCategory ( category ) ; } ) ;
if ( allSameCategory & & ( category = = firstCategory ) )
{
categoryAction - > setCheckable ( true ) ;
categoryAction - > setChecked ( true ) ;
}
}
// Tag Menu
// Tag Menu
QStringList tags ( BitTorrent : : Session : : instance ( ) - > tags ( ) . values ( ) ) ;
QStringList tags ( BitTorrent : : Session : : instance ( ) - > tags ( ) . values ( ) ) ;
std : : sort ( tags . begin ( ) , tags . end ( ) , Utils : : Compare : : NaturalLessThan < Qt : : CaseInsensitive > ( ) ) ;
std : : sort ( tags . begin ( ) , tags . end ( ) , Utils : : Compare : : NaturalLessThan < Qt : : CaseInsensitive > ( ) ) ;
@ -995,6 +1065,11 @@ void TransferListWidget::displayListMenu(const QPoint &)
tagsMenu - > addAction ( action ) ;
tagsMenu - > addAction ( action ) ;
}
}
actionAutoTMM - > setCheckState ( allSameAutoTMM
? ( firstAutoTMM ? Qt : : Checked : Qt : : Unchecked )
: Qt : : PartiallyChecked ) ;
listMenu - > addAction ( actionAutoTMM ) ;
listMenu - > addSeparator ( ) ;
listMenu - > addSeparator ( ) ;
listMenu - > addAction ( actionTorrentOptions ) ;
listMenu - > addAction ( actionTorrentOptions ) ;
if ( ! oneNotSeed & & oneHasMetadata )
if ( ! oneNotSeed & & oneHasMetadata )
@ -1012,6 +1087,17 @@ void TransferListWidget::displayListMenu(const QPoint &)
addedPreviewAction = true ;
addedPreviewAction = true ;
}
}
if ( oneNotSeed )
if ( oneNotSeed )
{
actionSequentialDownload - > setCheckState ( allSameSequentialDownloadMode
? ( sequentialDownloadMode ? Qt : : Checked : Qt : : Unchecked )
: Qt : : PartiallyChecked ) ;
listMenu - > addAction ( actionSequentialDownload ) ;
actionFirstLastPiecePrio - > setCheckState ( allSamePrioFirstlast
? ( prioritizeFirstLast ? Qt : : Checked : Qt : : Unchecked )
: Qt : : PartiallyChecked ) ;
listMenu - > addAction ( actionFirstLastPiecePrio ) ;
}
addedPreviewAction = true ;
addedPreviewAction = true ;
if ( addedPreviewAction )
if ( addedPreviewAction )