1
mirror of https://github.com/qbittorrent/qBittorrent synced 2025-10-19 05:12:18 +02:00

Compare commits

..

23 Commits

Author SHA1 Message Date
sledgehammer999
91943e4815 Merge pull request #21808 from sledgehammer999/backport_ssl
Don't ignore SSL errors (v4_6_x)

Backport of PR #21364
2024-11-09 15:28:03 +02:00
sledgehammer999
2388ad0aab Reorder code to match UI 2024-11-09 12:11:58 +02:00
sledgehammer999
a65eb6c604 Don't ignore SSL errors 2024-11-09 12:05:37 +02:00
sledgehammer999
a869e4151c Update Changelog 2024-09-17 17:26:37 +03:00
sledgehammer999
839bc696d0 Bump to 4.6.7 2024-09-17 00:12:42 +03:00
sledgehammer999
e6845d6960 Update Changelog 2024-09-17 00:09:40 +03:00
sledgehammer999
413b2e14fa Sync translations from Transifex and run lupdate 2024-09-17 00:08:34 +03:00
sledgehammer999
b0fbe7bfdb Make Program Updater choose the same build for download
We're probably stuck offering the duo of RC_1_2 and RC_2_0 for some
time in the future. So hardcode the choices and make the Program Updater
choose the variant the user currently uses.
2024-09-16 22:40:00 +03:00
Vladimir Golovnev
bb0fcc5841 Focus on Download button if torrent link retrieved from the clipboard
PR #20716.
Closes #20682.
2024-09-16 09:59:27 +03:00
Vladimir Golovnev
94d98e78db WebUI: Fix incorrectly backported code
PR #21248.
Closes #21237.
2024-08-24 20:24:20 +03:00
sledgehammer999
c01265c4cf Bump to 4.6.6 2024-08-18 21:28:49 +03:00
sledgehammer999
f1466871ee Update Changelog 2024-08-18 21:18:33 +03:00
sledgehammer999
cfe15c2455 Sync translations from Transifex and run lupdate 2024-08-18 21:08:57 +03:00
Vladimir Golovnev
742bc410f4 Backport changes to v4.6.x branch
PR #21035.
2024-08-16 07:12:35 +03:00
cayenne17
64029e0493 Update User-Agent
PR #20801.
2024-08-15 20:41:24 +03:00
skomerko
58ba6f41f3 WebUI: Clear trackerList on full update
Like other similar data structures, trackerList also need to be cleared in the event of a full sync update.

PR #21148.
2024-08-11 15:39:01 +03:00
Vladimir Golovnev
d9023c647a Fix Incomplete Save Path cannot be changed for torrents without metadata
PR #21152.
Closes #21140.
2024-08-11 15:38:52 +03:00
Vladimir Golovnev
827f9d1345 Hide zero status filters when torrents removed
PR #21150.
Closes #21146.
2024-08-08 08:22:01 +03:00
Vladimir Golovnev
2f8044bd26 Prevent incorrect size from being used for creating array
PR #21050.
2024-07-14 15:55:42 +03:00
Vladimir Golovnev
92db0170d5 Apply bulk changes to correct content widget items
PR #21006.
Closes #21001.
2024-07-14 15:55:21 +03:00
Vladimir Golovnev
efa517ea90 WebUI: Correctly apply changed "save path" of RSS rules
PR #21030.
Closes #20141.
2024-07-08 10:12:02 +03:00
Vladimir Golovnev
47723115f6 Show scroll bar in Torrent Tags dialog
PR #21026.
Closes #21022.
2024-07-07 17:04:52 +03:00
Vladimir Golovnev
95e431a296 Fix handling of tags containing '&' character
PR #21024.
Closes #20773.
2024-07-07 17:04:35 +03:00
94 changed files with 8000 additions and 7824 deletions

View File

