From 816bc4570727a761c1ca634e05895c0dcfb5bce7 Mon Sep 17 00:00:00 2001 From: jagannatharjun Date: Sun, 18 Oct 2020 12:36:18 +0530 Subject: [PATCH 1/3] Implement ProgressBarDelegate --- src/gui/CMakeLists.txt | 2 + src/gui/gui.pri | 2 + src/gui/progressbardelegate.cpp | 73 +++++++++++++++++++++++++++++++++ src/gui/progressbardelegate.h | 51 +++++++++++++++++++++++ 4 files changed, 128 insertions(+) create mode 100644 src/gui/progressbardelegate.cpp create mode 100644 src/gui/progressbardelegate.h diff --git a/src/gui/CMakeLists.txt b/src/gui/CMakeLists.txt index e38cbb71c..1169cb51d 100644 --- a/src/gui/CMakeLists.txt +++ b/src/gui/CMakeLists.txt @@ -26,6 +26,7 @@ add_library(qbt_gui STATIC powermanagement/powermanagement.h previewlistdelegate.h previewselectdialog.h + progressbardelegate.h properties/downloadedpiecesbar.h properties/peerlistsortmodel.h properties/peerlistwidget.h @@ -105,6 +106,7 @@ add_library(qbt_gui STATIC powermanagement/powermanagement.cpp previewlistdelegate.cpp previewselectdialog.cpp + progressbardelegate.cpp properties/downloadedpiecesbar.cpp properties/peerlistsortmodel.cpp properties/peerlistwidget.cpp diff --git a/src/gui/gui.pri b/src/gui/gui.pri index c206947ee..8dfb7c37c 100644 --- a/src/gui/gui.pri +++ b/src/gui/gui.pri @@ -27,6 +27,7 @@ HEADERS += \ $$PWD/powermanagement/powermanagement.h \ $$PWD/previewlistdelegate.h \ $$PWD/previewselectdialog.h \ + $$PWD/progressbardelegate.h \ $$PWD/properties/downloadedpiecesbar.h \ $$PWD/properties/peerlistsortmodel.h \ $$PWD/properties/peerlistwidget.h \ @@ -106,6 +107,7 @@ SOURCES += \ $$PWD/powermanagement/powermanagement.cpp \ $$PWD/previewlistdelegate.cpp \ $$PWD/previewselectdialog.cpp \ + $$PWD/progressbardelegate.cpp \ $$PWD/properties/downloadedpiecesbar.cpp \ $$PWD/properties/peerlistsortmodel.cpp \ $$PWD/properties/peerlistwidget.cpp \ diff --git a/src/gui/progressbardelegate.cpp b/src/gui/progressbardelegate.cpp new file mode 100644 index 000000000..706f80799 --- /dev/null +++ b/src/gui/progressbardelegate.cpp @@ -0,0 +1,73 @@ +/* + * Bittorrent Client using Qt and libtorrent. + * Copyright (C) 2020 Prince Gupta + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * In addition, as a special exception, the copyright holders give permission to + * link this program with the OpenSSL project's "OpenSSL" library (or with + * modified versions of it that use the same license as the "OpenSSL" library), + * and distribute the linked executables. You must obey the GNU General Public + * License in all respects for all of the code used other than "OpenSSL". If you + * modify file(s), you may extend this exception to your version of the file(s), + * but you are not obligated to do so. If you do not wish to do so, delete this + * exception statement from your version. + */ + +#include "progressbardelegate.h" + +#include +#include +#include +#include + +#if (defined(Q_OS_WIN) || defined(Q_OS_MACOS)) +#include +#endif + +ProgressBarDelegate::ProgressBarDelegate(const int progressColumn, const int dataRole, QObject *parent) + : QStyledItemDelegate {parent} + , m_progressColumn {progressColumn} + , m_dataRole {dataRole} +{ +#if (defined(Q_OS_WIN) || defined(Q_OS_MACOS)) + m_dummyProgressBar.setStyle(new QProxyStyle {"fusion"}); +#endif +} + +void ProgressBarDelegate::initProgressStyleOption(QStyleOptionProgressBar &option, const QModelIndex &index) const +{ + option.text = index.data().toString(); + option.progress = static_cast(index.data(m_dataRole).toReal()); + option.maximum = 100; + option.minimum = 0; + option.state |= (QStyle::State_Enabled | QStyle::State_Horizontal); + option.textVisible = true; +} + +void ProgressBarDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const +{ + if (index.column() != m_progressColumn) + return QStyledItemDelegate::paint(painter, option, index); + + QStyleOptionProgressBar newopt; + newopt.initFrom(&m_dummyProgressBar); + newopt.rect = option.rect; + initProgressStyleOption(newopt, index); + + painter->save(); + m_dummyProgressBar.style()->drawControl(QStyle::CE_ProgressBar, &newopt, painter, &m_dummyProgressBar); + painter->restore(); +} diff --git a/src/gui/progressbardelegate.h b/src/gui/progressbardelegate.h new file mode 100644 index 000000000..5432f17d7 --- /dev/null +++ b/src/gui/progressbardelegate.h @@ -0,0 +1,51 @@ +/* + * Bittorrent Client using Qt and libtorrent. + * Copyright (C) 2020 Prince Gupta + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * In addition, as a special exception, the copyright holders give permission to + * link this program with the OpenSSL project's "OpenSSL" library (or with + * modified versions of it that use the same license as the "OpenSSL" library), + * and distribute the linked executables. You must obey the GNU General Public + * License in all respects for all of the code used other than "OpenSSL". If you + * modify file(s), you may extend this exception to your version of the file(s), + * but you are not obligated to do so. If you do not wish to do so, delete this + * exception statement from your version. + */ + +#pragma once + +#include +#include + +class QStyleOptionProgressBar; + +class ProgressBarDelegate : public QStyledItemDelegate +{ +public: + ProgressBarDelegate(int progressColumn, int dataRole, QObject *parent = nullptr); + +protected: + void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const override; + virtual void initProgressStyleOption(QStyleOptionProgressBar &option, const QModelIndex &index) const; + +private: + const int m_progressColumn; + const int m_dataRole; + + // for painting progressbar with stylesheet option, a dummy progress bar is required + QProgressBar m_dummyProgressBar; +}; From 49d5591f48373dc872a7a2a2ef6e9fc3d646292b Mon Sep 17 00:00:00 2001 From: jagannatharjun Date: Sun, 18 Oct 2020 12:37:14 +0530 Subject: [PATCH 2/3] Use ProgressBarDelegate for drawing progressbar in TransferListView --- src/gui/transferlistdelegate.cpp | 39 +------------------------------- src/gui/transferlistdelegate.h | 9 ++------ 2 files changed, 3 insertions(+), 45 deletions(-) diff --git a/src/gui/transferlistdelegate.cpp b/src/gui/transferlistdelegate.cpp index d8ecfb1a4..eddbef7b8 100644 --- a/src/gui/transferlistdelegate.cpp +++ b/src/gui/transferlistdelegate.cpp @@ -28,50 +28,13 @@ #include "transferlistdelegate.h" -#include #include -#include -#include -#if defined(Q_OS_WIN) || defined(Q_OS_MACOS) -#include -#endif - -#include "base/utils/string.h" #include "transferlistmodel.h" TransferListDelegate::TransferListDelegate(QObject *parent) - : QStyledItemDelegate {parent} -{ -} - -void TransferListDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const + : ProgressBarDelegate {TransferListModel::TR_PROGRESS, TransferListModel::UnderlyingDataRole, parent} { - if (index.column() != TransferListModel::TR_PROGRESS) { - QStyledItemDelegate::paint(painter, option, index); - return; - } - - QStyleOptionProgressBar newopt; - newopt.rect = option.rect; - newopt.text = index.data().toString(); - newopt.progress = static_cast(index.data(TransferListModel::UnderlyingDataRole).toReal()); - newopt.maximum = 100; - newopt.minimum = 0; - newopt.state = option.state; - newopt.textVisible = true; - -#if defined(Q_OS_WIN) || defined(Q_OS_MACOS) - // XXX: To avoid having the progress text on the right of the bar - QProxyStyle fusionStyle {"fusion"}; - QStyle *style = &fusionStyle; -#else - QStyle *style = option.widget ? option.widget->style() : QApplication::style(); -#endif - - painter->save(); - style->drawControl(QStyle::CE_ProgressBar, &newopt, painter); - painter->restore(); } QWidget *TransferListDelegate::createEditor(QWidget *, const QStyleOptionViewItem &, const QModelIndex &) const diff --git a/src/gui/transferlistdelegate.h b/src/gui/transferlistdelegate.h index 2d5302cca..7be78cc39 100644 --- a/src/gui/transferlistdelegate.h +++ b/src/gui/transferlistdelegate.h @@ -28,13 +28,9 @@ #pragma once -#include +#include "progressbardelegate.h" -class QModelIndex; -class QPainter; -class QStyleOptionViewItem; - -class TransferListDelegate final : public QStyledItemDelegate +class TransferListDelegate final : public ProgressBarDelegate { Q_OBJECT Q_DISABLE_COPY(TransferListDelegate) @@ -42,7 +38,6 @@ class TransferListDelegate final : public QStyledItemDelegate public: explicit TransferListDelegate(QObject *parent); - void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const override; QWidget *createEditor(QWidget *, const QStyleOptionViewItem &, const QModelIndex &) const override; QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const override; }; From 02f19bfbee1a1529a8dae5106f98c909d82c1932 Mon Sep 17 00:00:00 2001 From: jagannatharjun Date: Sat, 24 Oct 2020 12:57:46 +0530 Subject: [PATCH 3/3] Use ProgressbarDelegate for drawing progressbar in PropListDelegate Also directly provide display data from model rather then generating it in delegate --- src/gui/properties/proplistdelegate.cpp | 109 ++++-------------------- src/gui/properties/proplistdelegate.h | 7 +- src/gui/torrentcontentfiltermodel.cpp | 2 +- src/gui/torrentcontentmodel.cpp | 43 ++++++---- src/gui/torrentcontentmodel.h | 5 ++ src/gui/torrentcontentmodelfolder.cpp | 2 +- src/gui/torrentcontentmodelfolder.h | 2 +- src/gui/torrentcontentmodelitem.cpp | 55 +++++++++++- src/gui/torrentcontentmodelitem.h | 8 +- 9 files changed, 113 insertions(+), 120 deletions(-) diff --git a/src/gui/properties/proplistdelegate.cpp b/src/gui/properties/proplistdelegate.cpp index bfb7bf0fa..b3382ade6 100644 --- a/src/gui/properties/proplistdelegate.cpp +++ b/src/gui/properties/proplistdelegate.cpp @@ -42,9 +42,7 @@ #include "base/bittorrent/downloadpriority.h" #include "base/bittorrent/torrenthandle.h" -#include "base/unicodestrings.h" -#include "base/utils/misc.h" -#include "base/utils/string.h" +#include "gui/torrentcontentmodel.h" #include "propertieswidget.h" namespace @@ -64,107 +62,31 @@ namespace } PropListDelegate::PropListDelegate(PropertiesWidget *properties) - : QStyledItemDelegate(properties) + : ProgressBarDelegate {PROGRESS, TorrentContentModel::UnderlyingDataRole, properties} , m_properties(properties) { } -void PropListDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const +void PropListDelegate::initProgressStyleOption(QStyleOptionProgressBar &option, const QModelIndex &index) const { - painter->save(); - - const QStyle *style = option.widget ? option.widget->style() : QApplication::style(); - QStyleOptionViewItem opt = option; - QStyledItemDelegate::initStyleOption(&opt, index); - - switch (index.column()) { - case PCSIZE: - case REMAINING: - opt.text = Utils::Misc::friendlyUnit(index.data().toLongLong()); - style->drawControl(QStyle::CE_ItemViewItem, &opt, painter, opt.widget); - break; - - case PROGRESS: { - const qreal progress = (index.data().toReal() * 100); - if (progress < 0) - break; - - QStyleOptionProgressBar newopt; - newopt.rect = opt.rect; - newopt.text = (progress == 100) ? QString("100%") : (Utils::String::fromDouble(progress, 1) + '%'); - newopt.progress = static_cast(progress); - newopt.maximum = 100; - newopt.minimum = 0; - newopt.textVisible = true; - if (index.sibling(index.row(), PRIORITY).data().toInt() == static_cast(BitTorrent::DownloadPriority::Ignored)) { - newopt.state &= ~QStyle::State_Enabled; - newopt.palette = progressBarDisabledPalette(); - } - else { - newopt.state |= QStyle::State_Enabled; - } - -#if defined(Q_OS_WIN) || defined(Q_OS_MACOS) - // XXX: To avoid having the progress text on the right of the bar - QProxyStyle("fusion").drawControl(QStyle::CE_ProgressBar, &newopt, painter, 0); -#else - QApplication::style()->drawControl(QStyle::CE_ProgressBar, &newopt, painter); -#endif - } - break; - - case PRIORITY: { - QString text = ""; - switch (static_cast(index.data().toInt())) { - case BitTorrent::DownloadPriority::Mixed: - text = tr("Mixed", "Mixed (priorities"); - break; - case BitTorrent::DownloadPriority::Ignored: - text = tr("Not downloaded"); - break; - case BitTorrent::DownloadPriority::High: - text = tr("High", "High (priority)"); - break; - case BitTorrent::DownloadPriority::Maximum: - text = tr("Maximum", "Maximum (priority)"); - break; - default: - text = tr("Normal", "Normal (priority)"); - break; - } - opt.text = text; - style->drawControl(QStyle::CE_ItemViewItem, &opt, painter, opt.widget); - } - break; - - case AVAILABILITY: { - const qreal availability = index.data().toReal(); - if (availability < 0) { - opt.text = tr("N/A"); - } - else { - const QString value = (availability >= 1.0) - ? QLatin1String("100") - : Utils::String::fromDouble(availability * 100, 1); - opt.text = (value + C_THIN_SPACE + QLatin1Char('%')); - } - style->drawControl(QStyle::CE_ItemViewItem, &opt, painter, opt.widget); - } - break; - - default: - QStyledItemDelegate::paint(painter, option, index); - break; + ProgressBarDelegate::initProgressStyleOption(option, index); + const int priority + = index.sibling(index.row(), PRIORITY).data(TorrentContentModel::UnderlyingDataRole).toInt(); + if (static_cast(priority) == BitTorrent::DownloadPriority::Ignored) { + option.state &= ~QStyle::State_Enabled; + option.palette = progressBarDisabledPalette(); + } + else { + option.state |= QStyle::State_Enabled; } - - painter->restore(); } void PropListDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const { auto *combobox = static_cast(editor); // Set combobox index - switch (static_cast(index.data().toInt())) { + const int priority = index.data(TorrentContentModel::UnderlyingDataRole).toInt(); + switch (static_cast(priority)) { case BitTorrent::DownloadPriority::Ignored: combobox->setCurrentIndex(0); break; @@ -190,7 +112,8 @@ QWidget *PropListDelegate::createEditor(QWidget *parent, const QStyleOptionViewI return nullptr; } - if (index.data().toInt() == static_cast(BitTorrent::DownloadPriority::Mixed)) + const int priority = index.data(TorrentContentModel::UnderlyingDataRole).toInt(); + if (static_cast(priority) == BitTorrent::DownloadPriority::Mixed) return nullptr; auto *editor = new QComboBox(parent); diff --git a/src/gui/properties/proplistdelegate.h b/src/gui/properties/proplistdelegate.h index 4af03b0e6..563c77bc5 100644 --- a/src/gui/properties/proplistdelegate.h +++ b/src/gui/properties/proplistdelegate.h @@ -29,7 +29,7 @@ #ifndef PROPLISTDELEGATE_H #define PROPLISTDELEGATE_H -#include +#include "gui/progressbardelegate.h" class QAbstractItemModel; class QModelIndex; @@ -49,14 +49,13 @@ enum PropColumn AVAILABILITY }; -class PropListDelegate final : public QStyledItemDelegate +class PropListDelegate final : public ProgressBarDelegate { Q_OBJECT public: explicit PropListDelegate(PropertiesWidget *properties); - void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const override; void setEditorData(QWidget *editor, const QModelIndex &index) const override; QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem & /* option */, const QModelIndex &index) const override; @@ -68,6 +67,8 @@ signals: void filteredFilesChanged() const; private: + void initProgressStyleOption(QStyleOptionProgressBar &option, const QModelIndex &index) const override; + PropertiesWidget *m_properties; }; diff --git a/src/gui/torrentcontentfiltermodel.cpp b/src/gui/torrentcontentfiltermodel.cpp index 8f91b0711..f28b3a1fa 100644 --- a/src/gui/torrentcontentfiltermodel.cpp +++ b/src/gui/torrentcontentfiltermodel.cpp @@ -39,7 +39,7 @@ TorrentContentFilterModel::TorrentContentFilterModel(QObject *parent) setSourceModel(m_model); // Filter settings setFilterKeyColumn(TorrentContentModelItem::COL_NAME); - setFilterRole(Qt::DisplayRole); + setFilterRole(TorrentContentModel::UnderlyingDataRole); setDynamicSortFilter(true); setSortCaseSensitivity(Qt::CaseInsensitive); } diff --git a/src/gui/torrentcontentmodel.cpp b/src/gui/torrentcontentmodel.cpp index 7462f44ab..a71013a7f 100644 --- a/src/gui/torrentcontentmodel.cpp +++ b/src/gui/torrentcontentmodel.cpp @@ -180,7 +180,7 @@ namespace TorrentContentModel::TorrentContentModel(QObject *parent) : QAbstractItemModel(parent) - , m_rootItem(new TorrentContentModelFolder(QVector({ tr("Name"), tr("Size"), tr("Progress"), tr("Download Priority"), tr("Remaining"), tr("Availability") }))) + , m_rootItem(new TorrentContentModelFolder(QVector({ tr("Name"), tr("Size"), tr("Progress"), tr("Download Priority"), tr("Remaining"), tr("Availability") }))) { #if defined(Q_OS_WIN) m_fileIconProvider = new WinShellFileIconProvider(); @@ -332,25 +332,34 @@ QVariant TorrentContentModel::data(const QModelIndex &index, int role) const auto *item = static_cast(index.internalPointer()); - if ((index.column() == TorrentContentModelItem::COL_NAME) && (role == Qt::DecorationRole)) { - if (item->itemType() == TorrentContentModelItem::FolderType) - return m_fileIconProvider->icon(QFileIconProvider::Folder); + switch (role) { + case Qt::DecorationRole: { + if (index.column() != TorrentContentModelItem::COL_NAME) + return {}; - return m_fileIconProvider->icon(QFileInfo(item->name())); - } + if (item->itemType() == TorrentContentModelItem::FolderType) + return m_fileIconProvider->icon(QFileIconProvider::Folder); + return m_fileIconProvider->icon(QFileInfo(item->name())); + } + case Qt::CheckStateRole: { + if (index.column() != TorrentContentModelItem::COL_NAME) + return {}; - if ((index.column() == TorrentContentModelItem::COL_NAME) && (role == Qt::CheckStateRole)) { - if (item->data(TorrentContentModelItem::COL_PRIO).toInt() == static_cast(BitTorrent::DownloadPriority::Ignored)) - return Qt::Unchecked; - if (item->data(TorrentContentModelItem::COL_PRIO).toInt() == static_cast(BitTorrent::DownloadPriority::Mixed)) - return Qt::PartiallyChecked; - return Qt::Checked; - } + if (item->priority() == BitTorrent::DownloadPriority::Ignored) + return Qt::Unchecked; + if (item->priority() == BitTorrent::DownloadPriority::Mixed) + return Qt::PartiallyChecked; + return Qt::Checked; + } + case Qt::DisplayRole: + return item->displayData(index.column()); - if (role == Qt::DisplayRole) - return item->data(index.column()); + case Roles::UnderlyingDataRole: + return item->underlyingData(index.column()); - return {}; + default: + return {}; + } } Qt::ItemFlags TorrentContentModel::flags(const QModelIndex &index) const @@ -367,7 +376,7 @@ Qt::ItemFlags TorrentContentModel::flags(const QModelIndex &index) const QVariant TorrentContentModel::headerData(int section, Qt::Orientation orientation, int role) const { if ((orientation == Qt::Horizontal) && (role == Qt::DisplayRole)) - return m_rootItem->data(section); + return m_rootItem->displayData(section); return {}; } diff --git a/src/gui/torrentcontentmodel.h b/src/gui/torrentcontentmodel.h index 779f82a4e..90bf9ba8c 100644 --- a/src/gui/torrentcontentmodel.h +++ b/src/gui/torrentcontentmodel.h @@ -51,6 +51,11 @@ class TorrentContentModel final : public QAbstractItemModel Q_DISABLE_COPY(TorrentContentModel) public: + enum Roles + { + UnderlyingDataRole = Qt::UserRole + }; + TorrentContentModel(QObject *parent = nullptr); ~TorrentContentModel() override; diff --git a/src/gui/torrentcontentmodelfolder.cpp b/src/gui/torrentcontentmodelfolder.cpp index 5e0627a43..d20fa86d8 100644 --- a/src/gui/torrentcontentmodelfolder.cpp +++ b/src/gui/torrentcontentmodelfolder.cpp @@ -43,7 +43,7 @@ TorrentContentModelFolder::TorrentContentModelFolder(const QString &name, Torren m_name.chop(4); } -TorrentContentModelFolder::TorrentContentModelFolder(const QVector &data) +TorrentContentModelFolder::TorrentContentModelFolder(const QVector &data) : TorrentContentModelItem(nullptr) { Q_ASSERT(data.size() == NB_COL); diff --git a/src/gui/torrentcontentmodelfolder.h b/src/gui/torrentcontentmodelfolder.h index a99f89999..3654c21fd 100644 --- a/src/gui/torrentcontentmodelfolder.h +++ b/src/gui/torrentcontentmodelfolder.h @@ -43,7 +43,7 @@ public: TorrentContentModelFolder(const QString &name, TorrentContentModelFolder *parent); // Invisible root item constructor - explicit TorrentContentModelFolder(const QVector &data); + explicit TorrentContentModelFolder(const QVector &data); ~TorrentContentModelFolder() override; diff --git a/src/gui/torrentcontentmodelitem.cpp b/src/gui/torrentcontentmodelitem.cpp index 48a8828aa..ba5216f8e 100644 --- a/src/gui/torrentcontentmodelitem.cpp +++ b/src/gui/torrentcontentmodelitem.cpp @@ -30,6 +30,9 @@ #include +#include "base/unicodestrings.h" +#include "base/utils/misc.h" +#include "base/utils/string.h" #include "torrentcontentmodelfolder.h" TorrentContentModelItem::TorrentContentModelItem(TorrentContentModelFolder *parent) @@ -99,7 +102,55 @@ int TorrentContentModelItem::columnCount() const return NB_COL; } -QVariant TorrentContentModelItem::data(int column) const +QString TorrentContentModelItem::displayData(const int column) const +{ + if (isRootItem()) + return m_itemData.value(column); + + switch (column) { + case COL_NAME: + return m_name; + case COL_PRIO: { + switch (m_priority) { + case BitTorrent::DownloadPriority::Mixed: + return tr("Mixed", "Mixed (priorities"); + case BitTorrent::DownloadPriority::Ignored: + return tr("Not downloaded"); + case BitTorrent::DownloadPriority::High: + return tr("High", "High (priority)"); + case BitTorrent::DownloadPriority::Maximum: + return tr("Maximum", "Maximum (priority)"); + default: + return tr("Normal", "Normal (priority)"); + } + } + case COL_PROGRESS: { + const qreal progress = m_progress * 100; + return (static_cast(progress) == 100) + ? QString::fromLatin1("100%") + : (Utils::String::fromDouble(progress, 1) + QLatin1Char('%')); + } + case COL_SIZE: + return Utils::Misc::friendlyUnit(m_size); + case COL_REMAINING: + return Utils::Misc::friendlyUnit(remaining()); + case COL_AVAILABILITY: { + const int avail = availability(); + if (avail < 0) + return tr("N/A"); + + const QString value = (avail >= 1.0) + ? QString::fromLatin1("100") + : Utils::String::fromDouble((avail * 100), 1); + return QString {value + C_THIN_SPACE + QLatin1Char('%')}; + } + default: + Q_ASSERT(false); + return {}; + } +} + +QVariant TorrentContentModelItem::underlyingData(const int column) const { if (isRootItem()) return m_itemData.value(column); @@ -110,7 +161,7 @@ QVariant TorrentContentModelItem::data(int column) const case COL_PRIO: return static_cast(m_priority); case COL_PROGRESS: - return progress(); + return progress() * 100; case COL_SIZE: return m_size; case COL_REMAINING: diff --git a/src/gui/torrentcontentmodelitem.h b/src/gui/torrentcontentmodelitem.h index c0a532ce2..077f1b790 100644 --- a/src/gui/torrentcontentmodelitem.h +++ b/src/gui/torrentcontentmodelitem.h @@ -29,6 +29,7 @@ #ifndef TORRENTCONTENTMODELITEM_H #define TORRENTCONTENTMODELITEM_H +#include #include #include "base/bittorrent/downloadpriority.h" @@ -39,6 +40,8 @@ class TorrentContentModelFolder; class TorrentContentModelItem { + Q_DECLARE_TR_FUNCTIONS(TorrentContentModelItem); + public: enum TreeItemColumns { @@ -77,13 +80,14 @@ public: virtual void setPriority(BitTorrent::DownloadPriority newPriority, bool updateParent = true) = 0; int columnCount() const; - QVariant data(int column) const; + QString displayData(int column) const; + QVariant underlyingData(int column) const; int row() const; protected: TorrentContentModelFolder *m_parentItem; // Root item members - QVector m_itemData; + QVector m_itemData; // Non-root item members QString m_name; qulonglong m_size;