You've already forked qBittorrent
mirror of
https://github.com/qbittorrent/qBittorrent
synced 2025-10-09 18:32:15 +02:00
Compare commits
34 Commits
release-4.
...
release-4.
Author | SHA1 | Date | |
---|---|---|---|
![]() |
4cb386af35 | ||
![]() |
14ab1b015c | ||
![]() |
0a4971c994 | ||
![]() |
a75ae21434 | ||
![]() |
01eed5dae9 | ||
![]() |
e73397c750 | ||
![]() |
869d079507 | ||
![]() |
71174edf72 | ||
![]() |
b3d46ecb78 | ||
![]() |
80035a2520 | ||
![]() |
6790335239 | ||
![]() |
48ff494dca | ||
![]() |
c5b361ce74 | ||
![]() |
397b7b9407 | ||
![]() |
6e0c1e2147 | ||
![]() |
e93c360db6 | ||
![]() |
270e2023cd | ||
![]() |
5ac858213b | ||
![]() |
f0ee6aba29 | ||
![]() |
fa418087c4 | ||
![]() |
8493e1ad64 | ||
![]() |
fe90fcef5b | ||
![]() |
210fd80167 | ||
![]() |
0a1e864f74 | ||
![]() |
7adccab687 | ||
![]() |
67e536d869 | ||
![]() |
86e8d848f6 | ||
![]() |
88114b4588 | ||
![]() |
e468f004f4 | ||
![]() |
4cfccc54ea | ||
![]() |
5ffa7e4752 | ||
![]() |
d7fd576293 | ||
![]() |
83b34053a1 | ||
![]() |
b9164adb7a |
22
Changelog
22
Changelog
@@ -1,3 +1,25 @@
|
||||
Tue Feb 15 2022 - sledgehammer999 <sledgehammer999@qbittorrent.org> - v4.4.1
|
||||
- FEATURE: Restore all torrent settings to the torrent's main context menu (thalieht)
|
||||
- FEATURE: Add confirmation for enabling Auto TMM from context menu (thalieht)
|
||||
- FEATURE: Add tooltip to Automatic Torrent Management context menu action (thalieht)
|
||||
- FEATURE: Add Select All/None buttons in new torrent dialog (thalieht)
|
||||
- BUGFIX: Keep "torrent info" alive while generate .torrent file (glassez)
|
||||
- BUGFIX: Correctly handle Auto TMM in Torrent Files Watcher (glassez)
|
||||
- BUGFIX: Correctly track the root folder name change (glassez)
|
||||
- BUGFIX: Various fixes to the moving torrent code (glassez)
|
||||
- BUGFIX: Update the torrent's download path field when changing category (thalieht)
|
||||
- BUGFIX: Correctly handle received metadata (glassez)
|
||||
- BUGFIX: Store hybrid torrents using legacy filenames (glassez)
|
||||
- BUGFIX: Open correct directory when clicked on Browse button (glassez)
|
||||
- BUGFIX: Fix crash when shutting down and clicing on system tray icon (Chocobo1)
|
||||
- BUGFIX: Fix "Free space on disk" in new torrent dialog (thalieht)
|
||||
- BUGFIX: Optimize completed files handling (Prince Gupta)
|
||||
- BUGFIX: Migrate proxy settings (sledgehammer999)
|
||||
- BUGFIX: Try to recover missing categories (glassez)
|
||||
- WEBUI: WebAPI: fix wrong key used for categories (Chocobo1)
|
||||
- WEBUI: Remove hack for outdated IE 6 browser (Chocobo1)
|
||||
- RSS: Correctly handle XML parsing errors (glassez)
|
||||
|
||||
Thu Jan 06 2022 - sledgehammer999 <sledgehammer999@qbittorrent.org> - v4.4.0
|
||||
- FEATURE: Support for v2 torrents along with libtorrent 2.0.x support (glassez, Chocobo1)
|
||||
- FEATURE: Support for Qt6 (glassez)
|
||||
|
2
INSTALL
2
INSTALL
@@ -11,7 +11,7 @@ qBittorrent - A BitTorrent client in C++ / Qt
|
||||
|
||||
- OpenSSL >= 1.1.1
|
||||
|
||||
- Qt 5.15.2 - 5.x
|
||||
- Qt 5.15.2 - 5.x || 6.2.0 - 6.x
|
||||
|
||||
- zlib >= 1.2.11
|
||||
|
||||
|
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.4.0alpha.
|
||||
# Generated by GNU Autoconf 2.71 for qbittorrent v4.4.1.
|
||||
#
|
||||
# Report bugs to <bugs.qbittorrent.org>.
|
||||
#
|
||||
@@ -611,8 +611,8 @@ MAKEFLAGS=
|
||||
# Identity of this package.
|
||||
PACKAGE_NAME='qbittorrent'
|
||||
PACKAGE_TARNAME='qbittorrent'
|
||||
PACKAGE_VERSION='v4.4.0alpha'
|
||||
PACKAGE_STRING='qbittorrent v4.4.0alpha'
|
||||
PACKAGE_VERSION='v4.4.1'
|
||||
PACKAGE_STRING='qbittorrent v4.4.1'
|
||||
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.4.0alpha to adapt to many kinds of systems.
|
||||
\`configure' configures qbittorrent v4.4.1 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.4.0alpha:";;
|
||||
short | recursive ) echo "Configuration of qbittorrent v4.4.1:";;
|
||||
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.4.0alpha
|
||||
qbittorrent configure v4.4.1
|
||||
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.4.0alpha, which was
|
||||
It was created by qbittorrent $as_me v4.4.1, 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.4.0alpha'
|
||||
VERSION='v4.4.1'
|
||||
|
||||
|
||||
printf "%s\n" "#define PACKAGE \"$PACKAGE\"" >>confdefs.h
|
||||
@@ -7254,7 +7254,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.4.0alpha, which was
|
||||
This file was extended by qbittorrent $as_me v4.4.1, which was
|
||||
generated by GNU Autoconf 2.71. Invocation command line was
|
||||
|
||||
CONFIG_FILES = $CONFIG_FILES
|
||||
@@ -7314,7 +7314,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.4.0alpha
|
||||
qbittorrent config.status v4.4.1
|
||||
configured by $0, generated by GNU Autoconf 2.71,
|
||||
with options \\"\$ac_cs_config\\"
|
||||
|
||||
|
@@ -1,5 +1,4 @@
|
||||
|
||||
AC_INIT([qbittorrent], [v4.4.0alpha], [bugs.qbittorrent.org], [], [https://www.qbittorrent.org/])
|
||||
AC_INIT([qbittorrent], [v4.4.1], [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.4.0</string>
|
||||
<string>4.4.1</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>${EXECUTABLE_NAME}</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
|
@@ -74,6 +74,6 @@
|
||||
<url type="translate">https://github.com/qbittorrent/qBittorrent/wiki/How-to-translate-qBittorrent</url>
|
||||
<content_rating type="oars-1.1"/>
|
||||
<releases>
|
||||
<release version="4.4.0" date="2020-10-18"/>
|
||||
<release version="4.4.1" date="2022-02-15"/>
|
||||
</releases>
|
||||
</component>
|
||||
|
@@ -115,6 +115,8 @@ Name[lt]=qBittorrent
|
||||
Comment[mk]=Превземајте и споделувајте фајлови преку BitTorrent
|
||||
GenericName[mk]=BitTorrent клиент
|
||||
Name[mk]=qBittorrent
|
||||
Comment[my]=တောရန့်ဖြင့်ဖိုင်များဒေါင်းလုဒ်ဆွဲရန်နှင့်မျှဝေရန်
|
||||
GenericName[my]=တောရန့်စီမံခန့်ခွဲသည့်အရာ
|
||||
Name[my]=qBittorrent
|
||||
Comment[nb]=Last ned og del filer over BitTorrent
|
||||
GenericName[nb]=BitTorrent-klient
|
||||
|
2
dist/windows/options.nsi
vendored
2
dist/windows/options.nsi
vendored
@@ -28,7 +28,7 @@ XPStyle on
|
||||
!define CSIDL_LOCALAPPDATA '0x1C' ;Local Application Data path
|
||||
|
||||
; Program specific
|
||||
!define PROG_VERSION "4.4.0"
|
||||
!define PROG_VERSION "4.4.1"
|
||||
|
||||
!define MUI_FINISHPAGE_RUN
|
||||
!define MUI_FINISHPAGE_RUN_FUNCTION PageFinishRun
|
||||
|
@@ -650,8 +650,8 @@ int Application::exec(const QStringList ¶ms)
|
||||
const auto scheme = QString::fromLatin1(pref->isWebUiHttpsEnabled() ? "https" : "http");
|
||||
const auto url = QString::fromLatin1("%1://localhost:%2\n").arg(scheme, QString::number(pref->getWebUiPort()));
|
||||
const QString mesg = QString::fromLatin1("\n******** %1 ********\n").arg(tr("Information"))
|
||||
+ tr("To control qBittorrent, access the WebUI at: %1\n").arg(url);
|
||||
printf("%s", qUtf8Printable(mesg));
|
||||
+ tr("To control qBittorrent, access the WebUI at: %1").arg(url);
|
||||
printf("%s\n", qUtf8Printable(mesg));
|
||||
|
||||
if (pref->getWebUIPassword() == "ARQ77eY1NUZaQsuDHbIMCA==:0WMRkYTUWVT9wVvdDtHAjU9b3b7uB8NR1Gur2hmQCvCDpm39Q+PsJRJPaCU51dEiz+dTzh8qbPsL8WkFljQYFQ==")
|
||||
{
|
||||
|
@@ -32,6 +32,7 @@
|
||||
|
||||
#include "base/bittorrent/torrentcontentlayout.h"
|
||||
#include "base/logger.h"
|
||||
#include "base/net/proxyconfigurationmanager.h"
|
||||
#include "base/preferences.h"
|
||||
#include "base/profile.h"
|
||||
#include "base/settingsstorage.h"
|
||||
@@ -42,7 +43,7 @@
|
||||
|
||||
namespace
|
||||
{
|
||||
const int MIGRATION_VERSION = 2;
|
||||
const int MIGRATION_VERSION = 3;
|
||||
const char MIGRATION_VERSION_KEY[] = "Meta/MigrationVersion";
|
||||
|
||||
void exportWebUIHttpsFiles()
|
||||
@@ -326,6 +327,46 @@ namespace
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void migrateProxySettingsEnum()
|
||||
{
|
||||
auto *settingsStorage = SettingsStorage::instance();
|
||||
const auto key = QString::fromLatin1("Network/Proxy/Type");
|
||||
const auto value = settingsStorage->loadValue<QString>(key);
|
||||
|
||||
bool ok = false;
|
||||
const auto number = value.toInt(&ok);
|
||||
|
||||
if (ok)
|
||||
{
|
||||
switch (number)
|
||||
{
|
||||
case 0:
|
||||
settingsStorage->storeValue(key, Net::ProxyType::None);
|
||||
break;
|
||||
case 1:
|
||||
settingsStorage->storeValue(key, Net::ProxyType::HTTP);
|
||||
break;
|
||||
case 2:
|
||||
settingsStorage->storeValue(key, Net::ProxyType::SOCKS5);
|
||||
break;
|
||||
case 3:
|
||||
settingsStorage->storeValue(key, Net::ProxyType::HTTP_PW);
|
||||
break;
|
||||
case 4:
|
||||
settingsStorage->storeValue(key, Net::ProxyType::SOCKS5_PW);
|
||||
break;
|
||||
case 5:
|
||||
settingsStorage->storeValue(key, Net::ProxyType::SOCKS4);
|
||||
break;
|
||||
default:
|
||||
LogMsg(QObject::tr("Invalid value found in configuration file, reverting it to default. Key: \"%1\". Invalid value: \"%2\".")
|
||||
.arg(key, QString::number(number)), Log::WARNING);
|
||||
settingsStorage->removeValue(key);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool upgrade(const bool /*ask*/)
|
||||
@@ -343,9 +384,13 @@ bool upgrade(const bool /*ask*/)
|
||||
upgradeDNSServiceSettings();
|
||||
upgradeTrayIconStyleSettings();
|
||||
}
|
||||
|
||||
if (version < 2)
|
||||
migrateSettingKeys();
|
||||
|
||||
if (version < 3)
|
||||
migrateProxySettingsEnum();
|
||||
|
||||
version = MIGRATION_VERSION;
|
||||
}
|
||||
|
||||
|
@@ -36,6 +36,13 @@ BitTorrent::InfoHash::InfoHash(const WrappedType &nativeHash)
|
||||
{
|
||||
}
|
||||
|
||||
#ifdef QBT_USES_LIBTORRENT2
|
||||
BitTorrent::InfoHash::InfoHash(const SHA1Hash &v1, const SHA256Hash &v2)
|
||||
: InfoHash {WrappedType(v1, v2)}
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
bool BitTorrent::InfoHash::isValid() const
|
||||
{
|
||||
return m_valid;
|
||||
|
@@ -65,6 +65,9 @@ namespace BitTorrent
|
||||
|
||||
InfoHash() = default;
|
||||
InfoHash(const WrappedType &nativeHash);
|
||||
#ifdef QBT_USES_LIBTORRENT2
|
||||
InfoHash(const SHA1Hash &v1, const SHA256Hash &v2);
|
||||
#endif
|
||||
|
||||
bool isValid() const;
|
||||
SHA1Hash v1() const;
|
||||
@@ -85,3 +88,6 @@ namespace BitTorrent
|
||||
}
|
||||
|
||||
Q_DECLARE_METATYPE(BitTorrent::TorrentID)
|
||||
// We can declare it as Q_MOVABLE_TYPE to improve performance
|
||||
// since base type uses QSharedDataPointer as the only member
|
||||
Q_DECLARE_TYPEINFO(BitTorrent::TorrentID, Q_MOVABLE_TYPE);
|
||||
|
@@ -41,6 +41,7 @@ namespace
|
||||
NativeTorrentExtension::NativeTorrentExtension(const lt::torrent_handle &torrentHandle)
|
||||
: m_torrentHandle {torrentHandle}
|
||||
{
|
||||
on_state(m_torrentHandle.status({}).state);
|
||||
}
|
||||
|
||||
bool NativeTorrentExtension::on_pause()
|
||||
@@ -56,7 +57,10 @@ bool NativeTorrentExtension::on_pause()
|
||||
void NativeTorrentExtension::on_state(const lt::torrent_status::state_t state)
|
||||
{
|
||||
if (m_state == lt::torrent_status::downloading_metadata)
|
||||
m_torrentHandle.set_flags(lt::torrent_flags::stop_when_ready);
|
||||
{
|
||||
m_torrentHandle.unset_flags(lt::torrent_flags::auto_managed);
|
||||
m_torrentHandle.pause();
|
||||
}
|
||||
|
||||
m_state = state;
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
@@ -273,13 +273,16 @@ TorrentImpl::TorrentImpl(Session *session, lt::session *nativeSession
|
||||
m_torrentInfo = TorrentInfo(*m_ltAddTorrentParams.ti);
|
||||
|
||||
Q_ASSERT(m_filePaths.isEmpty());
|
||||
Q_ASSERT(m_indexMap.isEmpty());
|
||||
const int filesCount = m_torrentInfo.filesCount();
|
||||
m_filePaths.reserve(filesCount);
|
||||
m_indexMap.reserve(filesCount);
|
||||
const std::shared_ptr<const lt::torrent_info> currentInfo = m_nativeHandle.torrent_file();
|
||||
const lt::file_storage &fileStorage = currentInfo->files();
|
||||
for (int i = 0; i < filesCount; ++i)
|
||||
{
|
||||
const lt::file_index_t nativeIndex = m_torrentInfo.nativeIndexes().at(i);
|
||||
m_indexMap[nativeIndex] = i;
|
||||
const QString filePath = Utils::Fs::toUniformPath(QString::fromStdString(fileStorage.file_path(nativeIndex)));
|
||||
m_filePaths.append(filePath);
|
||||
}
|
||||
@@ -412,7 +415,7 @@ void TorrentImpl::setSavePath(const QString &path)
|
||||
m_session->handleTorrentNeedSaveResumeData(this);
|
||||
|
||||
const bool isFinished = isSeed() || m_hasSeedStatus;
|
||||
if (isFinished)
|
||||
if (isFinished || downloadPath().isEmpty())
|
||||
moveStorage(savePath(), MoveStorageMode::KeepExistingFiles);
|
||||
}
|
||||
|
||||
@@ -444,7 +447,7 @@ QString TorrentImpl::rootPath() const
|
||||
if (!hasMetadata())
|
||||
return {};
|
||||
|
||||
const QString relativeRootPath = m_torrentInfo.rootFolder();
|
||||
const QString relativeRootPath = Utils::Fs::findRootFolder(filePaths());
|
||||
if (relativeRootPath.isEmpty())
|
||||
return {};
|
||||
|
||||
@@ -1500,14 +1503,22 @@ void TorrentImpl::fileSearchFinished(const QString &savePath, const QStringList
|
||||
|
||||
void TorrentImpl::endReceivedMetadataHandling(const QString &savePath, const QStringList &fileNames)
|
||||
{
|
||||
Q_ASSERT(m_filePaths.isEmpty());
|
||||
Q_ASSERT(m_indexMap.isEmpty());
|
||||
|
||||
lt::add_torrent_params &p = m_ltAddTorrentParams;
|
||||
|
||||
const std::shared_ptr<lt::torrent_info> metadata = std::const_pointer_cast<lt::torrent_info>(m_nativeHandle.torrent_file());
|
||||
m_torrentInfo = TorrentInfo(*metadata);
|
||||
m_filePaths = fileNames;
|
||||
m_indexMap.reserve(filesCount());
|
||||
const auto nativeIndexes = m_torrentInfo.nativeIndexes();
|
||||
for (int i = 0; i < fileNames.size(); ++i)
|
||||
p.renamed_files[nativeIndexes[i]] = fileNames[i].toStdString();
|
||||
{
|
||||
const auto nativeIndex = nativeIndexes.at(i);
|
||||
m_indexMap[nativeIndex] = i;
|
||||
p.renamed_files[nativeIndex] = fileNames[i].toStdString();
|
||||
}
|
||||
p.save_path = Utils::Fs::toNativePath(savePath).toStdString();
|
||||
p.ti = metadata;
|
||||
|
||||
@@ -1862,7 +1873,7 @@ void TorrentImpl::handleFastResumeRejectedAlert(const lt::fastresume_rejected_al
|
||||
|
||||
void TorrentImpl::handleFileRenamedAlert(const lt::file_renamed_alert *p)
|
||||
{
|
||||
const int fileIndex = m_torrentInfo.nativeIndexes().indexOf(p->index);
|
||||
const int fileIndex = m_indexMap.value(p->index, -1);
|
||||
Q_ASSERT(fileIndex >= 0);
|
||||
|
||||
// Remove empty leftover folders
|
||||
@@ -1892,9 +1903,10 @@ void TorrentImpl::handleFileRenamedAlert(const lt::file_renamed_alert *p)
|
||||
++pathIdx;
|
||||
}
|
||||
|
||||
QDir storageDir {actualStorageLocation()};
|
||||
for (int i = (oldPathParts.size() - 1); i >= pathIdx; --i)
|
||||
{
|
||||
QDir().rmdir(savePath() + Utils::String::join(oldPathParts, QString::fromLatin1("/")));
|
||||
storageDir.rmdir(Utils::String::join(oldPathParts, QString::fromLatin1("/")));
|
||||
oldPathParts.removeLast();
|
||||
}
|
||||
|
||||
@@ -1907,7 +1919,7 @@ void TorrentImpl::handleFileRenamedAlert(const lt::file_renamed_alert *p)
|
||||
|
||||
void TorrentImpl::handleFileRenameFailedAlert(const lt::file_rename_failed_alert *p)
|
||||
{
|
||||
const int fileIndex = m_torrentInfo.nativeIndexes().indexOf(p->index);
|
||||
const int fileIndex = m_indexMap.value(p->index, -1);
|
||||
Q_ASSERT(fileIndex >= 0);
|
||||
|
||||
LogMsg(tr("File rename failed. Torrent: \"%1\", file: \"%2\", reason: \"%3\"")
|
||||
@@ -1922,12 +1934,11 @@ void TorrentImpl::handleFileRenameFailedAlert(const lt::file_rename_failed_alert
|
||||
|
||||
void TorrentImpl::handleFileCompletedAlert(const lt::file_completed_alert *p)
|
||||
{
|
||||
const int fileIndex = m_torrentInfo.nativeIndexes().indexOf(p->index);
|
||||
Q_ASSERT(fileIndex >= 0);
|
||||
|
||||
qDebug("A file completed download in torrent \"%s\"", qUtf8Printable(name()));
|
||||
if (m_session->isAppendExtensionEnabled())
|
||||
{
|
||||
const int fileIndex = m_indexMap.value(p->index, -1);
|
||||
Q_ASSERT(fileIndex >= 0);
|
||||
|
||||
QString name = filePath(fileIndex);
|
||||
if (name.endsWith(QB_EXT))
|
||||
{
|
||||
@@ -2081,7 +2092,8 @@ void TorrentImpl::adjustStorageLocation()
|
||||
const bool isFinished = isSeed() || m_hasSeedStatus;
|
||||
const QDir targetDir {((isFinished || downloadPath.isEmpty()) ? savePath() : downloadPath)};
|
||||
|
||||
moveStorage(targetDir.absolutePath(), MoveStorageMode::Overwrite);
|
||||
if ((targetDir != QDir(actualStorageLocation())) || isMoveInProgress())
|
||||
moveStorage(targetDir.absolutePath(), MoveStorageMode::Overwrite);
|
||||
}
|
||||
|
||||
lt::torrent_handle TorrentImpl::nativeHandle() const
|
||||
|
@@ -286,6 +286,7 @@ namespace BitTorrent
|
||||
TorrentState m_state = TorrentState::Unknown;
|
||||
TorrentInfo m_torrentInfo;
|
||||
QStringList m_filePaths;
|
||||
QHash<lt::file_index_t, int> m_indexMap;
|
||||
SpeedMonitor m_speedMonitor;
|
||||
|
||||
InfoHash m_infoHash;
|
||||
|
@@ -140,7 +140,7 @@ nonstd::expected<void, QString> TorrentInfo::saveToFile(const QString &path) con
|
||||
|
||||
try
|
||||
{
|
||||
const auto torrentCreator = lt::create_torrent(*nativeInfo());
|
||||
const auto torrentCreator = lt::create_torrent(*m_nativeInfo);
|
||||
const lt::entry torrentEntry = torrentCreator.generate();
|
||||
const nonstd::expected<void, QString> result = Utils::IO::saveToFile(path, torrentEntry);
|
||||
if (!result)
|
||||
@@ -409,19 +409,6 @@ int TorrentInfo::fileIndex(const QString &fileName) const
|
||||
return -1;
|
||||
}
|
||||
|
||||
QString TorrentInfo::rootFolder() const
|
||||
{
|
||||
if (!isValid())
|
||||
return {};
|
||||
|
||||
return Utils::Fs::findRootFolder(filePaths());
|
||||
}
|
||||
|
||||
bool TorrentInfo::hasRootFolder() const
|
||||
{
|
||||
return !rootFolder().isEmpty();
|
||||
}
|
||||
|
||||
TorrentContentLayout TorrentInfo::contentLayout() const
|
||||
{
|
||||
if (!isValid())
|
||||
|
@@ -92,9 +92,6 @@ namespace BitTorrent
|
||||
PieceRange filePieces(const QString &file) const;
|
||||
PieceRange filePieces(int fileIndex) const;
|
||||
|
||||
QString rootFolder() const;
|
||||
bool hasRootFolder() const;
|
||||
|
||||
std::shared_ptr<lt::torrent_info> nativeInfo() const;
|
||||
QVector<lt::file_index_t> nativeIndexes() const;
|
||||
|
||||
|
@@ -591,16 +591,16 @@ void Parser::parse_impl(const QByteArray &feedData)
|
||||
xml.skipCurrentElement();
|
||||
}
|
||||
|
||||
if (!foundChannel)
|
||||
{
|
||||
m_result.error = tr("Invalid RSS feed.");
|
||||
}
|
||||
else if (xml.hasError())
|
||||
if (xml.hasError())
|
||||
{
|
||||
m_result.error = tr("%1 (line: %2, column: %3, offset: %4).")
|
||||
.arg(xml.errorString()).arg(xml.lineNumber())
|
||||
.arg(xml.columnNumber()).arg(xml.characterOffset());
|
||||
}
|
||||
else if (!foundChannel)
|
||||
{
|
||||
m_result.error = tr("Invalid RSS feed.");
|
||||
}
|
||||
|
||||
emit finished(m_result);
|
||||
m_result.articles.clear(); // clear articles only
|
||||
|
@@ -511,7 +511,8 @@ void TorrentFilesWatcher::Worker::processFolder(const QString &path, const QStri
|
||||
if (path != watchedFolderPath)
|
||||
{
|
||||
const QString subdirPath = watchedDir.relativeFilePath(path);
|
||||
if (addTorrentParams.useAutoTMM)
|
||||
const bool useAutoTMM = addTorrentParams.useAutoTMM.value_or(!BitTorrent::Session::instance()->isAutoTMMDisabledByDefault());
|
||||
if (useAutoTMM)
|
||||
{
|
||||
addTorrentParams.category = addTorrentParams.category.isEmpty()
|
||||
? subdirPath : (addTorrentParams.category + QLatin1Char('/') + subdirPath);
|
||||
@@ -590,7 +591,8 @@ void TorrentFilesWatcher::Worker::processFailedTorrents()
|
||||
if (exactDirPath != dir.path())
|
||||
{
|
||||
const QString subdirPath = dir.relativeFilePath(exactDirPath);
|
||||
if (addTorrentParams.useAutoTMM)
|
||||
const bool useAutoTMM = addTorrentParams.useAutoTMM.value_or(!BitTorrent::Session::instance()->isAutoTMMDisabledByDefault());
|
||||
if (useAutoTMM)
|
||||
{
|
||||
addTorrentParams.category = addTorrentParams.category.isEmpty()
|
||||
? subdirPath : (addTorrentParams.category + QLatin1Char('/') + subdirPath);
|
||||
|
@@ -30,9 +30,9 @@
|
||||
|
||||
#define QBT_VERSION_MAJOR 4
|
||||
#define QBT_VERSION_MINOR 4
|
||||
#define QBT_VERSION_BUGFIX 0
|
||||
#define QBT_VERSION_BUGFIX 1
|
||||
#define QBT_VERSION_BUILD 0
|
||||
#define QBT_VERSION_STATUS "rc1" // Should be empty for stable releases!
|
||||
#define QBT_VERSION_STATUS "" // Should be empty for stable releases!
|
||||
|
||||
#define QBT__STRINGIFY(x) #x
|
||||
#define QBT_STRINGIFY(x) QBT__STRINGIFY(x)
|
||||
|
@@ -200,7 +200,7 @@ AddNewTorrentDialog::AddNewTorrentDialog(const BitTorrent::AddTorrentParams &inP
|
||||
|
||||
m_ui->startTorrentCheckBox->setChecked(!m_torrentParams.addPaused.value_or(session->isAddTorrentPaused()));
|
||||
|
||||
m_ui->comboTTM->blockSignals(true); // the TreeView size isn't correct if the slot does it job at this point
|
||||
m_ui->comboTTM->blockSignals(true); // the TreeView size isn't correct if the slot does its job at this point
|
||||
m_ui->comboTTM->setCurrentIndex(session->isAutoTMMDisabledByDefault() ? 0 : 1);
|
||||
m_ui->comboTTM->blockSignals(false);
|
||||
|
||||
@@ -874,6 +874,8 @@ void AddNewTorrentDialog::setupTreeview()
|
||||
connect(m_ui->contentTreeView, &QAbstractItemView::clicked, m_ui->contentTreeView
|
||||
, qOverload<const QModelIndex &>(&QAbstractItemView::edit));
|
||||
connect(m_ui->contentTreeView, &QWidget::customContextMenuRequested, this, &AddNewTorrentDialog::displayContentTreeMenu);
|
||||
connect(m_ui->buttonSelectAll, &QPushButton::clicked, m_contentModel, &TorrentContentFilterModel::selectAll);
|
||||
connect(m_ui->buttonSelectNone, &QPushButton::clicked, m_contentModel, &TorrentContentFilterModel::selectNone);
|
||||
|
||||
const auto contentLayout = ((m_ui->contentLayoutComboBox->currentIndex() == 0)
|
||||
? BitTorrent::detectContentLayout(m_torrentInfo.filePaths())
|
||||
@@ -964,9 +966,9 @@ void AddNewTorrentDialog::TMMChanged(int index)
|
||||
|
||||
m_ui->groupBoxDownloadPath->blockSignals(true);
|
||||
m_ui->groupBoxDownloadPath->setChecked(!downloadPath.isEmpty());
|
||||
|
||||
updateDiskSpaceLabel();
|
||||
}
|
||||
|
||||
updateDiskSpaceLabel();
|
||||
}
|
||||
|
||||
void AddNewTorrentDialog::doNotDeleteTorrentClicked(bool checked)
|
||||
|
@@ -392,22 +392,59 @@
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="TorrentContentTreeView" name="contentTreeView">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
|
||||
<horstretch>1</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="contextMenuPolicy">
|
||||
<enum>Qt::CustomContextMenu</enum>
|
||||
</property>
|
||||
<property name="selectionMode">
|
||||
<enum>QAbstractItemView::ExtendedSelection</enum>
|
||||
</property>
|
||||
<property name="sortingEnabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<widget class="QWidget" name="layoutWidget">
|
||||
<layout class="QVBoxLayout" name="verticalLayout_5">
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="contentFilterLayout">
|
||||
<item>
|
||||
<widget class="QPushButton" name="buttonSelectAll">
|
||||
<property name="text">
|
||||
<string>Select All</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="buttonSelectNone">
|
||||
<property name="text">
|
||||
<string>Select None</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_6">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>168</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="TorrentContentTreeView" name="contentTreeView">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
|
||||
<horstretch>1</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="contextMenuPolicy">
|
||||
<enum>Qt::CustomContextMenu</enum>
|
||||
</property>
|
||||
<property name="selectionMode">
|
||||
<enum>QAbstractItemView::ExtendedSelection</enum>
|
||||
</property>
|
||||
<property name="sortingEnabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</widget>
|
||||
</item>
|
||||
|
@@ -111,8 +111,12 @@ FileSystemPathEdit::FileSystemPathEditPrivate::FileSystemPathEditPrivate(
|
||||
void FileSystemPathEdit::FileSystemPathEditPrivate::browseActionTriggered()
|
||||
{
|
||||
Q_Q(FileSystemPathEdit);
|
||||
|
||||
const QFileInfo fileInfo {q->selectedPath()};
|
||||
const QString directory = (m_mode == FileSystemPathEdit::Mode::DirectoryOpen) || (m_mode == FileSystemPathEdit::Mode::DirectorySave)
|
||||
? fileInfo.absoluteFilePath()
|
||||
: fileInfo.absolutePath();
|
||||
QString filter = q->fileNameFilter();
|
||||
QString directory = q->currentDirectory().isEmpty() ? QDir::homePath() : q->currentDirectory();
|
||||
|
||||
QString selectedPath;
|
||||
switch (m_mode)
|
||||
@@ -308,11 +312,6 @@ void FileSystemPathEdit::setDialogCaption(const QString &caption)
|
||||
d->m_dialogCaption = caption;
|
||||
}
|
||||
|
||||
QString FileSystemPathEdit::currentDirectory() const
|
||||
{
|
||||
return QFileInfo(selectedPath()).absoluteDir().absolutePath();
|
||||
}
|
||||
|
||||
QWidget *FileSystemPathEdit::editWidgetImpl() const
|
||||
{
|
||||
Q_D(const FileSystemPathEdit);
|
||||
|
@@ -64,7 +64,6 @@ public:
|
||||
Mode mode() const;
|
||||
void setMode(Mode mode);
|
||||
|
||||
QString currentDirectory() const;
|
||||
QString selectedPath() const;
|
||||
void setSelectedPath(const QString &val);
|
||||
|
||||
|
@@ -1235,6 +1235,7 @@ void MainWindow::closeEvent(QCloseEvent *e)
|
||||
#ifndef Q_OS_MACOS
|
||||
if (m_systrayIcon)
|
||||
{
|
||||
m_systrayIcon->disconnect();
|
||||
m_systrayIcon->setToolTip(tr("qBittorrent is shutting down..."));
|
||||
m_trayIconMenu->setEnabled(false);
|
||||
}
|
||||
|
@@ -519,6 +519,9 @@ void TorrentOptionsDialog::handleCategoryChanged(const int index)
|
||||
{
|
||||
const QString savePath = BitTorrent::Session::instance()->categorySavePath(m_ui->comboCategory->currentText());
|
||||
m_ui->savePath->setSelectedPath(Utils::Fs::toNativePath(savePath));
|
||||
const QString downloadPath = BitTorrent::Session::instance()->categoryDownloadPath(m_ui->comboCategory->currentText());
|
||||
m_ui->downloadPath->setSelectedPath(Utils::Fs::toNativePath(downloadPath));
|
||||
m_ui->checkUseDownloadPath->setChecked(!downloadPath.isEmpty());
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -331,6 +331,40 @@ QVector<BitTorrent::Torrent *> TransferListWidget::getVisibleTorrents() const
|
||||
return torrents;
|
||||
}
|
||||
|
||||
void TransferListWidget::setSelectedTorrentsLocation()
|
||||
{
|
||||
const QVector<BitTorrent::Torrent *> torrents = getSelectedTorrents();
|
||||
if (torrents.isEmpty())
|
||||
return;
|
||||
|
||||
const QString oldLocation = torrents[0]->savePath();
|
||||
|
||||
auto fileDialog = new QFileDialog(this, tr("Choose save path"), oldLocation);
|
||||
fileDialog->setAttribute(Qt::WA_DeleteOnClose);
|
||||
fileDialog->setFileMode(QFileDialog::Directory);
|
||||
fileDialog->setModal(true);
|
||||
fileDialog->setOptions(QFileDialog::DontConfirmOverwrite | QFileDialog::ShowDirsOnly | QFileDialog::HideNameFilterDetails);
|
||||
connect(fileDialog, &QDialog::accepted, this, [this, fileDialog]()
|
||||
{
|
||||
const QVector<BitTorrent::Torrent *> torrents = getSelectedTorrents();
|
||||
if (torrents.isEmpty())
|
||||
return;
|
||||
|
||||
const QString newLocation = fileDialog->selectedFiles().constFirst();
|
||||
if (newLocation.isEmpty() || !QDir(newLocation).exists())
|
||||
return;
|
||||
|
||||
// Actually move storage
|
||||
for (BitTorrent::Torrent *const torrent : torrents)
|
||||
{
|
||||
torrent->setAutoTMMEnabled(false);
|
||||
torrent->setSavePath(newLocation);
|
||||
}
|
||||
});
|
||||
|
||||
fileDialog->show();
|
||||
}
|
||||
|
||||
void TransferListWidget::pauseAllTorrents()
|
||||
{
|
||||
for (BitTorrent::Torrent *const torrent : asConst(BitTorrent::Session::instance()->torrents()))
|
||||
@@ -647,8 +681,28 @@ void TransferListWidget::setSelectedTorrentsSuperSeeding(const bool enabled) con
|
||||
}
|
||||
}
|
||||
|
||||
void TransferListWidget::setSelectedAutoTMMEnabled(const bool enabled) const
|
||||
void TransferListWidget::setSelectedTorrentsSequentialDownload(const bool enabled) const
|
||||
{
|
||||
for (BitTorrent::Torrent *const torrent : asConst(getSelectedTorrents()))
|
||||
torrent->setSequentialDownload(enabled);
|
||||
}
|
||||
|
||||
void TransferListWidget::setSelectedFirstLastPiecePrio(const bool enabled) const
|
||||
{
|
||||
for (BitTorrent::Torrent *const torrent : asConst(getSelectedTorrents()))
|
||||
torrent->setFirstLastPiecePriority(enabled);
|
||||
}
|
||||
|
||||
void TransferListWidget::setSelectedAutoTMMEnabled(const bool enabled)
|
||||
{
|
||||
if (enabled)
|
||||
{
|
||||
const QMessageBox::StandardButton btn = QMessageBox::question(this, tr("Enable automatic torrent management")
|
||||
, tr("Are you sure you want to enable Automatic Torrent Management for the selected torrent(s)? They may be relocated.")
|
||||
, (QMessageBox::Yes | QMessageBox::No), QMessageBox::Yes);
|
||||
if (btn != QMessageBox::Yes) return;
|
||||
}
|
||||
|
||||
for (BitTorrent::Torrent *const torrent : asConst(getSelectedTorrents()))
|
||||
torrent->setAutoTMMEnabled(enabled);
|
||||
}
|
||||
@@ -796,6 +850,7 @@ void TransferListWidget::displayListMenu(const QPoint &)
|
||||
|
||||
auto *listMenu = new QMenu(this);
|
||||
listMenu->setAttribute(Qt::WA_DeleteOnClose);
|
||||
listMenu->setToolTipsVisible(true);
|
||||
|
||||
// Create actions
|
||||
|
||||
@@ -821,6 +876,8 @@ void TransferListWidget::displayListMenu(const QPoint &)
|
||||
connect(actionTopQueuePos, &QAction::triggered, this, &TransferListWidget::topQueuePosSelectedTorrents);
|
||||
auto *actionBottomQueuePos = new QAction(UIThemeManager::instance()->getIcon("go-bottom"), tr("Move to bottom", "i.e. Move to bottom of the queue"), listMenu);
|
||||
connect(actionBottomQueuePos, &QAction::triggered, this, &TransferListWidget::bottomQueuePosSelectedTorrents);
|
||||
auto *actionSetTorrentPath = new QAction(UIThemeManager::instance()->getIcon("inode-directory"), tr("Set location..."), listMenu);
|
||||
connect(actionSetTorrentPath, &QAction::triggered, this, &TransferListWidget::setSelectedTorrentsLocation);
|
||||
auto *actionForceRecheck = new QAction(UIThemeManager::instance()->getIcon("document-edit-verify"), tr("Force recheck"), listMenu);
|
||||
connect(actionForceRecheck, &QAction::triggered, this, &TransferListWidget::recheckSelectedTorrents);
|
||||
auto *actionForceReannounce = new QAction(UIThemeManager::instance()->getIcon("document-edit-verify"), tr("Force reannounce"), listMenu);
|
||||
@@ -839,6 +896,13 @@ void TransferListWidget::displayListMenu(const QPoint &)
|
||||
connect(actionSuperSeedingMode, &QAction::triggered, this, &TransferListWidget::setSelectedTorrentsSuperSeeding);
|
||||
auto *actionRename = new QAction(UIThemeManager::instance()->getIcon("edit-rename"), tr("Rename..."), listMenu);
|
||||
connect(actionRename, &QAction::triggered, this, &TransferListWidget::renameSelectedTorrent);
|
||||
auto *actionSequentialDownload = new TriStateAction(tr("Download in sequential order"), listMenu);
|
||||
connect(actionSequentialDownload, &QAction::triggered, this, &TransferListWidget::setSelectedTorrentsSequentialDownload);
|
||||
auto *actionFirstLastPiecePrio = new TriStateAction(tr("Download first and last pieces first"), listMenu);
|
||||
connect(actionFirstLastPiecePrio, &QAction::triggered, this, &TransferListWidget::setSelectedFirstLastPiecePrio);
|
||||
auto *actionAutoTMM = new TriStateAction(tr("Automatic Torrent Management"), listMenu);
|
||||
actionAutoTMM->setToolTip(tr("Automatic mode means that various torrent properties (e.g. save path) will be decided by the associated category"));
|
||||
connect(actionAutoTMM, &QAction::triggered, this, &TransferListWidget::setSelectedAutoTMMEnabled);
|
||||
auto *actionEditTracker = new QAction(UIThemeManager::instance()->getIcon("edit-rename"), tr("Edit trackers..."), listMenu);
|
||||
connect(actionEditTracker, &QAction::triggered, this, &TransferListWidget::editTorrentTrackers);
|
||||
// End of actions
|
||||
@@ -851,6 +915,8 @@ void TransferListWidget::displayListMenu(const QPoint &)
|
||||
bool sequentialDownloadMode = false, prioritizeFirstLast = false;
|
||||
bool oneHasMetadata = false, oneNotSeed = false;
|
||||
bool allSameCategory = true;
|
||||
bool allSameAutoTMM = true;
|
||||
bool firstAutoTMM = false;
|
||||
QString firstCategory;
|
||||
bool first = true;
|
||||
TagSet tagsInAny;
|
||||
@@ -874,6 +940,7 @@ void TransferListWidget::displayListMenu(const QPoint &)
|
||||
|
||||
if (first)
|
||||
{
|
||||
firstAutoTMM = torrent->isAutoTMMEnabled();
|
||||
tagsInAll = torrentTags;
|
||||
}
|
||||
else
|
||||
@@ -881,6 +948,9 @@ void TransferListWidget::displayListMenu(const QPoint &)
|
||||
tagsInAll.intersect(torrentTags);
|
||||
}
|
||||
|
||||
if (firstAutoTMM != torrent->isAutoTMMEnabled())
|
||||
allSameAutoTMM = false;
|
||||
|
||||
if (torrent->hasMetadata())
|
||||
oneHasMetadata = true;
|
||||
if (!torrent->isSeed())
|
||||
@@ -940,7 +1010,7 @@ void TransferListWidget::displayListMenu(const QPoint &)
|
||||
|
||||
if (oneHasMetadata && oneNotSeed && !allSameSequentialDownloadMode
|
||||
&& !allSamePrioFirstlast && !allSameSuperSeeding && !allSameCategory
|
||||
&& needsStart && needsForce && needsPause && needsPreview
|
||||
&& needsStart && needsForce && needsPause && needsPreview && !allSameAutoTMM
|
||||
&& hasInfohashV1 && hasInfohashV2)
|
||||
{
|
||||
break;
|
||||
@@ -956,10 +1026,36 @@ void TransferListWidget::displayListMenu(const QPoint &)
|
||||
listMenu->addSeparator();
|
||||
listMenu->addAction(actionDelete);
|
||||
listMenu->addSeparator();
|
||||
listMenu->addAction(actionSetTorrentPath);
|
||||
if (selectedIndexes.size() == 1)
|
||||
listMenu->addAction(actionRename);
|
||||
listMenu->addAction(actionEditTracker);
|
||||
|
||||
// Category Menu
|
||||
QStringList categories = BitTorrent::Session::instance()->categories();
|
||||
std::sort(categories.begin(), categories.end(), Utils::Compare::NaturalLessThan<Qt::CaseInsensitive>());
|
||||
|
||||
QMenu *categoryMenu = listMenu->addMenu(UIThemeManager::instance()->getIcon("view-categories"), tr("Category"));
|
||||
|
||||
categoryMenu->addAction(UIThemeManager::instance()->getIcon("list-add"), tr("New...", "New category...")
|
||||
, this, &TransferListWidget::askNewCategoryForSelection);
|
||||
categoryMenu->addAction(UIThemeManager::instance()->getIcon("edit-clear"), tr("Reset", "Reset category")
|
||||
, this, [this]() { setSelectionCategory(""); });
|
||||
categoryMenu->addSeparator();
|
||||
|
||||
for (const QString &category : asConst(categories))
|
||||
{
|
||||
const QString escapedCategory = QString(category).replace('&', "&&"); // avoid '&' becomes accelerator key
|
||||
QAction *categoryAction = categoryMenu->addAction(UIThemeManager::instance()->getIcon("inode-directory"), escapedCategory
|
||||
, this, [this, category]() { setSelectionCategory(category); });
|
||||
|
||||
if (allSameCategory && (category == firstCategory))
|
||||
{
|
||||
categoryAction->setCheckable(true);
|
||||
categoryAction->setChecked(true);
|
||||
}
|
||||
}
|
||||
|
||||
// Tag Menu
|
||||
QStringList tags(BitTorrent::Session::instance()->tags().values());
|
||||
std::sort(tags.begin(), tags.end(), Utils::Compare::NaturalLessThan<Qt::CaseInsensitive>());
|
||||
@@ -998,6 +1094,11 @@ void TransferListWidget::displayListMenu(const QPoint &)
|
||||
tagsMenu->addAction(action);
|
||||
}
|
||||
|
||||
actionAutoTMM->setCheckState(allSameAutoTMM
|
||||
? (firstAutoTMM ? Qt::Checked : Qt::Unchecked)
|
||||
: Qt::PartiallyChecked);
|
||||
listMenu->addAction(actionAutoTMM);
|
||||
|
||||
listMenu->addSeparator();
|
||||
listMenu->addAction(actionTorrentOptions);
|
||||
if (!oneNotSeed && oneHasMetadata)
|
||||
@@ -1015,7 +1116,19 @@ void TransferListWidget::displayListMenu(const QPoint &)
|
||||
addedPreviewAction = true;
|
||||
}
|
||||
if (oneNotSeed)
|
||||
{
|
||||
actionSequentialDownload->setCheckState(allSameSequentialDownloadMode
|
||||
? (sequentialDownloadMode ? Qt::Checked : Qt::Unchecked)
|
||||
: Qt::PartiallyChecked);
|
||||
listMenu->addAction(actionSequentialDownload);
|
||||
|
||||
actionFirstLastPiecePrio->setCheckState(allSamePrioFirstlast
|
||||
? (prioritizeFirstLast ? Qt::Checked : Qt::Unchecked)
|
||||
: Qt::PartiallyChecked);
|
||||
listMenu->addAction(actionFirstLastPiecePrio);
|
||||
|
||||
addedPreviewAction = true;
|
||||
}
|
||||
|
||||
if (addedPreviewAction)
|
||||
listMenu->addSeparator();
|
||||
|
@@ -65,6 +65,7 @@ public slots:
|
||||
void addSelectionTag(const QString &tag);
|
||||
void removeSelectionTag(const QString &tag);
|
||||
void clearSelectionTags();
|
||||
void setSelectedTorrentsLocation();
|
||||
void pauseAllTorrents();
|
||||
void resumeAllTorrents();
|
||||
void startSelectedTorrents();
|
||||
@@ -90,7 +91,7 @@ public slots:
|
||||
void setTorrentOptions();
|
||||
void previewSelectedTorrents();
|
||||
void hideQueuePosColumn(bool hide);
|
||||
void displayDLHoSMenu(const QPoint&);
|
||||
void displayDLHoSMenu(const QPoint &);
|
||||
void applyNameFilter(const QString &name);
|
||||
void applyStatusFilter(int f);
|
||||
void applyCategoryFilter(const QString &category);
|
||||
@@ -108,7 +109,9 @@ private slots:
|
||||
void displayListMenu(const QPoint &);
|
||||
void currentChanged(const QModelIndex ¤t, const QModelIndex&) override;
|
||||
void setSelectedTorrentsSuperSeeding(bool enabled) const;
|
||||
void setSelectedAutoTMMEnabled(bool enabled) const;
|
||||
void setSelectedTorrentsSequentialDownload(bool enabled) const;
|
||||
void setSelectedFirstLastPiecePrio(bool enabled) const;
|
||||
void setSelectedAutoTMMEnabled(bool enabled);
|
||||
void askNewCategoryForSelection();
|
||||
void saveSettings();
|
||||
|
||||
|
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
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user