@@ -1,3 +1,18 @@
Mon Sep 16th 2024 - sledgehammer999 <sledgehammer999@qbittorrent.org> - v4.6.7
- BUGFIX: The updater will launch the link to the build variant you're currently using (sledgehammer999)
- BUGFIX: Focus on Download button if torrent link retrieved from the clipboard (glassez)
- WEBUI: RSS: The list of feeds wouldn't load for Apply Rule (glassez)
Sun Aug 18th 2024 - sledgehammer999 <sledgehammer999@qbittorrent.org> - v4.6.6
- BUGFIX: Fix handling of tags containing '&' character (glassez)
- BUGFIX: Show scroll bar in Torrent Tags dialog (glassez)
- BUGFIX: Apply bulk changes to correct content widget items (glassez)
- BUGFIX: Hide zero status filters when torrents are removed (glassez)
- BUGFIX: Fix `Incomplete Save Path` cannot be changed for torrents without metadata (glassez)
- WEBUI: Correctly apply changed "save path" of RSS rules (glassez)
- WEBUI: Clear tracker list on full update (skomerko)
- OTHER: Update User-Agent string for internal downloader and search engines (cayenne17)
Sun May 26th 2024 - sledgehammer999 <sledgehammer999@qbittorrent.org> - v4.6.5
- BUGFIX: Prevent app from being closed when disabling system tray icon (glassez)
- BUGFIX: Fix <kbd>Enter</kbd> key behavior in Add new torrent dialog (glassez)

20
configure vendored
View File

@@ -1,6 +1,6 @@
#! /bin/sh
# Guess values for system-dependent variables and create Makefiles.
# Generated by GNU Autoconf 2.71 for qbittorrent v4.6.5.
# Generated by GNU Autoconf 2.71 for qbittorrent v4.6.7.
#
# Report bugs to <bugs.qbittorrent.org>.
#
@@ -611,8 +611,8 @@ MAKEFLAGS=
# Identity of this package.
PACKAGE_NAME='qbittorrent'
PACKAGE_TARNAME='qbittorrent'
PACKAGE_VERSION='v4.6.5'
PACKAGE_STRING='qbittorrent v4.6.5'
PACKAGE_VERSION='v4.6.7'
PACKAGE_STRING='qbittorrent v4.6.7'
PACKAGE_BUGREPORT='bugs.qbittorrent.org'
PACKAGE_URL='https://www.qbittorrent.org/'
@@ -1329,7 +1329,7 @@ if test "$ac_init_help" = "long"; then
# Omit some internal or obsolete options to make the list less imposing.
# This message is too long to be a string in the A/UX 3.1 sh.
cat <<_ACEOF
\`configure' configures qbittorrent v4.6.5 to adapt to many kinds of systems.
\`configure' configures qbittorrent v4.6.7 to adapt to many kinds of systems.
Usage: $0 [OPTION]... [VAR=VALUE]...
@@ -1400,7 +1400,7 @@ fi
if test -n "$ac_init_help"; then
case $ac_init_help in
short | recursive ) echo "Configuration of qbittorrent v4.6.5:";;
short | recursive ) echo "Configuration of qbittorrent v4.6.7:";;
esac
cat <<\_ACEOF
@@ -1533,7 +1533,7 @@ fi
test -n "$ac_init_help" && exit $ac_status
if $ac_init_version; then
cat <<\_ACEOF
qbittorrent configure v4.6.5
qbittorrent configure v4.6.7
generated by GNU Autoconf 2.71
Copyright (C) 2021 Free Software Foundation, Inc.
@@ -1648,7 +1648,7 @@ cat >config.log <<_ACEOF
This file contains any messages produced by compilers while
running configure, to aid debugging if configure makes a mistake.
It was created by qbittorrent $as_me v4.6.5, which was
It was created by qbittorrent $as_me v4.6.7, which was
generated by GNU Autoconf 2.71. Invocation command line was
$ $0$ac_configure_args_raw
@@ -4779,7 +4779,7 @@ fi
# Define the identity of the package.
PACKAGE='qbittorrent'
VERSION='v4.6.5'
VERSION='v4.6.7'
printf "%s\n" "#define PACKAGE \"$PACKAGE\"" >>confdefs.h
@@ -7237,7 +7237,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
# report actual input values of CONFIG_FILES etc. instead of their
# values after options handling.
ac_log="
This file was extended by qbittorrent $as_me v4.6.5, which was
This file was extended by qbittorrent $as_me v4.6.7, which was
generated by GNU Autoconf 2.71. Invocation command line was
CONFIG_FILES = $CONFIG_FILES
@@ -7297,7 +7297,7 @@ ac_cs_config_escaped=`printf "%s\n" "$ac_cs_config" | sed "s/^ //; s/'/'\\\\\\\\
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
ac_cs_config='$ac_cs_config_escaped'
ac_cs_version="\\
qbittorrent config.status v4.6.5
qbittorrent config.status v4.6.7
configured by $0, generated by GNU Autoconf 2.71,
with options \\"\$ac_cs_config\\"

