From ca9f5a18d49e1af573b60dce7add08dd70091e7a Mon Sep 17 00:00:00 2001 From: Chocobo1 Date: Fri, 27 May 2022 02:29:17 +0800 Subject: [PATCH 1/6] Suppress type narrowing warnings --- src/app/signalhandler.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/app/signalhandler.cpp b/src/app/signalhandler.cpp index 841cc4c7c..9eb49e379 100644 --- a/src/app/signalhandler.cpp +++ b/src/app/signalhandler.cpp @@ -76,8 +76,8 @@ namespace { const size_t strLen = strlen(str); #ifdef Q_OS_WIN - if (_write(_fileno(stderr), str, strLen) < static_cast(strLen)) - std::ignore = _write(_fileno(stdout), str, strLen); + if (_write(_fileno(stderr), str, static_cast(strLen)) < static_cast(strLen)) + std::ignore = _write(_fileno(stdout), str, static_cast(strLen)); #else if (write(STDERR_FILENO, str, strLen) < static_cast(strLen)) std::ignore = write(STDOUT_FILENO, str, strLen); From 7eaaa8f92af1d466675a05f9e97f5f64060569c8 Mon Sep 17 00:00:00 2001 From: Chocobo1 Date: Fri, 27 May 2022 02:35:55 +0800 Subject: [PATCH 2/6] Turn static variable into class member --- src/app/application.cpp | 4 +--- src/app/application.h | 2 ++ 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/app/application.cpp b/src/app/application.cpp index 120854475..ea82b27c2 100644 --- a/src/app/application.cpp +++ b/src/app/application.cpp @@ -43,7 +43,6 @@ #include #endif -#include #include #include #include @@ -808,8 +807,7 @@ void Application::applyMemoryWorkingSetLimit() void Application::cleanup() { // cleanup() can be called multiple times during shutdown. We only need it once. - static QAtomicInt alreadyDone; - if (!alreadyDone.testAndSetAcquire(0, 1)) + if (!m_isCleanupRun.testAndSetAcquire(0, 1)) return; #ifndef DISABLE_GUI diff --git a/src/app/application.h b/src/app/application.h index 5747b01e5..6f70ca1a5 100644 --- a/src/app/application.h +++ b/src/app/application.h @@ -31,6 +31,7 @@ #pragma once #include +#include #include #include #include @@ -145,6 +146,7 @@ private: ApplicationInstanceManager *m_instanceManager = nullptr; bool m_running = false; + QAtomicInt m_isCleanupRun; ShutdownDialogAction m_shutdownAct; QBtCommandLineParameters m_commandLineArgs; From a9f99aed48bd78c6fa3857aaa1b17942e216f7e6 Mon Sep 17 00:00:00 2001 From: Chocobo1 Date: Fri, 27 May 2022 03:06:04 +0800 Subject: [PATCH 3/6] Revise code --- src/base/utils/misc.cpp | 2 +- src/gui/torrentcontentmodel.cpp | 38 +++++++++++++++------------------ 2 files changed, 18 insertions(+), 22 deletions(-) diff --git a/src/base/utils/misc.cpp b/src/base/utils/misc.cpp index eaf26f84a..f02ec106d 100644 --- a/src/base/utils/misc.cpp +++ b/src/base/utils/misc.cpp @@ -500,7 +500,7 @@ QString Utils::Misc::opensslVersionString() #else static const auto version {QString::fromLatin1(SSLeay_version(SSLEAY_VERSION))}; #endif - return QStringView(version).split(u' ', Qt::SkipEmptyParts).at(1).toString(); + return version.section(u' ', 1, 1); } QString Utils::Misc::zlibVersionString() diff --git a/src/gui/torrentcontentmodel.cpp b/src/gui/torrentcontentmodel.cpp index 36fe9b281..17898bcfc 100644 --- a/src/gui/torrentcontentmodel.cpp +++ b/src/gui/torrentcontentmodel.cpp @@ -91,7 +91,8 @@ namespace if (!ext.isEmpty()) { QPixmap cached; - if (QPixmapCache::find(ext, &cached)) return {cached}; + if (QPixmapCache::find(ext, &cached)) + return {cached}; const QPixmap pixmap = pixmapForExtension(ext); if (!pixmap.isNull()) @@ -115,16 +116,17 @@ namespace QPixmap pixmapForExtension(const QString &ext) const override { const std::wstring extWStr = QString(u'.' + ext).toStdWString(); - SHFILEINFO sfi {}; - HRESULT hr = ::SHGetFileInfoW(extWStr.c_str(), - FILE_ATTRIBUTE_NORMAL, &sfi, sizeof(sfi), SHGFI_ICON | SHGFI_USEFILEATTRIBUTES); + + SHFILEINFOW sfi {}; + const HRESULT hr = ::SHGetFileInfoW(extWStr.c_str(), + FILE_ATTRIBUTE_NORMAL, &sfi, sizeof(sfi), (SHGFI_ICON | SHGFI_USEFILEATTRIBUTES)); if (FAILED(hr)) return {}; #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 - QPixmap iconPixmap = QtWin::fromHICON(sfi.hIcon); + const QPixmap iconPixmap = QtWin::fromHICON(sfi.hIcon); #endif ::DestroyIcon(sfi.hIcon); return iconPixmap; @@ -158,30 +160,24 @@ namespace return (!testIcon1.isNull() || !testIcon2.isNull()); } - class MimeFileIconProvider : public UnifiedFileIconProvider + class MimeFileIconProvider final : public UnifiedFileIconProvider { using QFileIconProvider::icon; QIcon icon(const QFileInfo &info) const override { - const QMimeType mimeType = m_db.mimeTypeForFile(info, QMimeDatabase::MatchExtension); - QIcon res = QIcon::fromTheme(mimeType.iconName()); - if (!res.isNull()) - { - return res; - } + const QMimeType mimeType = QMimeDatabase().mimeTypeForFile(info, QMimeDatabase::MatchExtension); - res = QIcon::fromTheme(mimeType.genericIconName()); - if (!res.isNull()) - { - return res; - } + const auto mimeIcon = QIcon::fromTheme(mimeType.iconName()); + if (!mimeIcon.isNull()) + return mimeIcon; + + const auto genericIcon = QIcon::fromTheme(mimeType.genericIconName()); + if (!genericIcon.isNull()) + return genericIcon; return UnifiedFileIconProvider::icon(info); } - - private: - QMimeDatabase m_db; }; #endif // Q_OS_WIN } From f54cc5796ef9561fd3142b566fdf69e5a5fb3620 Mon Sep 17 00:00:00 2001 From: Chocobo1 Date: Fri, 27 May 2022 03:12:10 +0800 Subject: [PATCH 4/6] Move function into anonymous namespace --- src/gui/mainwindow.cpp | 32 ++-- src/gui/transferlistmodel.cpp | 327 ++++++++++++++++------------------ 2 files changed, 170 insertions(+), 189 deletions(-) diff --git a/src/gui/mainwindow.cpp b/src/gui/mainwindow.cpp index 4c5aea10a..7140a0692 100644 --- a/src/gui/mainwindow.cpp +++ b/src/gui/mainwindow.cpp @@ -121,6 +121,21 @@ namespace || (!str.startsWith(u"file:", Qt::CaseInsensitive) && 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) @@ -1388,28 +1403,11 @@ void MainWindow::dragEnterEvent(QDragEnterEvent *event) } #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() { dockMainWindowHandle = this; MacUtils::overrideDockClickHandler(dockClickHandler); } - #endif // Q_OS_MACOS /***************************************************** diff --git a/src/gui/transferlistmodel.cpp b/src/gui/transferlistmodel.cpp index 197d8f176..2fab81906 100644 --- a/src/gui/transferlistmodel.cpp +++ b/src/gui/transferlistmodel.cpp @@ -45,23 +45,163 @@ #include "base/utils/string.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 { + 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); + } + + QIcon getIconByState(const BitTorrent::TorrentState state) + { + switch (state) + { + case BitTorrent::TorrentState::Downloading: + case BitTorrent::TorrentState::ForcedDownloading: + case BitTorrent::TorrentState::DownloadingMetadata: + case BitTorrent::TorrentState::ForcedDownloadingMetadata: + return getDownloadingIcon(); + case BitTorrent::TorrentState::StalledDownloading: + return getStalledDownloadingIcon(); + case BitTorrent::TorrentState::StalledUploading: + return getStalledUploadingIcon(); + case BitTorrent::TorrentState::Uploading: + case BitTorrent::TorrentState::ForcedUploading: + return getUploadingIcon(); + case BitTorrent::TorrentState::PausedDownloading: + return getPausedIcon(); + case BitTorrent::TorrentState::PausedUploading: + return getCompletedIcon(); + case BitTorrent::TorrentState::QueuedDownloading: + case BitTorrent::TorrentState::QueuedUploading: + return getQueuedIcon(); + case BitTorrent::TorrentState::CheckingDownloading: + case BitTorrent::TorrentState::CheckingUploading: + case BitTorrent::TorrentState::CheckingResumeData: + case BitTorrent::TorrentState::Moving: + return getCheckingIcon(); + case BitTorrent::TorrentState::Unknown: + case BitTorrent::TorrentState::MissingFiles: + case BitTorrent::TorrentState::Error: + return getErrorIcon(); + default: + Q_ASSERT(false); + return getErrorIcon(); + } + } + + 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 + } + } + QHash torrentStateColorsFromUITheme() { struct TorrentStateColorDescriptor @@ -656,160 +796,3 @@ void TransferListModel::configure() emit dataChanged(index(0, 0), index((rowCount() - 1), (columnCount() - 1))); } } - -// Static functions - -QIcon getIconByState(const BitTorrent::TorrentState state) -{ - switch (state) - { - case BitTorrent::TorrentState::Downloading: - case BitTorrent::TorrentState::ForcedDownloading: - case BitTorrent::TorrentState::DownloadingMetadata: - case BitTorrent::TorrentState::ForcedDownloadingMetadata: - return getDownloadingIcon(); - case BitTorrent::TorrentState::StalledDownloading: - return getStalledDownloadingIcon(); - case BitTorrent::TorrentState::StalledUploading: - return getStalledUploadingIcon(); - case BitTorrent::TorrentState::Uploading: - case BitTorrent::TorrentState::ForcedUploading: - return getUploadingIcon(); - case BitTorrent::TorrentState::PausedDownloading: - return getPausedIcon(); - case BitTorrent::TorrentState::PausedUploading: - return getCompletedIcon(); - case BitTorrent::TorrentState::QueuedDownloading: - case BitTorrent::TorrentState::QueuedUploading: - return getQueuedIcon(); - case BitTorrent::TorrentState::CheckingDownloading: - case BitTorrent::TorrentState::CheckingUploading: - case BitTorrent::TorrentState::CheckingResumeData: - case BitTorrent::TorrentState::Moving: - return getCheckingIcon(); - case BitTorrent::TorrentState::Unknown: - case BitTorrent::TorrentState::MissingFiles: - case BitTorrent::TorrentState::Error: - return getErrorIcon(); - default: - Q_ASSERT(false); - return getErrorIcon(); - } -} - -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); -} From c2c17fd0536d9ea15e56fa83ef165db710896f28 Mon Sep 17 00:00:00 2001 From: Chocobo1 Date: Fri, 27 May 2022 03:44:23 +0800 Subject: [PATCH 5/6] Revise icon cache look up Find in `m_iconCache` first because it is cheaper than calling `QIcon::fromTheme()`. --- src/gui/uithememanager.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/gui/uithememanager.cpp b/src/gui/uithememanager.cpp index 4e8aa6933..3fadcd826 100644 --- a/src/gui/uithememanager.cpp +++ b/src/gui/uithememanager.cpp @@ -201,7 +201,13 @@ void UIThemeManager::applyStyleSheet() 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)) + // Don't cache system icons because users might change them at run time if (m_useSystemTheme) { QIcon icon = QIcon::fromTheme(iconId); @@ -211,12 +217,6 @@ QIcon UIThemeManager::getIcon(const QString &iconId, const QString &fallback) co } #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()}; m_iconCache[iconId] = icon; return icon; From 73faf67084891b39d176fd49e37f0ddf51a82b52 Mon Sep 17 00:00:00 2001 From: Chocobo1 Date: Fri, 27 May 2022 03:46:14 +0800 Subject: [PATCH 6/6] Clean up usage of `static` keyword They are either misused or redundant, so remove it. --- src/base/bittorrent/session.cpp | 2 +- src/base/bittorrent/statistics.cpp | 2 +- src/base/rss/rss_item.cpp | 2 +- src/base/torrentfileguard.cpp | 16 ++-- src/base/torrentfileguard.h | 9 +- src/base/utils/misc.cpp | 2 +- src/gui/search/searchjobwidget.cpp | 14 +-- src/gui/search/searchjobwidget.h | 5 +- src/gui/torrentcontentmodel.cpp | 23 +++-- src/gui/torrentcontentmodel.h | 4 +- src/gui/transferlistdelegate.cpp | 7 +- src/gui/transferlistdelegate.h | 1 + src/gui/transferlistmodel.cpp | 144 ++++++++++------------------- src/gui/transferlistmodel.h | 13 +++ 14 files changed, 106 insertions(+), 138 deletions(-) diff --git a/src/base/bittorrent/session.cpp b/src/base/bittorrent/session.cpp index af7188339..f4d404444 100644 --- a/src/base/bittorrent/session.cpp +++ b/src/base/bittorrent/session.cpp @@ -635,7 +635,7 @@ Path Session::downloadPath() const bool Session::isValidCategoryName(const QString &name) { - static const QRegularExpression re(uR"(^([^\\\/]|[^\\\/]([^\\\/]|\/(?=[^\/]))*[^\\\/])$)"_qs); + const QRegularExpression re(uR"(^([^\\\/]|[^\\\/]([^\\\/]|\/(?=[^\/]))*[^\\\/])$)"_qs); if (!name.isEmpty() && (name.indexOf(re) != 0)) { qDebug() << "Incorrect category name:" << name; diff --git a/src/base/bittorrent/statistics.cpp b/src/base/bittorrent/statistics.cpp index 0af93c9c4..142833155 100644 --- a/src/base/bittorrent/statistics.cpp +++ b/src/base/bittorrent/statistics.cpp @@ -35,7 +35,7 @@ #include "base/bittorrent/sessionstatus.h" #include "base/profile.h" -static const qint64 SAVE_INTERVAL = 15 * 60 * 1000; +const qint64 SAVE_INTERVAL = 15 * 60 * 1000; using namespace BitTorrent; diff --git a/src/base/rss/rss_item.cpp b/src/base/rss/rss_item.cpp index 2179b3a22..05fe8677e 100644 --- a/src/base/rss/rss_item.cpp +++ b/src/base/rss/rss_item.cpp @@ -68,7 +68,7 @@ QString Item::name() const bool Item::isValidPath(const QString &path) { - static const QRegularExpression re( + const QRegularExpression re( uR"(\A[^\%1]+(\%1[^\%1]+)*\z)"_qs.arg(Item::PathSeparator) , QRegularExpression::DontCaptureOption); diff --git a/src/base/torrentfileguard.cpp b/src/base/torrentfileguard.cpp index 3ea4eb085..9c398b365 100644 --- a/src/base/torrentfileguard.cpp +++ b/src/base/torrentfileguard.cpp @@ -31,6 +31,14 @@ #include "settingvalue.h" #include "utils/fs.h" +namespace +{ + SettingValue autoDeleteModeSetting() + { + return SettingValue {u"Core/AutoDeleteAddedTorrentFile"_qs}; + } +} + FileGuard::FileGuard(const Path &path) : m_path {path} , m_remove {true} @@ -76,13 +84,7 @@ TorrentFileGuard::AutoDeleteMode TorrentFileGuard::autoDeleteMode() return autoDeleteModeSetting().get(AutoDeleteMode::Never); } -void TorrentFileGuard::setAutoDeleteMode(TorrentFileGuard::AutoDeleteMode mode) +void TorrentFileGuard::setAutoDeleteMode(const TorrentFileGuard::AutoDeleteMode mode) { autoDeleteModeSetting() = mode; } - -SettingValue &TorrentFileGuard::autoDeleteModeSetting() -{ - static SettingValue setting {u"Core/AutoDeleteAddedTorrentFile"_qs}; - return setting; -} diff --git a/src/base/torrentfileguard.h b/src/base/torrentfileguard.h index 3da84d658..83e015995 100644 --- a/src/base/torrentfileguard.h +++ b/src/base/torrentfileguard.h @@ -33,8 +33,6 @@ #include "base/path.h" -template class SettingValue; - /// Utility class to defer file deletion class FileGuard { @@ -47,7 +45,7 @@ public: private: Path m_path; - bool m_remove; + bool m_remove = false; }; /// Reads settings for .torrent files from preferences @@ -64,7 +62,7 @@ public: void markAsAddedToSession(); 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, IfAdded, @@ -77,9 +75,8 @@ public: private: TorrentFileGuard(const Path &path, AutoDeleteMode mode); - static SettingValue &autoDeleteModeSetting(); Q_ENUM(AutoDeleteMode) AutoDeleteMode m_mode; - bool m_wasAdded; + bool m_wasAdded = false; }; diff --git a/src/base/utils/misc.cpp b/src/base/utils/misc.cpp index f02ec106d..01d81e178 100644 --- a/src/base/utils/misc.cpp +++ b/src/base/utils/misc.cpp @@ -457,7 +457,7 @@ QString Utils::Misc::parseHtmlLinks(const QString &rawText) result.replace(reURL, u"\\1\\2"_qs); // Capture links without scheme - static const QRegularExpression reNoScheme(u""_qs); + const QRegularExpression reNoScheme(u""_qs); result.replace(reNoScheme, u""_qs); // to preserve plain text formatting diff --git a/src/gui/search/searchjobwidget.cpp b/src/gui/search/searchjobwidget.cpp index 8ef1551bf..afe7623c5 100644 --- a/src/gui/search/searchjobwidget.cpp +++ b/src/gui/search/searchjobwidget.cpp @@ -44,7 +44,6 @@ #include "base/search/searchdownloadhandler.h" #include "base/search/searchhandler.h" #include "base/search/searchpluginmanager.h" -#include "base/settingvalue.h" #include "base/utils/misc.h" #include "gui/addnewtorrentdialog.h" #include "gui/lineedit.h" @@ -57,6 +56,7 @@ SearchJobWidget::SearchJobWidget(SearchHandler *searchHandler, QWidget *parent) : QWidget(parent) , m_ui(new Ui::SearchJobWidget) , m_searchHandler(searchHandler) + , m_nameFilteringMode(u"Search/FilteringMode"_qs) { m_ui->setupUi(this); @@ -319,7 +319,7 @@ void SearchJobWidget::updateFilter() sizeInBytes(m_ui->minSize->value(), static_cast(m_ui->minSizeUnit->currentIndex())), sizeInBytes(m_ui->maxSize->value(), static_cast(m_ui->maxSizeUnit->currentIndex()))); - nameFilteringModeSetting() = filteringMode(); + m_nameFilteringMode = filteringMode(); m_proxyModel->invalidate(); updateResultsCount(); @@ -355,8 +355,8 @@ void SearchJobWidget::fillFilterComboBoxes() m_ui->filterMode->addItem(tr("Torrent names only"), static_cast(NameFilteringMode::OnlyNames)); m_ui->filterMode->addItem(tr("Everywhere"), static_cast(NameFilteringMode::Everywhere)); - QVariant selectedMode = static_cast(nameFilteringModeSetting().get(NameFilteringMode::OnlyNames)); - int index = m_ui->filterMode->findData(selectedMode); + const QVariant selectedMode = static_cast(m_nameFilteringMode.get(NameFilteringMode::OnlyNames)); + const int index = m_ui->filterMode->findData(selectedMode); m_ui->filterMode->setCurrentIndex((index == -1) ? 0 : index); } @@ -545,12 +545,6 @@ void SearchJobWidget::appendSearchResults(const QVector &results) updateResultsCount(); } -SettingValue &SearchJobWidget::nameFilteringModeSetting() -{ - static SettingValue setting {u"Search/FilteringMode"_qs}; - return setting; -} - void SearchJobWidget::keyPressEvent(QKeyEvent *event) { switch (event->key()) diff --git a/src/gui/search/searchjobwidget.h b/src/gui/search/searchjobwidget.h index 61052168d..e4818a5df 100644 --- a/src/gui/search/searchjobwidget.h +++ b/src/gui/search/searchjobwidget.h @@ -31,6 +31,8 @@ #include +#include "base/settingvalue.h" + #define ENGINE_URL_COLUMN 4 #define URL_COLUMN 5 @@ -127,7 +129,6 @@ private: void copyField(int column) const; static QString statusText(Status st); - static SettingValue &nameFilteringModeSetting(); Ui::SearchJobWidget *m_ui; SearchHandler *m_searchHandler; @@ -136,6 +137,8 @@ private: LineEdit *m_lineEditSearchResultsFilter; Status m_status = Status::Ongoing; bool m_noSearchResults = true; + + SettingValue m_nameFilteringMode; }; Q_DECLARE_METATYPE(SearchJobWidget::NameFilteringMode) diff --git a/src/gui/torrentcontentmodel.cpp b/src/gui/torrentcontentmodel.cpp index 17898bcfc..1064029c7 100644 --- a/src/gui/torrentcontentmodel.cpp +++ b/src/gui/torrentcontentmodel.cpp @@ -69,14 +69,20 @@ namespace class UnifiedFileIconProvider : public QFileIconProvider { public: + UnifiedFileIconProvider() + : m_textPlainIcon {UIThemeManager::instance()->getIcon(u"text-plain"_qs)} + { + } + using QFileIconProvider::icon; - QIcon icon(const QFileInfo &info) const override + QIcon icon(const QFileInfo &) const override { - Q_UNUSED(info); - static QIcon cached = UIThemeManager::instance()->getIcon(u"text-plain"_qs); - return cached; + return m_textPlainIcon; } + + private: + QIcon m_textPlainIcon; }; #ifdef QBT_PIXMAP_CACHE_FOR_FILE_ICONS @@ -185,15 +191,14 @@ namespace TorrentContentModel::TorrentContentModel(QObject *parent) : QAbstractItemModel(parent) , m_rootItem(new TorrentContentModelFolder(QVector({ tr("Name"), tr("Total Size"), tr("Progress"), tr("Download Priority"), tr("Remaining"), tr("Availability") }))) -{ #if defined(Q_OS_WIN) - m_fileIconProvider = new WinShellFileIconProvider(); + , m_fileIconProvider {new WinShellFileIconProvider} #elif defined(Q_OS_MACOS) - m_fileIconProvider = new MacFileIconProvider(); + , m_fileIconProvider {new MacFileIconProvider} #else - static bool doesBuiltInProviderWork = doesQFileIconProviderWork(); - m_fileIconProvider = doesBuiltInProviderWork ? new QFileIconProvider() : new MimeFileIconProvider(); + , m_fileIconProvider {doesQFileIconProviderWork() ? new QFileIconProvider : new MimeFileIconProvider} #endif +{ } TorrentContentModel::~TorrentContentModel() diff --git a/src/gui/torrentcontentmodel.h b/src/gui/torrentcontentmodel.h index 10764957a..a1baf0666 100644 --- a/src/gui/torrentcontentmodel.h +++ b/src/gui/torrentcontentmodel.h @@ -84,7 +84,7 @@ public slots: void selectNone(); private: - TorrentContentModelFolder *m_rootItem; + TorrentContentModelFolder *m_rootItem = nullptr; QVector m_filesIndex; - QFileIconProvider *m_fileIconProvider; + QFileIconProvider *m_fileIconProvider = nullptr; }; diff --git a/src/gui/transferlistdelegate.cpp b/src/gui/transferlistdelegate.cpp index b649ecff1..dc21654d7 100644 --- a/src/gui/transferlistdelegate.cpp +++ b/src/gui/transferlistdelegate.cpp @@ -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. // This happens because icon from the 'name' column is no longer drawn. - static int nameColHeight = -1; - if (nameColHeight == -1) + if (m_nameColHeight == -1) { 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); - size.setHeight(std::max(nameColHeight, size.height())); + size.setHeight(std::max(m_nameColHeight, size.height())); return size; } diff --git a/src/gui/transferlistdelegate.h b/src/gui/transferlistdelegate.h index 1c912db34..01194d118 100644 --- a/src/gui/transferlistdelegate.h +++ b/src/gui/transferlistdelegate.h @@ -46,4 +46,5 @@ public: private: ProgressBarPainter m_progressBarPainter; + mutable int m_nameColHeight = -1; }; diff --git a/src/gui/transferlistmodel.cpp b/src/gui/transferlistmodel.cpp index 2fab81906..ee0f75136 100644 --- a/src/gui/transferlistmodel.cpp +++ b/src/gui/transferlistmodel.cpp @@ -32,7 +32,6 @@ #include #include #include -#include #include #include "base/bittorrent/session.h" @@ -47,60 +46,6 @@ namespace { - 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(); @@ -109,48 +54,10 @@ namespace return (color.lightness() < 127); } - QIcon getIconByState(const BitTorrent::TorrentState state) - { - switch (state) - { - case BitTorrent::TorrentState::Downloading: - case BitTorrent::TorrentState::ForcedDownloading: - case BitTorrent::TorrentState::DownloadingMetadata: - case BitTorrent::TorrentState::ForcedDownloadingMetadata: - return getDownloadingIcon(); - case BitTorrent::TorrentState::StalledDownloading: - return getStalledDownloadingIcon(); - case BitTorrent::TorrentState::StalledUploading: - return getStalledUploadingIcon(); - case BitTorrent::TorrentState::Uploading: - case BitTorrent::TorrentState::ForcedUploading: - return getUploadingIcon(); - case BitTorrent::TorrentState::PausedDownloading: - return getPausedIcon(); - case BitTorrent::TorrentState::PausedUploading: - return getCompletedIcon(); - case BitTorrent::TorrentState::QueuedDownloading: - case BitTorrent::TorrentState::QueuedUploading: - return getQueuedIcon(); - case BitTorrent::TorrentState::CheckingDownloading: - case BitTorrent::TorrentState::CheckingUploading: - case BitTorrent::TorrentState::CheckingResumeData: - case BitTorrent::TorrentState::Moving: - return getCheckingIcon(); - case BitTorrent::TorrentState::Unknown: - case BitTorrent::TorrentState::MissingFiles: - case BitTorrent::TorrentState::Error: - return getErrorIcon(); - default: - Q_ASSERT(false); - return getErrorIcon(); - } - } - QColor getDefaultColorByState(const BitTorrent::TorrentState state) { // Color names taken from http://cloford.com/resources/colours/500col.htm - bool dark = isDarkTheme(); + const bool dark = isDarkTheme(); switch (state) { @@ -267,8 +174,17 @@ TransferListModel::TransferListModel(QObject *parent) {BitTorrent::TorrentState::Moving, tr("Moving", "Torrent local data are being moved/relocated")}, {BitTorrent::TorrentState::MissingFiles, tr("Missing Files")}, {BitTorrent::TorrentState::Error, tr("Errored", "Torrent status, the torrent has an error")} - } + } , 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(); connect(Preferences::instance(), &Preferences::changed, this, &TransferListModel::configure); @@ -796,3 +712,41 @@ void TransferListModel::configure() emit dataChanged(index(0, 0), index((rowCount() - 1), (columnCount() - 1))); } } + +QIcon TransferListModel::getIconByState(const BitTorrent::TorrentState state) const +{ + switch (state) + { + case BitTorrent::TorrentState::Downloading: + case BitTorrent::TorrentState::ForcedDownloading: + case BitTorrent::TorrentState::DownloadingMetadata: + case BitTorrent::TorrentState::ForcedDownloadingMetadata: + return m_downloadingIcon; + case BitTorrent::TorrentState::StalledDownloading: + return m_stalledDLIcon; + case BitTorrent::TorrentState::StalledUploading: + return m_stalledUPIcon; + case BitTorrent::TorrentState::Uploading: + case BitTorrent::TorrentState::ForcedUploading: + return m_uploadingIcon; + case BitTorrent::TorrentState::PausedDownloading: + return m_pausedIcon; + case BitTorrent::TorrentState::PausedUploading: + return m_completedIcon; + case BitTorrent::TorrentState::QueuedDownloading: + case BitTorrent::TorrentState::QueuedUploading: + return m_queuedIcon; + case BitTorrent::TorrentState::CheckingDownloading: + case BitTorrent::TorrentState::CheckingUploading: + case BitTorrent::TorrentState::CheckingResumeData: + case BitTorrent::TorrentState::Moving: + return m_checkingIcon; + case BitTorrent::TorrentState::Unknown: + case BitTorrent::TorrentState::MissingFiles: + case BitTorrent::TorrentState::Error: + return m_errorIcon; + default: + Q_ASSERT(false); + return m_errorIcon; + } +} diff --git a/src/gui/transferlistmodel.h b/src/gui/transferlistmodel.h index dcd52600d..d5f1550d1 100644 --- a/src/gui/transferlistmodel.h +++ b/src/gui/transferlistmodel.h @@ -32,6 +32,7 @@ #include #include #include +#include #include #include "base/bittorrent/torrent.h" @@ -111,6 +112,7 @@ private: void configure(); QString displayValue(const BitTorrent::Torrent *torrent, int column) const; QVariant internalValue(const BitTorrent::Torrent *torrent, int column, bool alt) const; + QIcon getIconByState(const BitTorrent::TorrentState state) const; QList m_torrentList; // maps row number to torrent handle QHash m_torrentMap; // maps torrent handle to row number @@ -126,4 +128,15 @@ private: }; 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; };