diff --git a/src/gui/properties/peerlistwidget.cpp b/src/gui/properties/peerlistwidget.cpp index feda1608e..28aa4fc09 100644 --- a/src/gui/properties/peerlistwidget.cpp +++ b/src/gui/properties/peerlistwidget.cpp @@ -301,7 +301,7 @@ void PeerListWidget::copySelectedPeers() int row = m_proxyModel->mapToSource(index).row(); QString ip = m_listModel->data(m_listModel->index(row, PeerListDelegate::IP_HIDDEN)).toString(); QString myport = m_listModel->data(m_listModel->index(row, PeerListDelegate::PORT)).toString(); - if (ip.indexOf('.') == -1) // IPv6 + if (!ip.contains('.')) // IPv6 selectedPeers << '[' + ip + "]:" + myport; else // IPv4 selectedPeers << ip + ':' + myport; diff --git a/src/gui/transferlistdelegate.cpp b/src/gui/transferlistdelegate.cpp index 7cfbef768..ffc2edbf0 100644 --- a/src/gui/transferlistdelegate.cpp +++ b/src/gui/transferlistdelegate.cpp @@ -54,16 +54,18 @@ TransferListDelegate::TransferListDelegate(QObject *parent) void TransferListDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const { painter->save(); + bool isHideState = true; if (Preferences::instance()->getHideZeroComboValues() == 1) { // paused torrents only - QModelIndex stateIndex = index.sibling(index.row(), TransferListModel::TR_STATUS); + const QModelIndex stateIndex = index.sibling(index.row(), TransferListModel::TR_STATUS); if (stateIndex.data().value() != BitTorrent::TorrentState::PausedDownloading) isHideState = false; } - const bool hideValues = Preferences::instance()->getHideZeroValues() & isHideState; + const bool hideValues = Preferences::instance()->getHideZeroValues() && isHideState; QStyleOptionViewItem opt = QItemDelegate::setOptions(index, option); QItemDelegate::drawBackground(painter, opt, index); + switch (index.column()) { case TransferListModel::TR_AMOUNT_DOWNLOADED: case TransferListModel::TR_AMOUNT_UPLOADED: @@ -81,10 +83,10 @@ void TransferListDelegate::paint(QPainter *painter, const QStyleOptionViewItem & } break; case TransferListModel::TR_ETA: { - opt.displayAlignment = Qt::AlignRight | Qt::AlignVCenter; - QItemDelegate::drawDisplay(painter, opt, option.rect, Utils::Misc::userFriendlyDuration(index.data().toLongLong(), MAX_ETA)); + opt.displayAlignment = Qt::AlignRight | Qt::AlignVCenter; + QItemDelegate::drawDisplay(painter, opt, option.rect, Utils::Misc::userFriendlyDuration(index.data().toLongLong(), MAX_ETA)); + } break; - } case TransferListModel::TR_SEEDS: case TransferListModel::TR_PEERS: { qlonglong value = index.data().toLongLong(); @@ -148,30 +150,32 @@ void TransferListDelegate::paint(QPainter *painter, const QStyleOptionViewItem & case TransferListModel::TR_QUEUE_POSITION: { const int queuePos = index.data().toInt(); opt.displayAlignment = Qt::AlignRight | Qt::AlignVCenter; - if (queuePos > 0) { + if (queuePos > 0) QItemDelegate::paint(painter, opt, index); - } - else { + else QItemDelegate::drawDisplay(painter, opt, opt.rect, "*"); - } } break; case TransferListModel::TR_PROGRESS: { + const qreal progress = index.data().toDouble() * 100; + QStyleOptionProgressBar newopt; - qreal progress = index.data().toDouble() * 100.; newopt.rect = opt.rect; - newopt.text = ((progress == 100.0) ? QString("100%") : Utils::String::fromDouble(progress, 1) + '%'); + newopt.text = ((progress == 100) + ? QString("100%") + : (Utils::String::fromDouble(progress, 1) + '%')); newopt.progress = static_cast(progress); newopt.maximum = 100; newopt.minimum = 0; newopt.state |= QStyle::State_Enabled; newopt.textVisible = true; -#if !defined(Q_OS_WIN) && !defined(Q_OS_MACOS) - QApplication::style()->drawControl(QStyle::CE_ProgressBar, &newopt, painter); -#else - // XXX: To avoid having the progress text on the right of the bar + +#if defined(Q_OS_WIN) || defined(Q_OS_MACOS) + // XXX: To avoid having the progress text on the right of the bar QProxyStyle st("fusion"); - st.drawControl(QStyle::CE_ProgressBar, &newopt, painter, 0); + st.drawControl(QStyle::CE_ProgressBar, &newopt, painter); +#else + QApplication::style()->drawControl(QStyle::CE_ProgressBar, &newopt, painter); #endif } break; @@ -207,6 +211,7 @@ void TransferListDelegate::paint(QPainter *painter, const QStyleOptionViewItem & default: QItemDelegate::paint(painter, option, index); } + painter->restore(); } @@ -225,7 +230,7 @@ QSize TransferListDelegate::sizeHint(const QStyleOptionViewItem &option, const Q static int nameColHeight = -1; if (nameColHeight == -1) { - QModelIndex nameColumn = index.sibling(index.row(), TransferListModel::TR_NAME); + const QModelIndex nameColumn = index.sibling(index.row(), TransferListModel::TR_NAME); nameColHeight = QItemDelegate::sizeHint(option, nameColumn).height(); } @@ -236,60 +241,41 @@ QSize TransferListDelegate::sizeHint(const QStyleOptionViewItem &option, const Q QString TransferListDelegate::getStatusString(const BitTorrent::TorrentState state) const { - QString str; - switch (state) { case BitTorrent::TorrentState::Downloading: - str = tr("Downloading"); - break; + return tr("Downloading"); case BitTorrent::TorrentState::StalledDownloading: - str = tr("Stalled", "Torrent is waiting for download to begin"); - break; + return tr("Stalled", "Torrent is waiting for download to begin"); case BitTorrent::TorrentState::DownloadingMetadata: - str = tr("Downloading metadata", "used when loading a magnet link"); - break; + return tr("Downloading metadata", "Used when loading a magnet link"); case BitTorrent::TorrentState::ForcedDownloading: - str = tr("[F] Downloading", "used when the torrent is forced started. You probably shouldn't translate the F."); - break; + return tr("[F] Downloading", "Used when the torrent is forced started. You probably shouldn't translate the F."); case BitTorrent::TorrentState::Allocating: - str = tr("Allocating", "qBittorrent is allocating the files on disk"); - break; + return tr("Allocating", "qBittorrent is allocating the files on disk"); case BitTorrent::TorrentState::Uploading: case BitTorrent::TorrentState::StalledUploading: - str = tr("Seeding", "Torrent is complete and in upload-only mode"); - break; + return tr("Seeding", "Torrent is complete and in upload-only mode"); case BitTorrent::TorrentState::ForcedUploading: - str = tr("[F] Seeding", "used when the torrent is forced started. You probably shouldn't translate the F."); - break; + return tr("[F] Seeding", "Used when the torrent is forced started. You probably shouldn't translate the F."); case BitTorrent::TorrentState::QueuedDownloading: case BitTorrent::TorrentState::QueuedUploading: - str = tr("Queued", "i.e. torrent is queued"); - break; + return tr("Queued", "Torrent is queued"); case BitTorrent::TorrentState::CheckingDownloading: case BitTorrent::TorrentState::CheckingUploading: - str = tr("Checking", "Torrent local data is being checked"); - break; + return tr("Checking", "Torrent local data is being checked"); case BitTorrent::TorrentState::CheckingResumeData: - str = tr("Checking resume data", "used when loading the torrents from disk after qbt is launched. It checks the correctness of the .fastresume file. Normally it is completed in a fraction of a second, unless loading many many torrents."); - break; + return tr("Checking resume data", "Used when loading the torrents from disk after qbt is launched. It checks the correctness of the .fastresume file. Normally it is completed in a fraction of a second, unless loading many many torrents."); case BitTorrent::TorrentState::PausedDownloading: - str = tr("Paused"); - break; + return tr("Paused"); case BitTorrent::TorrentState::PausedUploading: - str = tr("Completed"); - break; + return tr("Completed"); case BitTorrent::TorrentState::Moving: - str = tr("Moving", "Torrent local data are being moved/relocated"); - break; + return tr("Moving", "Torrent local data are being moved/relocated"); case BitTorrent::TorrentState::MissingFiles: - str = tr("Missing Files"); - break; + return tr("Missing Files"); case BitTorrent::TorrentState::Error: - str = tr("Errored", "torrent status, the torrent has an error"); - break; + return tr("Errored", "Torrent status, the torrent has an error"); default: - str = ""; + return {}; } - - return str; } diff --git a/src/gui/transferlistsortmodel.cpp b/src/gui/transferlistsortmodel.cpp index 78a136e22..045610141 100644 --- a/src/gui/transferlistsortmodel.cpp +++ b/src/gui/transferlistsortmodel.cpp @@ -114,13 +114,11 @@ bool TransferListSortModel::lessThan(const QModelIndex &left, const QModelIndex case TransferListModel::TR_ADD_DATE: case TransferListModel::TR_SEED_DATE: - case TransferListModel::TR_SEEN_COMPLETE_DATE: { + case TransferListModel::TR_SEEN_COMPLETE_DATE: return dateLessThan(sortColumn(), left, right, true); - } - case TransferListModel::TR_QUEUE_POSITION: { + case TransferListModel::TR_QUEUE_POSITION: return lowerPositionThan(left, right); - } case TransferListModel::TR_SEEDS: case TransferListModel::TR_PEERS: { @@ -140,20 +138,22 @@ bool TransferListSortModel::lessThan(const QModelIndex &left, const QModelIndex } case TransferListModel::TR_ETA: { - const TransferListModel *model = qobject_cast(sourceModel()); - // Sorting rules prioritized. // 1. Active torrents at the top // 2. Seeding torrents at the bottom // 3. Torrents with invalid ETAs at the bottom - const bool isActiveL = TorrentFilter::ActiveTorrent.match(model->torrentHandle(model->index(left.row()))); - const bool isActiveR = TorrentFilter::ActiveTorrent.match(model->torrentHandle(model->index(right.row()))); + const TransferListModel *model = qobject_cast(sourceModel()); + + // From QSortFilterProxyModel::lessThan() documentation: + // "Note: The indices passed in correspond to the source model" + const bool isActiveL = TorrentFilter::ActiveTorrent.match(model->torrentHandle(left)); + const bool isActiveR = TorrentFilter::ActiveTorrent.match(model->torrentHandle(right)); if (isActiveL != isActiveR) return isActiveL; - const int queuePosL = model->data(model->index(left.row(), TransferListModel::TR_QUEUE_POSITION)).toInt(); - const int queuePosR = model->data(model->index(right.row(), TransferListModel::TR_QUEUE_POSITION)).toInt(); + const int queuePosL = left.sibling(left.row(), TransferListModel::TR_QUEUE_POSITION).data().toInt(); + const int queuePosR = right.sibling(right.row(), TransferListModel::TR_QUEUE_POSITION).data().toInt(); const bool isSeedingL = (queuePosL < 0); const bool isSeedingR = (queuePosR < 0); if (isSeedingL != isSeedingR) { @@ -201,22 +201,20 @@ bool TransferListSortModel::lessThan(const QModelIndex &left, const QModelIndex return (vL < vR); } - default: { + default: if (left.data() != right.data()) return QSortFilterProxyModel::lessThan(left, right); return lowerPositionThan(left, right); - } } } bool TransferListSortModel::lowerPositionThan(const QModelIndex &left, const QModelIndex &right) const { - const TransferListModel *model = qobject_cast(sourceModel()); - // Sort according to TR_QUEUE_POSITION - const int queueL = model->data(model->index(left.row(), TransferListModel::TR_QUEUE_POSITION)).toInt(); - const int queueR = model->data(model->index(right.row(), TransferListModel::TR_QUEUE_POSITION)).toInt(); + const int queueL = left.sibling(left.row(), TransferListModel::TR_QUEUE_POSITION).data().toInt(); + const int queueR = right.sibling(right.row(), TransferListModel::TR_QUEUE_POSITION).data().toInt(); + if ((queueL > 0) || (queueR > 0)) { if ((queueL > 0) && (queueR > 0)) return queueL < queueR; @@ -233,9 +231,9 @@ bool TransferListSortModel::lowerPositionThan(const QModelIndex &left, const QMo // (detailed discussion in #2526 and #2158). bool TransferListSortModel::dateLessThan(const int dateColumn, const QModelIndex &left, const QModelIndex &right, bool sortInvalidInBottom) const { - const TransferListModel *model = qobject_cast(sourceModel()); - const QDateTime dateL = model->data(model->index(left.row(), dateColumn)).toDateTime(); - const QDateTime dateR = model->data(model->index(right.row(), dateColumn)).toDateTime(); + const QDateTime dateL = left.sibling(left.row(), dateColumn).data().toDateTime(); + const QDateTime dateR = right.sibling(right.row(), dateColumn).data().toDateTime(); + if (dateL.isValid() && dateR.isValid()) { if (dateL != dateR) return dateL < dateR; @@ -248,23 +246,24 @@ bool TransferListSortModel::dateLessThan(const int dateColumn, const QModelIndex } // Finally, sort by hash - const QString hashL(model->torrentHandle(model->index(left.row()))->hash()); - const QString hashR(model->torrentHandle(model->index(right.row()))->hash()); + const TransferListModel *model = qobject_cast(sourceModel()); + const QString hashL = model->torrentHandle(left)->hash(); + const QString hashR = model->torrentHandle(right)->hash(); return hashL < hashR; } -bool TransferListSortModel::filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const +bool TransferListSortModel::filterAcceptsRow(const int sourceRow, const QModelIndex &sourceParent) const { return matchFilter(sourceRow, sourceParent) && QSortFilterProxyModel::filterAcceptsRow(sourceRow, sourceParent); } -bool TransferListSortModel::matchFilter(int sourceRow, const QModelIndex &sourceParent) const +bool TransferListSortModel::matchFilter(const int sourceRow, const QModelIndex &sourceParent) const { - auto *model = qobject_cast(sourceModel()); + const auto *model = qobject_cast(sourceModel()); if (!model) return false; - BitTorrent::TorrentHandle *const torrent = model->torrentHandle(model->index(sourceRow, 0, sourceParent)); + const BitTorrent::TorrentHandle *torrent = model->torrentHandle(model->index(sourceRow, 0, sourceParent)); if (!torrent) return false; return m_filter.match(torrent);