1
mirror of https://github.com/qbittorrent/qBittorrent synced 2025-10-14 11:52:15 +02:00

Compare commits

..

25 Commits

Author SHA1 Message Date
sledgehammer999
4b794a9930 Bump to 5.0.5 2025-04-13 10:55:32 +03:00
sledgehammer999
96b27a313e Update Changelog 2025-04-13 10:45:01 +03:00
Daniel Nylander
c39849bd3b NSIS: Update Swedish translation
PR #22046.
2025-04-13 10:43:51 +03:00
sledgehammer999
daf7af0d7b Sync translations from Transifex and run lupdate 2025-04-13 10:37:24 +03:00
Vladimir Golovnev
a6809efbbb Backport changes to v5.0.x branch
PR #22336.
2025-04-02 11:16:56 +03:00
Vladimir Golovnev
ddd8fbd34e Add option to enable previous Add new torrent dialog behavior
Some people are still unhappy with "standalone window mode" of "Add new torrent dialog" so just provide them with an option to use old "modal dialog mode" in all the current qBittorrent branches.

PR #22492 (based on original PR #19874).
2025-03-31 09:19:26 +03:00
Vladimir Golovnev
13fcd3d635 Add missing includes
PR #22362.
2025-03-05 09:07:18 +03:00
Vladimir Golovnev
3c6ff0097f Don't miss to declare some of the color IDs
PR #22330.
Closes #22326.
2025-02-25 18:57:00 +03:00
Vladimir Golovnev
03dc089148 Improve command line parameters serialization
PR #22319.
Closes #22306.
2025-02-25 09:11:59 +03:00
sledgehammer999
100ee5dbe0 Bump to 5.0.4 2025-02-18 16:13:57 +02:00
sledgehammer999
310a9d8e1a Update Changelog 2025-02-18 16:11:44 +02:00
Vladimir Golovnev
677cabcbdf GHA CI: fix AppImage building
PR #22286.
2025-02-16 17:46:38 +03:00
sledgehammer999
b86079974c Bump copyright year 2025-02-16 16:39:55 +02:00
sledgehammer999
ca6a89e238 Sync translations from Transifex and run lupdate 2025-02-16 16:27:34 +02:00
Chocobo1
0132b17af6 GHA CI: fix AppImage building
Upstream now defaults to static runtime and the previous URL is invalid now.
Upstream commits:
* c28054bab6
* ce5291e259

Also fuse2 is not needed now as stated on:
https://github.com/AppImage/type2-runtime?tab=readme-ov-file#type2-runtime-

PR #22286.
2025-02-16 11:02:36 +03:00
Vladimir Golovnev
505c1e1c0a Backport changes to v5.0.x branch
PR #22207.
2025-02-14 13:56:49 +03:00
Vladimir Golovnev
ecde201ec5 WebAPI: Don't trim string parameters
PR #22266.
Closes #19485.
Closes #22254.
2025-02-12 09:34:37 +03:00
skomerko
730bf957a4 WebUI: Don't keep references to context menu targets
PR https://github.com/qbittorrent/qBittorrent/pull/22234.
2025-02-11 20:26:43 +03:00
Hugo Carvalho
069cd029eb NSIS: Update Portuguese translation
PR #21632.
2025-02-11 12:19:56 +03:00
Vladimir Golovnev
375e6800e9 Remove stopped torrent from "error" tracker filter
PR #22219.
2025-01-31 15:25:23 +03:00
Vladimir Golovnev
09fb92466a Handle Qt style options uniformly
PR #22133.
Closes #22061.
2025-01-28 21:18:19 +03:00
thalieht
69321f0e94 Hide zero and infinity values in peer list only when that setting is set to Always
PR #22205.
Closes #21998.
2025-01-27 09:47:54 +03:00
thalieht
f39e066672 Fix torrent content checkbox state under certain conditions
PR #22190.
Closes #22189.
2025-01-26 17:08:19 +03:00
Chocobo1
6a5ea93c92 Avoid memory leak on macOS
Only Mark-of-the-Web and Power Management are affected.

PR #22176.
2025-01-19 16:35:45 +08:00
Chocobo1
35dce07c63 Fix cannot remove trackers via WebAPI
The backport commit c3c7f28bad was insufficient.

Closes 22039.
PR #22071.
2024-12-29 14:40:17 +08:00
109 changed files with 18704 additions and 18135 deletions

View File

@@ -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

View File

@@ -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
View File

@@ -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>

View File

@@ -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

View File

@@ -62,6 +62,6 @@
<url type="contribute">https://github.com/qbittorrent/qBittorrent/blob/master/CONTRIBUTING.md</url>
<content_rating type="oars-1.1"/>
<releases>
<release version="5.0.3" date="2024-12-16"/>
<release version="5.0.5" date="2025-04-13"/>
</releases>
</component>

View File

@@ -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}"

View File

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

View File

@@ -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:"

View File

@@ -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 &params)
{
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;

View File

@@ -29,7 +29,10 @@
#pragma once
#include <QByteArray>
#include <QHash>
#include <QHostAddress>
#include <QMap>
#include <QString>
#include <QVector>

View File

@@ -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())

View File

@@ -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);

View File

@@ -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);

View File

@@ -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!

View File

@@ -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:"));

View File

@@ -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());

View File

@@ -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)

View File

@@ -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;

View File

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

View File

@@ -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

View File

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

View File

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

View File

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

View File

@@ -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