mirror of
https://github.com/d47081/qBittorrent.git
synced 2025-01-11 07:18:08 +00:00
Merge pull request #13632 from jagannatharjun/progress-style
Allow progress bar styling from custom themes
This commit is contained in:
commit
4209a5699a
@ -26,6 +26,7 @@ add_library(qbt_gui STATIC
|
|||||||
powermanagement/powermanagement.h
|
powermanagement/powermanagement.h
|
||||||
previewlistdelegate.h
|
previewlistdelegate.h
|
||||||
previewselectdialog.h
|
previewselectdialog.h
|
||||||
|
progressbardelegate.h
|
||||||
properties/downloadedpiecesbar.h
|
properties/downloadedpiecesbar.h
|
||||||
properties/peerlistsortmodel.h
|
properties/peerlistsortmodel.h
|
||||||
properties/peerlistwidget.h
|
properties/peerlistwidget.h
|
||||||
@ -105,6 +106,7 @@ add_library(qbt_gui STATIC
|
|||||||
powermanagement/powermanagement.cpp
|
powermanagement/powermanagement.cpp
|
||||||
previewlistdelegate.cpp
|
previewlistdelegate.cpp
|
||||||
previewselectdialog.cpp
|
previewselectdialog.cpp
|
||||||
|
progressbardelegate.cpp
|
||||||
properties/downloadedpiecesbar.cpp
|
properties/downloadedpiecesbar.cpp
|
||||||
properties/peerlistsortmodel.cpp
|
properties/peerlistsortmodel.cpp
|
||||||
properties/peerlistwidget.cpp
|
properties/peerlistwidget.cpp
|
||||||
|
@ -27,6 +27,7 @@ HEADERS += \
|
|||||||
$$PWD/powermanagement/powermanagement.h \
|
$$PWD/powermanagement/powermanagement.h \
|
||||||
$$PWD/previewlistdelegate.h \
|
$$PWD/previewlistdelegate.h \
|
||||||
$$PWD/previewselectdialog.h \
|
$$PWD/previewselectdialog.h \
|
||||||
|
$$PWD/progressbardelegate.h \
|
||||||
$$PWD/properties/downloadedpiecesbar.h \
|
$$PWD/properties/downloadedpiecesbar.h \
|
||||||
$$PWD/properties/peerlistsortmodel.h \
|
$$PWD/properties/peerlistsortmodel.h \
|
||||||
$$PWD/properties/peerlistwidget.h \
|
$$PWD/properties/peerlistwidget.h \
|
||||||
@ -106,6 +107,7 @@ SOURCES += \
|
|||||||
$$PWD/powermanagement/powermanagement.cpp \
|
$$PWD/powermanagement/powermanagement.cpp \
|
||||||
$$PWD/previewlistdelegate.cpp \
|
$$PWD/previewlistdelegate.cpp \
|
||||||
$$PWD/previewselectdialog.cpp \
|
$$PWD/previewselectdialog.cpp \
|
||||||
|
$$PWD/progressbardelegate.cpp \
|
||||||
$$PWD/properties/downloadedpiecesbar.cpp \
|
$$PWD/properties/downloadedpiecesbar.cpp \
|
||||||
$$PWD/properties/peerlistsortmodel.cpp \
|
$$PWD/properties/peerlistsortmodel.cpp \
|
||||||
$$PWD/properties/peerlistwidget.cpp \
|
$$PWD/properties/peerlistwidget.cpp \
|
||||||
|
73
src/gui/progressbardelegate.cpp
Normal file
73
src/gui/progressbardelegate.cpp
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
/*
|
||||||
|
* Bittorrent Client using Qt and libtorrent.
|
||||||
|
* Copyright (C) 2020 Prince Gupta <jagannatharjun11@gmail.com>
|
||||||
|
*
|
||||||
|
* 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 <QApplication>
|
||||||
|
#include <QModelIndex>
|
||||||
|
#include <QPainter>
|
||||||
|
#include <QStyleOptionViewItem>
|
||||||
|
|
||||||
|
#if (defined(Q_OS_WIN) || defined(Q_OS_MACOS))
|
||||||
|
#include <QProxyStyle>
|
||||||
|
#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<int>(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();
|
||||||
|
}
|
51
src/gui/progressbardelegate.h
Normal file
51
src/gui/progressbardelegate.h
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
/*
|
||||||
|
* Bittorrent Client using Qt and libtorrent.
|
||||||
|
* Copyright (C) 2020 Prince Gupta <jagannatharjun11@gmail.com>
|
||||||
|
*
|
||||||
|
* 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 <QProgressBar>
|
||||||
|
#include <QStyledItemDelegate>
|
||||||
|
|
||||||
|
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;
|
||||||
|
};
|
@ -42,9 +42,7 @@
|
|||||||
|
|
||||||
#include "base/bittorrent/downloadpriority.h"
|
#include "base/bittorrent/downloadpriority.h"
|
||||||
#include "base/bittorrent/torrenthandle.h"
|
#include "base/bittorrent/torrenthandle.h"
|
||||||
#include "base/unicodestrings.h"
|
#include "gui/torrentcontentmodel.h"
|
||||||
#include "base/utils/misc.h"
|
|
||||||
#include "base/utils/string.h"
|
|
||||||
#include "propertieswidget.h"
|
#include "propertieswidget.h"
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
@ -64,107 +62,31 @@ namespace
|
|||||||
}
|
}
|
||||||
|
|
||||||
PropListDelegate::PropListDelegate(PropertiesWidget *properties)
|
PropListDelegate::PropListDelegate(PropertiesWidget *properties)
|
||||||
: QStyledItemDelegate(properties)
|
: ProgressBarDelegate {PROGRESS, TorrentContentModel::UnderlyingDataRole, properties}
|
||||||
, m_properties(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();
|
ProgressBarDelegate::initProgressStyleOption(option, index);
|
||||||
|
const int priority
|
||||||
const QStyle *style = option.widget ? option.widget->style() : QApplication::style();
|
= index.sibling(index.row(), PRIORITY).data(TorrentContentModel::UnderlyingDataRole).toInt();
|
||||||
QStyleOptionViewItem opt = option;
|
if (static_cast<BitTorrent::DownloadPriority>(priority) == BitTorrent::DownloadPriority::Ignored) {
|
||||||
QStyledItemDelegate::initStyleOption(&opt, index);
|
option.state &= ~QStyle::State_Enabled;
|
||||||
|
option.palette = progressBarDisabledPalette();
|
||||||
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<int>(progress);
|
|
||||||
newopt.maximum = 100;
|
|
||||||
newopt.minimum = 0;
|
|
||||||
newopt.textVisible = true;
|
|
||||||
if (index.sibling(index.row(), PRIORITY).data().toInt() == static_cast<int>(BitTorrent::DownloadPriority::Ignored)) {
|
|
||||||
newopt.state &= ~QStyle::State_Enabled;
|
|
||||||
newopt.palette = progressBarDisabledPalette();
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
newopt.state |= QStyle::State_Enabled;
|
option.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<BitTorrent::DownloadPriority>(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;
|
|
||||||
}
|
|
||||||
|
|
||||||
painter->restore();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void PropListDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const
|
void PropListDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const
|
||||||
{
|
{
|
||||||
auto *combobox = static_cast<QComboBox *>(editor);
|
auto *combobox = static_cast<QComboBox *>(editor);
|
||||||
// Set combobox index
|
// Set combobox index
|
||||||
switch (static_cast<BitTorrent::DownloadPriority>(index.data().toInt())) {
|
const int priority = index.data(TorrentContentModel::UnderlyingDataRole).toInt();
|
||||||
|
switch (static_cast<BitTorrent::DownloadPriority>(priority)) {
|
||||||
case BitTorrent::DownloadPriority::Ignored:
|
case BitTorrent::DownloadPriority::Ignored:
|
||||||
combobox->setCurrentIndex(0);
|
combobox->setCurrentIndex(0);
|
||||||
break;
|
break;
|
||||||
@ -190,7 +112,8 @@ QWidget *PropListDelegate::createEditor(QWidget *parent, const QStyleOptionViewI
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (index.data().toInt() == static_cast<int>(BitTorrent::DownloadPriority::Mixed))
|
const int priority = index.data(TorrentContentModel::UnderlyingDataRole).toInt();
|
||||||
|
if (static_cast<BitTorrent::DownloadPriority>(priority) == BitTorrent::DownloadPriority::Mixed)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
auto *editor = new QComboBox(parent);
|
auto *editor = new QComboBox(parent);
|
||||||
|
@ -29,7 +29,7 @@
|
|||||||
#ifndef PROPLISTDELEGATE_H
|
#ifndef PROPLISTDELEGATE_H
|
||||||
#define PROPLISTDELEGATE_H
|
#define PROPLISTDELEGATE_H
|
||||||
|
|
||||||
#include <QStyledItemDelegate>
|
#include "gui/progressbardelegate.h"
|
||||||
|
|
||||||
class QAbstractItemModel;
|
class QAbstractItemModel;
|
||||||
class QModelIndex;
|
class QModelIndex;
|
||||||
@ -49,14 +49,13 @@ enum PropColumn
|
|||||||
AVAILABILITY
|
AVAILABILITY
|
||||||
};
|
};
|
||||||
|
|
||||||
class PropListDelegate final : public QStyledItemDelegate
|
class PropListDelegate final : public ProgressBarDelegate
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit PropListDelegate(PropertiesWidget *properties);
|
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;
|
void setEditorData(QWidget *editor, const QModelIndex &index) const override;
|
||||||
QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem & /* option */, 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;
|
void filteredFilesChanged() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
void initProgressStyleOption(QStyleOptionProgressBar &option, const QModelIndex &index) const override;
|
||||||
|
|
||||||
PropertiesWidget *m_properties;
|
PropertiesWidget *m_properties;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -39,7 +39,7 @@ TorrentContentFilterModel::TorrentContentFilterModel(QObject *parent)
|
|||||||
setSourceModel(m_model);
|
setSourceModel(m_model);
|
||||||
// Filter settings
|
// Filter settings
|
||||||
setFilterKeyColumn(TorrentContentModelItem::COL_NAME);
|
setFilterKeyColumn(TorrentContentModelItem::COL_NAME);
|
||||||
setFilterRole(Qt::DisplayRole);
|
setFilterRole(TorrentContentModel::UnderlyingDataRole);
|
||||||
setDynamicSortFilter(true);
|
setDynamicSortFilter(true);
|
||||||
setSortCaseSensitivity(Qt::CaseInsensitive);
|
setSortCaseSensitivity(Qt::CaseInsensitive);
|
||||||
}
|
}
|
||||||
|
@ -180,7 +180,7 @@ namespace
|
|||||||
|
|
||||||
TorrentContentModel::TorrentContentModel(QObject *parent)
|
TorrentContentModel::TorrentContentModel(QObject *parent)
|
||||||
: QAbstractItemModel(parent)
|
: QAbstractItemModel(parent)
|
||||||
, m_rootItem(new TorrentContentModelFolder(QVector<QVariant>({ tr("Name"), tr("Size"), tr("Progress"), tr("Download Priority"), tr("Remaining"), tr("Availability") })))
|
, m_rootItem(new TorrentContentModelFolder(QVector<QString>({ tr("Name"), tr("Size"), tr("Progress"), tr("Download Priority"), tr("Remaining"), tr("Availability") })))
|
||||||
{
|
{
|
||||||
#if defined(Q_OS_WIN)
|
#if defined(Q_OS_WIN)
|
||||||
m_fileIconProvider = new WinShellFileIconProvider();
|
m_fileIconProvider = new WinShellFileIconProvider();
|
||||||
@ -332,26 +332,35 @@ QVariant TorrentContentModel::data(const QModelIndex &index, int role) const
|
|||||||
|
|
||||||
auto *item = static_cast<TorrentContentModelItem*>(index.internalPointer());
|
auto *item = static_cast<TorrentContentModelItem*>(index.internalPointer());
|
||||||
|
|
||||||
if ((index.column() == TorrentContentModelItem::COL_NAME) && (role == Qt::DecorationRole)) {
|
switch (role) {
|
||||||
|
case Qt::DecorationRole: {
|
||||||
|
if (index.column() != TorrentContentModelItem::COL_NAME)
|
||||||
|
return {};
|
||||||
|
|
||||||
if (item->itemType() == TorrentContentModelItem::FolderType)
|
if (item->itemType() == TorrentContentModelItem::FolderType)
|
||||||
return m_fileIconProvider->icon(QFileIconProvider::Folder);
|
return m_fileIconProvider->icon(QFileIconProvider::Folder);
|
||||||
|
|
||||||
return m_fileIconProvider->icon(QFileInfo(item->name()));
|
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->priority() == BitTorrent::DownloadPriority::Ignored)
|
||||||
if (item->data(TorrentContentModelItem::COL_PRIO).toInt() == static_cast<int>(BitTorrent::DownloadPriority::Ignored))
|
|
||||||
return Qt::Unchecked;
|
return Qt::Unchecked;
|
||||||
if (item->data(TorrentContentModelItem::COL_PRIO).toInt() == static_cast<int>(BitTorrent::DownloadPriority::Mixed))
|
if (item->priority() == BitTorrent::DownloadPriority::Mixed)
|
||||||
return Qt::PartiallyChecked;
|
return Qt::PartiallyChecked;
|
||||||
return Qt::Checked;
|
return Qt::Checked;
|
||||||
}
|
}
|
||||||
|
case Qt::DisplayRole:
|
||||||
|
return item->displayData(index.column());
|
||||||
|
|
||||||
if (role == Qt::DisplayRole)
|
case Roles::UnderlyingDataRole:
|
||||||
return item->data(index.column());
|
return item->underlyingData(index.column());
|
||||||
|
|
||||||
|
default:
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Qt::ItemFlags TorrentContentModel::flags(const QModelIndex &index) const
|
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
|
QVariant TorrentContentModel::headerData(int section, Qt::Orientation orientation, int role) const
|
||||||
{
|
{
|
||||||
if ((orientation == Qt::Horizontal) && (role == Qt::DisplayRole))
|
if ((orientation == Qt::Horizontal) && (role == Qt::DisplayRole))
|
||||||
return m_rootItem->data(section);
|
return m_rootItem->displayData(section);
|
||||||
|
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
@ -51,6 +51,11 @@ class TorrentContentModel final : public QAbstractItemModel
|
|||||||
Q_DISABLE_COPY(TorrentContentModel)
|
Q_DISABLE_COPY(TorrentContentModel)
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
enum Roles
|
||||||
|
{
|
||||||
|
UnderlyingDataRole = Qt::UserRole
|
||||||
|
};
|
||||||
|
|
||||||
TorrentContentModel(QObject *parent = nullptr);
|
TorrentContentModel(QObject *parent = nullptr);
|
||||||
~TorrentContentModel() override;
|
~TorrentContentModel() override;
|
||||||
|
|
||||||
|
@ -43,7 +43,7 @@ TorrentContentModelFolder::TorrentContentModelFolder(const QString &name, Torren
|
|||||||
m_name.chop(4);
|
m_name.chop(4);
|
||||||
}
|
}
|
||||||
|
|
||||||
TorrentContentModelFolder::TorrentContentModelFolder(const QVector<QVariant> &data)
|
TorrentContentModelFolder::TorrentContentModelFolder(const QVector<QString> &data)
|
||||||
: TorrentContentModelItem(nullptr)
|
: TorrentContentModelItem(nullptr)
|
||||||
{
|
{
|
||||||
Q_ASSERT(data.size() == NB_COL);
|
Q_ASSERT(data.size() == NB_COL);
|
||||||
|
@ -43,7 +43,7 @@ public:
|
|||||||
TorrentContentModelFolder(const QString &name, TorrentContentModelFolder *parent);
|
TorrentContentModelFolder(const QString &name, TorrentContentModelFolder *parent);
|
||||||
|
|
||||||
// Invisible root item constructor
|
// Invisible root item constructor
|
||||||
explicit TorrentContentModelFolder(const QVector<QVariant> &data);
|
explicit TorrentContentModelFolder(const QVector<QString> &data);
|
||||||
|
|
||||||
~TorrentContentModelFolder() override;
|
~TorrentContentModelFolder() override;
|
||||||
|
|
||||||
|
@ -30,6 +30,9 @@
|
|||||||
|
|
||||||
#include <QVariant>
|
#include <QVariant>
|
||||||
|
|
||||||
|
#include "base/unicodestrings.h"
|
||||||
|
#include "base/utils/misc.h"
|
||||||
|
#include "base/utils/string.h"
|
||||||
#include "torrentcontentmodelfolder.h"
|
#include "torrentcontentmodelfolder.h"
|
||||||
|
|
||||||
TorrentContentModelItem::TorrentContentModelItem(TorrentContentModelFolder *parent)
|
TorrentContentModelItem::TorrentContentModelItem(TorrentContentModelFolder *parent)
|
||||||
@ -99,7 +102,55 @@ int TorrentContentModelItem::columnCount() const
|
|||||||
return NB_COL;
|
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<int>(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())
|
if (isRootItem())
|
||||||
return m_itemData.value(column);
|
return m_itemData.value(column);
|
||||||
@ -110,7 +161,7 @@ QVariant TorrentContentModelItem::data(int column) const
|
|||||||
case COL_PRIO:
|
case COL_PRIO:
|
||||||
return static_cast<int>(m_priority);
|
return static_cast<int>(m_priority);
|
||||||
case COL_PROGRESS:
|
case COL_PROGRESS:
|
||||||
return progress();
|
return progress() * 100;
|
||||||
case COL_SIZE:
|
case COL_SIZE:
|
||||||
return m_size;
|
return m_size;
|
||||||
case COL_REMAINING:
|
case COL_REMAINING:
|
||||||
|
@ -29,6 +29,7 @@
|
|||||||
#ifndef TORRENTCONTENTMODELITEM_H
|
#ifndef TORRENTCONTENTMODELITEM_H
|
||||||
#define TORRENTCONTENTMODELITEM_H
|
#define TORRENTCONTENTMODELITEM_H
|
||||||
|
|
||||||
|
#include <QCoreApplication>
|
||||||
#include <QVector>
|
#include <QVector>
|
||||||
|
|
||||||
#include "base/bittorrent/downloadpriority.h"
|
#include "base/bittorrent/downloadpriority.h"
|
||||||
@ -39,6 +40,8 @@ class TorrentContentModelFolder;
|
|||||||
|
|
||||||
class TorrentContentModelItem
|
class TorrentContentModelItem
|
||||||
{
|
{
|
||||||
|
Q_DECLARE_TR_FUNCTIONS(TorrentContentModelItem);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
enum TreeItemColumns
|
enum TreeItemColumns
|
||||||
{
|
{
|
||||||
@ -77,13 +80,14 @@ public:
|
|||||||
virtual void setPriority(BitTorrent::DownloadPriority newPriority, bool updateParent = true) = 0;
|
virtual void setPriority(BitTorrent::DownloadPriority newPriority, bool updateParent = true) = 0;
|
||||||
|
|
||||||
int columnCount() const;
|
int columnCount() const;
|
||||||
QVariant data(int column) const;
|
QString displayData(int column) const;
|
||||||
|
QVariant underlyingData(int column) const;
|
||||||
int row() const;
|
int row() const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
TorrentContentModelFolder *m_parentItem;
|
TorrentContentModelFolder *m_parentItem;
|
||||||
// Root item members
|
// Root item members
|
||||||
QVector<QVariant> m_itemData;
|
QVector<QString> m_itemData;
|
||||||
// Non-root item members
|
// Non-root item members
|
||||||
QString m_name;
|
QString m_name;
|
||||||
qulonglong m_size;
|
qulonglong m_size;
|
||||||
|
@ -28,52 +28,15 @@
|
|||||||
|
|
||||||
#include "transferlistdelegate.h"
|
#include "transferlistdelegate.h"
|
||||||
|
|
||||||
#include <QApplication>
|
|
||||||
#include <QModelIndex>
|
#include <QModelIndex>
|
||||||
#include <QPainter>
|
|
||||||
#include <QStyleOptionViewItem>
|
|
||||||
|
|
||||||
#if defined(Q_OS_WIN) || defined(Q_OS_MACOS)
|
|
||||||
#include <QProxyStyle>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "base/utils/string.h"
|
|
||||||
#include "transferlistmodel.h"
|
#include "transferlistmodel.h"
|
||||||
|
|
||||||
TransferListDelegate::TransferListDelegate(QObject *parent)
|
TransferListDelegate::TransferListDelegate(QObject *parent)
|
||||||
: QStyledItemDelegate {parent}
|
: ProgressBarDelegate {TransferListModel::TR_PROGRESS, TransferListModel::UnderlyingDataRole, parent}
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void TransferListDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
|
|
||||||
{
|
|
||||||
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<int>(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
|
QWidget *TransferListDelegate::createEditor(QWidget *, const QStyleOptionViewItem &, const QModelIndex &) const
|
||||||
{
|
{
|
||||||
// No editor here
|
// No editor here
|
||||||
|
@ -28,13 +28,9 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <QStyledItemDelegate>
|
#include "progressbardelegate.h"
|
||||||
|
|
||||||
class QModelIndex;
|
class TransferListDelegate final : public ProgressBarDelegate
|
||||||
class QPainter;
|
|
||||||
class QStyleOptionViewItem;
|
|
||||||
|
|
||||||
class TransferListDelegate final : public QStyledItemDelegate
|
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
Q_DISABLE_COPY(TransferListDelegate)
|
Q_DISABLE_COPY(TransferListDelegate)
|
||||||
@ -42,7 +38,6 @@ class TransferListDelegate final : public QStyledItemDelegate
|
|||||||
public:
|
public:
|
||||||
explicit TransferListDelegate(QObject *parent);
|
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;
|
QWidget *createEditor(QWidget *, const QStyleOptionViewItem &, const QModelIndex &) const override;
|
||||||
QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const override;
|
QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const override;
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user