mirror of
https://github.com/qbittorrent/qBittorrent
synced 2025-07-13 16:53:08 -07:00
parent
25b7972f88
commit
ce013f132f
11 changed files with 195 additions and 126 deletions
|
@ -1,5 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* Bittorrent Client using Qt and libtorrent.
|
* Bittorrent Client using Qt and libtorrent.
|
||||||
|
* Copyright (C) 2024 Vladimir Golovnev <glassez@yandex.ru>
|
||||||
* Copyright (C) 2020 Prince Gupta <jagannatharjun11@gmail.com>
|
* Copyright (C) 2020 Prince Gupta <jagannatharjun11@gmail.com>
|
||||||
* Copyright (C) 2019 sledgehammer999 <hammered999@gmail.com>
|
* Copyright (C) 2019 sledgehammer999 <hammered999@gmail.com>
|
||||||
*
|
*
|
||||||
|
@ -36,65 +37,26 @@
|
||||||
#include "base/global.h"
|
#include "base/global.h"
|
||||||
#include "gui/uithememanager.h"
|
#include "gui/uithememanager.h"
|
||||||
|
|
||||||
namespace
|
const int MAX_VISIBLE_MESSAGES = 20000;
|
||||||
{
|
|
||||||
const int MAX_VISIBLE_MESSAGES = 20000;
|
|
||||||
|
|
||||||
QColor getTimestampColor()
|
BaseLogModel::Message::Message(const QString &time, const QString &message, const Log::MsgType type)
|
||||||
{
|
: m_time {time}
|
||||||
return UIThemeManager::instance()->getColor(u"Log.TimeStamp"_s);
|
, m_message {message}
|
||||||
}
|
, m_type {type}
|
||||||
|
|
||||||
QColor getLogNormalColor()
|
|
||||||
{
|
|
||||||
return UIThemeManager::instance()->getColor(u"Log.Normal"_s);
|
|
||||||
}
|
|
||||||
|
|
||||||
QColor getLogInfoColor()
|
|
||||||
{
|
|
||||||
return UIThemeManager::instance()->getColor(u"Log.Info"_s);
|
|
||||||
}
|
|
||||||
|
|
||||||
QColor getLogWarningColor()
|
|
||||||
{
|
|
||||||
return UIThemeManager::instance()->getColor(u"Log.Warning"_s);
|
|
||||||
}
|
|
||||||
|
|
||||||
QColor getLogCriticalColor()
|
|
||||||
{
|
|
||||||
return UIThemeManager::instance()->getColor(u"Log.Critical"_s);
|
|
||||||
}
|
|
||||||
|
|
||||||
QColor getPeerBannedColor()
|
|
||||||
{
|
|
||||||
return UIThemeManager::instance()->getColor(u"Log.BannedPeer"_s);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
BaseLogModel::Message::Message(const QString &time, const QString &message, const QColor &foreground, const Log::MsgType type)
|
|
||||||
: m_time(time)
|
|
||||||
, m_message(message)
|
|
||||||
, m_foreground(foreground)
|
|
||||||
, m_type(type)
|
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
QVariant BaseLogModel::Message::time() const
|
QString BaseLogModel::Message::time() const
|
||||||
{
|
{
|
||||||
return m_time;
|
return m_time;
|
||||||
}
|
}
|
||||||
|
|
||||||
QVariant BaseLogModel::Message::message() const
|
QString BaseLogModel::Message::message() const
|
||||||
{
|
{
|
||||||
return m_message;
|
return m_message;
|
||||||
}
|
}
|
||||||
|
|
||||||
QVariant BaseLogModel::Message::foreground() const
|
Log::MsgType BaseLogModel::Message::type() const
|
||||||
{
|
|
||||||
return m_foreground;
|
|
||||||
}
|
|
||||||
|
|
||||||
QVariant BaseLogModel::Message::type() const
|
|
||||||
{
|
{
|
||||||
return m_type;
|
return m_type;
|
||||||
}
|
}
|
||||||
|
@ -102,8 +64,9 @@ QVariant BaseLogModel::Message::type() const
|
||||||
BaseLogModel::BaseLogModel(QObject *parent)
|
BaseLogModel::BaseLogModel(QObject *parent)
|
||||||
: QAbstractListModel(parent)
|
: QAbstractListModel(parent)
|
||||||
, m_messages(MAX_VISIBLE_MESSAGES)
|
, m_messages(MAX_VISIBLE_MESSAGES)
|
||||||
, m_timeForeground(getTimestampColor())
|
|
||||||
{
|
{
|
||||||
|
loadColors();
|
||||||
|
connect(UIThemeManager::instance(), &UIThemeManager::themeChanged, this, &BaseLogModel::onUIThemeChanged);
|
||||||
}
|
}
|
||||||
|
|
||||||
int BaseLogModel::rowCount(const QModelIndex &) const
|
int BaseLogModel::rowCount(const QModelIndex &) const
|
||||||
|
@ -135,7 +98,7 @@ QVariant BaseLogModel::data(const QModelIndex &index, const int role) const
|
||||||
case TimeForegroundRole:
|
case TimeForegroundRole:
|
||||||
return m_timeForeground;
|
return m_timeForeground;
|
||||||
case MessageForegroundRole:
|
case MessageForegroundRole:
|
||||||
return message.foreground();
|
return messageForeground(message);
|
||||||
case TypeRole:
|
case TypeRole:
|
||||||
return message.type();
|
return message.type();
|
||||||
default:
|
default:
|
||||||
|
@ -160,6 +123,17 @@ void BaseLogModel::addNewMessage(const BaseLogModel::Message &message)
|
||||||
endInsertRows();
|
endInsertRows();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void BaseLogModel::onUIThemeChanged()
|
||||||
|
{
|
||||||
|
loadColors();
|
||||||
|
emit dataChanged(index(0, 0), index((rowCount() - 1), (columnCount() - 1)), {TimeForegroundRole, MessageForegroundRole});
|
||||||
|
}
|
||||||
|
|
||||||
|
void BaseLogModel::loadColors()
|
||||||
|
{
|
||||||
|
m_timeForeground = UIThemeManager::instance()->getColor(u"Log.TimeStamp"_s);
|
||||||
|
}
|
||||||
|
|
||||||
void BaseLogModel::reset()
|
void BaseLogModel::reset()
|
||||||
{
|
{
|
||||||
beginResetModel();
|
beginResetModel();
|
||||||
|
@ -169,14 +143,9 @@ void BaseLogModel::reset()
|
||||||
|
|
||||||
LogMessageModel::LogMessageModel(QObject *parent)
|
LogMessageModel::LogMessageModel(QObject *parent)
|
||||||
: BaseLogModel(parent)
|
: BaseLogModel(parent)
|
||||||
, m_foregroundForMessageTypes
|
|
||||||
{
|
|
||||||
{Log::NORMAL, getLogNormalColor()},
|
|
||||||
{Log::INFO, getLogInfoColor()},
|
|
||||||
{Log::WARNING, getLogWarningColor()},
|
|
||||||
{Log::CRITICAL, getLogCriticalColor()}
|
|
||||||
}
|
|
||||||
{
|
{
|
||||||
|
loadColors();
|
||||||
|
|
||||||
for (const Log::Msg &msg : asConst(Logger::instance()->getMessages()))
|
for (const Log::Msg &msg : asConst(Logger::instance()->getMessages()))
|
||||||
handleNewMessage(msg);
|
handleNewMessage(msg);
|
||||||
connect(Logger::instance(), &Logger::newLogMessage, this, &LogMessageModel::handleNewMessage);
|
connect(Logger::instance(), &Logger::newLogMessage, this, &LogMessageModel::handleNewMessage);
|
||||||
|
@ -185,16 +154,38 @@ LogMessageModel::LogMessageModel(QObject *parent)
|
||||||
void LogMessageModel::handleNewMessage(const Log::Msg &message)
|
void LogMessageModel::handleNewMessage(const Log::Msg &message)
|
||||||
{
|
{
|
||||||
const QString time = QLocale::system().toString(QDateTime::fromSecsSinceEpoch(message.timestamp), QLocale::ShortFormat);
|
const QString time = QLocale::system().toString(QDateTime::fromSecsSinceEpoch(message.timestamp), QLocale::ShortFormat);
|
||||||
const QString messageText = message.message;
|
addNewMessage({time, message.message, message.type});
|
||||||
const QColor foreground = m_foregroundForMessageTypes[message.type];
|
}
|
||||||
|
|
||||||
addNewMessage({time, messageText, foreground, message.type});
|
QColor LogMessageModel::messageForeground(const Message &message) const
|
||||||
|
{
|
||||||
|
return m_foregroundForMessageTypes.value(message.type());
|
||||||
|
}
|
||||||
|
|
||||||
|
void LogMessageModel::onUIThemeChanged()
|
||||||
|
{
|
||||||
|
loadColors();
|
||||||
|
BaseLogModel::onUIThemeChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
void LogMessageModel::loadColors()
|
||||||
|
{
|
||||||
|
const auto *themeManager = UIThemeManager::instance();
|
||||||
|
const QColor normalColor = themeManager->getColor(u"Log.Normal"_s);
|
||||||
|
m_foregroundForMessageTypes =
|
||||||
|
{
|
||||||
|
{Log::NORMAL, normalColor.isValid() ? normalColor : QApplication::palette().color(QPalette::Active, QPalette::WindowText)},
|
||||||
|
{Log::INFO, themeManager->getColor(u"Log.Info"_s)},
|
||||||
|
{Log::WARNING, themeManager->getColor(u"Log.Warning"_s)},
|
||||||
|
{Log::CRITICAL, themeManager->getColor(u"Log.Critical"_s)}
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
LogPeerModel::LogPeerModel(QObject *parent)
|
LogPeerModel::LogPeerModel(QObject *parent)
|
||||||
: BaseLogModel(parent)
|
: BaseLogModel(parent)
|
||||||
, m_bannedPeerForeground(getPeerBannedColor())
|
|
||||||
{
|
{
|
||||||
|
loadColors();
|
||||||
|
|
||||||
for (const Log::Peer &peer : asConst(Logger::instance()->getPeers()))
|
for (const Log::Peer &peer : asConst(Logger::instance()->getPeers()))
|
||||||
handleNewMessage(peer);
|
handleNewMessage(peer);
|
||||||
connect(Logger::instance(), &Logger::newLogPeer, this, &LogPeerModel::handleNewMessage);
|
connect(Logger::instance(), &Logger::newLogPeer, this, &LogPeerModel::handleNewMessage);
|
||||||
|
@ -207,5 +198,21 @@ void LogPeerModel::handleNewMessage(const Log::Peer &peer)
|
||||||
? tr("%1 was blocked. Reason: %2.", "0.0.0.0 was blocked. Reason: reason for blocking.").arg(peer.ip, peer.reason)
|
? tr("%1 was blocked. Reason: %2.", "0.0.0.0 was blocked. Reason: reason for blocking.").arg(peer.ip, peer.reason)
|
||||||
: tr("%1 was banned", "0.0.0.0 was banned").arg(peer.ip);
|
: tr("%1 was banned", "0.0.0.0 was banned").arg(peer.ip);
|
||||||
|
|
||||||
addNewMessage({time, message, m_bannedPeerForeground, Log::NORMAL});
|
addNewMessage({time, message, Log::NORMAL});
|
||||||
|
}
|
||||||
|
|
||||||
|
QColor LogPeerModel::messageForeground([[maybe_unused]] const Message &message) const
|
||||||
|
{
|
||||||
|
return m_bannedPeerForeground;
|
||||||
|
}
|
||||||
|
|
||||||
|
void LogPeerModel::onUIThemeChanged()
|
||||||
|
{
|
||||||
|
loadColors();
|
||||||
|
BaseLogModel::onUIThemeChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
void LogPeerModel::loadColors()
|
||||||
|
{
|
||||||
|
m_bannedPeerForeground = UIThemeManager::instance()->getColor(u"Log.BannedPeer"_s);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* Bittorrent Client using Qt and libtorrent.
|
* Bittorrent Client using Qt and libtorrent.
|
||||||
|
* Copyright (C) 2024 Vladimir Golovnev <glassez@yandex.ru>
|
||||||
* Copyright (C) 2020 Prince Gupta <jagannatharjun11@gmail.com>
|
* Copyright (C) 2020 Prince Gupta <jagannatharjun11@gmail.com>
|
||||||
* Copyright (C) 2019 sledgehammer999 <hammered999@gmail.com>
|
* Copyright (C) 2019 sledgehammer999 <hammered999@gmail.com>
|
||||||
*
|
*
|
||||||
|
@ -62,25 +63,27 @@ protected:
|
||||||
class Message
|
class Message
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Message(const QString &time, const QString &message, const QColor &foreground, Log::MsgType type);
|
Message(const QString &time, const QString &message, Log::MsgType type);
|
||||||
|
|
||||||
QVariant time() const;
|
QString time() const;
|
||||||
QVariant message() const;
|
QString message() const;
|
||||||
QVariant foreground() const;
|
Log::MsgType type() const;
|
||||||
QVariant type() const;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QVariant m_time;
|
QString m_time;
|
||||||
QVariant m_message;
|
QString m_message;
|
||||||
QVariant m_foreground;
|
Log::MsgType m_type;
|
||||||
QVariant m_type;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
void addNewMessage(const Message &message);
|
void addNewMessage(const Message &message);
|
||||||
|
virtual QColor messageForeground(const Message &message) const = 0;
|
||||||
|
virtual void onUIThemeChanged();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
void loadColors();
|
||||||
|
|
||||||
boost::circular_buffer_space_optimized<Message> m_messages;
|
boost::circular_buffer_space_optimized<Message> m_messages;
|
||||||
const QColor m_timeForeground;
|
QColor m_timeForeground;
|
||||||
};
|
};
|
||||||
|
|
||||||
class LogMessageModel : public BaseLogModel
|
class LogMessageModel : public BaseLogModel
|
||||||
|
@ -95,7 +98,11 @@ private slots:
|
||||||
void handleNewMessage(const Log::Msg &message);
|
void handleNewMessage(const Log::Msg &message);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const QHash<int, QColor> m_foregroundForMessageTypes;
|
QColor messageForeground(const Message &message) const override;
|
||||||
|
void onUIThemeChanged() override;
|
||||||
|
void loadColors();
|
||||||
|
|
||||||
|
QHash<int, QColor> m_foregroundForMessageTypes;
|
||||||
};
|
};
|
||||||
|
|
||||||
class LogPeerModel : public BaseLogModel
|
class LogPeerModel : public BaseLogModel
|
||||||
|
@ -110,5 +117,9 @@ private slots:
|
||||||
void handleNewMessage(const Log::Peer &peer);
|
void handleNewMessage(const Log::Peer &peer);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const QColor m_bannedPeerForeground;
|
QColor messageForeground(const Message &message) const override;
|
||||||
|
void onUIThemeChanged() override;
|
||||||
|
void loadColors();
|
||||||
|
|
||||||
|
QColor m_bannedPeerForeground;
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* Bittorrent Client using Qt and libtorrent.
|
* Bittorrent Client using Qt and libtorrent.
|
||||||
* Copyright (C) 2017 Vladimir Golovnev <glassez@yandex.ru>
|
* Copyright (C) 2017-2024 Vladimir Golovnev <glassez@yandex.ru>
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License
|
* modify it under the terms of the GNU General Public License
|
||||||
|
@ -28,6 +28,7 @@
|
||||||
|
|
||||||
#include "articlelistwidget.h"
|
#include "articlelistwidget.h"
|
||||||
|
|
||||||
|
#include <QApplication>
|
||||||
#include <QListWidgetItem>
|
#include <QListWidgetItem>
|
||||||
|
|
||||||
#include "base/global.h"
|
#include "base/global.h"
|
||||||
|
@ -42,6 +43,12 @@ ArticleListWidget::ArticleListWidget(QWidget *parent)
|
||||||
setSelectionMode(QAbstractItemView::ExtendedSelection);
|
setSelectionMode(QAbstractItemView::ExtendedSelection);
|
||||||
|
|
||||||
checkInvariant();
|
checkInvariant();
|
||||||
|
|
||||||
|
connect(UIThemeManager::instance(), &UIThemeManager::themeChanged, this, [this]
|
||||||
|
{
|
||||||
|
for (int row = 0; row < count(); ++row)
|
||||||
|
applyUITheme(item(row));
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
RSS::Article *ArticleListWidget::getRSSArticle(QListWidgetItem *item) const
|
RSS::Article *ArticleListWidget::getRSSArticle(QListWidgetItem *item) const
|
||||||
|
@ -100,11 +107,10 @@ void ArticleListWidget::handleArticleAdded(RSS::Article *rssArticle)
|
||||||
void ArticleListWidget::handleArticleRead(RSS::Article *rssArticle)
|
void ArticleListWidget::handleArticleRead(RSS::Article *rssArticle)
|
||||||
{
|
{
|
||||||
auto *item = mapRSSArticle(rssArticle);
|
auto *item = mapRSSArticle(rssArticle);
|
||||||
if (!item) return;
|
if (!item)
|
||||||
|
return;
|
||||||
|
|
||||||
const QBrush foregroundBrush {UIThemeManager::instance()->getColor(u"RSS.ReadArticle"_s)};
|
applyUITheme(item);
|
||||||
item->setData(Qt::ForegroundRole, foregroundBrush);
|
|
||||||
item->setData(Qt::DecorationRole, UIThemeManager::instance()->getIcon(u"rss_read_article"_s, u"sphere"_s));
|
|
||||||
|
|
||||||
checkInvariant();
|
checkInvariant();
|
||||||
}
|
}
|
||||||
|
@ -127,18 +133,25 @@ QListWidgetItem *ArticleListWidget::createItem(RSS::Article *article) const
|
||||||
|
|
||||||
item->setData(Qt::DisplayRole, article->title());
|
item->setData(Qt::DisplayRole, article->title());
|
||||||
item->setData(Qt::UserRole, QVariant::fromValue(article));
|
item->setData(Qt::UserRole, QVariant::fromValue(article));
|
||||||
if (article->isRead())
|
applyUITheme(item);
|
||||||
{
|
|
||||||
const QBrush foregroundBrush {UIThemeManager::instance()->getColor(u"RSS.ReadArticle"_s)};
|
|
||||||
item->setData(Qt::ForegroundRole, foregroundBrush);
|
|
||||||
item->setData(Qt::DecorationRole, UIThemeManager::instance()->getIcon(u"rss_read_article"_s, u"sphere"_s));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
const QBrush foregroundBrush {UIThemeManager::instance()->getColor(u"RSS.UnreadArticle"_s)};
|
|
||||||
item->setData(Qt::ForegroundRole, foregroundBrush);
|
|
||||||
item->setData(Qt::DecorationRole, UIThemeManager::instance()->getIcon(u"rss_unread_article"_s, u"sphere"_s));
|
|
||||||
}
|
|
||||||
|
|
||||||
return item;
|
return item;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ArticleListWidget::applyUITheme(QListWidgetItem *item) const
|
||||||
|
{
|
||||||
|
const bool isRead = getRSSArticle(item)->isRead();
|
||||||
|
const auto *themeManager = UIThemeManager::instance();
|
||||||
|
if (isRead)
|
||||||
|
{
|
||||||
|
const QColor color = themeManager->getColor(u"RSS.ReadArticle"_s);
|
||||||
|
item->setData(Qt::ForegroundRole, (color.isValid() ? color : QApplication::palette().color(QPalette::Inactive, QPalette::WindowText)));
|
||||||
|
item->setData(Qt::DecorationRole, themeManager->getIcon(u"rss_read_article"_s, u"sphere"_s));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
const QColor color = themeManager->getColor(u"RSS.UnreadArticle"_s);
|
||||||
|
item->setData(Qt::ForegroundRole, (color.isValid() ? color : QApplication::palette().color(QPalette::Active, QPalette::Link)));
|
||||||
|
item->setData(Qt::DecorationRole, themeManager->getIcon(u"rss_unread_article"_s, u"sphere"_s));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* Bittorrent Client using Qt and libtorrent.
|
* Bittorrent Client using Qt and libtorrent.
|
||||||
* Copyright (C) 2017 Vladimir Golovnev <glassez@yandex.ru>
|
* Copyright (C) 2017-2024 Vladimir Golovnev <glassez@yandex.ru>
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License
|
* modify it under the terms of the GNU General Public License
|
||||||
|
@ -58,6 +58,7 @@ private slots:
|
||||||
private:
|
private:
|
||||||
void checkInvariant() const;
|
void checkInvariant() const;
|
||||||
QListWidgetItem *createItem(RSS::Article *article) const;
|
QListWidgetItem *createItem(RSS::Article *article) const;
|
||||||
|
void applyUITheme(QListWidgetItem *item) const;
|
||||||
|
|
||||||
RSS::Item *m_rssItem = nullptr;
|
RSS::Item *m_rssItem = nullptr;
|
||||||
bool m_unreadOnly = false;
|
bool m_unreadOnly = false;
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* Bittorrent Client using Qt and libtorrent.
|
* Bittorrent Client using Qt and libtorrent.
|
||||||
* Copyright (C) 2015 Vladimir Golovnev <glassez@yandex.ru>
|
* Copyright (C) 2015-2024 Vladimir Golovnev <glassez@yandex.ru>
|
||||||
* Copyright (C) 2010 Christophe Dumez <chris@qbittorrent.org>
|
* Copyright (C) 2010 Christophe Dumez <chris@qbittorrent.org>
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
|
@ -112,21 +112,17 @@ TransferListModel::TransferListModel(QObject *parent)
|
||||||
{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_checkingIcon {UIThemeManager::instance()->getIcon(u"force-recheck"_s, u"checking"_s)}
|
|
||||||
, m_completedIcon {UIThemeManager::instance()->getIcon(u"checked-completed"_s, u"completed"_s)}
|
|
||||||
, m_downloadingIcon {UIThemeManager::instance()->getIcon(u"downloading"_s)}
|
|
||||||
, m_errorIcon {UIThemeManager::instance()->getIcon(u"error"_s)}
|
|
||||||
, m_movingIcon {UIThemeManager::instance()->getIcon(u"set-location"_s)}
|
|
||||||
, m_pausedIcon {UIThemeManager::instance()->getIcon(u"stopped"_s, u"media-playback-pause"_s)}
|
|
||||||
, m_queuedIcon {UIThemeManager::instance()->getIcon(u"queued"_s)}
|
|
||||||
, m_stalledDLIcon {UIThemeManager::instance()->getIcon(u"stalledDL"_s)}
|
|
||||||
, m_stalledUPIcon {UIThemeManager::instance()->getIcon(u"stalledUP"_s)}
|
|
||||||
, m_uploadingIcon {UIThemeManager::instance()->getIcon(u"upload"_s, u"uploading"_s)}
|
|
||||||
{
|
{
|
||||||
configure();
|
configure();
|
||||||
connect(Preferences::instance(), &Preferences::changed, this, &TransferListModel::configure);
|
connect(Preferences::instance(), &Preferences::changed, this, &TransferListModel::configure);
|
||||||
|
|
||||||
|
loadUIThemeResources();
|
||||||
|
connect(UIThemeManager::instance(), &UIThemeManager::themeChanged, this, [this]
|
||||||
|
{
|
||||||
|
loadUIThemeResources();
|
||||||
|
emit dataChanged(index(0, 0), index((rowCount() - 1), (columnCount() - 1)), {Qt::DecorationRole, Qt::ForegroundRole});
|
||||||
|
});
|
||||||
|
|
||||||
// Load the torrents
|
// Load the torrents
|
||||||
using namespace BitTorrent;
|
using namespace BitTorrent;
|
||||||
addTorrents(Session::instance()->torrents());
|
addTorrents(Session::instance()->torrents());
|
||||||
|
@ -699,6 +695,23 @@ void TransferListModel::configure()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TransferListModel::loadUIThemeResources()
|
||||||
|
{
|
||||||
|
m_stateThemeColors = torrentStateColorsFromUITheme();
|
||||||
|
|
||||||
|
const auto *themeManager = UIThemeManager::instance();
|
||||||
|
m_checkingIcon = themeManager->getIcon(u"force-recheck"_s, u"checking"_s);
|
||||||
|
m_completedIcon = themeManager->getIcon(u"checked-completed"_s, u"completed"_s);
|
||||||
|
m_downloadingIcon = themeManager->getIcon(u"downloading"_s);
|
||||||
|
m_errorIcon = themeManager->getIcon(u"error"_s);
|
||||||
|
m_movingIcon = themeManager->getIcon(u"set-location"_s);
|
||||||
|
m_pausedIcon = themeManager->getIcon(u"stopped"_s, u"media-playback-pause"_s);
|
||||||
|
m_queuedIcon = themeManager->getIcon(u"queued"_s);
|
||||||
|
m_stalledDLIcon = themeManager->getIcon(u"stalledDL"_s);
|
||||||
|
m_stalledUPIcon = themeManager->getIcon(u"stalledUP"_s);
|
||||||
|
m_uploadingIcon = themeManager->getIcon(u"upload"_s, u"uploading"_s);
|
||||||
|
}
|
||||||
|
|
||||||
QIcon TransferListModel::getIconByState(const BitTorrent::TorrentState state) const
|
QIcon TransferListModel::getIconByState(const BitTorrent::TorrentState state) const
|
||||||
{
|
{
|
||||||
switch (state)
|
switch (state)
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* Bittorrent Client using Qt and libtorrent.
|
* Bittorrent Client using Qt and libtorrent.
|
||||||
* Copyright (C) 2015 Vladimir Golovnev <glassez@yandex.ru>
|
* Copyright (C) 2015-2024 Vladimir Golovnev <glassez@yandex.ru>
|
||||||
* Copyright (C) 2010 Christophe Dumez <chris@qbittorrent.org>
|
* Copyright (C) 2010 Christophe Dumez <chris@qbittorrent.org>
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
|
@ -114,6 +114,7 @@ private slots:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void configure();
|
void configure();
|
||||||
|
void loadUIThemeResources();
|
||||||
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(BitTorrent::TorrentState state) const;
|
QIcon getIconByState(BitTorrent::TorrentState state) const;
|
||||||
|
@ -122,7 +123,7 @@ private:
|
||||||
QHash<BitTorrent::Torrent *, int> m_torrentMap; // maps torrent handle to row number
|
QHash<BitTorrent::Torrent *, int> m_torrentMap; // maps torrent handle to row number
|
||||||
const QHash<BitTorrent::TorrentState, QString> m_statusStrings;
|
const QHash<BitTorrent::TorrentState, QString> m_statusStrings;
|
||||||
// row text colors
|
// row text colors
|
||||||
const QHash<BitTorrent::TorrentState, QColor> m_stateThemeColors;
|
QHash<BitTorrent::TorrentState, QColor> m_stateThemeColors;
|
||||||
|
|
||||||
enum class HideZeroValuesMode
|
enum class HideZeroValuesMode
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* Bittorrent Client using Qt and libtorrent.
|
* Bittorrent Client using Qt and libtorrent.
|
||||||
* Copyright (C) 2023 Vladimir Golovnev <glassez@yandex.ru>
|
* Copyright (C) 2023-2024 Vladimir Golovnev <glassez@yandex.ru>
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License
|
* modify it under the terms of the GNU General Public License
|
||||||
|
@ -29,7 +29,6 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <QApplication>
|
|
||||||
#include <QColor>
|
#include <QColor>
|
||||||
#include <QHash>
|
#include <QHash>
|
||||||
#include <QPalette>
|
#include <QPalette>
|
||||||
|
@ -53,17 +52,16 @@ struct UIThemeColor
|
||||||
|
|
||||||
inline QHash<QString, UIThemeColor> defaultUIThemeColors()
|
inline QHash<QString, UIThemeColor> defaultUIThemeColors()
|
||||||
{
|
{
|
||||||
const QPalette palette = QApplication::palette();
|
|
||||||
return {
|
return {
|
||||||
{u"Log.TimeStamp"_s, {Color::Primer::Light::fgSubtle, Color::Primer::Dark::fgSubtle}},
|
{u"Log.TimeStamp"_s, {Color::Primer::Light::fgSubtle, Color::Primer::Dark::fgSubtle}},
|
||||||
{u"Log.Normal"_s, {palette.color(QPalette::Active, QPalette::WindowText), palette.color(QPalette::Active, QPalette::WindowText)}},
|
{u"Log.Normal"_s, {{}, {}}},
|
||||||
{u"Log.Info"_s, {Color::Primer::Light::accentFg, Color::Primer::Dark::accentFg}},
|
{u"Log.Info"_s, {Color::Primer::Light::accentFg, Color::Primer::Dark::accentFg}},
|
||||||
{u"Log.Warning"_s, {Color::Primer::Light::severeFg, Color::Primer::Dark::severeFg}},
|
{u"Log.Warning"_s, {Color::Primer::Light::severeFg, Color::Primer::Dark::severeFg}},
|
||||||
{u"Log.Critical"_s, {Color::Primer::Light::dangerFg, Color::Primer::Dark::dangerFg}},
|
{u"Log.Critical"_s, {Color::Primer::Light::dangerFg, Color::Primer::Dark::dangerFg}},
|
||||||
{u"Log.BannedPeer"_s, {Color::Primer::Light::dangerFg, Color::Primer::Dark::dangerFg}},
|
{u"Log.BannedPeer"_s, {Color::Primer::Light::dangerFg, Color::Primer::Dark::dangerFg}},
|
||||||
|
|
||||||
{u"RSS.ReadArticle"_s, {palette.color(QPalette::Inactive, QPalette::WindowText), palette.color(QPalette::Inactive, QPalette::WindowText)}},
|
{u"RSS.ReadArticle"_s, {{}, {}}},
|
||||||
{u"RSS.UnreadArticle"_s, {palette.color(QPalette::Active, QPalette::Link), palette.color(QPalette::Active, QPalette::Link)}},
|
{u"RSS.UnreadArticle"_s, {{}, {}}},
|
||||||
|
|
||||||
{u"TransferList.Downloading"_s, {Color::Primer::Light::successFg, Color::Primer::Dark::successFg}},
|
{u"TransferList.Downloading"_s, {Color::Primer::Light::successFg, Color::Primer::Dark::successFg}},
|
||||||
{u"TransferList.StalledDownloading"_s, {Color::Primer::Light::successEmphasis, Color::Primer::Dark::successEmphasis}},
|
{u"TransferList.StalledDownloading"_s, {Color::Primer::Light::successEmphasis, Color::Primer::Dark::successEmphasis}},
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* Bittorrent Client using Qt and libtorrent.
|
* Bittorrent Client using Qt and libtorrent.
|
||||||
* Copyright (C) 2023 Vladimir Golovnev <glassez@yandex.ru>
|
* Copyright (C) 2023-2024 Vladimir Golovnev <glassez@yandex.ru>
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License
|
* modify it under the terms of the GNU General Public License
|
||||||
|
@ -64,21 +64,23 @@ namespace
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class ColorWidget final : public QFrame
|
class ColorWidget final : public QLabel
|
||||||
{
|
{
|
||||||
Q_DISABLE_COPY_MOVE(ColorWidget)
|
Q_DISABLE_COPY_MOVE(ColorWidget)
|
||||||
Q_DECLARE_TR_FUNCTIONS(ColorWidget)
|
Q_DECLARE_TR_FUNCTIONS(ColorWidget)
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit ColorWidget(const QColor ¤tColor, const QColor &defaultColor, QWidget *parent = nullptr)
|
explicit ColorWidget(const QColor ¤tColor, const QColor &defaultColor, QWidget *parent = nullptr)
|
||||||
: QFrame(parent)
|
: QLabel(parent)
|
||||||
, m_defaultColor {defaultColor}
|
, m_defaultColor {defaultColor}
|
||||||
|
, m_currentColor {currentColor}
|
||||||
{
|
{
|
||||||
setObjectName(u"colorWidget"_s);
|
setObjectName(u"colorWidget"_s);
|
||||||
setFrameShape(QFrame::Box);
|
setFrameShape(QFrame::Box);
|
||||||
setFrameShadow(QFrame::Plain);
|
setFrameShadow(QFrame::Plain);
|
||||||
|
setAlignment(Qt::AlignCenter);
|
||||||
|
|
||||||
setCurrentColor(currentColor);
|
applyColor(currentColor);
|
||||||
}
|
}
|
||||||
|
|
||||||
QColor currentColor() const
|
QColor currentColor() const
|
||||||
|
@ -119,7 +121,16 @@ private:
|
||||||
|
|
||||||
void applyColor(const QColor &color)
|
void applyColor(const QColor &color)
|
||||||
{
|
{
|
||||||
setStyleSheet(u"#colorWidget { background-color: %1; }"_s.arg(color.name()));
|
if (color.isValid())
|
||||||
|
{
|
||||||
|
setStyleSheet(u"#colorWidget { background-color: %1; }"_s.arg(color.name()));
|
||||||
|
setText({});
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
setStyleSheet({});
|
||||||
|
setText(tr("System"));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void showColorDialog()
|
void showColorDialog()
|
||||||
|
@ -262,6 +273,8 @@ void UIThemeDialog::loadColors()
|
||||||
int row = 2;
|
int row = 2;
|
||||||
for (const QString &id : colorIDs)
|
for (const QString &id : colorIDs)
|
||||||
{
|
{
|
||||||
|
if (id == u"Log.Normal")
|
||||||
|
qDebug() << "!!!!!!!";
|
||||||
m_ui->colorsLayout->addWidget(new QLabel(id), row, 0);
|
m_ui->colorsLayout->addWidget(new QLabel(id), row, 0);
|
||||||
|
|
||||||
const UIThemeColor &defaultColor = defaultColors.value(id);
|
const UIThemeColor &defaultColor = defaultColors.value(id);
|
||||||
|
|
|
@ -30,6 +30,7 @@
|
||||||
|
|
||||||
#include "uithememanager.h"
|
#include "uithememanager.h"
|
||||||
|
|
||||||
|
#include <QApplication>
|
||||||
#include <QPalette>
|
#include <QPalette>
|
||||||
#include <QPixmapCache>
|
#include <QPixmapCache>
|
||||||
#include <QResource>
|
#include <QResource>
|
||||||
|
@ -79,11 +80,8 @@ UIThemeManager::UIThemeManager()
|
||||||
, m_useSystemIcons {Preferences::instance()->useSystemIcons()}
|
, m_useSystemIcons {Preferences::instance()->useSystemIcons()}
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
connect(QApplication::styleHints(), &QStyleHints::colorSchemeChanged, this, []
|
// NOTE: Qt::QueuedConnection can be omitted as soon as support for Qt 6.5 is dropped
|
||||||
{
|
connect(QApplication::styleHints(), &QStyleHints::colorSchemeChanged, this, &UIThemeManager::onColorSchemeChanged, Qt::QueuedConnection);
|
||||||
// workaround to refresh styled controls once color scheme is changed
|
|
||||||
QApplication::setStyle(QApplication::style()->name());
|
|
||||||
});
|
|
||||||
|
|
||||||
if (m_useCustomTheme)
|
if (m_useCustomTheme)
|
||||||
{
|
{
|
||||||
|
@ -122,6 +120,14 @@ void UIThemeManager::applyStyleSheet() const
|
||||||
qApp->setStyleSheet(QString::fromUtf8(m_themeSource->readStyleSheet()));
|
qApp->setStyleSheet(QString::fromUtf8(m_themeSource->readStyleSheet()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void UIThemeManager::onColorSchemeChanged()
|
||||||
|
{
|
||||||
|
emit themeChanged();
|
||||||
|
|
||||||
|
// workaround to refresh styled controls once color scheme is changed
|
||||||
|
QApplication::setStyle(QApplication::style()->name());
|
||||||
|
}
|
||||||
|
|
||||||
QIcon UIThemeManager::getIcon(const QString &iconId, [[maybe_unused]] const QString &fallback) const
|
QIcon UIThemeManager::getIcon(const QString &iconId, [[maybe_unused]] const QString &fallback) const
|
||||||
{
|
{
|
||||||
const auto colorMode = isDarkTheme() ? ColorMode::Dark : ColorMode::Light;
|
const auto colorMode = isDarkTheme() ? ColorMode::Dark : ColorMode::Light;
|
||||||
|
@ -184,8 +190,6 @@ QPixmap UIThemeManager::getScaledPixmap(const QString &iconId, const int height)
|
||||||
QColor UIThemeManager::getColor(const QString &id) const
|
QColor UIThemeManager::getColor(const QString &id) const
|
||||||
{
|
{
|
||||||
const QColor color = m_themeSource->getColor(id, (isDarkTheme() ? ColorMode::Dark : ColorMode::Light));
|
const QColor color = m_themeSource->getColor(id, (isDarkTheme() ? ColorMode::Dark : ColorMode::Light));
|
||||||
Q_ASSERT(color.isValid());
|
|
||||||
|
|
||||||
return color;
|
return color;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* Bittorrent Client using Qt and libtorrent.
|
* Bittorrent Client using Qt and libtorrent.
|
||||||
* Copyright (C) 2023 Vladimir Golovnev <glassez@yandex.ru>
|
* Copyright (C) 2023-2024 Vladimir Golovnev <glassez@yandex.ru>
|
||||||
* Copyright (C) 2019 Prince Gupta <jagannatharjun11@gmail.com>
|
* Copyright (C) 2019 Prince Gupta <jagannatharjun11@gmail.com>
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
|
@ -38,7 +38,6 @@
|
||||||
#include <QPixmap>
|
#include <QPixmap>
|
||||||
#include <QString>
|
#include <QString>
|
||||||
|
|
||||||
#include "base/pathfwd.h"
|
|
||||||
#include "uithemesource.h"
|
#include "uithemesource.h"
|
||||||
|
|
||||||
class UIThemeManager final : public QObject
|
class UIThemeManager final : public QObject
|
||||||
|
@ -57,11 +56,15 @@ public:
|
||||||
|
|
||||||
QColor getColor(const QString &id) const;
|
QColor getColor(const QString &id) const;
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void themeChanged();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
UIThemeManager(); // singleton class
|
UIThemeManager(); // singleton class
|
||||||
|
|
||||||
void applyPalette() const;
|
void applyPalette() const;
|
||||||
void applyStyleSheet() const;
|
void applyStyleSheet() const;
|
||||||
|
void onColorSchemeChanged();
|
||||||
|
|
||||||
static UIThemeManager *m_instance;
|
static UIThemeManager *m_instance;
|
||||||
const bool m_useCustomTheme;
|
const bool m_useCustomTheme;
|
||||||
|
|
|
@ -114,8 +114,13 @@ QByteArray DefaultThemeSource::readStyleSheet()
|
||||||
|
|
||||||
QColor DefaultThemeSource::getColor(const QString &colorId, const ColorMode colorMode) const
|
QColor DefaultThemeSource::getColor(const QString &colorId, const ColorMode colorMode) const
|
||||||
{
|
{
|
||||||
|
const auto iter = m_colors.constFind(colorId);
|
||||||
|
Q_ASSERT(iter != m_colors.constEnd());
|
||||||
|
if (iter == m_colors.constEnd()) [[unlikely]]
|
||||||
|
return {};
|
||||||
|
|
||||||
return (colorMode == ColorMode::Light)
|
return (colorMode == ColorMode::Light)
|
||||||
? m_colors.value(colorId).light : m_colors.value(colorId).dark;
|
? iter.value().light : iter.value().dark;
|
||||||
}
|
}
|
||||||
|
|
||||||
Path DefaultThemeSource::getIconPath(const QString &iconId, const ColorMode colorMode) const
|
Path DefaultThemeSource::getIconPath(const QString &iconId, const ColorMode colorMode) const
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue