Backport changes to v5.0.x branch

PR #22207.
This commit is contained in:
Vladimir Golovnev 2025-02-14 13:56:49 +03:00 committed by GitHub
commit 505c1e1c0a
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
7 changed files with 43 additions and 29 deletions

View file

@ -7,7 +7,7 @@ LangString inst_desktop ${LANG_PORTUGUESE} "Criar atalho no ambiente de trabalho
;LangString inst_startmenu ${LANG_ENGLISH} "Create Start Menu Shortcut"
LangString inst_startmenu ${LANG_PORTUGUESE} "Criar atalho no menu Iniciar"
;LangString inst_startup ${LANG_ENGLISH} "Start qBittorrent on Windows start up"
LangString inst_startup ${LANG_PORTUGUESE} "Iniciar o qBittorrent na inicialização do Windows"
LangString inst_startup ${LANG_PORTUGUESE} "Iniciar o qBittorrent no arranque do Windows"
;LangString inst_torrent ${LANG_ENGLISH} "Open .torrent files with qBittorrent"
LangString inst_torrent ${LANG_PORTUGUESE} "Abrir ficheiros .torrent com o qBittorrent"
;LangString inst_magnet ${LANG_ENGLISH} "Open magnet links with qBittorrent"
@ -29,7 +29,7 @@ LangString launch_qbt ${LANG_PORTUGUESE} "Iniciar qBittorrent."
;LangString inst_requires_64bit ${LANG_ENGLISH} "This installer works only in 64-bit Windows versions."
LangString inst_requires_64bit ${LANG_PORTUGUESE} "Este instalador funciona apenas em versões Windows de 64 bits."
;LangString inst_requires_win10 ${LANG_ENGLISH} "This installer requires at least Windows 10 (1809) / Windows Server 2019."
LangString inst_requires_win10 ${LANG_PORTUGUESE} "This installer requires at least Windows 10 (1809) / Windows Server 2019."
LangString inst_requires_win10 ${LANG_PORTUGUESE} "Este instalador requer, pelo menos, o Windows 10 (1809) / Windows Server 2019."
;LangString inst_uninstall_link_description ${LANG_ENGLISH} "Uninstall qBittorrent"
LangString inst_uninstall_link_description ${LANG_PORTUGUESE} "Desinstalar qBittorrent"

View file

@ -1,6 +1,6 @@
/*
* Bittorrent Client using Qt and libtorrent.
* Copyright (C) 2023-2024 Vladimir Golovnev <glassez@yandex.ru>
* Copyright (C) 2023-2025 Vladimir Golovnev <glassez@yandex.ru>
* Copyright (C) 2024 Jonathan Ketchker
* Copyright (C) 2006 Christophe Dumez <chris@qbittorrent.org>
*
@ -456,10 +456,7 @@ void OptionsDialog::saveBehaviorTabOptions() const
pref->setLocale(locale);
#ifdef Q_OS_WIN
if (const QVariant systemStyle = m_ui->comboStyle->currentData(); systemStyle.isValid())
pref->setStyle(systemStyle.toString());
else
pref->setStyle(m_ui->comboStyle->currentText());
pref->setStyle(m_ui->comboStyle->currentData().toString());
#endif
#if (defined(Q_OS_UNIX) && !defined(Q_OS_MACOS))
@ -1695,18 +1692,20 @@ void OptionsDialog::initializeStyleCombo()
{
#ifdef Q_OS_WIN
m_ui->labelStyleHint->setText(tr("%1 is recommended for best compatibility with Windows dark mode"
, "Fusion is recommended for best compatibility with Windows dark mode").arg(u"Fusion"_s));
, "Fusion is recommended for best compatibility with Windows dark mode").arg(u"Fusion"_s));
m_ui->comboStyle->addItem(tr("System", "System default Qt style"), u"system"_s);
m_ui->comboStyle->setItemData(0, tr("Let Qt decide the style for this system"), Qt::ToolTipRole);
m_ui->comboStyle->insertSeparator(1);
QStringList styleNames = QStyleFactory::keys();
std::sort(styleNames.begin(), styleNames.end(), Utils::Compare::NaturalLessThan<Qt::CaseInsensitive>());
m_ui->comboStyle->addItems(styleNames);
for (const QString &styleName : asConst(styleNames))
m_ui->comboStyle->addItem(styleName, styleName);
const QString prefStyleName = Preferences::instance()->getStyle();
const QString selectedStyleName = prefStyleName.isEmpty() ? QApplication::style()->name() : prefStyleName;
m_ui->comboStyle->setCurrentIndex(m_ui->comboStyle->findText(selectedStyleName, Qt::MatchFixedString));
const int styleIndex = m_ui->comboStyle->findData(selectedStyleName, Qt::UserRole, Qt::MatchFixedString);
m_ui->comboStyle->setCurrentIndex(std::max(0, styleIndex));
#else
m_ui->labelStyle->hide();
m_ui->comboStyle->hide();

View file

@ -420,7 +420,8 @@ void PeerListWidget::loadPeers(const BitTorrent::Torrent *torrent)
for (auto i = m_peerItems.cbegin(); i != m_peerItems.cend(); ++i)
existingPeers.insert(i.key());
const bool hideZeroValues = Preferences::instance()->getHideZeroValues();
const Preferences *pref = Preferences::instance();
const bool hideZeroValues = (pref->getHideZeroValues() && (pref->getHideZeroComboValues() == 0));
for (const BitTorrent::PeerInfo &peer : peers)
{
const PeerEndpoint peerEndpoint {peer.address(), peer.connectionType()};

View file

@ -398,7 +398,9 @@ QVariant TorrentContentModel::data(const QModelIndex &index, const int role) con
const bool hasIgnored = std::any_of(childItems.cbegin(), childItems.cend()
, [](const TorrentContentModelItem *childItem)
{
return (childItem->priority() == BitTorrent::DownloadPriority::Ignored);
const auto prio = childItem->priority();
return ((prio == BitTorrent::DownloadPriority::Ignored)
|| (prio == BitTorrent::DownloadPriority::Mixed));
});
return hasIgnored ? Qt::PartiallyChecked : Qt::Checked;

View file

@ -444,6 +444,16 @@ void TrackersFilterWidget::handleTrackerStatusesUpdated(const BitTorrent::Torren
trackerErrorHashesIt = m_trackerErrors.insert(id, {});
trackerErrorHashesIt->insert(trackerEntryStatus.url);
}
else if (trackerEntryStatus.state == BitTorrent::TrackerEndpointState::NotContacted)
{
// remove tracker from "error", "tracker error" and "warning" categories
if (warningHashesIt != m_warnings.end())
warningHashesIt->remove(trackerEntryStatus.url);
if (errorHashesIt != m_errors.end())
errorHashesIt->remove(trackerEntryStatus.url);
if (trackerErrorHashesIt != m_trackerErrors.end())
trackerErrorHashesIt->remove(trackerEntryStatus.url);
}
}
if ((errorHashesIt != m_errors.end()) && errorHashesIt->isEmpty())

View file

@ -49,7 +49,7 @@ void RSSController::addFolderAction()
{
requireParams({u"path"_s});
const QString path = params()[u"path"_s].trimmed();
const QString path = params()[u"path"_s];
const nonstd::expected<void, QString> result = RSS::Session::instance()->addFolder(path);
if (!result)
throw APIError(APIErrorType::Conflict, result.error());
@ -59,8 +59,8 @@ void RSSController::addFeedAction()
{
requireParams({u"url"_s, u"path"_s});
const QString url = params()[u"url"_s].trimmed();
const QString path = params()[u"path"_s].trimmed();
const QString url = params()[u"url"_s];
const QString path = params()[u"path"_s];
const nonstd::expected<void, QString> result = RSS::Session::instance()->addFeed(url, (path.isEmpty() ? url : path));
if (!result)
throw APIError(APIErrorType::Conflict, result.error());
@ -70,8 +70,8 @@ void RSSController::setFeedURLAction()
{
requireParams({u"path"_s, u"url"_s});
const QString path = params()[u"path"_s].trimmed();
const QString url = params()[u"url"_s].trimmed();
const QString path = params()[u"path"_s];
const QString url = params()[u"url"_s];
const nonstd::expected<void, QString> result = RSS::Session::instance()->setFeedURL(path, url);
if (!result)
throw APIError(APIErrorType::Conflict, result.error());
@ -81,7 +81,7 @@ void RSSController::removeItemAction()
{
requireParams({u"path"_s});
const QString path = params()[u"path"_s].trimmed();
const QString path = params()[u"path"_s];
const nonstd::expected<void, QString> result = RSS::Session::instance()->removeItem(path);
if (!result)
throw APIError(APIErrorType::Conflict, result.error());
@ -91,8 +91,8 @@ void RSSController::moveItemAction()
{
requireParams({u"itemPath"_s, u"destPath"_s});
const QString itemPath = params()[u"itemPath"_s].trimmed();
const QString destPath = params()[u"destPath"_s].trimmed();
const QString itemPath = params()[u"itemPath"_s];
const QString destPath = params()[u"destPath"_s];
const nonstd::expected<void, QString> result = RSS::Session::instance()->moveItem(itemPath, destPath);
if (!result)
throw APIError(APIErrorType::Conflict, result.error());
@ -146,8 +146,8 @@ void RSSController::setRuleAction()
{
requireParams({u"ruleName"_s, u"ruleDef"_s});
const QString ruleName {params()[u"ruleName"_s].trimmed()};
const QByteArray ruleDef {params()[u"ruleDef"_s].trimmed().toUtf8()};
const QString ruleName {params()[u"ruleName"_s]};
const QByteArray ruleDef {params()[u"ruleDef"_s].toUtf8()};
const auto jsonObj = QJsonDocument::fromJson(ruleDef).object();
RSS::AutoDownloader::instance()->setRule(RSS::AutoDownloadRule::fromJsonObject(jsonObj, ruleName));
@ -157,8 +157,8 @@ void RSSController::renameRuleAction()
{
requireParams({u"ruleName"_s, u"newRuleName"_s});
const QString ruleName {params()[u"ruleName"_s].trimmed()};
const QString newRuleName {params()[u"newRuleName"_s].trimmed()};
const QString ruleName {params()[u"ruleName"_s]};
const QString newRuleName {params()[u"newRuleName"_s]};
RSS::AutoDownloader::instance()->renameRule(ruleName, newRuleName);
}
@ -167,7 +167,7 @@ void RSSController::removeRuleAction()
{
requireParams({u"ruleName"_s});
const QString ruleName {params()[u"ruleName"_s].trimmed()};
const QString ruleName {params()[u"ruleName"_s]};
RSS::AutoDownloader::instance()->removeRule(ruleName);
}

View file

@ -74,7 +74,6 @@ window.qBittorrent.ContextMenu = (function() {
// option diffs menu
this.menu = $(this.options.menu);
this.targets = $$(this.options.targets);
// fx
this.fx = new Fx.Tween(this.menu, {
@ -185,11 +184,14 @@ window.qBittorrent.ContextMenu = (function() {
},
addTarget: function(t) {
if (t.hasEventListeners)
return;
// prevent long press from selecting this text
t.style.setProperty("user-select", "none");
t.style.setProperty("-webkit-user-select", "none");
t.hasEventListeners = true;
this.targets[this.targets.length] = t;
this.setupEventListeners(t);
},
@ -210,8 +212,8 @@ window.qBittorrent.ContextMenu = (function() {
// get things started
startListener: function() {
/* all elements */
this.targets.each((el) => {
this.setupEventListeners(el);
$$(this.options.targets).each((el) => {
this.addTarget(el);
}, this);
/* menu items */