You've already forked qBittorrent
mirror of
https://github.com/qbittorrent/qBittorrent
synced 2025-10-14 11:52:15 +02:00
Compare commits
25 Commits
release-5.
...
release-5.
Author | SHA1 | Date | |
---|---|---|---|
![]() |
4b794a9930 | ||
![]() |
96b27a313e | ||
![]() |
c39849bd3b | ||
![]() |
daf7af0d7b | ||
![]() |
a6809efbbb | ||
![]() |
ddd8fbd34e | ||
![]() |
13fcd3d635 | ||
![]() |
3c6ff0097f | ||
![]() |
03dc089148 | ||
![]() |
100ee5dbe0 | ||
![]() |
310a9d8e1a | ||
![]() |
677cabcbdf | ||
![]() |
b86079974c | ||
![]() |
ca6a89e238 | ||
![]() |
0132b17af6 | ||
![]() |
505c1e1c0a | ||
![]() |
ecde201ec5 | ||
![]() |
730bf957a4 | ||
![]() |
069cd029eb | ||
![]() |
375e6800e9 | ||
![]() |
09fb92466a | ||
![]() |
69321f0e94 | ||
![]() |
f39e066672 | ||
![]() |
6a5ea93c92 | ||
![]() |
35dce07c63 |
13
.github/workflows/ci_ubuntu.yaml
vendored
13
.github/workflows/ci_ubuntu.yaml
vendored
@@ -134,16 +134,15 @@ jobs:
|
||||
|
||||
- name: Install AppImage
|
||||
run: |
|
||||
sudo apt install libfuse2
|
||||
curl \
|
||||
-L \
|
||||
-Z \
|
||||
-O https://github.com/linuxdeploy/linuxdeploy/releases/download/continuous/linuxdeploy-static-x86_64.AppImage \
|
||||
-O https://github.com/linuxdeploy/linuxdeploy-plugin-qt/releases/download/continuous/linuxdeploy-plugin-qt-static-x86_64.AppImage \
|
||||
-O https://github.com/linuxdeploy/linuxdeploy/releases/download/continuous/linuxdeploy-x86_64.AppImage \
|
||||
-O https://github.com/linuxdeploy/linuxdeploy-plugin-qt/releases/download/continuous/linuxdeploy-plugin-qt-x86_64.AppImage \
|
||||
-O https://github.com/linuxdeploy/linuxdeploy-plugin-appimage/releases/download/continuous/linuxdeploy-plugin-appimage-x86_64.AppImage
|
||||
chmod +x \
|
||||
linuxdeploy-static-x86_64.AppImage \
|
||||
linuxdeploy-plugin-qt-static-x86_64.AppImage \
|
||||
linuxdeploy-x86_64.AppImage \
|
||||
linuxdeploy-plugin-qt-x86_64.AppImage \
|
||||
linuxdeploy-plugin-appimage-x86_64.AppImage
|
||||
|
||||
- name: Prepare files for AppImage
|
||||
@@ -156,12 +155,12 @@ jobs:
|
||||
|
||||
- name: Package AppImage
|
||||
run: |
|
||||
./linuxdeploy-static-x86_64.AppImage --appdir qbittorrent --plugin qt
|
||||
./linuxdeploy-x86_64.AppImage --appdir qbittorrent --plugin qt
|
||||
rm qbittorrent/apprun-hooks/*
|
||||
cp .github/workflows/helper/appimage/export_vars.sh qbittorrent/apprun-hooks/export_vars.sh
|
||||
NO_APPSTREAM=1 \
|
||||
OUTPUT=upload/qbittorrent-CI_Ubuntu_x86_64.AppImage \
|
||||
./linuxdeploy-static-x86_64.AppImage --appdir qbittorrent --output appimage
|
||||
./linuxdeploy-x86_64.AppImage --appdir qbittorrent --output appimage
|
||||
|
||||
- name: Upload build artifacts
|
||||
uses: actions/upload-artifact@v4
|
||||
|
17
Changelog
17
Changelog
@@ -1,3 +1,20 @@
|
||||
Sun Apr 13th 2025 - sledgehammer999 <sledgehammer999@qbittorrent.org> - v5.0.5
|
||||
- FEATURE: Add an advanced setting for setting the "Add New Torrent" dialog as modal (glassez)
|
||||
- BUGFIX: Improve command line parameters serialization (glassez)
|
||||
- BUGFIX: Declare missing color IDs for theming (glassez)
|
||||
- WINDOWS: NSIS: Update Swedish translation (Daniel Nylander)
|
||||
|
||||
Tue Feb 18th 2025 - sledgehammer999 <sledgehammer999@qbittorrent.org> - v5.0.4
|
||||
- BUGFIX: Fix cannot remove trackers via WebAPI (Chocobo1)
|
||||
- BUGFIX: Fix torrent content checkbox state under certain conditions (thalieht)
|
||||
- BUGFIX: Hide zero and infinity values in peer list only when that setting is set to `Always` (thalieht)
|
||||
- BUGFIX: Remove stopped torrent from "error" tracker filter (glassez)
|
||||
- WEBUI: Fix memory leak in context menus (skomerko)
|
||||
- WEBAPI: Don't trim string parameters (glassez)
|
||||
- WINDOWS: Handle Qt style options uniformly (glassez)
|
||||
- WINDOWS: NSIS: Update Portuguese translation (Hugo Carvalho)
|
||||
- MACOS: Avoid memory leak (Chocobo1)
|
||||
|
||||
Mon Dec 16th 2024 - sledgehammer999 <sledgehammer999@qbittorrent.org> - v5.0.3
|
||||
- BUGFIX: Discard obsolete "state update" events after torrent is reloaded (glassez)
|
||||
- BUGFIX: Fix incorrect SQL column definition (glassez)
|
||||
|
4
dist/mac/Info.plist
vendored
4
dist/mac/Info.plist
vendored
@@ -55,7 +55,7 @@
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>APPL</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>5.0.3</string>
|
||||
<string>5.0.5</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>${EXECUTABLE_NAME}</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
@@ -67,7 +67,7 @@
|
||||
<key>NSAppleScriptEnabled</key>
|
||||
<string>YES</string>
|
||||
<key>NSHumanReadableCopyright</key>
|
||||
<string>Copyright © 2006-2024 The qBittorrent project</string>
|
||||
<string>Copyright © 2006-2025 The qBittorrent project</string>
|
||||
<key>UTExportedTypeDeclarations</key>
|
||||
<array>
|
||||
<dict>
|
||||
|
@@ -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
|
||||
|
@@ -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="5.0.3" date="2024-12-16"/>
|
||||
<release version="5.0.5" date="2025-04-13"/>
|
||||
</releases>
|
||||
</component>
|
||||
|
4
dist/windows/config.nsh
vendored
4
dist/windows/config.nsh
vendored
@@ -14,7 +14,7 @@
|
||||
; 4.5.1.3 -> good
|
||||
; 4.5.1.3.2 -> bad
|
||||
; 4.5.0beta -> bad
|
||||
!define /ifndef QBT_VERSION "5.0.3"
|
||||
!define /ifndef QBT_VERSION "5.0.5"
|
||||
|
||||
; Option that controls the installer's window name
|
||||
; If set, its value will be used like this:
|
||||
@@ -86,7 +86,7 @@ OutFile "qbittorrent_${QBT_INSTALLER_FILENAME}_setup.exe"
|
||||
;Installer Version Information
|
||||
VIAddVersionKey "ProductName" "qBittorrent"
|
||||
VIAddVersionKey "CompanyName" "The qBittorrent project"
|
||||
VIAddVersionKey "LegalCopyright" "Copyright ©2006-2024 The qBittorrent project"
|
||||
VIAddVersionKey "LegalCopyright" "Copyright ©2006-2025 The qBittorrent project"
|
||||
VIAddVersionKey "FileDescription" "qBittorrent - A Bittorrent Client"
|
||||
VIAddVersionKey "FileVersion" "${QBT_VERSION}"
|
||||
|
||||
|
@@ -7,7 +7,7 @@ LangString inst_desktop ${LANG_PORTUGUESE} "Criar atalho no ambiente de trabalho
|
||||
;LangString inst_startmenu ${LANG_ENGLISH} "Create Start Menu Shortcut"
|
||||
LangString inst_startmenu ${LANG_PORTUGUESE} "Criar atalho no menu Iniciar"
|
||||
;LangString inst_startup ${LANG_ENGLISH} "Start qBittorrent on Windows start up"
|
||||
LangString inst_startup ${LANG_PORTUGUESE} "Iniciar o qBittorrent na inicialização do Windows"
|
||||
LangString inst_startup ${LANG_PORTUGUESE} "Iniciar o qBittorrent no arranque do Windows"
|
||||
;LangString inst_torrent ${LANG_ENGLISH} "Open .torrent files with qBittorrent"
|
||||
LangString inst_torrent ${LANG_PORTUGUESE} "Abrir ficheiros .torrent com o qBittorrent"
|
||||
;LangString inst_magnet ${LANG_ENGLISH} "Open magnet links with qBittorrent"
|
||||
@@ -29,7 +29,7 @@ LangString launch_qbt ${LANG_PORTUGUESE} "Iniciar qBittorrent."
|
||||
;LangString inst_requires_64bit ${LANG_ENGLISH} "This installer works only in 64-bit Windows versions."
|
||||
LangString inst_requires_64bit ${LANG_PORTUGUESE} "Este instalador funciona apenas em versões Windows de 64 bits."
|
||||
;LangString inst_requires_win10 ${LANG_ENGLISH} "This installer requires at least Windows 10 (1809) / Windows Server 2019."
|
||||
LangString inst_requires_win10 ${LANG_PORTUGUESE} "This installer requires at least Windows 10 (1809) / Windows Server 2019."
|
||||
LangString inst_requires_win10 ${LANG_PORTUGUESE} "Este instalador requer, pelo menos, o Windows 10 (1809) / Windows Server 2019."
|
||||
;LangString inst_uninstall_link_description ${LANG_ENGLISH} "Uninstall qBittorrent"
|
||||
LangString inst_uninstall_link_description ${LANG_PORTUGUESE} "Desinstalar qBittorrent"
|
||||
|
||||
|
12
dist/windows/installer-translations/swedish.nsh
vendored
12
dist/windows/installer-translations/swedish.nsh
vendored
@@ -7,21 +7,21 @@ LangString inst_desktop ${LANG_SWEDISH} "Skapa skrivbordsgenväg"
|
||||
;LangString inst_startmenu ${LANG_ENGLISH} "Create Start Menu Shortcut"
|
||||
LangString inst_startmenu ${LANG_SWEDISH} "Skapa startmenygenväg"
|
||||
;LangString inst_startup ${LANG_ENGLISH} "Start qBittorrent on Windows start up"
|
||||
LangString inst_startup ${LANG_SWEDISH} "Starta qBittorrent vid Windows start"
|
||||
LangString inst_startup ${LANG_SWEDISH} "Starta qBittorrent vid Windows-uppstart"
|
||||
;LangString inst_torrent ${LANG_ENGLISH} "Open .torrent files with qBittorrent"
|
||||
LangString inst_torrent ${LANG_SWEDISH} "Öppna .torrent-filer med qBittorrent"
|
||||
;LangString inst_magnet ${LANG_ENGLISH} "Open magnet links with qBittorrent"
|
||||
LangString inst_magnet ${LANG_SWEDISH} "Öppna magnetlänkar med qBittorrent"
|
||||
;LangString inst_firewall ${LANG_ENGLISH} "Add Windows Firewall rule"
|
||||
LangString inst_firewall ${LANG_SWEDISH} "Lägg till Windows-brandväggregel"
|
||||
LangString inst_firewall ${LANG_SWEDISH} "Lägg till Windows-brandväggsregel"
|
||||
;LangString inst_pathlimit ${LANG_ENGLISH} "Disable Windows path length limit (260 character MAX_PATH limitation, requires Windows 10 1607 or later)"
|
||||
LangString inst_pathlimit ${LANG_SWEDISH} "Inaktivera gränsen för Windows-sökvägslängd (260 tecken MAX_PATH-begränsning, kräver Windows 10 1607 eller senare)"
|
||||
;LangString inst_firewallinfo ${LANG_ENGLISH} "Adding Windows Firewall rule"
|
||||
LangString inst_firewallinfo ${LANG_SWEDISH} "Lägger till Windows-brandväggregel"
|
||||
LangString inst_firewallinfo ${LANG_SWEDISH} "Lägger till Windows-brandväggsregel"
|
||||
;LangString inst_warning ${LANG_ENGLISH} "qBittorrent is running. Please close the application before installing."
|
||||
LangString inst_warning ${LANG_SWEDISH} "qBittorrent körs. Vänligen stäng programmet innan du installerar."
|
||||
LangString inst_warning ${LANG_SWEDISH} "qBittorrent körs. Stäng programmet innan du installerar."
|
||||
;LangString inst_uninstall_question ${LANG_ENGLISH} "Current version will be uninstalled. User settings and torrents will remain intact."
|
||||
LangString inst_uninstall_question ${LANG_SWEDISH} "Nuvarande version avinstalleras. Användarinställningar och torrenter kommer att förbli intakta."
|
||||
LangString inst_uninstall_question ${LANG_SWEDISH} "Aktuell version avinstalleras. Användarinställningar och torrenter kommer att förbli intakta."
|
||||
;LangString inst_unist ${LANG_ENGLISH} "Uninstalling previous version."
|
||||
LangString inst_unist ${LANG_SWEDISH} "Avinstallerar tidigare version."
|
||||
;LangString launch_qbt ${LANG_ENGLISH} "Launch qBittorrent."
|
||||
@@ -53,7 +53,7 @@ LangString remove_firewallinfo ${LANG_SWEDISH} "Tar bort Windows-brandväggsrege
|
||||
;LangString remove_cache ${LANG_ENGLISH} "Remove torrents and cached data"
|
||||
LangString remove_cache ${LANG_SWEDISH} "Ta bort torrenter och cachade data"
|
||||
;LangString uninst_warning ${LANG_ENGLISH} "qBittorrent is running. Please close the application before uninstalling."
|
||||
LangString uninst_warning ${LANG_SWEDISH} "qBittorrent körs. Vänligen stäng programmet innan du avinstallerar."
|
||||
LangString uninst_warning ${LANG_SWEDISH} "qBittorrent körs. Stäng programmet innan du avinstallerar."
|
||||
;LangString uninst_tor_warn ${LANG_ENGLISH} "Not removing .torrent association. It is associated with:"
|
||||
LangString uninst_tor_warn ${LANG_SWEDISH} "Tar inte bort .torrent-association. Den är associerad med:"
|
||||
;LangString uninst_mag_warn ${LANG_ENGLISH} "Not removing magnet association. It is associated with:"
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Bittorrent Client using Qt and libtorrent.
|
||||
* Copyright (C) 2015-2024 Vladimir Golovnev <glassez@yandex.ru>
|
||||
* Copyright (C) 2015-2025 Vladimir Golovnev <glassez@yandex.ru>
|
||||
* Copyright (C) 2006 Christophe Dumez
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
@@ -124,6 +124,28 @@ namespace
|
||||
const int PIXMAP_CACHE_SIZE = 64 * 1024 * 1024; // 64MiB
|
||||
#endif
|
||||
|
||||
const QString PARAM_ADDSTOPPED = u"@addStopped"_s;
|
||||
const QString PARAM_CATEGORY = u"@category"_s;
|
||||
const QString PARAM_FIRSTLASTPIECEPRIORITY = u"@firstLastPiecePriority"_s;
|
||||
const QString PARAM_SAVEPATH = u"@savePath"_s;
|
||||
const QString PARAM_SEQUENTIAL = u"@sequential"_s;
|
||||
const QString PARAM_SKIPCHECKING = u"@skipChecking"_s;
|
||||
const QString PARAM_SKIPDIALOG = u"@skipDialog"_s;
|
||||
|
||||
QString bindParamValue(const QStringView paramName, const QStringView paramValue)
|
||||
{
|
||||
return paramName + u'=' + paramValue;
|
||||
}
|
||||
|
||||
std::pair<QStringView, QStringView> parseParam(const QStringView param)
|
||||
{
|
||||
const qsizetype sepIndex = param.indexOf(u'=');
|
||||
if (sepIndex >= 0)
|
||||
return {param.first(sepIndex), param.sliced(sepIndex + 1)};
|
||||
|
||||
return {param, {}};
|
||||
}
|
||||
|
||||
QString serializeParams(const QBtCommandLineParameters ¶ms)
|
||||
{
|
||||
QStringList result;
|
||||
@@ -138,85 +160,86 @@ namespace
|
||||
const BitTorrent::AddTorrentParams &addTorrentParams = params.addTorrentParams;
|
||||
|
||||
if (!addTorrentParams.savePath.isEmpty())
|
||||
result.append(u"@savePath=" + addTorrentParams.savePath.data());
|
||||
result.append(bindParamValue(PARAM_SAVEPATH, addTorrentParams.savePath.data()));
|
||||
|
||||
if (addTorrentParams.addStopped.has_value())
|
||||
result.append(*addTorrentParams.addStopped ? u"@addStopped=1"_s : u"@addStopped=0"_s);
|
||||
result.append(bindParamValue(PARAM_ADDSTOPPED, (*addTorrentParams.addStopped ? u"1" : u"0")));
|
||||
|
||||
if (addTorrentParams.skipChecking)
|
||||
result.append(u"@skipChecking"_s);
|
||||
result.append(PARAM_SKIPCHECKING);
|
||||
|
||||
if (!addTorrentParams.category.isEmpty())
|
||||
result.append(u"@category=" + addTorrentParams.category);
|
||||
result.append(bindParamValue(PARAM_CATEGORY, addTorrentParams.category));
|
||||
|
||||
if (addTorrentParams.sequential)
|
||||
result.append(u"@sequential"_s);
|
||||
result.append(PARAM_SEQUENTIAL);
|
||||
|
||||
if (addTorrentParams.firstLastPiecePriority)
|
||||
result.append(u"@firstLastPiecePriority"_s);
|
||||
result.append(PARAM_FIRSTLASTPIECEPRIORITY);
|
||||
|
||||
if (params.skipDialog.has_value())
|
||||
result.append(*params.skipDialog ? u"@skipDialog=1"_s : u"@skipDialog=0"_s);
|
||||
result.append(bindParamValue(PARAM_SKIPDIALOG, (*params.skipDialog ? u"1" : u"0")));
|
||||
|
||||
result += params.torrentSources;
|
||||
|
||||
return result.join(PARAMS_SEPARATOR);
|
||||
}
|
||||
|
||||
QBtCommandLineParameters parseParams(const QString &str)
|
||||
QBtCommandLineParameters parseParams(const QStringView str)
|
||||
{
|
||||
QBtCommandLineParameters parsedParams;
|
||||
BitTorrent::AddTorrentParams &addTorrentParams = parsedParams.addTorrentParams;
|
||||
|
||||
for (QString param : asConst(str.split(PARAMS_SEPARATOR, Qt::SkipEmptyParts)))
|
||||
for (QStringView param : asConst(str.split(PARAMS_SEPARATOR, Qt::SkipEmptyParts)))
|
||||
{
|
||||
param = param.trimmed();
|
||||
const auto [paramName, paramValue] = parseParam(param);
|
||||
|
||||
// Process strings indicating options specified by the user.
|
||||
|
||||
if (param.startsWith(u"@savePath="))
|
||||
if (paramName == PARAM_SAVEPATH)
|
||||
{
|
||||
addTorrentParams.savePath = Path(param.mid(10));
|
||||
addTorrentParams.savePath = Path(paramValue.toString());
|
||||
continue;
|
||||
}
|
||||
|
||||
if (param.startsWith(u"@addStopped="))
|
||||
if (paramName == PARAM_ADDSTOPPED)
|
||||
{
|
||||
addTorrentParams.addStopped = (QStringView(param).mid(11).toInt() != 0);
|
||||
addTorrentParams.addStopped = (paramValue.toInt() != 0);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (param == u"@skipChecking")
|
||||
if (paramName == PARAM_SKIPCHECKING)
|
||||
{
|
||||
addTorrentParams.skipChecking = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (param.startsWith(u"@category="))
|
||||
if (paramName == PARAM_CATEGORY)
|
||||
{
|
||||
addTorrentParams.category = param.mid(10);
|
||||
addTorrentParams.category = paramValue.toString();
|
||||
continue;
|
||||
}
|
||||
|
||||
if (param == u"@sequential")
|
||||
if (paramName == PARAM_SEQUENTIAL)
|
||||
{
|
||||
addTorrentParams.sequential = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (param == u"@firstLastPiecePriority")
|
||||
if (paramName == PARAM_FIRSTLASTPIECEPRIORITY)
|
||||
{
|
||||
addTorrentParams.firstLastPiecePriority = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (param.startsWith(u"@skipDialog="))
|
||||
if (paramName == PARAM_SKIPDIALOG)
|
||||
{
|
||||
parsedParams.skipDialog = (QStringView(param).mid(12).toInt() != 0);
|
||||
parsedParams.skipDialog = (paramValue.toInt() != 0);
|
||||
continue;
|
||||
}
|
||||
|
||||
parsedParams.torrentSources.append(param);
|
||||
parsedParams.torrentSources.append(param.toString());
|
||||
}
|
||||
|
||||
return parsedParams;
|
||||
|
@@ -29,7 +29,10 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <QByteArray>
|
||||
#include <QHash>
|
||||
#include <QHostAddress>
|
||||
#include <QMap>
|
||||
#include <QString>
|
||||
#include <QVector>
|
||||
|
||||
|
@@ -2000,6 +2000,19 @@ void Preferences::setAddNewTorrentDialogSavePathHistoryLength(const int value)
|
||||
setValue(u"AddNewTorrentDialog/SavePathHistoryLength"_s, clampedValue);
|
||||
}
|
||||
|
||||
bool Preferences::isAddNewTorrentDialogAttached() const
|
||||
{
|
||||
return value(u"AddNewTorrentDialog/Attached"_s, false);
|
||||
}
|
||||
|
||||
void Preferences::setAddNewTorrentDialogAttached(const bool attached)
|
||||
{
|
||||
if (attached == isAddNewTorrentDialogAttached())
|
||||
return;
|
||||
|
||||
setValue(u"AddNewTorrentDialog/Attached"_s, attached);
|
||||
}
|
||||
|
||||
void Preferences::apply()
|
||||
{
|
||||
if (SettingsStorage::instance()->save())
|
||||
|
@@ -423,6 +423,8 @@ public:
|
||||
void setAddNewTorrentDialogTopLevel(bool value);
|
||||
int addNewTorrentDialogSavePathHistoryLength() const;
|
||||
void setAddNewTorrentDialogSavePathHistoryLength(int value);
|
||||
bool isAddNewTorrentDialogAttached() const;
|
||||
void setAddNewTorrentDialogAttached(bool attached);
|
||||
|
||||
public slots:
|
||||
void setStatusFilterState(bool checked);
|
||||
|
@@ -316,7 +316,11 @@ bool Utils::OS::applyMarkOfTheWeb(const Path &file, const QString &url)
|
||||
|
||||
::CFDictionarySetValue(properties, kLSQuarantineTypeKey, kLSQuarantineTypeOtherDownload);
|
||||
if (!url.isEmpty())
|
||||
::CFDictionarySetValue(properties, kLSQuarantineDataURLKey, url.toCFString());
|
||||
{
|
||||
const CFStringRef urlCFString = url.toCFString();
|
||||
[[maybe_unused]] const auto urlStringGuard = qScopeGuard([&urlCFString] { ::CFRelease(urlCFString); });
|
||||
::CFDictionarySetValue(properties, kLSQuarantineDataURLKey, urlCFString);
|
||||
}
|
||||
|
||||
const Boolean success = ::CFURLSetResourcePropertyForKey(fileURL, kCFURLQuarantinePropertiesKey
|
||||
, properties, NULL);
|
||||
|
@@ -30,7 +30,7 @@
|
||||
|
||||
#define QBT_VERSION_MAJOR 5
|
||||
#define QBT_VERSION_MINOR 0
|
||||
#define QBT_VERSION_BUGFIX 3
|
||||
#define QBT_VERSION_BUGFIX 5
|
||||
#define QBT_VERSION_BUILD 0
|
||||
#define QBT_VERSION_STATUS "" // Should be empty for stable releases!
|
||||
|
||||
|
@@ -67,7 +67,7 @@ AboutDialog::AboutDialog(QWidget *parent)
|
||||
u"</p>"_s
|
||||
.arg(tr("An advanced BitTorrent client programmed in C++, based on Qt toolkit and libtorrent-rasterbar.")
|
||||
.replace(u"C++"_s, u"C\u2060+\u2060+"_s) // make C++ non-breaking
|
||||
, tr("Copyright %1 2006-2024 The qBittorrent project").arg(C_COPYRIGHT)
|
||||
, tr("Copyright %1 2006-2025 The qBittorrent project").arg(C_COPYRIGHT)
|
||||
, tr("Home Page:")
|
||||
, tr("Forum:")
|
||||
, tr("Bug Tracker:"));
|
||||
|
@@ -97,6 +97,7 @@ namespace
|
||||
ENABLE_SPEED_WIDGET,
|
||||
#ifndef Q_OS_MACOS
|
||||
ENABLE_ICONS_IN_MENUS,
|
||||
USE_ATTACHED_ADD_NEW_TORRENT_DIALOG,
|
||||
#endif
|
||||
// embedded tracker
|
||||
TRACKER_STATUS,
|
||||
@@ -323,6 +324,7 @@ void AdvancedSettings::saveAdvancedSettings() const
|
||||
pref->setSpeedWidgetEnabled(m_checkBoxSpeedWidgetEnabled.isChecked());
|
||||
#ifndef Q_OS_MACOS
|
||||
pref->setIconsInMenusEnabled(m_checkBoxIconsInMenusEnabled.isChecked());
|
||||
pref->setAddNewTorrentDialogAttached(m_checkBoxAttachedAddNewTorrentDialog.isChecked());
|
||||
#endif
|
||||
|
||||
// Tracker
|
||||
@@ -835,6 +837,9 @@ void AdvancedSettings::loadAdvancedSettings()
|
||||
// Enable icons in menus
|
||||
m_checkBoxIconsInMenusEnabled.setChecked(pref->iconsInMenusEnabled());
|
||||
addRow(ENABLE_ICONS_IN_MENUS, tr("Enable icons in menus"), &m_checkBoxIconsInMenusEnabled);
|
||||
|
||||
m_checkBoxAttachedAddNewTorrentDialog.setChecked(pref->isAddNewTorrentDialogAttached());
|
||||
addRow(USE_ATTACHED_ADD_NEW_TORRENT_DIALOG, tr("Attach \"Add new torrent\" dialog to main window"), &m_checkBoxAttachedAddNewTorrentDialog);
|
||||
#endif
|
||||
// Tracker State
|
||||
m_checkBoxTrackerStatus.setChecked(session->isTrackerEnabled());
|
||||
|
@@ -108,6 +108,7 @@ private:
|
||||
|
||||
#ifndef Q_OS_MACOS
|
||||
QCheckBox m_checkBoxIconsInMenusEnabled;
|
||||
QCheckBox m_checkBoxAttachedAddNewTorrentDialog;
|
||||
#endif
|
||||
|
||||
#if defined(Q_OS_MACOS) || defined(Q_OS_WIN)
|
||||
|
@@ -225,12 +225,19 @@ bool GUIAddTorrentManager::processTorrent(const QString &source
|
||||
if (!hasMetadata)
|
||||
btSession()->downloadMetadata(torrentDescr);
|
||||
|
||||
#ifdef Q_OS_MACOS
|
||||
const bool attached = false;
|
||||
#else
|
||||
const bool attached = Preferences::instance()->isAddNewTorrentDialogAttached();
|
||||
#endif
|
||||
|
||||
// By not setting a parent to the "AddNewTorrentDialog", all those dialogs
|
||||
// will be displayed on top and will not overlap with the main window.
|
||||
auto *dlg = new AddNewTorrentDialog(torrentDescr, params, nullptr);
|
||||
auto *dlg = new AddNewTorrentDialog(torrentDescr, params, (attached ? app()->mainWindow() : nullptr));
|
||||
// Qt::Window is required to avoid showing only two dialog on top (see #12852).
|
||||
// Also improves the general convenience of adding multiple torrents.
|
||||
dlg->setWindowFlags(Qt::Window);
|
||||
if (!attached)
|
||||
dlg->setWindowFlags(Qt::Window);
|
||||
|
||||
dlg->setAttribute(Qt::WA_DeleteOnClose);
|
||||
m_dialogs[infoHash] = dlg;
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Bittorrent Client using Qt and libtorrent.
|
||||
* Copyright (C) 2023-2024 Vladimir Golovnev <glassez@yandex.ru>
|
||||
* Copyright (C) 2023-2025 Vladimir Golovnev <glassez@yandex.ru>
|
||||
* Copyright (C) 2024 Jonathan Ketchker
|
||||
* Copyright (C) 2006 Christophe Dumez <chris@qbittorrent.org>
|
||||
*
|
||||
@@ -456,10 +456,7 @@ void OptionsDialog::saveBehaviorTabOptions() const
|
||||
pref->setLocale(locale);
|
||||
|
||||
#ifdef Q_OS_WIN
|
||||
if (const QVariant systemStyle = m_ui->comboStyle->currentData(); systemStyle.isValid())
|
||||
pref->setStyle(systemStyle.toString());
|
||||
else
|
||||
pref->setStyle(m_ui->comboStyle->currentText());
|
||||
pref->setStyle(m_ui->comboStyle->currentData().toString());
|
||||
#endif
|
||||
|
||||
#if (defined(Q_OS_UNIX) && !defined(Q_OS_MACOS))
|
||||
@@ -1695,18 +1692,20 @@ void OptionsDialog::initializeStyleCombo()
|
||||
{
|
||||
#ifdef Q_OS_WIN
|
||||
m_ui->labelStyleHint->setText(tr("%1 is recommended for best compatibility with Windows dark mode"
|
||||
, "Fusion is recommended for best compatibility with Windows dark mode").arg(u"Fusion"_s));
|
||||
, "Fusion is recommended for best compatibility with Windows dark mode").arg(u"Fusion"_s));
|
||||
m_ui->comboStyle->addItem(tr("System", "System default Qt style"), u"system"_s);
|
||||
m_ui->comboStyle->setItemData(0, tr("Let Qt decide the style for this system"), Qt::ToolTipRole);
|
||||
m_ui->comboStyle->insertSeparator(1);
|
||||
|
||||
QStringList styleNames = QStyleFactory::keys();
|
||||
std::sort(styleNames.begin(), styleNames.end(), Utils::Compare::NaturalLessThan<Qt::CaseInsensitive>());
|
||||
m_ui->comboStyle->addItems(styleNames);
|
||||
for (const QString &styleName : asConst(styleNames))
|
||||
m_ui->comboStyle->addItem(styleName, styleName);
|
||||
|
||||
const QString prefStyleName = Preferences::instance()->getStyle();
|
||||
const QString selectedStyleName = prefStyleName.isEmpty() ? QApplication::style()->name() : prefStyleName;
|
||||
m_ui->comboStyle->setCurrentIndex(m_ui->comboStyle->findText(selectedStyleName, Qt::MatchFixedString));
|
||||
const int styleIndex = m_ui->comboStyle->findData(selectedStyleName, Qt::UserRole, Qt::MatchFixedString);
|
||||
m_ui->comboStyle->setCurrentIndex(std::max(0, styleIndex));
|
||||
#else
|
||||
m_ui->labelStyle->hide();
|
||||
m_ui->comboStyle->hide();
|
||||
|
@@ -32,6 +32,7 @@
|
||||
|
||||
#ifdef Q_OS_MACOS
|
||||
#include <IOKit/pwr_mgt/IOPMLib.h>
|
||||
#include <QScopeGuard>
|
||||
#endif
|
||||
|
||||
#ifdef Q_OS_WIN
|
||||
@@ -74,8 +75,10 @@ void PowerManagement::setBusy()
|
||||
#elif defined(QBT_USES_DBUS)
|
||||
m_inhibitor->requestBusy();
|
||||
#elif defined(Q_OS_MACOS)
|
||||
const CFStringRef assertName = tr("qBittorrent is active").toCFString();
|
||||
[[maybe_unused]] const auto assertNameGuard = qScopeGuard([&assertName] { ::CFRelease(assertName); });
|
||||
const IOReturn success = ::IOPMAssertionCreateWithName(kIOPMAssertionTypeNoIdleSleep, kIOPMAssertionLevelOn
|
||||
, tr("qBittorrent is active").toCFString(), &m_assertionID);
|
||||
, assertName, &m_assertionID);
|
||||
if (success != kIOReturnSuccess)
|
||||
m_busy = false;
|
||||
#endif
|
||||
|
@@ -420,7 +420,8 @@ void PeerListWidget::loadPeers(const BitTorrent::Torrent *torrent)
|
||||
for (auto i = m_peerItems.cbegin(); i != m_peerItems.cend(); ++i)
|
||||
existingPeers.insert(i.key());
|
||||
|
||||
const bool hideZeroValues = Preferences::instance()->getHideZeroValues();
|
||||
const Preferences *pref = Preferences::instance();
|
||||
const bool hideZeroValues = (pref->getHideZeroValues() && (pref->getHideZeroComboValues() == 0));
|
||||
for (const BitTorrent::PeerInfo &peer : peers)
|
||||
{
|
||||
const PeerEndpoint peerEndpoint {peer.address(), peer.connectionType()};
|
||||
|
@@ -398,7 +398,9 @@ QVariant TorrentContentModel::data(const QModelIndex &index, const int role) con
|
||||
const bool hasIgnored = std::any_of(childItems.cbegin(), childItems.cend()
|
||||
, [](const TorrentContentModelItem *childItem)
|
||||
{
|
||||
return (childItem->priority() == BitTorrent::DownloadPriority::Ignored);
|
||||
const auto prio = childItem->priority();
|
||||
return ((prio == BitTorrent::DownloadPriority::Ignored)
|
||||
|| (prio == BitTorrent::DownloadPriority::Mixed));
|
||||
});
|
||||
|
||||
return hasIgnored ? Qt::PartiallyChecked : Qt::Checked;
|
||||
|
@@ -444,6 +444,16 @@ void TrackersFilterWidget::handleTrackerStatusesUpdated(const BitTorrent::Torren
|
||||
trackerErrorHashesIt = m_trackerErrors.insert(id, {});
|
||||
trackerErrorHashesIt->insert(trackerEntryStatus.url);
|
||||
}
|
||||
else if (trackerEntryStatus.state == BitTorrent::TrackerEndpointState::NotContacted)
|
||||
{
|
||||
// remove tracker from "error", "tracker error" and "warning" categories
|
||||
if (warningHashesIt != m_warnings.end())
|
||||
warningHashesIt->remove(trackerEntryStatus.url);
|
||||
if (errorHashesIt != m_errors.end())
|
||||
errorHashesIt->remove(trackerEntryStatus.url);
|
||||
if (trackerErrorHashesIt != m_trackerErrors.end())
|
||||
trackerErrorHashesIt->remove(trackerEntryStatus.url);
|
||||
}
|
||||
}
|
||||
|
||||
if ((errorHashesIt != m_errors.end()) && errorHashesIt->isEmpty())
|
||||
|
@@ -80,7 +80,33 @@ inline QHash<QString, UIThemeColor> defaultUIThemeColors()
|
||||
{u"TransferList.StoppedUploading"_s, {Color::Primer::Light::doneFg, Color::Primer::Dark::doneFg}},
|
||||
{u"TransferList.Moving"_s, {Color::Primer::Light::successFg, Color::Primer::Dark::successFg}},
|
||||
{u"TransferList.MissingFiles"_s, {Color::Primer::Light::dangerFg, Color::Primer::Dark::dangerFg}},
|
||||
{u"TransferList.Error"_s, {Color::Primer::Light::dangerFg, Color::Primer::Dark::dangerFg}}
|
||||
{u"TransferList.Error"_s, {Color::Primer::Light::dangerFg, Color::Primer::Dark::dangerFg}},
|
||||
|
||||
{u"Palette.Window"_s, {{}, {}}},
|
||||
{u"Palette.WindowText"_s, {{}, {}}},
|
||||
{u"Palette.Base"_s, {{}, {}}},
|
||||
{u"Palette.AlternateBase"_s, {{}, {}}},
|
||||
{u"Palette.Text"_s, {{}, {}}},
|
||||
{u"Palette.ToolTipBase"_s, {{}, {}}},
|
||||
{u"Palette.ToolTipText"_s, {{}, {}}},
|
||||
{u"Palette.BrightText"_s, {{}, {}}},
|
||||
{u"Palette.Highlight"_s, {{}, {}}},
|
||||
{u"Palette.HighlightedText"_s, {{}, {}}},
|
||||
{u"Palette.Button"_s, {{}, {}}},
|
||||
{u"Palette.ButtonText"_s, {{}, {}}},
|
||||
{u"Palette.Link"_s, {{}, {}}},
|
||||
{u"Palette.LinkVisited"_s, {{}, {}}},
|
||||
{u"Palette.Light"_s, {{}, {}}},
|
||||
{u"Palette.Midlight"_s, {{}, {}}},
|
||||
{u"Palette.Mid"_s, {{}, {}}},
|
||||
{u"Palette.Dark"_s, {{}, {}}},
|
||||
{u"Palette.Shadow"_s, {{}, {}}},
|
||||
{u"Palette.WindowTextDisabled"_s, {{}, {}}},
|
||||
{u"Palette.TextDisabled"_s, {{}, {}}},
|
||||
{u"Palette.ToolTipTextDisabled"_s, {{}, {}}},
|
||||
{u"Palette.BrightTextDisabled"_s, {{}, {}}},
|
||||
{u"Palette.HighlightedTextDisabled"_s, {{}, {}}},
|
||||
{u"Palette.ButtonTextDisabled"_s, {{}, {}}}
|
||||
};
|
||||
}
|
||||
|
||||
|
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
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user