View File

@@ -1,4 +1,4 @@
AC_INIT([qbittorrent], [v4.6.5], [bugs.qbittorrent.org], [], [https://www.qbittorrent.org/])
AC_INIT([qbittorrent], [v4.6.7], [bugs.qbittorrent.org], [], [https://www.qbittorrent.org/])
AC_CONFIG_AUX_DIR([build-aux])
AC_CONFIG_MACRO_DIR([m4])
: ${CFLAGS=""}

2
dist/mac/Info.plist vendored
View File

@@ -55,7 +55,7 @@
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>4.6.5</string>
<string>4.6.7</string>
<key>CFBundleExecutable</key>
<string>${EXECUTABLE_NAME}</string>
<key>CFBundleIdentifier</key>

View File

@@ -21,7 +21,7 @@ GenericName[ar]=عميل بت‎تورنت
Comment[ar]=نزّل وشارك الملفات عبر كيوبت‎تورنت
Name[ar]=qBittorrent
GenericName[be]=Кліент BitTorrent
Comment[be]=Сьцягваньне й раздача файлаў праз пратакол BitTorrent
Comment[be]=Спампоўванне і раздача файлаў праз пратакол BitTorrent
Name[be]=qBittorrent
GenericName[bg]=BitTorrent клиент
Comment[bg]=Сваляне и споделяне на файлове чрез BitTorrent
@@ -105,7 +105,7 @@ GenericName[ka]=BitTorrent კლიენტი
Comment[ka]=გადმოტვირთეთ და გააზიარეთ ფაილები BitTorrent-ის საშუალებით
Name[ka]=qBittorrent
GenericName[ko]=BitTorrent 클라이언트
Comment[ko]=BitTorrent를 통한 파일 내려받기 및 공유
Comment[ko]=BitTorrent를 통한 파일 다운로드 및 공유
Name[ko]=qBittorrent
GenericName[lt]=BitTorrent klientas
Comment[lt]=Atsisiųskite bei dalinkitės failais BitTorrent tinkle
@@ -228,4 +228,6 @@ Name[ne_NP]=qBittorrent
GenericName[pt_PT]=Cliente BitTorrent
Comment[pt_PT]=Transferir e partilhar ficheiros por BitTorrent
Name[pt_PT]=qBittorrent
GenericName[si_LK]=BitTorrent සේවාදායකයා
Comment[si_LK]=BitTorrent හරහා ගොනු බාගත කර බෙදාගන්න.
Name[si_LK]=qBittorrent

View File

@@ -62,6 +62,6 @@
<url type="contribute">https://github.com/qbittorrent/qBittorrent/blob/master/CONTRIBUTING.md</url>
<content_rating type="oars-1.1"/>
<releases>
<release version="4.6.5" date="2024-05-26"/>
<release version="4.6.7" date="2024-09-16"/>
</releases>
</component>

View File

@@ -25,7 +25,7 @@
; 4.5.1.3 -> good
; 4.5.1.3.2 -> bad
; 4.5.0beta -> bad
!define /ifndef QBT_VERSION "4.6.5"
!define /ifndef QBT_VERSION "4.6.7"
; Option that controls the installer's window name
; If set, its value will be used like this:

View File

@@ -425,6 +425,8 @@ Path TorrentImpl::savePath() const
void TorrentImpl::setSavePath(const Path &path)
{
Q_ASSERT(!isAutoTMMEnabled());
if (Q_UNLIKELY(isAutoTMMEnabled()))
return;
const Path basePath = m_session->useCategoryPathsInManualMode()
? m_session->categorySavePath(category()) : m_session->savePath();
@@ -452,6 +454,8 @@ Path TorrentImpl::downloadPath() const
void TorrentImpl::setDownloadPath(const Path &path)
{
Q_ASSERT(!isAutoTMMEnabled());
if (Q_UNLIKELY(isAutoTMMEnabled()))
return;
const Path basePath = m_session->useCategoryPathsInManualMode()
? m_session->categoryDownloadPath(category()) : m_session->downloadPath();
@@ -1364,11 +1368,13 @@ QBitArray TorrentImpl::pieces() const
QBitArray TorrentImpl::downloadingPieces() const
{
QBitArray result(piecesCount());
if (!hasMetadata())
return {};
std::vector<lt::partial_piece_info> queue;
m_nativeHandle.get_download_queue(queue);
QBitArray result {piecesCount()};
for (const lt::partial_piece_info &info : queue)
result.setBit(LT::toUnderlyingType(info.piece_index));
@@ -1821,8 +1827,17 @@ void TorrentImpl::moveStorage(const Path &newPath, const MoveStorageContext cont
{
if (!hasMetadata())
{
m_savePath = newPath;
m_session->handleTorrentSavePathChanged(this);
if (context == MoveStorageContext::ChangeSavePath)
{
m_savePath = newPath;
m_session->handleTorrentSavePathChanged(this);
}
else if (context == MoveStorageContext::ChangeDownloadPath)
{
m_downloadPath = newPath;
m_session->handleTorrentSavePathChanged(this);
}
return;
}

View File

@@ -51,7 +51,7 @@
namespace
{
// Disguise as Firefox to avoid web server banning
const char DEFAULT_USER_AGENT[] = "Mozilla/5.0 (X11; Linux x86_64; rv:68.0) Gecko/20100101 Firefox/68.0";
const char DEFAULT_USER_AGENT[] = "Mozilla/5.0 (X11; Linux x86_64; rv:125.0) Gecko/20100101 Firefox/125.0";
}
class Net::DownloadManager::NetworkCookieJar final : public QNetworkCookieJar
@@ -124,10 +124,20 @@ Net::DownloadManager::DownloadManager(QObject *parent)
QStringList errorList;
for (const QSslError &error : errors)
errorList += error.errorString();
LogMsg(tr("Ignoring SSL error, URL: \"%1\", errors: \"%2\"").arg(reply->url().toString(), errorList.join(u". ")), Log::WARNING);
// Ignore all SSL errors
reply->ignoreSslErrors();
QString errorMsg;
if (!Preferences::instance()->isIgnoreSSLErrors())
{
errorMsg = tr("SSL error, URL: \"%1\", errors: \"%2\"");
}
else
{
errorMsg = tr("Ignoring SSL error, URL: \"%1\", errors: \"%2\"");
// Ignore all SSL errors
reply->ignoreSslErrors();
}
LogMsg(errorMsg.arg(reply->url().toString(), errorList.join(u". ")), Log::WARNING);
});
connect(ProxyConfigurationManager::instance(), &ProxyConfigurationManager::proxyConfigurationChanged

View File

@@ -1331,6 +1331,19 @@ void Preferences::setTrackerPortForwardingEnabled(const bool enabled)
setValue(u"Preferences/Advanced/trackerPortForwarding"_s, enabled);
}
bool Preferences::isIgnoreSSLErrors() const
{
return value(u"Preferences/Advanced/IgnoreSSLErrors"_s, false);
}
void Preferences::setIgnoreSSLErrors(const bool enabled)
{
if (enabled == isIgnoreSSLErrors())
return;
setValue(u"Preferences/Advanced/IgnoreSSLErrors"_s, enabled);
}
#if defined(Q_OS_WIN) || defined(Q_OS_MACOS)
bool Preferences::isUpdateCheckEnabled() const
{

View File

@@ -296,6 +296,8 @@ public:
void setTrackerPort(int port);
bool isTrackerPortForwardingEnabled() const;
void setTrackerPortForwardingEnabled(bool enabled);
bool isIgnoreSSLErrors() const;
void setIgnoreSSLErrors(bool enabled);
#if defined(Q_OS_WIN) || defined(Q_OS_MACOS)
bool isUpdateCheckEnabled() const;
void setUpdateCheckEnabled(bool enabled);

View File

@@ -30,7 +30,7 @@
#define QBT_VERSION_MAJOR 4
#define QBT_VERSION_MINOR 6
#define QBT_VERSION_BUGFIX 5
#define QBT_VERSION_BUGFIX 7
#define QBT_VERSION_BUILD 0
#define QBT_VERSION_STATUS "" // Should be empty for stable releases!

View File

@@ -100,6 +100,7 @@ namespace
TRACKER_STATUS,
TRACKER_PORT,
TRACKER_PORT_FORWARDING,
IGNORE_SSL_ERRORS,
// libtorrent section
LIBTORRENT_HEADER,
BDECODE_DEPTH_LIMIT,
@@ -319,6 +320,8 @@ void AdvancedSettings::saveAdvancedSettings() const
pref->setTrackerPortForwardingEnabled(m_checkBoxTrackerPortForwarding.isChecked());
session->setTrackerEnabled(m_checkBoxTrackerStatus.isChecked());
// Ignore SSL errors
pref->setIgnoreSSLErrors(m_checkBoxIgnoreSSLErrors.isChecked());
// Choking algorithm
session->setChokingAlgorithm(m_comboBoxChokingAlgorithm.currentData().value<BitTorrent::ChokingAlgorithm>());
// Seed choking algorithm
@@ -813,6 +816,10 @@ void AdvancedSettings::loadAdvancedSettings()
// Tracker port forwarding
m_checkBoxTrackerPortForwarding.setChecked(pref->isTrackerPortForwardingEnabled());
addRow(TRACKER_PORT_FORWARDING, tr("Enable port forwarding for embedded tracker"), &m_checkBoxTrackerPortForwarding);
// Ignore SSL errors
m_checkBoxIgnoreSSLErrors.setChecked(pref->isIgnoreSSLErrors());
m_checkBoxIgnoreSSLErrors.setToolTip(tr("Affects certificate validation and non-torrent protocol activities (e.g. RSS feeds, program updates, torrent files, geoip db, etc)"));
addRow(IGNORE_SSL_ERRORS, tr("Ignore SSL errors"), &m_checkBoxIgnoreSSLErrors);
// Choking algorithm
m_comboBoxChokingAlgorithm.addItem(tr("Fixed slots"), QVariant::fromValue(BitTorrent::ChokingAlgorithm::FixedSlots));
m_comboBoxChokingAlgorithm.addItem(tr("Upload rate based"), QVariant::fromValue(BitTorrent::ChokingAlgorithm::RateBased));

View File

@@ -77,9 +77,9 @@ private:
m_spinBoxSavePathHistoryLength, m_spinBoxPeerTurnover, m_spinBoxPeerTurnoverCutoff, m_spinBoxPeerTurnoverInterval, m_spinBoxRequestQueueSize;
QCheckBox m_checkBoxOsCache, m_checkBoxRecheckCompleted, m_checkBoxResolveCountries, m_checkBoxResolveHosts,
m_checkBoxProgramNotifications, m_checkBoxTorrentAddedNotifications, m_checkBoxReannounceWhenAddressChanged, m_checkBoxTrackerFavicon, m_checkBoxTrackerStatus,
m_checkBoxTrackerPortForwarding, m_checkBoxConfirmTorrentRecheck, m_checkBoxConfirmRemoveAllTags, m_checkBoxAnnounceAllTrackers, m_checkBoxAnnounceAllTiers,
m_checkBoxMultiConnectionsPerIp, m_checkBoxValidateHTTPSTrackerCertificate, m_checkBoxSSRFMitigation, m_checkBoxBlockPeersOnPrivilegedPorts, m_checkBoxPieceExtentAffinity,
m_checkBoxSuggestMode, m_checkBoxSpeedWidgetEnabled, m_checkBoxIDNSupport;
m_checkBoxTrackerPortForwarding, m_checkBoxIgnoreSSLErrors, m_checkBoxConfirmTorrentRecheck, m_checkBoxConfirmRemoveAllTags, m_checkBoxAnnounceAllTrackers,
m_checkBoxAnnounceAllTiers, m_checkBoxMultiConnectionsPerIp, m_checkBoxValidateHTTPSTrackerCertificate, m_checkBoxSSRFMitigation, m_checkBoxBlockPeersOnPrivilegedPorts,
m_checkBoxPieceExtentAffinity, m_checkBoxSuggestMode, m_checkBoxSpeedWidgetEnabled, m_checkBoxIDNSupport;
QComboBox m_comboBoxInterface, m_comboBoxInterfaceAddress, m_comboBoxDiskIOReadMode, m_comboBoxDiskIOWriteMode, m_comboBoxUtpMixedMode, m_comboBoxChokingAlgorithm,
m_comboBoxSeedChokingAlgorithm, m_comboBoxResumeDataStorage;
QLineEdit m_lineEditAnnounceIP;

View File

@@ -90,11 +90,12 @@ DownloadFromURLDialog::DownloadFromURLDialog(QWidget *parent)
urls << urlString;
}
const QString text = urls.join(u'\n')
+ (!urls.isEmpty() ? u"\n" : u"");
m_ui->textUrls->setText(text);
m_ui->textUrls->moveCursor(QTextCursor::End);
if (!urls.isEmpty())
{
m_ui->textUrls->setText(urls.join(u'\n') + u"\n");
m_ui->textUrls->moveCursor(QTextCursor::End);
m_ui->buttonBox->setFocus();
}
if (const QSize dialogSize = m_storeDialogSize; dialogSize.isValid())
resize(dialogSize);

View File

@@ -29,6 +29,9 @@
#include "programupdater.h"
#include <libtorrent/version.hpp>
#include <QtCore/qconfig.h>
#include <QtGlobal>
#if defined(Q_OS_WIN)
@@ -71,6 +74,22 @@ namespace
}
return (newVersion > currentVersion);
}
QString buildVariant()
{
#if defined(Q_OS_MACOS)
const auto BASE_OS = u"Mac OS X"_s;
#elif defined(Q_OS_WIN)
const auto BASE_OS = (::IsWindows7OrGreater() && QSysInfo::currentCpuArchitecture().endsWith(u"64"))
? u"Windows x64"_s
: u"Windows"_s;
#endif
if constexpr ((QT_VERSION_MAJOR == 6) && (LIBTORRENT_VERSION_MAJOR == 1))
return BASE_OS;
return u"%1 (qt%2 lt%3%4)"_s.arg(BASE_OS, QString::number(QT_VERSION_MAJOR), QString::number(LIBTORRENT_VERSION_MAJOR), QString::number(LIBTORRENT_VERSION_MINOR));
}
}
void ProgramUpdater::checkForUpdates() const
@@ -107,14 +126,7 @@ void ProgramUpdater::rssDownloadFinished(const Net::DownloadResult &result)
: QString {};
};
#ifdef Q_OS_MACOS
const QString OS_TYPE = u"Mac OS X"_s;
#elif defined(Q_OS_WIN)
const QString OS_TYPE = (::IsWindows7OrGreater() && QSysInfo::currentCpuArchitecture().endsWith(u"64"))
? u"Windows x64"_s
: u"Windows"_s;
#endif
const QString variant = buildVariant();
bool inItem = false;
QString version;
QString updateLink;
@@ -140,7 +152,7 @@ void ProgramUpdater::rssDownloadFinished(const Net::DownloadResult &result)
{
if (inItem && (xml.name() == u"item"))
{
if (type.compare(OS_TYPE, Qt::CaseInsensitive) == 0)
if (type.compare(variant, Qt::CaseInsensitive) == 0)
{
qDebug("The last update available is %s", qUtf8Printable(version));
if (!version.isEmpty())

View File

@@ -56,6 +56,19 @@
#include "gui/macutilities.h"
#endif
namespace
{
QList<QPersistentModelIndex> toPersistentIndexes(const QModelIndexList &indexes)
{
QList<QPersistentModelIndex> persistentIndexes;
persistentIndexes.reserve(indexes.size());
for (const QModelIndex &index : indexes)
persistentIndexes.append(index);
return persistentIndexes;
}
}
TorrentContentWidget::TorrentContentWidget(QWidget *parent)
: QTreeView(parent)
{
@@ -219,9 +232,9 @@ void TorrentContentWidget::keyPressEvent(QKeyEvent *event)
const Qt::CheckState state = (static_cast<Qt::CheckState>(value.toInt()) == Qt::Checked)
? Qt::Unchecked : Qt::Checked;
const QModelIndexList selection = selectionModel()->selectedRows(TorrentContentModelItem::COL_NAME);
const QList<QPersistentModelIndex> selection = toPersistentIndexes(selectionModel()->selectedRows(TorrentContentModelItem::COL_NAME));
for (const QModelIndex &index : selection)
for (const QPersistentModelIndex &index : selection)
model()->setData(index, state, Qt::CheckStateRole);
}
@@ -248,10 +261,10 @@ void TorrentContentWidget::renameSelectedFile()
void TorrentContentWidget::applyPriorities(const BitTorrent::DownloadPriority priority)
{
const QModelIndexList selectedRows = selectionModel()->selectedRows(0);
for (const QModelIndex &index : selectedRows)
const QList<QPersistentModelIndex> selectedRows = toPersistentIndexes(selectionModel()->selectedRows(Priority));
for (const QPersistentModelIndex &index : selectedRows)
{
model()->setData(index.sibling(index.row(), Priority), static_cast<int>(priority));
model()->setData(index, static_cast<int>(priority));
}
}
@@ -261,7 +274,7 @@ void TorrentContentWidget::applyPrioritiesByOrder()
// a download priority that will apply to each item. The number of groups depends on how
// many "download priority" are available to be assigned
const QModelIndexList selectedRows = selectionModel()->selectedRows(0);
const QList<QPersistentModelIndex> selectedRows = toPersistentIndexes(selectionModel()->selectedRows(Priority));
const qsizetype priorityGroups = 3;
const auto priorityGroupSize = std::max<qsizetype>((selectedRows.length() / priorityGroups), 1);
@@ -283,8 +296,8 @@ void TorrentContentWidget::applyPrioritiesByOrder()
break;
}
const QModelIndex &index = selectedRows[i];
model()->setData(index.sibling(index.row(), Priority), static_cast<int>(priority));
const QPersistentModelIndex &index = selectedRows[i];
model()->setData(index, static_cast<int>(priority));
}
}

View File

@@ -1,6 +1,6 @@
/*
* 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
* modify it under the terms of the GNU General Public License
@@ -37,6 +37,7 @@
#include "base/global.h"
#include "autoexpandabledialog.h"
#include "flowlayout.h"
#include "utils.h"
#include "ui_torrenttagsdialog.h"
@@ -52,10 +53,10 @@ TorrentTagsDialog::TorrentTagsDialog(const TagSet &initialTags, QWidget *parent)
connect(m_ui->buttonBox, &QDialogButtonBox::accepted, this, &QDialog::accept);
connect(m_ui->buttonBox, &QDialogButtonBox::rejected, this, &QDialog::reject);
auto *tagsLayout = new FlowLayout(m_ui->scrollArea);
auto *tagsLayout = new FlowLayout(m_ui->scrollArea->widget());
for (const QString &tag : asConst(initialTags.united(BitTorrent::Session::instance()->tags())))
{
auto *tagWidget = new QCheckBox(tag);
auto *tagWidget = new QCheckBox(Utils::Gui::tagToWidgetText(tag));
if (initialTags.contains(tag))
tagWidget->setChecked(true);
tagsLayout->addWidget(tagWidget);
@@ -78,12 +79,12 @@ TorrentTagsDialog::~TorrentTagsDialog()
TagSet TorrentTagsDialog::tags() const
{
TagSet tags;
auto *layout = m_ui->scrollArea->layout();
auto *layout = m_ui->scrollArea->widget()->layout();
for (int i = 0; i < (layout->count() - 1); ++i)
{
const auto *tagWidget = static_cast<QCheckBox *>(layout->itemAt(i)->widget());
if (tagWidget->isChecked())
tags.insert(tagWidget->text());
tags.insert(Utils::Gui::widgetTextToTag(tagWidget->text()));
}
return tags;
@@ -111,9 +112,9 @@ void TorrentTagsDialog::addNewTag()
}
else
{
auto *layout = m_ui->scrollArea->layout();
auto *layout = m_ui->scrollArea->widget()->layout();
auto *btn = layout->takeAt(layout->count() - 1);
auto *tagWidget = new QCheckBox(tag);
auto *tagWidget = new QCheckBox(Utils::Gui::tagToWidgetText(tag));
tagWidget->setChecked(true);
layout->addWidget(tagWidget);
layout->addItem(btn);

View File

@@ -235,10 +235,7 @@ void StatusFilterWidget::applyFilter(int row)
void StatusFilterWidget::handleTorrentsLoaded(const QVector<BitTorrent::Torrent *> &torrents)
{
for (const BitTorrent::Torrent *torrent : torrents)
updateTorrentStatus(torrent);
updateTexts();
update(torrents);
}
void StatusFilterWidget::torrentAboutToBeDeleted(BitTorrent::Torrent *const torrent)
@@ -273,6 +270,12 @@ void StatusFilterWidget::torrentAboutToBeDeleted(BitTorrent::Torrent *const torr
m_nbStalled = m_nbStalledUploading + m_nbStalledDownloading;
updateTexts();
if (Preferences::instance()->getHideZeroStatusFilters())
{
hideZeroItems();
updateGeometry();
}
}
void StatusFilterWidget::configure()

View File

@@ -1,5 +1,6 @@
/*
* Bittorrent Client using Qt and libtorrent.
* Copyright (C) 2023-2024 Vladimir Golovnev <glassez@yandex.ru>
* Copyright (C) 2006 Christophe Dumez <chris@qbittorrent.org>
*
* This program is free software; you can redistribute it and/or
@@ -1191,7 +1192,7 @@ void TransferListWidget::displayListMenu()
for (const QString &tag : asConst(tags))
{
auto *action = new TriStateAction(tag, tagsMenu);
auto *action = new TriStateAction(Utils::Gui::tagToWidgetText(tag), tagsMenu);
action->setCloseOnInteraction(false);
const Qt::CheckState initialState = tagsInAll.contains(tag) ? Qt::Checked

View File

@@ -1,5 +1,6 @@
/*
* Bittorrent Client using Qt and libtorrent.
* Copyright (C) 2024 Vladimir Golovnev <glassez@yandex.ru>
* Copyright (C) 2017 Mike Tzou
*
* This program is free software; you can redistribute it and/or
@@ -218,3 +219,29 @@ void Utils::Gui::openFolderSelect(const Path &path)
openPath(path.parentPath());
#endif
}
QString Utils::Gui::tagToWidgetText(const QString &tag)
{
return QString(tag).replace(u'&', u"&&"_s);
}
QString Utils::Gui::widgetTextToTag(const QString &text)
{
// replace pairs of '&' with single '&' and remove non-paired occurrences of '&'
QString cleanedText;
cleanedText.reserve(text.size());
bool amp = false;
for (const QChar c : text)
{
if (c == u'&')
{
amp = !amp;
if (amp)
continue;
}
cleanedText.append(c);
}
return cleanedText;
}

View File

@@ -1,5 +1,6 @@
/*
* Bittorrent Client using Qt and libtorrent.
* Copyright (C) 2024 Vladimir Golovnev <glassez@yandex.ru>
* Copyright (C) 2017 Mike Tzou
*
* This program is free software; you can redistribute it and/or
@@ -34,6 +35,7 @@ class QIcon;
class QPixmap;
class QPoint;
class QSize;
class QString;
class QWidget;
namespace Utils::Gui
@@ -51,4 +53,7 @@ namespace Utils::Gui
void openPath(const Path &path);
void openFolderSelect(const Path &path);
QString tagToWidgetText(const QString &tag);
QString widgetTextToTag(const QString &text);
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

Some files were not shown because too many files have changed in this diff Show More