@ -41,7 +41,6 @@ TransferListSortModel::TransferListSortModel(QObject *parent)
: QSortFilterProxyModel { parent }
: QSortFilterProxyModel { parent }
{
{
setSortRole ( TransferListModel : : UnderlyingDataRole ) ;
setSortRole ( TransferListModel : : UnderlyingDataRole ) ;
QMetaType : : registerComparators < BitTorrent : : TorrentState > ( ) ;
}
}
void TransferListSortModel : : setStatusFilter ( TorrentFilter : : Type filter )
void TransferListSortModel : : setStatusFilter ( TorrentFilter : : Type filter )
@ -122,21 +121,21 @@ bool TransferListSortModel::lessThan_impl(const QModelIndex &left, const QModelI
return ( Utils : : String : : naturalCompare ( leftValue . toString ( ) , rightValue . toString ( ) , Qt : : CaseInsensitive ) < 0 ) ;
return ( Utils : : String : : naturalCompare ( leftValue . toString ( ) , rightValue . toString ( ) , Qt : : CaseInsensitive ) < 0 ) ;
case TransferListModel : : TR_STATUS :
case TransferListModel : : TR_STATUS :
// QSortFilterProxyModel::lessThan() uses the < operator only for specific QVariant types
{
// so our custom type is outside that list.
const auto stateL = leftValue . value < BitTorrent : : TorrentState > ( ) ;
// In this case QSortFilterProxyModel::lessThan() converts other types to QString and
const auto stateR = rightValue . value < BitTorrent : : TorrentState > ( ) ;
// sorts them.
// Thus we can't use the code in the default label.
if ( stateL ! = stateR )
if ( leftValue ! = rightValue )
return stateL < stateR ;
return leftValue < rightValue ;
return invokeLessThanForColumn ( TransferListModel : : TR_QUEUE_POSITION ) ;
return invokeLessThanForColumn ( TransferListModel : : TR_QUEUE_POSITION ) ;
}
case TransferListModel : : TR_ADD_DATE :
case TransferListModel : : TR_ADD_DATE :
case TransferListModel : : TR_SEED_DATE :
case TransferListModel : : TR_SEED_DATE :
case TransferListModel : : TR_SEEN_COMPLETE_DATE :
case TransferListModel : : TR_SEEN_COMPLETE_DATE :
{
{
const QDateTime dateL = leftValue . toDateTime ( ) ;
const auto dateL = leftValue . toDateTime ( ) ;
const QDateTime dateR = rightValue . toDateTime ( ) ;
const auto dateR = rightValue . toDateTime ( ) ;
if ( dateL . isValid ( ) & & dateR . isValid ( ) )
if ( dateL . isValid ( ) & & dateR . isValid ( ) )
{
{
@ -156,20 +155,21 @@ bool TransferListSortModel::lessThan_impl(const QModelIndex &left, const QModelI
}
}
case TransferListModel : : TR_QUEUE_POSITION :
case TransferListModel : : TR_QUEUE_POSITION :
{
{
// QVariant has comparators for all basic types
const auto positionL = leftValue . toInt ( ) ;
if ( ( leftValue > 0 ) | | ( rightValue > 0 ) )
const auto positionR = rightValue . toInt ( ) ;
{
if ( ( leftValue > 0 ) & & ( rightValue > 0 ) )
return leftValue < rightValue ;
return leftValue ! = 0 ;
if ( ( positionL > 0 ) | | ( positionR > 0 ) )
{
if ( ( positionL > 0 ) & & ( positionR > 0 ) )
return positionL < positionR ;
return positionL ! = 0 ;
}
}
// Sort according to TR_SEED_DATE
// Sort according to TR_SEED_DATE
const QDateTime dateL = left . sibling ( left . row ( ) , TransferListModel : : TR_SEED_DATE )
const auto dateL = left . sibling ( left . row ( ) , TransferListModel : : TR_SEED_DATE )
. data ( TransferListModel : : UnderlyingDataRole ) . toDateTime ( ) ;
. data ( TransferListModel : : UnderlyingDataRole ) . toDateTime ( ) ;
const QDateTime dateR = right . sibling ( right . row ( ) , TransferListModel : : TR_SEED_DATE )
const auto dateR = right . sibling ( right . row ( ) , TransferListModel : : TR_SEED_DATE )
. data ( TransferListModel : : UnderlyingDataRole ) . toDateTime ( ) ;
. data ( TransferListModel : : UnderlyingDataRole ) . toDateTime ( ) ;
if ( dateL . isValid ( ) & & dateR . isValid ( ) )
if ( dateL . isValid ( ) & & dateR . isValid ( ) )
@ -191,22 +191,23 @@ bool TransferListSortModel::lessThan_impl(const QModelIndex &left, const QModelI
case TransferListModel : : TR_SEEDS :
case TransferListModel : : TR_SEEDS :
case TransferListModel : : TR_PEERS :
case TransferListModel : : TR_PEERS :
{
{
// QVariant has comparators for all basic types
// Active peers/seeds take precedence over total peers/seeds
// Active peers/seeds take precedence over total peers/seeds.
const auto activeL = leftValue . toInt ( ) ;
if ( leftValue ! = rightValue )
const auto activeR = rightValue . toInt ( ) ;
return ( leftValue < rightValue ) ;
if ( activeL ! = activeR )
return activeL < activeR ;
const QVariant leftValueTotal = left . data ( TransferListModel : : AdditionalUnderlyingDataRole ) ;
const QVariant rightValueTotal = right . data ( TransferListModel : : AdditionalUnderlyingDataRole ) ;
const auto totalL = left . data ( TransferListModel : : AdditionalUnderlyingDataRole ) . toInt ( ) ;
if ( leftValueTotal ! = rightValueTotal )
const auto totalR = right . data ( TransferListModel : : AdditionalUnderlyingDataRole ) . toInt ( ) ;
return ( leftValueTotal < rightValueTotal ) ;
if ( totalL ! = totalR )
return totalL < totalR ;
return invokeLessThanForColumn ( TransferListModel : : TR_QUEUE_POSITION ) ;
return invokeLessThanForColumn ( TransferListModel : : TR_QUEUE_POSITION ) ;
}
}
case TransferListModel : : TR_ETA :
case TransferListModel : : TR_ETA :
{
{
// Sorting rules prioritized.
// Sorting rules prioritized.
// 1. Active torrents at the top
// 1. Active torrents at the top
// 2. Seeding torrents at the bottom
// 2. Seeding torrents at the bottom
@ -221,9 +222,9 @@ bool TransferListSortModel::lessThan_impl(const QModelIndex &left, const QModelI
if ( isActiveL ! = isActiveR )
if ( isActiveL ! = isActiveR )
return isActiveL ;
return isActiveL ;
const int queuePosL = left . sibling ( left . row ( ) , TransferListModel : : TR_QUEUE_POSITION )
const auto queuePosL = left . sibling ( left . row ( ) , TransferListModel : : TR_QUEUE_POSITION )
. data ( TransferListModel : : UnderlyingDataRole ) . toInt ( ) ;
. data ( TransferListModel : : UnderlyingDataRole ) . toInt ( ) ;
const int queuePosR = right . sibling ( right . row ( ) , TransferListModel : : TR_QUEUE_POSITION )
const auto queuePosR = right . sibling ( right . row ( ) , TransferListModel : : TR_QUEUE_POSITION )
. data ( TransferListModel : : UnderlyingDataRole ) . toInt ( ) ;
. data ( TransferListModel : : UnderlyingDataRole ) . toInt ( ) ;
const bool isSeedingL = ( queuePosL < 0 ) ;
const bool isSeedingL = ( queuePosL < 0 ) ;
const bool isSeedingR = ( queuePosR < 0 ) ;
const bool isSeedingR = ( queuePosR < 0 ) ;
@ -236,8 +237,8 @@ bool TransferListSortModel::lessThan_impl(const QModelIndex &left, const QModelI
return isAscendingOrder ;
return isAscendingOrder ;
}
}
const qlonglong etaL = leftValue . toLongLong ( ) ;
const auto etaL = leftValue . toLongLong ( ) ;
const qlonglong etaR = rightValue . toLongLong ( ) ;
const auto etaR = rightValue . toLongLong ( ) ;
const bool isInvalidL = ( ( etaL < 0 ) | | ( etaL > = MAX_ETA ) ) ;
const bool isInvalidL = ( ( etaL < 0 ) | | ( etaL > = MAX_ETA ) ) ;
const bool isInvalidR = ( ( etaR < 0 ) | | ( etaR > = MAX_ETA ) ) ;
const bool isInvalidR = ( ( etaR < 0 ) | | ( etaR > = MAX_ETA ) ) ;
if ( isInvalidL & & isInvalidR )
if ( isInvalidL & & isInvalidR )
@ -255,12 +256,24 @@ bool TransferListSortModel::lessThan_impl(const QModelIndex &left, const QModelI
}
}
case TransferListModel : : TR_LAST_ACTIVITY :
case TransferListModel : : TR_LAST_ACTIVITY :
{
const auto lastActivityL = leftValue . toLongLong ( ) ;
const auto lastActivityR = rightValue . toLongLong ( ) ;
if ( lastActivityL < 0 ) return false ;
if ( lastActivityR < 0 ) return true ;
return lastActivityL < lastActivityR ;
}
case TransferListModel : : TR_RATIO_LIMIT :
case TransferListModel : : TR_RATIO_LIMIT :
// QVariant has comparators for all basic types
{
if ( leftValue < 0 ) return false ;
const auto ratioL = leftValue . toReal ( ) ;
if ( rightValue < 0 ) return true ;
const auto ratioR = rightValue . toReal ( ) ;
return ( leftValue < rightValue ) ;
if ( ratioL < 0 ) return false ;
if ( ratioR < 0 ) return true ;
return ratioL < ratioR ;
}
}
}
return ( leftValue ! = rightValue )
return ( leftValue ! = rightValue )