You've already forked qBittorrent
mirror of
https://github.com/qbittorrent/qBittorrent
synced 2025-10-19 05:12:18 +02:00
Compare commits
23 Commits
release-4.
...
v4_6_x
Author | SHA1 | Date | |
---|---|---|---|
![]() |
91943e4815 | ||
![]() |
2388ad0aab | ||
![]() |
a65eb6c604 | ||
![]() |
a869e4151c | ||
![]() |
839bc696d0 | ||
![]() |
e6845d6960 | ||
![]() |
413b2e14fa | ||
![]() |
b0fbe7bfdb | ||
![]() |
bb0fcc5841 | ||
![]() |
94d98e78db | ||
![]() |
c01265c4cf | ||
![]() |
f1466871ee | ||
![]() |
cfe15c2455 | ||
![]() |
742bc410f4 | ||
![]() |
64029e0493 | ||
![]() |
58ba6f41f3 | ||
![]() |
d9023c647a | ||
![]() |
827f9d1345 | ||
![]() |
2f8044bd26 | ||
![]() |
92db0170d5 | ||
![]() |
efa517ea90 | ||
![]() |
47723115f6 | ||
![]() |
95e431a296 |
15
Changelog
15
Changelog
@@ -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
20
configure
vendored
@@ -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\\"
|
||||
|
||||
|
@@ -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
2
dist/mac/Info.plist
vendored
@@ -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>
|
||||
|
@@ -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
|
||||
|
@@ -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>
|
||||
|
2
dist/windows/config.nsi
vendored
2
dist/windows/config.nsi
vendored
@@ -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:
|
||||
|
@@ -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;
|
||||
}
|
||||
|
||||
|
@@ -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
|
||||
|
@@ -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
|
||||
{
|
||||
|
@@ -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);
|
||||
|
@@ -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!
|
||||
|
||||
|
@@ -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));
|
||||
|
@@ -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;
|
||||
|
@@ -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);
|
||||
|
@@ -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())
|
||||
|
@@ -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));
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -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);
|
||||
|
@@ -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()
|
||||
|
@@ -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
|
||||
|
@@ -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;
|
||||
}
|
||||
|
@@ -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
Reference in New Issue
Block a user