diff --git a/src/gui/transferlistsortmodel.cpp b/src/gui/transferlistsortmodel.cpp index 0574e44c4..41fbe2d72 100644 --- a/src/gui/transferlistsortmodel.cpp +++ b/src/gui/transferlistsortmodel.cpp @@ -107,14 +107,7 @@ bool TransferListSortModel::lessThan(const QModelIndex &left, const QModelIndex return QSortFilterProxyModel::lessThan(left, right); } else if (column == TorrentModelItem::TR_ADD_DATE || column == TorrentModelItem::TR_SEED_DATE || column == TorrentModelItem::TR_SEEN_COMPLETE_DATE) { - QDateTime vL = left.data().toDateTime(); - QDateTime vR = right.data().toDateTime(); - - //not valid dates should be sorted at the bottom. - if (!vL.isValid()) return false; - if (!vR.isValid()) return true; - - return vL < vR; + return dateLessThan(column, left, right); } else if (column == TorrentModelItem::TR_PRIORITY) { return lowerPositionThan(left, right); @@ -191,14 +184,7 @@ bool TransferListSortModel::lessThan(const QModelIndex &left, const QModelIndex if (invalidL && invalidR) { if (seedingL) { //Both seeding - QDateTime dateL = model->data(model->index(left.row(), TorrentModelItem::TR_SEED_DATE)).toDateTime(); - QDateTime dateR = model->data(model->index(right.row(), TorrentModelItem::TR_SEED_DATE)).toDateTime(); - - //not valid dates should be sorted at the bottom. - if (!dateL.isValid()) return false; - if (!dateR.isValid()) return true; - - return dateL < dateR; + return dateLessThan(TorrentModelItem::TR_SEED_DATE, left, right); } else { return prioL < prioR; @@ -253,8 +239,17 @@ bool TransferListSortModel::lowerPositionThan(const QModelIndex &left, const QMo } // Sort according to TR_SEED_DATE - const QDateTime dateL = model->data(model->index(left.row(), TorrentModelItem::TR_SEED_DATE)).toDateTime(); - const QDateTime dateR = model->data(model->index(right.row(), TorrentModelItem::TR_SEED_DATE)).toDateTime(); + return dateLessThan(TorrentModelItem::TR_SEED_DATE, left, right); +} + +// Every time we compare QDateTimes we need a fallback comparison in case both +// values are empty. This is a workaround for unstable sort in QSortFilterProxyModel +// (detailed discussion in #2526 and #2158). +bool TransferListSortModel::dateLessThan(const int dateColumn, const QModelIndex &left, const QModelIndex &right) const +{ + const TorrentModel *model = dynamic_cast(sourceModel()); + const QDateTime dateL = model->data(model->index(left.row(), dateColumn)).toDateTime(); + const QDateTime dateR = model->data(model->index(right.row(), dateColumn)).toDateTime(); if (dateL.isValid() && dateR.isValid()) { if (dateL != dateR) return dateL < dateR; diff --git a/src/gui/transferlistsortmodel.h b/src/gui/transferlistsortmodel.h index ec59587a6..b4b3437ec 100644 --- a/src/gui/transferlistsortmodel.h +++ b/src/gui/transferlistsortmodel.h @@ -51,6 +51,7 @@ public: private: bool lessThan(const QModelIndex &left, const QModelIndex &right) const; bool lowerPositionThan(const QModelIndex &left, const QModelIndex &right) const; + bool dateLessThan(const int dateColumn, const QModelIndex &left, const QModelIndex &right) const; bool filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const; bool matchStatusFilter(int sourceRow, const QModelIndex &sourceParent) const;