1
0
mirror of https://github.com/d47081/qBittorrent.git synced 2025-02-02 09:55:55 +00:00

Merge pull request #17116 from Chocobo1/cleanup

Clean up usage of `static` keyword
This commit is contained in:
Chocobo1 2022-05-31 12:39:30 +08:00 committed by GitHub
commit 9cd993d1da
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
19 changed files with 185 additions and 240 deletions

View File

@ -43,7 +43,6 @@
#include <sys/resource.h> #include <sys/resource.h>
#endif #endif
#include <QAtomicInt>
#include <QByteArray> #include <QByteArray>
#include <QDebug> #include <QDebug>
#include <QLibraryInfo> #include <QLibraryInfo>
@ -808,8 +807,7 @@ void Application::applyMemoryWorkingSetLimit()
void Application::cleanup() void Application::cleanup()
{ {
// cleanup() can be called multiple times during shutdown. We only need it once. // cleanup() can be called multiple times during shutdown. We only need it once.
static QAtomicInt alreadyDone; if (!m_isCleanupRun.testAndSetAcquire(0, 1))
if (!alreadyDone.testAndSetAcquire(0, 1))
return; return;
#ifndef DISABLE_GUI #ifndef DISABLE_GUI

View File

@ -31,6 +31,7 @@
#pragma once #pragma once
#include <QtGlobal> #include <QtGlobal>
#include <QAtomicInt>
#include <QCoreApplication> #include <QCoreApplication>
#include <QPointer> #include <QPointer>
#include <QStringList> #include <QStringList>
@ -145,6 +146,7 @@ private:
ApplicationInstanceManager *m_instanceManager = nullptr; ApplicationInstanceManager *m_instanceManager = nullptr;
bool m_running = false; bool m_running = false;
QAtomicInt m_isCleanupRun;
ShutdownDialogAction m_shutdownAct; ShutdownDialogAction m_shutdownAct;
QBtCommandLineParameters m_commandLineArgs; QBtCommandLineParameters m_commandLineArgs;

View File

@ -76,8 +76,8 @@ namespace
{ {
const size_t strLen = strlen(str); const size_t strLen = strlen(str);
#ifdef Q_OS_WIN #ifdef Q_OS_WIN
if (_write(_fileno(stderr), str, strLen) < static_cast<int>(strLen)) if (_write(_fileno(stderr), str, static_cast<unsigned int>(strLen)) < static_cast<int>(strLen))
std::ignore = _write(_fileno(stdout), str, strLen); std::ignore = _write(_fileno(stdout), str, static_cast<unsigned int>(strLen));
#else #else
if (write(STDERR_FILENO, str, strLen) < static_cast<ssize_t>(strLen)) if (write(STDERR_FILENO, str, strLen) < static_cast<ssize_t>(strLen))
std::ignore = write(STDOUT_FILENO, str, strLen); std::ignore = write(STDOUT_FILENO, str, strLen);

View File

@ -635,7 +635,7 @@ Path Session::downloadPath() const
bool Session::isValidCategoryName(const QString &name) bool Session::isValidCategoryName(const QString &name)
{ {
static const QRegularExpression re(uR"(^([^\\\/]|[^\\\/]([^\\\/]|\/(?=[^\/]))*[^\\\/])$)"_qs); const QRegularExpression re(uR"(^([^\\\/]|[^\\\/]([^\\\/]|\/(?=[^\/]))*[^\\\/])$)"_qs);
if (!name.isEmpty() && (name.indexOf(re) != 0)) if (!name.isEmpty() && (name.indexOf(re) != 0))
{ {
qDebug() << "Incorrect category name:" << name; qDebug() << "Incorrect category name:" << name;

View File

@ -35,7 +35,7 @@
#include "base/bittorrent/sessionstatus.h" #include "base/bittorrent/sessionstatus.h"
#include "base/profile.h" #include "base/profile.h"
static const qint64 SAVE_INTERVAL = 15 * 60 * 1000; const qint64 SAVE_INTERVAL = 15 * 60 * 1000;
using namespace BitTorrent; using namespace BitTorrent;

View File

@ -68,7 +68,7 @@ QString Item::name() const
bool Item::isValidPath(const QString &path) bool Item::isValidPath(const QString &path)
{ {
static const QRegularExpression re( const QRegularExpression re(
uR"(\A[^\%1]+(\%1[^\%1]+)*\z)"_qs.arg(Item::PathSeparator) uR"(\A[^\%1]+(\%1[^\%1]+)*\z)"_qs.arg(Item::PathSeparator)
, QRegularExpression::DontCaptureOption); , QRegularExpression::DontCaptureOption);

View File

@ -31,6 +31,14 @@
#include "settingvalue.h" #include "settingvalue.h"
#include "utils/fs.h" #include "utils/fs.h"
namespace
{
SettingValue<TorrentFileGuard::AutoDeleteMode> autoDeleteModeSetting()
{
return SettingValue<TorrentFileGuard::AutoDeleteMode> {u"Core/AutoDeleteAddedTorrentFile"_qs};
}
}
FileGuard::FileGuard(const Path &path) FileGuard::FileGuard(const Path &path)
: m_path {path} : m_path {path}
, m_remove {true} , m_remove {true}
@ -76,13 +84,7 @@ TorrentFileGuard::AutoDeleteMode TorrentFileGuard::autoDeleteMode()
return autoDeleteModeSetting().get(AutoDeleteMode::Never); return autoDeleteModeSetting().get(AutoDeleteMode::Never);
} }
void TorrentFileGuard::setAutoDeleteMode(TorrentFileGuard::AutoDeleteMode mode) void TorrentFileGuard::setAutoDeleteMode(const TorrentFileGuard::AutoDeleteMode mode)
{ {
autoDeleteModeSetting() = mode; autoDeleteModeSetting() = mode;
} }
SettingValue<TorrentFileGuard::AutoDeleteMode> &TorrentFileGuard::autoDeleteModeSetting()
{
static SettingValue<AutoDeleteMode> setting {u"Core/AutoDeleteAddedTorrentFile"_qs};
return setting;
}

View File

@ -33,8 +33,6 @@
#include "base/path.h" #include "base/path.h"
template <typename T> class SettingValue;
/// Utility class to defer file deletion /// Utility class to defer file deletion
class FileGuard class FileGuard
{ {
@ -47,7 +45,7 @@ public:
private: private:
Path m_path; Path m_path;
bool m_remove; bool m_remove = false;
}; };
/// Reads settings for .torrent files from preferences /// Reads settings for .torrent files from preferences
@ -64,7 +62,7 @@ public:
void markAsAddedToSession(); void markAsAddedToSession();
using FileGuard::setAutoRemove; using FileGuard::setAutoRemove;
enum AutoDeleteMode: int // do not change these names: they are stored in config file enum AutoDeleteMode : int // do not change these names: they are stored in config file
{ {
Never, Never,
IfAdded, IfAdded,
@ -77,9 +75,8 @@ public:
private: private:
TorrentFileGuard(const Path &path, AutoDeleteMode mode); TorrentFileGuard(const Path &path, AutoDeleteMode mode);
static SettingValue<AutoDeleteMode> &autoDeleteModeSetting();
Q_ENUM(AutoDeleteMode) Q_ENUM(AutoDeleteMode)
AutoDeleteMode m_mode; AutoDeleteMode m_mode;
bool m_wasAdded; bool m_wasAdded = false;
}; };

View File

@ -457,7 +457,7 @@ QString Utils::Misc::parseHtmlLinks(const QString &rawText)
result.replace(reURL, u"\\1<a href=\"\\2\">\\2</a>"_qs); result.replace(reURL, u"\\1<a href=\"\\2\">\\2</a>"_qs);
// Capture links without scheme // Capture links without scheme
static const QRegularExpression reNoScheme(u"<a\\s+href=\"(?!https?)([a-zA-Z0-9\\?%=&/_\\.-:#]+)\\s*\">"_qs); const QRegularExpression reNoScheme(u"<a\\s+href=\"(?!https?)([a-zA-Z0-9\\?%=&/_\\.-:#]+)\\s*\">"_qs);
result.replace(reNoScheme, u"<a href=\"http://\\1\">"_qs); result.replace(reNoScheme, u"<a href=\"http://\\1\">"_qs);
// to preserve plain text formatting // to preserve plain text formatting
@ -500,7 +500,7 @@ QString Utils::Misc::opensslVersionString()
#else #else
static const auto version {QString::fromLatin1(SSLeay_version(SSLEAY_VERSION))}; static const auto version {QString::fromLatin1(SSLeay_version(SSLEAY_VERSION))};
#endif #endif
return QStringView(version).split(u' ', Qt::SkipEmptyParts).at(1).toString(); return version.section(u' ', 1, 1);
} }
QString Utils::Misc::zlibVersionString() QString Utils::Misc::zlibVersionString()

View File

@ -121,6 +121,21 @@ namespace
|| (!str.startsWith(u"file:", Qt::CaseInsensitive) || (!str.startsWith(u"file:", Qt::CaseInsensitive)
&& Net::DownloadManager::hasSupportedScheme(str)); && Net::DownloadManager::hasSupportedScheme(str));
} }
#ifdef Q_OS_MACOS
MainWindow *dockMainWindowHandle = nullptr;
bool dockClickHandler(id self, SEL cmd, ...)
{
Q_UNUSED(self)
Q_UNUSED(cmd)
if (dockMainWindowHandle && !dockMainWindowHandle->isVisible())
dockMainWindowHandle->activate();
return true;
}
#endif
} }
MainWindow::MainWindow(QWidget *parent) MainWindow::MainWindow(QWidget *parent)
@ -1388,28 +1403,11 @@ void MainWindow::dragEnterEvent(QDragEnterEvent *event)
} }
#ifdef Q_OS_MACOS #ifdef Q_OS_MACOS
static MainWindow *dockMainWindowHandle;
static bool dockClickHandler(id self, SEL cmd, ...)
{
Q_UNUSED(self)
Q_UNUSED(cmd)
if (dockMainWindowHandle && !dockMainWindowHandle->isVisible())
{
dockMainWindowHandle->activate();
}
return true;
}
void MainWindow::setupDockClickHandler() void MainWindow::setupDockClickHandler()
{ {
dockMainWindowHandle = this; dockMainWindowHandle = this;
MacUtils::overrideDockClickHandler(dockClickHandler); MacUtils::overrideDockClickHandler(dockClickHandler);
} }
#endif // Q_OS_MACOS #endif // Q_OS_MACOS
/***************************************************** /*****************************************************

View File

@ -44,7 +44,6 @@
#include "base/search/searchdownloadhandler.h" #include "base/search/searchdownloadhandler.h"
#include "base/search/searchhandler.h" #include "base/search/searchhandler.h"
#include "base/search/searchpluginmanager.h" #include "base/search/searchpluginmanager.h"
#include "base/settingvalue.h"
#include "base/utils/misc.h" #include "base/utils/misc.h"
#include "gui/addnewtorrentdialog.h" #include "gui/addnewtorrentdialog.h"
#include "gui/lineedit.h" #include "gui/lineedit.h"
@ -57,6 +56,7 @@ SearchJobWidget::SearchJobWidget(SearchHandler *searchHandler, QWidget *parent)
: QWidget(parent) : QWidget(parent)
, m_ui(new Ui::SearchJobWidget) , m_ui(new Ui::SearchJobWidget)
, m_searchHandler(searchHandler) , m_searchHandler(searchHandler)
, m_nameFilteringMode(u"Search/FilteringMode"_qs)
{ {
m_ui->setupUi(this); m_ui->setupUi(this);
@ -319,7 +319,7 @@ void SearchJobWidget::updateFilter()
sizeInBytes(m_ui->minSize->value(), static_cast<SizeUnit>(m_ui->minSizeUnit->currentIndex())), sizeInBytes(m_ui->minSize->value(), static_cast<SizeUnit>(m_ui->minSizeUnit->currentIndex())),
sizeInBytes(m_ui->maxSize->value(), static_cast<SizeUnit>(m_ui->maxSizeUnit->currentIndex()))); sizeInBytes(m_ui->maxSize->value(), static_cast<SizeUnit>(m_ui->maxSizeUnit->currentIndex())));
nameFilteringModeSetting() = filteringMode(); m_nameFilteringMode = filteringMode();
m_proxyModel->invalidate(); m_proxyModel->invalidate();
updateResultsCount(); updateResultsCount();
@ -355,8 +355,8 @@ void SearchJobWidget::fillFilterComboBoxes()
m_ui->filterMode->addItem(tr("Torrent names only"), static_cast<int>(NameFilteringMode::OnlyNames)); m_ui->filterMode->addItem(tr("Torrent names only"), static_cast<int>(NameFilteringMode::OnlyNames));
m_ui->filterMode->addItem(tr("Everywhere"), static_cast<int>(NameFilteringMode::Everywhere)); m_ui->filterMode->addItem(tr("Everywhere"), static_cast<int>(NameFilteringMode::Everywhere));
QVariant selectedMode = static_cast<int>(nameFilteringModeSetting().get(NameFilteringMode::OnlyNames)); const QVariant selectedMode = static_cast<int>(m_nameFilteringMode.get(NameFilteringMode::OnlyNames));
int index = m_ui->filterMode->findData(selectedMode); const int index = m_ui->filterMode->findData(selectedMode);
m_ui->filterMode->setCurrentIndex((index == -1) ? 0 : index); m_ui->filterMode->setCurrentIndex((index == -1) ? 0 : index);
} }
@ -545,12 +545,6 @@ void SearchJobWidget::appendSearchResults(const QVector<SearchResult> &results)
updateResultsCount(); updateResultsCount();
} }
SettingValue<SearchJobWidget::NameFilteringMode> &SearchJobWidget::nameFilteringModeSetting()
{
static SettingValue<NameFilteringMode> setting {u"Search/FilteringMode"_qs};
return setting;
}
void SearchJobWidget::keyPressEvent(QKeyEvent *event) void SearchJobWidget::keyPressEvent(QKeyEvent *event)
{ {
switch (event->key()) switch (event->key())

View File

@ -31,6 +31,8 @@
#include <QWidget> #include <QWidget>
#include "base/settingvalue.h"
#define ENGINE_URL_COLUMN 4 #define ENGINE_URL_COLUMN 4
#define URL_COLUMN 5 #define URL_COLUMN 5
@ -127,7 +129,6 @@ private:
void copyField(int column) const; void copyField(int column) const;
static QString statusText(Status st); static QString statusText(Status st);
static SettingValue<NameFilteringMode> &nameFilteringModeSetting();
Ui::SearchJobWidget *m_ui; Ui::SearchJobWidget *m_ui;
SearchHandler *m_searchHandler; SearchHandler *m_searchHandler;
@ -136,6 +137,8 @@ private:
LineEdit *m_lineEditSearchResultsFilter; LineEdit *m_lineEditSearchResultsFilter;
Status m_status = Status::Ongoing; Status m_status = Status::Ongoing;
bool m_noSearchResults = true; bool m_noSearchResults = true;
SettingValue<NameFilteringMode> m_nameFilteringMode;
}; };
Q_DECLARE_METATYPE(SearchJobWidget::NameFilteringMode) Q_DECLARE_METATYPE(SearchJobWidget::NameFilteringMode)

View File

@ -69,14 +69,20 @@ namespace
class UnifiedFileIconProvider : public QFileIconProvider class UnifiedFileIconProvider : public QFileIconProvider
{ {
public: public:
UnifiedFileIconProvider()
: m_textPlainIcon {UIThemeManager::instance()->getIcon(u"text-plain"_qs)}
{
}
using QFileIconProvider::icon; using QFileIconProvider::icon;
QIcon icon(const QFileInfo &info) const override QIcon icon(const QFileInfo &) const override
{ {
Q_UNUSED(info); return m_textPlainIcon;
static QIcon cached = UIThemeManager::instance()->getIcon(u"text-plain"_qs);
return cached;
} }
private:
QIcon m_textPlainIcon;
}; };
#ifdef QBT_PIXMAP_CACHE_FOR_FILE_ICONS #ifdef QBT_PIXMAP_CACHE_FOR_FILE_ICONS
@ -91,7 +97,8 @@ namespace
if (!ext.isEmpty()) if (!ext.isEmpty())
{ {
QPixmap cached; QPixmap cached;
if (QPixmapCache::find(ext, &cached)) return {cached}; if (QPixmapCache::find(ext, &cached))
return {cached};
const QPixmap pixmap = pixmapForExtension(ext); const QPixmap pixmap = pixmapForExtension(ext);
if (!pixmap.isNull()) if (!pixmap.isNull())
@ -115,16 +122,17 @@ namespace
QPixmap pixmapForExtension(const QString &ext) const override QPixmap pixmapForExtension(const QString &ext) const override
{ {
const std::wstring extWStr = QString(u'.' + ext).toStdWString(); const std::wstring extWStr = QString(u'.' + ext).toStdWString();
SHFILEINFO sfi {};
HRESULT hr = ::SHGetFileInfoW(extWStr.c_str(), SHFILEINFOW sfi {};
FILE_ATTRIBUTE_NORMAL, &sfi, sizeof(sfi), SHGFI_ICON | SHGFI_USEFILEATTRIBUTES); const HRESULT hr = ::SHGetFileInfoW(extWStr.c_str(),
FILE_ATTRIBUTE_NORMAL, &sfi, sizeof(sfi), (SHGFI_ICON | SHGFI_USEFILEATTRIBUTES));
if (FAILED(hr)) if (FAILED(hr))
return {}; return {};
#if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)) #if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0))
auto iconPixmap = QPixmap::fromImage(QImage::fromHICON(sfi.hIcon)); const auto iconPixmap = QPixmap::fromImage(QImage::fromHICON(sfi.hIcon));
#else #else
QPixmap iconPixmap = QtWin::fromHICON(sfi.hIcon); const QPixmap iconPixmap = QtWin::fromHICON(sfi.hIcon);
#endif #endif
::DestroyIcon(sfi.hIcon); ::DestroyIcon(sfi.hIcon);
return iconPixmap; return iconPixmap;
@ -158,30 +166,24 @@ namespace
return (!testIcon1.isNull() || !testIcon2.isNull()); return (!testIcon1.isNull() || !testIcon2.isNull());
} }
class MimeFileIconProvider : public UnifiedFileIconProvider class MimeFileIconProvider final : public UnifiedFileIconProvider
{ {
using QFileIconProvider::icon; using QFileIconProvider::icon;
QIcon icon(const QFileInfo &info) const override QIcon icon(const QFileInfo &info) const override
{ {
const QMimeType mimeType = m_db.mimeTypeForFile(info, QMimeDatabase::MatchExtension); const QMimeType mimeType = QMimeDatabase().mimeTypeForFile(info, QMimeDatabase::MatchExtension);
QIcon res = QIcon::fromTheme(mimeType.iconName());
if (!res.isNull())
{
return res;
}
res = QIcon::fromTheme(mimeType.genericIconName()); const auto mimeIcon = QIcon::fromTheme(mimeType.iconName());
if (!res.isNull()) if (!mimeIcon.isNull())
{ return mimeIcon;
return res;
} const auto genericIcon = QIcon::fromTheme(mimeType.genericIconName());
if (!genericIcon.isNull())
return genericIcon;
return UnifiedFileIconProvider::icon(info); return UnifiedFileIconProvider::icon(info);
} }
private:
QMimeDatabase m_db;
}; };
#endif // Q_OS_WIN #endif // Q_OS_WIN
} }
@ -189,15 +191,14 @@ namespace
TorrentContentModel::TorrentContentModel(QObject *parent) TorrentContentModel::TorrentContentModel(QObject *parent)
: QAbstractItemModel(parent) : QAbstractItemModel(parent)
, m_rootItem(new TorrentContentModelFolder(QVector<QString>({ tr("Name"), tr("Total Size"), tr("Progress"), tr("Download Priority"), tr("Remaining"), tr("Availability") }))) , m_rootItem(new TorrentContentModelFolder(QVector<QString>({ tr("Name"), tr("Total 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}
#elif defined(Q_OS_MACOS) #elif defined(Q_OS_MACOS)
m_fileIconProvider = new MacFileIconProvider(); , m_fileIconProvider {new MacFileIconProvider}
#else #else
static bool doesBuiltInProviderWork = doesQFileIconProviderWork(); , m_fileIconProvider {doesQFileIconProviderWork() ? new QFileIconProvider : new MimeFileIconProvider}
m_fileIconProvider = doesBuiltInProviderWork ? new QFileIconProvider() : new MimeFileIconProvider();
#endif #endif
{
} }
TorrentContentModel::~TorrentContentModel() TorrentContentModel::~TorrentContentModel()

View File

@ -84,7 +84,7 @@ public slots:
void selectNone(); void selectNone();
private: private:
TorrentContentModelFolder *m_rootItem; TorrentContentModelFolder *m_rootItem = nullptr;
QVector<TorrentContentModelFile *> m_filesIndex; QVector<TorrentContentModelFile *> m_filesIndex;
QFileIconProvider *m_fileIconProvider; QFileIconProvider *m_fileIconProvider = nullptr;
}; };

View File

@ -50,15 +50,14 @@ QSize TransferListDelegate::sizeHint(const QStyleOptionViewItem &option, const Q
// the rows shrink if the text's height is smaller than the icon's height. // the rows shrink if the text's height is smaller than the icon's height.
// This happens because icon from the 'name' column is no longer drawn. // This happens because icon from the 'name' column is no longer drawn.
static int nameColHeight = -1; if (m_nameColHeight == -1)
if (nameColHeight == -1)
{ {
const QModelIndex nameColumn = index.sibling(index.row(), TransferListModel::TR_NAME); const QModelIndex nameColumn = index.sibling(index.row(), TransferListModel::TR_NAME);
nameColHeight = QStyledItemDelegate::sizeHint(option, nameColumn).height(); m_nameColHeight = QStyledItemDelegate::sizeHint(option, nameColumn).height();
} }
QSize size = QStyledItemDelegate::sizeHint(option, index); QSize size = QStyledItemDelegate::sizeHint(option, index);
size.setHeight(std::max(nameColHeight, size.height())); size.setHeight(std::max(m_nameColHeight, size.height()));
return size; return size;
} }

View File

@ -46,4 +46,5 @@ public:
private: private:
ProgressBarPainter m_progressBarPainter; ProgressBarPainter m_progressBarPainter;
mutable int m_nameColHeight = -1;
}; };

View File

@ -32,7 +32,6 @@
#include <QApplication> #include <QApplication>
#include <QDateTime> #include <QDateTime>
#include <QDebug> #include <QDebug>
#include <QIcon>
#include <QPalette> #include <QPalette>
#include "base/bittorrent/session.h" #include "base/bittorrent/session.h"
@ -45,23 +44,71 @@
#include "base/utils/string.h" #include "base/utils/string.h"
#include "uithememanager.h" #include "uithememanager.h"
static QIcon getIconByState(BitTorrent::TorrentState state);
static QColor getDefaultColorByState(BitTorrent::TorrentState state);
static QIcon getPausedIcon();
static QIcon getQueuedIcon();
static QIcon getDownloadingIcon();
static QIcon getStalledDownloadingIcon();
static QIcon getUploadingIcon();
static QIcon getStalledUploadingIcon();
static QIcon getCompletedIcon();
static QIcon getCheckingIcon();
static QIcon getErrorIcon();
static bool isDarkTheme();
namespace namespace
{ {
bool isDarkTheme()
{
const QPalette pal = QApplication::palette();
// QPalette::Base is used for the background of the Treeview
const QColor &color = pal.color(QPalette::Active, QPalette::Base);
return (color.lightness() < 127);
}
QColor getDefaultColorByState(const BitTorrent::TorrentState state)
{
// Color names taken from http://cloford.com/resources/colours/500col.htm
const bool dark = isDarkTheme();
switch (state)
{
case BitTorrent::TorrentState::Downloading:
case BitTorrent::TorrentState::ForcedDownloading:
case BitTorrent::TorrentState::DownloadingMetadata:
case BitTorrent::TorrentState::ForcedDownloadingMetadata:
if (!dark)
return {34, 139, 34}; // Forest Green
else
return {50, 205, 50}; // Lime Green
case BitTorrent::TorrentState::StalledDownloading:
case BitTorrent::TorrentState::StalledUploading:
if (!dark)
return {0, 0, 0}; // Black
else
return {204, 204, 204}; // Gray 80
case BitTorrent::TorrentState::Uploading:
case BitTorrent::TorrentState::ForcedUploading:
if (!dark)
return {65, 105, 225}; // Royal Blue
else
return {99, 184, 255}; // Steel Blue 1
case BitTorrent::TorrentState::PausedDownloading:
return {250, 128, 114}; // Salmon
case BitTorrent::TorrentState::PausedUploading:
if (!dark)
return {0, 0, 139}; // Dark Blue
else
return {79, 148, 205}; // Steel Blue 3
case BitTorrent::TorrentState::Error:
case BitTorrent::TorrentState::MissingFiles:
return {255, 0, 0}; // red
case BitTorrent::TorrentState::QueuedDownloading:
case BitTorrent::TorrentState::QueuedUploading:
case BitTorrent::TorrentState::CheckingDownloading:
case BitTorrent::TorrentState::CheckingUploading:
case BitTorrent::TorrentState::CheckingResumeData:
case BitTorrent::TorrentState::Moving:
if (!dark)
return {0, 128, 128}; // Teal
else
return {0, 205, 205}; // Cyan 3
case BitTorrent::TorrentState::Unknown:
return {255, 0, 0}; // red
default:
Q_ASSERT(false);
return {255, 0, 0}; // red
}
}
QHash<BitTorrent::TorrentState, QColor> torrentStateColorsFromUITheme() QHash<BitTorrent::TorrentState, QColor> torrentStateColorsFromUITheme()
{ {
struct TorrentStateColorDescriptor struct TorrentStateColorDescriptor
@ -127,8 +174,17 @@ TransferListModel::TransferListModel(QObject *parent)
{BitTorrent::TorrentState::Moving, tr("Moving", "Torrent local data are being moved/relocated")}, {BitTorrent::TorrentState::Moving, tr("Moving", "Torrent local data are being moved/relocated")},
{BitTorrent::TorrentState::MissingFiles, tr("Missing Files")}, {BitTorrent::TorrentState::MissingFiles, tr("Missing Files")},
{BitTorrent::TorrentState::Error, tr("Errored", "Torrent status, the torrent has an error")} {BitTorrent::TorrentState::Error, tr("Errored", "Torrent status, the torrent has an error")}
} }
, m_stateThemeColors {torrentStateColorsFromUITheme()} , m_stateThemeColors {torrentStateColorsFromUITheme()}
, m_checkingIcon {UIThemeManager::instance()->getIcon(u"checking"_qs)}
, m_completedIcon {UIThemeManager::instance()->getIcon(u"completed"_qs)}
, m_downloadingIcon {UIThemeManager::instance()->getIcon(u"downloading"_qs)}
, m_errorIcon {UIThemeManager::instance()->getIcon(u"error"_qs)}
, m_pausedIcon {UIThemeManager::instance()->getIcon(u"paused"_qs)}
, m_queuedIcon {UIThemeManager::instance()->getIcon(u"queued"_qs)}
, m_stalledDLIcon {UIThemeManager::instance()->getIcon(u"stalledDL"_qs)}
, m_stalledUPIcon {UIThemeManager::instance()->getIcon(u"stalledUP"_qs)}
, m_uploadingIcon {UIThemeManager::instance()->getIcon(u"uploading"_qs)}
{ {
configure(); configure();
connect(Preferences::instance(), &Preferences::changed, this, &TransferListModel::configure); connect(Preferences::instance(), &Preferences::changed, this, &TransferListModel::configure);
@ -657,9 +713,7 @@ void TransferListModel::configure()
} }
} }
// Static functions QIcon TransferListModel::getIconByState(const BitTorrent::TorrentState state) const
QIcon getIconByState(const BitTorrent::TorrentState state)
{ {
switch (state) switch (state)
{ {
@ -667,149 +721,32 @@ QIcon getIconByState(const BitTorrent::TorrentState state)
case BitTorrent::TorrentState::ForcedDownloading: case BitTorrent::TorrentState::ForcedDownloading:
case BitTorrent::TorrentState::DownloadingMetadata: case BitTorrent::TorrentState::DownloadingMetadata:
case BitTorrent::TorrentState::ForcedDownloadingMetadata: case BitTorrent::TorrentState::ForcedDownloadingMetadata:
return getDownloadingIcon(); return m_downloadingIcon;
case BitTorrent::TorrentState::StalledDownloading: case BitTorrent::TorrentState::StalledDownloading:
return getStalledDownloadingIcon(); return m_stalledDLIcon;
case BitTorrent::TorrentState::StalledUploading: case BitTorrent::TorrentState::StalledUploading:
return getStalledUploadingIcon(); return m_stalledUPIcon;
case BitTorrent::TorrentState::Uploading: case BitTorrent::TorrentState::Uploading:
case BitTorrent::TorrentState::ForcedUploading: case BitTorrent::TorrentState::ForcedUploading:
return getUploadingIcon(); return m_uploadingIcon;
case BitTorrent::TorrentState::PausedDownloading: case BitTorrent::TorrentState::PausedDownloading:
return getPausedIcon(); return m_pausedIcon;
case BitTorrent::TorrentState::PausedUploading: case BitTorrent::TorrentState::PausedUploading:
return getCompletedIcon(); return m_completedIcon;
case BitTorrent::TorrentState::QueuedDownloading: case BitTorrent::TorrentState::QueuedDownloading:
case BitTorrent::TorrentState::QueuedUploading: case BitTorrent::TorrentState::QueuedUploading:
return getQueuedIcon(); return m_queuedIcon;
case BitTorrent::TorrentState::CheckingDownloading: case BitTorrent::TorrentState::CheckingDownloading:
case BitTorrent::TorrentState::CheckingUploading: case BitTorrent::TorrentState::CheckingUploading:
case BitTorrent::TorrentState::CheckingResumeData: case BitTorrent::TorrentState::CheckingResumeData:
case BitTorrent::TorrentState::Moving: case BitTorrent::TorrentState::Moving:
return getCheckingIcon(); return m_checkingIcon;
case BitTorrent::TorrentState::Unknown: case BitTorrent::TorrentState::Unknown:
case BitTorrent::TorrentState::MissingFiles: case BitTorrent::TorrentState::MissingFiles:
case BitTorrent::TorrentState::Error: case BitTorrent::TorrentState::Error:
return getErrorIcon(); return m_errorIcon;
default: default:
Q_ASSERT(false); Q_ASSERT(false);
return getErrorIcon(); return m_errorIcon;
} }
} }
QColor getDefaultColorByState(const BitTorrent::TorrentState state)
{
// Color names taken from http://cloford.com/resources/colours/500col.htm
bool dark = isDarkTheme();
switch (state)
{
case BitTorrent::TorrentState::Downloading:
case BitTorrent::TorrentState::ForcedDownloading:
case BitTorrent::TorrentState::DownloadingMetadata:
case BitTorrent::TorrentState::ForcedDownloadingMetadata:
if (!dark)
return {34, 139, 34}; // Forest Green
else
return {50, 205, 50}; // Lime Green
case BitTorrent::TorrentState::StalledDownloading:
case BitTorrent::TorrentState::StalledUploading:
if (!dark)
return {0, 0, 0}; // Black
else
return {204, 204, 204}; // Gray 80
case BitTorrent::TorrentState::Uploading:
case BitTorrent::TorrentState::ForcedUploading:
if (!dark)
return {65, 105, 225}; // Royal Blue
else
return {99, 184, 255}; // Steel Blue 1
case BitTorrent::TorrentState::PausedDownloading:
return {250, 128, 114}; // Salmon
case BitTorrent::TorrentState::PausedUploading:
if (!dark)
return {0, 0, 139}; // Dark Blue
else
return {79, 148, 205}; // Steel Blue 3
case BitTorrent::TorrentState::Error:
case BitTorrent::TorrentState::MissingFiles:
return {255, 0, 0}; // red
case BitTorrent::TorrentState::QueuedDownloading:
case BitTorrent::TorrentState::QueuedUploading:
case BitTorrent::TorrentState::CheckingDownloading:
case BitTorrent::TorrentState::CheckingUploading:
case BitTorrent::TorrentState::CheckingResumeData:
case BitTorrent::TorrentState::Moving:
if (!dark)
return {0, 128, 128}; // Teal
else
return {0, 205, 205}; // Cyan 3
case BitTorrent::TorrentState::Unknown:
return {255, 0, 0}; // red
default:
Q_ASSERT(false);
return {255, 0, 0}; // red
}
}
QIcon getPausedIcon()
{
static QIcon cached = UIThemeManager::instance()->getIcon(u"paused"_qs);
return cached;
}
QIcon getQueuedIcon()
{
static QIcon cached = UIThemeManager::instance()->getIcon(u"queued"_qs);
return cached;
}
QIcon getDownloadingIcon()
{
static QIcon cached = UIThemeManager::instance()->getIcon(u"downloading"_qs);
return cached;
}
QIcon getStalledDownloadingIcon()
{
static QIcon cached = UIThemeManager::instance()->getIcon(u"stalledDL"_qs);
return cached;
}
QIcon getUploadingIcon()
{
static QIcon cached = UIThemeManager::instance()->getIcon(u"uploading"_qs);
return cached;
}
QIcon getStalledUploadingIcon()
{
static QIcon cached = UIThemeManager::instance()->getIcon(u"stalledUP"_qs);
return cached;
}
QIcon getCompletedIcon()
{
static QIcon cached = UIThemeManager::instance()->getIcon(u"completed"_qs);
return cached;
}
QIcon getCheckingIcon()
{
static QIcon cached = UIThemeManager::instance()->getIcon(u"checking"_qs);
return cached;
}
QIcon getErrorIcon()
{
static QIcon cached = UIThemeManager::instance()->getIcon(u"error"_qs);
return cached;
}
bool isDarkTheme()
{
const QPalette pal = QApplication::palette();
// QPalette::Base is used for the background of the Treeview
const QColor &color = pal.color(QPalette::Active, QPalette::Base);
return (color.lightness() < 127);
}

View File

@ -32,6 +32,7 @@
#include <QAbstractListModel> #include <QAbstractListModel>
#include <QColor> #include <QColor>
#include <QHash> #include <QHash>
#include <QIcon>
#include <QList> #include <QList>
#include "base/bittorrent/torrent.h" #include "base/bittorrent/torrent.h"
@ -111,6 +112,7 @@ private:
void configure(); void configure();
QString displayValue(const BitTorrent::Torrent *torrent, int column) const; QString displayValue(const BitTorrent::Torrent *torrent, int column) const;
QVariant internalValue(const BitTorrent::Torrent *torrent, int column, bool alt) const; QVariant internalValue(const BitTorrent::Torrent *torrent, int column, bool alt) const;
QIcon getIconByState(const BitTorrent::TorrentState state) const;
QList<BitTorrent::Torrent *> m_torrentList; // maps row number to torrent handle QList<BitTorrent::Torrent *> m_torrentList; // maps row number to torrent handle
QHash<BitTorrent::Torrent *, int> m_torrentMap; // maps torrent handle to row number QHash<BitTorrent::Torrent *, int> m_torrentMap; // maps torrent handle to row number
@ -126,4 +128,15 @@ private:
}; };
HideZeroValuesMode m_hideZeroValuesMode = HideZeroValuesMode::Never; HideZeroValuesMode m_hideZeroValuesMode = HideZeroValuesMode::Never;
// cached icons
QIcon m_checkingIcon;
QIcon m_completedIcon;
QIcon m_downloadingIcon;
QIcon m_errorIcon;
QIcon m_pausedIcon;
QIcon m_queuedIcon;
QIcon m_stalledDLIcon;
QIcon m_stalledUPIcon;
QIcon m_uploadingIcon;
}; };

View File

@ -201,7 +201,13 @@ void UIThemeManager::applyStyleSheet() const
QIcon UIThemeManager::getIcon(const QString &iconId, const QString &fallback) const QIcon UIThemeManager::getIcon(const QString &iconId, const QString &fallback) const
{ {
// Cache to avoid rescaling svg icons
const auto iter = m_iconCache.find(iconId);
if (iter != m_iconCache.end())
return *iter;
#if (defined(Q_OS_UNIX) && !defined(Q_OS_MACOS)) #if (defined(Q_OS_UNIX) && !defined(Q_OS_MACOS))
// Don't cache system icons because users might change them at run time
if (m_useSystemTheme) if (m_useSystemTheme)
{ {
QIcon icon = QIcon::fromTheme(iconId); QIcon icon = QIcon::fromTheme(iconId);
@ -211,12 +217,6 @@ QIcon UIThemeManager::getIcon(const QString &iconId, const QString &fallback) co
} }
#endif #endif
// Cache to avoid rescaling svg icons
// And don't cache system icons because users might change them at run time
const auto iter = m_iconCache.find(iconId);
if (iter != m_iconCache.end())
return *iter;
const QIcon icon {getIconPathFromResources(iconId, fallback).data()}; const QIcon icon {getIconPathFromResources(iconId, fallback).data()};
m_iconCache[iconId] = icon; m_iconCache[iconId] = icon;
return icon; return icon;