diff --git a/.github/workflows/ci_macos.yaml b/.github/workflows/ci_macos.yaml
index 6180a44ea..e3f14f115 100644
--- a/.github/workflows/ci_macos.yaml
+++ b/.github/workflows/ci_macos.yaml
@@ -23,7 +23,6 @@ jobs:
env:
boost_path: "${{ github.workspace }}/../boost"
- openssl_root: "$(brew --prefix openssl@3)"
libtorrent_path: "${{ github.workspace }}/../libtorrent"
steps:
@@ -70,7 +69,7 @@ jobs:
mv "${{ github.workspace }}/.."/boost_* "${{ env.boost_path }}"
- name: Install Qt
- uses: jurplel/install-qt-action@v3
+ uses: jurplel/install-qt-action@v4
with:
version: ${{ matrix.qt_version }}
archives: qtbase qtdeclarative qtsvg qttools
@@ -94,8 +93,7 @@ jobs:
-DCMAKE_CXX_STANDARD=17 \
-DCMAKE_EXPORT_COMPILE_COMMANDS=ON \
-DBOOST_ROOT="${{ env.boost_path }}" \
- -Ddeprecated-functions=OFF \
- -DOPENSSL_ROOT_DIR="${{ env.openssl_root }}"
+ -Ddeprecated-functions=OFF
cmake --build build
sudo cmake --install build
@@ -109,7 +107,6 @@ jobs:
-DCMAKE_BUILD_TYPE=RelWithDebInfo \
-DCMAKE_EXPORT_COMPILE_COMMANDS=ON \
-DBOOST_ROOT="${{ env.boost_path }}" \
- -DOPENSSL_ROOT_DIR="${{ env.openssl_root }}" \
-DTESTING=ON \
-DVERBOSE_CONFIGURE=ON \
-D${{ matrix.qbt_gui }}
diff --git a/.github/workflows/ci_python.yaml b/.github/workflows/ci_python.yaml
index f08b382b4..fe525c8c6 100644
--- a/.github/workflows/ci_python.yaml
+++ b/.github/workflows/ci_python.yaml
@@ -53,7 +53,7 @@ jobs:
python-version: '3.7'
- name: Install tools (search engine)
- run: pip install bandit pycodestyle pyflakes
+ run: pip install bandit mypy pycodestyle pyflakes pyright
- name: Gather files (search engine)
run: |
@@ -61,6 +61,16 @@ jobs:
echo $PY_FILES
echo "PY_FILES=$PY_FILES" >> "$GITHUB_ENV"
+ - name: Check typings (search engine)
+ run: |
+ MYPYPATH="src/searchengine/nova3" \
+ mypy \
+ --follow-imports skip \
+ --strict \
+ $PY_FILES
+ pyright \
+ $PY_FILES
+
- name: Lint code (search engine)
run: |
pyflakes $PY_FILES
diff --git a/.github/workflows/ci_ubuntu.yaml b/.github/workflows/ci_ubuntu.yaml
index bcae07196..c35ca3e30 100644
--- a/.github/workflows/ci_ubuntu.yaml
+++ b/.github/workflows/ci_ubuntu.yaml
@@ -64,7 +64,7 @@ jobs:
mv "${{ github.workspace }}/.."/boost_* "${{ env.boost_path }}"
- name: Install Qt
- uses: jurplel/install-qt-action@v3
+ uses: jurplel/install-qt-action@v4
with:
version: ${{ matrix.qt_version }}
archives: icu qtbase qtdeclarative qtsvg qttools
@@ -134,7 +134,6 @@ jobs:
- name: Install AppImage
run: |
- sudo apt install libfuse2
curl \
-L \
-Z \
diff --git a/.github/workflows/ci_windows.yaml b/.github/workflows/ci_windows.yaml
index d6050d2fa..f04f90d55 100644
--- a/.github/workflows/ci_windows.yaml
+++ b/.github/workflows/ci_windows.yaml
@@ -93,9 +93,9 @@ jobs:
move "${{ github.workspace }}/../boost_*" "${{ env.boost_path }}"
- name: Install Qt
- uses: jurplel/install-qt-action@v3
+ uses: jurplel/install-qt-action@v4
with:
- version: "6.7.0"
+ version: "6.7.3"
archives: qtbase qtsvg qttools
cache: true
@@ -153,26 +153,26 @@ jobs:
copy build/qbittorrent.pdb upload/qBittorrent
copy dist/windows/qt.conf upload/qBittorrent
# runtimes
- copy "${{ env.Qt6_DIR }}/bin/Qt6Core.dll" upload/qBittorrent
- copy "${{ env.Qt6_DIR }}/bin/Qt6Gui.dll" upload/qBittorrent
- copy "${{ env.Qt6_DIR }}/bin/Qt6Network.dll" upload/qBittorrent
- copy "${{ env.Qt6_DIR }}/bin/Qt6Sql.dll" upload/qBittorrent
- copy "${{ env.Qt6_DIR }}/bin/Qt6Svg.dll" upload/qBittorrent
- copy "${{ env.Qt6_DIR }}/bin/Qt6Widgets.dll" upload/qBittorrent
- copy "${{ env.Qt6_DIR }}/bin/Qt6Xml.dll" upload/qBittorrent
+ copy "${{ env.Qt_ROOT_DIR }}/bin/Qt6Core.dll" upload/qBittorrent
+ copy "${{ env.Qt_ROOT_DIR }}/bin/Qt6Gui.dll" upload/qBittorrent
+ copy "${{ env.Qt_ROOT_DIR }}/bin/Qt6Network.dll" upload/qBittorrent
+ copy "${{ env.Qt_ROOT_DIR }}/bin/Qt6Sql.dll" upload/qBittorrent
+ copy "${{ env.Qt_ROOT_DIR }}/bin/Qt6Svg.dll" upload/qBittorrent
+ copy "${{ env.Qt_ROOT_DIR }}/bin/Qt6Widgets.dll" upload/qBittorrent
+ copy "${{ env.Qt_ROOT_DIR }}/bin/Qt6Xml.dll" upload/qBittorrent
mkdir upload/qBittorrent/plugins/iconengines
- copy "${{ env.Qt6_DIR }}/plugins/iconengines/qsvgicon.dll" upload/qBittorrent/plugins/iconengines
+ copy "${{ env.Qt_ROOT_DIR }}/plugins/iconengines/qsvgicon.dll" upload/qBittorrent/plugins/iconengines
mkdir upload/qBittorrent/plugins/imageformats
- copy "${{ env.Qt6_DIR }}/plugins/imageformats/qico.dll" upload/qBittorrent/plugins/imageformats
- copy "${{ env.Qt6_DIR }}/plugins/imageformats/qsvg.dll" upload/qBittorrent/plugins/imageformats
+ copy "${{ env.Qt_ROOT_DIR }}/plugins/imageformats/qico.dll" upload/qBittorrent/plugins/imageformats
+ copy "${{ env.Qt_ROOT_DIR }}/plugins/imageformats/qsvg.dll" upload/qBittorrent/plugins/imageformats
mkdir upload/qBittorrent/plugins/platforms
- copy "${{ env.Qt6_DIR }}/plugins/platforms/qwindows.dll" upload/qBittorrent/plugins/platforms
+ copy "${{ env.Qt_ROOT_DIR }}/plugins/platforms/qwindows.dll" upload/qBittorrent/plugins/platforms
mkdir upload/qBittorrent/plugins/sqldrivers
- copy "${{ env.Qt6_DIR }}/plugins/sqldrivers/qsqlite.dll" upload/qBittorrent/plugins/sqldrivers
+ copy "${{ env.Qt_ROOT_DIR }}/plugins/sqldrivers/qsqlite.dll" upload/qBittorrent/plugins/sqldrivers
mkdir upload/qBittorrent/plugins/styles
- copy "${{ env.Qt6_DIR }}/plugins/styles/qmodernwindowsstyle.dll" upload/qBittorrent/plugins/styles
+ copy "${{ env.Qt_ROOT_DIR }}/plugins/styles/qmodernwindowsstyle.dll" upload/qBittorrent/plugins/styles
mkdir upload/qBittorrent/plugins/tls
- copy "${{ env.Qt6_DIR }}/plugins/tls/qschannelbackend.dll" upload/qBittorrent/plugins/tls
+ copy "${{ env.Qt_ROOT_DIR }}/plugins/tls/qschannelbackend.dll" upload/qBittorrent/plugins/tls
# cmake additionals
mkdir upload/cmake
copy build/compile_commands.json upload/cmake
diff --git a/.github/workflows/coverity-scan.yaml b/.github/workflows/coverity-scan.yaml
index cf3c3dc3b..fa66c6cb3 100644
--- a/.github/workflows/coverity-scan.yaml
+++ b/.github/workflows/coverity-scan.yaml
@@ -52,7 +52,7 @@ jobs:
mv "${{ github.workspace }}/.."/boost_* "${{ env.boost_path }}"
- name: Install Qt
- uses: jurplel/install-qt-action@v3
+ uses: jurplel/install-qt-action@v4
with:
version: ${{ matrix.qt_version }}
archives: icu qtbase qtdeclarative qtsvg qttools
diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
index 816654ef8..504c83ada 100644
--- a/.pre-commit-config.yaml
+++ b/.pre-commit-config.yaml
@@ -78,11 +78,7 @@ repos:
m4/.* |
src/base/3rdparty/.* |
src/searchengine/nova3/socks.py |
- src/webui/www/private/lang/.* |
- src/webui/www/private/scripts/lib/.* |
- src/webui/www/public/lang/.* |
- src/webui/www/public/scripts/lib/.* |
- src/webui/www/transifex/.*
+ src/webui/www/private/scripts/lib/.*
)$
exclude_types:
- ts
@@ -106,11 +102,7 @@ repos:
m4/.* |
src/base/3rdparty/.* |
src/searchengine/nova3/socks.py |
- src/webui/www/private/lang/.* |
- src/webui/www/private/scripts/lib/.* |
- src/webui/www/public/lang/.* |
- src/webui/www/public/scripts/lib/.* |
- src/webui/www/transifex/.*
+ src/webui/www/private/scripts/lib/.*
)$
exclude_types:
- svg
diff --git a/.tx/config b/.tx/config
index 593cf8675..d00bebb5d 100644
--- a/.tx/config
+++ b/.tx/config
@@ -1,7 +1,7 @@
[main]
host = https://www.transifex.com
-[o:sledgehammer999:p:qbittorrent:r:qbittorrent_master]
+[o:sledgehammer999:p:qbittorrent:r:qbittorrent_v50x]
file_filter = src/lang/qbittorrent_.ts
source_file = src/lang/qbittorrent_en.ts
source_lang = en
@@ -9,7 +9,7 @@ type = QT
minimum_perc = 23
lang_map = pt: pt_PT, zh: zh_CN
-[o:sledgehammer999:p:qbittorrent:r:qbittorrent_webui]
+[o:sledgehammer999:p:qbittorrent:r:qbittorrent_webui_v50x]
file_filter = src/webui/www/translations/webui_.ts
source_file = src/webui/www/translations/webui_en.ts
source_lang = en
@@ -17,14 +17,6 @@ type = QT
minimum_perc = 23
lang_map = pt: pt_PT, zh: zh_CN
-[o:sledgehammer999:p:qbittorrent:r:qbittorrent_webui_json]
-file_filter = src/webui/www/transifex/.json
-source_file = src/webui/www/transifex/en.json
-source_lang = en
-type = KEYVALUEJSON
-minimum_perc = 23
-lang_map = pt: pt_PT, zh: zh_CN
-
[o:sledgehammer999:p:qbittorrent:r:qbittorrentdesktop_master]
source_file = dist/unix/org.qbittorrent.qBittorrent.desktop
source_lang = en
diff --git a/Changelog b/Changelog
index 8d702641d..92beb956d 100644
--- a/Changelog
+++ b/Changelog
@@ -1,4 +1,61 @@
-Unreleased - sledgehammer999 - v5.0.0
+Tue Feb 18th 2025 - sledgehammer999 - 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 - v5.0.3
+ - BUGFIX: Discard obsolete "state update" events after torrent is reloaded (glassez)
+ - BUGFIX: Fix incorrect SQL column definition (glassez)
+ - BUGFIX: Avoid redundant requests of announce entries from libtorrent (glassez)
+ - WEBUI: Fix removing tracker URL with '|' character (Thomas Piccirello)
+ - WEBUI: Fix reloading page after login (Evgenii Ryshkov)
+ - WEBAPI: Fix incorrect key in torrent creator (Bartu Özen)
+ - RSS: Don't add duplicate episodes to previously matched (wavygecko)
+ - RSS: Use cached current time when parsing RSS feed (glassez)
+ - WINDOWS: Don't follow symlink when creating torrents on Windows (Chocobo1)
+ - WINDOWS: NSIS: Update Italian translation (Giacomo411)
+
+Sun Nov 17th 2024 - sledgehammer999 - v5.0.2
+ - BUGFIX: Remove trackers from previous category when moved to new one (glassez)
+ - BUGFIX: Fix `.torrent` file could not be deleted when torrent is canceled (glassez)
+ - BUGFIX: Reset tracker entries when pausing the session (glassez)
+ - BUGFIX: Check real palette darkness to detect "dark theme" (glassez)
+ - BUGFIX: Correctly handle "torrent finished" events (glassez)
+ - BUGFIX: Preserve initial torrent progress while checking resume data (glassez)
+ - BUGFIX: Avoid reapplying Mark-of-the-Web when it already exists (Chocobo1)
+ - BUGFIX: Don't apply Mark-of-the-Web on existing files (Chocobo1)
+ - WEBUI: Add color scheme switcher (sledgehammer999)
+ - SEARCH: Correctly delete the moved search tab (glassez)
+ - WINDOWS: Correctly save and restore Qt style setting (glassez)
+ - WINDOWS: NSIS: update Luxembourgish, Simplified Chinese and Traditional Chinese translations (Ikko Eltociear Ashimine, 3gf8jv4dv)
+
+Mon Oct 28th 2024 - sledgehammer999 - v5.0.1
+ - FEATURE: Add "Simple pread/pwrite" disk IO type (Hanabishi)
+ - BUGFIX: Don't ignore SSL errors (sledgehammer999)
+ - BUGFIX: Don't try to apply Mark-of-the-Web to nonexistent files (glassez)
+ - BUGFIX: Disable "Move to trash" option by default (glassez)
+ - BUGFIX: Disable the ability to create torrents with a piece size of 256MiB (stalkerok)
+ - BUGFIX: Allow to choose Qt style (glassez)
+ - BUGFIX: Always notify user about duplicate torrent (glassez)
+ - BUGFIX: Correctly handle "torrent finished after move" event (glassez)
+ - BUGFIX: Correctly apply filename filter when `!qB` extension is enabled (glassez)
+ - BUGFIX: Improve color scheme change detection (glassez)
+ - BUGFIX: Fix button state for SSL certificate check (Chocobo1)
+ - WEBUI: Fix CSS that results in hidden torrent list in some browsers (skomerko)
+ - WEBUI: Use proper text color to highlight items in all filter lists (skomerko)
+ - WEBUI: Fix 'rename files' dialog cannot be opened more than once (Chocobo1)
+ - WEBUI: Fix UI of Advanced Settings to show all settings (glassez)
+ - WEBUI: Free resources allocated by web session once it is destructed (dyseg)
+ - SEARCH: Import correct libraries (Chocobo1)
+ - OTHER: Sync flag icons with upstream (xavier2k6)
+
+Sun Sep 29th 2024 - sledgehammer999 - v5.0.0
- FEATURE: Support creating .torrent with larger piece size (Chocobo1)
- FEATURE: Improve tracker entries handling (glassez)
- FEATURE: Add separate filter item for tracker errors (glassez)
@@ -12,14 +69,30 @@ Unreleased - sledgehammer999 - v5.0.0
- FEATURE: Enable Ctrl+F hotkey for more inputs (thalieht)
- FEATURE: Add seeding limits to RSS and Watched folders options UI (glassez)
- FEATURE: Subcategories implicitly follow the parent category options (glassez)
- - FEATURE: Add support for SSL torrents (Chocobo1, Radu Carpa)
- FEATURE: Add option to name each qbittorrent instance (Chocobo1)
- FEATURE: Add button for sending test email (Thomas Piccirello)
- FEATURE: Allow torrents to override default share limit action (glassez)
+ - FEATURE: Use Start/Stop instead of Resume/Pause (thalieht)
+ - FEATURE: Add the Popularity metric (Aliaksei Urbanski)
+ - FEATURE: Focus on Download button if torrent link retrieved from the clipboard (glassez)
+ - FEATURE: Add ability to pause/resume entire BitTorrent session (glassez)
+ - FEATURE: Add an option to set BitTorrent session shutdown timeout (glassez)
+ - FEATURE: Apply "Excluded file names" to folder names as well (glassez)
+ - FEATURE: Allow to use regular expression to filter torrent content (glassez)
+ - FEATURE: Allow to move content files to Trash instead of deleting them (glassez)
+ - FEATURE: Add ability to display torrent "privateness" in UI (ManiMatter)
+ - FEATURE: Add a flag in `Peers` tab denoting a connection using NAT hole punching (stalkerok)
- BUGFIX: Display error message when unrecoverable error occurred (glassez)
- BUGFIX: Update size of selected files when selection is changed (glassez)
- BUGFIX: Normalize tags by trimming leading/trailing whitespace (glassez)
- BUGFIX: Correctly handle share limits in torrent options dialog (glassez)
+ - BUGFIX: Adjust tracker tier when adding additional trackers (Chocobo1)
+ - BUGFIX: Fix inconsistent naming between `Done/Progress` column (luzpaz)
+ - BUGFIX: Sanitize peer client names (Hanabishi)
+ - BUGFIX: Apply share limits immediately when torrent downloading is finished (glassez)
+ - BUGFIX: Show download progress for folders with zero byte size as 100 instead of 0 (vikas_c)
+ - BUGFIX: Fix highlighted piece color (Prince Gupta)
+ - BUGFIX: Apply "merge trackers" logic regardless of way the torrent is added (glassez)
- WEBUI: Improve WebUI responsiveness (Chocobo1)
- WEBUI: Do not exit the app when WebUI has failed to start (Hanabishi)
- WEBUI: Add `Moving` filter to side panel (xavier2k6)
@@ -28,14 +101,37 @@ Unreleased - sledgehammer999 - v5.0.0
- WEBUI: Leave the fields empty when value is invalid (Chocobo1)
- WEBUI: Use natural sorting (Chocobo1)
- WEBUI: Improve WebUI login behavior (JayRet)
+ - WEBUI: Conditionally show filters sidebar (Thomas Piccirello)
+ - WEBUI: Add support for running concurrent searches (Thomas Piccirello)
+ - WEBUI: Improve accuracy of trackers list (Thomas Piccirello)
+ - WEBUI: Fix error when category doesn't exist (Thomas Piccirello)
+ - WEBUI: Improve table scrolling and selection on mobile (Thomas Piccirello)
+ - WEBUI: Restore search tabs on load (Thomas Piccirello)
+ - WEBUI: Restore previously used tab on load (Thomas Piccirello)
+ - WEBUI: Increase default height of `Share ratio limit` dialog (thalieht)
+ - WEBUI: Use enabled search plugins by default (Thomas Piccirello)
+ - WEBUI: Add columns `Incomplete Save Path`, `Info Hash v1`, `Info Hash v2` (thalieht)
+ - WEBUI: Always create generic filter items (skomerko)
+ - WEBUI: Provide `Use Category paths in Manual Mode` option (skomerko)
+ - WEBUI: Provide `Merge trackers to existing torrent` option (skomerko)
- WEBAPI: Fix wrong timestamp values (Chocobo1)
- WEBAPI: Send binary data with filename and mime type specified (glassez)
- WEBAPI: Expose API for the torrent creator (glassez, Radu Carpa)
+ - WEBAPI: Add support for SSL torrents (Chocobo1, Radu Carpa)
+ - WEBAPI: Provide endpoint for listing directory content (Paweł Kotiuk)
+ - WEBAPI: Provide "private" flag via "torrents/info" endpoint (ManiMatter)
+ - WEBAPI: Add a way to download .torrent file using search plugin (glassez)
+ - WEBAPI: Add "private" filter for "torrents/info" endpoint (ManiMatter)
+ - WEBAPI: Add root_path to "torrents/info" result (David Newhall)
- RSS: Show RSS feed title in HTML browser (Jay)
- RSS: Allow to set delay between requests to the same host (jNullj)
- SEARCH: Allow users to specify Python executable path (Chocobo1)
+ - SEARCH: Lazy load search plugins (milahu)
+ - SEARCH: Add date column to the built-in search engine (ducalex)
+ - SEARCH: Allow to rearrange search tabs (glassez)
- WINDOWS: Use Fusion style on Windows 10+. It has better compatibility with dark mode (glassez)
- WINDOWS: Allow to set qBittorrent as default program (glassez)
+ - WINDOWS: Don't access "Favorites" folder unexpectedly (glassez)
- LINUX: Add support for systemd power management (Chocobo1)
- LINUX: Add support for localized man pages (Victor Chernyakin)
- LINUX: Specify a locale if none is set (Chocobo1)
diff --git a/dist/mac/Info.plist b/dist/mac/Info.plist
index 50f6ccbd4..e3acd941a 100644
--- a/dist/mac/Info.plist
+++ b/dist/mac/Info.plist
@@ -55,7 +55,7 @@
CFBundlePackageType
APPL
CFBundleShortVersionString
- 5.0.0
+ 5.0.4
CFBundleExecutable
${EXECUTABLE_NAME}
CFBundleIdentifier
@@ -67,7 +67,7 @@
NSAppleScriptEnabled
YES
NSHumanReadableCopyright
- Copyright © 2006-2024 The qBittorrent project
+ Copyright © 2006-2025 The qBittorrent project
UTExportedTypeDeclarations
diff --git a/dist/unix/org.qbittorrent.qBittorrent.desktop b/dist/unix/org.qbittorrent.qBittorrent.desktop
index cb9e814cb..2cd055a1a 100644
--- a/dist/unix/org.qbittorrent.qBittorrent.desktop
+++ b/dist/unix/org.qbittorrent.qBittorrent.desktop
@@ -14,216 +14,220 @@ Keywords=bittorrent;torrent;magnet;download;p2p;
SingleMainWindow=true
# Translations
-Comment[af]=Aflaai en deel lêers oor BitTorrent
GenericName[af]=BitTorrent kliënt
+Comment[af]=Aflaai en deel lêers oor BitTorrent
Name[af]=qBittorrent
-Comment[ar]=نزّل وشارك الملفات عبر كيوبتتورنت
GenericName[ar]=عميل بتتورنت
+Comment[ar]=نزّل وشارك الملفات عبر كيوبتتورنت
Name[ar]=qBittorrent
-Comment[be]=Спампоўванне і раздача файлаў праз пратакол BitTorrent
GenericName[be]=Кліент BitTorrent
+Comment[be]=Спампоўванне і раздача файлаў праз пратакол BitTorrent
Name[be]=qBittorrent
-Comment[bg]=Сваляне и споделяне на файлове чрез BitTorrent
GenericName[bg]=BitTorrent клиент
+Comment[bg]=Сваляне и споделяне на файлове чрез BitTorrent
Name[bg]=qBittorrent
-Comment[bn]=বিটটরেন্টে ফাইল ডাউনলোড এবং শেয়ার করুন
GenericName[bn]=বিটটরেন্ট ক্লায়েন্ট
+Comment[bn]=বিটটরেন্টে ফাইল ডাউনলোড এবং শেয়ার করুন
Name[bn]=qBittorrent
-Comment[zh]=通过 BitTorrent 下载和分享文件
GenericName[zh]=BitTorrent 客户端
+Comment[zh]=通过 BitTorrent 下载和分享文件
Name[zh]=qBittorrent
-Comment[bs]=Preuzmi i dijeli datoteke preko BitTorrent-a
GenericName[bs]=BitTorrent klijent
+Comment[bs]=Preuzmi i dijeli datoteke preko BitTorrent-a
Name[bs]=qBittorrent
-Comment[ca]=Baixeu i compartiu fitxers amb el BitTorrent
GenericName[ca]=Client de BitTorrent
+Comment[ca]=Baixeu i compartiu fitxers amb el BitTorrent
Name[ca]=qBittorrent
-Comment[cs]=Stahování a sdílení souborů přes síť BitTorrent
GenericName[cs]=BitTorrent klient
+Comment[cs]=Stahování a sdílení souborů přes síť BitTorrent
Name[cs]=qBittorrent
-Comment[da]=Download og del filer over BitTorrent
GenericName[da]=BitTorrent-klient
+Comment[da]=Download og del filer over BitTorrent
Name[da]=qBittorrent
-Comment[de]=Über BitTorrent Dateien herunterladen und teilen
GenericName[de]=BitTorrent Client
+Comment[de]=Über BitTorrent Dateien herunterladen und teilen
Name[de]=qBittorrent
-Comment[el]=Κάντε λήψη και μοιραστείτε αρχεία μέσω BitTorrent
GenericName[el]=BitTorrent client
+Comment[el]=Κάντε λήψη και μοιραστείτε αρχεία μέσω BitTorrent
Name[el]=qBittorrent
-Comment[en_GB]=Download and share files over BitTorrent
GenericName[en_GB]=BitTorrent client
+Comment[en_GB]=Download and share files over BitTorrent
Name[en_GB]=qBittorrent
-Comment[es]=Descargue y comparta archivos por BitTorrent
GenericName[es]=Cliente BitTorrent
+Comment[es]=Descargue y comparta archivos por BitTorrent
Name[es]=qBittorrent
-Comment[et]=Lae alla ja jaga faile üle BitTorrenti
GenericName[et]=BitTorrent klient
+Comment[et]=Lae alla ja jaga faile üle BitTorrenti
Name[et]=qBittorrent
-Comment[eu]=Jeitsi eta elkarbanatu agiriak BitTorrent bidez
GenericName[eu]=BitTorrent bezeroa
+Comment[eu]=Jeitsi eta elkarbanatu agiriak BitTorrent bidez
Name[eu]=qBittorrent
-Comment[fa]=دانلود و به اشتراک گذاری فایل های بوسیله بیت تورنت
GenericName[fa]=بیت تورنت نسخه کلاینت
+Comment[fa]=دانلود و به اشتراک گذاری فایل های بوسیله بیت تورنت
Name[fa]=qBittorrent
-Comment[fi]=Lataa ja jaa tiedostoja BitTorrentia käyttäen
GenericName[fi]=BitTorrent-asiakasohjelma
+Comment[fi]=Lataa ja jaa tiedostoja BitTorrentia käyttäen
Name[fi]=qBittorrent
-Comment[fr]=Télécharger et partager des fichiers sur BitTorrent
GenericName[fr]=Client BitTorrent
+Comment[fr]=Télécharger et partager des fichiers sur BitTorrent
Name[fr]=qBittorrent
-Comment[gl]=Descargar e compartir ficheiros co protocolo BitTorrent
GenericName[gl]=Cliente BitTorrent
+Comment[gl]=Descargar e compartir ficheiros co protocolo BitTorrent
Name[gl]=qBittorrent
-Comment[gu]=બિટ્ટોરેંટ પર ફાઈલો ડાઉનલોડ અને શેર કરો
GenericName[gu]=બિટ્ટોરેંટ ક્લાયન્ટ
+Comment[gu]=બિટ્ટોરેંટ પર ફાઈલો ડાઉનલોડ અને શેર કરો
Name[gu]=qBittorrent
-Comment[he]=הורד ושתף קבצים על גבי ביטורנט
GenericName[he]=לקוח ביטורנט
+Comment[he]=הורד ושתף קבצים על גבי ביטורנט
Name[he]=qBittorrent
-Comment[hr]=Preuzmite i dijelite datoteke putem BitTorrenta
GenericName[hr]=BitTorrent klijent
+Comment[hr]=Preuzmite i dijelite datoteke putem BitTorrenta
Name[hr]=qBittorrent
-Comment[hu]=Fájlok letöltése és megosztása a BitTorrent hálózaton keresztül
GenericName[hu]=BitTorrent kliens
+Comment[hu]=Fájlok letöltése és megosztása a BitTorrent hálózaton keresztül
Name[hu]=qBittorrent
-Comment[hy]=Նիշքերի փոխանցում BitTorrent-ի միջոցով
GenericName[hy]=BitTorrent սպասառու
+Comment[hy]=Նիշքերի փոխանցում BitTorrent-ի միջոցով
Name[hy]=qBittorrent
-Comment[id]=Unduh dan berbagi berkas melalui BitTorrent
GenericName[id]=Klien BitTorrent
+Comment[id]=Unduh dan berbagi berkas melalui BitTorrent
Name[id]=qBittorrent
-Comment[is]=Sækja og deila skrám yfir BitTorrent
GenericName[is]=BitTorrent biðlarar
+Comment[is]=Sækja og deila skrám yfir BitTorrent
Name[is]=qBittorrent
-Comment[it]=Scarica e condividi file tramite BitTorrent
GenericName[it]=Client BitTorrent
+Comment[it]=Scarica e condividi file tramite BitTorrent
Name[it]=qBittorrent
-Comment[ja]=BitTorrentでファイルのダウンロードと共有
GenericName[ja]=BitTorrentクライアント
+Comment[ja]=BitTorrentでファイルのダウンロードと共有
Name[ja]=qBittorrent
-Comment[ka]=გადმოტვირთეთ და გააზიარეთ ფაილები BitTorrent-ის საშუალებით
GenericName[ka]=BitTorrent კლიენტი
+Comment[ka]=გადმოტვირთეთ და გააზიარეთ ფაილები BitTorrent-ის საშუალებით
Name[ka]=qBittorrent
-Comment[ko]=BitTorrent를 통한 파일 내려받기 및 공유
GenericName[ko]=BitTorrent 클라이언트
+Comment[ko]=BitTorrent를 통한 파일 다운로드 및 공유
Name[ko]=qBittorrent
-Comment[lt]=Atsisiųskite bei dalinkitės failais BitTorrent tinkle
GenericName[lt]=BitTorrent klientas
+Comment[lt]=Atsisiųskite bei dalinkitės failais BitTorrent tinkle
Name[lt]=qBittorrent
-Comment[mk]=Превземајте и споделувајте фајлови преку BitTorrent
GenericName[mk]=BitTorrent клиент
+Comment[mk]=Превземајте и споделувајте фајлови преку BitTorrent
Name[mk]=qBittorrent
-Comment[my]=တောရန့်ဖြင့်ဖိုင်များဒေါင်းလုဒ်ဆွဲရန်နှင့်မျှဝေရန်
GenericName[my]=တောရန့်စီမံခန့်ခွဲသည့်အရာ
+Comment[my]=တောရန့်ဖြင့်ဖိုင်များဒေါင်းလုဒ်ဆွဲရန်နှင့်မျှဝေရန်
Name[my]=qBittorrent
-Comment[nb]=Last ned og del filer over BitTorrent
GenericName[nb]=BitTorrent-klient
+Comment[nb]=Last ned og del filer over BitTorrent
Name[nb]=qBittorrent
-Comment[nl]=Bestanden downloaden en delen via BitTorrent
GenericName[nl]=BitTorrent-client
+Comment[nl]=Bestanden downloaden en delen via BitTorrent
Name[nl]=qBittorrent
-Comment[pl]=Pobieraj i dziel się plikami przez BitTorrent
GenericName[pl]=Klient BitTorrent
+Comment[pl]=Pobieraj i dziel się plikami przez BitTorrent
Name[pl]=qBittorrent
-Comment[pt]=Transferir e partilhar ficheiros por BitTorrent
GenericName[pt]=Cliente BitTorrent
+Comment[pt]=Transferir e partilhar ficheiros por BitTorrent
Name[pt]=qBittorrent
-Comment[pt_BR]=Baixe e compartilhe arquivos pelo BitTorrent
GenericName[pt_BR]=Cliente BitTorrent
+Comment[pt_BR]=Baixe e compartilhe arquivos pelo BitTorrent
Name[pt_BR]=qBittorrent
-Comment[ro]=Descărcați și partajați fișiere prin BitTorrent
GenericName[ro]=Client BitTorrent
+Comment[ro]=Descărcați și partajați fișiere prin BitTorrent
Name[ro]=qBittorrent
-Comment[ru]=Обмен файлами по сети БитТоррент
GenericName[ru]=Клиент сети БитТоррент
+Comment[ru]=Обмен файлами по сети БитТоррент
Name[ru]=qBittorrent
-Comment[sk]=Sťahovanie a zdieľanie súborov prostredníctvom siete BitTorrent
GenericName[sk]=Klient siete BitTorrent
+Comment[sk]=Sťahovanie a zdieľanie súborov prostredníctvom siete BitTorrent
Name[sk]=qBittorrent
-Comment[sl]=Prenesite in delite datoteke preko BitTorrenta
GenericName[sl]=BitTorrent odjemalec
+Comment[sl]=Prenesite in delite datoteke preko BitTorrenta
Name[sl]=qBittorrent
+GenericName[sq]=Klienti BitTorrent
+Comment[sq]=Shkarko dhe shpërndaj skedarë në BitTorrent
Name[sq]=qBittorrent
-Comment[sr]=Преузимајте и делите фајлове преко BitTorrent протокола
-GenericName[sr]=BitTorrent-клијент
+GenericName[sr]=BitTorrent клијент
+Comment[sr]=Преузимајте и делите фајлове преко BitTorrent-а
Name[sr]=qBittorrent
-Comment[sr@latin]=Preuzimanje i deljenje fajlova preko BitTorrent-a
GenericName[sr@latin]=BitTorrent klijent
+Comment[sr@latin]=Preuzimanje i deljenje fajlova preko BitTorrent-a
Name[sr@latin]=qBittorrent
-Comment[sv]=Hämta och dela filer över BitTorrent
GenericName[sv]=BitTorrent-klient
+Comment[sv]=Hämta och dela filer över BitTorrent
Name[sv]=qBittorrent
-Comment[ta]=BitTorrent வழியாக கோப்புகளை பதிவிறக்க மற்றும் பகிர
GenericName[ta]=BitTorrent வாடிக்கையாளர்
+Comment[ta]=BitTorrent வழியாக கோப்புகளை பதிவிறக்க மற்றும் பகிர
Name[ta]=qBittorrent
-Comment[te]=క్యు బిట్ టొరెంట్ తో ఫైల్స్ దిగుమతి చేసుకోండి , పంచుకోండి
GenericName[te]=క్యు బిట్ టొరెంట్ క్లయింట్
+Comment[te]=క్యు బిట్ టొరెంట్ తో ఫైల్స్ దిగుమతి చేసుకోండి , పంచుకోండి
Name[te]=qBittorrent
-Comment[th]=ดาวน์โหลดและแชร์ไฟล์ผ่าน BitTorrent
-GenericName[th]=โปรแกรมบิททอเร้นท์
+GenericName[th]=ไคลเอนต์บิททอร์เรนต์
+Comment[th]=ดาวน์โหลดและแชร์ไฟล์ผ่านบิตทอร์เรนต์
Name[th]=qBittorrent
-Comment[tr]=Dosyaları BitTorrent üzerinden indirin ve paylaşın
GenericName[tr]=BitTorrent istemcisi
+Comment[tr]=Dosyaları BitTorrent üzerinden indirin ve paylaşın
Name[tr]=qBittorrent
-Comment[ur]=BitTorrent پر فائلوں کو ڈاؤن لوڈ کریں اور اشتراک کریں
GenericName[ur]=قیو بٹ ٹورنٹ کلائنٹ
+Comment[ur]=BitTorrent پر فائلوں کو ڈاؤن لوڈ کریں اور اشتراک کریں
Name[ur]=qBittorrent
-Comment[uk]=Завантажуйте та поширюйте файли через BitTorrent
GenericName[uk]=BitTorrent-клієнт
+Comment[uk]=Завантажуйте та поширюйте файли через BitTorrent
Name[uk]=qBittorrent
-Comment[vi]=Tải xuống và chia sẻ tệp qua BitTorrent
GenericName[vi]=Máy khách BitTorrent
+Comment[vi]=Tải xuống và chia sẻ tệp qua BitTorrent
Name[vi]=qBittorrent
-Comment[zh_HK]=經由BitTorrent下載並分享檔案
GenericName[zh_HK]=BitTorrent用戶端
+Comment[zh_HK]=經由BitTorrent下載並分享檔案
Name[zh_HK]=qBittorrent
-Comment[zh_TW]=經由 BitTorrent 下載並分享檔案
GenericName[zh_TW]=BitTorrent 用戶端
+Comment[zh_TW]=使用 BitTorrent 下載並分享檔案
Name[zh_TW]=qBittorrent
-Comment[eo]=Elŝutu kaj kunhavigu dosierojn per BitTorrent
GenericName[eo]=BitTorrent-kliento
+Comment[eo]=Elŝutu kaj kunhavigu dosierojn per BitTorrent
Name[eo]=qBittorrent
-Comment[kk]=BitTorrent арқылы файл жүктеу және бөлісу
GenericName[kk]=BitTorrent клиенті
+Comment[kk]=BitTorrent арқылы файл жүктеу және бөлісу
Name[kk]=qBittorrent
-Comment[en_AU]=Download and share files over BitTorrent
GenericName[en_AU]=BitTorrent client
+Comment[en_AU]=Download and share files over BitTorrent
Name[en_AU]=qBittorrent
Name[rm]=qBittorrent
Name[jv]=qBittorrent
-Comment[oc]=Telecargar e partejar de fichièrs amb BitTorrent
GenericName[oc]=Client BitTorrent
+Comment[oc]=Telecargar e partejar de fichièrs amb BitTorrent
Name[oc]=qBittorrent
Name[ug]=qBittorrent
Name[yi]=qBittorrent
-Comment[nqo]=ߞߐߕߐ߯ߘߐ ߟߎ߬ ߟߊߖߌ߰ ߞߊ߬ ߓߊ߲߫ ߞߵߊ߬ߟߎ߬ ߘߐߕߟߊ߫ ߓߌߙߏߙߍ߲ߕ ߞߊ߲߬
GenericName[nqo]=ߓߌߙߏߙߍ߲ߕ ߕߣߐ߬ߓߐ߬ߟߊ
+Comment[nqo]=ߞߐߕߐ߯ߘߐ ߟߎ߬ ߟߊߖߌ߰ ߞߊ߬ ߓߊ߲߫ ߞߵߊ߬ߟߎ߬ ߘߐߕߟߊ߫ ߓߌߙߏߙߍ߲ߕ ߞߊ߲߬
Name[nqo]=qBittorrent
-Comment[uz@Latn]=BitTorrent orqali fayllarni yuklab olish va baham ko‘rish
GenericName[uz@Latn]=BitTorrent mijozi
+Comment[uz@Latn]=BitTorrent orqali fayllarni yuklab olish va baham ko‘rish
Name[uz@Latn]=qBittorrent
-Comment[ltg]=Atsasyuteit i daleit failus ar BitTorrent
GenericName[ltg]=BitTorrent klients
+Comment[ltg]=Atsasyuteit i daleit failus ar BitTorrent
Name[ltg]=qBittorrent
-Comment[hi_IN]=BitTorrent द्वारा फाइल डाउनलोड व सहभाजन
GenericName[hi_IN]=Bittorrent साधन
+Comment[hi_IN]=BitTorrent द्वारा फाइल डाउनलोड व सहभाजन
Name[hi_IN]=qBittorrent
-Comment[az@latin]=Faylları BitTorrent vasitəsilə endirin və paylaşın
GenericName[az@latin]=BitTorrent client
+Comment[az@latin]=Faylları BitTorrent vasitəsilə endirin və paylaşın
Name[az@latin]=qBittorrent
-Comment[lv_LV]=Lejupielādēt un koplietot failus ar BitTorrent
GenericName[lv_LV]=BitTorrent klients
+Comment[lv_LV]=Lejupielādēt un koplietot failus ar BitTorrent
Name[lv_LV]=qBittorrent
-Comment[ms_MY]=Muat turun dan kongsi fail melalui BitTorrent
GenericName[ms_MY]=Klien BitTorrent
+Comment[ms_MY]=Muat turun dan kongsi fail melalui BitTorrent
Name[ms_MY]=qBittorrent
-Comment[mn_MN]=BitTorrent-оор файлуудаа тат, түгээ
GenericName[mn_MN]=BitTorrent татагч
+Comment[mn_MN]=BitTorrent-оор файлуудаа тат, түгээ
Name[mn_MN]=qBittorrent
-Comment[ne_NP]=फाइलहरू डाउनलोड गर्नुहोस् र BitTorrent मा साझा गर्नुहोस्
GenericName[ne_NP]=BitTorrent क्लाइन्ट
+Comment[ne_NP]=फाइलहरू डाउनलोड गर्नुहोस् र BitTorrent मा साझा गर्नुहोस्
Name[ne_NP]=qBittorrent
-Comment[pt_PT]=Transferir e partilhar ficheiros por BitTorrent
GenericName[pt_PT]=Cliente BitTorrent
+Comment[pt_PT]=Transferir e partilhar ficheiros por BitTorrent
Name[pt_PT]=qBittorrent
+GenericName[si_LK]=BitTorrent සේවාදායකයා
+Comment[si_LK]=BitTorrent හරහා ගොනු බාගත කර බෙදාගන්න.
Name[si_LK]=qBittorrent
diff --git a/dist/unix/org.qbittorrent.qBittorrent.metainfo.xml b/dist/unix/org.qbittorrent.qBittorrent.metainfo.xml
index 6a840a610..c7808bdb9 100644
--- a/dist/unix/org.qbittorrent.qBittorrent.metainfo.xml
+++ b/dist/unix/org.qbittorrent.qBittorrent.metainfo.xml
@@ -62,6 +62,6 @@
https://github.com/qbittorrent/qBittorrent/blob/master/CONTRIBUTING.md
-
+
diff --git a/dist/windows/config.nsh b/dist/windows/config.nsh
index 658262782..8da1f0f79 100644
--- a/dist/windows/config.nsh
+++ b/dist/windows/config.nsh
@@ -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.0"
+!define /ifndef QBT_VERSION "5.0.4"
; 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}"
diff --git a/dist/windows/installer-translations/italian.nsh b/dist/windows/installer-translations/italian.nsh
index a63024b01..2668dc5ca 100644
--- a/dist/windows/installer-translations/italian.nsh
+++ b/dist/windows/installer-translations/italian.nsh
@@ -29,7 +29,7 @@ LangString launch_qbt ${LANG_ITALIAN} "Esegui qBittorrent."
;LangString inst_requires_64bit ${LANG_ENGLISH} "This installer works only in 64-bit Windows versions."
LangString inst_requires_64bit ${LANG_ITALIAN} "Questo installer funziona solo con versioni di Windows a 64bit."
;LangString inst_requires_win10 ${LANG_ENGLISH} "This installer requires at least Windows 10 (1809) / Windows Server 2019."
-LangString inst_requires_win10 ${LANG_ITALIAN} "This installer requires at least Windows 10 (1809) / Windows Server 2019."
+LangString inst_requires_win10 ${LANG_ITALIAN} "Questo installer richiede almeno Windows 10 (1809) / Windows Server 2019."
;LangString inst_uninstall_link_description ${LANG_ENGLISH} "Uninstall qBittorrent"
LangString inst_uninstall_link_description ${LANG_ITALIAN} "Disinstalla qBittorrent"
diff --git a/dist/windows/installer-translations/luxembourgish.nsh b/dist/windows/installer-translations/luxembourgish.nsh
index b866e3c93..4a30e954a 100644
--- a/dist/windows/installer-translations/luxembourgish.nsh
+++ b/dist/windows/installer-translations/luxembourgish.nsh
@@ -15,7 +15,7 @@ LangString inst_magnet ${LANG_LUXEMBOURGISH} "Magnet-Linken mat qBittorrent opma
;LangString inst_firewall ${LANG_ENGLISH} "Add Windows Firewall rule"
LangString inst_firewall ${LANG_LUXEMBOURGISH} "Reegel an der Windows Firewall dobäisetzen"
;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_LUXEMBOURGISH} "D'Windows path lenght (Padlängtbeschränkung) desaktivéieren (260 Zeechen MAX_PATH Beschränkung, erfuerdert min. Windows 10 1607)"
+LangString inst_pathlimit ${LANG_LUXEMBOURGISH} "D'Windows path length (Padlängtbeschränkung) desaktivéieren (260 Zeechen MAX_PATH Beschränkung, erfuerdert min. Windows 10 1607)"
;LangString inst_firewallinfo ${LANG_ENGLISH} "Adding Windows Firewall rule"
LangString inst_firewallinfo ${LANG_LUXEMBOURGISH} "Reegel an der Windows Firewall dobäisetzen"
;LangString inst_warning ${LANG_ENGLISH} "qBittorrent is running. Please close the application before installing."
diff --git a/dist/windows/installer-translations/portuguese.nsh b/dist/windows/installer-translations/portuguese.nsh
index b067b00da..c149119f4 100644
--- a/dist/windows/installer-translations/portuguese.nsh
+++ b/dist/windows/installer-translations/portuguese.nsh
@@ -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"
diff --git a/dist/windows/installer-translations/simpchinese.nsh b/dist/windows/installer-translations/simpchinese.nsh
index 42744b0d0..f0256e046 100644
--- a/dist/windows/installer-translations/simpchinese.nsh
+++ b/dist/windows/installer-translations/simpchinese.nsh
@@ -23,13 +23,13 @@ LangString inst_warning ${LANG_SIMPCHINESE} "qBittorrent 正在运行。 安装
;LangString inst_uninstall_question ${LANG_ENGLISH} "Current version will be uninstalled. User settings and torrents will remain intact."
LangString inst_uninstall_question ${LANG_SIMPCHINESE} "当前版本会被卸载。 用户设置和种子会被完整保留。"
;LangString inst_unist ${LANG_ENGLISH} "Uninstalling previous version."
-LangString inst_unist ${LANG_SIMPCHINESE} "卸载以前的版本。"
+LangString inst_unist ${LANG_SIMPCHINESE} "正在卸载以前的版本。"
;LangString launch_qbt ${LANG_ENGLISH} "Launch qBittorrent."
LangString launch_qbt ${LANG_SIMPCHINESE} "启动 qBittorrent。"
;LangString inst_requires_64bit ${LANG_ENGLISH} "This installer works only in 64-bit Windows versions."
LangString inst_requires_64bit ${LANG_SIMPCHINESE} "此安装程序仅支持 64 位 Windows 系统。"
;LangString inst_requires_win10 ${LANG_ENGLISH} "This installer requires at least Windows 10 (1809) / Windows Server 2019."
-LangString inst_requires_win10 ${LANG_SIMPCHINESE} "This installer requires at least Windows 10 (1809) / Windows Server 2019."
+LangString inst_requires_win10 ${LANG_SIMPCHINESE} "此安装程序仅支持 Windows 10 (1809) / Windows Server 2019 或更新的系统。"
;LangString inst_uninstall_link_description ${LANG_ENGLISH} "Uninstall qBittorrent"
LangString inst_uninstall_link_description ${LANG_SIMPCHINESE} "卸载 qBittorrent"
diff --git a/dist/windows/installer-translations/tradchinese.nsh b/dist/windows/installer-translations/tradchinese.nsh
index cfacc6d92..49bcff874 100644
--- a/dist/windows/installer-translations/tradchinese.nsh
+++ b/dist/windows/installer-translations/tradchinese.nsh
@@ -29,7 +29,7 @@ LangString launch_qbt ${LANG_TRADCHINESE} "啟動 qBittorrent"
;LangString inst_requires_64bit ${LANG_ENGLISH} "This installer works only in 64-bit Windows versions."
LangString inst_requires_64bit ${LANG_TRADCHINESE} "此安裝程式僅支援 64 位元版本的 Windows。"
;LangString inst_requires_win10 ${LANG_ENGLISH} "This installer requires at least Windows 10 (1809) / Windows Server 2019."
-LangString inst_requires_win10 ${LANG_TRADCHINESE} "This installer requires at least Windows 10 (1809) / Windows Server 2019."
+LangString inst_requires_win10 ${LANG_TRADCHINESE} "此安裝程式僅支援 Windows 10 (1809) / Windows Server 2019 以上的系統。"
;LangString inst_uninstall_link_description ${LANG_ENGLISH} "Uninstall qBittorrent"
LangString inst_uninstall_link_description ${LANG_TRADCHINESE} "移除 qBittorrent"
diff --git a/src/app/main.cpp b/src/app/main.cpp
index 53455f99b..d80629f44 100644
--- a/src/app/main.cpp
+++ b/src/app/main.cpp
@@ -1,6 +1,6 @@
/*
* Bittorrent Client using Qt and libtorrent.
- * Copyright (C) 2014-2023 Vladimir Golovnev
+ * Copyright (C) 2014-2024 Vladimir Golovnev
* Copyright (C) 2006 Christophe Dumez
*
* This program is free software; you can redistribute it and/or
@@ -58,10 +58,6 @@
#include
#include
-#ifdef Q_OS_WIN
-#include
-#endif
-
#ifdef QBT_STATIC_QT
#include
Q_IMPORT_PLUGIN(QICOPlugin)
@@ -189,11 +185,6 @@ int main(int argc, char *argv[])
// We must save it here because QApplication constructor may change it
const bool isOneArg = (argc == 2);
-#if !defined(DISABLE_GUI) && defined(Q_OS_WIN)
- if (QOperatingSystemVersion::current() >= QOperatingSystemVersion::Windows10)
- QApplication::setStyle(u"Fusion"_s);
-#endif
-
// `app` must be declared out of try block to allow display message box in case of exception
std::unique_ptr app;
try
diff --git a/src/base/CMakeLists.txt b/src/base/CMakeLists.txt
index d764871d7..38154e98a 100644
--- a/src/base/CMakeLists.txt
+++ b/src/base/CMakeLists.txt
@@ -38,6 +38,8 @@ add_library(qbt_base STATIC
bittorrent/torrent.h
bittorrent/torrentcontenthandler.h
bittorrent/torrentcontentlayout.h
+ bittorrent/torrentcontentremoveoption.h
+ bittorrent/torrentcontentremover.h
bittorrent/torrentcreationmanager.h
bittorrent/torrentcreationtask.h
bittorrent/torrentcreator.h
@@ -145,6 +147,7 @@ add_library(qbt_base STATIC
bittorrent/sslparameters.cpp
bittorrent/torrent.cpp
bittorrent/torrentcontenthandler.cpp
+ bittorrent/torrentcontentremover.cpp
bittorrent/torrentcreationmanager.cpp
bittorrent/torrentcreationtask.cpp
bittorrent/torrentcreator.cpp
diff --git a/src/base/addtorrentmanager.cpp b/src/base/addtorrentmanager.cpp
index a094dbd85..ce446a72b 100644
--- a/src/base/addtorrentmanager.cpp
+++ b/src/base/addtorrentmanager.cpp
@@ -157,10 +157,36 @@ void AddTorrentManager::handleAddTorrentFailed(const QString &source, const QStr
emit addTorrentFailed(source, reason);
}
-void AddTorrentManager::handleDuplicateTorrent(const QString &source, BitTorrent::Torrent *torrent, const QString &message)
+void AddTorrentManager::handleDuplicateTorrent(const QString &source
+ , const BitTorrent::TorrentDescriptor &torrentDescr, BitTorrent::Torrent *existingTorrent)
{
+ const bool hasMetadata = torrentDescr.info().has_value();
+ if (hasMetadata)
+ {
+ // Trying to set metadata to existing torrent in case if it has none
+ existingTorrent->setMetadata(*torrentDescr.info());
+ }
+
+ const bool isPrivate = existingTorrent->isPrivate() || (hasMetadata && torrentDescr.info()->isPrivate());
+ QString message;
+ if (!btSession()->isMergeTrackersEnabled())
+ {
+ message = tr("Merging of trackers is disabled");
+ }
+ else if (isPrivate)
+ {
+ message = tr("Trackers cannot be merged because it is a private torrent");
+ }
+ else
+ {
+ // merge trackers and web seeds
+ existingTorrent->addTrackers(torrentDescr.trackers());
+ existingTorrent->addUrlSeeds(torrentDescr.urlSeeds());
+ message = tr("Trackers are merged from new source");
+ }
+
LogMsg(tr("Detected an attempt to add a duplicate torrent. Source: %1. Existing torrent: %2. Result: %3")
- .arg(source, torrent->name(), message));
+ .arg(source, existingTorrent->name(), message));
emit addTorrentFailed(source, message);
}
@@ -169,11 +195,9 @@ void AddTorrentManager::setTorrentFileGuard(const QString &source, std::shared_p
m_guardedTorrentFiles.emplace(source, std::move(torrentFileGuard));
}
-void AddTorrentManager::releaseTorrentFileGuard(const QString &source)
+std::shared_ptr AddTorrentManager::releaseTorrentFileGuard(const QString &source)
{
- auto torrentFileGuard = m_guardedTorrentFiles.take(source);
- if (torrentFileGuard)
- torrentFileGuard->setAutoRemove(false);
+ return m_guardedTorrentFiles.take(source);
}
bool AddTorrentManager::processTorrent(const QString &source, const BitTorrent::TorrentDescriptor &torrentDescr
@@ -184,32 +208,7 @@ bool AddTorrentManager::processTorrent(const QString &source, const BitTorrent::
if (BitTorrent::Torrent *torrent = btSession()->findTorrent(infoHash))
{
// a duplicate torrent is being added
-
- const bool hasMetadata = torrentDescr.info().has_value();
- if (hasMetadata)
- {
- // Trying to set metadata to existing torrent in case if it has none
- torrent->setMetadata(*torrentDescr.info());
- }
-
- if (!btSession()->isMergeTrackersEnabled())
- {
- handleDuplicateTorrent(source, torrent, tr("Merging of trackers is disabled"));
- return false;
- }
-
- const bool isPrivate = torrent->isPrivate() || (hasMetadata && torrentDescr.info()->isPrivate());
- if (isPrivate)
- {
- handleDuplicateTorrent(source, torrent, tr("Trackers cannot be merged because it is a private torrent"));
- return false;
- }
-
- // merge trackers and web seeds
- torrent->addTrackers(torrentDescr.trackers());
- torrent->addUrlSeeds(torrentDescr.urlSeeds());
-
- handleDuplicateTorrent(source, torrent, tr("Trackers are merged from new source"));
+ handleDuplicateTorrent(source, torrentDescr, torrent);
return false;
}
diff --git a/src/base/addtorrentmanager.h b/src/base/addtorrentmanager.h
index ef31ae4da..0e2fc6f49 100644
--- a/src/base/addtorrentmanager.h
+++ b/src/base/addtorrentmanager.h
@@ -72,9 +72,9 @@ protected:
bool addTorrentToSession(const QString &source, const BitTorrent::TorrentDescriptor &torrentDescr
, const BitTorrent::AddTorrentParams &addTorrentParams);
void handleAddTorrentFailed(const QString &source, const QString &reason);
- void handleDuplicateTorrent(const QString &source, BitTorrent::Torrent *torrent, const QString &message);
+ void handleDuplicateTorrent(const QString &source, const BitTorrent::TorrentDescriptor &torrentDescr, BitTorrent::Torrent *existingTorrent);
void setTorrentFileGuard(const QString &source, std::shared_ptr torrentFileGuard);
- void releaseTorrentFileGuard(const QString &source);
+ std::shared_ptr releaseTorrentFileGuard(const QString &source);
private:
void onDownloadFinished(const Net::DownloadResult &result);
diff --git a/src/base/bittorrent/bencoderesumedatastorage.cpp b/src/base/bittorrent/bencoderesumedatastorage.cpp
index 4107c5aa9..a34e5a34a 100644
--- a/src/base/bittorrent/bencoderesumedatastorage.cpp
+++ b/src/base/bittorrent/bencoderesumedatastorage.cpp
@@ -40,7 +40,6 @@
#include
#include
-#include "base/algorithm.h"
#include "base/exceptions.h"
#include "base/global.h"
#include "base/logger.h"
diff --git a/src/base/bittorrent/customstorage.cpp b/src/base/bittorrent/customstorage.cpp
index c4957ef07..9134b1507 100644
--- a/src/base/bittorrent/customstorage.cpp
+++ b/src/base/bittorrent/customstorage.cpp
@@ -240,11 +240,11 @@ void CustomDiskIOThread::handleCompleteFiles(lt::storage_index_t storage, const
lt::storage_interface *customStorageConstructor(const lt::storage_params ¶ms, lt::file_pool &pool)
{
- return new CustomStorage {params, pool};
+ return new CustomStorage(params, pool);
}
CustomStorage::CustomStorage(const lt::storage_params ¶ms, lt::file_pool &filePool)
- : lt::default_storage {params, filePool}
+ : lt::default_storage(params, filePool)
, m_savePath {params.path}
{
}
diff --git a/src/base/bittorrent/dbresumedatastorage.cpp b/src/base/bittorrent/dbresumedatastorage.cpp
index bb0efbdaf..5e36e75fb 100644
--- a/src/base/bittorrent/dbresumedatastorage.cpp
+++ b/src/base/bittorrent/dbresumedatastorage.cpp
@@ -67,7 +67,7 @@ namespace
{
const QString DB_CONNECTION_NAME = u"ResumeDataStorage"_s;
- const int DB_VERSION = 7;
+ const int DB_VERSION = 8;
const QString DB_TABLE_META = u"meta"_s;
const QString DB_TABLE_TORRENTS = u"torrents"_s;
@@ -628,7 +628,31 @@ void BitTorrent::DBResumeDataStorage::updateDB(const int fromVersion) const
}
if (fromVersion <= 6)
- addColumn(DB_TABLE_TORRENTS, DB_COLUMN_SHARE_LIMIT_ACTION, "TEXTNOT NULL DEFAULT `Default`");
+ addColumn(DB_TABLE_TORRENTS, DB_COLUMN_SHARE_LIMIT_ACTION, "TEXT NOT NULL DEFAULT `Default`");
+
+ if (fromVersion == 7)
+ {
+ const QString TEMP_COLUMN_NAME = DB_COLUMN_SHARE_LIMIT_ACTION.name + u"_temp";
+
+ auto queryStr = u"ALTER TABLE %1 ADD %2 %3"_s
+ .arg(quoted(DB_TABLE_TORRENTS), TEMP_COLUMN_NAME, u"TEXT NOT NULL DEFAULT `Default`");
+ if (!query.exec(queryStr))
+ throw RuntimeError(query.lastError().text());
+
+ queryStr = u"UPDATE %1 SET %2 = %3"_s
+ .arg(quoted(DB_TABLE_TORRENTS), quoted(TEMP_COLUMN_NAME), quoted(DB_COLUMN_SHARE_LIMIT_ACTION.name));
+ if (!query.exec(queryStr))
+ throw RuntimeError(query.lastError().text());
+
+ queryStr = u"ALTER TABLE %1 DROP %2"_s.arg(quoted(DB_TABLE_TORRENTS), quoted(DB_COLUMN_SHARE_LIMIT_ACTION.name));
+ if (!query.exec(queryStr))
+ throw RuntimeError(query.lastError().text());
+
+ queryStr = u"ALTER TABLE %1 RENAME %2 TO %3"_s
+ .arg(quoted(DB_TABLE_TORRENTS), quoted(TEMP_COLUMN_NAME), quoted(DB_COLUMN_SHARE_LIMIT_ACTION.name));
+ if (!query.exec(queryStr))
+ throw RuntimeError(query.lastError().text());
+ }
const QString updateMetaVersionQuery = makeUpdateStatement(DB_TABLE_META, {DB_COLUMN_NAME, DB_COLUMN_VALUE});
if (!query.prepare(updateMetaVersionQuery))
diff --git a/src/base/bittorrent/peerinfo.cpp b/src/base/bittorrent/peerinfo.cpp
index cf27ba302..3706b1e81 100644
--- a/src/base/bittorrent/peerinfo.cpp
+++ b/src/base/bittorrent/peerinfo.cpp
@@ -367,6 +367,10 @@ void PeerInfo::determineFlags()
if (useUTPSocket())
updateFlags(u'P', C_UTP);
+ // h = Peer is using NAT hole punching
+ if (isHolepunched())
+ updateFlags(u'h', tr("Peer is using NAT hole punching"));
+
m_flags.chop(1);
m_flagsDescription.chop(1);
}
diff --git a/src/base/bittorrent/session.h b/src/base/bittorrent/session.h
index d4d3e758a..bd0e1f9bd 100644
--- a/src/base/bittorrent/session.h
+++ b/src/base/bittorrent/session.h
@@ -37,17 +37,12 @@
#include "addtorrentparams.h"
#include "categoryoptions.h"
#include "sharelimitaction.h"
+#include "torrentcontentremoveoption.h"
#include "trackerentry.h"
#include "trackerentrystatus.h"
class QString;
-enum DeleteOption
-{
- DeleteTorrent,
- DeleteTorrentAndFiles
-};
-
namespace BitTorrent
{
class InfoHash;
@@ -58,6 +53,12 @@ namespace BitTorrent
struct CacheStatus;
struct SessionStatus;
+ enum class TorrentRemoveOption
+ {
+ KeepContent,
+ RemoveContent
+ };
+
// Using `Q_ENUM_NS()` without a wrapper namespace in our case is not advised
// since `Q_NAMESPACE` cannot be used when the same namespace resides at different files.
// https://www.kdab.com/new-qt-5-8-meta-object-support-namespaces/#comment-143779
@@ -91,7 +92,8 @@ namespace BitTorrent
{
Default = 0,
MMap = 1,
- Posix = 2
+ Posix = 2,
+ SimplePreadPwrite = 3
};
Q_ENUM_NS(DiskIOType)
@@ -425,7 +427,7 @@ namespace BitTorrent
virtual void setExcludedFileNamesEnabled(bool enabled) = 0;
virtual QStringList excludedFileNames() const = 0;
virtual void setExcludedFileNames(const QStringList &newList) = 0;
- virtual bool isFilenameExcluded(const QString &fileName) const = 0;
+ virtual void applyFilenameFilter(const PathList &files, QList &priorities) = 0;
virtual QStringList bannedIPs() const = 0;
virtual void setBannedIPs(const QStringList &newList) = 0;
virtual ResumeDataStorageType resumeDataStorageType() const = 0;
@@ -434,6 +436,8 @@ namespace BitTorrent
virtual void setMergeTrackersEnabled(bool enabled) = 0;
virtual bool isStartPaused() const = 0;
virtual void setStartPaused(bool value) = 0;
+ virtual TorrentContentRemoveOption torrentContentRemoveOption() const = 0;
+ virtual void setTorrentContentRemoveOption(TorrentContentRemoveOption option) = 0;
virtual bool isRestored() const = 0;
@@ -453,7 +457,7 @@ namespace BitTorrent
virtual bool isKnownTorrent(const InfoHash &infoHash) const = 0;
virtual bool addTorrent(const TorrentDescriptor &torrentDescr, const AddTorrentParams ¶ms = {}) = 0;
- virtual bool deleteTorrent(const TorrentID &id, DeleteOption deleteOption = DeleteOption::DeleteTorrent) = 0;
+ virtual bool removeTorrent(const TorrentID &id, TorrentRemoveOption deleteOption = TorrentRemoveOption::KeepContent) = 0;
virtual bool downloadMetadata(const TorrentDescriptor &torrentDescr) = 0;
virtual bool cancelDownloadMetadata(const TorrentID &id) = 0;
diff --git a/src/base/bittorrent/sessionimpl.cpp b/src/base/bittorrent/sessionimpl.cpp
index 5822bcb63..edd6cc696 100644
--- a/src/base/bittorrent/sessionimpl.cpp
+++ b/src/base/bittorrent/sessionimpl.cpp
@@ -66,6 +66,7 @@
#include
#include
#include
+#include
#include
#include
#include
@@ -101,6 +102,7 @@
#include "nativesessionextension.h"
#include "portforwarderimpl.h"
#include "resumedatastorage.h"
+#include "torrentcontentremover.h"
#include "torrentdescriptor.h"
#include "torrentimpl.h"
#include "tracker.h"
@@ -525,6 +527,7 @@ SessionImpl::SessionImpl(QObject *parent)
, m_I2POutboundQuantity {BITTORRENT_SESSION_KEY(u"I2P/OutboundQuantity"_s), 3}
, m_I2PInboundLength {BITTORRENT_SESSION_KEY(u"I2P/InboundLength"_s), 3}
, m_I2POutboundLength {BITTORRENT_SESSION_KEY(u"I2P/OutboundLength"_s), 3}
+ , m_torrentContentRemoveOption {BITTORRENT_SESSION_KEY(u"TorrentContentRemoveOption"_s), TorrentContentRemoveOption::Delete}
, m_startPaused {BITTORRENT_SESSION_KEY(u"StartPaused"_s)}
, m_seedingLimitTimer {new QTimer(this)}
, m_resumeDataTimer {new QTimer(this)}
@@ -550,7 +553,14 @@ SessionImpl::SessionImpl(QObject *parent)
, this, [this]() { m_recentErroredTorrents.clear(); });
m_seedingLimitTimer->setInterval(10s);
- connect(m_seedingLimitTimer, &QTimer::timeout, this, &SessionImpl::processShareLimits);
+ connect(m_seedingLimitTimer, &QTimer::timeout, this, [this]
+ {
+ // We shouldn't iterate over `m_torrents` in the loop below
+ // since `deleteTorrent()` modifies it indirectly
+ const QHash torrents {m_torrents};
+ for (TorrentImpl *torrent : torrents)
+ processTorrentShareLimits(torrent);
+ });
initializeNativeSession();
configureComponents();
@@ -586,6 +596,11 @@ SessionImpl::SessionImpl(QObject *parent)
connect(m_ioThread.get(), &QThread::finished, m_fileSearcher, &QObject::deleteLater);
connect(m_fileSearcher, &FileSearcher::searchFinished, this, &SessionImpl::fileSearchFinished);
+ m_torrentContentRemover = new TorrentContentRemover;
+ m_torrentContentRemover->moveToThread(m_ioThread.get());
+ connect(m_ioThread.get(), &QThread::finished, m_torrentContentRemover, &QObject::deleteLater);
+ connect(m_torrentContentRemover, &TorrentContentRemover::jobFinished, this, &SessionImpl::torrentContentRemovingFinished);
+
m_ioThread->start();
initMetrics();
@@ -604,7 +619,7 @@ SessionImpl::~SessionImpl()
{
m_nativeSession->pause();
- const qint64 timeout = (m_shutdownTimeout >= 0) ? (m_shutdownTimeout * 1000) : -1;
+ const auto timeout = (m_shutdownTimeout >= 0) ? (static_cast(m_shutdownTimeout) * 1000) : -1;
const QDeadlineTimer shutdownDeadlineTimer {timeout};
if (m_torrentsQueueChanged)
@@ -1592,7 +1607,7 @@ void SessionImpl::endStartup(ResumeSessionContext *context)
reannounceToAllTrackers();
}
- m_wakeupCheckTimestamp = QDateTime::currentDateTime();
+ m_wakeupCheckTimestamp = now;
});
m_wakeupCheckTimestamp = QDateTime::currentDateTime();
m_wakeupCheckTimer->start(30s);
@@ -1624,6 +1639,13 @@ void SessionImpl::initializeNativeSession()
#ifdef QBT_USES_LIBTORRENT2
// preserve the same behavior as in earlier libtorrent versions
pack.set_bool(lt::settings_pack::enable_set_file_valid_data, true);
+
+ // This is a special case. We use MMap disk IO but tweak it to always fallback to pread/pwrite.
+ if (diskIOType() == DiskIOType::SimplePreadPwrite)
+ {
+ pack.set_int(lt::settings_pack::mmap_file_size_cutoff, std::numeric_limits::max());
+ pack.set_int(lt::settings_pack::disk_write_mode, lt::settings_pack::mmap_write_mode_t::always_pwrite);
+ }
#endif
lt::session_params sessionParams {std::move(pack), {}};
@@ -1634,6 +1656,7 @@ void SessionImpl::initializeNativeSession()
sessionParams.disk_io_constructor = customPosixDiskIOConstructor;
break;
case DiskIOType::MMap:
+ case DiskIOType::SimplePreadPwrite:
sessionParams.disk_io_constructor = customMMapDiskIOConstructor;
break;
default:
@@ -2236,72 +2259,66 @@ void SessionImpl::populateAdditionalTrackers()
m_additionalTrackerEntries = parseTrackerEntries(additionalTrackers());
}
-void SessionImpl::processShareLimits()
+void SessionImpl::processTorrentShareLimits(TorrentImpl *torrent)
{
+ if (!torrent->isFinished() || torrent->isForced())
+ return;
+
const auto effectiveLimit = [](const T limit, const T useGlobalLimit, const T globalLimit) -> T
{
return (limit == useGlobalLimit) ? globalLimit : limit;
};
- // We shouldn't iterate over `m_torrents` in the loop below
- // since `deleteTorrent()` modifies it indirectly
- const QHash torrents {m_torrents};
- for (const auto &[torrentID, torrent] : torrents.asKeyValueRange())
+ const qreal ratioLimit = effectiveLimit(torrent->ratioLimit(), Torrent::USE_GLOBAL_RATIO, globalMaxRatio());
+ const int seedingTimeLimit = effectiveLimit(torrent->seedingTimeLimit(), Torrent::USE_GLOBAL_SEEDING_TIME, globalMaxSeedingMinutes());
+ const int inactiveSeedingTimeLimit = effectiveLimit(torrent->inactiveSeedingTimeLimit(), Torrent::USE_GLOBAL_INACTIVE_SEEDING_TIME, globalMaxInactiveSeedingMinutes());
+
+ bool reached = false;
+ QString description;
+
+ if (const qreal ratio = torrent->realRatio();
+ (ratioLimit >= 0) && (ratio <= Torrent::MAX_RATIO) && (ratio >= ratioLimit))
{
- if (!torrent->isFinished() || torrent->isForced())
- continue;
+ reached = true;
+ description = tr("Torrent reached the share ratio limit.");
+ }
+ else if (const qlonglong seedingTimeInMinutes = torrent->finishedTime() / 60;
+ (seedingTimeLimit >= 0) && (seedingTimeInMinutes <= Torrent::MAX_SEEDING_TIME) && (seedingTimeInMinutes >= seedingTimeLimit))
+ {
+ reached = true;
+ description = tr("Torrent reached the seeding time limit.");
+ }
+ else if (const qlonglong inactiveSeedingTimeInMinutes = torrent->timeSinceActivity() / 60;
+ (inactiveSeedingTimeLimit >= 0) && (inactiveSeedingTimeInMinutes <= Torrent::MAX_INACTIVE_SEEDING_TIME) && (inactiveSeedingTimeInMinutes >= inactiveSeedingTimeLimit))
+ {
+ reached = true;
+ description = tr("Torrent reached the inactive seeding time limit.");
+ }
- const qreal ratioLimit = effectiveLimit(torrent->ratioLimit(), Torrent::USE_GLOBAL_RATIO, globalMaxRatio());
- const int seedingTimeLimit = effectiveLimit(torrent->seedingTimeLimit(), Torrent::USE_GLOBAL_SEEDING_TIME, globalMaxSeedingMinutes());
- const int inactiveSeedingTimeLimit = effectiveLimit(torrent->inactiveSeedingTimeLimit(), Torrent::USE_GLOBAL_INACTIVE_SEEDING_TIME, globalMaxInactiveSeedingMinutes());
+ if (reached)
+ {
+ const QString torrentName = tr("Torrent: \"%1\".").arg(torrent->name());
+ const ShareLimitAction shareLimitAction = (torrent->shareLimitAction() == ShareLimitAction::Default) ? m_shareLimitAction : torrent->shareLimitAction();
- bool reached = false;
- QString description;
-
- if (const qreal ratio = torrent->realRatio();
- (ratioLimit >= 0) && (ratio <= Torrent::MAX_RATIO) && (ratio >= ratioLimit))
+ if (shareLimitAction == ShareLimitAction::Remove)
{
- reached = true;
- description = tr("Torrent reached the share ratio limit.");
+ LogMsg(u"%1 %2 %3"_s.arg(description, tr("Removing torrent."), torrentName));
+ removeTorrent(torrent->id(), TorrentRemoveOption::KeepContent);
}
- else if (const qlonglong seedingTimeInMinutes = torrent->finishedTime() / 60;
- (seedingTimeLimit >= 0) && (seedingTimeInMinutes <= Torrent::MAX_SEEDING_TIME) && (seedingTimeInMinutes >= seedingTimeLimit))
+ else if (shareLimitAction == ShareLimitAction::RemoveWithContent)
{
- reached = true;
- description = tr("Torrent reached the seeding time limit.");
+ LogMsg(u"%1 %2 %3"_s.arg(description, tr("Removing torrent and deleting its content."), torrentName));
+ removeTorrent(torrent->id(), TorrentRemoveOption::RemoveContent);
}
- else if (const qlonglong inactiveSeedingTimeInMinutes = torrent->timeSinceActivity() / 60;
- (inactiveSeedingTimeLimit >= 0) && (inactiveSeedingTimeInMinutes <= Torrent::MAX_INACTIVE_SEEDING_TIME) && (inactiveSeedingTimeInMinutes >= inactiveSeedingTimeLimit))
+ else if ((shareLimitAction == ShareLimitAction::Stop) && !torrent->isStopped())
{
- reached = true;
- description = tr("Torrent reached the inactive seeding time limit.");
+ torrent->stop();
+ LogMsg(u"%1 %2 %3"_s.arg(description, tr("Torrent stopped."), torrentName));
}
-
- if (reached)
+ else if ((shareLimitAction == ShareLimitAction::EnableSuperSeeding) && !torrent->isStopped() && !torrent->superSeeding())
{
- const QString torrentName = tr("Torrent: \"%1\".").arg(torrent->name());
- const ShareLimitAction shareLimitAction = (torrent->shareLimitAction() == ShareLimitAction::Default) ? m_shareLimitAction : torrent->shareLimitAction();
-
- if (shareLimitAction == ShareLimitAction::Remove)
- {
- LogMsg(u"%1 %2 %3"_s.arg(description, tr("Removing torrent."), torrentName));
- deleteTorrent(torrentID);
- }
- else if (shareLimitAction == ShareLimitAction::RemoveWithContent)
- {
- LogMsg(u"%1 %2 %3"_s.arg(description, tr("Removing torrent and deleting its content."), torrentName));
- deleteTorrent(torrentID, DeleteTorrentAndFiles);
- }
- else if ((shareLimitAction == ShareLimitAction::Stop) && !torrent->isStopped())
- {
- torrent->stop();
- LogMsg(u"%1 %2 %3"_s.arg(description, tr("Torrent stopped."), torrentName));
- }
- else if ((shareLimitAction == ShareLimitAction::EnableSuperSeeding) && !torrent->isStopped() && !torrent->superSeeding())
- {
- torrent->setSuperSeeding(true);
- LogMsg(u"%1 %2 %3"_s.arg(description, tr("Super seeding enabled."), torrentName));
- }
+ torrent->setSuperSeeding(true);
+ LogMsg(u"%1 %2 %3"_s.arg(description, tr("Super seeding enabled."), torrentName));
}
}
}
@@ -2331,6 +2348,19 @@ void SessionImpl::fileSearchFinished(const TorrentID &id, const Path &savePath,
}
}
+void SessionImpl::torrentContentRemovingFinished(const QString &torrentName, const QString &errorMessage)
+{
+ if (errorMessage.isEmpty())
+ {
+ LogMsg(tr("Torrent content removed. Torrent: \"%1\"").arg(torrentName));
+ }
+ else
+ {
+ LogMsg(tr("Failed to remove torrent content. Torrent: \"%1\". Error: \"%2\"")
+ .arg(torrentName, errorMessage), Log::WARNING);
+ }
+}
+
Torrent *SessionImpl::getTorrent(const TorrentID &id) const
{
return m_torrents.value(id);
@@ -2377,26 +2407,29 @@ void SessionImpl::banIP(const QString &ip)
// Delete a torrent from the session, given its hash
// and from the disk, if the corresponding deleteOption is chosen
-bool SessionImpl::deleteTorrent(const TorrentID &id, const DeleteOption deleteOption)
+bool SessionImpl::removeTorrent(const TorrentID &id, const TorrentRemoveOption deleteOption)
{
TorrentImpl *const torrent = m_torrents.take(id);
if (!torrent)
return false;
- qDebug("Deleting torrent with ID: %s", qUtf8Printable(torrent->id().toString()));
+ const TorrentID torrentID = torrent->id();
+ const QString torrentName = torrent->name();
+
+ qDebug("Deleting torrent with ID: %s", qUtf8Printable(torrentID.toString()));
emit torrentAboutToBeRemoved(torrent);
if (const InfoHash infoHash = torrent->infoHash(); infoHash.isHybrid())
m_hybridTorrentsByAltID.remove(TorrentID::fromSHA1Hash(infoHash.v1()));
// Remove it from session
- if (deleteOption == DeleteTorrent)
+ if (deleteOption == TorrentRemoveOption::KeepContent)
{
- m_removingTorrents[torrent->id()] = {torrent->name(), {}, deleteOption};
+ m_removingTorrents[torrentID] = {torrentName, torrent->actualStorageLocation(), {}, deleteOption};
const lt::torrent_handle nativeHandle {torrent->nativeHandle()};
const auto iter = std::find_if(m_moveStorageQueue.begin(), m_moveStorageQueue.end()
- , [&nativeHandle](const MoveStorageJob &job)
+ , [&nativeHandle](const MoveStorageJob &job)
{
return job.torrentHandle == nativeHandle;
});
@@ -2414,14 +2447,14 @@ bool SessionImpl::deleteTorrent(const TorrentID &id, const DeleteOption deleteOp
}
else
{
- m_removingTorrents[torrent->id()] = {torrent->name(), torrent->rootPath(), deleteOption};
+ m_removingTorrents[torrentID] = {torrentName, torrent->actualStorageLocation(), torrent->actualFilePaths(), deleteOption};
if (m_moveStorageQueue.size() > 1)
{
// Delete "move storage job" for the deleted torrent
// (note: we shouldn't delete active job)
const auto iter = std::find_if((m_moveStorageQueue.begin() + 1), m_moveStorageQueue.end()
- , [torrent](const MoveStorageJob &job)
+ , [torrent](const MoveStorageJob &job)
{
return job.torrentHandle == torrent->nativeHandle();
});
@@ -2429,12 +2462,13 @@ bool SessionImpl::deleteTorrent(const TorrentID &id, const DeleteOption deleteOp
m_moveStorageQueue.erase(iter);
}
- m_nativeSession->remove_torrent(torrent->nativeHandle(), lt::session::delete_files);
+ m_nativeSession->remove_torrent(torrent->nativeHandle(), lt::session::delete_partfile);
}
// Remove it from torrent resume directory
- m_resumeDataStorage->remove(torrent->id());
+ m_resumeDataStorage->remove(torrentID);
+ LogMsg(tr("Torrent removed. Torrent: \"%1\"").arg(torrentName));
delete torrent;
return true;
}
@@ -2462,7 +2496,7 @@ bool SessionImpl::cancelDownloadMetadata(const TorrentID &id)
}
#endif
- m_nativeSession->remove_torrent(nativeHandle, lt::session::delete_files);
+ m_nativeSession->remove_torrent(nativeHandle);
return true;
}
@@ -2686,8 +2720,39 @@ bool SessionImpl::addTorrent_impl(const TorrentDescriptor &source, const AddTorr
if (m_loadingTorrents.contains(id) || (infoHash.isHybrid() && m_loadingTorrents.contains(altID)))
return false;
- if (findTorrent(infoHash))
+ if (Torrent *torrent = findTorrent(infoHash))
+ {
+ // a duplicate torrent is being added
+
+ if (hasMetadata)
+ {
+ // Trying to set metadata to existing torrent in case if it has none
+ torrent->setMetadata(*source.info());
+ }
+
+ if (!isMergeTrackersEnabled())
+ {
+ LogMsg(tr("Detected an attempt to add a duplicate torrent. Existing torrent: %1. Result: %2")
+ .arg(torrent->name(), tr("Merging of trackers is disabled")));
+ return false;
+ }
+
+ const bool isPrivate = torrent->isPrivate() || (hasMetadata && source.info()->isPrivate());
+ if (isPrivate)
+ {
+ LogMsg(tr("Detected an attempt to add a duplicate torrent. Existing torrent: %1. Result: %2")
+ .arg(torrent->name(), tr("Trackers cannot be merged because it is a private torrent")));
+ return false;
+ }
+
+ // merge trackers and web seeds
+ torrent->addTrackers(source.trackers());
+ torrent->addUrlSeeds(source.urlSeeds());
+
+ LogMsg(tr("Detected an attempt to add a duplicate torrent. Existing torrent: %1. Result: %2")
+ .arg(torrent->name(), tr("Trackers are merged from new source")));
return false;
+ }
// It looks illogical that we don't just use an existing handle,
// but as previous experience has shown, it actually creates unnecessary
@@ -2751,6 +2816,19 @@ bool SessionImpl::addTorrent_impl(const TorrentDescriptor &source, const AddTorr
loadTorrentParams.name = contentName;
}
+ const auto nativeIndexes = torrentInfo.nativeIndexes();
+
+ Q_ASSERT(p.file_priorities.empty());
+ Q_ASSERT(addTorrentParams.filePriorities.isEmpty() || (addTorrentParams.filePriorities.size() == nativeIndexes.size()));
+ QList filePriorities = addTorrentParams.filePriorities;
+
+ // Filename filter should be applied before `findIncompleteFiles()` is called.
+ if (filePriorities.isEmpty() && isExcludedFileNamesEnabled())
+ {
+ // Check file name blacklist when priorities are not explicitly set
+ applyFilenameFilter(filePaths, filePriorities);
+ }
+
if (!loadTorrentParams.hasFinishedStatus)
{
const Path actualDownloadPath = useAutoTMM
@@ -2759,36 +2837,20 @@ bool SessionImpl::addTorrent_impl(const TorrentDescriptor &source, const AddTorr
isFindingIncompleteFiles = true;
}
- const auto nativeIndexes = torrentInfo.nativeIndexes();
if (!isFindingIncompleteFiles)
{
for (int index = 0; index < filePaths.size(); ++index)
p.renamed_files[nativeIndexes[index]] = filePaths.at(index).toString().toStdString();
}
- Q_ASSERT(p.file_priorities.empty());
- Q_ASSERT(addTorrentParams.filePriorities.isEmpty() || (addTorrentParams.filePriorities.size() == nativeIndexes.size()));
-
const int internalFilesCount = torrentInfo.nativeInfo()->files().num_files(); // including .pad files
// Use qBittorrent default priority rather than libtorrent's (4)
p.file_priorities = std::vector(internalFilesCount, LT::toNative(DownloadPriority::Normal));
- if (addTorrentParams.filePriorities.isEmpty())
+ if (!filePriorities.isEmpty())
{
- if (isExcludedFileNamesEnabled())
- {
- // Check file name blacklist when priorities are not explicitly set
- for (int i = 0; i < filePaths.size(); ++i)
- {
- if (isFilenameExcluded(filePaths.at(i).filename()))
- p.file_priorities[LT::toUnderlyingType(nativeIndexes[i])] = lt::dont_download;
- }
- }
- }
- else
- {
- for (int i = 0; i < addTorrentParams.filePriorities.size(); ++i)
- p.file_priorities[LT::toUnderlyingType(nativeIndexes[i])] = LT::toNative(addTorrentParams.filePriorities[i]);
+ for (int i = 0; i < filePriorities.size(); ++i)
+ p.file_priorities[LT::toUnderlyingType(nativeIndexes[i])] = LT::toNative(filePriorities[i]);
}
Q_ASSERT(p.ti);
@@ -3874,21 +3936,41 @@ void SessionImpl::populateExcludedFileNamesRegExpList()
for (const QString &str : excludedNames)
{
- const QString pattern = QRegularExpression::anchoredPattern(QRegularExpression::wildcardToRegularExpression(str));
+ const QString pattern = QRegularExpression::wildcardToRegularExpression(str);
const QRegularExpression re {pattern, QRegularExpression::CaseInsensitiveOption};
m_excludedFileNamesRegExpList.append(re);
}
}
-bool SessionImpl::isFilenameExcluded(const QString &fileName) const
+void SessionImpl::applyFilenameFilter(const PathList &files, QList &priorities)
{
if (!isExcludedFileNamesEnabled())
- return false;
+ return;
- return std::any_of(m_excludedFileNamesRegExpList.begin(), m_excludedFileNamesRegExpList.end(), [&fileName](const QRegularExpression &re)
+ const auto isFilenameExcluded = [patterns = m_excludedFileNamesRegExpList](const Path &fileName)
{
- return re.match(fileName).hasMatch();
- });
+ return std::any_of(patterns.begin(), patterns.end(), [&fileName](const QRegularExpression &re)
+ {
+ Path path = fileName;
+ while (!re.match(path.filename()).hasMatch())
+ {
+ path = path.parentPath();
+ if (path.isEmpty())
+ return false;
+ }
+ return true;
+ });
+ };
+
+ priorities.resize(files.count(), DownloadPriority::Normal);
+ for (int i = 0; i < priorities.size(); ++i)
+ {
+ if (priorities[i] == BitTorrent::DownloadPriority::Ignored)
+ continue;
+
+ if (isFilenameExcluded(files.at(i)))
+ priorities[i] = BitTorrent::DownloadPriority::Ignored;
+ }
}
void SessionImpl::setBannedIPs(const QStringList &newList)
@@ -3957,6 +4039,16 @@ void SessionImpl::setStartPaused(const bool value)
m_startPaused = value;
}
+TorrentContentRemoveOption SessionImpl::torrentContentRemoveOption() const
+{
+ return m_torrentContentRemoveOption;
+}
+
+void SessionImpl::setTorrentContentRemoveOption(const TorrentContentRemoveOption option)
+{
+ m_torrentContentRemoveOption = option;
+}
+
QStringList SessionImpl::bannedIPs() const
{
return m_bannedIPs;
@@ -3974,14 +4066,29 @@ bool SessionImpl::isPaused() const
void SessionImpl::pause()
{
- if (!m_isPaused)
- {
- if (isRestored())
- m_nativeSession->pause();
+ if (m_isPaused)
+ return;
- m_isPaused = true;
- emit paused();
+ if (isRestored())
+ {
+ m_nativeSession->pause();
+
+ for (TorrentImpl *torrent : asConst(m_torrents))
+ {
+ torrent->resetTrackerEntryStatuses();
+
+ const QList trackers = torrent->trackers();
+ QHash updatedTrackers;
+ updatedTrackers.reserve(trackers.size());
+
+ for (const TrackerEntryStatus &status : trackers)
+ updatedTrackers.emplace(status.url, status);
+ emit trackerEntryStatusesUpdated(torrent, updatedTrackers);
+ }
}
+
+ m_isPaused = true;
+ emit paused();
}
void SessionImpl::resume()
@@ -4890,7 +4997,7 @@ void SessionImpl::updateSeedingLimitTimer()
if ((globalMaxRatio() == Torrent::NO_RATIO_LIMIT) && !hasPerTorrentRatioLimit()
&& (globalMaxSeedingMinutes() == Torrent::NO_SEEDING_TIME_LIMIT) && !hasPerTorrentSeedingTimeLimit()
&& (globalMaxInactiveSeedingMinutes() == Torrent::NO_INACTIVE_SEEDING_TIME_LIMIT) && !hasPerTorrentInactiveSeedingTimeLimit())
- {
+ {
if (m_seedingLimitTimer->isActive())
m_seedingLimitTimer->stop();
}
@@ -5002,18 +5109,7 @@ void SessionImpl::handleTorrentChecked(TorrentImpl *const torrent)
void SessionImpl::handleTorrentFinished(TorrentImpl *const torrent)
{
- LogMsg(tr("Torrent download finished. Torrent: \"%1\"").arg(torrent->name()));
- emit torrentFinished(torrent);
-
- if (const Path exportPath = finishedTorrentExportDirectory(); !exportPath.isEmpty())
- exportTorrentFile(torrent, exportPath);
-
- const bool hasUnfinishedTorrents = std::any_of(m_torrents.cbegin(), m_torrents.cend(), [](const TorrentImpl *torrent)
- {
- return !(torrent->isFinished() || torrent->isStopped() || torrent->isErrored());
- });
- if (!hasUnfinishedTorrents)
- emit allTorrentsFinished();
+ m_pendingFinishedTorrents.append(torrent);
}
void SessionImpl::handleTorrentResumeDataReady(TorrentImpl *const torrent, const LoadTorrentParams &data)
@@ -5141,11 +5237,37 @@ void SessionImpl::handleMoveTorrentStorageJobFinished(const Path &newPath)
// Last job is completed for torrent that being removing, so actually remove it
const lt::torrent_handle nativeHandle {finishedJob.torrentHandle};
const RemovingTorrentData &removingTorrentData = m_removingTorrents[nativeHandle.info_hash()];
- if (removingTorrentData.deleteOption == DeleteTorrent)
+ if (removingTorrentData.removeOption == TorrentRemoveOption::KeepContent)
m_nativeSession->remove_torrent(nativeHandle, lt::session::delete_partfile);
}
}
+void SessionImpl::processPendingFinishedTorrents()
+{
+ if (m_pendingFinishedTorrents.isEmpty())
+ return;
+
+ for (TorrentImpl *torrent : asConst(m_pendingFinishedTorrents))
+ {
+ LogMsg(tr("Torrent download finished. Torrent: \"%1\"").arg(torrent->name()));
+ emit torrentFinished(torrent);
+
+ if (const Path exportPath = finishedTorrentExportDirectory(); !exportPath.isEmpty())
+ exportTorrentFile(torrent, exportPath);
+
+ processTorrentShareLimits(torrent);
+ }
+
+ m_pendingFinishedTorrents.clear();
+
+ const bool hasUnfinishedTorrents = std::any_of(m_torrents.cbegin(), m_torrents.cend(), [](const TorrentImpl *torrent)
+ {
+ return !(torrent->isFinished() || torrent->isStopped() || torrent->isErrored());
+ });
+ if (!hasUnfinishedTorrents)
+ emit allTorrentsFinished();
+}
+
void SessionImpl::storeCategories() const
{
QJsonObject jsonObj;
@@ -5372,6 +5494,11 @@ void SessionImpl::setTorrentContentLayout(const TorrentContentLayout value)
// Read alerts sent by libtorrent session
void SessionImpl::readAlerts()
{
+ // cache current datetime of Qt and libtorrent clocks in order
+ // to optimize conversion of time points from lt to Qt clocks
+ m_ltNow = lt::clock_type::now();
+ m_qNow = QDateTime::currentDateTime();
+
const std::vector alerts = getPendingAlerts();
Q_ASSERT(m_loadedTorrents.isEmpty());
@@ -5398,7 +5525,8 @@ void SessionImpl::readAlerts()
}
}
- processTrackerStatuses();
+ // Some torrents may become "finished" after different alerts handling.
+ processPendingFinishedTorrents();
}
void SessionImpl::handleAddTorrentAlert(const lt::add_torrent_alert *alert)
@@ -5660,74 +5788,32 @@ TorrentImpl *SessionImpl::createTorrent(const lt::torrent_handle &nativeHandle,
return torrent;
}
-void SessionImpl::handleTorrentRemovedAlert(const lt::torrent_removed_alert *alert)
+void SessionImpl::handleTorrentRemovedAlert(const lt::torrent_removed_alert */*alert*/)
{
-#ifdef QBT_USES_LIBTORRENT2
- const auto id = TorrentID::fromInfoHash(alert->info_hashes);
-#else
- const auto id = TorrentID::fromInfoHash(alert->info_hash);
-#endif
-
- const auto removingTorrentDataIter = m_removingTorrents.find(id);
- if (removingTorrentDataIter != m_removingTorrents.end())
- {
- if (removingTorrentDataIter->deleteOption == DeleteTorrent)
- {
- LogMsg(tr("Removed torrent. Torrent: \"%1\"").arg(removingTorrentDataIter->name));
- m_removingTorrents.erase(removingTorrentDataIter);
- }
- }
+ // We cannot consider `torrent_removed_alert` as a starting point for removing content,
+ // because it has an inconsistent posting time between different versions of libtorrent,
+ // so files may still be in use in some cases.
}
void SessionImpl::handleTorrentDeletedAlert(const lt::torrent_deleted_alert *alert)
{
#ifdef QBT_USES_LIBTORRENT2
- const auto id = TorrentID::fromInfoHash(alert->info_hashes);
+ const auto torrentID = TorrentID::fromInfoHash(alert->info_hashes);
#else
- const auto id = TorrentID::fromInfoHash(alert->info_hash);
+ const auto torrentID = TorrentID::fromInfoHash(alert->info_hash);
#endif
-
- const auto removingTorrentDataIter = m_removingTorrents.find(id);
- if (removingTorrentDataIter == m_removingTorrents.end())
- return;
-
- // torrent_deleted_alert can also be posted due to deletion of partfile. Ignore it in such a case.
- if (removingTorrentDataIter->deleteOption == DeleteTorrent)
- return;
-
- Utils::Fs::smartRemoveEmptyFolderTree(removingTorrentDataIter->pathToRemove);
- LogMsg(tr("Removed torrent and deleted its content. Torrent: \"%1\"").arg(removingTorrentDataIter->name));
- m_removingTorrents.erase(removingTorrentDataIter);
+ handleRemovedTorrent(torrentID);
}
void SessionImpl::handleTorrentDeleteFailedAlert(const lt::torrent_delete_failed_alert *alert)
{
#ifdef QBT_USES_LIBTORRENT2
- const auto id = TorrentID::fromInfoHash(alert->info_hashes);
+ const auto torrentID = TorrentID::fromInfoHash(alert->info_hashes);
#else
- const auto id = TorrentID::fromInfoHash(alert->info_hash);
+ const auto torrentID = TorrentID::fromInfoHash(alert->info_hash);
#endif
-
- const auto removingTorrentDataIter = m_removingTorrents.find(id);
- if (removingTorrentDataIter == m_removingTorrents.end())
- return;
-
- if (alert->error)
- {
- // libtorrent won't delete the directory if it contains files not listed in the torrent,
- // so we remove the directory ourselves
- Utils::Fs::smartRemoveEmptyFolderTree(removingTorrentDataIter->pathToRemove);
-
- LogMsg(tr("Removed torrent but failed to delete its content and/or partfile. Torrent: \"%1\". Error: \"%2\"")
- .arg(removingTorrentDataIter->name, QString::fromLocal8Bit(alert->error.message().c_str()))
- , Log::WARNING);
- }
- else // torrent without metadata, hence no files on disk
- {
- LogMsg(tr("Removed torrent. Torrent: \"%1\"").arg(removingTorrentDataIter->name));
- }
-
- m_removingTorrents.erase(removingTorrentDataIter);
+ const auto errorMessage = alert->error ? QString::fromLocal8Bit(alert->error.message().c_str()) : QString();
+ handleRemovedTorrent(torrentID, errorMessage);
}
void SessionImpl::handleTorrentNeedCertAlert(const lt::torrent_need_cert_alert *alert)
@@ -6116,7 +6202,12 @@ void SessionImpl::handleTrackerAlert(const lt::tracker_alert *alert)
if (!torrent)
return;
+ [[maybe_unused]] const QMutexLocker updatedTrackerStatusesLocker {&m_updatedTrackerStatusesMutex};
+
+ const auto prevSize = m_updatedTrackerStatuses.size();
QMap &updateInfo = m_updatedTrackerStatuses[torrent->nativeHandle()][std::string(alert->tracker_url())][alert->local_endpoint];
+ if (prevSize < m_updatedTrackerStatuses.size())
+ updateTrackerEntryStatuses(torrent->nativeHandle());
if (alert->type() == lt::tracker_reply_alert::alert_type)
{
@@ -6140,7 +6231,7 @@ void SessionImpl::handleTorrentConflictAlert(const lt::torrent_conflict_alert *a
if (torrent2)
{
if (torrent1)
- deleteTorrent(torrentIDv1);
+ removeTorrent(torrentIDv1);
else
cancelDownloadMetadata(torrentIDv1);
@@ -6178,17 +6269,6 @@ void SessionImpl::handleTorrentConflictAlert(const lt::torrent_conflict_alert *a
}
#endif
-void SessionImpl::processTrackerStatuses()
-{
- if (m_updatedTrackerStatuses.isEmpty())
- return;
-
- for (auto it = m_updatedTrackerStatuses.cbegin(); it != m_updatedTrackerStatuses.cend(); ++it)
- updateTrackerEntryStatuses(it.key(), it.value());
-
- m_updatedTrackerStatuses.clear();
-}
-
void SessionImpl::saveStatistics() const
{
if (!m_isStatisticsDirty)
@@ -6213,15 +6293,19 @@ void SessionImpl::loadStatistics()
m_previouslyUploaded = value[u"AlltimeUL"_s].toLongLong();
}
-void SessionImpl::updateTrackerEntryStatuses(lt::torrent_handle torrentHandle, QHash>> updatedTrackers)
+void SessionImpl::updateTrackerEntryStatuses(lt::torrent_handle torrentHandle)
{
- invokeAsync([this, torrentHandle = std::move(torrentHandle), updatedTrackers = std::move(updatedTrackers)]() mutable
+ invokeAsync([this, torrentHandle = std::move(torrentHandle)]() mutable
{
try
{
std::vector nativeTrackers = torrentHandle.trackers();
- invoke([this, torrentHandle, nativeTrackers = std::move(nativeTrackers)
- , updatedTrackers = std::move(updatedTrackers)]
+
+ QMutexLocker updatedTrackerStatusesLocker {&m_updatedTrackerStatusesMutex};
+ QHash>> updatedTrackers = m_updatedTrackerStatuses.take(torrentHandle);
+ updatedTrackerStatusesLocker.unlock();
+
+ invoke([this, torrentHandle, nativeTrackers = std::move(nativeTrackers), updatedTrackers = std::move(updatedTrackers)]
{
TorrentImpl *torrent = m_torrents.value(torrentHandle.info_hash());
if (!torrent || torrent->isStopped())
@@ -6249,3 +6333,35 @@ void SessionImpl::updateTrackerEntryStatuses(lt::torrent_handle torrentHandle, Q
}
});
}
+
+void SessionImpl::handleRemovedTorrent(const TorrentID &torrentID, const QString &partfileRemoveError)
+{
+ const auto removingTorrentDataIter = m_removingTorrents.find(torrentID);
+ if (removingTorrentDataIter == m_removingTorrents.end())
+ return;
+
+ if (!partfileRemoveError.isEmpty())
+ {
+ LogMsg(tr("Failed to remove partfile. Torrent: \"%1\". Reason: \"%2\".")
+ .arg(removingTorrentDataIter->name, partfileRemoveError)
+ , Log::WARNING);
+ }
+
+ if ((removingTorrentDataIter->removeOption == TorrentRemoveOption::RemoveContent)
+ && !removingTorrentDataIter->contentStoragePath.isEmpty())
+ {
+ QMetaObject::invokeMethod(m_torrentContentRemover, [this, jobData = *removingTorrentDataIter]
+ {
+ m_torrentContentRemover->performJob(jobData.name, jobData.contentStoragePath
+ , jobData.fileNames, m_torrentContentRemoveOption);
+ });
+ }
+
+ m_removingTorrents.erase(removingTorrentDataIter);
+}
+
+QDateTime SessionImpl::fromLTTimePoint32(const lt::time_point32 &timePoint) const
+{
+ const auto secsSinceNow = lt::duration_cast(timePoint - m_ltNow + lt::milliseconds(500)).count();
+ return m_qNow.addSecs(secsSinceNow);
+}
diff --git a/src/base/bittorrent/sessionimpl.h b/src/base/bittorrent/sessionimpl.h
index 40ffbfffa..20f6558f5 100644
--- a/src/base/bittorrent/sessionimpl.h
+++ b/src/base/bittorrent/sessionimpl.h
@@ -41,6 +41,7 @@
#include
#include
#include
+#include
#include
#include
#include
@@ -75,6 +76,7 @@ namespace BitTorrent
class InfoHash;
class ResumeDataStorage;
class Torrent;
+ class TorrentContentRemover;
class TorrentDescriptor;
class TorrentImpl;
class Tracker;
@@ -402,7 +404,7 @@ namespace BitTorrent
void setExcludedFileNamesEnabled(bool enabled) override;
QStringList excludedFileNames() const override;
void setExcludedFileNames(const QStringList &excludedFileNames) override;
- bool isFilenameExcluded(const QString &fileName) const override;
+ void applyFilenameFilter(const PathList &files, QList &priorities) override;
QStringList bannedIPs() const override;
void setBannedIPs(const QStringList &newList) override;
ResumeDataStorageType resumeDataStorageType() const override;
@@ -411,6 +413,8 @@ namespace BitTorrent
void setMergeTrackersEnabled(bool enabled) override;
bool isStartPaused() const override;
void setStartPaused(bool value) override;
+ TorrentContentRemoveOption torrentContentRemoveOption() const override;
+ void setTorrentContentRemoveOption(TorrentContentRemoveOption option) override;
bool isRestored() const override;
@@ -430,7 +434,7 @@ namespace BitTorrent
bool isKnownTorrent(const InfoHash &infoHash) const override;
bool addTorrent(const TorrentDescriptor &torrentDescr, const AddTorrentParams ¶ms = {}) override;
- bool deleteTorrent(const TorrentID &id, DeleteOption deleteOption = DeleteTorrent) override;
+ bool removeTorrent(const TorrentID &id, TorrentRemoveOption deleteOption = TorrentRemoveOption::KeepContent) override;
bool downloadMetadata(const TorrentDescriptor &torrentDescr) override;
bool cancelDownloadMetadata(const TorrentID &id) override;
@@ -472,6 +476,8 @@ namespace BitTorrent
void addMappedPorts(const QSet &ports);
void removeMappedPorts(const QSet &ports);
+ QDateTime fromLTTimePoint32(const lt::time_point32 &timePoint) const;
+
template
void invoke(Func &&func)
{
@@ -487,11 +493,11 @@ namespace BitTorrent
void configureDeferred();
void readAlerts();
void enqueueRefresh();
- void processShareLimits();
void generateResumeData();
void handleIPFilterParsed(int ruleCount);
void handleIPFilterError();
void fileSearchFinished(const TorrentID &id, const Path &savePath, const PathList &fileNames);
+ void torrentContentRemovingFinished(const QString &torrentName, const QString &errorMessage);
private:
struct ResumeSessionContext;
@@ -507,8 +513,9 @@ namespace BitTorrent
struct RemovingTorrentData
{
QString name;
- Path pathToRemove;
- DeleteOption deleteOption {};
+ Path contentStoragePath;
+ PathList fileNames;
+ TorrentRemoveOption removeOption {};
};
explicit SessionImpl(QObject *parent = nullptr);
@@ -535,7 +542,7 @@ namespace BitTorrent
void populateAdditionalTrackers();
void enableIPFilter();
void disableIPFilter();
- void processTrackerStatuses();
+ void processTorrentShareLimits(TorrentImpl *torrent);
void populateExcludedFileNamesRegExpList();
void prepareStartup();
void handleLoadedResumeData(ResumeSessionContext *context);
@@ -588,6 +595,7 @@ namespace BitTorrent
void moveTorrentStorage(const MoveStorageJob &job) const;
void handleMoveTorrentStorageJobFinished(const Path &newPath);
+ void processPendingFinishedTorrents();
void loadCategories();
void storeCategories() const;
@@ -597,15 +605,9 @@ namespace BitTorrent
void saveStatistics() const;
void loadStatistics();
- void updateTrackerEntryStatuses(lt::torrent_handle torrentHandle, QHash>> updatedTrackers);
+ void updateTrackerEntryStatuses(lt::torrent_handle torrentHandle);
- // BitTorrent
- lt::session *m_nativeSession = nullptr;
- NativeSessionExtension *m_nativeSessionExtension = nullptr;
-
- bool m_deferredConfigureScheduled = false;
- bool m_IPFilteringConfigured = false;
- mutable bool m_listenInterfaceConfigured = false;
+ void handleRemovedTorrent(const TorrentID &torrentID, const QString &partfileRemoveError = {});
CachedSettingValue m_DHTBootstrapNodes;
CachedSettingValue m_isDHTEnabled;
@@ -731,8 +733,16 @@ namespace BitTorrent
CachedSettingValue m_I2POutboundQuantity;
CachedSettingValue m_I2PInboundLength;
CachedSettingValue m_I2POutboundLength;
+ CachedSettingValue m_torrentContentRemoveOption;
SettingValue m_startPaused;
+ lt::session *m_nativeSession = nullptr;
+ NativeSessionExtension *m_nativeSessionExtension = nullptr;
+
+ bool m_deferredConfigureScheduled = false;
+ bool m_IPFilteringConfigured = false;
+ mutable bool m_listenInterfaceConfigured = false;
+
bool m_isRestored = false;
bool m_isPaused = isStartPaused();
@@ -766,6 +776,7 @@ namespace BitTorrent
QThreadPool *m_asyncWorker = nullptr;
ResumeDataStorage *m_resumeDataStorage = nullptr;
FileSearcher *m_fileSearcher = nullptr;
+ TorrentContentRemover *m_torrentContentRemover = nullptr;
QHash m_downloadedMetadata;
@@ -783,6 +794,7 @@ namespace BitTorrent
// This field holds amounts of peers reported by trackers in their responses to announces
// (torrent.tracker_name.tracker_local_endpoint.protocol_version.num_peers)
QHash>>> m_updatedTrackerStatuses;
+ QMutex m_updatedTrackerStatusesMutex;
// I/O errored torrents
QSet m_recentErroredTorrents;
@@ -809,6 +821,11 @@ namespace BitTorrent
QTimer *m_wakeupCheckTimer = nullptr;
QDateTime m_wakeupCheckTimestamp;
+ QList m_pendingFinishedTorrents;
+
+ QDateTime m_qNow;
+ lt::clock_type::time_point m_ltNow;
+
friend void Session::initInstance();
friend void Session::freeInstance();
friend Session *Session::instance();
diff --git a/src/base/bittorrent/torrent.h b/src/base/bittorrent/torrent.h
index 34cccd4ff..240075f62 100644
--- a/src/base/bittorrent/torrent.h
+++ b/src/base/bittorrent/torrent.h
@@ -215,7 +215,15 @@ namespace BitTorrent
virtual int piecesCount() const = 0;
virtual int piecesHave() const = 0;
virtual qreal progress() const = 0;
+
virtual QDateTime addedTime() const = 0;
+ virtual QDateTime completedTime() const = 0;
+ virtual QDateTime lastSeenComplete() const = 0;
+ virtual qlonglong activeTime() const = 0;
+ virtual qlonglong finishedTime() const = 0;
+ virtual qlonglong timeSinceUpload() const = 0;
+ virtual qlonglong timeSinceDownload() const = 0;
+ virtual qlonglong timeSinceActivity() const = 0;
// Share limits
virtual qreal ratioLimit() const = 0;
@@ -228,6 +236,7 @@ namespace BitTorrent
virtual void setShareLimitAction(ShareLimitAction action) = 0;
virtual PathList filePaths() const = 0;
+ virtual PathList actualFilePaths() const = 0;
virtual TorrentInfo info() const = 0;
virtual bool isFinished() const = 0;
@@ -253,8 +262,6 @@ namespace BitTorrent
virtual QString error() const = 0;
virtual qlonglong totalDownload() const = 0;
virtual qlonglong totalUpload() const = 0;
- virtual qlonglong activeTime() const = 0;
- virtual qlonglong finishedTime() const = 0;
virtual qlonglong eta() const = 0;
virtual int seedsCount() const = 0;
virtual int peersCount() const = 0;
@@ -262,11 +269,6 @@ namespace BitTorrent
virtual int totalSeedsCount() const = 0;
virtual int totalPeersCount() const = 0;
virtual int totalLeechersCount() const = 0;
- virtual QDateTime lastSeenComplete() const = 0;
- virtual QDateTime completedTime() const = 0;
- virtual qlonglong timeSinceUpload() const = 0;
- virtual qlonglong timeSinceDownload() const = 0;
- virtual qlonglong timeSinceActivity() const = 0;
virtual int downloadLimit() const = 0;
virtual int uploadLimit() const = 0;
virtual bool superSeeding() const = 0;
diff --git a/src/base/bittorrent/torrentcontentremoveoption.h b/src/base/bittorrent/torrentcontentremoveoption.h
new file mode 100644
index 000000000..1083e5ec0
--- /dev/null
+++ b/src/base/bittorrent/torrentcontentremoveoption.h
@@ -0,0 +1,50 @@
+/*
+ * Bittorrent Client using Qt and libtorrent.
+ * Copyright (C) 2024 Vladimir Golovnev
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * In addition, as a special exception, the copyright holders give permission to
+ * link this program with the OpenSSL project's "OpenSSL" library (or with
+ * modified versions of it that use the same license as the "OpenSSL" library),
+ * and distribute the linked executables. You must obey the GNU General Public
+ * License in all respects for all of the code used other than "OpenSSL". If you
+ * modify file(s), you may extend this exception to your version of the file(s),
+ * but you are not obligated to do so. If you do not wish to do so, delete this
+ * exception statement from your version.
+ */
+
+#pragma once
+
+#include
+
+namespace BitTorrent
+{
+ // Using `Q_ENUM_NS()` without a wrapper namespace in our case is not advised
+ // since `Q_NAMESPACE` cannot be used when the same namespace resides at different files.
+ // https://www.kdab.com/new-qt-5-8-meta-object-support-namespaces/#comment-143779
+ inline namespace TorrentContentRemoveOptionNS
+ {
+ Q_NAMESPACE
+
+ enum class TorrentContentRemoveOption
+ {
+ Delete,
+ MoveToTrash
+ };
+
+ Q_ENUM_NS(TorrentContentRemoveOption)
+ }
+}
diff --git a/src/base/bittorrent/torrentcontentremover.cpp b/src/base/bittorrent/torrentcontentremover.cpp
new file mode 100644
index 000000000..861f4be96
--- /dev/null
+++ b/src/base/bittorrent/torrentcontentremover.cpp
@@ -0,0 +1,61 @@
+/*
+ * Bittorrent Client using Qt and libtorrent.
+ * Copyright (C) 2024 Vladimir Golovnev
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * In addition, as a special exception, the copyright holders give permission to
+ * link this program with the OpenSSL project's "OpenSSL" library (or with
+ * modified versions of it that use the same license as the "OpenSSL" library),
+ * and distribute the linked executables. You must obey the GNU General Public
+ * License in all respects for all of the code used other than "OpenSSL". If you
+ * modify file(s), you may extend this exception to your version of the file(s),
+ * but you are not obligated to do so. If you do not wish to do so, delete this
+ * exception statement from your version.
+ */
+
+#include "torrentcontentremover.h"
+
+#include "base/utils/fs.h"
+
+void BitTorrent::TorrentContentRemover::performJob(const QString &torrentName, const Path &basePath
+ , const PathList &fileNames, const TorrentContentRemoveOption option)
+{
+ QString errorMessage;
+
+ if (!fileNames.isEmpty())
+ {
+ const auto removeFileFn = [&option](const Path &filePath)
+ {
+ return ((option == TorrentContentRemoveOption::MoveToTrash)
+ ? Utils::Fs::moveFileToTrash : Utils::Fs::removeFile)(filePath);
+ };
+
+ for (const Path &fileName : fileNames)
+ {
+ if (const auto result = removeFileFn(basePath / fileName)
+ ; !result && errorMessage.isEmpty())
+ {
+ errorMessage = result.error();
+ }
+ }
+
+ const Path rootPath = Path::findRootFolder(fileNames);
+ if (!rootPath.isEmpty())
+ Utils::Fs::smartRemoveEmptyFolderTree(basePath / rootPath);
+ }
+
+ emit jobFinished(torrentName, errorMessage);
+}
diff --git a/src/base/bittorrent/torrentcontentremover.h b/src/base/bittorrent/torrentcontentremover.h
new file mode 100644
index 000000000..a18161493
--- /dev/null
+++ b/src/base/bittorrent/torrentcontentremover.h
@@ -0,0 +1,53 @@
+/*
+ * Bittorrent Client using Qt and libtorrent.
+ * Copyright (C) 2024 Vladimir Golovnev
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * In addition, as a special exception, the copyright holders give permission to
+ * link this program with the OpenSSL project's "OpenSSL" library (or with
+ * modified versions of it that use the same license as the "OpenSSL" library),
+ * and distribute the linked executables. You must obey the GNU General Public
+ * License in all respects for all of the code used other than "OpenSSL". If you
+ * modify file(s), you may extend this exception to your version of the file(s),
+ * but you are not obligated to do so. If you do not wish to do so, delete this
+ * exception statement from your version.
+ */
+
+#pragma once
+
+#include
+
+#include "base/path.h"
+#include "torrentcontentremoveoption.h"
+
+namespace BitTorrent
+{
+ class TorrentContentRemover final : public QObject
+ {
+ Q_OBJECT
+ Q_DISABLE_COPY_MOVE(TorrentContentRemover)
+
+ public:
+ using QObject::QObject;
+
+ public slots:
+ void performJob(const QString &torrentName, const Path &basePath
+ , const PathList &fileNames, TorrentContentRemoveOption option);
+
+ signals:
+ void jobFinished(const QString &torrentName, const QString &errorMessage);
+ };
+}
diff --git a/src/base/bittorrent/torrentcreator.cpp b/src/base/bittorrent/torrentcreator.cpp
index 3cd26ba7c..727e9a9dc 100644
--- a/src/base/bittorrent/torrentcreator.cpp
+++ b/src/base/bittorrent/torrentcreator.cpp
@@ -36,6 +36,7 @@
#include
#include
+#include
#include
#include
#include
@@ -123,7 +124,14 @@ void TorrentCreator::run()
// need to sort the file names by natural sort order
QStringList dirs = {m_params.sourcePath.data()};
- QDirIterator dirIter {m_params.sourcePath.data(), (QDir::AllDirs | QDir::NoDotAndDotDot), QDirIterator::Subdirectories};
+#ifdef Q_OS_WIN
+ // libtorrent couldn't handle .lnk files on Windows
+ // Also, Windows users do not expect torrent creator to traverse into .lnk files so skip over them
+ const QDir::Filters dirFilters {QDir::AllDirs | QDir::NoDotAndDotDot | QDir::NoSymLinks};
+#else
+ const QDir::Filters dirFilters {QDir::AllDirs | QDir::NoDotAndDotDot};
+#endif
+ QDirIterator dirIter {m_params.sourcePath.data(), dirFilters, QDirIterator::Subdirectories};
while (dirIter.hasNext())
{
const QString filePath = dirIter.next();
@@ -138,7 +146,12 @@ void TorrentCreator::run()
{
QStringList tmpNames; // natural sort files within each dir
- QDirIterator fileIter {dir, QDir::Files};
+#ifdef Q_OS_WIN
+ const QDir::Filters fileFilters {QDir::Files | QDir::NoSymLinks};
+#else
+ const QDir::Filters fileFilters {QDir::Files};
+#endif
+ QDirIterator fileIter {dir, fileFilters};
while (fileIter.hasNext())
{
const QFileInfo fileInfo = fileIter.nextFileInfo();
diff --git a/src/base/bittorrent/torrentdescriptor.cpp b/src/base/bittorrent/torrentdescriptor.cpp
index bc5a4619a..072cf3e8d 100644
--- a/src/base/bittorrent/torrentdescriptor.cpp
+++ b/src/base/bittorrent/torrentdescriptor.cpp
@@ -1,6 +1,6 @@
/*
* Bittorrent Client using Qt and libtorrent.
- * Copyright (C) 2015-2023 Vladimir Golovnev
+ * Copyright (C) 2015-2024 Vladimir Golovnev
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -35,9 +35,7 @@
#include
#include
-#include
#include
-#include
#include
#include "base/global.h"
@@ -147,7 +145,13 @@ BitTorrent::TorrentDescriptor::TorrentDescriptor(lt::add_torrent_params ltAddTor
: m_ltAddTorrentParams {std::move(ltAddTorrentParams)}
{
if (m_ltAddTorrentParams.ti && m_ltAddTorrentParams.ti->is_valid())
+ {
m_info.emplace(*m_ltAddTorrentParams.ti);
+ if (m_ltAddTorrentParams.ti->creation_date() > 0)
+ m_creationDate = QDateTime::fromSecsSinceEpoch(m_ltAddTorrentParams.ti->creation_date());
+ m_creator = QString::fromStdString(m_ltAddTorrentParams.ti->creator());
+ m_comment = QString::fromStdString(m_ltAddTorrentParams.ti->comment());
+ }
}
BitTorrent::InfoHash BitTorrent::TorrentDescriptor::infoHash() const
@@ -166,18 +170,17 @@ QString BitTorrent::TorrentDescriptor::name() const
QDateTime BitTorrent::TorrentDescriptor::creationDate() const
{
- return ((m_ltAddTorrentParams.ti->creation_date() != 0)
- ? QDateTime::fromSecsSinceEpoch(m_ltAddTorrentParams.ti->creation_date()) : QDateTime());
+ return m_creationDate;
}
QString BitTorrent::TorrentDescriptor::creator() const
{
- return QString::fromStdString(m_ltAddTorrentParams.ti->creator());
+ return m_creator;
}
QString BitTorrent::TorrentDescriptor::comment() const
{
- return QString::fromStdString(m_ltAddTorrentParams.ti->comment());
+ return m_comment;
}
const std::optional &BitTorrent::TorrentDescriptor::info() const
diff --git a/src/base/bittorrent/torrentdescriptor.h b/src/base/bittorrent/torrentdescriptor.h
index 86f9059c3..a1c0e13dc 100644
--- a/src/base/bittorrent/torrentdescriptor.h
+++ b/src/base/bittorrent/torrentdescriptor.h
@@ -33,7 +33,9 @@
#include
#include
+#include
#include
+#include
#include "base/3rdparty/expected.hpp"
#include "base/path.h"
@@ -41,8 +43,6 @@
#include "torrentinfo.h"
class QByteArray;
-class QDateTime;
-class QString;
class QUrl;
namespace BitTorrent
@@ -78,6 +78,9 @@ namespace BitTorrent
lt::add_torrent_params m_ltAddTorrentParams;
std::optional m_info;
+ QDateTime m_creationDate;
+ QString m_creator;
+ QString m_comment;
};
}
diff --git a/src/base/bittorrent/torrentimpl.cpp b/src/base/bittorrent/torrentimpl.cpp
index 4cc41c084..f5a42142d 100644
--- a/src/base/bittorrent/torrentimpl.cpp
+++ b/src/base/bittorrent/torrentimpl.cpp
@@ -49,6 +49,7 @@
#include
#include
+#include
#include
#include
#include
@@ -77,6 +78,10 @@
#include "base/utils/os.h"
#endif // Q_OS_MACOS || Q_OS_WIN
+#ifndef QBT_USES_LIBTORRENT2
+#include "customstorage.h"
+#endif
+
using namespace BitTorrent;
namespace
@@ -88,37 +93,28 @@ namespace
return entry;
}
- QDateTime fromLTTimePoint32(const lt::time_point32 &timePoint)
- {
- const auto ltNow = lt::clock_type::now();
- const auto qNow = QDateTime::currentDateTime();
- const auto secsSinceNow = lt::duration_cast(timePoint - ltNow + lt::milliseconds(500)).count();
-
- return qNow.addSecs(secsSinceNow);
- }
-
QString toString(const lt::tcp::endpoint <TCPEndpoint)
{
- return QString::fromStdString((std::stringstream() << ltTCPEndpoint).str());
+ static QCache cache;
+
+ if (const QString *endpointName = cache.object(ltTCPEndpoint))
+ return *endpointName;
+
+ const std::string tmp = (std::ostringstream() << ltTCPEndpoint).str();
+ const auto endpointName = QString::fromLatin1(tmp.c_str(), tmp.size());
+ cache.insert(ltTCPEndpoint, new QString(endpointName));
+ return endpointName;
}
+ template
void updateTrackerEntryStatus(TrackerEntryStatus &trackerEntryStatus, const lt::announce_entry &nativeEntry
- , const QSet &btProtocols, const QHash> &updateInfo)
+ , const QSet &btProtocols, const QHash> &updateInfo
+ , const FromLTTimePoint32Func &fromLTTimePoint32)
{
Q_ASSERT(trackerEntryStatus.url == QString::fromStdString(nativeEntry.url));
trackerEntryStatus.tier = nativeEntry.tier;
- // remove outdated endpoints
- trackerEntryStatus.endpoints.removeIf([&nativeEntry](const QHash, TrackerEndpointStatus>::iterator &iter)
- {
- return std::none_of(nativeEntry.endpoints.cbegin(), nativeEntry.endpoints.cend()
- , [&endpointName = std::get<0>(iter.key())](const auto &existingEndpoint)
- {
- return (endpointName == toString(existingEndpoint.local_endpoint));
- });
- });
-
const auto numEndpoints = static_cast(nativeEntry.endpoints.size()) * btProtocols.size();
int numUpdating = 0;
@@ -201,6 +197,19 @@ namespace
}
}
+ if (trackerEntryStatus.endpoints.size() > numEndpoints)
+ {
+ // remove outdated endpoints
+ trackerEntryStatus.endpoints.removeIf([&nativeEntry](const QHash, TrackerEndpointStatus>::iterator &iter)
+ {
+ return std::none_of(nativeEntry.endpoints.cbegin(), nativeEntry.endpoints.cend()
+ , [&endpointName = std::get<0>(iter.key())](const auto &existingEndpoint)
+ {
+ return (endpointName == toString(existingEndpoint.local_endpoint));
+ });
+ });
+ }
+
if (numEndpoints > 0)
{
if (numUpdating > 0)
@@ -313,6 +322,11 @@ TorrentImpl::TorrentImpl(SessionImpl *session, lt::session *nativeSession
{
if (m_ltAddTorrentParams.ti)
{
+ if (const std::time_t creationDate = m_ltAddTorrentParams.ti->creation_date(); creationDate > 0)
+ m_creationDate = QDateTime::fromSecsSinceEpoch(creationDate);
+ m_creator = QString::fromStdString(m_ltAddTorrentParams.ti->creator());
+ m_comment = QString::fromStdString(m_ltAddTorrentParams.ti->comment());
+
// Initialize it only if torrent is added with metadata.
// Otherwise it should be initialized in "Metadata received" handler.
m_torrentInfo = TorrentInfo(*m_ltAddTorrentParams.ti);
@@ -356,6 +370,12 @@ TorrentImpl::TorrentImpl(SessionImpl *session, lt::session *nativeSession
m_urlSeeds.append(QString::fromStdString(urlSeed));
m_nativeStatus = extensionData->status;
+ m_addedTime = QDateTime::fromSecsSinceEpoch(m_nativeStatus.added_time);
+ if (m_nativeStatus.completed_time > 0)
+ m_completedTime = QDateTime::fromSecsSinceEpoch(m_nativeStatus.completed_time);
+ if (m_nativeStatus.last_seen_complete > 0)
+ m_lastSeenComplete = QDateTime::fromSecsSinceEpoch(m_nativeStatus.last_seen_complete);
+
if (hasMetadata())
updateProgress();
@@ -399,17 +419,17 @@ QString TorrentImpl::name() const
QDateTime TorrentImpl::creationDate() const
{
- return m_torrentInfo.creationDate();
+ return m_creationDate;
}
QString TorrentImpl::creator() const
{
- return m_torrentInfo.creator();
+ return m_creator;
}
QString TorrentImpl::comment() const
{
- return m_torrentInfo.comment();
+ return m_comment;
}
bool TorrentImpl::isPrivate() const
@@ -456,6 +476,8 @@ Path TorrentImpl::savePath() const
void TorrentImpl::setSavePath(const Path &path)
{
Q_ASSERT(!isAutoTMMEnabled());
+ if (isAutoTMMEnabled()) [[unlikely]]
+ return;
const Path basePath = m_session->useCategoryPathsInManualMode()
? m_session->categorySavePath(category()) : m_session->savePath();
@@ -483,6 +505,8 @@ Path TorrentImpl::downloadPath() const
void TorrentImpl::setDownloadPath(const Path &path)
{
Q_ASSERT(!isAutoTMMEnabled());
+ if (isAutoTMMEnabled()) [[unlikely]]
+ return;
const Path basePath = m_session->useCategoryPathsInManualMode()
? m_session->categoryDownloadPath(category()) : m_session->downloadPath();
@@ -934,7 +958,52 @@ void TorrentImpl::removeAllTags()
QDateTime TorrentImpl::addedTime() const
{
- return QDateTime::fromSecsSinceEpoch(m_nativeStatus.added_time);
+ return m_addedTime;
+}
+
+QDateTime TorrentImpl::completedTime() const
+{
+ return m_completedTime;
+}
+
+QDateTime TorrentImpl::lastSeenComplete() const
+{
+ return m_lastSeenComplete;
+}
+
+qlonglong TorrentImpl::activeTime() const
+{
+ return lt::total_seconds(m_nativeStatus.active_duration);
+}
+
+qlonglong TorrentImpl::finishedTime() const
+{
+ return lt::total_seconds(m_nativeStatus.finished_duration);
+}
+
+qlonglong TorrentImpl::timeSinceUpload() const
+{
+ if (m_nativeStatus.last_upload.time_since_epoch().count() == 0)
+ return -1;
+
+ return lt::total_seconds(lt::clock_type::now() - m_nativeStatus.last_upload);
+}
+
+qlonglong TorrentImpl::timeSinceDownload() const
+{
+ if (m_nativeStatus.last_download.time_since_epoch().count() == 0)
+ return -1;
+
+ return lt::total_seconds(lt::clock_type::now() - m_nativeStatus.last_download);
+}
+
+qlonglong TorrentImpl::timeSinceActivity() const
+{
+ const qlonglong upTime = timeSinceUpload();
+ const qlonglong downTime = timeSinceDownload();
+ return ((upTime < 0) != (downTime < 0))
+ ? std::max(upTime, downTime)
+ : std::min(upTime, downTime);
}
qreal TorrentImpl::ratioLimit() const
@@ -982,6 +1051,21 @@ PathList TorrentImpl::filePaths() const
return m_filePaths;
}
+PathList TorrentImpl::actualFilePaths() const
+{
+ if (!hasMetadata())
+ return {};
+
+ PathList paths;
+ paths.reserve(filesCount());
+
+ const lt::file_storage files = nativeTorrentInfo()->files();
+ for (const lt::file_index_t &nativeIndex : asConst(m_torrentInfo.nativeIndexes()))
+ paths.emplaceBack(files.file_path(nativeIndex));
+
+ return paths;
+}
+
QVector TorrentImpl::filePriorities() const
{
return m_filePriorities;
@@ -1238,16 +1322,6 @@ qlonglong TorrentImpl::totalUpload() const
return m_nativeStatus.all_time_upload;
}
-qlonglong TorrentImpl::activeTime() const
-{
- return lt::total_seconds(m_nativeStatus.active_duration);
-}
-
-qlonglong TorrentImpl::finishedTime() const
-{
- return lt::total_seconds(m_nativeStatus.finished_duration);
-}
-
qlonglong TorrentImpl::eta() const
{
if (isStopped()) return MAX_ETA;
@@ -1357,45 +1431,6 @@ int TorrentImpl::totalLeechersCount() const
return (m_nativeStatus.num_incomplete > -1) ? m_nativeStatus.num_incomplete : (m_nativeStatus.list_peers - m_nativeStatus.list_seeds);
}
-QDateTime TorrentImpl::lastSeenComplete() const
-{
- if (m_nativeStatus.last_seen_complete > 0)
- return QDateTime::fromSecsSinceEpoch(m_nativeStatus.last_seen_complete);
- else
- return {};
-}
-
-QDateTime TorrentImpl::completedTime() const
-{
- if (m_nativeStatus.completed_time > 0)
- return QDateTime::fromSecsSinceEpoch(m_nativeStatus.completed_time);
- else
- return {};
-}
-
-qlonglong TorrentImpl::timeSinceUpload() const
-{
- if (m_nativeStatus.last_upload.time_since_epoch().count() == 0)
- return -1;
- return lt::total_seconds(lt::clock_type::now() - m_nativeStatus.last_upload);
-}
-
-qlonglong TorrentImpl::timeSinceDownload() const
-{
- if (m_nativeStatus.last_download.time_since_epoch().count() == 0)
- return -1;
- return lt::total_seconds(lt::clock_type::now() - m_nativeStatus.last_download);
-}
-
-qlonglong TorrentImpl::timeSinceActivity() const
-{
- const qlonglong upTime = timeSinceUpload();
- const qlonglong downTime = timeSinceDownload();
- return ((upTime < 0) != (downTime < 0))
- ? std::max(upTime, downTime)
- : std::min(upTime, downTime);
-}
-
int TorrentImpl::downloadLimit() const
{
return m_downloadLimit;;
@@ -1447,11 +1482,13 @@ QBitArray TorrentImpl::pieces() const
QBitArray TorrentImpl::downloadingPieces() const
{
- QBitArray result(piecesCount());
+ if (!hasMetadata())
+ return {};
std::vector queue;
m_nativeHandle.get_download_queue(queue);
+ QBitArray result {piecesCount()};
for (const lt::partial_piece_info &info : queue)
result.setBit(LT::toUnderlyingType(info.piece_index));
@@ -1607,9 +1644,19 @@ void TorrentImpl::forceRecheck()
return;
m_nativeHandle.force_recheck();
+
// We have to force update the cached state, otherwise someone will be able to get
// an incorrect one during the interval until the cached state is updated in a regular way.
m_nativeStatus.state = lt::torrent_status::checking_resume_data;
+ m_nativeStatus.pieces.clear_all();
+ m_nativeStatus.num_pieces = 0;
+ m_ltAddTorrentParams.have_pieces.clear();
+ m_ltAddTorrentParams.verified_pieces.clear();
+ m_ltAddTorrentParams.unfinished_pieces.clear();
+ m_completedFiles.fill(false);
+ m_filesProgress.fill(0);
+ m_pieces.fill(false);
+ m_unchecked = false;
if (m_hasMissingFiles)
{
@@ -1622,14 +1669,6 @@ void TorrentImpl::forceRecheck()
}
}
- m_unchecked = false;
-
- m_completedFiles.fill(false);
- m_filesProgress.fill(0);
- m_pieces.fill(false);
- m_nativeStatus.pieces.clear_all();
- m_nativeStatus.num_pieces = 0;
-
if (isStopped())
{
// When "force recheck" is applied on Stopped torrent, we start them to perform checking
@@ -1734,7 +1773,13 @@ TrackerEntryStatus TorrentImpl::updateTrackerEntryStatus(const lt::announce_entr
#else
const QSet btProtocols {1};
#endif
- ::updateTrackerEntryStatus(*it, announceEntry, btProtocols, updateInfo);
+
+ const auto fromLTTimePoint32 = [this](const lt::time_point32 &timePoint)
+ {
+ return m_session->fromLTTimePoint32(timePoint);
+ };
+ ::updateTrackerEntryStatus(*it, announceEntry, btProtocols, updateInfo, fromLTTimePoint32);
+
return *it;
}
@@ -1791,12 +1836,13 @@ void TorrentImpl::endReceivedMetadataHandling(const Path &savePath, const PathLi
const Path filePath = actualFilePath.removedExtension(QB_EXT);
m_filePaths.append(filePath);
- lt::download_priority_t &nativePriority = p.file_priorities[LT::toUnderlyingType(nativeIndex)];
- if ((nativePriority != lt::dont_download) && m_session->isFilenameExcluded(filePath.filename()))
- nativePriority = lt::dont_download;
- const auto priority = LT::fromNative(nativePriority);
- m_filePriorities.append(priority);
+ m_filePriorities.append(LT::fromNative(p.file_priorities[LT::toUnderlyingType(nativeIndex)]));
}
+
+ m_session->applyFilenameFilter(m_filePaths, m_filePriorities);
+ for (int i = 0; i < m_filePriorities.size(); ++i)
+ p.file_priorities[LT::toUnderlyingType(nativeIndexes[i])] = LT::toNative(m_filePriorities[i]);
+
p.save_path = savePath.toString().toStdString();
p.ti = metadata;
@@ -1859,6 +1905,9 @@ void TorrentImpl::reload()
auto *const extensionData = new ExtensionData;
p.userdata = LTClientData(extensionData);
+#ifndef QBT_USES_LIBTORRENT2
+ p.storage = customStorageConstructor;
+#endif
m_nativeHandle = m_nativeSession->add_torrent(p);
m_nativeStatus = extensionData->status;
@@ -1933,8 +1982,17 @@ void TorrentImpl::moveStorage(const Path &newPath, const MoveStorageContext cont
{
if (!hasMetadata())
{
- m_savePath = newPath;
- m_session->handleTorrentSavePathChanged(this);
+ if (context == MoveStorageContext::ChangeSavePath)
+ {
+ m_savePath = newPath;
+ m_session->handleTorrentSavePathChanged(this);
+ }
+ else if (context == MoveStorageContext::ChangeDownloadPath)
+ {
+ m_downloadPath = newPath;
+ m_session->handleTorrentSavePathChanged(this);
+ }
+
return;
}
@@ -2104,6 +2162,7 @@ void TorrentImpl::handleSaveResumeDataAlert(const lt::save_resume_data_alert *p)
m_ltAddTorrentParams.have_pieces.clear();
m_ltAddTorrentParams.verified_pieces.clear();
+ m_ltAddTorrentParams.unfinished_pieces.clear();
m_nativeStatus.torrent_file = m_ltAddTorrentParams.ti;
@@ -2146,23 +2205,37 @@ void TorrentImpl::handleSaveResumeDataAlert(const lt::save_resume_data_alert *p)
void TorrentImpl::prepareResumeData(const lt::add_torrent_params ¶ms)
{
- if (m_hasMissingFiles)
{
- const auto havePieces = m_ltAddTorrentParams.have_pieces;
- const auto unfinishedPieces = m_ltAddTorrentParams.unfinished_pieces;
- const auto verifiedPieces = m_ltAddTorrentParams.verified_pieces;
+ decltype(params.have_pieces) havePieces;
+ decltype(params.unfinished_pieces) unfinishedPieces;
+ decltype(params.verified_pieces) verifiedPieces;
+
+ // The resume data obtained from libtorrent contains an empty "progress" in the following cases:
+ // 1. when it was requested at a time when the initial resume data has not yet been checked,
+ // 2. when initial resume data was rejected
+ // We should preserve the initial "progress" in such cases.
+ const bool needPreserveProgress = m_hasMissingFiles
+ || (!m_ltAddTorrentParams.have_pieces.empty() && params.have_pieces.empty());
+ const bool preserveSeedMode = !m_hasMissingFiles && !hasMetadata()
+ && (m_ltAddTorrentParams.flags & lt::torrent_flags::seed_mode);
+
+ if (needPreserveProgress)
+ {
+ havePieces = std::move(m_ltAddTorrentParams.have_pieces);
+ unfinishedPieces = std::move(m_ltAddTorrentParams.unfinished_pieces);
+ verifiedPieces = std::move(m_ltAddTorrentParams.verified_pieces);
+ }
- // Update recent resume data but preserve existing progress
- m_ltAddTorrentParams = params;
- m_ltAddTorrentParams.have_pieces = havePieces;
- m_ltAddTorrentParams.unfinished_pieces = unfinishedPieces;
- m_ltAddTorrentParams.verified_pieces = verifiedPieces;
- }
- else
- {
- const bool preserveSeedMode = (!hasMetadata() && (m_ltAddTorrentParams.flags & lt::torrent_flags::seed_mode));
// Update recent resume data
m_ltAddTorrentParams = params;
+
+ if (needPreserveProgress)
+ {
+ m_ltAddTorrentParams.have_pieces = std::move(havePieces);
+ m_ltAddTorrentParams.unfinished_pieces = std::move(unfinishedPieces);
+ m_ltAddTorrentParams.verified_pieces = std::move(verifiedPieces);
+ }
+
if (preserveSeedMode)
m_ltAddTorrentParams.flags |= lt::torrent_flags::seed_mode;
}
@@ -2312,7 +2385,8 @@ void TorrentImpl::handleFileCompletedAlert(const lt::file_completed_alert *p)
#if defined(Q_OS_MACOS) || defined(Q_OS_WIN)
// only apply Mark-of-the-Web to new download files
- if (Preferences::instance()->isMarkOfTheWebEnabled() && isDownloading())
+ if (Preferences::instance()->isMarkOfTheWebEnabled()
+ && (m_nativeStatus.state == lt::torrent_status::downloading))
{
const Path fullpath = actualStorageLocation() / actualPath;
Utils::OS::applyMarkOfTheWeb(fullpath);
@@ -2558,11 +2632,23 @@ bool TorrentImpl::isMoveInProgress() const
void TorrentImpl::updateStatus(const lt::torrent_status &nativeStatus)
{
+ // Since libtorrent alerts are handled asynchronously there can be obsolete
+ // "state update" event reached here after torrent was reloaded in libtorrent.
+ // Just discard such events.
+ if (nativeStatus.handle != m_nativeHandle) [[unlikely]]
+ return;
+
const lt::torrent_status oldStatus = std::exchange(m_nativeStatus, nativeStatus);
if (m_nativeStatus.num_pieces != oldStatus.num_pieces)
updateProgress();
+ if (m_nativeStatus.completed_time != oldStatus.completed_time)
+ m_completedTime = (m_nativeStatus.completed_time > 0) ? QDateTime::fromSecsSinceEpoch(m_nativeStatus.completed_time) : QDateTime();
+
+ if (m_nativeStatus.last_seen_complete != oldStatus.last_seen_complete)
+ m_lastSeenComplete = QDateTime::fromSecsSinceEpoch(m_nativeStatus.last_seen_complete);
+
updateState();
m_payloadRateMonitor.addSample({nativeStatus.download_payload_rate
diff --git a/src/base/bittorrent/torrentimpl.h b/src/base/bittorrent/torrentimpl.h
index 54b84c1f4..f968642c7 100644
--- a/src/base/bittorrent/torrentimpl.h
+++ b/src/base/bittorrent/torrentimpl.h
@@ -138,7 +138,15 @@ namespace BitTorrent
int piecesCount() const override;
int piecesHave() const override;
qreal progress() const override;
+
QDateTime addedTime() const override;
+ QDateTime completedTime() const override;
+ QDateTime lastSeenComplete() const override;
+ qlonglong activeTime() const override;
+ qlonglong finishedTime() const override;
+ qlonglong timeSinceUpload() const override;
+ qlonglong timeSinceDownload() const override;
+ qlonglong timeSinceActivity() const override;
qreal ratioLimit() const override;
void setRatioLimit(qreal limit) override;
@@ -153,6 +161,7 @@ namespace BitTorrent
Path actualFilePath(int index) const override;
qlonglong fileSize(int index) const override;
PathList filePaths() const override;
+ PathList actualFilePaths() const override;
QVector filePriorities() const override;
TorrentInfo info() const override;
@@ -180,8 +189,6 @@ namespace BitTorrent
QString error() const override;
qlonglong totalDownload() const override;
qlonglong totalUpload() const override;
- qlonglong activeTime() const override;
- qlonglong finishedTime() const override;
qlonglong eta() const override;
QVector filesProgress() const override;
int seedsCount() const override;
@@ -190,11 +197,6 @@ namespace BitTorrent
int totalSeedsCount() const override;
int totalPeersCount() const override;
int totalLeechersCount() const override;
- QDateTime lastSeenComplete() const override;
- QDateTime completedTime() const override;
- qlonglong timeSinceUpload() const override;
- qlonglong timeSinceDownload() const override;
- qlonglong timeSinceActivity() const override;
int downloadLimit() const override;
int uploadLimit() const override;
bool superSeeding() const override;
@@ -341,6 +343,14 @@ namespace BitTorrent
InfoHash m_infoHash;
+ QDateTime m_creationDate;
+ QString m_creator;
+ QString m_comment;
+
+ QDateTime m_addedTime;
+ QDateTime m_completedTime;
+ QDateTime m_lastSeenComplete;
+
// m_moveFinishedTriggers is activated only when the following conditions are met:
// all file rename jobs complete, all file move jobs complete
QQueue m_moveFinishedTriggers;
diff --git a/src/base/http/connection.cpp b/src/base/http/connection.cpp
index 4a96295e4..32a7ce840 100644
--- a/src/base/http/connection.cpp
+++ b/src/base/http/connection.cpp
@@ -44,6 +44,7 @@ Connection::Connection(QTcpSocket *socket, IRequestHandler *requestHandler, QObj
, m_requestHandler(requestHandler)
{
m_socket->setParent(this);
+ connect(m_socket, &QAbstractSocket::disconnected, this, &Connection::closed);
// reserve common size for requests, don't use the max allowed size which is too big for
// memory constrained platforms
@@ -62,11 +63,6 @@ Connection::Connection(QTcpSocket *socket, IRequestHandler *requestHandler, QObj
});
}
-Connection::~Connection()
-{
- m_socket->close();
-}
-
void Connection::read()
{
// reuse existing buffer and avoid unnecessary memory allocation/relocation
@@ -182,11 +178,6 @@ bool Connection::hasExpired(const qint64 timeout) const
&& m_idleTimer.hasExpired(timeout);
}
-bool Connection::isClosed() const
-{
- return (m_socket->state() == QAbstractSocket::UnconnectedState);
-}
-
bool Connection::acceptsGzipEncoding(QString codings)
{
// [rfc7231] 5.3.4. Accept-Encoding
diff --git a/src/base/http/connection.h b/src/base/http/connection.h
index 5b8f67a78..46a263106 100644
--- a/src/base/http/connection.h
+++ b/src/base/http/connection.h
@@ -47,10 +47,11 @@ namespace Http
public:
Connection(QTcpSocket *socket, IRequestHandler *requestHandler, QObject *parent = nullptr);
- ~Connection();
bool hasExpired(qint64 timeout) const;
- bool isClosed() const;
+
+ signals:
+ void closed();
private:
static bool acceptsGzipEncoding(QString codings);
diff --git a/src/base/http/server.cpp b/src/base/http/server.cpp
index 1e2320e11..19233dc27 100644
--- a/src/base/http/server.cpp
+++ b/src/base/http/server.cpp
@@ -32,7 +32,10 @@
#include
#include
+#include
+#include
+#include
#include
#include
#include
@@ -40,7 +43,6 @@
#include
#include
-#include "base/algorithm.h"
#include "base/global.h"
#include "base/utils/net.h"
#include "base/utils/sslkey.h"
@@ -113,32 +115,38 @@ Server::Server(IRequestHandler *requestHandler, QObject *parent)
void Server::incomingConnection(const qintptr socketDescriptor)
{
- if (m_connections.size() >= CONNECTIONS_LIMIT) return;
-
- QTcpSocket *serverSocket = nullptr;
- if (m_https)
- serverSocket = new QSslSocket(this);
- else
- serverSocket = new QTcpSocket(this);
-
+ std::unique_ptr serverSocket = m_https ? std::make_unique(this) : std::make_unique(this);
if (!serverSocket->setSocketDescriptor(socketDescriptor))
+ return;
+
+ if (m_connections.size() >= CONNECTIONS_LIMIT)
{
- delete serverSocket;
+ qWarning("Too many connections. Exceeded CONNECTIONS_LIMIT (%d). Connection closed.", CONNECTIONS_LIMIT);
return;
}
- if (m_https)
+ try
{
- static_cast(serverSocket)->setProtocol(QSsl::SecureProtocols);
- static_cast(serverSocket)->setPrivateKey(m_key);
- static_cast(serverSocket)->setLocalCertificateChain(m_certificates);
- static_cast(serverSocket)->setPeerVerifyMode(QSslSocket::VerifyNone);
- static_cast(serverSocket)->startServerEncryption();
- }
+ if (m_https)
+ {
+ auto *sslSocket = static_cast(serverSocket.get());
+ sslSocket->setProtocol(QSsl::SecureProtocols);
+ sslSocket->setPrivateKey(m_key);
+ sslSocket->setLocalCertificateChain(m_certificates);
+ sslSocket->setPeerVerifyMode(QSslSocket::VerifyNone);
+ sslSocket->startServerEncryption();
+ }
- auto *c = new Connection(serverSocket, m_requestHandler, this);
- m_connections.insert(c);
- connect(serverSocket, &QAbstractSocket::disconnected, this, [c, this]() { removeConnection(c); });
+ auto *connection = new Connection(serverSocket.release(), m_requestHandler, this);
+ m_connections.insert(connection);
+ connect(connection, &Connection::closed, this, [this, connection] { removeConnection(connection); });
+ }
+ catch (const std::bad_alloc &exception)
+ {
+ // drop the connection instead of throwing exception and crash
+ qWarning("Failed to allocate memory for HTTP connection. Connection closed.");
+ return;
+ }
}
void Server::removeConnection(Connection *connection)
diff --git a/src/base/net/downloadmanager.cpp b/src/base/net/downloadmanager.cpp
index 6b6eba17b..b84006f6f 100644
--- a/src/base/net/downloadmanager.cpp
+++ b/src/base/net/downloadmanager.cpp
@@ -148,10 +148,20 @@ Net::DownloadManager::DownloadManager(QObject *parent)
QStringList errorList;
for (const QSslError &error : errors)
errorList += error.errorString();
- LogMsg(tr("Ignoring SSL error, URL: \"%1\", errors: \"%2\"").arg(reply->url().toString(), errorList.join(u". ")), Log::WARNING);
- // Ignore all SSL errors
- reply->ignoreSslErrors();
+ QString errorMsg;
+ if (!Preferences::instance()->isIgnoreSSLErrors())
+ {
+ errorMsg = tr("SSL error, URL: \"%1\", errors: \"%2\"");
+ }
+ else
+ {
+ errorMsg = tr("Ignoring SSL error, URL: \"%1\", errors: \"%2\"");
+ // Ignore all SSL errors
+ reply->ignoreSslErrors();
+ }
+
+ LogMsg(errorMsg.arg(reply->url().toString(), errorList.join(u". ")), Log::WARNING);
});
connect(ProxyConfigurationManager::instance(), &ProxyConfigurationManager::proxyConfigurationChanged
diff --git a/src/base/net/smtp.h b/src/base/net/smtp.h
index 28c7cadeb..d58d8322b 100644
--- a/src/base/net/smtp.h
+++ b/src/base/net/smtp.h
@@ -43,7 +43,6 @@ class QSslSocket;
#else
class QTcpSocket;
#endif
-class QTextCodec;
namespace Net
{
diff --git a/src/base/preferences.cpp b/src/base/preferences.cpp
index 13c1c8b00..5b3fcb94e 100644
--- a/src/base/preferences.cpp
+++ b/src/base/preferences.cpp
@@ -134,17 +134,17 @@ void Preferences::setCustomUIThemePath(const Path &path)
setValue(u"Preferences/General/CustomUIThemePath"_s, path);
}
-bool Preferences::deleteTorrentFilesAsDefault() const
+bool Preferences::removeTorrentContent() const
{
return value(u"Preferences/General/DeleteTorrentsFilesAsDefault"_s, false);
}
-void Preferences::setDeleteTorrentFilesAsDefault(const bool del)
+void Preferences::setRemoveTorrentContent(const bool remove)
{
- if (del == deleteTorrentFilesAsDefault())
+ if (remove == removeTorrentContent())
return;
- setValue(u"Preferences/General/DeleteTorrentsFilesAsDefault"_s, del);
+ setValue(u"Preferences/General/DeleteTorrentsFilesAsDefault"_s, remove);
}
bool Preferences::confirmOnExit() const
@@ -429,6 +429,19 @@ void Preferences::setWinStartup(const bool b)
settings.remove(profileID);
}
}
+
+QString Preferences::getStyle() const
+{
+ return value(u"Appearance/Style"_s);
+}
+
+void Preferences::setStyle(const QString &styleName)
+{
+ if (styleName == getStyle())
+ return;
+
+ setValue(u"Appearance/Style"_s, styleName);
+}
#endif // Q_OS_WIN
// Downloads
@@ -1330,6 +1343,19 @@ void Preferences::setMarkOfTheWebEnabled(const bool enabled)
setValue(u"Preferences/Advanced/markOfTheWeb"_s, enabled);
}
+bool Preferences::isIgnoreSSLErrors() const
+{
+ return value(u"Preferences/Advanced/IgnoreSSLErrors"_s, false);
+}
+
+void Preferences::setIgnoreSSLErrors(const bool enabled)
+{
+ if (enabled == isIgnoreSSLErrors())
+ return;
+
+ setValue(u"Preferences/Advanced/IgnoreSSLErrors"_s, enabled);
+}
+
Path Preferences::getPythonExecutablePath() const
{
return value(u"Preferences/Search/pythonExecutablePath"_s, Path());
diff --git a/src/base/preferences.h b/src/base/preferences.h
index 90f26b055..a106ac7cf 100644
--- a/src/base/preferences.h
+++ b/src/base/preferences.h
@@ -105,8 +105,8 @@ public:
void setUseCustomUITheme(bool use);
Path customUIThemePath() const;
void setCustomUIThemePath(const Path &path);
- bool deleteTorrentFilesAsDefault() const;
- void setDeleteTorrentFilesAsDefault(bool del);
+ bool removeTorrentContent() const;
+ void setRemoveTorrentContent(bool remove);
bool confirmOnExit() const;
void setConfirmOnExit(bool confirm);
bool speedInTitleBar() const;
@@ -130,6 +130,8 @@ public:
#ifdef Q_OS_WIN
bool WinStartup() const;
void setWinStartup(bool b);
+ QString getStyle() const;
+ void setStyle(const QString &styleName);
#endif
// Downloads
@@ -293,6 +295,8 @@ public:
void setTrackerPortForwardingEnabled(bool enabled);
bool isMarkOfTheWebEnabled() const;
void setMarkOfTheWebEnabled(bool enabled);
+ bool isIgnoreSSLErrors() const;
+ void setIgnoreSSLErrors(bool enabled);
Path getPythonExecutablePath() const;
void setPythonExecutablePath(const Path &path);
#if defined(Q_OS_WIN) || defined(Q_OS_MACOS)
diff --git a/src/base/rss/rss_autodownloadrule.cpp b/src/base/rss/rss_autodownloadrule.cpp
index 3a8265c23..2960b984b 100644
--- a/src/base/rss/rss_autodownloadrule.cpp
+++ b/src/base/rss/rss_autodownloadrule.cpp
@@ -396,6 +396,8 @@ bool AutoDownloadRule::matchesSmartEpisodeFilter(const QString &articleTitle) co
m_dataPtr->lastComputedEpisodes.append(episodeStr + u"-REPACK");
m_dataPtr->lastComputedEpisodes.append(episodeStr + u"-PROPER");
}
+
+ return true;
}
m_dataPtr->lastComputedEpisodes.append(episodeStr);
diff --git a/src/base/rss/rss_parser.cpp b/src/base/rss/rss_parser.cpp
index 7c9acf4ca..f1cb2b65d 100644
--- a/src/base/rss/rss_parser.cpp
+++ b/src/base/rss/rss_parser.cpp
@@ -1,6 +1,6 @@
/*
* Bittorrent Client using Qt and libtorrent.
- * Copyright (C) 2015 Vladimir Golovnev
+ * Copyright (C) 2015-2024 Vladimir Golovnev
* Copyright (C) 2012 Christophe Dumez
*
* This program is free software; you can redistribute it and/or
@@ -29,11 +29,8 @@
#include "rss_parser.h"
-#include
#include
-#include
#include
-#include
#include
#include
#include
@@ -359,7 +356,7 @@ namespace
};
// Ported to Qt from KDElibs4
- QDateTime parseDate(const QString &string)
+ QDateTime parseDate(const QString &string, const QDateTime &fallbackDate)
{
const char16_t shortDay[][4] =
{
@@ -382,7 +379,7 @@ namespace
const QString str = string.trimmed();
if (str.isEmpty())
- return QDateTime::currentDateTime();
+ return fallbackDate;
int nyear = 6; // indexes within string to values
int nmonth = 4;
@@ -402,14 +399,14 @@ namespace
const bool h1 = (parts[3] == u"-");
const bool h2 = (parts[5] == u"-");
if (h1 != h2)
- return QDateTime::currentDateTime();
+ return fallbackDate;
}
else
{
// Check for the obsolete form "Wdy Mon DD HH:MM:SS YYYY"
rx = QRegularExpression {u"^([A-Z][a-z]+)\\s+(\\S+)\\s+(\\d\\d)\\s+(\\d\\d):(\\d\\d):(\\d\\d)\\s+(\\d\\d\\d\\d)$"_s};
if (str.indexOf(rx, 0, &rxMatch) != 0)
- return QDateTime::currentDateTime();
+ return fallbackDate;
nyear = 7;
nmonth = 2;
@@ -427,14 +424,14 @@ namespace
const int hour = parts[nhour].toInt(&ok[2]);
const int minute = parts[nmin].toInt(&ok[3]);
if (!ok[0] || !ok[1] || !ok[2] || !ok[3])
- return QDateTime::currentDateTime();
+ return fallbackDate;
int second = 0;
if (!parts[nsec].isEmpty())
{
second = parts[nsec].toInt(&ok[0]);
if (!ok[0])
- return QDateTime::currentDateTime();
+ return fallbackDate;
}
const bool leapSecond = (second == 60);
@@ -518,21 +515,21 @@ namespace
const QDate qDate(year, month + 1, day); // convert date, and check for out-of-range
if (!qDate.isValid())
- return QDateTime::currentDateTime();
+ return fallbackDate;
const QTime qTime(hour, minute, second);
QDateTime result(qDate, qTime, Qt::UTC);
if (offset)
result = result.addSecs(-offset);
if (!result.isValid())
- return QDateTime::currentDateTime(); // invalid date/time
+ return fallbackDate; // invalid date/time
if (leapSecond)
{
// Validate a leap second time. Leap seconds are inserted after 23:59:59 UTC.
// Convert the time to UTC and check that it is 00:00:00.
if ((hour*3600 + minute*60 + 60 - offset + 86400*5) % 86400) // (max abs(offset) is 100 hours)
- return QDateTime::currentDateTime(); // the time isn't the last second of the day
+ return fallbackDate; // the time isn't the last second of the day
}
return result;
@@ -550,6 +547,7 @@ RSS::Private::Parser::Parser(const QString &lastBuildDate)
void RSS::Private::Parser::parse(const QByteArray &feedData)
{
QXmlStreamReader xml {feedData};
+ m_fallbackDate = QDateTime::currentDateTime();
XmlStreamEntityResolver resolver;
xml.setEntityResolver(&resolver);
bool foundChannel = false;
@@ -641,7 +639,7 @@ void RSS::Private::Parser::parseRssArticle(QXmlStreamReader &xml)
}
else if (name == u"pubDate")
{
- article[Article::KeyDate] = parseDate(xml.readElementText().trimmed());
+ article[Article::KeyDate] = parseDate(xml.readElementText().trimmed(), m_fallbackDate);
}
else if (name == u"author")
{
@@ -755,7 +753,7 @@ void RSS::Private::Parser::parseAtomArticle(QXmlStreamReader &xml)
{
// ATOM uses standard compliant date, don't do fancy stuff
const QDateTime articleDate = QDateTime::fromString(xml.readElementText().trimmed(), Qt::ISODate);
- article[Article::KeyDate] = (articleDate.isValid() ? articleDate : QDateTime::currentDateTime());
+ article[Article::KeyDate] = (articleDate.isValid() ? articleDate : m_fallbackDate);
}
else if (name == u"author")
{
diff --git a/src/base/rss/rss_parser.h b/src/base/rss/rss_parser.h
index 7abfeeb2e..17d4a2464 100644
--- a/src/base/rss/rss_parser.h
+++ b/src/base/rss/rss_parser.h
@@ -1,6 +1,6 @@
/*
* Bittorrent Client using Qt and libtorrent.
- * Copyright (C) 2015 Vladimir Golovnev
+ * Copyright (C) 2015-2024 Vladimir Golovnev
* Copyright (C) 2012 Christophe Dumez
*
* This program is free software; you can redistribute it and/or
@@ -29,6 +29,7 @@
#pragma once
+#include
#include
#include
#include
@@ -66,6 +67,7 @@ namespace RSS::Private
void parseAtomChannel(QXmlStreamReader &xml);
void addArticle(QVariantHash article);
+ QDateTime m_fallbackDate;
QString m_baseUrl;
ParsingResult m_result;
QSet m_articleIDs;
diff --git a/src/base/torrentfilter.cpp b/src/base/torrentfilter.cpp
index 7ad8cf112..89d9a97e9 100644
--- a/src/base/torrentfilter.cpp
+++ b/src/base/torrentfilter.cpp
@@ -52,19 +52,21 @@ const TorrentFilter TorrentFilter::ErroredTorrent(TorrentFilter::Errored);
using BitTorrent::Torrent;
TorrentFilter::TorrentFilter(const Type type, const std::optional &idSet
- , const std::optional &category, const std::optional &tag)
+ , const std::optional &category, const std::optional &tag, const std::optional isPrivate)
: m_type {type}
, m_category {category}
, m_tag {tag}
, m_idSet {idSet}
+ , m_private {isPrivate}
{
}
TorrentFilter::TorrentFilter(const QString &filter, const std::optional &idSet
- , const std::optional &category, const std::optional &tag)
+ , const std::optional &category, const std::optional &tag, const std::optional isPrivate)
: m_category {category}
, m_tag {tag}
, m_idSet {idSet}
+ , m_private {isPrivate}
{
setTypeByName(filter);
}
@@ -147,11 +149,22 @@ bool TorrentFilter::setTag(const std::optional &tag)
return false;
}
+bool TorrentFilter::setPrivate(const std::optional isPrivate)
+{
+ if (m_private != isPrivate)
+ {
+ m_private = isPrivate;
+ return true;
+ }
+
+ return false;
+}
+
bool TorrentFilter::match(const Torrent *const torrent) const
{
if (!torrent) return false;
- return (matchState(torrent) && matchHash(torrent) && matchCategory(torrent) && matchTag(torrent));
+ return (matchState(torrent) && matchHash(torrent) && matchCategory(torrent) && matchTag(torrent) && matchPrivate(torrent));
}
bool TorrentFilter::matchState(const BitTorrent::Torrent *const torrent) const
@@ -224,3 +237,11 @@ bool TorrentFilter::matchTag(const BitTorrent::Torrent *const torrent) const
return torrent->hasTag(*m_tag);
}
+
+bool TorrentFilter::matchPrivate(const BitTorrent::Torrent *const torrent) const
+{
+ if (!m_private)
+ return true;
+
+ return m_private == torrent->isPrivate();
+}
diff --git a/src/base/torrentfilter.h b/src/base/torrentfilter.h
index 19092fb8e..39fd3e06f 100644
--- a/src/base/torrentfilter.h
+++ b/src/base/torrentfilter.h
@@ -87,16 +87,24 @@ public:
TorrentFilter() = default;
// category & tags: pass empty string for uncategorized / untagged torrents.
- TorrentFilter(Type type, const std::optional &idSet = AnyID
- , const std::optional &category = AnyCategory, const std::optional &tag = AnyTag);
- TorrentFilter(const QString &filter, const std::optional &idSet = AnyID
- , const std::optional &category = AnyCategory, const std::optional &tags = AnyTag);
+ TorrentFilter(Type type
+ , const std::optional &idSet = AnyID
+ , const std::optional &category = AnyCategory
+ , const std::optional &tag = AnyTag
+ , std::optional isPrivate = {});
+ TorrentFilter(const QString &filter
+ , const std::optional &idSet = AnyID
+ , const std::optional &category = AnyCategory
+ , const std::optional &tags = AnyTag
+ , std::optional isPrivate = {});
+
bool setType(Type type);
bool setTypeByName(const QString &filter);
bool setTorrentIDSet(const std::optional &idSet);
bool setCategory(const std::optional &category);
bool setTag(const std::optional &tag);
+ bool setPrivate(std::optional isPrivate);
bool match(const BitTorrent::Torrent *torrent) const;
@@ -105,9 +113,11 @@ private:
bool matchHash(const BitTorrent::Torrent *torrent) const;
bool matchCategory(const BitTorrent::Torrent *torrent) const;
bool matchTag(const BitTorrent::Torrent *torrent) const;
+ bool matchPrivate(const BitTorrent::Torrent *torrent) const;
Type m_type {All};
std::optional m_category;
std::optional m_tag;
std::optional m_idSet;
+ std::optional m_private;
};
diff --git a/src/base/utils/fs.cpp b/src/base/utils/fs.cpp
index 4d89f49a0..dbcfafb74 100644
--- a/src/base/utils/fs.cpp
+++ b/src/base/utils/fs.cpp
@@ -1,6 +1,6 @@
/*
* Bittorrent Client using Qt and libtorrent.
- * Copyright (C) 2022 Vladimir Golovnev
+ * Copyright (C) 2022-2024 Vladimir Golovnev
* Copyright (C) 2012 Christophe Dumez
*
* This program is free software; you can redistribute it and/or
@@ -29,8 +29,6 @@
#include "fs.h"
-#include
-#include
#include
#if defined(Q_OS_WIN)
@@ -52,6 +50,7 @@
#include
#endif
+#include
#include
#include
#include
@@ -311,20 +310,42 @@ bool Utils::Fs::renameFile(const Path &from, const Path &to)
*
* This function will try to fix the file permissions before removing it.
*/
-bool Utils::Fs::removeFile(const Path &path)
+nonstd::expected Utils::Fs::removeFile(const Path &path)
{
- if (QFile::remove(path.data()))
- return true;
-
QFile file {path.data()};
+ if (file.remove())
+ return {};
+
if (!file.exists())
- return true;
+ return {};
// Make sure we have read/write permissions
file.setPermissions(file.permissions() | QFile::ReadOwner | QFile::WriteOwner | QFile::ReadUser | QFile::WriteUser);
- return file.remove();
+ if (file.remove())
+ return {};
+
+ return nonstd::make_unexpected(file.errorString());
}
+nonstd::expected Utils::Fs::moveFileToTrash(const Path &path)
+{
+ QFile file {path.data()};
+ if (file.moveToTrash())
+ return {};
+
+ if (!file.exists())
+ return {};
+
+ // Make sure we have read/write permissions
+ file.setPermissions(file.permissions() | QFile::ReadOwner | QFile::WriteOwner | QFile::ReadUser | QFile::WriteUser);
+ if (file.moveToTrash())
+ return {};
+
+ const QString errorMessage = file.errorString();
+ return nonstd::make_unexpected(!errorMessage.isEmpty() ? errorMessage : QCoreApplication::translate("fs", "Unknown error"));
+}
+
+
bool Utils::Fs::isReadable(const Path &path)
{
return QFileInfo(path.data()).isReadable();
diff --git a/src/base/utils/fs.h b/src/base/utils/fs.h
index 3dccb1d2d..eced8b072 100644
--- a/src/base/utils/fs.h
+++ b/src/base/utils/fs.h
@@ -1,6 +1,6 @@
/*
* Bittorrent Client using Qt and libtorrent.
- * Copyright (C) 2022 Vladimir Golovnev
+ * Copyright (C) 2022-2024 Vladimir Golovnev
* Copyright (C) 2012 Christophe Dumez
*
* This program is free software; you can redistribute it and/or
@@ -35,6 +35,7 @@
#include
+#include "base/3rdparty/expected.hpp"
#include "base/global.h"
#include "base/pathfwd.h"
@@ -60,7 +61,8 @@ namespace Utils::Fs
bool copyFile(const Path &from, const Path &to);
bool renameFile(const Path &from, const Path &to);
- bool removeFile(const Path &path);
+ nonstd::expected removeFile(const Path &path);
+ nonstd::expected moveFileToTrash(const Path &path);
bool mkdir(const Path &dirPath);
bool mkpath(const Path &dirPath);
bool rmdir(const Path &dirPath);
diff --git a/src/base/utils/os.cpp b/src/base/utils/os.cpp
index 8bfd7d07e..c946cb698 100644
--- a/src/base/utils/os.cpp
+++ b/src/base/utils/os.cpp
@@ -31,6 +31,8 @@
#include "os.h"
#ifdef Q_OS_WIN
+#include
+
#include
#include
#include
@@ -42,6 +44,8 @@
#include
#endif // Q_OS_MACOS
+#include
+
#ifdef QBT_USES_DBUS
#include
#endif // QBT_USES_DBUS
@@ -271,6 +275,11 @@ Path Utils::OS::windowsSystemPath()
#if defined(Q_OS_MACOS) || defined(Q_OS_WIN)
bool Utils::OS::applyMarkOfTheWeb(const Path &file, const QString &url)
{
+ // Trying to apply this to a non-existent file is unacceptable,
+ // as it may unexpectedly create such a file.
+ if (!file.exists())
+ return false;
+
Q_ASSERT(url.isEmpty() || url.startsWith(u"http:") || url.startsWith(u"https:"));
#ifdef Q_OS_MACOS
@@ -278,34 +287,53 @@ bool Utils::OS::applyMarkOfTheWeb(const Path &file, const QString &url)
// https://searchfox.org/mozilla-central/rev/ffdc4971dc18e1141cb2a90c2b0b776365650270/xpcom/io/CocoaFileUtils.mm#230
// https://github.com/transmission/transmission/blob/f62f7427edb1fd5c430e0ef6956bbaa4f03ae597/macosx/Torrent.mm#L1945-L1955
+ const CFStringRef fileString = file.toString().toCFString();
+ [[maybe_unused]] const auto fileStringGuard = qScopeGuard([&fileString] { ::CFRelease(fileString); });
+ const CFURLRef fileURL = ::CFURLCreateWithFileSystemPath(kCFAllocatorDefault
+ , fileString, kCFURLPOSIXPathStyle, false);
+ [[maybe_unused]] const auto fileURLGuard = qScopeGuard([&fileURL] { ::CFRelease(fileURL); });
+
+ if (CFDictionaryRef currentProperties = nullptr;
+ ::CFURLCopyResourcePropertyForKey(fileURL, kCFURLQuarantinePropertiesKey, ¤tProperties, NULL)
+ && currentProperties)
+ {
+ [[maybe_unused]] const auto currentPropertiesGuard = qScopeGuard([¤tProperties] { ::CFRelease(currentProperties); });
+
+ if (CFStringRef quarantineType = nullptr;
+ ::CFDictionaryGetValueIfPresent(currentProperties, kLSQuarantineTypeKey, reinterpret_cast(&quarantineType))
+ && quarantineType)
+ {
+ if (::CFStringCompare(quarantineType, kLSQuarantineTypeOtherDownload, 0) == kCFCompareEqualTo)
+ return true;
+ }
+ }
+
CFMutableDictionaryRef properties = ::CFDictionaryCreateMutable(kCFAllocatorDefault, 0
, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
- if (properties == NULL)
+ if (!properties)
return false;
+ [[maybe_unused]] const auto propertiesGuard = qScopeGuard([&properties] { ::CFRelease(properties); });
::CFDictionarySetValue(properties, kLSQuarantineTypeKey, kLSQuarantineTypeOtherDownload);
if (!url.isEmpty())
- ::CFDictionarySetValue(properties, kLSQuarantineDataURLKey, url.toCFString());
-
- const CFStringRef fileString = file.toString().toCFString();
- const CFURLRef fileURL = ::CFURLCreateWithFileSystemPath(kCFAllocatorDefault
- , fileString, kCFURLPOSIXPathStyle, false);
+ {
+ 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);
-
- ::CFRelease(fileURL);
- ::CFRelease(fileString);
- ::CFRelease(properties);
-
return success;
#elif defined(Q_OS_WIN)
const QString zoneIDStream = file.toString() + u":Zone.Identifier";
- HANDLE handle = ::CreateFileW(zoneIDStream.toStdWString().c_str(), GENERIC_WRITE
+
+ HANDLE handle = ::CreateFileW(zoneIDStream.toStdWString().c_str(), (GENERIC_READ | GENERIC_WRITE)
, (FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE)
, nullptr, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, nullptr);
if (handle == INVALID_HANDLE_VALUE)
return false;
+ [[maybe_unused]] const auto handleGuard = qScopeGuard([&handle] { ::CloseHandle(handle); });
// 5.6.1 Zone.Identifier Stream Name
// https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-fscc/6e3f7352-d11c-4d76-8c39-2516a9df36e8
@@ -313,10 +341,27 @@ bool Utils::OS::applyMarkOfTheWeb(const Path &file, const QString &url)
const QByteArray zoneID = QByteArrayLiteral("[ZoneTransfer]\r\nZoneId=3\r\n")
+ u"HostUrl=%1\r\n"_s.arg(hostURL).toUtf8();
+ if (LARGE_INTEGER streamSize = {0};
+ ::GetFileSizeEx(handle, &streamSize) && (streamSize.QuadPart > 0))
+ {
+ const DWORD expectedReadSize = std::min(streamSize.QuadPart, 1024);
+ QByteArray buf {expectedReadSize, '\0'};
+
+ if (DWORD actualReadSize = 0;
+ ::ReadFile(handle, buf.data(), expectedReadSize, &actualReadSize, nullptr) && (actualReadSize == expectedReadSize))
+ {
+ if (buf.startsWith("[ZoneTransfer]\r\n") && buf.contains("\r\nZoneId=3\r\n") && buf.contains("\r\nHostUrl="))
+ return true;
+ }
+ }
+
+ if (!::SetFilePointerEx(handle, {0}, nullptr, FILE_BEGIN))
+ return false;
+ if (!::SetEndOfFile(handle))
+ return false;
+
DWORD written = 0;
const BOOL writeResult = ::WriteFile(handle, zoneID.constData(), zoneID.size(), &written, nullptr);
- ::CloseHandle(handle);
-
return writeResult && (written == zoneID.size());
#endif
}
diff --git a/src/base/version.h.in b/src/base/version.h.in
index 9e06e895b..151aa9a4d 100644
--- a/src/base/version.h.in
+++ b/src/base/version.h.in
@@ -30,9 +30,9 @@
#define QBT_VERSION_MAJOR 5
#define QBT_VERSION_MINOR 0
-#define QBT_VERSION_BUGFIX 0
+#define QBT_VERSION_BUGFIX 4
#define QBT_VERSION_BUILD 0
-#define QBT_VERSION_STATUS "beta1" // 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)
diff --git a/src/gui/CMakeLists.txt b/src/gui/CMakeLists.txt
index 1a426ed6e..9db94e77e 100644
--- a/src/gui/CMakeLists.txt
+++ b/src/gui/CMakeLists.txt
@@ -52,6 +52,8 @@ add_library(qbt_gui STATIC
desktopintegration.h
downloadfromurldialog.h
executionlogwidget.h
+ filterpatternformat.h
+ filterpatternformatmenu.h
flowlayout.h
fspathedit.h
fspathedit_p.h
@@ -151,6 +153,7 @@ add_library(qbt_gui STATIC
desktopintegration.cpp
downloadfromurldialog.cpp
executionlogwidget.cpp
+ filterpatternformatmenu.cpp
flowlayout.cpp
fspathedit.cpp
fspathedit_p.cpp
diff --git a/src/gui/aboutdialog.cpp b/src/gui/aboutdialog.cpp
index bc1be50a3..5a8976fed 100644
--- a/src/gui/aboutdialog.cpp
+++ b/src/gui/aboutdialog.cpp
@@ -67,7 +67,7 @@ AboutDialog::AboutDialog(QWidget *parent)
u"
"_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:"));
diff --git a/src/gui/addnewtorrentdialog.cpp b/src/gui/addnewtorrentdialog.cpp
index 99ecdda59..5417e6dbe 100644
--- a/src/gui/addnewtorrentdialog.cpp
+++ b/src/gui/addnewtorrentdialog.cpp
@@ -1,6 +1,6 @@
/*
* Bittorrent Client using Qt and libtorrent.
- * Copyright (C) 2022-2023 Vladimir Golovnev
+ * Copyright (C) 2022-2024 Vladimir Golovnev
* Copyright (C) 2012 Christophe Dumez
*
* This program is free software; you can redistribute it and/or
@@ -64,6 +64,7 @@
#include "base/utils/fs.h"
#include "base/utils/misc.h"
#include "base/utils/string.h"
+#include "filterpatternformatmenu.h"
#include "lineedit.h"
#include "torrenttagsdialog.h"
@@ -181,6 +182,11 @@ public:
return (m_filePaths.isEmpty() ? m_torrentInfo.filePath(index) : m_filePaths.at(index));
}
+ PathList filePaths() const
+ {
+ return (m_filePaths.isEmpty() ? m_torrentInfo.filePaths() : m_filePaths);
+ }
+
void renameFile(const int index, const Path &newFilePath) override
{
Q_ASSERT((index >= 0) && (index < filesCount()));
@@ -290,6 +296,7 @@ AddNewTorrentDialog::AddNewTorrentDialog(const BitTorrent::TorrentDescriptor &to
, m_storeRememberLastSavePath {SETTINGS_KEY(u"RememberLastSavePath"_s)}
, m_storeTreeHeaderState {u"GUI/Qt6/" SETTINGS_KEY(u"TreeHeaderState"_s)}
, m_storeSplitterState {u"GUI/Qt6/" SETTINGS_KEY(u"SplitterState"_s)}
+ , m_storeFilterPatternFormat {u"GUI/" SETTINGS_KEY(u"FilterPatternFormat"_s)}
{
m_ui->setupUi(this);
@@ -316,6 +323,8 @@ AddNewTorrentDialog::AddNewTorrentDialog(const BitTorrent::TorrentDescriptor &to
// Torrent content filtering
m_filterLine->setPlaceholderText(tr("Filter files..."));
m_filterLine->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
+ m_filterLine->setContextMenuPolicy(Qt::CustomContextMenu);
+ connect(m_filterLine, &QWidget::customContextMenuRequested, this, &AddNewTorrentDialog::showContentFilterContextMenu);
m_ui->contentFilterLayout->insertWidget(3, m_filterLine);
const auto *focusSearchHotkey = new QShortcut(QKeySequence::Find, this);
connect(focusSearchHotkey, &QShortcut::activated, this, [this]()
@@ -360,7 +369,7 @@ AddNewTorrentDialog::AddNewTorrentDialog(const BitTorrent::TorrentDescriptor &to
});
dlg->open();
});
- connect(m_filterLine, &LineEdit::textChanged, m_ui->contentTreeView, &TorrentContentWidget::setFilterPattern);
+ connect(m_filterLine, &LineEdit::textChanged, this, &AddNewTorrentDialog::setContentFilterPattern);
connect(m_ui->buttonSelectAll, &QPushButton::clicked, m_ui->contentTreeView, &TorrentContentWidget::checkAll);
connect(m_ui->buttonSelectNone, &QPushButton::clicked, m_ui->contentTreeView, &TorrentContentWidget::checkNone);
connect(Preferences::instance(), &Preferences::changed, []
@@ -691,6 +700,28 @@ void AddNewTorrentDialog::saveTorrentFile()
}
}
+void AddNewTorrentDialog::showContentFilterContextMenu()
+{
+ QMenu *menu = m_filterLine->createStandardContextMenu();
+
+ auto *formatMenu = new FilterPatternFormatMenu(m_storeFilterPatternFormat.get(FilterPatternFormat::Wildcards), menu);
+ connect(formatMenu, &FilterPatternFormatMenu::patternFormatChanged, this, [this](const FilterPatternFormat format)
+ {
+ m_storeFilterPatternFormat = format;
+ setContentFilterPattern();
+ });
+
+ menu->addSeparator();
+ menu->addMenu(formatMenu);
+ menu->setAttribute(Qt::WA_DeleteOnClose);
+ menu->popup(QCursor::pos());
+}
+
+void AddNewTorrentDialog::setContentFilterPattern()
+{
+ m_ui->contentTreeView->setFilterPattern(m_filterLine->text(), m_storeFilterPatternFormat.get(FilterPatternFormat::Wildcards));
+}
+
void AddNewTorrentDialog::populateSavePaths()
{
Q_ASSERT(m_currentContext);
@@ -790,6 +821,8 @@ void AddNewTorrentDialog::reject()
if (!m_currentContext) [[unlikely]]
return;
+ emit torrentRejected(m_currentContext->torrentDescr);
+
const BitTorrent::TorrentDescriptor &torrentDescr = m_currentContext->torrentDescr;
const bool hasMetadata = torrentDescr.info().has_value();
if (!hasMetadata)
@@ -886,15 +919,7 @@ void AddNewTorrentDialog::setupTreeview()
{
// Check file name blacklist for torrents that are manually added
QVector priorities = m_contentAdaptor->filePriorities();
- for (int i = 0; i < priorities.size(); ++i)
- {
- if (priorities[i] == BitTorrent::DownloadPriority::Ignored)
- continue;
-
- if (BitTorrent::Session::instance()->isFilenameExcluded(torrentInfo.filePath(i).filename()))
- priorities[i] = BitTorrent::DownloadPriority::Ignored;
- }
-
+ BitTorrent::Session::instance()->applyFilenameFilter(m_contentAdaptor->filePaths(), priorities);
m_contentAdaptor->prioritizeFiles(priorities);
}
diff --git a/src/gui/addnewtorrentdialog.h b/src/gui/addnewtorrentdialog.h
index 1dd1eb1b1..bc530953b 100644
--- a/src/gui/addnewtorrentdialog.h
+++ b/src/gui/addnewtorrentdialog.h
@@ -1,6 +1,6 @@
/*
* Bittorrent Client using Qt and libtorrent.
- * Copyright (C) 2022-2023 Vladimir Golovnev
+ * Copyright (C) 2022-2024 Vladimir Golovnev
* Copyright (C) 2012 Christophe Dumez
*
* This program is free software; you can redistribute it and/or
@@ -35,6 +35,7 @@
#include "base/path.h"
#include "base/settingvalue.h"
+#include "filterpatternformat.h"
class LineEdit;
@@ -65,6 +66,7 @@ public:
signals:
void torrentAccepted(const BitTorrent::TorrentDescriptor &torrentDescriptor, const BitTorrent::AddTorrentParams &addTorrentParams);
+ void torrentRejected(const BitTorrent::TorrentDescriptor &torrentDescriptor);
private slots:
void updateDiskSpaceLabel();
@@ -92,6 +94,8 @@ private:
void setMetadataProgressIndicator(bool visibleIndicator, const QString &labelText = {});
void setupTreeview();
void saveTorrentFile();
+ void showContentFilterContextMenu();
+ void setContentFilterPattern();
Ui::AddNewTorrentDialog *m_ui = nullptr;
std::unique_ptr m_contentAdaptor;
@@ -107,4 +111,5 @@ private:
SettingValue m_storeRememberLastSavePath;
SettingValue m_storeTreeHeaderState;
SettingValue m_storeSplitterState;
+ SettingValue m_storeFilterPatternFormat;
};
diff --git a/src/gui/advancedsettings.cpp b/src/gui/advancedsettings.cpp
index d81cfecc6..53d50f468 100644
--- a/src/gui/advancedsettings.cpp
+++ b/src/gui/advancedsettings.cpp
@@ -63,6 +63,7 @@ namespace
// qBittorrent section
QBITTORRENT_HEADER,
RESUME_DATA_STORAGE,
+ TORRENT_CONTENT_REMOVE_OPTION,
#if defined(QBT_USES_LIBTORRENT2) && !defined(Q_OS_MACOS)
MEMORY_WORKING_SET_LIMIT,
#endif
@@ -104,6 +105,7 @@ namespace
#if defined(Q_OS_MACOS) || defined(Q_OS_WIN)
ENABLE_MARK_OF_THE_WEB,
#endif // Q_OS_MACOS || Q_OS_WIN
+ IGNORE_SSL_ERRORS,
PYTHON_EXECUTABLE_PATH,
START_SESSION_PAUSED,
SESSION_SHUTDOWN_TIMEOUT,
@@ -331,6 +333,8 @@ void AdvancedSettings::saveAdvancedSettings() const
// Mark-of-the-Web
pref->setMarkOfTheWebEnabled(m_checkBoxMarkOfTheWeb.isChecked());
#endif // Q_OS_MACOS || Q_OS_WIN
+ // Ignore SSL errors
+ pref->setIgnoreSSLErrors(m_checkBoxIgnoreSSLErrors.isChecked());
// Python executable path
pref->setPythonExecutablePath(Path(m_pythonExecutablePath.text().trimmed()));
// Start session paused
@@ -364,6 +368,8 @@ void AdvancedSettings::saveAdvancedSettings() const
session->setI2PInboundLength(m_spinBoxI2PInboundLength.value());
session->setI2POutboundLength(m_spinBoxI2POutboundLength.value());
#endif
+
+ session->setTorrentContentRemoveOption(m_comboBoxTorrentContentRemoveOption.currentData().value());
}
#ifndef QBT_USES_LIBTORRENT2
@@ -472,6 +478,11 @@ void AdvancedSettings::loadAdvancedSettings()
m_comboBoxResumeDataStorage.setCurrentIndex(m_comboBoxResumeDataStorage.findData(QVariant::fromValue(session->resumeDataStorageType())));
addRow(RESUME_DATA_STORAGE, tr("Resume data storage type (requires restart)"), &m_comboBoxResumeDataStorage);
+ m_comboBoxTorrentContentRemoveOption.addItem(tr("Delete files permanently"), QVariant::fromValue(BitTorrent::TorrentContentRemoveOption::Delete));
+ m_comboBoxTorrentContentRemoveOption.addItem(tr("Move files to trash (if possible)"), QVariant::fromValue(BitTorrent::TorrentContentRemoveOption::MoveToTrash));
+ m_comboBoxTorrentContentRemoveOption.setCurrentIndex(m_comboBoxTorrentContentRemoveOption.findData(QVariant::fromValue(session->torrentContentRemoveOption())));
+ addRow(TORRENT_CONTENT_REMOVE_OPTION, tr("Torrent content removing mode"), &m_comboBoxTorrentContentRemoveOption);
+
#if defined(QBT_USES_LIBTORRENT2) && !defined(Q_OS_MACOS)
// Physical memory (RAM) usage limit
m_spinBoxMemoryWorkingSetLimit.setMinimum(1);
@@ -577,6 +588,7 @@ void AdvancedSettings::loadAdvancedSettings()
m_comboBoxDiskIOType.addItem(tr("Default"), QVariant::fromValue(BitTorrent::DiskIOType::Default));
m_comboBoxDiskIOType.addItem(tr("Memory mapped files"), QVariant::fromValue(BitTorrent::DiskIOType::MMap));
m_comboBoxDiskIOType.addItem(tr("POSIX-compliant"), QVariant::fromValue(BitTorrent::DiskIOType::Posix));
+ m_comboBoxDiskIOType.addItem(tr("Simple pread/pwrite"), QVariant::fromValue(BitTorrent::DiskIOType::SimplePreadPwrite));
m_comboBoxDiskIOType.setCurrentIndex(m_comboBoxDiskIOType.findData(QVariant::fromValue(session->diskIOType())));
addRow(DISK_IO_TYPE, tr("Disk IO type (requires restart)") + u' ' + makeLink(u"https://www.libtorrent.org/single-page-ref.html#default-disk-io-constructor", u"(?)")
, &m_comboBoxDiskIOType);
@@ -845,6 +857,10 @@ void AdvancedSettings::loadAdvancedSettings()
m_checkBoxMarkOfTheWeb.setChecked(pref->isMarkOfTheWebEnabled());
addRow(ENABLE_MARK_OF_THE_WEB, motwLabel, &m_checkBoxMarkOfTheWeb);
#endif // Q_OS_MACOS || Q_OS_WIN
+ // Ignore SSL errors
+ m_checkBoxIgnoreSSLErrors.setChecked(pref->isIgnoreSSLErrors());
+ m_checkBoxIgnoreSSLErrors.setToolTip(tr("Affects certificate validation and non-torrent protocol activities (e.g. RSS feeds, program updates, torrent files, geoip db, etc)"));
+ addRow(IGNORE_SSL_ERRORS, tr("Ignore SSL errors"), &m_checkBoxIgnoreSSLErrors);
// Python executable path
m_pythonExecutablePath.setPlaceholderText(tr("(Auto detect if empty)"));
m_pythonExecutablePath.setText(pref->getPythonExecutablePath().toString());
diff --git a/src/gui/advancedsettings.h b/src/gui/advancedsettings.h
index 386a44d10..74914b293 100644
--- a/src/gui/advancedsettings.h
+++ b/src/gui/advancedsettings.h
@@ -77,11 +77,12 @@ private:
m_spinBoxSavePathHistoryLength, m_spinBoxPeerTurnover, m_spinBoxPeerTurnoverCutoff, m_spinBoxPeerTurnoverInterval, m_spinBoxRequestQueueSize;
QCheckBox m_checkBoxOsCache, m_checkBoxRecheckCompleted, m_checkBoxResolveCountries, m_checkBoxResolveHosts,
m_checkBoxProgramNotifications, m_checkBoxTorrentAddedNotifications, m_checkBoxReannounceWhenAddressChanged, m_checkBoxTrackerFavicon, m_checkBoxTrackerStatus,
- m_checkBoxTrackerPortForwarding, m_checkBoxConfirmTorrentRecheck, m_checkBoxConfirmRemoveAllTags, m_checkBoxAnnounceAllTrackers, m_checkBoxAnnounceAllTiers,
- m_checkBoxMultiConnectionsPerIp, m_checkBoxValidateHTTPSTrackerCertificate, m_checkBoxSSRFMitigation, m_checkBoxBlockPeersOnPrivilegedPorts, m_checkBoxPieceExtentAffinity,
- m_checkBoxSuggestMode, m_checkBoxSpeedWidgetEnabled, m_checkBoxIDNSupport, m_checkBoxConfirmRemoveTrackerFromAllTorrents, m_checkBoxStartSessionPaused;
+ m_checkBoxTrackerPortForwarding, m_checkBoxIgnoreSSLErrors, m_checkBoxConfirmTorrentRecheck, m_checkBoxConfirmRemoveAllTags, m_checkBoxAnnounceAllTrackers,
+ m_checkBoxAnnounceAllTiers, m_checkBoxMultiConnectionsPerIp, m_checkBoxValidateHTTPSTrackerCertificate, m_checkBoxSSRFMitigation, m_checkBoxBlockPeersOnPrivilegedPorts,
+ m_checkBoxPieceExtentAffinity, m_checkBoxSuggestMode, m_checkBoxSpeedWidgetEnabled, m_checkBoxIDNSupport, m_checkBoxConfirmRemoveTrackerFromAllTorrents,
+ m_checkBoxStartSessionPaused;
QComboBox m_comboBoxInterface, m_comboBoxInterfaceAddress, m_comboBoxDiskIOReadMode, m_comboBoxDiskIOWriteMode, m_comboBoxUtpMixedMode, m_comboBoxChokingAlgorithm,
- m_comboBoxSeedChokingAlgorithm, m_comboBoxResumeDataStorage;
+ m_comboBoxSeedChokingAlgorithm, m_comboBoxResumeDataStorage, m_comboBoxTorrentContentRemoveOption;
QLineEdit m_lineEditAppInstanceName, m_pythonExecutablePath, m_lineEditAnnounceIP, m_lineEditDHTBootstrapNodes;
#ifndef QBT_USES_LIBTORRENT2
diff --git a/src/gui/deletionconfirmationdialog.cpp b/src/gui/deletionconfirmationdialog.cpp
index e667a4ad3..9f5fe5452 100644
--- a/src/gui/deletionconfirmationdialog.cpp
+++ b/src/gui/deletionconfirmationdialog.cpp
@@ -1,5 +1,6 @@
/*
* Bittorrent Client using Qt and libtorrent.
+ * Copyright (C) 2024 Vladimir Golovnev
* Copyright (C) 2006 Christophe Dumez
*
* This program is free software; you can redistribute it and/or
@@ -30,6 +31,7 @@
#include
+#include "base/bittorrent/session.h"
#include "base/global.h"
#include "base/preferences.h"
#include "uithememanager.h"
@@ -53,8 +55,8 @@ DeletionConfirmationDialog::DeletionConfirmationDialog(QWidget *parent, const in
m_ui->rememberBtn->setIcon(UIThemeManager::instance()->getIcon(u"object-locked"_s));
m_ui->rememberBtn->setIconSize(Utils::Gui::mediumIconSize());
- m_ui->checkPermDelete->setChecked(defaultDeleteFiles || Preferences::instance()->deleteTorrentFilesAsDefault());
- connect(m_ui->checkPermDelete, &QCheckBox::clicked, this, &DeletionConfirmationDialog::updateRememberButtonState);
+ m_ui->checkRemoveContent->setChecked(defaultDeleteFiles || Preferences::instance()->removeTorrentContent());
+ connect(m_ui->checkRemoveContent, &QCheckBox::clicked, this, &DeletionConfirmationDialog::updateRememberButtonState);
m_ui->buttonBox->button(QDialogButtonBox::Ok)->setText(tr("Remove"));
m_ui->buttonBox->button(QDialogButtonBox::Cancel)->setFocus();
@@ -67,18 +69,18 @@ DeletionConfirmationDialog::~DeletionConfirmationDialog()
delete m_ui;
}
-bool DeletionConfirmationDialog::isDeleteFileSelected() const
+bool DeletionConfirmationDialog::isRemoveContentSelected() const
{
- return m_ui->checkPermDelete->isChecked();
+ return m_ui->checkRemoveContent->isChecked();
}
void DeletionConfirmationDialog::updateRememberButtonState()
{
- m_ui->rememberBtn->setEnabled(m_ui->checkPermDelete->isChecked() != Preferences::instance()->deleteTorrentFilesAsDefault());
+ m_ui->rememberBtn->setEnabled(m_ui->checkRemoveContent->isChecked() != Preferences::instance()->removeTorrentContent());
}
void DeletionConfirmationDialog::on_rememberBtn_clicked()
{
- Preferences::instance()->setDeleteTorrentFilesAsDefault(m_ui->checkPermDelete->isChecked());
+ Preferences::instance()->setRemoveTorrentContent(m_ui->checkRemoveContent->isChecked());
m_ui->rememberBtn->setEnabled(false);
}
diff --git a/src/gui/deletionconfirmationdialog.h b/src/gui/deletionconfirmationdialog.h
index f93f1746b..9ff657849 100644
--- a/src/gui/deletionconfirmationdialog.h
+++ b/src/gui/deletionconfirmationdialog.h
@@ -1,5 +1,6 @@
/*
* Bittorrent Client using Qt and libtorrent.
+ * Copyright (C) 2024 Vladimir Golovnev
* Copyright (C) 2006 Christophe Dumez
*
* This program is free software; you can redistribute it and/or
@@ -37,16 +38,16 @@ namespace Ui
class DeletionConfirmationDialog;
}
-class DeletionConfirmationDialog : public QDialog
+class DeletionConfirmationDialog final : public QDialog
{
Q_OBJECT
Q_DISABLE_COPY_MOVE(DeletionConfirmationDialog)
public:
DeletionConfirmationDialog(QWidget *parent, int size, const QString &name, bool defaultDeleteFiles);
- ~DeletionConfirmationDialog();
+ ~DeletionConfirmationDialog() override;
- bool isDeleteFileSelected() const;
+ bool isRemoveContentSelected() const;
private slots:
void updateRememberButtonState();
diff --git a/src/gui/deletionconfirmationdialog.ui b/src/gui/deletionconfirmationdialog.ui
index 9912e2b44..56834c918 100644
--- a/src/gui/deletionconfirmationdialog.ui
+++ b/src/gui/deletionconfirmationdialog.ui
@@ -75,7 +75,7 @@
-
-
+
0
@@ -88,7 +88,7 @@
- Also permanently delete the files
+ Also remove the content files
diff --git a/src/gui/filterpatternformat.h b/src/gui/filterpatternformat.h
new file mode 100644
index 000000000..71b3c5c51
--- /dev/null
+++ b/src/gui/filterpatternformat.h
@@ -0,0 +1,48 @@
+/*
+ * Bittorrent Client using Qt and libtorrent.
+ * Copyright (C) 2024 Vladimir Golovnev
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * In addition, as a special exception, the copyright holders give permission to
+ * link this program with the OpenSSL project's "OpenSSL" library (or with
+ * modified versions of it that use the same license as the "OpenSSL" library),
+ * and distribute the linked executables. You must obey the GNU General Public
+ * License in all respects for all of the code used other than "OpenSSL". If you
+ * modify file(s), you may extend this exception to your version of the file(s),
+ * but you are not obligated to do so. If you do not wish to do so, delete this
+ * exception statement from your version.
+ */
+
+#pragma once
+
+#include
+
+// Using `Q_ENUM_NS()` without a wrapper namespace in our case is not advised
+// since `Q_NAMESPACE` cannot be used when the same namespace resides at different files.
+// https://www.kdab.com/new-qt-5-8-meta-object-support-namespaces/#comment-143779
+inline namespace FilterPatternFormatNS
+{
+ Q_NAMESPACE
+
+ enum class FilterPatternFormat
+ {
+ PlainText,
+ Wildcards,
+ Regex
+ };
+
+ Q_ENUM_NS(FilterPatternFormat)
+}
diff --git a/src/gui/filterpatternformatmenu.cpp b/src/gui/filterpatternformatmenu.cpp
new file mode 100644
index 000000000..d13ab685a
--- /dev/null
+++ b/src/gui/filterpatternformatmenu.cpp
@@ -0,0 +1,82 @@
+/*
+ * Bittorrent Client using Qt and libtorrent.
+ * Copyright (C) 2024 Vladimir Golovnev
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * In addition, as a special exception, the copyright holders give permission to
+ * link this program with the OpenSSL project's "OpenSSL" library (or with
+ * modified versions of it that use the same license as the "OpenSSL" library),
+ * and distribute the linked executables. You must obey the GNU General Public
+ * License in all respects for all of the code used other than "OpenSSL". If you
+ * modify file(s), you may extend this exception to your version of the file(s),
+ * but you are not obligated to do so. If you do not wish to do so, delete this
+ * exception statement from your version.
+ */
+
+#include "filterpatternformatmenu.h"
+
+#include
+
+FilterPatternFormatMenu::FilterPatternFormatMenu(const FilterPatternFormat format, QWidget *parent)
+ : QMenu(parent)
+{
+ setTitle(tr("Pattern Format"));
+
+ auto *patternFormatGroup = new QActionGroup(this);
+ patternFormatGroup->setExclusive(true);
+
+ QAction *plainTextAction = addAction(tr("Plain text"));
+ plainTextAction->setCheckable(true);
+ patternFormatGroup->addAction(plainTextAction);
+
+ QAction *wildcardsAction = addAction(tr("Wildcards"));
+ wildcardsAction->setCheckable(true);
+ patternFormatGroup->addAction(wildcardsAction);
+
+ QAction *regexAction = addAction(tr("Regular expression"));
+ regexAction->setCheckable(true);
+ patternFormatGroup->addAction(regexAction);
+
+ switch (format)
+ {
+ case FilterPatternFormat::Wildcards:
+ default:
+ wildcardsAction->setChecked(true);
+ break;
+ case FilterPatternFormat::PlainText:
+ plainTextAction->setChecked(true);
+ break;
+ case FilterPatternFormat::Regex:
+ regexAction->setChecked(true);
+ break;
+ }
+
+ connect(plainTextAction, &QAction::toggled, this, [this](const bool checked)
+ {
+ if (checked)
+ emit patternFormatChanged(FilterPatternFormat::PlainText);
+ });
+ connect(wildcardsAction, &QAction::toggled, this, [this](const bool checked)
+ {
+ if (checked)
+ emit patternFormatChanged(FilterPatternFormat::Wildcards);
+ });
+ connect(regexAction, &QAction::toggled, this, [this](const bool checked)
+ {
+ if (checked)
+ emit patternFormatChanged(FilterPatternFormat::Regex);
+ });
+}
diff --git a/src/gui/filterpatternformatmenu.h b/src/gui/filterpatternformatmenu.h
new file mode 100644
index 000000000..e201fd89d
--- /dev/null
+++ b/src/gui/filterpatternformatmenu.h
@@ -0,0 +1,45 @@
+/*
+ * Bittorrent Client using Qt and libtorrent.
+ * Copyright (C) 2024 Vladimir Golovnev
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * In addition, as a special exception, the copyright holders give permission to
+ * link this program with the OpenSSL project's "OpenSSL" library (or with
+ * modified versions of it that use the same license as the "OpenSSL" library),
+ * and distribute the linked executables. You must obey the GNU General Public
+ * License in all respects for all of the code used other than "OpenSSL". If you
+ * modify file(s), you may extend this exception to your version of the file(s),
+ * but you are not obligated to do so. If you do not wish to do so, delete this
+ * exception statement from your version.
+ */
+
+#pragma once
+
+#include
+
+#include "filterpatternformat.h"
+
+class FilterPatternFormatMenu final : public QMenu
+{
+ Q_OBJECT
+ Q_DISABLE_COPY_MOVE(FilterPatternFormatMenu)
+
+public:
+ explicit FilterPatternFormatMenu(FilterPatternFormat format, QWidget *parent = nullptr);
+
+signals:
+ void patternFormatChanged(FilterPatternFormat format);
+};
diff --git a/src/gui/guiaddtorrentmanager.cpp b/src/gui/guiaddtorrentmanager.cpp
index 2fbebef68..d600a4e17 100644
--- a/src/gui/guiaddtorrentmanager.cpp
+++ b/src/gui/guiaddtorrentmanager.cpp
@@ -175,7 +175,8 @@ void GUIAddTorrentManager::onMetadataDownloaded(const BitTorrent::TorrentInfo &m
}
}
-bool GUIAddTorrentManager::processTorrent(const QString &source, const BitTorrent::TorrentDescriptor &torrentDescr, const BitTorrent::AddTorrentParams ¶ms)
+bool GUIAddTorrentManager::processTorrent(const QString &source
+ , const BitTorrent::TorrentDescriptor &torrentDescr, const BitTorrent::AddTorrentParams ¶ms)
{
const bool hasMetadata = torrentDescr.info().has_value();
const BitTorrent::InfoHash infoHash = torrentDescr.infoHash();
@@ -183,32 +184,39 @@ bool GUIAddTorrentManager::processTorrent(const QString &source, const BitTorren
// Prevent showing the dialog if download is already present
if (BitTorrent::Torrent *torrent = btSession()->findTorrent(infoHash))
{
- if (hasMetadata)
+ if (Preferences::instance()->confirmMergeTrackers())
{
- // Trying to set metadata to existing torrent in case if it has none
- torrent->setMetadata(*torrentDescr.info());
- }
+ if (hasMetadata)
+ {
+ // Trying to set metadata to existing torrent in case if it has none
+ torrent->setMetadata(*torrentDescr.info());
+ }
- if (torrent->isPrivate() || (hasMetadata && torrentDescr.info()->isPrivate()))
- {
- handleDuplicateTorrent(source, torrent, tr("Trackers cannot be merged because it is a private torrent"));
+ const bool isPrivate = torrent->isPrivate() || (hasMetadata && torrentDescr.info()->isPrivate());
+ const QString dialogCaption = tr("Torrent is already present");
+ if (isPrivate)
+ {
+ // We cannot merge trackers for private torrent but we still notify user
+ // about duplicate torrent if confirmation dialog is enabled.
+ RaisedMessageBox::warning(app()->mainWindow(), dialogCaption
+ , tr("Trackers cannot be merged because it is a private torrent."));
+ }
+ else
+ {
+ const bool mergeTrackers = btSession()->isMergeTrackersEnabled();
+ const QMessageBox::StandardButton btn = RaisedMessageBox::question(app()->mainWindow(), dialogCaption
+ , tr("Torrent '%1' is already in the transfer list. Do you want to merge trackers from new source?").arg(torrent->name())
+ , (QMessageBox::Yes | QMessageBox::No), (mergeTrackers ? QMessageBox::Yes : QMessageBox::No));
+ if (btn == QMessageBox::Yes)
+ {
+ torrent->addTrackers(torrentDescr.trackers());
+ torrent->addUrlSeeds(torrentDescr.urlSeeds());
+ }
+ }
}
else
{
- bool mergeTrackers = btSession()->isMergeTrackersEnabled();
- if (Preferences::instance()->confirmMergeTrackers())
- {
- const QMessageBox::StandardButton btn = RaisedMessageBox::question(app()->mainWindow(), tr("Torrent is already present")
- , tr("Torrent '%1' is already in the transfer list. Do you want to merge trackers from new source?").arg(torrent->name())
- , (QMessageBox::Yes | QMessageBox::No), QMessageBox::Yes);
- mergeTrackers = (btn == QMessageBox::Yes);
- }
-
- if (mergeTrackers)
- {
- torrent->addTrackers(torrentDescr.trackers());
- torrent->addUrlSeeds(torrentDescr.urlSeeds());
- }
+ handleDuplicateTorrent(source, torrentDescr, torrent);
}
return false;
@@ -227,15 +235,22 @@ bool GUIAddTorrentManager::processTorrent(const QString &source, const BitTorren
dlg->setAttribute(Qt::WA_DeleteOnClose);
m_dialogs[infoHash] = dlg;
connect(dlg, &AddNewTorrentDialog::torrentAccepted, this
- , [this, source](const BitTorrent::TorrentDescriptor &torrentDescr, const BitTorrent::AddTorrentParams &addTorrentParams)
- {
- addTorrentToSession(source, torrentDescr, addTorrentParams);
- });
- connect(dlg, &QDialog::finished, this, [this, source, infoHash, dlg]
+ , [this, source, dlg](const BitTorrent::TorrentDescriptor &torrentDescr, const BitTorrent::AddTorrentParams &addTorrentParams)
{
if (dlg->isDoNotDeleteTorrentChecked())
- releaseTorrentFileGuard(source);
+ {
+ if (auto torrentFileGuard = releaseTorrentFileGuard(source))
+ torrentFileGuard->setAutoRemove(false);
+ }
+ addTorrentToSession(source, torrentDescr, addTorrentParams);
+ });
+ connect(dlg, &AddNewTorrentDialog::torrentRejected, this, [this, source]
+ {
+ releaseTorrentFileGuard(source);
+ });
+ connect(dlg, &QDialog::finished, this, [this, source, infoHash]
+ {
m_dialogs.remove(infoHash);
});
diff --git a/src/gui/optionsdialog.cpp b/src/gui/optionsdialog.cpp
index dd76877b3..81c3305f3 100644
--- a/src/gui/optionsdialog.cpp
+++ b/src/gui/optionsdialog.cpp
@@ -1,6 +1,6 @@
/*
* Bittorrent Client using Qt and libtorrent.
- * Copyright (C) 2023-2024 Vladimir Golovnev
+ * Copyright (C) 2023-2025 Vladimir Golovnev
* Copyright (C) 2024 Jonathan Ketchker
* Copyright (C) 2006 Christophe Dumez
*
@@ -30,6 +30,7 @@
#include "optionsdialog.h"
+#include
#include
#include
#include
@@ -44,6 +45,10 @@
#include
#include
+#ifdef Q_OS_WIN
+#include
+#endif
+
#include "base/bittorrent/session.h"
#include "base/bittorrent/sharelimitaction.h"
#include "base/exceptions.h"
@@ -56,6 +61,7 @@
#include "base/rss/rss_session.h"
#include "base/torrentfileguard.h"
#include "base/torrentfileswatcher.h"
+#include "base/utils/compare.h"
#include "base/utils/io.h"
#include "base/utils/misc.h"
#include "base/utils/net.h"
@@ -236,6 +242,8 @@ void OptionsDialog::loadBehaviorTabOptions()
initializeLanguageCombo();
setLocale(pref->getLocale());
+ initializeStyleCombo();
+
m_ui->checkUseCustomTheme->setChecked(Preferences::instance()->useCustomUITheme());
m_ui->customThemeFilePath->setSelectedPath(Preferences::instance()->customUIThemePath());
m_ui->customThemeFilePath->setMode(FileSystemPathEdit::Mode::FileOpen);
@@ -345,7 +353,11 @@ void OptionsDialog::loadBehaviorTabOptions()
m_ui->checkBoxPerformanceWarning->setChecked(session->isPerformanceWarningEnabled());
- connect(m_ui->comboI18n, qComboBoxCurrentIndexChanged, this, &ThisType::enableApplyButton);
+ connect(m_ui->comboLanguage, qComboBoxCurrentIndexChanged, this, &ThisType::enableApplyButton);
+
+#ifdef Q_OS_WIN
+ connect(m_ui->comboStyle, qComboBoxCurrentIndexChanged, this, &ThisType::enableApplyButton);
+#endif
#if (defined(Q_OS_UNIX) && !defined(Q_OS_MACOS))
connect(m_ui->checkUseSystemIcon, &QAbstractButton::toggled, this, &ThisType::enableApplyButton);
@@ -443,6 +455,10 @@ void OptionsDialog::saveBehaviorTabOptions() const
}
pref->setLocale(locale);
+#ifdef Q_OS_WIN
+ pref->setStyle(m_ui->comboStyle->currentData().toString());
+#endif
+
#if (defined(Q_OS_UNIX) && !defined(Q_OS_MACOS))
pref->useSystemIcons(m_ui->checkUseSystemIcon->isChecked());
#endif
@@ -1387,7 +1403,7 @@ void OptionsDialog::initializeLanguageCombo()
for (const QString &langFile : langFiles)
{
const QString langCode = QStringView(langFile).sliced(12).chopped(3).toString(); // remove "qbittorrent_" and ".qm"
- m_ui->comboI18n->addItem(Utils::Misc::languageToLocalizedString(langCode), langCode);
+ m_ui->comboLanguage->addItem(Utils::Misc::languageToLocalizedString(langCode), langCode);
}
}
@@ -1672,6 +1688,34 @@ bool OptionsDialog::isSplashScreenDisabled() const
return !m_ui->checkShowSplash->isChecked();
}
+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));
+ 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());
+ 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;
+ 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();
+ m_ui->labelStyleHint->hide();
+ m_ui->UISettingsBoxLayout->removeWidget(m_ui->labelStyle);
+ m_ui->UISettingsBoxLayout->removeWidget(m_ui->comboStyle);
+ m_ui->UISettingsBoxLayout->removeWidget(m_ui->labelStyleHint);
+#endif
+}
+
#ifdef Q_OS_WIN
bool OptionsDialog::WinStartup() const
{
@@ -1721,7 +1765,7 @@ QString OptionsDialog::getProxyPassword() const
// Locale Settings
QString OptionsDialog::getLocale() const
{
- return m_ui->comboI18n->itemData(m_ui->comboI18n->currentIndex(), Qt::UserRole).toString();
+ return m_ui->comboLanguage->itemData(m_ui->comboLanguage->currentIndex(), Qt::UserRole).toString();
}
void OptionsDialog::setLocale(const QString &localeStr)
@@ -1746,7 +1790,7 @@ void OptionsDialog::setLocale(const QString &localeStr)
name = locale.name();
}
// Attempt to find exact match
- int index = m_ui->comboI18n->findData(name, Qt::UserRole);
+ int index = m_ui->comboLanguage->findData(name, Qt::UserRole);
if (index < 0)
{
//Attempt to find a language match without a country
@@ -1754,16 +1798,16 @@ void OptionsDialog::setLocale(const QString &localeStr)
if (pos > -1)
{
QString lang = name.left(pos);
- index = m_ui->comboI18n->findData(lang, Qt::UserRole);
+ index = m_ui->comboLanguage->findData(lang, Qt::UserRole);
}
}
if (index < 0)
{
// Unrecognized, use US English
- index = m_ui->comboI18n->findData(u"en"_s, Qt::UserRole);
+ index = m_ui->comboLanguage->findData(u"en"_s, Qt::UserRole);
Q_ASSERT(index >= 0);
}
- m_ui->comboI18n->setCurrentIndex(index);
+ m_ui->comboLanguage->setCurrentIndex(index);
}
Path OptionsDialog::getTorrentExportDir() const
@@ -1869,7 +1913,7 @@ Path OptionsDialog::getFilter() const
void OptionsDialog::webUIHttpsCertChanged(const Path &path)
{
const auto readResult = Utils::IO::readFile(path, Utils::Net::MAX_SSL_FILE_SIZE);
- const bool isCertValid = !Utils::SSLKey::load(readResult.value_or(QByteArray())).isNull();
+ const bool isCertValid = Utils::Net::isSSLCertificatesValid(readResult.value_or(QByteArray()));
m_ui->textWebUIHttpsCert->setSelectedPath(path);
m_ui->lblSslCertStatus->setPixmap(UIThemeManager::instance()->getScaledPixmap(
diff --git a/src/gui/optionsdialog.h b/src/gui/optionsdialog.h
index 6cb66ea05..b5a6c51fc 100644
--- a/src/gui/optionsdialog.h
+++ b/src/gui/optionsdialog.h
@@ -1,6 +1,6 @@
/*
* Bittorrent Client using Qt and libtorrent.
- * Copyright (C) 2023 Vladimir Golovnev
+ * Copyright (C) 2023-2024 Vladimir Golovnev
* Copyright (C) 2006 Christophe Dumez
*
* This program is free software; you can redistribute it and/or
@@ -143,6 +143,7 @@ private:
// General options
void initializeLanguageCombo();
+ void initializeStyleCombo();
QString getLocale() const;
bool isSplashScreenDisabled() const;
#ifdef Q_OS_WIN
diff --git a/src/gui/optionsdialog.ui b/src/gui/optionsdialog.ui
index fcfba3f3b..4247b4ff3 100644
--- a/src/gui/optionsdialog.ui
+++ b/src/gui/optionsdialog.ui
@@ -132,9 +132,9 @@
Interface
-
+
-
-
+
true
@@ -146,17 +146,17 @@
-
-
+
Language:
-
-
+
-
-
+
Qt::Horizontal
@@ -168,7 +168,26 @@
- -
+
-
+
+
+ Style:
+
+
+
+ -
+
+
+ -
+
+
+
+ true
+
+
+
+
+ -
Use custom UI Theme
@@ -190,14 +209,14 @@
- -
+
-
Use icons from system theme
- -
+
-
Customize UI Theme...
@@ -3881,7 +3900,7 @@ Use ';' to split multiple entries. Can use wildcard '*'.
tabOption
- comboI18n
+ comboLanguage
checkUseCustomTheme
customThemeFilePath
checkAddStopped
diff --git a/src/gui/powermanagement/powermanagement.cpp b/src/gui/powermanagement/powermanagement.cpp
index a51bb10fe..c184dde8b 100644
--- a/src/gui/powermanagement/powermanagement.cpp
+++ b/src/gui/powermanagement/powermanagement.cpp
@@ -32,6 +32,7 @@
#ifdef Q_OS_MACOS
#include
+#include
#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
diff --git a/src/gui/programupdater.cpp b/src/gui/programupdater.cpp
index ead2e9e49..063bc5473 100644
--- a/src/gui/programupdater.cpp
+++ b/src/gui/programupdater.cpp
@@ -29,6 +29,9 @@
#include "programupdater.h"
+#include
+
+#include
#include
#include
#include
@@ -61,6 +64,20 @@ namespace
}
return (newVersion > currentVersion);
}
+
+ QString buildVariant()
+ {
+#if defined(Q_OS_MACOS)
+ const auto BASE_OS = u"Mac OS X"_s;
+#elif defined(Q_OS_WIN)
+ const auto BASE_OS = u"Windows x64"_s;
+#endif
+
+ if constexpr ((QT_VERSION_MAJOR == 6) && (LIBTORRENT_VERSION_MAJOR == 1))
+ return BASE_OS;
+
+ return u"%1 (qt%2 lt%3%4)"_s.arg(BASE_OS, QString::number(QT_VERSION_MAJOR), QString::number(LIBTORRENT_VERSION_MAJOR), QString::number(LIBTORRENT_VERSION_MINOR));
+ }
}
void ProgramUpdater::checkForUpdates() const
@@ -97,12 +114,7 @@ void ProgramUpdater::rssDownloadFinished(const Net::DownloadResult &result)
: QString {};
};
-#ifdef Q_OS_MACOS
- const QString OS_TYPE = u"Mac OS X"_s;
-#elif defined(Q_OS_WIN)
- const QString OS_TYPE = u"Windows x64"_s;
-#endif
-
+ const QString variant = buildVariant();
bool inItem = false;
QString version;
QString updateLink;
@@ -128,7 +140,7 @@ void ProgramUpdater::rssDownloadFinished(const Net::DownloadResult &result)
{
if (inItem && (xml.name() == u"item"))
{
- if (type.compare(OS_TYPE, Qt::CaseInsensitive) == 0)
+ if (type.compare(variant, Qt::CaseInsensitive) == 0)
{
qDebug("The last update available is %s", qUtf8Printable(version));
if (!version.isEmpty())
diff --git a/src/gui/properties/downloadedpiecesbar.cpp b/src/gui/properties/downloadedpiecesbar.cpp
index 486d761d4..d7b1a849d 100644
--- a/src/gui/properties/downloadedpiecesbar.cpp
+++ b/src/gui/properties/downloadedpiecesbar.cpp
@@ -1,5 +1,6 @@
/*
* Bittorrent Client using Qt and libtorrent.
+ * Copyright (C) 2024 Vladimir Golovnev
* Copyright (C) 2006 Christophe Dumez
*
* This program is free software; you can redistribute it and/or
@@ -46,9 +47,9 @@ namespace
}
DownloadedPiecesBar::DownloadedPiecesBar(QWidget *parent)
- : base {parent}
- , m_dlPieceColor {dlPieceColor(pieceColor())}
+ : base(parent)
{
+ updateColorsImpl();
}
QVector DownloadedPiecesBar::bitfieldToFloatVector(const QBitArray &vecin, int reqSize)
@@ -128,25 +129,24 @@ QVector DownloadedPiecesBar::bitfieldToFloatVector(const QBitArray &vecin
return result;
}
-bool DownloadedPiecesBar::updateImage(QImage &image)
+QImage DownloadedPiecesBar::renderImage()
{
// qDebug() << "updateImage";
- QImage image2(width() - 2 * borderWidth, 1, QImage::Format_RGB888);
- if (image2.isNull())
+ QImage image {width() - 2 * borderWidth, 1, QImage::Format_RGB888};
+ if (image.isNull())
{
- qDebug() << "QImage image2() allocation failed, width():" << width();
- return false;
+ qDebug() << "QImage allocation failed, width():" << width();
+ return image;
}
if (m_pieces.isEmpty())
{
- image2.fill(backgroundColor());
- image = image2;
- return true;
+ image.fill(backgroundColor());
+ return image;
}
- QVector scaledPieces = bitfieldToFloatVector(m_pieces, image2.width());
- QVector scaledPiecesDl = bitfieldToFloatVector(m_downloadedPieces, image2.width());
+ QVector scaledPieces = bitfieldToFloatVector(m_pieces, image.width());
+ QVector scaledPiecesDl = bitfieldToFloatVector(m_downloadedPieces, image.width());
// filling image
for (int x = 0; x < scaledPieces.size(); ++x)
@@ -161,15 +161,15 @@ bool DownloadedPiecesBar::updateImage(QImage &image)
QRgb mixedColor = mixTwoColors(pieceColor().rgb(), m_dlPieceColor.rgb(), ratio);
mixedColor = mixTwoColors(backgroundColor().rgb(), mixedColor, fillRatio);
- image2.setPixel(x, 0, mixedColor);
+ image.setPixel(x, 0, mixedColor);
}
else
{
- image2.setPixel(x, 0, pieceColors()[piecesToValue * 255]);
+ image.setPixel(x, 0, pieceColors()[piecesToValue * 255]);
}
}
- image = image2;
- return true;
+
+ return image;
}
void DownloadedPiecesBar::setProgress(const QBitArray &pieces, const QBitArray &downloadedPieces)
@@ -177,7 +177,7 @@ void DownloadedPiecesBar::setProgress(const QBitArray &pieces, const QBitArray &
m_pieces = pieces;
m_downloadedPieces = downloadedPieces;
- requestImageUpdate();
+ redraw();
}
void DownloadedPiecesBar::clear()
@@ -198,3 +198,14 @@ QString DownloadedPiecesBar::simpleToolTipText() const
+ u"";
}
+
+void DownloadedPiecesBar::updateColors()
+{
+ PiecesBar::updateColors();
+ updateColorsImpl();
+}
+
+void DownloadedPiecesBar::updateColorsImpl()
+{
+ m_dlPieceColor = dlPieceColor(pieceColor());
+}
diff --git a/src/gui/properties/downloadedpiecesbar.h b/src/gui/properties/downloadedpiecesbar.h
index d98a114b2..2e8a1e00b 100644
--- a/src/gui/properties/downloadedpiecesbar.h
+++ b/src/gui/properties/downloadedpiecesbar.h
@@ -1,5 +1,6 @@
/*
* Bittorrent Client using Qt and libtorrent.
+ * Copyright (C) 2024 Vladimir Golovnev
* Copyright (C) 2006 Christophe Dumez
*
* This program is free software; you can redistribute it and/or
@@ -52,11 +53,13 @@ public:
private:
// scale bitfield vector to float vector
QVector bitfieldToFloatVector(const QBitArray &vecin, int reqSize);
- bool updateImage(QImage &image) override;
+ QImage renderImage() override;
QString simpleToolTipText() const override;
+ void updateColors() override;
+ void updateColorsImpl();
// incomplete piece color
- const QColor m_dlPieceColor;
+ QColor m_dlPieceColor;
// last used bitfields, uses to better resize redraw
// TODO: make a diff pieces to new pieces and update only changed pixels, speedup when update > 20x faster
QBitArray m_pieces;
diff --git a/src/gui/properties/peerlistwidget.cpp b/src/gui/properties/peerlistwidget.cpp
index 02f0cc609..511a3bd1e 100644
--- a/src/gui/properties/peerlistwidget.cpp
+++ b/src/gui/properties/peerlistwidget.cpp
@@ -411,7 +411,7 @@ void PeerListWidget::loadPeers(const BitTorrent::Torrent *torrent)
return;
// Remove I2P peers since they will be completely reloaded.
- for (QStandardItem *item : asConst(m_I2PPeerItems))
+ for (const QStandardItem *item : asConst(m_I2PPeerItems))
m_listModel->removeRow(item->row());
m_I2PPeerItems.clear();
@@ -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()};
@@ -466,10 +467,14 @@ void PeerListWidget::loadPeers(const BitTorrent::Torrent *torrent)
{
QStandardItem *item = m_peerItems.take(peerEndpoint);
- QSet &items = m_itemsByIP[peerEndpoint.address.ip];
- items.remove(item);
- if (items.isEmpty())
- m_itemsByIP.remove(peerEndpoint.address.ip);
+ const auto items = m_itemsByIP.find(peerEndpoint.address.ip);
+ Q_ASSERT(items != m_itemsByIP.end());
+ if (items == m_itemsByIP.end()) [[unlikely]]
+ continue;
+
+ items->remove(item);
+ if (items->isEmpty())
+ m_itemsByIP.erase(items);
m_listModel->removeRow(item->row());
}
diff --git a/src/gui/properties/pieceavailabilitybar.cpp b/src/gui/properties/pieceavailabilitybar.cpp
index 0f33d704b..66b375e92 100644
--- a/src/gui/properties/pieceavailabilitybar.cpp
+++ b/src/gui/properties/pieceavailabilitybar.cpp
@@ -1,5 +1,6 @@
/*
* Bittorrent Client using Qt and libtorrent.
+ * Copyright (C) 2024 Vladimir Golovnev
* Copyright (C) 2006 Christophe Dumez
*
* This program is free software; you can redistribute it and/or
@@ -126,39 +127,38 @@ QVector PieceAvailabilityBar::intToFloatVector(const QVector &vecin,
return result;
}
-bool PieceAvailabilityBar::updateImage(QImage &image)
+QImage PieceAvailabilityBar::renderImage()
{
- QImage image2(width() - 2 * borderWidth, 1, QImage::Format_RGB888);
- if (image2.isNull())
+ QImage image {width() - 2 * borderWidth, 1, QImage::Format_RGB888};
+ if (image.isNull())
{
- qDebug() << "QImage image2() allocation failed, width():" << width();
- return false;
+ qDebug() << "QImage allocation failed, width():" << width();
+ return image;
}
if (m_pieces.empty())
{
- image2.fill(backgroundColor());
- image = image2;
- return true;
+ image.fill(backgroundColor());
+ return image;
}
- QVector scaledPieces = intToFloatVector(m_pieces, image2.width());
+ QVector scaledPieces = intToFloatVector(m_pieces, image.width());
// filling image
for (int x = 0; x < scaledPieces.size(); ++x)
{
float piecesToValue = scaledPieces.at(x);
- image2.setPixel(x, 0, pieceColors()[piecesToValue * 255]);
+ image.setPixel(x, 0, pieceColors()[piecesToValue * 255]);
}
- image = image2;
- return true;
+
+ return image;
}
void PieceAvailabilityBar::setAvailability(const QVector &avail)
{
m_pieces = avail;
- requestImageUpdate();
+ redraw();
}
void PieceAvailabilityBar::clear()
diff --git a/src/gui/properties/pieceavailabilitybar.h b/src/gui/properties/pieceavailabilitybar.h
index 05472d489..07ece9701 100644
--- a/src/gui/properties/pieceavailabilitybar.h
+++ b/src/gui/properties/pieceavailabilitybar.h
@@ -1,5 +1,6 @@
/*
* Bittorrent Client using Qt and libtorrent.
+ * Copyright (C) 2024 Vladimir Golovnev
* Copyright (C) 2006 Christophe Dumez
*
* This program is free software; you can redistribute it and/or
@@ -46,7 +47,7 @@ public:
void clear() override;
private:
- bool updateImage(QImage &image) override;
+ QImage renderImage() override;
QString simpleToolTipText() const override;
// last used int vector, uses to better resize redraw
diff --git a/src/gui/properties/piecesbar.cpp b/src/gui/properties/piecesbar.cpp
index 0d42ec2ab..da050d5c9 100644
--- a/src/gui/properties/piecesbar.cpp
+++ b/src/gui/properties/piecesbar.cpp
@@ -1,5 +1,6 @@
/*
* Bittorrent Client using Qt and libtorrent.
+ * Copyright (C) 2024 Vladimir Golovnev
* Copyright (C) 2016 Eugene Shalygin
* Copyright (C) 2006 Christophe Dumez
*
@@ -114,10 +115,10 @@ namespace
}
PiecesBar::PiecesBar(QWidget *parent)
- : QWidget {parent}
+ : QWidget(parent)
{
- updatePieceColors();
setMouseTracking(true);
+ updateColorsImpl();
}
void PiecesBar::setTorrent(const BitTorrent::Torrent *torrent)
@@ -135,12 +136,19 @@ void PiecesBar::clear()
bool PiecesBar::event(QEvent *e)
{
- if (e->type() == QEvent::ToolTip)
+ const QEvent::Type eventType = e->type();
+ if (eventType == QEvent::ToolTip)
{
showToolTip(static_cast(e));
return true;
}
+ if (eventType == QEvent::PaletteChange)
+ {
+ updateColors();
+ redraw();
+ }
+
return base::event(e);
}
@@ -154,7 +162,7 @@ void PiecesBar::leaveEvent(QEvent *e)
{
m_hovered = false;
m_highlightedRegion = {};
- requestImageUpdate();
+ redraw();
base::leaveEvent(e);
}
@@ -178,16 +186,17 @@ void PiecesBar::paintEvent(QPaintEvent *)
else
{
if (m_image.width() != imageRect.width())
- updateImage(m_image);
+ {
+ if (const QImage image = renderImage(); !image.isNull())
+ m_image = image;
+ }
painter.drawImage(imageRect, m_image);
}
if (!m_highlightedRegion.isNull())
{
- QColor highlightColor {this->palette().color(QPalette::Active, QPalette::Highlight)};
- highlightColor.setAlphaF(0.35f);
QRect targetHighlightRect {m_highlightedRegion.adjusted(borderWidth, borderWidth, borderWidth, height() - 2 * borderWidth)};
- painter.fillRect(targetHighlightRect, highlightColor);
+ painter.fillRect(targetHighlightRect, highlightedPieceColor());
}
QPainterPath border;
@@ -196,30 +205,40 @@ void PiecesBar::paintEvent(QPaintEvent *)
painter.drawPath(border);
}
-void PiecesBar::requestImageUpdate()
+void PiecesBar::redraw()
{
- if (updateImage(m_image))
+ if (const QImage image = renderImage(); !image.isNull())
+ {
+ m_image = image;
update();
+ }
}
QColor PiecesBar::backgroundColor() const
{
- return palette().color(QPalette::Base);
+ return palette().color(QPalette::Active, QPalette::Base);
}
QColor PiecesBar::borderColor() const
{
- return palette().color(QPalette::Dark);
+ return palette().color(QPalette::Active, QPalette::Dark);
}
QColor PiecesBar::pieceColor() const
{
- return palette().color(QPalette::Highlight);
+ return palette().color(QPalette::Active, QPalette::Highlight);
+}
+
+QColor PiecesBar::highlightedPieceColor() const
+{
+ QColor col = palette().color(QPalette::Highlight).darker();
+ col.setAlphaF(0.35);
+ return col;
}
QColor PiecesBar::colorBoxBorderColor() const
{
- return palette().color(QPalette::ToolTipText);
+ return palette().color(QPalette::Active, QPalette::ToolTipText);
}
const QVector &PiecesBar::pieceColors() const
@@ -325,12 +344,17 @@ void PiecesBar::highlightFile(int imagePos)
}
}
-void PiecesBar::updatePieceColors()
+void PiecesBar::updateColors()
+{
+ updateColorsImpl();
+}
+
+void PiecesBar::updateColorsImpl()
{
m_pieceColors = QVector(256);
for (int i = 0; i < 256; ++i)
{
- float ratio = (i / 255.0);
+ const float ratio = (i / 255.0);
m_pieceColors[i] = mixTwoColors(backgroundColor().rgb(), pieceColor().rgb(), ratio);
}
}
diff --git a/src/gui/properties/piecesbar.h b/src/gui/properties/piecesbar.h
index 2f6e20615..2474753e6 100644
--- a/src/gui/properties/piecesbar.h
+++ b/src/gui/properties/piecesbar.h
@@ -1,5 +1,6 @@
/*
* Bittorrent Client using Qt and libtorrent.
+ * Copyright (C) 2024 Vladimir Golovnev
* Copyright (C) 2016 Eugene Shalygin
* Copyright (C) 2006 Christophe Dumez
*
@@ -54,22 +55,22 @@ public:
virtual void clear();
- // QObject interface
- bool event(QEvent *e) override;
-
protected:
- // QWidget interface
+ bool event(QEvent *e) override;
void enterEvent(QEnterEvent *e) override;
void leaveEvent(QEvent *e) override;
void mouseMoveEvent(QMouseEvent *e) override;
-
void paintEvent(QPaintEvent *e) override;
- void requestImageUpdate();
+
+ virtual void updateColors();
+ void redraw();
QColor backgroundColor() const;
QColor borderColor() const;
QColor pieceColor() const;
+ QColor highlightedPieceColor() const;
QColor colorBoxBorderColor() const;
+
const QVector &pieceColors() const;
// mix two colors by light model, ratio <0, 1>
@@ -82,11 +83,9 @@ private:
void highlightFile(int imagePos);
virtual QString simpleToolTipText() const = 0;
+ virtual QImage renderImage() = 0;
- // draw new image to replace the actual image
- // returns true if image was successfully updated
- virtual bool updateImage(QImage &image) = 0;
- void updatePieceColors();
+ void updateColorsImpl();
const BitTorrent::Torrent *m_torrent = nullptr;
QImage m_image;
diff --git a/src/gui/properties/propertieswidget.cpp b/src/gui/properties/propertieswidget.cpp
index 980978cb9..26d737732 100644
--- a/src/gui/properties/propertieswidget.cpp
+++ b/src/gui/properties/propertieswidget.cpp
@@ -1,6 +1,6 @@
/*
* Bittorrent Client using Qt and libtorrent.
- * Copyright (C) 2022 Vladimir Golovnev
+ * Copyright (C) 2022-2024 Vladimir Golovnev
* Copyright (C) 2006 Christophe Dumez
*
* This program is free software; you can redistribute it and/or
@@ -52,6 +52,7 @@
#include "base/utils/misc.h"
#include "base/utils/string.h"
#include "gui/autoexpandabledialog.h"
+#include "gui/filterpatternformatmenu.h"
#include "gui/lineedit.h"
#include "gui/trackerlist/trackerlistwidget.h"
#include "gui/uithememanager.h"
@@ -66,6 +67,7 @@
PropertiesWidget::PropertiesWidget(QWidget *parent)
: QWidget(parent)
, m_ui {new Ui::PropertiesWidget}
+ , m_storeFilterPatternFormat {u"GUI/PropertiesWidget/FilterPatternFormat"_s}
{
m_ui->setupUi(this);
#ifndef Q_OS_MACOS
@@ -78,7 +80,9 @@ PropertiesWidget::PropertiesWidget(QWidget *parent)
m_contentFilterLine = new LineEdit(this);
m_contentFilterLine->setPlaceholderText(tr("Filter files..."));
m_contentFilterLine->setFixedWidth(300);
- connect(m_contentFilterLine, &LineEdit::textChanged, m_ui->filesList, &TorrentContentWidget::setFilterPattern);
+ m_contentFilterLine->setContextMenuPolicy(Qt::CustomContextMenu);
+ connect(m_contentFilterLine, &QWidget::customContextMenuRequested, this, &PropertiesWidget::showContentFilterContextMenu);
+ connect(m_contentFilterLine, &LineEdit::textChanged, this, &PropertiesWidget::setContentFilterPattern);
m_ui->contentFilterLayout->insertWidget(3, m_contentFilterLine);
m_ui->filesList->setDoubleClickAction(TorrentContentWidget::DoubleClickAction::Open);
@@ -206,6 +210,7 @@ void PropertiesWidget::clear()
m_ui->labelSavePathVal->clear();
m_ui->labelCreatedOnVal->clear();
m_ui->labelTotalPiecesVal->clear();
+ m_ui->labelPrivateVal->clear();
m_ui->labelInfohash1Val->clear();
m_ui->labelInfohash2Val->clear();
m_ui->labelCommentVal->clear();
@@ -274,6 +279,28 @@ void PropertiesWidget::updateSavePath(BitTorrent::Torrent *const torrent)
m_ui->labelSavePathVal->setText(m_torrent->savePath().toString());
}
+void PropertiesWidget::showContentFilterContextMenu()
+{
+ QMenu *menu = m_contentFilterLine->createStandardContextMenu();
+
+ auto *formatMenu = new FilterPatternFormatMenu(m_storeFilterPatternFormat.get(FilterPatternFormat::Wildcards), menu);
+ connect(formatMenu, &FilterPatternFormatMenu::patternFormatChanged, this, [this](const FilterPatternFormat format)
+ {
+ m_storeFilterPatternFormat = format;
+ setContentFilterPattern();
+ });
+
+ menu->addSeparator();
+ menu->addMenu(formatMenu);
+ menu->setAttribute(Qt::WA_DeleteOnClose);
+ menu->popup(QCursor::pos());
+}
+
+void PropertiesWidget::setContentFilterPattern()
+{
+ m_ui->filesList->setFilterPattern(m_contentFilterLine->text(), m_storeFilterPatternFormat.get(FilterPatternFormat::Wildcards));
+}
+
void PropertiesWidget::updateTorrentInfos(BitTorrent::Torrent *const torrent)
{
if (torrent == m_torrent)
@@ -309,7 +336,14 @@ void PropertiesWidget::loadTorrentInfos(BitTorrent::Torrent *const torrent)
m_ui->labelCommentVal->setText(Utils::Misc::parseHtmlLinks(m_torrent->comment().toHtmlEscaped()));
m_ui->labelCreatedByVal->setText(m_torrent->creator());
+
+ m_ui->labelPrivateVal->setText(m_torrent->isPrivate() ? tr("Yes") : tr("No"));
}
+ else
+ {
+ m_ui->labelPrivateVal->setText(tr("N/A"));
+ }
+
// Load dynamic data
loadDynamicData();
}
diff --git a/src/gui/properties/propertieswidget.h b/src/gui/properties/propertieswidget.h
index 31a1963b0..21b1b5fc5 100644
--- a/src/gui/properties/propertieswidget.h
+++ b/src/gui/properties/propertieswidget.h
@@ -1,6 +1,6 @@
/*
* Bittorrent Client using Qt and libtorrent.
- * Copyright (C) 2022 Vladimir Golovnev
+ * Copyright (C) 2022-2024 Vladimir Golovnev
* Copyright (C) 2006 Christophe Dumez
*
* This program is free software; you can redistribute it and/or
@@ -32,7 +32,8 @@
#include
#include
-#include "base/pathfwd.h"
+#include "base/settingvalue.h"
+#include "gui/filterpatternformat.h"
class QPushButton;
class QTreeView;
@@ -102,6 +103,8 @@ private slots:
private:
QPushButton *getButtonFromIndex(int index);
+ void showContentFilterContextMenu();
+ void setContentFilterPattern();
Ui::PropertiesWidget *m_ui = nullptr;
BitTorrent::Torrent *m_torrent = nullptr;
@@ -115,4 +118,6 @@ private:
PropTabBar *m_tabBar = nullptr;
LineEdit *m_contentFilterLine = nullptr;
int m_handleWidth = -1;
+
+ SettingValue m_storeFilterPatternFormat;
};
diff --git a/src/gui/properties/propertieswidget.ui b/src/gui/properties/propertieswidget.ui
index 17ffa6b4f..71b3864f9 100644
--- a/src/gui/properties/propertieswidget.ui
+++ b/src/gui/properties/propertieswidget.ui
@@ -823,6 +823,38 @@
-
+
+
+
+ 0
+ 0
+
+
+
+ Private:
+
+
+ Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+ Qt::PlainText
+
+
+ Qt::TextSelectableByMouse
+
+
+
+ -
@@ -838,71 +870,7 @@
- -
-
-
-
- 0
- 0
-
-
-
- Info Hash v2:
-
-
- Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter
-
-
-
-
-
-
-
- 0
- 0
-
-
-
- Qt::PlainText
-
-
- Qt::TextSelectableByMouse
-
-
-
- -
-
-
-
- 0
- 0
-
-
-
- Save Path:
-
-
- Qt::AlignRight|Qt::AlignTop|Qt::AlignTrailing
-
-
-
- -
-
-
-
- 0
- 0
-
-
-
- Comment:
-
-
- Qt::AlignRight|Qt::AlignTop|Qt::AlignTrailing
-
-
-
- -
@@ -918,7 +886,55 @@
+ -
+
+
+
+ 0
+ 0
+
+
+
+ Info Hash v2:
+
+
+ Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter
+
+
+
-
+
+
+
+ 0
+ 0
+
+
+
+ Qt::PlainText
+
+
+ Qt::TextSelectableByMouse
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+ Save Path:
+
+
+ Qt::AlignRight|Qt::AlignTop|Qt::AlignTrailing
+
+
+
+ -
@@ -937,7 +953,23 @@
- -
+
-
+
+
+
+ 0
+ 0
+
+
+
+ Comment:
+
+
+ Qt::AlignRight|Qt::AlignTop|Qt::AlignTrailing
+
+
+
+ -
diff --git a/src/gui/rss/htmlbrowser.cpp b/src/gui/rss/htmlbrowser.cpp
index ecf3ff7ad..4c34923bc 100644
--- a/src/gui/rss/htmlbrowser.cpp
+++ b/src/gui/rss/htmlbrowser.cpp
@@ -106,10 +106,12 @@ void HtmlBrowser::resourceLoaded(QNetworkReply *reply)
atts[QNetworkRequest::HttpStatusCodeAttribute] = 200;
atts[QNetworkRequest::HttpReasonPhraseAttribute] = u"Ok"_s;
metaData.setAttributes(atts);
- metaData.setLastModified(QDateTime::currentDateTime());
- metaData.setExpirationDate(QDateTime::currentDateTime().addDays(1));
+ const auto currentDateTime = QDateTime::currentDateTime();
+ metaData.setLastModified(currentDateTime);
+ metaData.setExpirationDate(currentDateTime.addDays(1));
QIODevice *dev = m_diskCache->prepare(metaData);
- if (!dev) return;
+ if (!dev)
+ return;
QApplication::style()->standardIcon(QStyle::SP_MessageBoxWarning).pixmap(32, 32).save(dev, "PNG");
m_diskCache->insert(dev);
diff --git a/src/gui/rss/rsswidget.cpp b/src/gui/rss/rsswidget.cpp
index 75d0be77a..a6ca52b6c 100644
--- a/src/gui/rss/rsswidget.cpp
+++ b/src/gui/rss/rsswidget.cpp
@@ -126,6 +126,8 @@ RSSWidget::RSSWidget(IGUIApplication *app, QWidget *parent)
, this, &RSSWidget::handleSessionProcessingStateChanged);
connect(RSS::Session::instance()->rootFolder(), &RSS::Folder::unreadCountChanged
, this, &RSSWidget::handleUnreadCountChanged);
+
+ m_ui->textBrowser->installEventFilter(this);
}
RSSWidget::~RSSWidget()
@@ -494,60 +496,11 @@ void RSSWidget::handleCurrentArticleItemChanged(QListWidgetItem *currentItem, QL
article->markAsRead();
}
- if (!currentItem) return;
+ if (!currentItem)
+ return;
auto *article = m_articleListWidget->getRSSArticle(currentItem);
- Q_ASSERT(article);
-
- const QString highlightedBaseColor = m_ui->textBrowser->palette().color(QPalette::Highlight).name();
- const QString highlightedBaseTextColor = m_ui->textBrowser->palette().color(QPalette::HighlightedText).name();
- const QString alternateBaseColor = m_ui->textBrowser->palette().color(QPalette::AlternateBase).name();
-
- QString html =
- u"
" +
- u"
%3
"_s.arg(highlightedBaseColor, highlightedBaseTextColor, article->title());
- if (article->date().isValid())
- html += u"
%2%3
"_s.arg(alternateBaseColor, tr("Date: "), QLocale::system().toString(article->date().toLocalTime()));
- if (m_feedListWidget->currentItem() == m_feedListWidget->stickyUnreadItem())
- html += u"
%2%3
"_s.arg(alternateBaseColor, tr("Feed: "), article->feed()->title());
- if (!article->author().isEmpty())
- html += u"
%2%3
"_s.arg(alternateBaseColor, tr("Author: "), article->author());
- html += u"
"
- u"";
- if (Qt::mightBeRichText(article->description()))
- {
- html += article->description();
- }
- else
- {
- QString description = article->description();
- QRegularExpression rx;
- // If description is plain text, replace BBCode tags with HTML and wrap everything in
so it looks nice
- rx.setPatternOptions(QRegularExpression::InvertedGreedinessOption
- | QRegularExpression::CaseInsensitiveOption);
-
- rx.setPattern(u"\\[img\\](.+)\\[/img\\]"_s);
- description = description.replace(rx, u"

"_s);
-
- rx.setPattern(u"\\[url=(\")?(.+)\\1\\]"_s);
- description = description.replace(rx, u"
"_s);
- description = description.replace(u"[/url]"_s, u""_s, Qt::CaseInsensitive);
-
- rx.setPattern(u"\\[(/)?([bius])\\]"_s);
- description = description.replace(rx, u"<\\1\\2>"_s);
-
- rx.setPattern(u"\\[color=(\")?(.+)\\1\\]"_s);
- description = description.replace(rx, u"
"_s);
- description = description.replace(u"[/color]"_s, u""_s, Qt::CaseInsensitive);
-
- rx.setPattern(u"\\[size=(\")?(.+)\\d\\1\\]"_s);
- description = description.replace(rx, u"
"_s);
- description = description.replace(u"[/size]"_s, u""_s, Qt::CaseInsensitive);
-
- html += u"
" + description + u"
";
- }
- html += u"
";
- m_ui->textBrowser->setHtml(html);
+ renderArticle(article);
}
void RSSWidget::saveSlidersPosition()
@@ -590,3 +543,73 @@ void RSSWidget::handleUnreadCountChanged()
{
emit unreadCountUpdated(RSS::Session::instance()->rootFolder()->unreadCount());
}
+
+bool RSSWidget::eventFilter(QObject *obj, QEvent *event)
+{
+ if ((obj == m_ui->textBrowser) && (event->type() == QEvent::PaletteChange))
+ {
+ QListWidgetItem *currentItem = m_articleListWidget->currentItem();
+ if (currentItem)
+ {
+ const RSS::Article *article = m_articleListWidget->getRSSArticle(currentItem);
+ renderArticle(article);
+ }
+ }
+
+ return false;
+}
+
+void RSSWidget::renderArticle(const RSS::Article *article) const
+{
+ Q_ASSERT(article);
+
+ const QString highlightedBaseColor = m_ui->textBrowser->palette().color(QPalette::Active, QPalette::Highlight).name();
+ const QString highlightedBaseTextColor = m_ui->textBrowser->palette().color(QPalette::Active, QPalette::HighlightedText).name();
+ const QString alternateBaseColor = m_ui->textBrowser->palette().color(QPalette::Active, QPalette::AlternateBase).name();
+
+ QString html =
+ u"" +
+ u"
%3
"_s.arg(highlightedBaseColor, highlightedBaseTextColor, article->title());
+ if (article->date().isValid())
+ html += u"
%2%3
"_s.arg(alternateBaseColor, tr("Date: "), QLocale::system().toString(article->date().toLocalTime()));
+ if (m_feedListWidget->currentItem() == m_feedListWidget->stickyUnreadItem())
+ html += u"
%2%3
"_s.arg(alternateBaseColor, tr("Feed: "), article->feed()->title());
+ if (!article->author().isEmpty())
+ html += u"
%2%3
"_s.arg(alternateBaseColor, tr("Author: "), article->author());
+ html += u"
"
+ u"";
+ if (Qt::mightBeRichText(article->description()))
+ {
+ html += article->description();
+ }
+ else
+ {
+ QString description = article->description();
+ QRegularExpression rx;
+ // If description is plain text, replace BBCode tags with HTML and wrap everything in
so it looks nice
+ rx.setPatternOptions(QRegularExpression::InvertedGreedinessOption
+ | QRegularExpression::CaseInsensitiveOption);
+
+ rx.setPattern(u"\\[img\\](.+)\\[/img\\]"_s);
+ description = description.replace(rx, u"

"_s);
+
+ rx.setPattern(u"\\[url=(\")?(.+)\\1\\]"_s);
+ description = description.replace(rx, u"
"_s);
+ description = description.replace(u"[/url]"_s, u""_s, Qt::CaseInsensitive);
+
+ rx.setPattern(u"\\[(/)?([bius])\\]"_s);
+ description = description.replace(rx, u"<\\1\\2>"_s);
+
+ rx.setPattern(u"\\[color=(\")?(.+)\\1\\]"_s);
+ description = description.replace(rx, u"
"_s);
+ description = description.replace(u"[/color]"_s, u""_s, Qt::CaseInsensitive);
+
+ rx.setPattern(u"\\[size=(\")?(.+)\\d\\1\\]"_s);
+ description = description.replace(rx, u"
"_s);
+ description = description.replace(u"[/size]"_s, u""_s, Qt::CaseInsensitive);
+
+ html += u"
" + description + u"
";
+ }
+ html += u"
";
+ m_ui->textBrowser->setHtml(html);
+}
diff --git a/src/gui/rss/rsswidget.h b/src/gui/rss/rsswidget.h
index 5c5aaaa1b..cc1da53bc 100644
--- a/src/gui/rss/rsswidget.h
+++ b/src/gui/rss/rsswidget.h
@@ -40,6 +40,11 @@ class QTreeWidgetItem;
class ArticleListWidget;
class FeedListWidget;
+namespace RSS
+{
+ class Article;
+}
+
namespace Ui
{
class RSSWidget;
@@ -85,6 +90,9 @@ private slots:
void handleUnreadCountChanged();
private:
+ bool eventFilter(QObject *obj, QEvent *event) override;
+ void renderArticle(const RSS::Article *article) const;
+
Ui::RSSWidget *m_ui = nullptr;
ArticleListWidget *m_articleListWidget = nullptr;
FeedListWidget *m_feedListWidget = nullptr;
diff --git a/src/gui/search/searchjobwidget.cpp b/src/gui/search/searchjobwidget.cpp
index e8aa99ead..512cd58bc 100644
--- a/src/gui/search/searchjobwidget.cpp
+++ b/src/gui/search/searchjobwidget.cpp
@@ -1,6 +1,6 @@
/*
* Bittorrent Client using Qt and libtorrent.
- * Copyright (C) 2018 Vladimir Golovnev
+ * Copyright (C) 2018-2024 Vladimir Golovnev
* Copyright (C) 2006 Christophe Dumez
*
* This program is free software; you can redistribute it and/or
@@ -50,6 +50,19 @@
#include "searchsortmodel.h"
#include "ui_searchjobwidget.h"
+namespace
+{
+ enum DataRole
+ {
+ LinkVisitedRole = Qt::UserRole + 100
+ };
+
+ QColor visitedRowColor()
+ {
+ return QApplication::palette().color(QPalette::Disabled, QPalette::WindowText);
+ }
+}
+
SearchJobWidget::SearchJobWidget(SearchHandler *searchHandler, IGUIApplication *app, QWidget *parent)
: GUIApplicationComponent(app, parent)
, m_ui {new Ui::SearchJobWidget}
@@ -158,6 +171,8 @@ SearchJobWidget::SearchJobWidget(SearchHandler *searchHandler, IGUIApplication *
connect(this, &QObject::destroyed, searchHandler, &QObject::deleteLater);
setStatusTip(statusText(m_status));
+
+ connect(UIThemeManager::instance(), &UIThemeManager::themeChanged, this, &SearchJobWidget::onUIThemeChanged);
}
SearchJobWidget::~SearchJobWidget()
@@ -179,9 +194,31 @@ QHeaderView *SearchJobWidget::header() const
// Set the color of a row in data model
void SearchJobWidget::setRowColor(int row, const QColor &color)
{
- m_proxyModel->setDynamicSortFilter(false);
for (int i = 0; i < m_proxyModel->columnCount(); ++i)
m_proxyModel->setData(m_proxyModel->index(row, i), color, Qt::ForegroundRole);
+}
+
+void SearchJobWidget::setRowVisited(const int row)
+{
+ m_proxyModel->setDynamicSortFilter(false);
+
+ m_proxyModel->setData(m_proxyModel->index(row, 0), true, LinkVisitedRole);
+ setRowColor(row, visitedRowColor());
+
+ m_proxyModel->setDynamicSortFilter(true);
+}
+
+void SearchJobWidget::onUIThemeChanged()
+{
+ m_proxyModel->setDynamicSortFilter(false);
+
+ for (int row = 0; row < m_proxyModel->rowCount(); ++row)
+ {
+ const QVariant userData = m_proxyModel->data(m_proxyModel->index(row, 0), LinkVisitedRole);
+ const bool isVisited = userData.toBool();
+ if (isVisited)
+ setRowColor(row, visitedRowColor());
+ }
m_proxyModel->setDynamicSortFilter(true);
}
@@ -284,7 +321,8 @@ void SearchJobWidget::downloadTorrent(const QModelIndex &rowIndex, const AddTorr
, this, [this, option](const QString &source) { addTorrentToSession(source, option); });
connect(downloadHandler, &SearchDownloadHandler::downloadFinished, downloadHandler, &SearchDownloadHandler::deleteLater);
}
- setRowColor(rowIndex.row(), QApplication::palette().color(QPalette::LinkVisited));
+
+ setRowVisited(rowIndex.row());
}
void SearchJobWidget::addTorrentToSession(const QString &source, const AddTorrentOption option)
diff --git a/src/gui/search/searchjobwidget.h b/src/gui/search/searchjobwidget.h
index f597c03af..0a84eeb34 100644
--- a/src/gui/search/searchjobwidget.h
+++ b/src/gui/search/searchjobwidget.h
@@ -1,6 +1,6 @@
/*
* Bittorrent Client using Qt and libtorrent.
- * Copyright (C) 2018 Vladimir Golovnev
+ * Copyright (C) 2018-2024 Vladimir Golovnev
* Copyright (C) 2006 Christophe Dumez
*
* This program is free software; you can redistribute it and/or
@@ -113,8 +113,10 @@ private:
void fillFilterComboBoxes();
NameFilteringMode filteringMode() const;
QHeaderView *header() const;
- void setRowColor(int row, const QColor &color);
int visibleColumnsCount() const;
+ void setRowColor(int row, const QColor &color);
+ void setRowVisited(int row);
+ void onUIThemeChanged();
void downloadTorrents(AddTorrentOption option = AddTorrentOption::Default);
void openTorrentPages() const;
diff --git a/src/gui/search/searchwidget.cpp b/src/gui/search/searchwidget.cpp
index 1128a561e..cabd8a135 100644
--- a/src/gui/search/searchwidget.cpp
+++ b/src/gui/search/searchwidget.cpp
@@ -1,7 +1,7 @@
/*
* Bittorrent Client using Qt and libtorrent.
+ * Copyright (C) 2015-2024 Vladimir Golovnev
* Copyright (C) 2020, Will Da Silva
- * Copyright (C) 2015, 2018 Vladimir Golovnev
* Copyright (C) 2006 Christophe Dumez
*
* This program is free software; you can redistribute it and/or
@@ -120,6 +120,7 @@ SearchWidget::SearchWidget(IGUIApplication *app, MainWindow *mainWindow)
#endif
connect(m_ui->tabWidget, &QTabWidget::tabCloseRequested, this, &SearchWidget::closeTab);
connect(m_ui->tabWidget, &QTabWidget::currentChanged, this, &SearchWidget::tabChanged);
+ connect(m_ui->tabWidget->tabBar(), &QTabBar::tabMoved, this, &SearchWidget::tabMoved);
const auto *searchManager = SearchPluginManager::instance();
const auto onPluginChanged = [this]()
@@ -262,6 +263,11 @@ void SearchWidget::tabChanged(const int index)
m_currentSearchTab = ((index < 0) ? nullptr : m_allTabs.at(m_ui->tabWidget->currentIndex()));
}
+void SearchWidget::tabMoved(const int from, const int to)
+{
+ m_allTabs.move(from, to);
+}
+
void SearchWidget::selectMultipleBox([[maybe_unused]] const int index)
{
if (selectedPlugin() == u"multi")
diff --git a/src/gui/search/searchwidget.h b/src/gui/search/searchwidget.h
index 06544308c..a1b18e470 100644
--- a/src/gui/search/searchwidget.h
+++ b/src/gui/search/searchwidget.h
@@ -1,7 +1,7 @@
/*
* Bittorrent Client using Qt and libtorrent.
+ * Copyright (C) 2015-2024 Vladimir Golovnev
* Copyright (C) 2020, Will Da Silva
- * Copyright (C) 2015, 2018 Vladimir Golovnev
* Copyright (C) 2006 Christophe Dumez
*
* This program is free software; you can redistribute it and/or
@@ -66,6 +66,7 @@ private slots:
private:
bool eventFilter(QObject *object, QEvent *event) override;
void tabChanged(int index);
+ void tabMoved(int from, int to);
void closeTab(int index);
void closeAllTabs();
void tabStatusChanged(QWidget *tab);
diff --git a/src/gui/torrentcontentmodel.cpp b/src/gui/torrentcontentmodel.cpp
index 61c43cebc..adcd778bf 100644
--- a/src/gui/torrentcontentmodel.cpp
+++ b/src/gui/torrentcontentmodel.cpp
@@ -1,6 +1,6 @@
/*
* Bittorrent Client using Qt and libtorrent.
- * Copyright (C) 2022-2023 Vladimir Golovnev
+ * Copyright (C) 2022-2024 Vladimir Golovnev
* Copyright (C) 2006-2012 Christophe Dumez
*
* This program is free software; you can redistribute it and/or
@@ -37,17 +37,12 @@
#include
#include
-#if defined(Q_OS_WIN)
-#include
-#include
-#else
-#include
-#include
-#endif
-
-#if defined Q_OS_WIN || defined Q_OS_MACOS
+#if defined(Q_OS_MACOS)
#define QBT_PIXMAP_CACHE_FOR_FILE_ICONS
#include
+#elif !defined(Q_OS_WIN)
+#include
+#include
#endif
#include "base/bittorrent/downloadpriority.h"
@@ -116,27 +111,8 @@ namespace
};
#endif // QBT_PIXMAP_CACHE_FOR_FILE_ICONS
-#if defined(Q_OS_WIN)
- // See QTBUG-25319 for explanation why this is required
- class WinShellFileIconProvider final : public CachingFileIconProvider
- {
- QPixmap pixmapForExtension(const QString &ext) const override
- {
- const std::wstring extWStr = QString(u'.' + ext).toStdWString();
-
- SHFILEINFOW sfi {};
- const HRESULT hr = ::SHGetFileInfoW(extWStr.c_str(),
- FILE_ATTRIBUTE_NORMAL, &sfi, sizeof(sfi), (SHGFI_ICON | SHGFI_USEFILEATTRIBUTES));
- if (FAILED(hr))
- return {};
-
- const auto iconPixmap = QPixmap::fromImage(QImage::fromHICON(sfi.hIcon));
- ::DestroyIcon(sfi.hIcon);
- return iconPixmap;
- }
- };
-#elif defined(Q_OS_MACOS)
- // There is a similar bug on macOS, to be reported to Qt
+#if defined(Q_OS_MACOS)
+ // There is a bug on macOS, to be reported to Qt
// https://github.com/qbittorrent/qBittorrent/pull/6156#issuecomment-316302615
class MacFileIconProvider final : public CachingFileIconProvider
{
@@ -145,7 +121,7 @@ namespace
return MacUtils::pixmapForExtension(ext, QSize(32, 32));
}
};
-#else
+#elif !defined(Q_OS_WIN)
/**
* @brief Tests whether QFileIconProvider actually works
*
@@ -189,7 +165,7 @@ TorrentContentModel::TorrentContentModel(QObject *parent)
: QAbstractItemModel(parent)
, m_rootItem(new TorrentContentModelFolder(QVector({ tr("Name"), tr("Total Size"), tr("Progress"), tr("Download Priority"), tr("Remaining"), tr("Availability") })))
#if defined(Q_OS_WIN)
- , m_fileIconProvider {new WinShellFileIconProvider}
+ , m_fileIconProvider {new QFileIconProvider}
#elif defined(Q_OS_MACOS)
, m_fileIconProvider {new MacFileIconProvider}
#else
@@ -422,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;
diff --git a/src/gui/torrentcontentmodelfolder.cpp b/src/gui/torrentcontentmodelfolder.cpp
index abece9c9b..b8a536216 100644
--- a/src/gui/torrentcontentmodelfolder.cpp
+++ b/src/gui/torrentcontentmodelfolder.cpp
@@ -147,10 +147,19 @@ void TorrentContentModelFolder::recalculateProgress()
tRemaining += child->remaining();
}
- if (!isRootItem() && (tSize > 0))
+ if (!isRootItem())
{
- m_progress = tProgress / tSize;
- m_remaining = tRemaining;
+ if (tSize > 0)
+ {
+ m_progress = tProgress / tSize;
+ m_remaining = tRemaining;
+ }
+ else
+ {
+ m_progress = 1.0;
+ m_remaining = 0;
+ }
+
Q_ASSERT(m_progress <= 1.);
}
}
diff --git a/src/gui/torrentcontentwidget.cpp b/src/gui/torrentcontentwidget.cpp
index 1b3817408..59c401871 100644
--- a/src/gui/torrentcontentwidget.cpp
+++ b/src/gui/torrentcontentwidget.cpp
@@ -1,6 +1,6 @@
/*
* Bittorrent Client using Qt and libtorrent.
- * Copyright (C) 2022 Vladimir Golovnev
+ * Copyright (C) 2022-2024 Vladimir Golovnev
* Copyright (C) 2014 Ivan Sorokin
*
* This program is free software; you can redistribute it and/or
@@ -56,6 +56,19 @@
#include "gui/macutilities.h"
#endif
+namespace
+{
+ QList toPersistentIndexes(const QModelIndexList &indexes)
+ {
+ QList persistentIndexes;
+ persistentIndexes.reserve(indexes.size());
+ for (const QModelIndex &index : indexes)
+ persistentIndexes.emplaceBack(index);
+
+ return persistentIndexes;
+ }
+}
+
TorrentContentWidget::TorrentContentWidget(QWidget *parent)
: QTreeView(parent)
{
@@ -173,10 +186,20 @@ Path TorrentContentWidget::getItemPath(const QModelIndex &index) const
return path;
}
-void TorrentContentWidget::setFilterPattern(const QString &patternText)
+void TorrentContentWidget::setFilterPattern(const QString &patternText, const FilterPatternFormat format)
{
- const QString pattern = Utils::String::wildcardToRegexPattern(patternText);
- m_filterModel->setFilterRegularExpression(QRegularExpression(pattern, QRegularExpression::CaseInsensitiveOption));
+ if (format == FilterPatternFormat::PlainText)
+ {
+ m_filterModel->setFilterFixedString(patternText);
+ m_filterModel->setFilterCaseSensitivity(Qt::CaseInsensitive);
+ }
+ else
+ {
+ const QString pattern = ((format == FilterPatternFormat::Regex)
+ ? patternText : Utils::String::wildcardToRegexPattern(patternText));
+ m_filterModel->setFilterRegularExpression(QRegularExpression(pattern, QRegularExpression::CaseInsensitiveOption));
+ }
+
if (patternText.isEmpty())
{
collapseAll();
@@ -219,9 +242,9 @@ void TorrentContentWidget::keyPressEvent(QKeyEvent *event)
const Qt::CheckState state = (static_cast(value.toInt()) == Qt::Checked)
? Qt::Unchecked : Qt::Checked;
- const QModelIndexList selection = selectionModel()->selectedRows(TorrentContentModelItem::COL_NAME);
+ const QList selection = toPersistentIndexes(selectionModel()->selectedRows(TorrentContentModelItem::COL_NAME));
- for (const QModelIndex &index : selection)
+ for (const QPersistentModelIndex &index : selection)
model()->setData(index, state, Qt::CheckStateRole);
}
@@ -248,10 +271,10 @@ void TorrentContentWidget::renameSelectedFile()
void TorrentContentWidget::applyPriorities(const BitTorrent::DownloadPriority priority)
{
- const QModelIndexList selectedRows = selectionModel()->selectedRows(0);
- for (const QModelIndex &index : selectedRows)
+ const QList selectedRows = toPersistentIndexes(selectionModel()->selectedRows(Priority));
+ for (const QPersistentModelIndex &index : selectedRows)
{
- model()->setData(index.sibling(index.row(), Priority), static_cast(priority));
+ model()->setData(index, static_cast(priority));
}
}
@@ -261,7 +284,7 @@ void TorrentContentWidget::applyPrioritiesByOrder()
// a download priority that will apply to each item. The number of groups depends on how
// many "download priority" are available to be assigned
- const QModelIndexList selectedRows = selectionModel()->selectedRows(0);
+ const QList selectedRows = toPersistentIndexes(selectionModel()->selectedRows(Priority));
const qsizetype priorityGroups = 3;
const auto priorityGroupSize = std::max((selectedRows.length() / priorityGroups), 1);
@@ -283,8 +306,8 @@ void TorrentContentWidget::applyPrioritiesByOrder()
break;
}
- const QModelIndex &index = selectedRows[i];
- model()->setData(index.sibling(index.row(), Priority), static_cast(priority));
+ const QPersistentModelIndex &index = selectedRows[i];
+ model()->setData(index, static_cast(priority));
}
}
diff --git a/src/gui/torrentcontentwidget.h b/src/gui/torrentcontentwidget.h
index 4baccb883..1e9f0835c 100644
--- a/src/gui/torrentcontentwidget.h
+++ b/src/gui/torrentcontentwidget.h
@@ -1,6 +1,6 @@
/*
* Bittorrent Client using Qt and libtorrent.
- * Copyright (C) 2022 Vladimir Golovnev
+ * Copyright (C) 2022-2024 Vladimir Golovnev
* Copyright (C) 2014 Ivan Sorokin
*
* This program is free software; you can redistribute it and/or
@@ -33,6 +33,7 @@
#include "base/bittorrent/downloadpriority.h"
#include "base/pathfwd.h"
+#include "filterpatternformat.h"
class QShortcut;
@@ -92,7 +93,7 @@ public:
int getFileIndex(const QModelIndex &index) const;
Path getItemPath(const QModelIndex &index) const;
- void setFilterPattern(const QString &patternText);
+ void setFilterPattern(const QString &patternText, FilterPatternFormat format = FilterPatternFormat::Wildcards);
void checkAll();
void checkNone();
diff --git a/src/gui/torrentcreatordialog.cpp b/src/gui/torrentcreatordialog.cpp
index d6b5bdf53..502df4db8 100644
--- a/src/gui/torrentcreatordialog.cpp
+++ b/src/gui/torrentcreatordialog.cpp
@@ -84,11 +84,7 @@ TorrentCreatorDialog::TorrentCreatorDialog(QWidget *parent, const Path &defaultP
m_ui->setupUi(this);
m_ui->comboPieceSize->addItem(tr("Auto"), 0);
-#ifdef QBT_USES_LIBTORRENT2
- for (int i = 4; i <= 18; ++i)
-#else
for (int i = 4; i <= 17; ++i)
-#endif
{
const int size = 1024 << i;
const QString displaySize = Utils::Misc::friendlyUnit(size, false, 0);
diff --git a/src/gui/torrenttagsdialog.cpp b/src/gui/torrenttagsdialog.cpp
index 9e48443b0..9901a4ba8 100644
--- a/src/gui/torrenttagsdialog.cpp
+++ b/src/gui/torrenttagsdialog.cpp
@@ -1,6 +1,6 @@
/*
* Bittorrent Client using Qt and libtorrent.
- * Copyright (C) 2023 Vladimir Golovnev
+ * Copyright (C) 2023-2024 Vladimir Golovnev
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -37,6 +37,7 @@
#include "base/global.h"
#include "autoexpandabledialog.h"
#include "flowlayout.h"
+#include "utils.h"
#include "ui_torrenttagsdialog.h"
@@ -52,10 +53,10 @@ TorrentTagsDialog::TorrentTagsDialog(const TagSet &initialTags, QWidget *parent)
connect(m_ui->buttonBox, &QDialogButtonBox::accepted, this, &QDialog::accept);
connect(m_ui->buttonBox, &QDialogButtonBox::rejected, this, &QDialog::reject);
- auto *tagsLayout = new FlowLayout(m_ui->scrollArea);
+ auto *tagsLayout = new FlowLayout(m_ui->scrollArea->widget());
for (const Tag &tag : asConst(initialTags.united(BitTorrent::Session::instance()->tags())))
{
- auto *tagWidget = new QCheckBox(tag.toString());
+ auto *tagWidget = new QCheckBox(Utils::Gui::tagToWidgetText(tag));
if (initialTags.contains(tag))
tagWidget->setChecked(true);
tagsLayout->addWidget(tagWidget);
@@ -78,12 +79,12 @@ TorrentTagsDialog::~TorrentTagsDialog()
TagSet TorrentTagsDialog::tags() const
{
TagSet tags;
- auto *layout = m_ui->scrollArea->layout();
+ auto *layout = m_ui->scrollArea->widget()->layout();
for (int i = 0; i < (layout->count() - 1); ++i)
{
const auto *tagWidget = static_cast(layout->itemAt(i)->widget());
if (tagWidget->isChecked())
- tags.insert(Tag(tagWidget->text()));
+ tags.insert(Utils::Gui::widgetTextToTag(tagWidget->text()));
}
return tags;
@@ -111,9 +112,9 @@ void TorrentTagsDialog::addNewTag()
}
else
{
- auto *layout = m_ui->scrollArea->layout();
+ auto *layout = m_ui->scrollArea->widget()->layout();
auto *btn = layout->takeAt(layout->count() - 1);
- auto *tagWidget = new QCheckBox(tag.toString());
+ auto *tagWidget = new QCheckBox(Utils::Gui::tagToWidgetText(tag));
tagWidget->setChecked(true);
layout->addWidget(tagWidget);
layout->addItem(btn);
diff --git a/src/gui/trackerlist/trackerlistmodel.cpp b/src/gui/trackerlist/trackerlistmodel.cpp
index 92fb8acb3..0d0b8fdf7 100644
--- a/src/gui/trackerlist/trackerlistmodel.cpp
+++ b/src/gui/trackerlist/trackerlistmodel.cpp
@@ -488,11 +488,11 @@ QVariant TrackerListModel::headerData(const int section, const Qt::Orientation o
switch (section)
{
case COL_URL:
- return tr("URL/Announce endpoint");
+ return tr("URL/Announce Endpoint");
case COL_TIER:
return tr("Tier");
case COL_PROTOCOL:
- return tr("Protocol");
+ return tr("BT Protocol");
case COL_STATUS:
return tr("Status");
case COL_PEERS:
@@ -506,9 +506,9 @@ QVariant TrackerListModel::headerData(const int section, const Qt::Orientation o
case COL_MSG:
return tr("Message");
case COL_NEXT_ANNOUNCE:
- return tr("Next announce");
+ return tr("Next Announce");
case COL_MIN_ANNOUNCE:
- return tr("Min announce");
+ return tr("Min Announce");
default:
return {};
}
@@ -585,7 +585,7 @@ QVariant TrackerListModel::data(const QModelIndex &index, const int role) const
case COL_TIER:
return (isEndpoint || (index.row() < STICKY_ROW_COUNT)) ? QString() : QString::number(itemPtr->tier);
case COL_PROTOCOL:
- return isEndpoint ? tr("v%1").arg(itemPtr->btVersion) : QString();
+ return isEndpoint ? (u'v' + QString::number(itemPtr->btVersion)) : QString();
case COL_STATUS:
if (isEndpoint)
return toString(itemPtr->status);
diff --git a/src/gui/transferlistfilters/statusfilterwidget.cpp b/src/gui/transferlistfilters/statusfilterwidget.cpp
index 802b5535b..dbb75e0da 100644
--- a/src/gui/transferlistfilters/statusfilterwidget.cpp
+++ b/src/gui/transferlistfilters/statusfilterwidget.cpp
@@ -235,10 +235,7 @@ void StatusFilterWidget::applyFilter(int row)
void StatusFilterWidget::handleTorrentsLoaded(const QVector &torrents)
{
- for (const BitTorrent::Torrent *torrent : torrents)
- updateTorrentStatus(torrent);
-
- updateTexts();
+ update(torrents);
}
void StatusFilterWidget::torrentAboutToBeDeleted(BitTorrent::Torrent *const torrent)
@@ -273,6 +270,12 @@ void StatusFilterWidget::torrentAboutToBeDeleted(BitTorrent::Torrent *const torr
m_nbStalled = m_nbStalledUploading + m_nbStalledDownloading;
updateTexts();
+
+ if (Preferences::instance()->getHideZeroStatusFilters())
+ {
+ hideZeroItems();
+ updateGeometry();
+ }
}
void StatusFilterWidget::configure()
diff --git a/src/gui/transferlistfilters/trackersfilterwidget.cpp b/src/gui/transferlistfilters/trackersfilterwidget.cpp
index a166c7da7..8793868a7 100644
--- a/src/gui/transferlistfilters/trackersfilterwidget.cpp
+++ b/src/gui/transferlistfilters/trackersfilterwidget.cpp
@@ -394,15 +394,11 @@ void TrackersFilterWidget::handleTrackerStatusesUpdated(const BitTorrent::Torren
{
if (trackerEntryStatus.state == BitTorrent::TrackerEndpointState::Working)
{
+ // remove tracker from "error" and "tracker error" categories
if (errorHashesIt != m_errors.end())
- {
errorHashesIt->remove(trackerEntryStatus.url);
- }
-
if (trackerErrorHashesIt != m_trackerErrors.end())
- {
trackerErrorHashesIt->remove(trackerEntryStatus.url);
- }
const bool hasNoWarningMessages = std::all_of(trackerEntryStatus.endpoints.cbegin(), trackerEntryStatus.endpoints.cend()
, [](const BitTorrent::TrackerEndpointStatus &endpointEntry)
@@ -426,16 +422,38 @@ void TrackersFilterWidget::handleTrackerStatusesUpdated(const BitTorrent::Torren
else if ((trackerEntryStatus.state == BitTorrent::TrackerEndpointState::NotWorking)
|| (trackerEntryStatus.state == BitTorrent::TrackerEndpointState::Unreachable))
{
+ // remove tracker from "tracker error" and "warning" categories
+ if (warningHashesIt != m_warnings.end())
+ warningHashesIt->remove(trackerEntryStatus.url);
+ if (trackerErrorHashesIt != m_trackerErrors.end())
+ trackerErrorHashesIt->remove(trackerEntryStatus.url);
+
if (errorHashesIt == m_errors.end())
errorHashesIt = m_errors.insert(id, {});
errorHashesIt->insert(trackerEntryStatus.url);
}
else if (trackerEntryStatus.state == BitTorrent::TrackerEndpointState::TrackerError)
{
+ // remove tracker from "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 = 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())
diff --git a/src/gui/transferlistfilterswidget.cpp b/src/gui/transferlistfilterswidget.cpp
index feb93d1a6..348290ace 100644
--- a/src/gui/transferlistfilterswidget.cpp
+++ b/src/gui/transferlistfilterswidget.cpp
@@ -39,7 +39,6 @@
#include
#include
-#include "base/algorithm.h"
#include "base/bittorrent/session.h"
#include "base/bittorrent/torrent.h"
#include "base/bittorrent/trackerentrystatus.h"
diff --git a/src/gui/transferlistmodel.cpp b/src/gui/transferlistmodel.cpp
index cb35a51c0..63f1b3ebb 100644
--- a/src/gui/transferlistmodel.cpp
+++ b/src/gui/transferlistmodel.cpp
@@ -193,6 +193,7 @@ QVariant TransferListModel::headerData(const int section, const Qt::Orientation
case TR_INFOHASH_V1: return tr("Info Hash v1", "i.e: torrent info hash v1");
case TR_INFOHASH_V2: return tr("Info Hash v2", "i.e: torrent info hash v2");
case TR_REANNOUNCE: return tr("Reannounce In", "Indicates the time until next trackers reannounce");
+ case TR_PRIVATE: return tr("Private", "Flags private torrents");
default: return {};
}
}
@@ -357,6 +358,15 @@ QString TransferListModel::displayValue(const BitTorrent::Torrent *torrent, cons
return Utils::Misc::userFriendlyDuration(time);
};
+ const auto privateString = [hideValues](const bool isPrivate, const bool hasMetadata) -> QString
+ {
+ if (hideValues && !isPrivate)
+ return {};
+ if (hasMetadata)
+ return isPrivate ? tr("Yes") : tr("No");
+ return tr("N/A");
+ };
+
switch (column)
{
case TR_NAME:
@@ -431,6 +441,8 @@ QString TransferListModel::displayValue(const BitTorrent::Torrent *torrent, cons
return hashString(torrent->infoHash().v2());
case TR_REANNOUNCE:
return reannounceString(torrent->nextAnnounce());
+ case TR_PRIVATE:
+ return privateString(torrent->isPrivate(), torrent->hasMetadata());
}
return {};
@@ -512,6 +524,8 @@ QVariant TransferListModel::internalValue(const BitTorrent::Torrent *torrent, co
return QVariant::fromValue(torrent->infoHash().v2());
case TR_REANNOUNCE:
return torrent->nextAnnounce();
+ case TR_PRIVATE:
+ return (torrent->hasMetadata() ? torrent->isPrivate() : QVariant());
}
return {};
diff --git a/src/gui/transferlistmodel.h b/src/gui/transferlistmodel.h
index 061db4683..5942f77da 100644
--- a/src/gui/transferlistmodel.h
+++ b/src/gui/transferlistmodel.h
@@ -86,6 +86,7 @@ public:
TR_INFOHASH_V1,
TR_INFOHASH_V2,
TR_REANNOUNCE,
+ TR_PRIVATE,
NB_COLUMNS
};
diff --git a/src/gui/transferlistsortmodel.cpp b/src/gui/transferlistsortmodel.cpp
index 2f9ce6ff0..782aead74 100644
--- a/src/gui/transferlistsortmodel.cpp
+++ b/src/gui/transferlistsortmodel.cpp
@@ -59,8 +59,8 @@ namespace
int customCompare(const TagSet &left, const TagSet &right, const Utils::Compare::NaturalCompare &compare)
{
for (auto leftIter = left.cbegin(), rightIter = right.cbegin();
- (leftIter != left.cend()) && (rightIter != right.cend());
- ++leftIter, ++rightIter)
+ (leftIter != left.cend()) && (rightIter != right.cend());
+ ++leftIter, ++rightIter)
{
const int result = compare(leftIter->toString(), rightIter->toString());
if (result != 0)
@@ -84,6 +84,17 @@ namespace
return isLeftValid ? -1 : 1;
}
+ int compareAsBool(const QVariant &left, const QVariant &right)
+ {
+ const bool leftValid = left.isValid();
+ const bool rightValid = right.isValid();
+ if (leftValid && rightValid)
+ return threeWayCompare(left.toBool(), right.toBool());
+ if (!leftValid && !rightValid)
+ return 0;
+ return leftValid ? -1 : 1;
+ }
+
int adjustSubSortColumn(const int column)
{
return ((column >= 0) && (column < TransferListModel::NB_COLUMNS))
@@ -214,6 +225,9 @@ int TransferListSortModel::compare(const QModelIndex &left, const QModelIndex &r
case TransferListModel::TR_UPSPEED:
return customCompare(leftValue.toInt(), rightValue.toInt());
+ case TransferListModel::TR_PRIVATE:
+ return compareAsBool(leftValue, rightValue);
+
case TransferListModel::TR_PEERS:
case TransferListModel::TR_SEEDS:
{
diff --git a/src/gui/transferlistwidget.cpp b/src/gui/transferlistwidget.cpp
index a1b79b29e..7b857e1a3 100644
--- a/src/gui/transferlistwidget.cpp
+++ b/src/gui/transferlistwidget.cpp
@@ -1,6 +1,6 @@
/*
* Bittorrent Client using Qt and libtorrent.
- * Copyright (C) 2023 Vladimir Golovnev
+ * Copyright (C) 2023-2024 Vladimir Golovnev
* Copyright (C) 2006 Christophe Dumez
*
* This program is free software; you can redistribute it and/or
@@ -116,9 +116,10 @@ namespace
void removeTorrents(const QVector &torrents, const bool isDeleteFileSelected)
{
auto *session = BitTorrent::Session::instance();
- const DeleteOption deleteOption = isDeleteFileSelected ? DeleteTorrentAndFiles : DeleteTorrent;
+ const BitTorrent::TorrentRemoveOption removeOption = isDeleteFileSelected
+ ? BitTorrent::TorrentRemoveOption::RemoveContent : BitTorrent::TorrentRemoveOption::KeepContent;
for (const BitTorrent::Torrent *torrent : torrents)
- session->deleteTorrent(torrent->id(), deleteOption);
+ session->removeTorrent(torrent->id(), removeOption);
}
}
@@ -183,6 +184,7 @@ TransferListWidget::TransferListWidget(QWidget *parent, MainWindow *mainWindow)
setColumnHidden(TransferListModel::TR_LAST_ACTIVITY, true);
setColumnHidden(TransferListModel::TR_TOTAL_SIZE, true);
setColumnHidden(TransferListModel::TR_REANNOUNCE, true);
+ setColumnHidden(TransferListModel::TR_PRIVATE, true);
}
//Ensure that at least one column is visible at all times
@@ -442,7 +444,7 @@ void TransferListWidget::deleteSelectedTorrents(const bool deleteLocalFiles)
{
// Some torrents might be removed when waiting for user input, so refetch the torrent list
// NOTE: this will only work when dialog is modal
- removeTorrents(getSelectedTorrents(), dialog->isDeleteFileSelected());
+ removeTorrents(getSelectedTorrents(), dialog->isRemoveContentSelected());
});
dialog->open();
}
@@ -465,7 +467,7 @@ void TransferListWidget::deleteVisibleTorrents()
{
// Some torrents might be removed when waiting for user input, so refetch the torrent list
// NOTE: this will only work when dialog is modal
- removeTorrents(getVisibleTorrents(), dialog->isDeleteFileSelected());
+ removeTorrents(getVisibleTorrents(), dialog->isRemoveContentSelected());
});
dialog->open();
}
@@ -1190,7 +1192,7 @@ void TransferListWidget::displayListMenu()
const TagSet tags = BitTorrent::Session::instance()->tags();
for (const Tag &tag : asConst(tags))
{
- auto *action = new TriStateAction(tag.toString(), tagsMenu);
+ auto *action = new TriStateAction(Utils::Gui::tagToWidgetText(tag), tagsMenu);
action->setCloseOnInteraction(false);
const Qt::CheckState initialState = tagsInAll.contains(tag) ? Qt::Checked
diff --git a/src/gui/uithememanager.cpp b/src/gui/uithememanager.cpp
index d27a91c78..f20f5e0a3 100644
--- a/src/gui/uithememanager.cpp
+++ b/src/gui/uithememanager.cpp
@@ -47,16 +47,9 @@ namespace
{
bool isDarkTheme()
{
- switch (qApp->styleHints()->colorScheme())
- {
- case Qt::ColorScheme::Dark:
- return true;
- case Qt::ColorScheme::Light:
- return false;
- default:
- // fallback to custom method
- return (qApp->palette().color(QPalette::Active, QPalette::Base).lightness() < 127);
- }
+ const QPalette palette = qApp->palette();
+ const QColor &color = palette.color(QPalette::Active, QPalette::Base);
+ return (color.lightness() < 127);
}
}
@@ -80,6 +73,14 @@ UIThemeManager::UIThemeManager()
, m_useSystemIcons {Preferences::instance()->useSystemIcons()}
#endif
{
+#ifdef Q_OS_WIN
+ if (const QString styleName = Preferences::instance()->getStyle(); styleName.compare(u"system", Qt::CaseInsensitive) != 0)
+ {
+ if (!QApplication::setStyle(styleName.isEmpty() ? u"Fusion"_s : styleName))
+ LogMsg(tr("Set app style failed. Unknown style: \"%1\"").arg(styleName), Log::WARNING);
+ }
+#endif
+
// NOTE: Qt::QueuedConnection can be omitted as soon as support for Qt 6.5 is dropped
connect(QApplication::styleHints(), &QStyleHints::colorSchemeChanged, this, &UIThemeManager::onColorSchemeChanged, Qt::QueuedConnection);
diff --git a/src/gui/utils.cpp b/src/gui/utils.cpp
index c7c1f24c4..f310c7f26 100644
--- a/src/gui/utils.cpp
+++ b/src/gui/utils.cpp
@@ -1,5 +1,6 @@
/*
* Bittorrent Client using Qt and libtorrent.
+ * Copyright (C) 2024 Vladimir Golovnev
* Copyright (C) 2017 Mike Tzou
*
* This program is free software; you can redistribute it and/or
@@ -54,6 +55,7 @@
#include "base/global.h"
#include "base/path.h"
+#include "base/tag.h"
#include "base/utils/fs.h"
#include "base/utils/version.h"
@@ -216,3 +218,29 @@ void Utils::Gui::openFolderSelect(const Path &path)
openPath(path.parentPath());
#endif
}
+
+QString Utils::Gui::tagToWidgetText(const Tag &tag)
+{
+ return tag.toString().replace(u'&', u"&&"_s);
+}
+
+Tag Utils::Gui::widgetTextToTag(const QString &text)
+{
+ // replace pairs of '&' with single '&' and remove non-paired occurrences of '&'
+ QString cleanedText;
+ cleanedText.reserve(text.size());
+ bool amp = false;
+ for (const QChar c : text)
+ {
+ if (c == u'&')
+ {
+ amp = !amp;
+ if (amp)
+ continue;
+ }
+
+ cleanedText.append(c);
+ }
+
+ return Tag(cleanedText);
+}
diff --git a/src/gui/utils.h b/src/gui/utils.h
index c633cb45d..46a49c2f6 100644
--- a/src/gui/utils.h
+++ b/src/gui/utils.h
@@ -1,5 +1,6 @@
/*
* Bittorrent Client using Qt and libtorrent.
+ * Copyright (C) 2024 Vladimir Golovnev
* Copyright (C) 2017 Mike Tzou
*
* This program is free software; you can redistribute it and/or
@@ -34,8 +35,11 @@ class QIcon;
class QPixmap;
class QPoint;
class QSize;
+class QString;
class QWidget;
+class Tag;
+
namespace Utils::Gui
{
bool isDarkTheme();
@@ -51,4 +55,7 @@ namespace Utils::Gui
void openPath(const Path &path);
void openFolderSelect(const Path &path);
+
+ QString tagToWidgetText(const Tag &tag);
+ Tag widgetTextToTag(const QString &text);
}
diff --git a/src/icons/flags/ad.svg b/src/icons/flags/ad.svg
index 3793d99aa..067ab772f 100644
--- a/src/icons/flags/ad.svg
+++ b/src/icons/flags/ad.svg
@@ -2,16 +2,16 @@
-
+
-
+
-
+
@@ -96,11 +96,11 @@
-
+
-
+
@@ -110,17 +110,17 @@
-
-
-
+
+
+
-
+
-
-
-
+
+
+
@@ -128,21 +128,21 @@
-
+
-
+
-
+
-
+
-
+
diff --git a/src/icons/flags/ae.svg b/src/icons/flags/ae.svg
index b7acdbdb3..651ac8523 100644
--- a/src/icons/flags/ae.svg
+++ b/src/icons/flags/ae.svg
@@ -1,6 +1,6 @@
diff --git a/src/icons/flags/af.svg b/src/icons/flags/af.svg
index 417dd0476..521ac4cfd 100644
--- a/src/icons/flags/af.svg
+++ b/src/icons/flags/af.svg
@@ -1,29 +1,29 @@
diff --git a/src/icons/flags/ag.svg b/src/icons/flags/ag.svg
index 250b50126..243c3d8f9 100644
--- a/src/icons/flags/ag.svg
+++ b/src/icons/flags/ag.svg
@@ -4,11 +4,11 @@
-
-
-
-
-
-
+
+
+
+
+
+
diff --git a/src/icons/flags/ai.svg b/src/icons/flags/ai.svg
index 81a857d5b..628ad9be9 100644
--- a/src/icons/flags/ai.svg
+++ b/src/icons/flags/ai.svg
@@ -1,17 +1,17 @@
diff --git a/src/icons/flags/al.svg b/src/icons/flags/al.svg
index b69ae195d..1135b4b80 100644
--- a/src/icons/flags/al.svg
+++ b/src/icons/flags/al.svg
@@ -1,5 +1,5 @@
diff --git a/src/icons/flags/ao.svg b/src/icons/flags/ao.svg
index 4dc39f6aa..b1863bd0f 100644
--- a/src/icons/flags/ao.svg
+++ b/src/icons/flags/ao.svg
@@ -1,12 +1,12 @@
-
+
@@ -60,7 +60,7 @@
-
+
diff --git a/src/icons/flags/as.svg b/src/icons/flags/as.svg
index b974013ac..354355672 100644
--- a/src/icons/flags/as.svg
+++ b/src/icons/flags/as.svg
@@ -6,67 +6,67 @@
-
+
-
-
+
+
-
-
+
+
-
-
-
-
+
+
+
+
-
-
-
+
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
+
-
+
-
-
+
+
-
-
+
+
-
+
-
+
-
-
-
-
+
+
+
+
-
+
-
-
+
+
-
-
-
-
-
-
-
+
+
+
+
+
+
+
-
+
diff --git a/src/icons/flags/at.svg b/src/icons/flags/at.svg
index c28250887..9d2775c08 100644
--- a/src/icons/flags/at.svg
+++ b/src/icons/flags/at.svg
@@ -1,6 +1,4 @@
-
-
-
-
+
+
diff --git a/src/icons/flags/au.svg b/src/icons/flags/au.svg
index 407fef43d..96e80768b 100644
--- a/src/icons/flags/au.svg
+++ b/src/icons/flags/au.svg
@@ -2,7 +2,7 @@
-
+
-
+
diff --git a/src/icons/flags/aw.svg b/src/icons/flags/aw.svg
index 32cabd545..413b7c45b 100644
--- a/src/icons/flags/aw.svg
+++ b/src/icons/flags/aw.svg
@@ -5,182 +5,182 @@
-
-
+
+
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/icons/flags/az.svg b/src/icons/flags/az.svg
index 8e56ef53c..355752211 100644
--- a/src/icons/flags/az.svg
+++ b/src/icons/flags/az.svg
@@ -4,5 +4,5 @@
-
+
diff --git a/src/icons/flags/ba.svg b/src/icons/flags/ba.svg
index fcd18914a..93bd9cf93 100644
--- a/src/icons/flags/ba.svg
+++ b/src/icons/flags/ba.svg
@@ -4,9 +4,9 @@
-
-
-
-
+
+
+
+
diff --git a/src/icons/flags/bb.svg b/src/icons/flags/bb.svg
index 263bdec05..cecd5cc33 100644
--- a/src/icons/flags/bb.svg
+++ b/src/icons/flags/bb.svg
@@ -1,6 +1,6 @@
-
+
diff --git a/src/icons/flags/be.svg b/src/icons/flags/be.svg
index 327f28fa2..ac706a0b5 100644
--- a/src/icons/flags/be.svg
+++ b/src/icons/flags/be.svg
@@ -1,6 +1,6 @@
-
+
diff --git a/src/icons/flags/bg.svg b/src/icons/flags/bg.svg
index b100dd0dc..af2d0d07c 100644
--- a/src/icons/flags/bg.svg
+++ b/src/icons/flags/bg.svg
@@ -1,7 +1,5 @@
-
-
-
-
-
+
+
+
diff --git a/src/icons/flags/bi.svg b/src/icons/flags/bi.svg
index 1050838bc..a4434a955 100644
--- a/src/icons/flags/bi.svg
+++ b/src/icons/flags/bi.svg
@@ -4,7 +4,7 @@
-
+
diff --git a/src/icons/flags/bl.svg b/src/icons/flags/bl.svg
index 819afc111..f84cbbaeb 100644
--- a/src/icons/flags/bl.svg
+++ b/src/icons/flags/bl.svg
@@ -1,5 +1,5 @@
-
-
+
+
diff --git a/src/icons/flags/bm.svg b/src/icons/flags/bm.svg
index a4dbc728f..bab3e0abe 100644
--- a/src/icons/flags/bm.svg
+++ b/src/icons/flags/bm.svg
@@ -8,18 +8,18 @@
-
+
-
+
-
+
@@ -57,38 +57,38 @@
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
-
+
+
-
-
+
+
-
+
diff --git a/src/icons/flags/bn.svg b/src/icons/flags/bn.svg
index f906abfeb..4b416ebb7 100644
--- a/src/icons/flags/bn.svg
+++ b/src/icons/flags/bn.svg
@@ -1,36 +1,36 @@
-
-
-
+
+
+
-
+
-
-
-
-
+
+
+
+
-
-
-
-
+
+
+
+
-
+
-
+
-
-
-
-
-
-
+
+
+
+
+
+
diff --git a/src/icons/flags/bo.svg b/src/icons/flags/bo.svg
index 17a0a0c12..46dc76735 100644
--- a/src/icons/flags/bo.svg
+++ b/src/icons/flags/bo.svg
@@ -73,10 +73,10 @@
-
+
-
+
@@ -101,19 +101,19 @@
-
+
-
-
-
-
+
+
+
+
-
+
@@ -139,16 +139,16 @@
-
-
-
-
+
+
+
+
-
+
-
+
@@ -157,21 +157,21 @@
-
+
-
+
-
+
-
+
@@ -183,24 +183,24 @@
-
+
-
+
-
+
-
+
-
+
-
+
-
+
@@ -299,28 +299,28 @@
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
-
-
+
+
-
-
-
-
+
+
+
+
@@ -330,157 +330,155 @@
-
+
-
+
-
-
-
+
-
+
-
+
-
+
-
-
+
+
-
-
-
-
+
+
+
+
-
-
+
+
-
-
-
-
-
+
+
+
+
+
-
-
-
+
+
+
-
-
-
-
-
-
-
+
+
+
+
+
+
+
-
+
-
-
-
+
+
+
-
-
-
-
+
+
+
+
-
-
+
+
-
-
-
+
+
+
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
+
+
+
+
+
+
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
-
-
-
+
+
+
-
-
+
+
-
-
-
+
+
+
-
-
-
-
-
-
+
+
+
+
+
+
-
-
+
+
@@ -491,18 +489,18 @@
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
@@ -510,41 +508,41 @@
-
-
+
+
-
+
-
+
-
+
-
-
-
-
+
+
+
+
-
-
-
-
-
-
+
+
+
+
+
+
-
+
@@ -558,7 +556,7 @@
-
+
@@ -566,33 +564,33 @@
-
-
-
+
+
+
-
+
-
-
-
-
+
+
+
+
-
+
-
-
-
-
-
+
+
+
+
+
-
-
+
+
@@ -600,19 +598,19 @@
-
+
-
-
+
+
-
+
@@ -620,54 +618,54 @@
-
+
-
-
+
+
-
-
-
-
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
+
-
-
-
+
+
+
-
+
-
+
diff --git a/src/icons/flags/br.svg b/src/icons/flags/br.svg
index 354a7013f..22c908e7e 100644
--- a/src/icons/flags/br.svg
+++ b/src/icons/flags/br.svg
@@ -1,45 +1,45 @@
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
+
-
+
-
-
+
+
-
-
+
+
-
+
-
+
diff --git a/src/icons/flags/bs.svg b/src/icons/flags/bs.svg
index 513be43ac..5cc918e5a 100644
--- a/src/icons/flags/bs.svg
+++ b/src/icons/flags/bs.svg
@@ -8,6 +8,6 @@
-
+
diff --git a/src/icons/flags/bt.svg b/src/icons/flags/bt.svg
index cea6006c1..798c79b38 100644
--- a/src/icons/flags/bt.svg
+++ b/src/icons/flags/bt.svg
@@ -3,25 +3,25 @@
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
-
-
-
-
+
+
+
+
-
+
@@ -60,7 +60,7 @@
-
+
@@ -68,7 +68,7 @@
-
+
diff --git a/src/icons/flags/bw.svg b/src/icons/flags/bw.svg
index a1c8db0af..3435608d6 100644
--- a/src/icons/flags/bw.svg
+++ b/src/icons/flags/bw.svg
@@ -2,6 +2,6 @@
-
+
diff --git a/src/icons/flags/by.svg b/src/icons/flags/by.svg
index 8d25ee3c1..7e90ff255 100644
--- a/src/icons/flags/by.svg
+++ b/src/icons/flags/by.svg
@@ -1,20 +1,18 @@
-
+
-
+
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
diff --git a/src/icons/flags/bz.svg b/src/icons/flags/bz.svg
index 08d3579de..25386a51a 100644
--- a/src/icons/flags/bz.svg
+++ b/src/icons/flags/bz.svg
@@ -17,16 +17,16 @@
-
-
+
+
-
-
+
+
-
+
-
+
@@ -40,7 +40,7 @@
-
+
@@ -52,7 +52,7 @@
-
+
@@ -60,9 +60,9 @@
-
+
-
+
@@ -70,21 +70,21 @@
-
+
-
+
-
+
-
+
@@ -92,7 +92,7 @@
-
+
@@ -104,42 +104,42 @@
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
diff --git a/src/icons/flags/ca.svg b/src/icons/flags/ca.svg
index f1b2c968a..89da5b7b5 100644
--- a/src/icons/flags/ca.svg
+++ b/src/icons/flags/ca.svg
@@ -1,4 +1,4 @@
-
+
diff --git a/src/icons/flags/cc.svg b/src/icons/flags/cc.svg
index 93025bd2d..ddfd18038 100644
--- a/src/icons/flags/cc.svg
+++ b/src/icons/flags/cc.svg
@@ -8,8 +8,8 @@
-
-
+
+
diff --git a/src/icons/flags/cd.svg b/src/icons/flags/cd.svg
index e106ddd53..b9cf52894 100644
--- a/src/icons/flags/cd.svg
+++ b/src/icons/flags/cd.svg
@@ -1,5 +1,5 @@
-
-
+
+
diff --git a/src/icons/flags/cg.svg b/src/icons/flags/cg.svg
index 9128715f6..f5a0e42d4 100644
--- a/src/icons/flags/cg.svg
+++ b/src/icons/flags/cg.svg
@@ -6,7 +6,7 @@
-
-
+
+
diff --git a/src/icons/flags/cl.svg b/src/icons/flags/cl.svg
index 01766fefd..5b3c72fa7 100644
--- a/src/icons/flags/cl.svg
+++ b/src/icons/flags/cl.svg
@@ -7,7 +7,7 @@
-
+
diff --git a/src/icons/flags/cm.svg b/src/icons/flags/cm.svg
index 389b66277..70adc8b68 100644
--- a/src/icons/flags/cm.svg
+++ b/src/icons/flags/cm.svg
@@ -2,7 +2,7 @@
-
+
diff --git a/src/icons/flags/cp.svg b/src/icons/flags/cp.svg
index b3efb0742..b8aa9cfd6 100644
--- a/src/icons/flags/cp.svg
+++ b/src/icons/flags/cp.svg
@@ -1,7 +1,7 @@
-
-
+
+
diff --git a/src/icons/flags/cu.svg b/src/icons/flags/cu.svg
index 6464f8eba..053c9ee3a 100644
--- a/src/icons/flags/cu.svg
+++ b/src/icons/flags/cu.svg
@@ -4,10 +4,10 @@
-
+
-
-
+
+
diff --git a/src/icons/flags/cv.svg b/src/icons/flags/cv.svg
index 5c251da2a..aec899490 100644
--- a/src/icons/flags/cv.svg
+++ b/src/icons/flags/cv.svg
@@ -4,7 +4,7 @@
-
+
diff --git a/src/icons/flags/cx.svg b/src/icons/flags/cx.svg
index 6803b3b66..374ff2dab 100644
--- a/src/icons/flags/cx.svg
+++ b/src/icons/flags/cx.svg
@@ -2,11 +2,11 @@
-
+
-
+
-
+
diff --git a/src/icons/flags/cy.svg b/src/icons/flags/cy.svg
index 2f69bf79f..7e3d883da 100644
--- a/src/icons/flags/cy.svg
+++ b/src/icons/flags/cy.svg
@@ -1,6 +1,6 @@
-
+
-
+
diff --git a/src/icons/flags/de.svg b/src/icons/flags/de.svg
index b08334b62..71aa2d2c3 100644
--- a/src/icons/flags/de.svg
+++ b/src/icons/flags/de.svg
@@ -1,5 +1,5 @@
-
-
-
+
+
+
diff --git a/src/icons/flags/dg.svg b/src/icons/flags/dg.svg
index b9f99a99d..f163caf94 100644
--- a/src/icons/flags/dg.svg
+++ b/src/icons/flags/dg.svg
@@ -30,7 +30,7 @@
-
+
@@ -104,8 +104,8 @@
-
-
+
+
@@ -120,7 +120,7 @@
-
+
diff --git a/src/icons/flags/dj.svg b/src/icons/flags/dj.svg
index ebf2fc66f..9b00a8205 100644
--- a/src/icons/flags/dj.svg
+++ b/src/icons/flags/dj.svg
@@ -4,10 +4,10 @@
-
+
-
+
diff --git a/src/icons/flags/dm.svg b/src/icons/flags/dm.svg
index 60457b796..f692094dd 100644
--- a/src/icons/flags/dm.svg
+++ b/src/icons/flags/dm.svg
@@ -4,66 +4,66 @@
-
+
-
-
+
+
-
+
-
-
+
+
-
-
-
+
+
+
-
-
-
+
+
+
-
-
-
+
+
+
-
-
+
+
-
-
-
+
+
+
-
+
-
+
-
-
+
+
-
+
-
+
-
+
diff --git a/src/icons/flags/do.svg b/src/icons/flags/do.svg
index d83769005..b1be393ed 100644
--- a/src/icons/flags/do.svg
+++ b/src/icons/flags/do.svg
@@ -2,64 +2,64 @@
-
+
-
-
-
+
+
+
-
-
-
+
+
+
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
-
-
+
+
-
+
-
-
-
-
-
-
+
+
+
+
+
+
-
-
-
+
+
+
-
-
-
-
+
+
+
+
-
-
-
-
-
+
+
+
+
+
-
+
@@ -67,20 +67,20 @@
-
-
-
-
-
+
+
+
+
+
-
+
-
+
@@ -101,7 +101,7 @@
-
+
@@ -110,12 +110,12 @@
-
+
-
+
-
-
+
+
diff --git a/src/icons/flags/eac.svg b/src/icons/flags/eac.svg
index 25a09a132..aaf8133f3 100644
--- a/src/icons/flags/eac.svg
+++ b/src/icons/flags/eac.svg
@@ -4,45 +4,45 @@
-
+
-
+
-
+
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
-
-
+
+
-
-
-
-
-
+
+
+
+
+
-
-
+
+
diff --git a/src/icons/flags/ec.svg b/src/icons/flags/ec.svg
index 65b78858a..397bfd982 100644
--- a/src/icons/flags/ec.svg
+++ b/src/icons/flags/ec.svg
@@ -5,15 +5,15 @@
-
-
-
+
+
+
-
-
-
-
-
+
+
+
+
+
@@ -40,9 +40,9 @@
-
-
-
+
+
+
@@ -50,15 +50,15 @@
-
-
-
+
+
+
-
-
-
-
+
+
+
+
@@ -73,10 +73,10 @@
-
-
-
-
+
+
+
+
@@ -86,53 +86,53 @@
-
-
-
-
+
+
+
+
-
-
-
-
+
+
+
+
-
+
-
+
-
-
-
+
+
+
-
-
+
+
-
+
-
+
-
+
-
+
-
-
+
+
-
+
diff --git a/src/icons/flags/ee.svg b/src/icons/flags/ee.svg
index 36ea288ca..8b98c2c42 100644
--- a/src/icons/flags/ee.svg
+++ b/src/icons/flags/ee.svg
@@ -1,7 +1,5 @@
-
-
-
-
-
+
+
+
diff --git a/src/icons/flags/eg.svg b/src/icons/flags/eg.svg
index 58c943c23..00d1fa59e 100644
--- a/src/icons/flags/eg.svg
+++ b/src/icons/flags/eg.svg
@@ -1,37 +1,37 @@
-
+
-
-
-
+
+
+
-
+
-
-
-
-
+
+
+
+
-
-
+
+
-
+
-
+
diff --git a/src/icons/flags/eh.svg b/src/icons/flags/eh.svg
index 2c9525bd0..6aec72883 100644
--- a/src/icons/flags/eh.svg
+++ b/src/icons/flags/eh.svg
@@ -4,8 +4,8 @@
-
-
+
+
diff --git a/src/icons/flags/er.svg b/src/icons/flags/er.svg
index 2705295f2..3f4f3f292 100644
--- a/src/icons/flags/er.svg
+++ b/src/icons/flags/er.svg
@@ -1,8 +1,8 @@
-
-
-
+
+
+
diff --git a/src/icons/flags/es-ga.svg b/src/icons/flags/es-ga.svg
index a91ffed06..31657813e 100644
--- a/src/icons/flags/es-ga.svg
+++ b/src/icons/flags/es-ga.svg
@@ -1,7 +1,7 @@
-
+
@@ -10,27 +10,27 @@
-
+
-
+
-
+
-
+
-
+
@@ -124,7 +124,7 @@
-
+
@@ -136,11 +136,11 @@
-
+
-
-
+
+
@@ -150,7 +150,7 @@
-
+
@@ -181,7 +181,7 @@
-
+
diff --git a/src/icons/flags/es.svg b/src/icons/flags/es.svg
index 815e0f846..acdf927f2 100644
--- a/src/icons/flags/es.svg
+++ b/src/icons/flags/es.svg
@@ -8,20 +8,20 @@
-
+
-
+
-
-
+
+
-
+
-
-
+
+
@@ -30,15 +30,15 @@
-
+
-
+
-
+
-
+
@@ -46,33 +46,33 @@
-
-
+
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
@@ -82,54 +82,54 @@
-
-
+
+
-
-
+
+
-
-
-
+
+
+
-
+
-
+
-
-
+
+
-
-
+
+
-
+
-
+
-
+
@@ -153,49 +153,49 @@
-
+
-
+
-
+
-
+
-
-
+
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
@@ -206,16 +206,16 @@
-
-
+
+
-
-
+
+
-
-
+
+
@@ -232,25 +232,25 @@
-
-
+
+
-
-
+
+
-
+
-
+
-
+
@@ -276,24 +276,24 @@
-
+
-
+
-
-
+
+
-
+
-
+
-
-
+
+
@@ -309,65 +309,65 @@
-
+
-
-
+
+
-
-
+
+
-
-
-
+
+
+
-
-
-
-
+
+
+
+
-
-
+
+
-
-
-
-
+
+
+
+
-
-
-
+
+
+
-
+
-
+
-
-
+
+
-
-
-
-
+
+
+
+
-
-
+
+
@@ -462,78 +462,78 @@
-
-
-
-
+
+
+
+
-
-
+
+
-
-
+
+
-
-
-
-
+
+
+
+
-
+
-
+
-
-
-
+
+
+
-
+
-
+
-
-
-
+
+
+
-
-
-
+
+
+
-
+
-
+
-
+
-
+
-
+
-
-
-
+
+
+
-
-
+
+
diff --git a/src/icons/flags/et.svg b/src/icons/flags/et.svg
index a3378fd95..3f99be486 100644
--- a/src/icons/flags/et.svg
+++ b/src/icons/flags/et.svg
@@ -4,11 +4,11 @@
-
+
-
+
diff --git a/src/icons/flags/eu.svg b/src/icons/flags/eu.svg
index bbfefd6b4..b0874c1ed 100644
--- a/src/icons/flags/eu.svg
+++ b/src/icons/flags/eu.svg
@@ -13,7 +13,7 @@
-
+
diff --git a/src/icons/flags/fj.svg b/src/icons/flags/fj.svg
index 2d7cd980c..23fbe57a8 100644
--- a/src/icons/flags/fj.svg
+++ b/src/icons/flags/fj.svg
@@ -1,11 +1,11 @@
-
+
-
+
@@ -13,41 +13,41 @@
-
-
+
+
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
+
+
+
+
+
+
-
+
-
+
-
+
@@ -56,17 +56,17 @@
-
+
-
+
-
+
-
+
@@ -75,25 +75,25 @@
-
-
-
-
+
+
+
+
-
-
+
+
-
-
-
-
-
+
+
+
+
+
-
+
@@ -101,15 +101,15 @@
-
+
-
-
-
-
-
+
+
+
+
+
diff --git a/src/icons/flags/fk.svg b/src/icons/flags/fk.svg
index b4935a55e..c65bf96de 100644
--- a/src/icons/flags/fk.svg
+++ b/src/icons/flags/fk.svg
@@ -21,27 +21,27 @@
-
+
-
+
-
-
-
+
+
+
-
-
+
+
-
+
@@ -56,13 +56,13 @@
-
+
-
+
diff --git a/src/icons/flags/fm.svg b/src/icons/flags/fm.svg
index 85f4f47ec..c1b7c9778 100644
--- a/src/icons/flags/fm.svg
+++ b/src/icons/flags/fm.svg
@@ -4,7 +4,7 @@
-
+
diff --git a/src/icons/flags/fo.svg b/src/icons/flags/fo.svg
index 717ee20b8..f802d285a 100644
--- a/src/icons/flags/fo.svg
+++ b/src/icons/flags/fo.svg
@@ -6,7 +6,7 @@
-
-
+
+
diff --git a/src/icons/flags/fr.svg b/src/icons/flags/fr.svg
index 79689fe94..4110e59e4 100644
--- a/src/icons/flags/fr.svg
+++ b/src/icons/flags/fr.svg
@@ -1,5 +1,5 @@
-
-
+
+
diff --git a/src/icons/flags/gb-nir.svg b/src/icons/flags/gb-nir.svg
index c9510f30c..e6be8dbc2 100644
--- a/src/icons/flags/gb-nir.svg
+++ b/src/icons/flags/gb-nir.svg
@@ -5,10 +5,10 @@
-
+
-
+
@@ -19,20 +19,20 @@
-
+
-
+
-
+
-
+
-
+
@@ -40,30 +40,30 @@
-
+
-
+
-
+
-
+
-
+
-
+
@@ -72,56 +72,56 @@
-
+
-
+
-
+
-
+
-
+
-
+
-
-
+
+
-
-
-
+
+
+
-
+
-
+
-
+
-
-
+
+
-
+
-
+
diff --git a/src/icons/flags/gb.svg b/src/icons/flags/gb.svg
index dbac25eae..799138319 100644
--- a/src/icons/flags/gb.svg
+++ b/src/icons/flags/gb.svg
@@ -1,7 +1,7 @@
-
-
-
-
+
+
+
+
diff --git a/src/icons/flags/gd.svg b/src/icons/flags/gd.svg
index f44e83913..cb51e9618 100644
--- a/src/icons/flags/gd.svg
+++ b/src/icons/flags/gd.svg
@@ -15,13 +15,13 @@
-
+
-
+
-
-
+
+
-
+
diff --git a/src/icons/flags/gf.svg b/src/icons/flags/gf.svg
index 734934266..f8fe94c65 100644
--- a/src/icons/flags/gf.svg
+++ b/src/icons/flags/gf.svg
@@ -1,5 +1,5 @@
-
-
+
+
diff --git a/src/icons/flags/gh.svg b/src/icons/flags/gh.svg
index a6497de88..5c3e3e69a 100644
--- a/src/icons/flags/gh.svg
+++ b/src/icons/flags/gh.svg
@@ -2,5 +2,5 @@
-
+
diff --git a/src/icons/flags/gi.svg b/src/icons/flags/gi.svg
index 92496be6b..e2b590afe 100644
--- a/src/icons/flags/gi.svg
+++ b/src/icons/flags/gi.svg
@@ -1,18 +1,18 @@
-
+
-
+
-
+
-
+
@@ -20,10 +20,10 @@
-
+
-
+
diff --git a/src/icons/flags/gp.svg b/src/icons/flags/gp.svg
index 528e554f0..ee55c4bcd 100644
--- a/src/icons/flags/gp.svg
+++ b/src/icons/flags/gp.svg
@@ -1,5 +1,5 @@
-
-
+
+
diff --git a/src/icons/flags/gq.svg b/src/icons/flags/gq.svg
index ba2acf28d..134e44217 100644
--- a/src/icons/flags/gq.svg
+++ b/src/icons/flags/gq.svg
@@ -4,7 +4,7 @@
-
+
@@ -16,8 +16,8 @@
-
+
-
+
diff --git a/src/icons/flags/gs.svg b/src/icons/flags/gs.svg
index 2e045dfdd..1536e073e 100644
--- a/src/icons/flags/gs.svg
+++ b/src/icons/flags/gs.svg
@@ -27,27 +27,27 @@
-
+
-
-
+
+
-
+
-
-
+
+
-
+
-
+
@@ -65,7 +65,7 @@
-
+
@@ -96,14 +96,14 @@
-
+
-
+
@@ -113,7 +113,7 @@
-
+
@@ -124,7 +124,7 @@
-
+
diff --git a/src/icons/flags/gt.svg b/src/icons/flags/gt.svg
index 9b3471244..f7cffbdc7 100644
--- a/src/icons/flags/gt.svg
+++ b/src/icons/flags/gt.svg
@@ -118,27 +118,27 @@
-
-
-
-
-
+
+
+
+
+
-
+
-
+
-
+
-
+
-
+
@@ -148,53 +148,53 @@
-
+
-
+
-
-
+
+
-
+
-
+
-
-
+
+
-
+
-
-
+
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
diff --git a/src/icons/flags/gu.svg b/src/icons/flags/gu.svg
index a5584ffd4..0d66e1bfa 100644
--- a/src/icons/flags/gu.svg
+++ b/src/icons/flags/gu.svg
@@ -2,22 +2,22 @@
-
-
+
+
-
-
- G
- U
- A
- M
-
+
+
+ G
+ U
+ A
+ M
+
-
-
-
-
-
+
+
+
+
+
diff --git a/src/icons/flags/gw.svg b/src/icons/flags/gw.svg
index b8d566a2a..d470bac9f 100644
--- a/src/icons/flags/gw.svg
+++ b/src/icons/flags/gw.svg
@@ -3,7 +3,7 @@
-
+
diff --git a/src/icons/flags/gy.svg b/src/icons/flags/gy.svg
index f4d9b8ab2..569fb5627 100644
--- a/src/icons/flags/gy.svg
+++ b/src/icons/flags/gy.svg
@@ -1,9 +1,9 @@
-
+
-
+
diff --git a/src/icons/flags/hk.svg b/src/icons/flags/hk.svg
index ec40b5fed..4fd55bc14 100644
--- a/src/icons/flags/hk.svg
+++ b/src/icons/flags/hk.svg
@@ -1,6 +1,6 @@
-
+
diff --git a/src/icons/flags/hm.svg b/src/icons/flags/hm.svg
index c0748d3be..815c48208 100644
--- a/src/icons/flags/hm.svg
+++ b/src/icons/flags/hm.svg
@@ -2,7 +2,7 @@
-
+
-
+
diff --git a/src/icons/flags/hn.svg b/src/icons/flags/hn.svg
index 1c166dc46..11fde67db 100644
--- a/src/icons/flags/hn.svg
+++ b/src/icons/flags/hn.svg
@@ -1,7 +1,7 @@
-
+
diff --git a/src/icons/flags/hr.svg b/src/icons/flags/hr.svg
index febbc2400..44fed27d5 100644
--- a/src/icons/flags/hr.svg
+++ b/src/icons/flags/hr.svg
@@ -4,55 +4,55 @@
-
-
+
+
-
-
+
+
-
-
-
+
+
+
-
+
-
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
-
+
+
+
-
+
-
+
-
+
-
-
-
-
+
+
+
+
diff --git a/src/icons/flags/ht.svg b/src/icons/flags/ht.svg
index 4cd4470f4..5d48eb93b 100644
--- a/src/icons/flags/ht.svg
+++ b/src/icons/flags/ht.svg
@@ -4,37 +4,37 @@
-
+
-
+
-
-
-
+
+
+
-
-
-
+
+
+
-
-
+
+
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
-
-
+
+
@@ -44,36 +44,36 @@
-
-
-
-
-
+
+
+
+
+
-
+
-
+
-
-
-
-
-
+
+
+
+
+
-
-
-
-
-
+
+
+
+
+
-
+
@@ -88,29 +88,29 @@
-
+
-
+
-
+
-
+
-
-
-
+
+
+
-
+
diff --git a/src/icons/flags/il.svg b/src/icons/flags/il.svg
index 724cf8bf3..f43be7e8e 100644
--- a/src/icons/flags/il.svg
+++ b/src/icons/flags/il.svg
@@ -4,11 +4,11 @@
-
+
-
-
-
-
+
+
+
+
diff --git a/src/icons/flags/im.svg b/src/icons/flags/im.svg
index 3d597a14b..f06f3d6fe 100644
--- a/src/icons/flags/im.svg
+++ b/src/icons/flags/im.svg
@@ -4,11 +4,11 @@
-
+
-
+
@@ -16,7 +16,7 @@
-
+
@@ -24,7 +24,7 @@
-
+
diff --git a/src/icons/flags/in.svg b/src/icons/flags/in.svg
index c634f68ac..bc47d7491 100644
--- a/src/icons/flags/in.svg
+++ b/src/icons/flags/in.svg
@@ -11,7 +11,7 @@
-
+
diff --git a/src/icons/flags/io.svg b/src/icons/flags/io.svg
index b04c46f5e..77016679e 100644
--- a/src/icons/flags/io.svg
+++ b/src/icons/flags/io.svg
@@ -30,7 +30,7 @@
-
+
@@ -104,8 +104,8 @@
-
-
+
+
@@ -120,7 +120,7 @@
-
+
diff --git a/src/icons/flags/iq.svg b/src/icons/flags/iq.svg
index 689178537..259da9adc 100644
--- a/src/icons/flags/iq.svg
+++ b/src/icons/flags/iq.svg
@@ -1,10 +1,10 @@
-
-
-
+
+
+
-
+
diff --git a/src/icons/flags/ir.svg b/src/icons/flags/ir.svg
index 5c9609eff..8c6d51621 100644
--- a/src/icons/flags/ir.svg
+++ b/src/icons/flags/ir.svg
@@ -4,7 +4,7 @@
-
+
@@ -209,11 +209,11 @@
-
-
-
-
-
+
+
+
+
+
diff --git a/src/icons/flags/is.svg b/src/icons/flags/is.svg
index 56cc97787..a6588afae 100644
--- a/src/icons/flags/is.svg
+++ b/src/icons/flags/is.svg
@@ -6,7 +6,7 @@
-
-
+
+
diff --git a/src/icons/flags/je.svg b/src/icons/flags/je.svg
index e69e4f465..611180d42 100644
--- a/src/icons/flags/je.svg
+++ b/src/icons/flags/je.svg
@@ -1,45 +1,62 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/icons/flags/jm.svg b/src/icons/flags/jm.svg
index e03a3422a..269df0383 100644
--- a/src/icons/flags/jm.svg
+++ b/src/icons/flags/jm.svg
@@ -1,6 +1,6 @@
-
+
diff --git a/src/icons/flags/jo.svg b/src/icons/flags/jo.svg
index 50802915e..d6f927d44 100644
--- a/src/icons/flags/jo.svg
+++ b/src/icons/flags/jo.svg
@@ -4,12 +4,12 @@
-
+
-
+
-
+
diff --git a/src/icons/flags/jp.svg b/src/icons/flags/jp.svg
index cd03a339d..cc1c181ce 100644
--- a/src/icons/flags/jp.svg
+++ b/src/icons/flags/jp.svg
@@ -6,6 +6,6 @@
-
+
diff --git a/src/icons/flags/ke.svg b/src/icons/flags/ke.svg
index 5b3779370..3a67ca3cc 100644
--- a/src/icons/flags/ke.svg
+++ b/src/icons/flags/ke.svg
@@ -3,14 +3,14 @@
-
+
-
+
diff --git a/src/icons/flags/kg.svg b/src/icons/flags/kg.svg
index 626af14da..68c210b1c 100644
--- a/src/icons/flags/kg.svg
+++ b/src/icons/flags/kg.svg
@@ -4,12 +4,12 @@
-
+
-
-
+
+
diff --git a/src/icons/flags/ki.svg b/src/icons/flags/ki.svg
index 1697ffe8b..0c8032807 100644
--- a/src/icons/flags/ki.svg
+++ b/src/icons/flags/ki.svg
@@ -4,28 +4,28 @@
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
diff --git a/src/icons/flags/km.svg b/src/icons/flags/km.svg
index 56d62c32e..414d65e47 100644
--- a/src/icons/flags/km.svg
+++ b/src/icons/flags/km.svg
@@ -9,7 +9,7 @@
-
+
diff --git a/src/icons/flags/kn.svg b/src/icons/flags/kn.svg
index 01a3a0a2a..47fe64d61 100644
--- a/src/icons/flags/kn.svg
+++ b/src/icons/flags/kn.svg
@@ -4,11 +4,11 @@
-
+
-
-
-
+
+
+
diff --git a/src/icons/flags/kp.svg b/src/icons/flags/kp.svg
index 94bc8e1ed..4d1dbab24 100644
--- a/src/icons/flags/kp.svg
+++ b/src/icons/flags/kp.svg
@@ -4,7 +4,7 @@
-
+
diff --git a/src/icons/flags/kr.svg b/src/icons/flags/kr.svg
index 44b51e251..6947eab2b 100644
--- a/src/icons/flags/kr.svg
+++ b/src/icons/flags/kr.svg
@@ -4,11 +4,11 @@
-
+
-
+
-
+
@@ -16,7 +16,7 @@
-
+
diff --git a/src/icons/flags/kw.svg b/src/icons/flags/kw.svg
index 7ff91a845..3dd89e996 100644
--- a/src/icons/flags/kw.svg
+++ b/src/icons/flags/kw.svg
@@ -8,6 +8,6 @@
-
+
diff --git a/src/icons/flags/ky.svg b/src/icons/flags/ky.svg
index d6e567b59..74a2fea2a 100644
--- a/src/icons/flags/ky.svg
+++ b/src/icons/flags/ky.svg
@@ -5,7 +5,7 @@
-
+
@@ -14,20 +14,20 @@
-
+
-
-
-
-
+
+
+
+
-
+
@@ -60,22 +60,22 @@
-
+
-
+
-
+
-
+
@@ -89,8 +89,8 @@
-
-
+
+
diff --git a/src/icons/flags/kz.svg b/src/icons/flags/kz.svg
index a69ba7a3b..04a47f53e 100644
--- a/src/icons/flags/kz.svg
+++ b/src/icons/flags/kz.svg
@@ -5,7 +5,7 @@
-
+
@@ -16,8 +16,8 @@
-
-
+
+
diff --git a/src/icons/flags/la.svg b/src/icons/flags/la.svg
index 9723a781a..6aea6b72b 100644
--- a/src/icons/flags/la.svg
+++ b/src/icons/flags/la.svg
@@ -7,6 +7,6 @@
-
+
diff --git a/src/icons/flags/lb.svg b/src/icons/flags/lb.svg
index 49650ad85..8619f2410 100644
--- a/src/icons/flags/lb.svg
+++ b/src/icons/flags/lb.svg
@@ -4,12 +4,12 @@
-
+
-
+
diff --git a/src/icons/flags/lc.svg b/src/icons/flags/lc.svg
index 46bbc6cc7..bb256541c 100644
--- a/src/icons/flags/lc.svg
+++ b/src/icons/flags/lc.svg
@@ -1,8 +1,8 @@
-
-
-
+
+
+
diff --git a/src/icons/flags/li.svg b/src/icons/flags/li.svg
index a08a05acd..68ea26fa3 100644
--- a/src/icons/flags/li.svg
+++ b/src/icons/flags/li.svg
@@ -3,10 +3,10 @@
-
+
-
+
@@ -20,23 +20,23 @@
-
+
-
+
-
+
-
+
-
+
diff --git a/src/icons/flags/lk.svg b/src/icons/flags/lk.svg
index 24c6559b7..2c5cdbe09 100644
--- a/src/icons/flags/lk.svg
+++ b/src/icons/flags/lk.svg
@@ -11,12 +11,12 @@
-
-
-
-
-
-
+
+
+
+
+
+
diff --git a/src/icons/flags/lr.svg b/src/icons/flags/lr.svg
index a31377f97..e482ab9d7 100644
--- a/src/icons/flags/lr.svg
+++ b/src/icons/flags/lr.svg
@@ -9,6 +9,6 @@
-
+
diff --git a/src/icons/flags/ls.svg b/src/icons/flags/ls.svg
index e70165028..a7c01a98f 100644
--- a/src/icons/flags/ls.svg
+++ b/src/icons/flags/ls.svg
@@ -4,5 +4,5 @@
-
+
diff --git a/src/icons/flags/lu.svg b/src/icons/flags/lu.svg
index c31d2bfa2..cc1220681 100644
--- a/src/icons/flags/lu.svg
+++ b/src/icons/flags/lu.svg
@@ -1,5 +1,5 @@
-
-
+
+
diff --git a/src/icons/flags/ly.svg b/src/icons/flags/ly.svg
index 14abcb243..1eaa51e46 100644
--- a/src/icons/flags/ly.svg
+++ b/src/icons/flags/ly.svg
@@ -6,7 +6,7 @@
-
+
diff --git a/src/icons/flags/md.svg b/src/icons/flags/md.svg
index a806572c2..6dc441e17 100644
--- a/src/icons/flags/md.svg
+++ b/src/icons/flags/md.svg
@@ -7,7 +7,7 @@
-
+
@@ -32,17 +32,17 @@
-
+
-
+
-
-
+
+
@@ -51,19 +51,19 @@
-
+
-
-
+
+
-
-
+
+
-
+
diff --git a/src/icons/flags/me.svg b/src/icons/flags/me.svg
index b56cce094..d89189074 100644
--- a/src/icons/flags/me.svg
+++ b/src/icons/flags/me.svg
@@ -1,28 +1,28 @@
-
-
+
+
-
-
-
+
+
+
-
+
-
+
-
-
-
-
-
-
+
+
+
+
+
+
@@ -32,43 +32,43 @@
-
-
-
-
-
+
+
+
+
+
-
-
-
-
+
+
+
+
-
+
-
+
-
+
-
-
+
+
-
-
+
+
-
+
-
-
-
-
-
-
+
+
+
+
+
+
@@ -81,36 +81,36 @@
-
-
+
+
-
-
+
+
-
-
-
+
+
+
-
+
-
+
-
+
-
+
-
+
-
-
-
+
+
+
-
+
diff --git a/src/icons/flags/mf.svg b/src/icons/flags/mf.svg
index a53ce5012..6305edc1c 100644
--- a/src/icons/flags/mf.svg
+++ b/src/icons/flags/mf.svg
@@ -1,5 +1,5 @@
-
-
+
+
diff --git a/src/icons/flags/mh.svg b/src/icons/flags/mh.svg
index 46351e541..7b9f49075 100644
--- a/src/icons/flags/mh.svg
+++ b/src/icons/flags/mh.svg
@@ -1,7 +1,7 @@
-
-
+
+
diff --git a/src/icons/flags/mm.svg b/src/icons/flags/mm.svg
index 8ed5e6ac2..42b4dee2b 100644
--- a/src/icons/flags/mm.svg
+++ b/src/icons/flags/mm.svg
@@ -2,7 +2,7 @@
-
+
diff --git a/src/icons/flags/mn.svg b/src/icons/flags/mn.svg
index 56cb0729b..152c2fcb0 100644
--- a/src/icons/flags/mn.svg
+++ b/src/icons/flags/mn.svg
@@ -4,9 +4,9 @@
-
+
-
+
diff --git a/src/icons/flags/mo.svg b/src/icons/flags/mo.svg
index 257faed69..d39985d05 100644
--- a/src/icons/flags/mo.svg
+++ b/src/icons/flags/mo.svg
@@ -2,7 +2,7 @@
-
+
diff --git a/src/icons/flags/mp.svg b/src/icons/flags/mp.svg
index 6696fdb83..ff59ebf87 100644
--- a/src/icons/flags/mp.svg
+++ b/src/icons/flags/mp.svg
@@ -7,7 +7,7 @@
-
+
@@ -52,27 +52,27 @@
-
+
-
-
-
+
+
+
-
+
-
+
-
-
+
+
-
+
diff --git a/src/icons/flags/mr.svg b/src/icons/flags/mr.svg
index 3f0a62645..7558234cb 100644
--- a/src/icons/flags/mr.svg
+++ b/src/icons/flags/mr.svg
@@ -1,6 +1,6 @@
-
+
diff --git a/src/icons/flags/ms.svg b/src/icons/flags/ms.svg
index 58641240c..faf07b07f 100644
--- a/src/icons/flags/ms.svg
+++ b/src/icons/flags/ms.svg
@@ -1,16 +1,16 @@
-
-
-
+
+
+
-
+
-
+
diff --git a/src/icons/flags/mt.svg b/src/icons/flags/mt.svg
index 676e801c5..c597266c3 100644
--- a/src/icons/flags/mt.svg
+++ b/src/icons/flags/mt.svg
@@ -1,49 +1,58 @@
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
diff --git a/src/icons/flags/mw.svg b/src/icons/flags/mw.svg
index 113aae543..d83ddb217 100644
--- a/src/icons/flags/mw.svg
+++ b/src/icons/flags/mw.svg
@@ -2,9 +2,9 @@
-
-
-
+
+
+
diff --git a/src/icons/flags/mx.svg b/src/icons/flags/mx.svg
index bb305b8d1..f98a89e17 100644
--- a/src/icons/flags/mx.svg
+++ b/src/icons/flags/mx.svg
@@ -39,87 +39,87 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
+
-
-
-
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
+
+
+
+
-
-
-
-
-
+
+
+
+
+
-
-
-
-
-
-
-
+
+
+
+
+
+
+
@@ -127,88 +127,88 @@
-
-
-
-
+
+
+
+
-
-
+
+
-
-
-
-
-
+
+
+
+
+
-
-
-
-
+
+
+
+
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
-
+
+
+
-
-
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
@@ -216,167 +216,167 @@
-
-
-
-
+
+
+
+
-
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
-
-
+
+
-
-
-
+
+
+
-
-
+
+
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
+
+
+
+
-
-
-
+
+
+
-
-
+
+
-
+
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
-
-
+
+
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
+
+
+
+
+
+
-
-
-
+
+
+
-
-
-
-
-
-
-
+
+
+
+
+
+
+
-
-
-
+
+
+
-
+
-
-
-
-
-
+
+
+
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
-
+
+
+
diff --git a/src/icons/flags/my.svg b/src/icons/flags/my.svg
index 264f48aef..89576f69e 100644
--- a/src/icons/flags/my.svg
+++ b/src/icons/flags/my.svg
@@ -1,6 +1,6 @@
-
+
@@ -15,8 +15,8 @@
-
-
+
+
diff --git a/src/icons/flags/mz.svg b/src/icons/flags/mz.svg
index eb020058b..2ee6ec14b 100644
--- a/src/icons/flags/mz.svg
+++ b/src/icons/flags/mz.svg
@@ -7,15 +7,15 @@
-
+
-
+
-
+
-
+
diff --git a/src/icons/flags/na.svg b/src/icons/flags/na.svg
index 799702e8c..35b9f783e 100644
--- a/src/icons/flags/na.svg
+++ b/src/icons/flags/na.svg
@@ -6,11 +6,11 @@
-
+
-
-
+
+
diff --git a/src/icons/flags/nc.svg b/src/icons/flags/nc.svg
index 96795408c..068f0c69a 100644
--- a/src/icons/flags/nc.svg
+++ b/src/icons/flags/nc.svg
@@ -4,10 +4,10 @@
-
-
-
-
-
-
+
+
+
+
+
+
diff --git a/src/icons/flags/nf.svg b/src/icons/flags/nf.svg
index ecdb4a3bd..c8b30938d 100644
--- a/src/icons/flags/nf.svg
+++ b/src/icons/flags/nf.svg
@@ -2,8 +2,8 @@
-
-
+
+
diff --git a/src/icons/flags/ni.svg b/src/icons/flags/ni.svg
index e16e77ae4..6dcdc9a80 100644
--- a/src/icons/flags/ni.svg
+++ b/src/icons/flags/ni.svg
@@ -38,13 +38,13 @@
-
-
-
+
+
+
-
+
@@ -59,62 +59,62 @@
-
-
-
+
+
+
-
+
-
-
+
+
-
-
-
+
+
+
-
+
-
+
-
-
-
+
+
+
-
+
-
-
-
-
+
+
+
+
-
+
-
+
-
+
-
+
@@ -125,5 +125,5 @@
-
+
diff --git a/src/icons/flags/nl.svg b/src/icons/flags/nl.svg
index 4faaf498e..e90f5b035 100644
--- a/src/icons/flags/nl.svg
+++ b/src/icons/flags/nl.svg
@@ -1,5 +1,5 @@
-
-
+
+
diff --git a/src/icons/flags/np.svg b/src/icons/flags/np.svg
index fead9402c..8d71d106b 100644
--- a/src/icons/flags/np.svg
+++ b/src/icons/flags/np.svg
@@ -4,10 +4,10 @@
-
+
-
+
diff --git a/src/icons/flags/nr.svg b/src/icons/flags/nr.svg
index e71ddcd8d..ff394c411 100644
--- a/src/icons/flags/nr.svg
+++ b/src/icons/flags/nr.svg
@@ -4,7 +4,7 @@
-
+
diff --git a/src/icons/flags/nz.svg b/src/icons/flags/nz.svg
index a0028fb2f..935d8a749 100644
--- a/src/icons/flags/nz.svg
+++ b/src/icons/flags/nz.svg
@@ -8,24 +8,24 @@
-
+
-
-
+
+
-
-
-
+
+
+
-
-
-
+
+
+
-
-
+
+
diff --git a/src/icons/flags/om.svg b/src/icons/flags/om.svg
index 1c7621799..c003f86e4 100644
--- a/src/icons/flags/om.svg
+++ b/src/icons/flags/om.svg
@@ -12,14 +12,14 @@
-
+
-
+
@@ -34,10 +34,10 @@
-
+
-
-
+
+
@@ -52,10 +52,10 @@
-
+
-
-
+
+
@@ -84,7 +84,7 @@
-
+
@@ -95,7 +95,7 @@
-
+
diff --git a/src/icons/flags/pc.svg b/src/icons/flags/pc.svg
new file mode 100644
index 000000000..882197da6
--- /dev/null
+++ b/src/icons/flags/pc.svg
@@ -0,0 +1,33 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/icons/flags/pf.svg b/src/icons/flags/pf.svg
index 16374f362..e06b236e8 100644
--- a/src/icons/flags/pf.svg
+++ b/src/icons/flags/pf.svg
@@ -8,12 +8,12 @@
-
+
-
+
-
+
diff --git a/src/icons/flags/pg.svg b/src/icons/flags/pg.svg
index 1080add5b..237cb6eee 100644
--- a/src/icons/flags/pg.svg
+++ b/src/icons/flags/pg.svg
@@ -1,7 +1,7 @@
-
-
+
+
diff --git a/src/icons/flags/pk.svg b/src/icons/flags/pk.svg
index fa02f6a8f..491e58ab1 100644
--- a/src/icons/flags/pk.svg
+++ b/src/icons/flags/pk.svg
@@ -4,7 +4,7 @@
-
+
diff --git a/src/icons/flags/pm.svg b/src/icons/flags/pm.svg
index 401139f7a..19a9330a3 100644
--- a/src/icons/flags/pm.svg
+++ b/src/icons/flags/pm.svg
@@ -1,5 +1,5 @@
-
-
+
+
diff --git a/src/icons/flags/pn.svg b/src/icons/flags/pn.svg
index 9788c9cc1..07958aca1 100644
--- a/src/icons/flags/pn.svg
+++ b/src/icons/flags/pn.svg
@@ -46,8 +46,8 @@
-
-
-
+
+
+
diff --git a/src/icons/flags/pr.svg b/src/icons/flags/pr.svg
index 3cb403b5c..ec51831dc 100644
--- a/src/icons/flags/pr.svg
+++ b/src/icons/flags/pr.svg
@@ -4,10 +4,10 @@
-
+
-
-
+
+
diff --git a/src/icons/flags/ps.svg b/src/icons/flags/ps.svg
index 82031486a..b33824a5d 100644
--- a/src/icons/flags/ps.svg
+++ b/src/icons/flags/ps.svg
@@ -4,12 +4,12 @@
-
+
-
+
-
+
diff --git a/src/icons/flags/pt.svg b/src/icons/flags/pt.svg
index 2f36b7ee7..445cf7f53 100644
--- a/src/icons/flags/pt.svg
+++ b/src/icons/flags/pt.svg
@@ -2,38 +2,38 @@
-
-
+
+
-
-
+
+
-
-
-
+
+
+
-
+
-
-
-
+
+
+
-
+
-
-
-
+
+
+
-
-
-
-
+
+
+
+
-
+
-
-
+
+
@@ -42,7 +42,7 @@
-
+
diff --git a/src/icons/flags/pw.svg b/src/icons/flags/pw.svg
index 089cbceea..9f89c5f14 100644
--- a/src/icons/flags/pw.svg
+++ b/src/icons/flags/pw.svg
@@ -6,6 +6,6 @@
-
+
diff --git a/src/icons/flags/py.svg b/src/icons/flags/py.svg
index bfbf01f1f..38e2051eb 100644
--- a/src/icons/flags/py.svg
+++ b/src/icons/flags/py.svg
@@ -2,24 +2,24 @@
-
+
-
+
-
+
-
+
@@ -146,12 +146,12 @@
-
-
+
+
-
+
-
+
diff --git a/src/icons/flags/qa.svg b/src/icons/flags/qa.svg
index bd493c381..901f3fa76 100644
--- a/src/icons/flags/qa.svg
+++ b/src/icons/flags/qa.svg
@@ -1,4 +1,4 @@
-
+
diff --git a/src/icons/flags/re.svg b/src/icons/flags/re.svg
index 3225dddf2..64e788e01 100644
--- a/src/icons/flags/re.svg
+++ b/src/icons/flags/re.svg
@@ -1,5 +1,5 @@
-
-
+
+
diff --git a/src/icons/flags/rs.svg b/src/icons/flags/rs.svg
index 120293ab0..2f971025b 100644
--- a/src/icons/flags/rs.svg
+++ b/src/icons/flags/rs.svg
@@ -4,146 +4,146 @@
-
+
-
+
-
+
-
-
+
+
-
+
-
+
-
+
-
+
-
-
-
-
+
+
+
+
-
-
+
+
-
-
+
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
-
+
+
-
+
-
+
-
+
-
+
-
+
-
+
-
-
-
+
+
+
-
+
-
+
-
-
+
+
-
+
-
-
+
+
-
+
-
+
-
+
-
-
+
+
-
+
-
-
-
+
+
+
@@ -154,23 +154,23 @@
-
+
-
+
-
+
-
+
-
+
-
+
@@ -180,21 +180,21 @@
-
+
-
+
-
+
-
-
+
+
-
-
+
+
-
-
+
+
@@ -205,88 +205,88 @@
-
-
+
+
-
+
-
+
-
-
-
+
+
+
-
+
-
+
-
+
-
+
-
+
-
-
-
+
+
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
-
-
-
-
+
+
+
+
+
-
+
-
-
-
+
+
+
-
-
+
+
-
+
-
+
-
+
diff --git a/src/icons/flags/ru.svg b/src/icons/flags/ru.svg
index f4d27efc9..cf243011a 100644
--- a/src/icons/flags/ru.svg
+++ b/src/icons/flags/ru.svg
@@ -1,7 +1,5 @@
-
-
-
-
-
+
+
+
diff --git a/src/icons/flags/rw.svg b/src/icons/flags/rw.svg
index 6cc669ed2..06e26ae44 100644
--- a/src/icons/flags/rw.svg
+++ b/src/icons/flags/rw.svg
@@ -2,7 +2,7 @@
-
+
diff --git a/src/icons/flags/sa.svg b/src/icons/flags/sa.svg
index 660396a70..c0a148663 100644
--- a/src/icons/flags/sa.svg
+++ b/src/icons/flags/sa.svg
@@ -4,22 +4,22 @@
-
+
-
-
-
-
+
+
+
+
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
diff --git a/src/icons/flags/sb.svg b/src/icons/flags/sb.svg
index a011360d5..6066f94cd 100644
--- a/src/icons/flags/sb.svg
+++ b/src/icons/flags/sb.svg
@@ -5,9 +5,9 @@
-
-
-
+
+
+
diff --git a/src/icons/flags/sd.svg b/src/icons/flags/sd.svg
index b8e4b9735..12818b411 100644
--- a/src/icons/flags/sd.svg
+++ b/src/icons/flags/sd.svg
@@ -5,9 +5,9 @@
-
+
-
+
diff --git a/src/icons/flags/se.svg b/src/icons/flags/se.svg
index 0e41780ef..8ba745aca 100644
--- a/src/icons/flags/se.svg
+++ b/src/icons/flags/se.svg
@@ -1,4 +1,4 @@
-
+
diff --git a/src/icons/flags/ac.svg b/src/icons/flags/sh-ac.svg
similarity index 61%
rename from src/icons/flags/ac.svg
rename to src/icons/flags/sh-ac.svg
index b1ae9ac52..22b365832 100644
--- a/src/icons/flags/ac.svg
+++ b/src/icons/flags/sh-ac.svg
@@ -1,90 +1,90 @@
-
+
-
+
-
+
-
+
-
+
-
+
-
-
-
-
+
+
+
+
-
-
-
+
+
+
-
+
-
+
-
-
+
+
-
+
-
-
-
+
+
+
-
+
-
+
-
-
+
+
-
-
-
+
+
+
-
+
-
+
-
-
+
+
-
+
-
-
-
-
-
-
-
+
+
+
+
+
+
+
-
+
-
+
@@ -100,68 +100,68 @@
-
+
-
+
-
+
-
+
-
+
-
-
+
+
-
-
+
+
-
+
-
-
+
+
-
-
+
+
-
+
-
-
-
-
-
+
+
+
+
+
-
+
-
-
+
+
-
+
-
+
-
-
+
+
-
-
+
+
-
+
@@ -171,51 +171,51 @@
-
+
-
+
-
+
-
-
+
+
-
+
-
+
-
+
-
+
-
-
+
+
-
-
-
+
+
+
-
-
+
+
-
+
-
-
-
-
+
+
+
+
-
-
-
+
+
+
@@ -223,10 +223,10 @@
-
+
-
-
+
+
@@ -251,10 +251,10 @@
-
+
-
+
@@ -271,7 +271,7 @@
-
+
@@ -337,198 +337,198 @@
-
+
-
+
-
+
-
-
-
-
-
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
+
+
-
-
-
+
+
+
-
-
-
+
+
+
-
-
-
+
+
+
-
-
-
+
+
+
-
-
-
-
+
+
+
+
-
-
+
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
-
+
+
-
+
-
-
-
+
+
+
-
+
-
-
-
+
+
+
-
+
-
+
-
+
-
+
-
-
-
-
+
+
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
+
-
-
+
+
-
-
-
+
+
+
-
+
-
+
-
-
+
+
@@ -538,134 +538,134 @@
-
-
+
+
-
-
-
+
+
+
-
-
-
+
+
+
-
-
-
+
+
+
-
-
-
-
+
+
+
+
-
-
+
+
-
+
-
+
-
+
-
+
-
+
-
+
-
-
+
+
-
+
-
-
-
+
+
+
-
+
-
-
+
+
-
+
-
+
-
+
-
+
-
-
-
-
+
+
+
+
-
-
+
+
-
-
-
+
+
+
-
-
+
+
-
+
-
-
+
+
-
-
-
+
+
+
-
+
-
+
-
-
+
+
@@ -675,8 +675,8 @@
-
-
+
+
diff --git a/src/icons/flags/sh-hl.svg b/src/icons/flags/sh-hl.svg
new file mode 100644
index 000000000..b92e703f2
--- /dev/null
+++ b/src/icons/flags/sh-hl.svg
@@ -0,0 +1,164 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/icons/flags/ta.svg b/src/icons/flags/sh-ta.svg
similarity index 81%
rename from src/icons/flags/ta.svg
rename to src/icons/flags/sh-ta.svg
index b68ad23c6..a103aac05 100644
--- a/src/icons/flags/ta.svg
+++ b/src/icons/flags/sh-ta.svg
@@ -1,38 +1,38 @@
-
-
+
+
-
-
+
+
-
+
-
+
-
+
-
-
+
+
-
-
-
-
+
+
+
+
-
+
-
-
+
+
@@ -40,10 +40,10 @@
-
-
+
+
-
+
@@ -51,22 +51,22 @@
-
-
+
+
-
+
-
-
-
+
+
+
-
-
+
+
-
+
-
+
diff --git a/src/icons/flags/sh.svg b/src/icons/flags/sh.svg
index 353915d3e..7aba0aec8 100644
--- a/src/icons/flags/sh.svg
+++ b/src/icons/flags/sh.svg
@@ -1,7 +1,7 @@
-
-
-
-
+
+
+
+
diff --git a/src/icons/flags/si.svg b/src/icons/flags/si.svg
index f2aea0168..66a390dcd 100644
--- a/src/icons/flags/si.svg
+++ b/src/icons/flags/si.svg
@@ -4,15 +4,15 @@
-
+
-
+
-
-
-
-
+
+
+
+
diff --git a/src/icons/flags/sk.svg b/src/icons/flags/sk.svg
index a1953fa67..81476940e 100644
--- a/src/icons/flags/sk.svg
+++ b/src/icons/flags/sk.svg
@@ -2,8 +2,8 @@
-
-
+
+
-
+
diff --git a/src/icons/flags/sm.svg b/src/icons/flags/sm.svg
index 0892990b2..00e9286c4 100644
--- a/src/icons/flags/sm.svg
+++ b/src/icons/flags/sm.svg
@@ -5,10 +5,10 @@
-
-
-
-
+
+
+
+
@@ -23,19 +23,19 @@
-
-
+
+
-
-
+
+
-
-
-
-
+
+
+
+
@@ -50,21 +50,21 @@
-
-
+
+
-
+
-
+
-
+
diff --git a/src/icons/flags/so.svg b/src/icons/flags/so.svg
index ae582f198..a581ac63c 100644
--- a/src/icons/flags/so.svg
+++ b/src/icons/flags/so.svg
@@ -4,8 +4,8 @@
-
+
-
+
diff --git a/src/icons/flags/ss.svg b/src/icons/flags/ss.svg
index 73804d80d..b257aa0b3 100644
--- a/src/icons/flags/ss.svg
+++ b/src/icons/flags/ss.svg
@@ -1,7 +1,7 @@
-
+
diff --git a/src/icons/flags/st.svg b/src/icons/flags/st.svg
index f2e75c141..1294bcb70 100644
--- a/src/icons/flags/st.svg
+++ b/src/icons/flags/st.svg
@@ -2,9 +2,9 @@
-
+
-
+
diff --git a/src/icons/flags/sv.svg b/src/icons/flags/sv.svg
index 3a63913d0..c811e912f 100644
--- a/src/icons/flags/sv.svg
+++ b/src/icons/flags/sv.svg
@@ -1,30 +1,30 @@
-
+
-
+
-
-
-
-
-
+
+
+
+
+
-
+
-
+
-
+
-
+
@@ -33,14 +33,14 @@
-
+
-
+
-
+
@@ -48,23 +48,23 @@
-
-
-
+
+
+
-
-
-
-
+
+
+
+
-
+
-
-
-
-
+
+
+
+
@@ -74,11 +74,11 @@
-
+
-
-
+
+
@@ -96,10 +96,10 @@
-
-
-
-
+
+
+
+
@@ -477,7 +477,7 @@
-
+
@@ -533,21 +533,21 @@
-
+
-
-
-
-
+
+
+
+
-
-
+
+
-
+
@@ -562,33 +562,33 @@
-
+
-
-
+
+
-
+
-
-
-
-
-
-
+
+
+
+
+
+
-
+
-
+
-
-
-
-
-
+
+
+
+
+
diff --git a/src/icons/flags/sx.svg b/src/icons/flags/sx.svg
index 84844e0f2..18f7a1397 100644
--- a/src/icons/flags/sx.svg
+++ b/src/icons/flags/sx.svg
@@ -5,36 +5,36 @@
-
-
-
-
-
-
+
+
+
+
+
+
-
-
+
+
-
+
-
-
+
+
-
+
-
+
@@ -44,7 +44,7 @@
-
+
diff --git a/src/icons/flags/sy.svg b/src/icons/flags/sy.svg
index 29636ae06..522555052 100644
--- a/src/icons/flags/sy.svg
+++ b/src/icons/flags/sy.svg
@@ -1,5 +1,5 @@
-
+
diff --git a/src/icons/flags/sz.svg b/src/icons/flags/sz.svg
index 5eef69140..294a2cc1a 100644
--- a/src/icons/flags/sz.svg
+++ b/src/icons/flags/sz.svg
@@ -2,7 +2,7 @@
-
+
@@ -13,7 +13,7 @@
-
+
@@ -22,13 +22,13 @@
-
+
-
+
-
+
-
+
diff --git a/src/icons/flags/tc.svg b/src/icons/flags/tc.svg
index 89d29bbf8..63f13c359 100644
--- a/src/icons/flags/tc.svg
+++ b/src/icons/flags/tc.svg
@@ -1,14 +1,14 @@
-
+
-
-
+
+
-
+
@@ -27,7 +27,7 @@
-
+
@@ -35,10 +35,10 @@
-
+
-
-
+
+
diff --git a/src/icons/flags/tf.svg b/src/icons/flags/tf.svg
index 88323d2cd..fba233563 100644
--- a/src/icons/flags/tf.svg
+++ b/src/icons/flags/tf.svg
@@ -6,7 +6,7 @@
-
+
diff --git a/src/icons/flags/tg.svg b/src/icons/flags/tg.svg
index e20f40d8d..c63a6d1a9 100644
--- a/src/icons/flags/tg.svg
+++ b/src/icons/flags/tg.svg
@@ -8,7 +8,7 @@
-
+
diff --git a/src/icons/flags/tj.svg b/src/icons/flags/tj.svg
index d2ba73338..9fba246cd 100644
--- a/src/icons/flags/tj.svg
+++ b/src/icons/flags/tj.svg
@@ -10,10 +10,10 @@
-
+
-
+
diff --git a/src/icons/flags/tk.svg b/src/icons/flags/tk.svg
index 65bab1372..05d3e86ce 100644
--- a/src/icons/flags/tk.svg
+++ b/src/icons/flags/tk.svg
@@ -1,5 +1,5 @@
-
+
diff --git a/src/icons/flags/tl.svg b/src/icons/flags/tl.svg
index bcfc1612d..3d0701a2c 100644
--- a/src/icons/flags/tl.svg
+++ b/src/icons/flags/tl.svg
@@ -6,8 +6,8 @@
-
-
+
+
diff --git a/src/icons/flags/tm.svg b/src/icons/flags/tm.svg
index 07c1a2f6c..8b656cc2b 100644
--- a/src/icons/flags/tm.svg
+++ b/src/icons/flags/tm.svg
@@ -34,7 +34,7 @@
-
+
@@ -76,7 +76,7 @@
-
+
@@ -98,7 +98,7 @@
-
+
@@ -200,5 +200,5 @@
-
+
diff --git a/src/icons/flags/tn.svg b/src/icons/flags/tn.svg
index 6a1989b4f..5735c1984 100644
--- a/src/icons/flags/tn.svg
+++ b/src/icons/flags/tn.svg
@@ -1,4 +1,4 @@
-
+
diff --git a/src/icons/flags/tr.svg b/src/icons/flags/tr.svg
index a92804f88..b96da21f0 100644
--- a/src/icons/flags/tr.svg
+++ b/src/icons/flags/tr.svg
@@ -1,7 +1,7 @@
-
+
diff --git a/src/icons/flags/tt.svg b/src/icons/flags/tt.svg
index 14adbe041..bc24938cf 100644
--- a/src/icons/flags/tt.svg
+++ b/src/icons/flags/tt.svg
@@ -1,5 +1,5 @@
-
-
+
+
diff --git a/src/icons/flags/tz.svg b/src/icons/flags/tz.svg
index 751c16720..a2cfbca42 100644
--- a/src/icons/flags/tz.svg
+++ b/src/icons/flags/tz.svg
@@ -6,8 +6,8 @@
-
-
-
+
+
+
diff --git a/src/icons/flags/ug.svg b/src/icons/flags/ug.svg
index 78252a42d..737eb2ce1 100644
--- a/src/icons/flags/ug.svg
+++ b/src/icons/flags/ug.svg
@@ -4,26 +4,26 @@
-
+
-
+
-
+
-
-
-
-
+
+
+
+
-
+
-
-
+
+
-
-
+
+
diff --git a/src/icons/flags/um.svg b/src/icons/flags/um.svg
index e04159498..9e9eddaa4 100644
--- a/src/icons/flags/um.svg
+++ b/src/icons/flags/um.svg
@@ -5,5 +5,5 @@
-
+
diff --git a/src/icons/flags/un.svg b/src/icons/flags/un.svg
index e47533703..e57793bc7 100644
--- a/src/icons/flags/un.svg
+++ b/src/icons/flags/un.svg
@@ -1,16 +1,16 @@
-
-
+
+
-
-
-
-
+
+
+
+
-
-
+
+
diff --git a/src/icons/flags/us.svg b/src/icons/flags/us.svg
index 615946d4b..9cfd0c927 100644
--- a/src/icons/flags/us.svg
+++ b/src/icons/flags/us.svg
@@ -5,5 +5,5 @@
-
+
diff --git a/src/icons/flags/uy.svg b/src/icons/flags/uy.svg
index 4a54b857a..62c36f8e5 100644
--- a/src/icons/flags/uy.svg
+++ b/src/icons/flags/uy.svg
@@ -1,7 +1,7 @@
-
+
@@ -16,7 +16,7 @@
-
+
diff --git a/src/icons/flags/uz.svg b/src/icons/flags/uz.svg
index aaf9382a4..0ccca1b1b 100644
--- a/src/icons/flags/uz.svg
+++ b/src/icons/flags/uz.svg
@@ -5,7 +5,7 @@
-
+
diff --git a/src/icons/flags/va.svg b/src/icons/flags/va.svg
index 25e6a9756..87e0fbbdc 100644
--- a/src/icons/flags/va.svg
+++ b/src/icons/flags/va.svg
@@ -2,23 +2,23 @@
-
+
-
-
+
+
-
-
-
-
+
+
+
+
-
+
@@ -52,7 +52,7 @@
-
+
@@ -174,13 +174,13 @@
-
+
-
+
diff --git a/src/icons/flags/vc.svg b/src/icons/flags/vc.svg
index 450f6f0a2..f26c2d8da 100644
--- a/src/icons/flags/vc.svg
+++ b/src/icons/flags/vc.svg
@@ -3,6 +3,6 @@
-
+
diff --git a/src/icons/flags/vg.svg b/src/icons/flags/vg.svg
index 4d2c3976e..0ee90fb28 100644
--- a/src/icons/flags/vg.svg
+++ b/src/icons/flags/vg.svg
@@ -11,15 +11,15 @@
-
-
-
+
+
+
-
+
@@ -34,10 +34,10 @@
-
-
+
+
-
+
@@ -54,6 +54,6 @@
-
+
diff --git a/src/icons/flags/vi.svg b/src/icons/flags/vi.svg
index 3a64338e8..427025779 100644
--- a/src/icons/flags/vi.svg
+++ b/src/icons/flags/vi.svg
@@ -8,11 +8,11 @@
-
-
+
+
-
-
+
+
@@ -21,8 +21,8 @@
-
+
-
-
+
+
diff --git a/src/icons/flags/vn.svg b/src/icons/flags/vn.svg
index 24bedc503..7e4bac8f4 100644
--- a/src/icons/flags/vn.svg
+++ b/src/icons/flags/vn.svg
@@ -4,7 +4,7 @@
-
+
diff --git a/src/icons/flags/vu.svg b/src/icons/flags/vu.svg
index efcff8954..91e1236a0 100644
--- a/src/icons/flags/vu.svg
+++ b/src/icons/flags/vu.svg
@@ -10,11 +10,11 @@
-
+
-
+
diff --git a/src/icons/flags/wf.svg b/src/icons/flags/wf.svg
index 57feb3a59..054c57df9 100644
--- a/src/icons/flags/wf.svg
+++ b/src/icons/flags/wf.svg
@@ -1,5 +1,5 @@
-
-
+
+
diff --git a/src/icons/flags/xk.svg b/src/icons/flags/xk.svg
index de6ef4da2..551e7a414 100644
--- a/src/icons/flags/xk.svg
+++ b/src/icons/flags/xk.svg
@@ -1,5 +1,5 @@
-
-
+
+
diff --git a/src/icons/flags/ye.svg b/src/icons/flags/ye.svg
index 61f0ed610..1c9e6d639 100644
--- a/src/icons/flags/ye.svg
+++ b/src/icons/flags/ye.svg
@@ -2,6 +2,6 @@
-
+
diff --git a/src/icons/flags/yt.svg b/src/icons/flags/yt.svg
index 5ea2f648c..e7776b307 100644
--- a/src/icons/flags/yt.svg
+++ b/src/icons/flags/yt.svg
@@ -1,5 +1,5 @@
-
-
+
+
diff --git a/src/icons/flags/za.svg b/src/icons/flags/za.svg
index aa54beb87..d563adb90 100644
--- a/src/icons/flags/za.svg
+++ b/src/icons/flags/za.svg
@@ -4,14 +4,14 @@
-
+
-
+
-
-
+
+
-
+
diff --git a/src/icons/flags/zm.svg b/src/icons/flags/zm.svg
index b8fdd63cb..13239f5e2 100644
--- a/src/icons/flags/zm.svg
+++ b/src/icons/flags/zm.svg
@@ -4,17 +4,17 @@
-
+
-
+
-
-
+
+
diff --git a/src/icons/flags/zw.svg b/src/icons/flags/zw.svg
index 5c1974693..6399ab4ab 100644
--- a/src/icons/flags/zw.svg
+++ b/src/icons/flags/zw.svg
@@ -8,14 +8,14 @@
-
+
-
-
+
+
-
+
diff --git a/src/icons/icons.qrc b/src/icons/icons.qrc
index 6200dd68f..5e22aadc6 100644
--- a/src/icons/icons.qrc
+++ b/src/icons/icons.qrc
@@ -24,7 +24,6 @@
filter-inactive.svg
filter-stalled.svg
firewalled.svg
- flags/ac.svg
flags/ad.svg
flags/ae.svg
flags/af.svg
@@ -212,6 +211,7 @@
flags/nz.svg
flags/om.svg
flags/pa.svg
+ flags/pc.svg
flags/pe.svg
flags/pf.svg
flags/pg.svg
@@ -237,6 +237,9 @@
flags/sd.svg
flags/se.svg
flags/sg.svg
+ flags/sh-ac.svg
+ flags/sh-hl.svg
+ flags/sh-ta.svg
flags/sh.svg
flags/si.svg
flags/sj.svg
@@ -252,7 +255,6 @@
flags/sx.svg
flags/sy.svg
flags/sz.svg
- flags/ta.svg
flags/tc.svg
flags/td.svg
flags/tf.svg
diff --git a/src/lang/qbittorrent_ar.ts b/src/lang/qbittorrent_ar.ts
index e26d39e24..07e5c8c87 100644
--- a/src/lang/qbittorrent_ar.ts
+++ b/src/lang/qbittorrent_ar.ts
@@ -93,8 +93,8 @@
- Copyright %1 2006-2024 The qBittorrent project
- حقوق النشر %1 2006-2024 مشروع كيوبتتورنت
+ Copyright %1 2006-2025 The qBittorrent project
+ حقوق النشر %1 2006-2025 مشروع كيوبتتورنت
@@ -231,25 +231,25 @@
شرط التوقف:
-
-
+
+
None
بدون
-
-
+
+
Metadata received
استلمت البيانات الوصفية
-
+
Torrents that have metadata initially will be added as stopped.
-
+ ستتم إضافة التورينت التي تحتوي على بيانات وصفية في البداية على أنها متوقفة.
-
-
+
+
Files checked
فُحصت الملفات
@@ -364,116 +364,112 @@
أحفظ كملف تورنت...
-
+
I/O Error
خطأ إدخال/إخراج
-
+
Not Available
This comment is unavailable
غير متوفر
-
+
Not Available
This date is unavailable
غير متوفر
-
+
Not available
غير متوفر
-
+
Magnet link
رابط مغناطيسي
-
+
Retrieving metadata...
يجلب البيانات الوصفية...
-
-
+
+
Choose save path
اختر مسار الحفظ
-
+
No stop condition is set.
لم يتم وضع شرط للتوقف
-
+
Torrent will stop after metadata is received.
سيتوقف التورنت بعد استقبال البيانات الوصفية
- Torrents that have metadata initially aren't affected.
- التورنت الذي يحتوي على بيانات وصفية ابتدائية لن يتأثر
-
-
-
+
Torrent will stop after files are initially checked.
سيتوقف التورنت بعد الملفات التي تم فحصحها
-
+
This will also download metadata if it wasn't there initially.
سيؤدي هذا أيضًا إلى تنزيل البيانات الوصفية إذا لم تكن موجودة في البداية.
-
-
+
+
N/A
لا يوجد
-
+
%1 (Free space on disk: %2)
%1 (المساحة الخالية من القرص: %2)
-
+
Not available
This size is unavailable.
غير متوفر
-
+
Torrent file (*%1)
ملف تورنت (*%1)
-
+
Save as torrent file
أحفظ كملف تورنت
-
+
Couldn't export torrent metadata file '%1'. Reason: %2.
تعذر تصدير ملف بيانات التعريف للتورنت '%1'. السبب: %2.
-
+
Cannot create v2 torrent until its data is fully downloaded.
لا يمكن إنشاء إصدار 2 للتورنت حتى يتم تنزيل بياناته بالكامل.
-
+
Filter files...
تصفية الملفات...
-
+
Parsing metadata...
يحلّل البيانات الوصفية...
-
+
Metadata retrieval complete
اكتمل جلب البيانات الوصفية
@@ -491,24 +487,24 @@
فشل أضافة التورنت. المصدر: "%1". السبب: "%2"
-
+
Detected an attempt to add a duplicate torrent. Source: %1. Existing torrent: %2. Result: %3
-
+ تم الكشف عن محاولة اضافة تورينت مكرر. المصدر: %1. التورينت الموجود: %2. النتيجة: %3
-
+
Merging of trackers is disabled
-
+ تم تعطيل دمج التتبع
-
+
Trackers cannot be merged because it is a private torrent
-
+ لا يمكن دمج التتبع بسبب ان التورينت خاص
-
+
Trackers are merged from new source
-
+ تم دمج التتبع من مصدر جديد
@@ -596,7 +592,7 @@
Torrent share limits
- حدود مشاركة التورنت
+ حدود مشاركة التورنت
@@ -672,763 +668,834 @@
AdvancedSettings
-
-
-
-
+
+
+
+
MiB
م.بايت
-
+
Recheck torrents on completion
إعادة تأكيد البيانات بعد اكتمال التنزيل
-
-
+
+
ms
milliseconds
ملي ثانية
-
+
Setting
الخيار
-
+
Value
Value set for this setting
القيمة
-
+
(disabled)
(مُعطّل)
-
+
(auto)
(آلي)
-
+
min
minutes
دقيقة
-
+
All addresses
جميع العناوين
-
+
qBittorrent Section
قسم كيوبتتورنت
-
-
+
+
Open documentation
فتح التعليمات
-
+
All IPv4 addresses
جميع عناوين IPv4
-
+
All IPv6 addresses
جميع عناوين IPv6
-
+
libtorrent Section
قسم libtorrent
-
+
Fastresume files
ملفات Fastresume
-
+
SQLite database (experimental)
قاعدة بيانات SQLite (تجريبية)
-
+
Resume data storage type (requires restart)
استئناف نوع تخزين البيانات (يتطلب إعادة التشغيل)
-
+
Normal
عادي
-
+
Below normal
أقل من المعتاد
-
+
Medium
متوسط
-
+
Low
منخفض
-
+
Very low
منخفض جدًا
-
+
Physical memory (RAM) usage limit
حد استخدام الذاكرة الفعلية (RAM).
-
+
Asynchronous I/O threads
مواضيع الإدخال/الإخراج غير متزامنة
-
+
Hashing threads
تجزئة المواضيع
-
+
File pool size
حجم تجمع الملفات
-
+
Outstanding memory when checking torrents
ذاكرة مميزة عند فحص التورنتات
-
+
Disk cache
ذاكرة التخزين المؤقت على القرص
-
-
-
-
+
+
+
+
s
seconds
ث
-
+
Disk cache expiry interval
مدة بقاء الذاكرة المؤقتة للقرص
-
+
Disk queue size
حجم صف القرص
-
-
+
+
Enable OS cache
مكّن النظام من خاصية الـcache
-
+
Coalesce reads & writes
اندماج القراءة والكتابة
-
+
Use piece extent affinity
استخدم مدى تقارب القطعة
-
+
Send upload piece suggestions
إرسال اقتراحات للقطع المُراد رفعها
-
-
-
-
+
+
+
+
0 (disabled)
0 (معطَّل)
-
+
Save resume data interval [0: disabled]
How often the fastresume file is saved.
حفظ الفاصل الزمني للاستئناف [0: معطل]
-
+
Outgoing ports (Min) [0: disabled]
المنافذ الصادرة (الحد الأدنى) [0: معطلة]
-
+
Outgoing ports (Max) [0: disabled]
المنافذ الصادرة (الحد الأقصى) [0: معطلة]
-
+
0 (permanent lease)
0 (إيجار دائم)
-
+
UPnP lease duration [0: permanent lease]
مدة تأجير UPnP [0: عقد إيجار دائم]
-
+
Stop tracker timeout [0: disabled]
إيقاف مهلة التتبع [0: معطل]
-
+
Notification timeout [0: infinite, -1: system default]
مهلة الإشعار [0: لا نهائي، -1: النظام الافتراضي]
-
+
Maximum outstanding requests to a single peer
الحد الأقصى للطلبات للقرين الواحد
-
-
-
-
-
+
+
+
+
+
KiB
ك.بايت
-
+
(infinite)
لا نهائي
-
+
(system default)
(الوضع الافتراضي للنظام)
-
+
+ Delete files permanently
+ حذف الملفات نهائيا
+
+
+
+ Move files to trash (if possible)
+ نقل الملفات إلى سلة المهملات (إذا كان ذلك ممكنا)
+
+
+
+ Torrent content removing mode
+ وضعية إزالة محتوى التورنت
+
+
+
This option is less effective on Linux
هذا الخيار أقل فعالية على لينكس
-
+
Process memory priority
-
+ أولوية ذاكرة العملية
-
+
Bdecode depth limit
حد عمق Bdecode
-
+
Bdecode token limit
حد رمز Bdecode
-
+
Default
الوضع الإفتراضي
-
+
Memory mapped files
ملفات الذاكرة المعينة
-
+
POSIX-compliant
متوافق مع POSIX
-
+
+ Simple pread/pwrite
+ pread/pwrite بسيطة
+
+
+
Disk IO type (requires restart)
نوع إدخال القرص Disk IO (يتطلب إعادة التشغيل)
-
-
+
+
Disable OS cache
تعطيل ذاكرة التخزين المؤقت لنظام التشغيل
-
+
Disk IO read mode
وضع قراءة إدخال القرص Disk IO
-
+
Write-through
الكتابة من خلال
-
+
Disk IO write mode
وضع الكتابة إدخال القرص Disk IO
-
+
Send buffer watermark
إرسال علامة مائية المخزن المؤقت
-
+
Send buffer low watermark
إرسال علامة مائية منخفضة المخزن المؤقت
-
+
Send buffer watermark factor
إرسال عامل العلامة المائية المخزن المؤقت
-
+
Outgoing connections per second
الاتصالات الصادرة في الثانية
-
-
+
+
0 (system default)
0 (افتراضي للنظام)
-
+
Socket send buffer size [0: system default]
حجم المخزن المؤقت لإرسال المقبس [0: النظام الافتراضي]
-
+
Socket receive buffer size [0: system default]
يتلقى المقبس حجم المخزن المؤقت [0: النظام الافتراضي]
-
+
Socket backlog size
حجم تراكم مأخذ التوصيل
-
+
.torrent file size limit
الحد الأقصى لحجم ملف torrent.
-
+
Type of service (ToS) for connections to peers
نوع الخدمة (ToS) للاتصالات مع الأقران
-
+
Prefer TCP
أفضل TCP
-
+
Peer proportional (throttles TCP)
القرين المتناسب (سرّع TCP)
-
+
Support internationalized domain name (IDN)
دعم اسم نطاق الإنترنت الدولي (IDN)
-
+
Allow multiple connections from the same IP address
السماح باتصالات متعددة من نفس عنوان الآي بي
-
+
Validate HTTPS tracker certificates
تحقق من صحة شهادات متتبع HTTPS
-
+
Server-side request forgery (SSRF) mitigation
التخفيف من تزوير الطلب من جانب الخادم (SSRF)
-
+
Disallow connection to peers on privileged ports
عدم السماح بالاتصال بالقرناء على المنافذ ذات الامتيازات
-
+
It appends the text to the window title to help distinguish qBittorent instances
-
+ يقوم بإلحاق النص بعنوان النافذة للمساعدة في التمييز بين مثيلات qBittorent
-
+
Customize application instance name
-
+ تخصيص اسم مثيل التطبيق
-
+
It controls the internal state update interval which in turn will affect UI updates
فهو يتحكم في الفاصل الزمني لتحديث الحالة الداخلية والذي سيؤثر بدوره على تحديثات واجهة المستخدم
-
+
Refresh interval
الفاصل الزمني للتحديث
-
+
Resolve peer host names
اظهار اسم الجهاز للقرين
-
+
IP address reported to trackers (requires restart)
تم الإبلاغ عن عنوان IP للمتتبعين (يتطلب إعادة التشغيل)
-
+
Reannounce to all trackers when IP or port changed
إعادة الاتصال بجميع المتتبعات عند تغيير IP أو المنفذ
-
+
Enable icons in menus
تفعيل الرموز في القوائم
-
+
Enable port forwarding for embedded tracker
تفعيل إعادة توجيه المنفذ لتتبع المضمن
-
+
Enable quarantine for downloaded files
-
+ تمكين العزل للملفات التي تم تنزيلها
-
+
Enable Mark-of-the-Web (MOTW) for downloaded files
-
+ تمكين Mark-of-the-Web (MOTW) للملفات التي تم تنزيلها
-
+
+ Affects certificate validation and non-torrent protocol activities (e.g. RSS feeds, program updates, torrent files, geoip db, etc)
+ يؤثر على التحقق من الشهادات وأنشطة البروتوكولات غير المتعلقة بالتورنت (مثل خلاصات RSS، تحديثات البرامج، ملفات التورنت، قاعدة بيانات geoip، إلخ).
+
+
+
+ Ignore SSL errors
+ تجاهل أخطاء SSL
+
+
+
(Auto detect if empty)
-
+ (الكشف التلقائي إذا كان فارغًا)
-
+
Python executable path (may require restart)
-
+ مسار بايثون القابل للتنفيذ (قد يتطلب إعادة التشغيل)
- Confirm removal of tracker from all torrents
-
+ Start BitTorrent session in paused state
+ بدء جلسة BitTorrent في حالة الإيقاف المؤقت
-
+
+ sec
+ seconds
+ ث
+
+
+
+ -1 (unlimited)
+ -1 (غير محدود)
+
+
+
+ BitTorrent session shutdown timeout [-1: unlimited]
+ مهلة إيقاف جلسة BitTorrent [-1: غير محدود]
+
+
+
+ Confirm removal of tracker from all torrents
+ تأكيد إزالة المتتبع (التراكر) من جميع التورينتات
+
+
+
Peer turnover disconnect percentage
النسبة المئوية لفصل دوران الأقران
-
+
Peer turnover threshold percentage
النسبة المئوية لبداية دوران الأقران
-
+
Peer turnover disconnect interval
الفترة الزمنية لفصل دوران الأقران
-
+
Resets to default if empty
-
+ يعيد التعيين إلى الوضع الافتراضي إذا كان فارغًا
-
+
DHT bootstrap nodes
-
+ عقد التمهيد DHT
-
+
I2P inbound quantity
I2P الكمية الواردة
-
+
I2P outbound quantity
الكمية الصادرة I2P
-
+
I2P inbound length
طول I2P الوارد
-
+
I2P outbound length
طول I2P الصادر
-
+
Display notifications
عرض الإشعارات
-
+
Display notifications for added torrents
عرض الإشعارات للتورنت المضافة.
-
+
Download tracker's favicon
تنزيل ايقونة التراكر
-
+
Save path history length
طول سجل مسار الحفظ
-
+
Enable speed graphs
تفعيل الرسم البياني لسرعة النقل
-
+
Fixed slots
فتحات ثابتة
-
+
Upload rate based
معدل الرفع على أساس
-
+
Upload slots behavior
سلوك فتحات الرفع
-
+
Round-robin
القرين الآلي الذي لا يبذر
-
+
Fastest upload
أسرع رفع
-
+
Anti-leech
مكافحة المُستهلكين
-
+
Upload choking algorithm
رفع خوارزمية الاختناق
-
+
Confirm torrent recheck
تأكيد إعادة التحقق من التورنت
-
+
Confirm removal of all tags
تأكيد إزالة جميع العلامات
-
+
Always announce to all trackers in a tier
أعلن دائمًا لجميع المتتبعات في المستوى
-
+
Always announce to all tiers
أعلن دائما لجميع المستويات
-
+
Any interface
i.e. Any network interface
أي واجهة
-
+
%1-TCP mixed mode algorithm
uTP-TCP mixed mode algorithm
خوارزمية الوضع المختلط %1-TCP
-
+
Resolve peer countries
اظهار أعلام الدول للقرناء
-
+
Network interface
واجهة الشبكة
-
+
Optional IP address to bind to
عنوان آي بي اختياري للربط به
-
+
Max concurrent HTTP announces
يعلن أقصى HTTP متزامن
-
+
Enable embedded tracker
تمكين المتتبع الداخلي
-
+
Embedded tracker port
منفذ المتتبع الداخلي
+
+ AppController
+
+
+
+ Invalid directory path
+ مسار المجلد غير صحيح
+
+
+
+ Directory does not exist
+ المجلد غير موجود
+
+
+
+ Invalid mode, allowed values: %1
+ وضع غير صالح، القيم المسموح بها: %1
+
+
Application
-
+
Running in portable mode. Auto detected profile folder at: %1
يعمل في الوضع المحمول. مجلد ملف التعريف المكتشف تلقائيًا في: %1
-
+
Redundant command line flag detected: "%1". Portable mode implies relative fastresume.
اكتشاف علامة سطر أوامر متكررة: "%1". يشير الوضع المحمول إلى استئناف سريع نسبي.
-
+
Using config directory: %1
استخدام دليل التكوين: %1
-
+
Torrent name: %1
اسم التورنت: %1
-
+
Torrent size: %1
حجم التورنت: %1
-
+
Save path: %1
مسار الحفظ: %1
-
+
The torrent was downloaded in %1.
The torrent was downloaded in 1 hour and 20 seconds
تم تنزيل التورنت في %1.
-
+
+
Thank you for using qBittorrent.
شكرا لاستخدامك كيوبتتورنت.
-
+
Torrent: %1, sending mail notification
التورنت: %1، يرسل إشعار البريد الإلكتروني
-
+
Add torrent failed
-
+ فشل إضافة تورنت
-
+
Couldn't add torrent '%1', reason: %2.
-
+ تعذّر إضافة التورنت '%1'، السبب: %2.
-
+
The WebUI administrator username is: %1
-
+ اسم المستخدم لمسؤول واجهة الويب هو: %1
-
+
The WebUI administrator password was not set. A temporary password is provided for this session: %1
-
+ لم يتم تعيين كلمة مرور لمسؤول واجهة الويب. تم تعيين كلمة مرور مؤقتة لهذه الجلسة: %1
-
+
You should set your own password in program preferences.
-
+ يجب عليك تعيين كلمة مرور خاصة بك في إعدادات البرنامج.
-
+
The WebUI is disabled! To enable the WebUI, edit the config file manually.
-
+ واجهة الويب للمستخدم معطلة! لتفعيل واجهة الويب للمستخدم، قم بتحرير ملف الإعدادات يدويًا.
-
+
Running external program. Torrent: "%1". Command: `%2`
تشغيل برنامج خارجي تورنت: "%1". الأمر: `%2`
-
+
Failed to run external program. Torrent: "%1". Command: `%2`
فشل في تشغيل برنامج خارجي. تورنت: "%1". الأمر: `%2`
-
+
Torrent "%1" has finished downloading
انتهى تنزيل التورنت "%1".
-
+
WebUI will be started shortly after internal preparations. Please wait...
سيتم بدء تشغيل WebUI بعد وقت قصير من الاستعدادات الداخلية. انتظر من فضلك...
-
-
+
+
Loading torrents...
جارِ تحميل التورنت...
-
+
E&xit
&خروج
-
+
I/O Error
i.e: Input/Output Error
خطأ إدخال/إخراج
-
+
An I/O error occurred for torrent '%1'.
Reason: %2
e.g: An error occurred for torrent 'xxx.avi'.
@@ -1437,100 +1504,110 @@
السبب: %2
-
+
Torrent added
تمت إضافة تورنت
-
+
'%1' was added.
e.g: xxx.avi was added.
تم إضافة '%1'
-
+
Download completed
انتهى التحميل
-
+
qBittorrent %1 started. Process ID: %2
qBittorrent v3.2.0alpha started
-
+ تم بدء %1 من qbittorrent. معرف العملية: %2
-
+
+ This is a test email.
+ هذا بريد إلكتروني اختباري.
+
+
+
+ Test email
+ بريد إلكتروني اختباري
+
+
+
'%1' has finished downloading.
e.g: xxx.avi has finished downloading.
انتهى تنزيل '%1'.
-
+
Information
معلومات
-
+
To fix the error, you may need to edit the config file manually.
-
+ لإصلاح الخطأ، قد تحتاج إلى تعديل ملف الإعدادات يدويًا.
-
+
To control qBittorrent, access the WebUI at: %1
للتحكم في كيوبتتورنت، افتح واجهة الوِب الرسومية على: %1
-
+
Exit
خروج
-
+
Recursive download confirmation
تأكيد متكرر للتنزيل
-
+
The torrent '%1' contains .torrent files, do you want to proceed with their downloads?
يحتوي ملف التورنت '%1' على ملفات .torrent، هل تريد متابعة تنزيلاتها؟
-
+
Never
أبدًا
-
+
Recursive download .torrent file within torrent. Source torrent: "%1". File: "%2"
تنزيل متكرر لملف .torren. داخل التورنت. تورنت المصدر: "%1". الملف: "%2"
-
+
Failed to set physical memory (RAM) usage limit. Error code: %1. Error message: "%2"
فشل في تعيين حد استخدام الذاكرة الفعلية (RAM). رمز الخطأ: %1. رسالة الخطأ: "%2"
-
+
Failed to set physical memory (RAM) usage hard limit. Requested size: %1. System hard limit: %2. Error code: %3. Error message: "%4"
فشل في تعيين الحد الأقصى لاستخدام الذاكرة الفعلية (RAM). الحجم المطلوب: %1. الحد الأقصى للنظام: %2. رمز الخطأ: %3. رسالة الخطأ: "%4"
-
+
qBittorrent termination initiated
بدأ إنهاء qBittorrent
-
+
qBittorrent is shutting down...
كيوبتتورنت قيد الإغلاق ...
-
+
Saving torrent progress...
حفظ تقدم التورنت...
-
+
qBittorrent is now ready to exit
qBittorrent جاهز الآن للخروج
@@ -1965,58 +2042,58 @@ Supports the formats: S01E01, 1x1, 2017.12.31 and 31.12.2017 (Date formats also
BitTorrent::BencodeResumeDataStorage
-
+
Cannot create torrent resume folder: "%1"
لا يمكن إنشاء مجلد استئناف التورنت: "%1"
-
+
Cannot parse resume data: invalid format
لا يمكن تحليل بيانات الاستئناف: التنسيق غير صالح
-
-
+
+
Cannot parse torrent info: %1
لا يمكن تحليل معلومات التورنت: %1
-
+
Cannot parse torrent info: invalid format
لا يمكن تحليل معلومات التورنت: التنسيق غير صالح
-
+
Mismatching info-hash detected in resume data
-
+ تم اكتشاف تجزئة معلومات غير متطابقة في بيانات الاستئناف.
-
+
Couldn't save torrent metadata to '%1'. Error: %2.
تعذر حفظ بيانات التعريف للتورنت في '%1'. خطأ: %2.
-
+
Couldn't save torrent resume data to '%1'. Error: %2.
تعذر حفظ بيانات الاستئناف للتورنت في '%1'. خطأ: %2.
-
+
Couldn't load torrents queue: %1
تعذر تحميل صف التورنت: %1
-
+
Cannot parse resume data: %1
لا يمكن تحليل بيانات الاستئناف: %1
-
+
Resume data is invalid: neither metadata nor info-hash was found
بيانات الاستئناف غير صالحة: لم يتم العثور على البيانات الوصفية ولا تجزئة المعلومات
-
+
Couldn't save data to '%1'. Error: %2
تعذر حفظ البيانات في '%1'. خطأ: %2
@@ -2024,38 +2101,38 @@ Supports the formats: S01E01, 1x1, 2017.12.31 and 31.12.2017 (Date formats also
BitTorrent::DBResumeDataStorage
-
+
Not found.
غير موجود.
-
+
Couldn't load resume data of torrent '%1'. Error: %2
تعذر تحميل بيانات الاستئناف للتورنت '%1'. خطأ: %2
-
-
+
+
Database is corrupted.
قاعدة البيانات تالفة.
-
+
Couldn't enable Write-Ahead Logging (WAL) journaling mode. Error: %1.
تعذر تمكين وضع تسجيل دفتر اليومية (WAL) لتسجيل الدخول. الخطأ: %1.
-
+
Couldn't obtain query result.
تعذر الحصول على نتيجة الاستعلام.
-
+
WAL mode is probably unsupported due to filesystem limitations.
ربما يكون وضع WAL غير مدعوم بسبب قيود نظام الملفات.
-
+
Couldn't begin transaction. Error: %1
تعذر بدء المعاملة. الخطأ: %1
@@ -2063,22 +2140,22 @@ Supports the formats: S01E01, 1x1, 2017.12.31 and 31.12.2017 (Date formats also
BitTorrent::ResumeDataStorage
-
+
Couldn't save torrent metadata. Error: %1.
تعذر حفظ بيانات التعريف للتورنت. خطأ: %1.
-
+
Couldn't store resume data for torrent '%1'. Error: %2
تعذر تخزين بيانات الاستئناف للتورنت '%1'. خطأ: %2
-
+
Couldn't delete resume data of torrent '%1'. Error: %2
تعذر حذف بيانات الاستئناف للتورنت '%1'. خطأ: %2
-
+
Couldn't store torrents queue positions. Error: %1
تعذر تخزين موضع صف التورنتات. خطأ: %1
@@ -2086,457 +2163,488 @@ Supports the formats: S01E01, 1x1, 2017.12.31 and 31.12.2017 (Date formats also
BitTorrent::SessionImpl
-
-
+
+
Distributed Hash Table (DHT) support: %1
دعم جدول التجزئة الموزع (DHT): %1
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
ON
يعمل
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
OFF
متوقف
-
-
+
+
Local Peer Discovery support: %1
دعم اكتشاف الأقران المحليين: %1
-
+
Restart is required to toggle Peer Exchange (PeX) support
يلزم إعادة التشغيل لتبديل دعم Peer Exchange (PeX).
-
+
Failed to resume torrent. Torrent: "%1". Reason: "%2"
فشل في استئناف التورنت. تورنت: "%1". السبب: "%2"
-
-
+
+
Failed to resume torrent: inconsistent torrent ID is detected. Torrent: "%1"
فشل استئناف التورنت: تم اكتشاف معرف تورنت غير متناسق. تورنت: "%1"
-
+
Detected inconsistent data: category is missing from the configuration file. Category will be recovered but its settings will be reset to default. Torrent: "%1". Category: "%2"
تم اكتشاف بيانات غير متناسقة: الفئة مفقودة من ملف التضبيط. سيتم استرداد الفئة ولكن سيتم إعادة ضبط إعداداتها على الوضع الافتراضي. تورنت: "%1". الفئة: "%2"
-
+
Detected inconsistent data: invalid category. Torrent: "%1". Category: "%2"
تم اكتشاف بيانات غير متناسقة: فئة غير صالحة. تورنت: "%1". الفئة: "%2"
-
+
Detected mismatch between the save paths of the recovered category and the current save path of the torrent. Torrent is now switched to Manual mode. Torrent: "%1". Category: "%2"
تم اكتشاف عدم تطابق بين مسارات الحفظ للفئة المستردة ومسار الحفظ الحالي للتورنت. تم الآن تحويل التورنت إلى الوضع اليدوي. تورنت: "%1". الفئة: "%2"
-
+
Detected inconsistent data: tag is missing from the configuration file. Tag will be recovered. Torrent: "%1". Tag: "%2"
تم اكتشاف بيانات غير متناسقة: العلامة مفقودة من ملف التضبيط. سيتم استرداد العلامة. تورنت: "%1". العلامة: "%2"
-
+
Detected inconsistent data: invalid tag. Torrent: "%1". Tag: "%2"
تم اكتشاف بيانات غير متناسقة: وسم غير صالح. تورنت: "%1". العلامة: "%2"
-
+
System wake-up event detected. Re-announcing to all the trackers...
تم اكتشاف حدث تنبيه النظام .جارِ إعادة إعلان إلى كافة المتتبعين...
-
+
Peer ID: "%1"
معرّف النظير: "%1"
-
+
HTTP User-Agent: "%1"
HTTP User-Agent: "%1"
-
+
Peer Exchange (PeX) support: %1
دعم تبادل الأقران (PeX): %1
-
-
+
+
Anonymous mode: %1
الوضع المجهول: %1
-
-
+
+
Encryption support: %1
دعم التشفير: %1
-
-
+
+
FORCED
مُجبر
-
+
Could not find GUID of network interface. Interface: "%1"
تعذر العثور على GUID لواجهة الشبكة. الواجهة: "%1"
-
+
Trying to listen on the following list of IP addresses: "%1"
محاولة الاستماع إلى قائمة عناوين IP التالية: "%1"
-
+
Torrent reached the share ratio limit.
وصل تورنت إلى الحد الأقصى لنسبة المشاركة.
-
-
-
+
Torrent: "%1".
تورنت: "%1".
-
-
-
- Removed torrent.
- تمت إزالة التورنت.
+
+
+
+ Detected an attempt to add a duplicate torrent. Existing torrent: %1. Result: %2
+
-
-
-
- Removed torrent and deleted its content.
- تمت إزالة التورنت وحذف محتواه.
+
+ Merging of trackers is disabled
+ تم تعطيل دمج التتبع
-
-
-
- Torrent paused.
- توقف التورنت مؤقتًا.
+
+ Trackers cannot be merged because it is a private torrent
+ لا يمكن دمج التتبع بسبب ان التورينت خاص
-
-
-
+
+ Trackers are merged from new source
+ تم دمج التتبع من مصدر جديد
+
+
+
+ Failed to remove partfile. Torrent: "%1". Reason: "%2".
+
+
+
+
Super seeding enabled.
تم تفعيل البذر الفائق.
-
+
Torrent reached the seeding time limit.
وصل التورنت إلى حد زمني البذر.
-
+
Torrent reached the inactive seeding time limit.
وصل التورنت إلى حد زمني للنشر الغير نشط.
-
+
Failed to load torrent. Reason: "%1"
فشل تحميل التورنت. السبب: "%1"
-
+
I2P error. Message: "%1".
-
+ خطأ I2P. الرسالة: "%1".
-
+
UPnP/NAT-PMP support: ON
دعم UPnP/NAT-PMP: مشغّل
-
+
+ Saving resume data completed.
+
+
+
+
+ BitTorrent session successfully finished.
+
+
+
+
+ Session shutdown timed out.
+
+
+
+
+ Removing torrent.
+ حذف التورنت
+
+
+
+ Removing torrent and deleting its content.
+ إزالة التورنت وحذف محتواه.
+
+
+
+ Torrent stopped.
+
+
+
+
+ Torrent content removed. Torrent: "%1"
+
+
+
+
+ Failed to remove torrent content. Torrent: "%1". Error: "%2"
+
+
+
+
+ Torrent removed. Torrent: "%1"
+
+
+
+
UPnP/NAT-PMP support: OFF
دعم UPnP/NAT-PMP: متوقف
-
+
Failed to export torrent. Torrent: "%1". Destination: "%2". Reason: "%3"
فشل تصدير تورنت. تورنت: "%1". الوجهة: "%2". السبب: "%3"
-
+
Aborted saving resume data. Number of outstanding torrents: %1
تم إحباط حفظ بيانات الاستئناف. عدد التورنت المعلقة: %1
-
+
The configured network address is invalid. Address: "%1"
عنوان الشبكة الذي تم تضبيطه غير صالح. العنوان %1"
-
-
+
+
Failed to find the configured network address to listen on. Address: "%1"
فشل العثور على عنوان الشبكة الذي تم تضبيطه للاستماع إليه. العنوان "%1"
-
+
The configured network interface is invalid. Interface: "%1"
واجهة الشبكة التي تم تضبيطها غير صالحة. الواجهة: "%1"
-
+
Rejected invalid IP address while applying the list of banned IP addresses. IP: "%1"
تم رفض عنوان IP غير صالح أثناء تطبيق قائمة عناوين IP المحظورة. عنوان IP: "%1"
-
+
Added tracker to torrent. Torrent: "%1". Tracker: "%2"
تمت إضافة تتبع إلى تورنت. تورنت: "%1". المتعقب: "%2"
-
+
Removed tracker from torrent. Torrent: "%1". Tracker: "%2"
تمت إزالة المتتبع من التورنت. تورنت: "%1". المتعقب: "%2"
-
+
Added URL seed to torrent. Torrent: "%1". URL: "%2"
تمت إضافة بذور URL إلى التورنت. تورنت: "%1". عنوان URL: "%2"
-
+
Removed URL seed from torrent. Torrent: "%1". URL: "%2"
تمت إزالة بذور URL من التورنت. تورنت: "%1". عنوان URL: "%2"
-
- Torrent paused. Torrent: "%1"
- توقف التورنت مؤقتًا. تورنت: "%1"
-
-
-
+
Torrent resumed. Torrent: "%1"
استئنف التورنت. تورنت: "%1"
-
+
Torrent download finished. Torrent: "%1"
انتهى تحميل التورنت. تورنت: "%1"
-
+
Torrent move canceled. Torrent: "%1". Source: "%2". Destination: "%3"
تم إلغاء حركة التورنت. تورنت: "%1". المصدر: "%2". الوجهة: "%3"
-
+
+ Torrent stopped. Torrent: "%1"
+
+
+
+
Failed to enqueue torrent move. Torrent: "%1". Source: "%2". Destination: "%3". Reason: torrent is currently moving to the destination
فشل في إدراج نقل التورنت. تورنت: "%1". المصدر: "%2". الوجهة: "%3". السبب: ينتقل التورنت حاليًا إلى الوجهة
-
+
Failed to enqueue torrent move. Torrent: "%1". Source: "%2" Destination: "%3". Reason: both paths point to the same location
فشل في إدراج نقل التورنت. تورنت: "%1". المصدر: "%2" الوجهة: "%3". السبب: كلا المسارين يشيران إلى نفس الموقع
-
+
Enqueued torrent move. Torrent: "%1". Source: "%2". Destination: "%3"
تحرك سيل في الصف. تورنت: "%1". المصدر: "%2". الوجهة: "%3"
-
+
Start moving torrent. Torrent: "%1". Destination: "%2"
ابدأ في تحريك التورنت. تورنت: "%1". الوجهة: "%2"
-
+
Failed to save Categories configuration. File: "%1". Error: "%2"
فشل حفظ تضبيط الفئات. الملف: "%1". خطأ: "%2"
-
+
Failed to parse Categories configuration. File: "%1". Error: "%2"
فشل في تحليل تضبيط الفئات. الملف: "%1". خطأ: "%2"
-
+
Successfully parsed the IP filter file. Number of rules applied: %1
تم تحليل ملف مرشح IP بنجاح. عدد القواعد المطبقة: %1
-
+
Failed to parse the IP filter file
فشل في تحليل ملف مرشح IP
-
+
Restored torrent. Torrent: "%1"
استُعيدت التورنت. تورنت: "%1"
-
+
Added new torrent. Torrent: "%1"
تمت إضافة تورنت جديد. تورنت: "%1"
-
+
Torrent errored. Torrent: "%1". Error: "%2"
خطأ في التورنت. تورنت: "%1". خطأ: "%2"
-
-
- Removed torrent. Torrent: "%1"
- أُزيلت التورنت. تورنت: "%1"
-
-
-
- Removed torrent and deleted its content. Torrent: "%1"
- أُزيلت التورنت وحُذفت محتواه. تورنت: "%1"
-
-
-
+
Torrent is missing SSL parameters. Torrent: "%1". Message: "%2"
-
+ يفتقر التورنت إلى معلمات SSL. التورنت: "%1". الرسالة: "%2"
-
+
File error alert. Torrent: "%1". File: "%2". Reason: "%3"
تنبيه خطأ في الملف. تورنت: "%1". الملف: "%2". السبب: "%3"
-
+
UPnP/NAT-PMP port mapping failed. Message: "%1"
فشل تعيين منفذ UPnP/NAT-PMP. الرسالة: "%1"
-
+
UPnP/NAT-PMP port mapping succeeded. Message: "%1"
نجح تعيين منفذ UPnP/NAT-PMP. الرسالة: "%1"
-
+
IP filter
this peer was blocked. Reason: IP filter.
تصفية الآي بي
-
+
filtered port (%1)
this peer was blocked. Reason: filtered port (8899).
المنفذ المتصفي (%1)
-
+
privileged port (%1)
this peer was blocked. Reason: privileged port (80).
المنفذ المميز (%1)
-
+
BitTorrent session encountered a serious error. Reason: "%1"
-
+ واجهت جلسة BitTorrent خطئًا خطيرًا. السبب: "%1"
-
+
SOCKS5 proxy error. Address: %1. Message: "%2".
خطأ وكيل SOCKS5. العنوان: %1. الرسالة: "%2".
-
+
%1 mixed mode restrictions
this peer was blocked. Reason: I2P mixed mode restrictions.
%1 قيود الوضع المختلط
-
+
Failed to load Categories. %1
فشل تحميل الفئات. %1
-
+
Failed to load Categories configuration. File: "%1". Error: "Invalid data format"
فشل تحميل تضبيط الفئات. الملف: "%1". خطأ: "تنسيق البيانات غير صالح"
-
- Removed torrent but failed to delete its content and/or partfile. Torrent: "%1". Error: "%2"
- أُزيلت التورنت ولكن فشل في حذف محتواه و/أو ملفه الجزئي. تورنت: "%1". خطأ: "%2"
-
-
-
+
%1 is disabled
this peer was blocked. Reason: uTP is disabled.
%1 مُعطّل
-
+
%1 is disabled
this peer was blocked. Reason: TCP is disabled.
%1 مُعطّل
-
+
URL seed DNS lookup failed. Torrent: "%1". URL: "%2". Error: "%3"
فشل البحث عن DNS لبذرة عنوان URL. تورنت: "%1". URL: "%2". خطأ: "%3"
-
+
Received error message from URL seed. Torrent: "%1". URL: "%2". Message: "%3"
تم تلقي رسالة خطأ من بذرة URL. تورنت: "%1". URL: "%2". الرسالة: "%3"
-
+
Successfully listening on IP. IP: "%1". Port: "%2/%3"
تم الاستماع بنجاح على IP. عنوان IP: "%1". المنفذ: "%2/%3"
-
+
Failed to listen on IP. IP: "%1". Port: "%2/%3". Reason: "%4"
فشل الاستماع على IP. عنوان IP: "%1". المنفذ: "%2/%3". السبب: "%4"
-
+
Detected external IP. IP: "%1"
تم اكتشاف IP خارجي. IP: "%1"
-
+
Error: Internal alert queue is full and alerts are dropped, you might see degraded performance. Dropped alert type: "%1". Message: "%2"
خطأ: قائمة انتظار التنبيهات الداخلية ممتلئة وتم إسقاط التنبيهات، وقد ترى انخفاضًا في الأداء. نوع التنبيه المسقط: "%1". الرسالة: "%2"
-
+
Moved torrent successfully. Torrent: "%1". Destination: "%2"
تم النقل بالتورنت بنجاح تورنت: "%1". الوجهة: "%2"
-
+
Failed to move torrent. Torrent: "%1". Source: "%2". Destination: "%3". Reason: "%4"
فشل في التورنت. تورنت: "%1". المصدر: "%2". الوجهة: "%3". السبب: "%4"
@@ -2546,19 +2654,19 @@ Supports the formats: S01E01, 1x1, 2017.12.31 and 31.12.2017 (Date formats also
Failed to start seeding.
-
+ فشل في بدء التوزيع.
BitTorrent::TorrentCreator
-
+
Operation aborted
تم إحباط العملية
-
-
+
+
Create new torrent file failed. Reason: %1.
فشل في إنشاء ملف تورنت جديد. السبب: %1.
@@ -2566,67 +2674,67 @@ Supports the formats: S01E01, 1x1, 2017.12.31 and 31.12.2017 (Date formats also
BitTorrent::TorrentImpl
-
+
Failed to add peer "%1" to torrent "%2". Reason: %3
فشل إضافة القرين "%1" إلى التورنت "%2". السبب: %3
-
+
Peer "%1" is added to torrent "%2"
تم إضافة القرين '%1' إلى التورنت '%2'
-
+
Unexpected data detected. Torrent: %1. Data: total_wanted=%2 total_wanted_done=%3.
تم اكتشاف بيانات غير متوقعة. تورنت: %1. البيانات: total_wanted=%2 total_wanted_done=%3.
-
+
Couldn't write to file. Reason: "%1". Torrent is now in "upload only" mode.
لا يمكن الكتابة إلى الملف. السبب: "%1". أصبح التورنت الآن في وضع "الرفع فقط".
-
+
Download first and last piece first: %1, torrent: '%2'
تنزيل أول وآخر قطعة أولًا: %1، التورنت: '%2'
-
+
On
مُفعل
-
+
Off
مُعطل
-
+
Failed to reload torrent. Torrent: %1. Reason: %2
-
+ فشل إعادة تحميل التورنت. التورنت: %1. السبب: %2
-
+
Generate resume data failed. Torrent: "%1". Reason: "%2"
فشل إنشاء بيانات الاستئناف. تورنت: "%1". السبب: "%2"
-
+
Failed to restore torrent. Files were probably moved or storage isn't accessible. Torrent: "%1". Reason: "%2"
فشل في استعادة التورنت. ربما تم نقل الملفات أو لا يمكن الوصول إلى مساحة التخزين. تورنت: "%1". السبب: "%2"
-
+
Missing metadata
البيانات الوصفية مفقودة
-
+
File rename failed. Torrent: "%1", file: "%2", reason: "%3"
فشل إعادة تسمية الملف. التورنت: "%1"، الملف: "%2"، السبب: "%3"
-
+
Performance alert: %1. More info: %2
تنبيه الأداء: %1. مزيد من المعلومات: %2
@@ -2663,12 +2771,6 @@ Supports the formats: S01E01, 1x1, 2017.12.31 and 31.12.2017 (Date formats also
Expected integer number in environment variable '%1', but got '%2'
رقم صحيح متوقع في متغير المحيط '%1'، لكن تم الحصول على '%2'
-
-
- Parameter '%1' must follow syntax '%1=%2'
- e.g. Parameter '--add-paused' must follow syntax '--add-paused=<true|false>'
- يجب أن يتبع المعلمة '%1' بناء الجملة '%1=%2'
-
Expected %1 in environment variable '%2', but got '%3'
@@ -2705,10 +2807,16 @@ Supports the formats: S01E01, 1x1, 2017.12.31 and 31.12.2017 (Date formats also
Display this help message and exit
عرض رسالة المساعدة هذه والخروج
+
+
+ Parameter '%1' must follow syntax '%1=%2'
+ e.g. Parameter '--add-stopped' must follow syntax '--add-stopped=<true|false>'
+ يجب أن يتبع المعلمة '%1' بناء الجملة '%1=%2'
+
Confirm the legal notice
-
+ تأكيد الإشعار القانوني
@@ -2719,7 +2827,7 @@ Supports the formats: S01E01, 1x1, 2017.12.31 and 31.12.2017 (Date formats also
Change the WebUI port
-
+ تغيير منفذ واجهة الويب
@@ -2790,8 +2898,8 @@ Supports the formats: S01E01, 1x1, 2017.12.31 and 31.12.2017 (Date formats also
- Add torrents as started or paused
- أضف التورنت كـ تم بدؤه أو متوقف
+ Add torrents as running or stopped
+
@@ -2881,13 +2989,13 @@ Supports the formats: S01E01, 1x1, 2017.12.31 and 31.12.2017 (Date formats also
- Resume torrents
- استئناف التورنتات
+ Start torrents
+
- Pause torrents
- إيقاف مؤقت التورنتات
+ Stop torrents
+
@@ -2898,15 +3006,20 @@ Supports the formats: S01E01, 1x1, 2017.12.31 and 31.12.2017 (Date formats also
ColorWidget
-
+
Edit...
تحرير...
-
+
Reset
إعادة تعيين
+
+
+ System
+
+
CookiesDialog
@@ -2947,12 +3060,12 @@ Supports the formats: S01E01, 1x1, 2017.12.31 and 31.12.2017 (Date formats also
CustomThemeSource
-
+
Failed to load custom theme style sheet. %1
فشل تحميل ورقة أنماط السمة المخصصة. %1
-
+
Failed to load custom theme colors. %1
فشل تحميل ألوان السمات المخصصة. %1
@@ -2960,7 +3073,7 @@ Supports the formats: S01E01, 1x1, 2017.12.31 and 31.12.2017 (Date formats also
DefaultThemeSource
-
+
Failed to load default theme colors. %1
فشل تحميل ألوان السمة الافتراضية. %1
@@ -2979,23 +3092,23 @@ Supports the formats: S01E01, 1x1, 2017.12.31 and 31.12.2017 (Date formats also
- Also permanently delete the files
- أيضًا احذف الملفات نهائيًا
+ Also remove the content files
+
-
+
Are you sure you want to remove '%1' from the transfer list?
Are you sure you want to remove 'ubuntu-linux-iso' from the transfer list?
هل أنت متأكد أنك تريد إزالة '%1' من قائمة النقل؟
-
+
Are you sure you want to remove these %1 torrents from the transfer list?
Are you sure you want to remove these 5 torrents from the transfer list?
هل أنت متأكد من رغبتك في إزالة ملفات التورنت %1 هذه من قائمة النقل؟
-
+
Remove
إزالة
@@ -3023,12 +3136,12 @@ Supports the formats: S01E01, 1x1, 2017.12.31 and 31.12.2017 (Date formats also
تنزيل
-
+
No URL entered
لم يتم إدخال روابط
-
+
Please type at least one URL.
برجاء إدخال رابط واحد على الأقل.
@@ -3187,25 +3300,48 @@ Supports the formats: S01E01, 1x1, 2017.12.31 and 31.12.2017 (Date formats also
خطأ في التحليل: ملف عامل التصفية ليس ملف PeerGuardian P2B صالح.
+
+ FilterPatternFormatMenu
+
+
+ Pattern Format
+
+
+
+
+ Plain text
+
+
+
+
+ Wildcards
+
+
+
+
+ Regular expression
+
+
+
GUIAddTorrentManager
-
+
Downloading torrent... Source: "%1"
تحميل التورنت... من المصدر: "%1"
-
- Trackers cannot be merged because it is a private torrent
-
-
-
-
+
Torrent is already present
التورنت موجود مسبقا بالفعل
-
+
+ Trackers cannot be merged because it is a private torrent.
+
+
+
+
Torrent '%1' is already in the transfer list. Do you want to merge trackers from new source?
التورنت '%1' موجود بالفعل في قائمة النقل. هل تريد دمج المتتبعات من مصدر الجديد؟
@@ -3252,17 +3388,17 @@ Supports the formats: S01E01, 1x1, 2017.12.31 and 31.12.2017 (Date formats also
Http::Connection
-
+
Http request size exceeds limitation, closing socket. Limit: %1, IP: %2
يتجاوز حجم طلب Http الحد ، إغلاق مأخذ التوصيل. الحد: %1، الآي بي: %2
-
+
Bad Http request method, closing socket. IP: %1. Method: "%2"
طريقة طلب Http غير صالحة، إغلاق المقبس. عنوان IP: %1. الطريقة: "%2"
-
+
Bad Http request, closing socket. IP: %1
طلب Http غير صالح ، إغلاق مأخذ التوصيل. الآي بي: %1
@@ -3303,22 +3439,22 @@ Supports the formats: S01E01, 1x1, 2017.12.31 and 31.12.2017 (Date formats also
IconWidget
-
+
Browse...
استعرض...
-
+
Reset
إعادة تعيين
-
+
Select icon
حدد الايقونة
-
+
Supported image files
ملفات الصور المدعومة
@@ -3343,24 +3479,24 @@ Supports the formats: S01E01, 1x1, 2017.12.31 and 31.12.2017 (Date formats also
If you have read the legal notice, you can use command line option `--confirm-legal-notice` to suppress this message.
-
+ إذا كنت قد قرأت الإشعار القانوني، يمكنك استخدام خيار سطر الأوامر `--confirm-legal-notice` لإخفاء هذه الرسالة.
Press 'Enter' key to continue...
-
+ اضغط على مفتاح "Enter" للاستمرار
LogPeerModel
-
+
%1 was blocked. Reason: %2.
0.0.0.0 was blocked. Reason: reason for blocking.
تم حظر %1. السبب: %2.
-
+
%1 was banned
0.0.0.0 was banned
تم حظر %1
@@ -3369,62 +3505,62 @@ Supports the formats: S01E01, 1x1, 2017.12.31 and 31.12.2017 (Date formats also
Main
-
+
%1 is an unknown command line parameter.
--random-parameter is an unknown command line parameter.
%1 معلمة سطر أوامر غير معروفة.
-
-
+
+
%1 must be the single command line parameter.
يجب أن تكون %1 معلمة سطر الأوامر الفردية.
-
+
Run application with -h option to read about command line parameters.
قم بتشغيل التطبيق بخيار -h لقراءة معلمات سطر الأوامر.
-
+
Bad command line
سطر أوامر تالف
-
+
Bad command line:
سطر أوامر تالف:
-
+
An unrecoverable error occurred.
-
+ حدث خطأ غير قابل للإصلاح.
+
-
qBittorrent has encountered an unrecoverable error.
-
+ لقد واجه برنامج qBittorrent خطأً غير قابل للإصلاح.
-
+
You cannot use %1: qBittorrent is already running.
-
+ لا يمكنك استخدام %1: qBittorrent هو قيد التشغيل بالفعل.
-
+
Another qBittorrent instance is already running.
-
+ هناك نسخة أخرى من qBittorrent تعمل بالفعل.
+
+
+
+ Found unexpected qBittorrent instance. Exiting this instance. Current process ID: %1.
+ تم العثور على مثيل غير متوقع لـ qBittorrent. جاري الخروج من هذا المثيل. معرف العملية الحالية: %1.
- Found unexpected qBittorrent instance. Exiting this instance. Current process ID: %1.
-
-
-
-
Error when daemonizing. Reason: "%1". Error code: %2.
-
+ خطأ عند تشغيل البرنامج في الخلفية. السبب: "%1". رمز الخطأ: %2.
@@ -3435,609 +3571,615 @@ Supports the formats: S01E01, 1x1, 2017.12.31 and 31.12.2017 (Date formats also
ت&حرير
-
+
&Tools
أ&دوات
-
+
&File
&ملف
-
+
&Help
م&ساعدة
-
+
On Downloads &Done
عند انت&هاء التنزيلات
-
+
&View
&عرض
-
+
&Options...
&خيارات...
-
- &Resume
- ا&ستئناف
-
-
-
+
&Remove
&إزالة
-
+
Torrent &Creator
مُ&نشيء التورنت
-
-
+
+
Alternative Speed Limits
حدود السرعات البديلة
-
+
&Top Toolbar
شريط الأدوات ال&علوي
-
+
Display Top Toolbar
عرض شريط الأدوات العلوي
-
+
Status &Bar
&شريط الحالة
-
+
Filters Sidebar
تصفيات الشريط الجانبي
-
+
S&peed in Title Bar
ال&سرعة في شريط العنوان
-
+
Show Transfer Speed in Title Bar
عرض السرعة في شريط العنوان
-
+
&RSS Reader
&قارئ RSS
-
+
Search &Engine
مُ&حرك البحث
-
+
L&ock qBittorrent
&قفل واجهة البرنامج
-
+
Do&nate!
ت&برع!
-
+
&Do nothing
&لا تفعل شيئا
-
+
Close Window
إغلاق النافذة
-
- R&esume All
- اس&تئناف الكل
-
-
-
+
Manage Cookies...
إدارة الكعكات...
-
+
Manage stored network cookies
إدارة كعكات الشبكة المُخزّنة
-
+
Normal Messages
رسائل عادية
-
+
Information Messages
رسائل معلومات
-
+
Warning Messages
رسائل تحذيرية
-
+
Critical Messages
رسائل حرجة
-
+
&Log
ال&سجل
-
+
+ Sta&rt
+
+
+
+
+ Sto&p
+
+
+
+
+ &Resume Session
+
+
+
+
+ Pau&se Session
+
+
+
+
Set Global Speed Limits...
تعيين حدود السرعة العامة...
-
+
Bottom of Queue
أسفل الصف
-
+
Move to the bottom of the queue
انتقل إلى أسفل الصف
-
+
Top of Queue
قمة الصف
-
+
Move to the top of the queue
انتقل إلى قمة الصف
-
+
Move Down Queue
انتقل أسفل في الصف
-
+
Move down in the queue
انتقل في أسفل الصف
-
+
Move Up Queue
انتقل أعلى في الصف
-
+
Move up in the queue
انتقل في أعلى الصف
-
+
&Exit qBittorrent
إ&غلاق البرنامج
-
+
&Suspend System
ت&عليق النظام
-
+
&Hibernate System
إ&لباث النظام
-
+
S&hutdown System
إ&طفاء تشغيل الجهاز
-
+
&Statistics
الإ&حصائات
-
+
Check for Updates
البحث عن تحديثات
-
+
Check for Program Updates
التحقق من وجود تحديثات للتطبيق
-
+
&About
&عن
-
- &Pause
- إ&لباث
-
-
-
- P&ause All
- إل&باث الكل
-
-
-
+
&Add Torrent File...
إ&ضافة ملف تورنت...
-
+
Open
فتح
-
+
E&xit
&خروج
-
+
Open URL
فتح الرابط
-
+
&Documentation
الت&عليمات
-
+
Lock
أوصد
-
-
-
+
+
+
Show
أظهر
-
+
Check for program updates
التحقق من وجود تحديثات للتطبيق
-
+
Add Torrent &Link...
إضافة &رابط تورنت...
-
+
If you like qBittorrent, please donate!
إذا أعجبك كيوبتتورنت، رجاءً تبرع!
-
-
+
+
Execution Log
السجل
-
+
Clear the password
إزالة كلمة السر
-
+
&Set Password
ت&عيين كلمة سر
-
+
Preferences
التفضيلات
-
+
&Clear Password
&مسح كلمة السر
-
+
Transfers
النقل
-
-
+
+
qBittorrent is minimized to tray
كيوبتتورنت مُصغّر في جوار الساعة
-
-
-
+
+
+
This behavior can be changed in the settings. You won't be reminded again.
هذا السلوك يمكن تغييره من الإعدادات. لن يتم تذكيرك مرة أخرى.
-
+
Icons Only
أيقونات فقط
-
+
Text Only
نص فقط
-
+
Text Alongside Icons
النص بجانب الأيقونات
-
+
Text Under Icons
النص أسفل الأيقونات
-
+
Follow System Style
اتباع شكل النظام
-
-
+
+
UI lock password
كلمة سر قفل الواجهة
-
-
+
+
Please type the UI lock password:
اكتب كلمة سر قفل الواجهة:
-
+
Are you sure you want to clear the password?
هل ترغب حقا في إزالة كلمة السر؟
-
+
Use regular expressions
استخدم التعبيرات العادية
-
+
Search
البحث
-
+
Transfers (%1)
النقل (%1)
-
+
qBittorrent was just updated and needs to be restarted for the changes to be effective.
تم تحديث كيوبتتورنت للتو ويحتاج لإعادة تشغيله لتصبح التغييرات فعّالة.
-
+
qBittorrent is closed to tray
تم إغلاق كيوبتتورنت إلى جوار الساعة
-
+
Some files are currently transferring.
بعض الملفات تنقل حاليا.
-
+
Are you sure you want to quit qBittorrent?
هل أنت متأكد من رغبتك في إغلاق كيوبتتورنت؟
-
+
&No
&لا
-
+
&Yes
&نعم
-
+
&Always Yes
نعم &دائما
-
+
Options saved.
تم حفظ الخيارات.
-
- [D: %1, U: %2] %3
- D = Download; U = Upload; %3 is the rest of the window title
+
+ [PAUSED] %1
+ %1 is the rest of the window title
-
-
+
+ [D: %1, U: %2] %3
+ D = Download; U = Upload; %3 is the rest of the window title
+ [D: %1, U: %2] %3
+
+
+
+
Missing Python Runtime
Python Runtime مفقود
-
+
qBittorrent Update Available
يوجد تحديث متاح
-
+
Python is required to use the search engine but it does not seem to be installed.
Do you want to install it now?
كيوبت تورنت بحاجة لبايثون ليتمكن من تشغيل محرك البحث، ولكن على ما يبدو أن بايثون غير مثبّت على جهازك.
هل ترغب بتثبيت بايثون الآن؟
-
+
Python is required to use the search engine but it does not seem to be installed.
كيوبت تورنت بحاجة لبايثون ليتمكن من تشغيل محرك البحث، ولكن على ما يبدو أن بايثون غير مثبّت على جهازك.
-
-
+
+
Old Python Runtime
إصدار بايثون قديم
-
+
A new version is available.
إصدار جديد متاح.
-
+
Do you want to download %1?
هل ترغب بتنزيل %1؟
-
+
Open changelog...
فتح سجل التغييرات ...
-
+
No updates available.
You are already using the latest version.
لا تحديثات متاحة.
أنت تستخدم أحدث إصدار.
-
+
&Check for Updates
&فحص وجود تحديثات
-
+
Your Python version (%1) is outdated. Minimum requirement: %2.
Do you want to install a newer version now?
إصدار بايثون لديك قديم (%1). والإصدار المتطلب يجب أن يكون %2 على الأقل.
هل ترغب بتثبيت الإصدار الأحدث الآن؟
-
+
Your Python version (%1) is outdated. Please upgrade to latest version for search engines to work.
Minimum requirement: %2.
إصدار بايثون لديك (%1) قديم. يرجى الترقية إلى أحدث إصدار حتى تعمل محركات البحث.
أدنى إصدار ممكن: %2.
-
+
+ Paused
+ مُلبث
+
+
+
Checking for Updates...
يتفقد وجود تحديثات...
-
+
Already checking for program updates in the background
يتحقق من وجود تحديثات للتطبيق في الخلفية
-
+
Download error
خطأ في التنزيل
-
+
Python setup could not be downloaded, reason: %1.
Please install it manually.
تعذّر تنزيل مُثبّت بايثون، والسبب: %1.
يرجى تثبيته يدويا.
-
-
+
+
Invalid password
كلمة سرّ خاطئة
-
+
Filter torrents...
تصفية التورنت..
-
+
Filter by:
صنف بواسطة:
-
+
The password must be at least 3 characters long
يجب أن تتكون كلمة المرور من 3 أحرف على الأقل
-
-
+
+
RSS (%1)
RSS (%1)
-
+
The password is invalid
كلمة السرّ خاطئة
-
+
DL speed: %1
e.g: Download speed: 10 KiB/s
سرعة التنزيل: %1
-
+
UP speed: %1
e.g: Upload speed: 10 KiB/s
سرعة الرفع: %1
- [D: %1, U: %2] qBittorrent %3
- D = Download; U = Upload; %3 is qBittorrent version
- [تنزيل: %1, رفع: %2] كيوبتتورنت %3
-
-
-
+
Hide
إخفاء
-
+
Exiting qBittorrent
إغلاق البرنامج
-
+
Open Torrent Files
فتح ملف تورنت
-
+
Torrent Files
ملفات التورنت
@@ -4232,7 +4374,12 @@ Please install it manually.
Net::DownloadManager
-
+
+ SSL error, URL: "%1", errors: "%2"
+
+
+
+
Ignoring SSL error, URL: "%1", errors: "%2"
تجاهل خطأ SSL ، الرابط: "%1"، الأخطاء: "%2"
@@ -5620,284 +5767,284 @@ Please install it manually.
متقدم
-
+
+ Style:
+
+
+
+
Customize UI Theme...
تخصيص سمة واجهة المستخدم...
-
+
Transfer List
قائمة النقل
-
+
Confirm when deleting torrents
التأكيد عند حذف التورنتات
-
- Shows a confirmation dialog upon pausing/resuming all the torrents
- يعرض مربع حوار التأكيد عند الإيقاف المؤقت/استئناف كافة ملفات التورنت
-
-
-
- Confirm "Pause/Resume all" actions
- قم بتأكيد إجراءات "الإيقاف المؤقت/استئناف الكل".
-
-
-
+
Use alternating row colors
In table elements, every other row will have a grey background.
استخدام ألوان متضادة للأسطر
-
+
Hide zero and infinity values
إخفاء قيم الصفر واللانهاية
-
+
Always
دائما
-
- Paused torrents only
- التورنتات المٌقفة مؤقتًا فقط
-
-
-
+
Action on double-click
الإجراء عند النقر المزدوج
-
+
Downloading torrents:
أثناء تنزيل التورنتات:
-
-
+
+
Start / Stop Torrent
تشغيل / إيقاف التورنت
-
-
+
+
Open destination folder
فتح المجلد الحاوي
-
-
+
+
No action
دون إجراء
-
+
Completed torrents:
التورنتات المكتملة:
-
+
Auto hide zero status filters
إخفاء مرشحات الحالة الصفرية تلقائيًا
-
+
Desktop
سطح الكتب
-
+
Start qBittorrent on Windows start up
ابدأ كيوبتتورنت عند بدء تشغيل ويندوز
-
+
Show splash screen on start up
إظهار شاشة البدء عند بدء البرنامج
-
+
Confirmation on exit when torrents are active
تأكيد الإغلاق عند وجود تورنتات نشطة
-
+
Confirmation on auto-exit when downloads finish
تأكيد الإغلاق التلقائي عند انتهاء التنزيلات
-
+
<html><head/><body><p>To set qBittorrent as default program for .torrent files and/or Magnet links<br/>you can use <span style=" font-weight:600;">Default Programs</span> dialog from <span style=" font-weight:600;">Control Panel</span>.</p></body></html>
-
+
KiB
ك.بايت
-
+
Torrent content layout:
تخطيط محتوى التورنت:
-
+
Original
الأصلي
-
+
Create subfolder
إنشاء مجلد فرعي
-
+
Don't create subfolder
لا تقم بإنشاء مجلد فرعي
-
+
The torrent will be added to the top of the download queue
ستتم إضافة التورنت إلى أعلى صف التنزيل
-
+
Add to top of queue
The torrent will be added to the top of the download queue
أضفه إلى قمة الصف
-
+
+ The torrent will be added to download list in a stopped state
+
+
+
+
When duplicate torrent is being added
عندما يتم إضافة تورنت مكررة
-
+
Merge trackers to existing torrent
دمج المتتبعات في التورنت الموجودة
-
+
Keep unselected files in ".unwanted" folder
-
+
Add...
إضافة...
-
+
Options..
خيارات...
-
+
Remove
إزالة
-
+
Email notification &upon download completion
إرسال تنبيه عبر البريد الإلكتروني عند اكتمال التنزيل
-
+
+ Send test email
+
+
+
+
Peer connection protocol:
بروتوكول اتصال القرين:
-
+
Any
أي
-
+
I2P (experimental)
I2P (تجريبي)
-
+
<html><head/><body><p>If "mixed mode" is enabled I2P torrents are allowed to also get peers from other sources than the tracker, and connect to regular IPs, not providing any anonymization. This may be useful if the user is not interested in the anonymization of I2P, but still wants to be able to connect to I2P peers.</p></body></html>
<html><head/><body><p>إذا كان "الوضع المختلط" تم تفعيل تورنتات I2P، كما يُسمح لها بالحصول على أقران من مصادر أخرى غير المتتبع، والاتصال بعناوين IP العادية، دون توفير أي إخفاء للهوية. قد يكون هذا مفيدًا إذا لم يكن المستخدم مهتمًا بإخفاء هوية I2P، ولكنه لا يزال يريد أن يكون قادرًا على الاتصال بأقران I2P.
-
+
Mixed mode
وضع مختلط
-
+
Some options are incompatible with the chosen proxy type!
بعض الخيارات غير متوافقة مع نوع الوكيل الذي تم اختياره!
-
+
If checked, hostname lookups are done via the proxy
إذا تم تحديده، فسيتم إجراء عمليات البحث عن اسم المضيف (hostname) عبر الوكيل
-
+
Perform hostname lookup via proxy
إجراء بحث عن اسم المضيف عبر الوكيل
-
+
Use proxy for BitTorrent purposes
استخدم الوكيل لأغراض BitTorrent
-
+
RSS feeds will use proxy
سوف تستخدم مواجز RSS الوكيل
-
+
Use proxy for RSS purposes
استخدم الوكيل لأغراض RSS
-
+
Search engine, software updates or anything else will use proxy
سيستخدم محرك البحث أو تحديثات البرامج أو أي شيء آخر الوكيل
-
+
Use proxy for general purposes
استخدم الوكيل للأغراض العامة
-
+
IP Fi<ering
تصفية الآي بي
-
+
Schedule &the use of alternative rate limits
جدولة واستخدام المعدل البديل
-
+
From:
From start time
من:
-
+
To:
To end time
إلى:
-
+
Find peers on the DHT network
ابحث عن القرناء على شبكة DHT
-
+
Allow encryption: Connect to peers regardless of setting
Require encryption: Only connect to peers with protocol encryption
Disable encryption: Only connect to peers without protocol encryption
@@ -5906,145 +6053,135 @@ Disable encryption: Only connect to peers without protocol encryption
تعطيل التشفير: اتصل بالقرناء فقط بدون تشفير البروتوكول
-
+
Allow encryption
السماح بالتشفير
-
+
(<a href="https://github.com/qbittorrent/qBittorrent/wiki/Anonymous-Mode">More information</a>)
(<a href="https://github.com/qbittorrent/qBittorrent/wiki/Anonymous-Mode">لمعلومات أكثر</a>)
-
+
Maximum active checking torrents:
الحد الأقصى التحقق النشطة لتورنت:
-
+
&Torrent Queueing
&انتظار التورنت
-
+
When total seeding time reaches
عندما يصل وقت البذر الكلي
-
+
When inactive seeding time reaches
عندما يصل وقت البذر غير النشط
-
- A&utomatically add these trackers to new downloads:
- إضافة هذه المتتبعات تلقائيًا إلى التنزيلات الجديدة:
-
-
-
+
RSS Reader
قارئ RSS
-
+
Enable fetching RSS feeds
تفعيل جلب مواجز RSS
-
+
Feeds refresh interval:
الفاصل الزمني لتحديث المواجز:
-
+
Same host request delay:
-
+
Maximum number of articles per feed:
أقصى عدد من المقالات لكل موجز:
-
-
-
+
+
+
min
minutes
د
-
+
Seeding Limits
حدود البذر
-
- Pause torrent
- إيقاف مؤقت التورنت
-
-
-
+
Remove torrent
إزالة التورنت
-
+
Remove torrent and its files
إزالة التورنت وملفاته
-
+
Enable super seeding for torrent
تفعيل البذر الخارق للتورنت
-
+
When ratio reaches
عندما تصل النسبة
-
+
RSS Torrent Auto Downloader
منزّل التورنت التلقائي من تغذية RSS
-
+
Enable auto downloading of RSS torrents
تفعيل التنزيل التلقائي لتورنتات RSS
-
+
Edit auto downloading rules...
تحرير قواعد التنزيل التلقائي...
-
+
RSS Smart Episode Filter
RSS مُصفّي الحلقات الذكي
-
+
Download REPACK/PROPER episodes
تنزيل REPACK/PROPER الحلقات
-
+
Filters:
تصفيات:
-
+
Web User Interface (Remote control)
واجهة مستخدم الويب (التحكم عن بُعد)
-
+
IP address:
عنوان الآي بي:
-
+
IP address that the Web UI will bind to.
Specify an IPv4 or IPv6 address. You can specify "0.0.0.0" for any IPv4 address,
"::" for any IPv6 address, or "*" for both IPv4 and IPv6.
@@ -6053,42 +6190,42 @@ Specify an IPv4 or IPv6 address. You can specify "0.0.0.0" for any IPv
"::" لأي عنوان IPv6 ، أو "*" لكلا IPv4 و IPv6.
-
+
Ban client after consecutive failures:
حظر العميل بعد إخفاقات متتالية:
-
+
Never
أبدًا
-
+
ban for:
حظر لـ:
-
+
Session timeout:
مهلة الجلسة:
-
+
Disabled
مُعطّل
-
+
Enable cookie Secure flag (requires HTTPS)
تفعيل علامة تأمين ملفات تعريف الارتباط (يتطلب HTTPS)
-
+
Server domains:
نطاقات الخادم:
-
+
Whitelist for filtering HTTP Host header values.
In order to defend against DNS rebinding attack,
you should put in domain names used by WebUI server.
@@ -6101,37 +6238,37 @@ Use ';' to split multiple entries. Can use wildcard '*'.
-
+
&Use HTTPS instead of HTTP
استخدام HTTPS بدلًا من HTTP
-
+
Bypass authentication for clients on localhost
تجاوز المصادقة للعملاء على المضيف المحلي
-
+
Bypass authentication for clients in whitelisted IP subnets
تجاوز المصادقة للعملاء في شبكات الآي بي الفرعية المدرجة في القائمة البيضاء
-
+
IP subnet whitelist...
القائمة البيضاء للشبكة الفرعية للآي بي ...
-
+
Specify reverse proxy IPs (or subnets, e.g. 0.0.0.0/24) in order to use forwarded client address (X-Forwarded-For header). Use ';' to split multiple entries.
حدد عناوين IP للوكيل العكسي (أو الشبكات الفرعية، على سبيل المثال 0.0.0.0/24) لاستخدام عنوان العميل المُعاد توجيهه (رأس X-Forwarded-For). يستخدم '؛' لتقسيم إدخالات متعددة.
-
+
Upda&te my dynamic domain name
تحديث اسم النطاق الديناميكي الخاص بي
-
+
Minimize qBittorrent to notification area
تصغير كيوبتتورنت إلى جوار الساعة
@@ -6146,180 +6283,180 @@ Use ';' to split multiple entries. Can use wildcard '*'.اللغة:
-
+
Tray icon style:
مظهر الأيقونة في جوار الساعة:
-
-
+
+
Normal
عادي
-
+
File association
ارتباط الملف
-
+
Use qBittorrent for .torrent files
استخدام كيوبتتورنت لفتح ملفات .torrent
-
+
Use qBittorrent for magnet links
استخدام كيوبتتورنت لفتح الروابط المغناطيسية
-
+
Check for program updates
التحقق من وجود تحديثات للبرنامج
-
+
Power Management
إدارة الطاقة
-
+
Save path:
مسار الحفظ:
-
+
Backup the log file after:
قم بعمل نسخة احتياطية من ملف السجل بعد:
-
+
Delete backup logs older than:
حذف سجلات النسخ الاحتياطي الأقدم من:
-
+
When adding a torrent
عند إضافة تورنت
-
+
Bring torrent dialog to the front
إحضار نافذة التورنت إلى الأمام
-
+
Also delete .torrent files whose addition was cancelled
احذف أيضًا ملفات .torrent التي تم إلغاء إضافتها
-
+
Also when addition is cancelled
أيضا عندما يتم إلغاء الإضافة
-
+
Warning! Data loss possible!
تحذير! فقدان البيانات ممكن!
-
+
Saving Management
إدارة التوفير
-
+
Default Torrent Management Mode:
نمط إدارة التورنت الافتراضي:
-
+
Manual
يدوي
-
+
Automatic
آلي
-
+
When Torrent Category changed:
عند تغيير فئة التورنت:
-
+
Relocate torrent
نقل التورنت
-
+
Switch torrent to Manual Mode
تبديل التورنت إلى الوضع اليدوي
-
-
+
+
Relocate affected torrents
نقل التورنتات المتضررة
-
-
+
+
Switch affected torrents to Manual Mode
تبديل التورنتات المتضررة إلى الوضع اليدوي
-
+
Use Subcategories
استخدام فئات فرعية
-
+
Default Save Path:
مسار الحفظ الافتراضي:
-
+
Copy .torrent files to:
نسخ ملفات torrent. إلى:
-
+
Show &qBittorrent in notification area
إظهار كيوبتتورنت بجوار الساعة
-
+
&Log file
ملف السجل
-
+
Display &torrent content and some options
عرض محتويات التورنت وبعض الخيارات
-
+
De&lete .torrent files afterwards
حذف ملفات .torrent بعد ذلك
-
+
Copy .torrent files for finished downloads to:
نسخ ملفات .torrent للتنزيلات المنتهية إلى:
-
+
Pre-allocate disk space for all files
تخصيص مسبق لمساحة القرص لجميع الملفات
-
+
Use custom UI Theme
استخدم سمة واجهة مستخدم مخصصة
-
+
UI Theme file:
ملف سمة واجهة المستخدم الرسومية:
@@ -6329,214 +6466,214 @@ Use ';' to split multiple entries. Can use wildcard '*'.يتطلب تغيير إعدادات الواجهة إعادة تشغيل التطبيق
-
+
Shows a confirmation dialog upon torrent deletion
عرض مربع حوار لتأكيد حذف التورنت
-
-
+
+
Preview file, otherwise open destination folder
معاينة الملف، وإلا افتح مجلد الوجهة
-
-
+
+
Show torrent options
عرض خيارات التورنت
-
+
Shows a confirmation dialog when exiting with active torrents
عرض مربع حوار لتأكيد الخروج عند وجود تورنتات نشطة
-
+
When minimizing, the main window is closed and must be reopened from the systray icon
عند التصغير، يتم إغلاق النافذة الرئيسية ويجب إعادة فتحها من جوار الساعة
-
+
The systray icon will still be visible when closing the main window
ستظل أيقونة البرنامج بجوار الساعة عند إغلاق النافذة الرئيسية
-
+
Close qBittorrent to notification area
The systray icon will still be visible when closing the main window
أغلق كيوبتتورنت إلى جوار الساعة
-
+
Monochrome (for dark theme)
أحادي اللون (للمظهر الداكن)
-
+
Monochrome (for light theme)
أحادي اللون (للمظهر الفاتح)
-
+
Inhibit system sleep when torrents are downloading
منع النظام من السُبات عند تنزيل ملفات التورنت
-
+
Inhibit system sleep when torrents are seeding
منع النظام من السُبات عندما يتم بذر التورنتات
-
+
Creates an additional log file after the log file reaches the specified file size
إنشاء ملف سجل إضافي بعد أن يصل ملف السجل إلى حجم الملف المحدد
-
+
days
Delete backup logs older than 10 days
أيام
-
+
months
Delete backup logs older than 10 months
شهور
-
+
years
Delete backup logs older than 10 years
أعوام
-
+
Log performance warnings
سجل تحذيرات الأداء
-
- The torrent will be added to download list in a paused state
- ستتم إضافة التورنت إلى قائمة التنزيل في حالة الإيقاف المؤقت
-
-
-
+
Do not start the download automatically
- The torrent will be added to download list in a paused state
+ The torrent will be added to download list in a stopped state
عدم بدء التنزيل بشكل تلقائي
-
+
Whether the .torrent file should be deleted after adding it
ما إذا كان يجب حذف ملف .torrent بعد إضافته
-
+
Allocate full file sizes on disk before starting downloads, to minimize fragmentation. Only useful for HDDs.
تخصيص أحجام الملفات الكاملة على القرص قبل بدء التنزيلات لتقليل التجزئة. مفيد فقط لمحركات الأقراص الصلبة.
-
+
Append .!qB extension to incomplete files
إضافة امتداد !qB. للملفات غير المنتهية
-
+
When a torrent is downloaded, offer to add torrents from any .torrent files found inside it
عند تنزيل ملف تورنت ، اعرض إضافة التورنتات من أي ملفات .torrent موجودة بداخله
-
+
Enable recursive download dialog
تفعيل مربع حوار التنزيل المتكرر
-
+
Automatic: Various torrent properties (e.g. save path) will be decided by the associated category
Manual: Various torrent properties (e.g. save path) must be assigned manually
تلقائي: سيتم تحديد خصائص التورنت المختلفة (مثل مسار الحفظ) من خلال الفئة المرتبطة
يدوي: يجب تعيين خصائص التورنت المختلفة (مثل مسار الحفظ) يدويًا
-
+
When Default Save/Incomplete Path changed:
عند تغيير مسار الحفظ/غير الكامل الافتراضي:
-
+
When Category Save Path changed:
عند تغيير مسار حفظ الفئة:
-
+
Use Category paths in Manual Mode
استخدم مسارات الفئات في الوضع اليدوي
-
+
Resolve relative Save Path against appropriate Category path instead of Default one
حل مسار الحفظ النسبي مقابل مسار الفئة المناسب بدلاً من المسار الافتراضي
-
+
Use icons from system theme
استخدم الأيقونات من سمة النظام
-
+
+ Stopped torrents only
+
+
+
+
Window state on start up:
حالة النافذة عند بدء التشغيل:
-
+
qBittorrent window state on start up
qBittorrent حالة النافذة عند بدء التشغيل
-
+
Torrent stop condition:
شرط توقف التورنت:
-
-
+
+
None
بدون
-
-
+
+
Metadata received
تم استلام البيانات الوصفية
-
-
+
+
Files checked
تم فحص الملف
-
+
Ask for merging trackers when torrent is being added manually
اطلب دمج المتتبعات عند إضافة التورنت يدويًا
-
+
Use another path for incomplete torrents:
استخدم مسارًا آخر للتورنتات غير المكتملة:
-
+
Automatically add torrents from:
إضافة التورنتات تلقائيًا من:
-
+
Excluded file names
أسماء الملفات المستبعدة
-
+
Blacklist filtered file names from being downloaded from torrent(s).
Files matching any of the filters in this list will have their priority automatically set to "Do not download".
@@ -6565,770 +6702,803 @@ readme.txt: تصفية اسم الملف الدقيق.
الملف التمهيدي [0-9].txt: قم بتصفية "readme1.txt" و"readme2.txt" ولكن ليس "readme10.txt".
-
+
Receiver
المتلقي
-
+
To:
To receiver
إلى:
-
+
SMTP server:
خادم SMTP:
-
+
Sender
مُرسل
-
+
From:
From sender
من:
-
+
This server requires a secure connection (SSL)
يتطلب هذا الخادم اتصالًا آمنًا (SSL)
-
-
+
+
Authentication
المصادقة
-
-
-
-
+
+
+
+
Username:
اسم المستخدم:
-
-
-
-
+
+
+
+
Password:
كلمة المرور:
-
+
Run external program
تشغيل برنامج خارجي
-
+
Run on torrent added
التشغيل على التورنت مضافة
-
+
Run on torrent finished
تشغيل على التورنت انتهى
-
+
Show console window
عرض نافذة وحدة التحكم
-
+
TCP and μTP
TCP و μTP
-
+
Listening Port
منفذ الاستماع
-
+
Port used for incoming connections:
المنفذ المستخدم للاتصالات الواردة:
-
+
Set to 0 to let your system pick an unused port
قم بالتعيين إلى 0 للسماح للنظام الخاص بك باختيار منفذ غير مستخدم
-
+
Random
عشوائي
-
+
Use UPnP / NAT-PMP port forwarding from my router
استخدام UPnP / NAT-PMP لفتح المنافذ تلقائيا
-
+
Connections Limits
حدود الاتصالات
-
+
Maximum number of connections per torrent:
أقصى عدد من الاتصالات لكل تورنت:
-
+
Global maximum number of connections:
أقصى عدد من الاتصالات العامة:
-
+
Maximum number of upload slots per torrent:
أقصى عدد من فتحات الرفع لكل تورنت:
-
+
Global maximum number of upload slots:
أقصى عدد من فتحات الرفع العامة:
-
+
Proxy Server
خادم البروكسي
-
+
Type:
النوع:
-
+
SOCKS4
SOCKS4
-
+
SOCKS5
SOCKS5
-
+
HTTP
HTTP
-
-
+
+
Host:
المضيف:
-
-
-
+
+
+
Port:
المنفذ:
-
+
Otherwise, the proxy server is only used for tracker connections
خلاف ذلك، خادم البروكسي سيستخدم على اتصالات المتتبعات فقط
-
+
Use proxy for peer connections
استخدام البروكسي على اتصالات القرناء
-
+
A&uthentication
المصادقة
-
+
Info: The password is saved unencrypted
معلومة: كلمة السر يتم حفظها بشكل غير مشفّر
-
+
Filter path (.dat, .p2p, .p2b):
مسار الفلتر (.dat, .p2p, .p2b):
-
+
Reload the filter
تحديث الفلاتر
-
+
Manually banned IP addresses...
عناوين الآي بي المحجوبة يدويًا ...
-
+
Apply to trackers
التطبيق على المتتبعات
-
+
Global Rate Limits
حدود المعدل العام
-
-
-
-
-
-
-
+
+
+
+
+
+
+
∞
∞
-
-
-
-
-
-
+
+
+
+
+
+
KiB/s
ك.بايت/ث
-
-
+
+
Upload:
الرفع:
-
-
+
+
Download:
التنزيل:
-
+
Alternative Rate Limits
حدود المعدل البديل
-
+
Start time
وقت البدء
-
+
End time
وقت النهاية
-
+
When:
عندما:
-
+
Every day
كل يوم
-
+
Weekdays
نهاية اليوم
-
+
Weekends
نهاية الأسبوع
-
+
Rate Limits Settings
إعدادات حدود المعدل
-
+
Apply rate limit to peers on LAN
تطبيق حد المعدل على القرناء الموجودين على الشبكة المحلية
-
+
Apply rate limit to transport overhead
تطبيق حد المعدل على النقل الزائد
-
+
Apply rate limit to µTP protocol
تطبيق حد المعدل على بروتوكول µTP
-
+
Privacy
الخصوصية
-
+
Enable DHT (decentralized network) to find more peers
تفعيل DHT (الشبكة اللامركزية) للعثور على المزيد من القرناء
-
+
Exchange peers with compatible Bittorrent clients (µTorrent, Vuze, ...)
استبدال القرناء بعملاء بت تورنت متوافقين (µTorrent، Vuze، ...)
-
+
Enable Peer Exchange (PeX) to find more peers
تفعيل تبادل القرناء (PeX) للعثور على المزيد من الأقران
-
+
Look for peers on your local network
إيجاد القرناء على شبكتك المحلية
-
+
Enable Local Peer Discovery to find more peers
تفعيل اكتشاف القرناء المحليين للعثور على المزيد من الأقران
-
+
Encryption mode:
نمط التشفير:
-
+
Require encryption
طلب التشفير
-
+
Disable encryption
تعطيل التشفير
-
+
Enable when using a proxy or a VPN connection
تفعيل عند استخدام اتصال بروكسي أو VPN
-
+
Enable anonymous mode
تفعيل الوضع المجهول
-
+
Maximum active downloads:
أقصى عدد للتنزيلات النشطة:
-
+
Maximum active uploads:
أقصى عدد للمرفوعات النشطة:
-
+
Maximum active torrents:
أقصى عدد للتورنتات النشطة:
-
+
Do not count slow torrents in these limits
عدم حساب التورنتات البطيئة في هذه الحدود
-
+
Upload rate threshold:
حد معدل الرفع:
-
+
Download rate threshold:
حد معدل التنزيل:
-
-
-
-
+
+
+
+
sec
seconds
ث
-
+
Torrent inactivity timer:
مؤقت عدم نشاط التورنت:
-
+
then
ثم
-
+
+ Stop torrent
+
+
+
+
+ A&utomatically append these trackers to new downloads:
+
+
+
+
Use UPnP / NAT-PMP to forward the port from my router
استخدام UPnP / NAT-PMP لفتح المنافذ تلقائيًا
-
+
Certificate:
الشهادة:
-
+
Key:
المفتاح:
-
+
<a href=https://httpd.apache.org/docs/current/ssl/ssl_faq.html#aboutcerts>Information about certificates</a>
<a href=https://httpd.apache.org/docs/current/ssl/ssl_faq.html#aboutcerts>معلومات عن الشهادات</a>
-
+
Change current password
تغيير كلمة المرور الحالية
-
+
Use alternative Web UI
استخدم واجهة وِب رسومية بديلة
-
+
Files location:
مكان الملفات:
-
+
Security
الأمان
-
+
Enable clickjacking protection
تفعيل الحماية من الاختراق
-
+
Enable Cross-Site Request Forgery (CSRF) protection
تفعيل الحماية عبر الموقع لطلب التزوير (CSRF)
-
+
Enable Host header validation
تفعيل التحقق من صحة رأس المضيف
-
+
Add custom HTTP headers
أضف رؤوس HTTP مخصصة
-
+
Header: value pairs, one per line
الرأس: أهمية مزدوجة، واحد لكل سطر
-
+
Enable reverse proxy support
تفعيل دعم البروكسي العكسي
-
+
Trusted proxies list:
قائمة البروكسي الموثوق بهم:
-
+
Service:
الخدمة:
-
+
Register
تسجيل
-
+
Domain name:
اسم النطاق:
-
+
By enabling these options, you can <strong>irrevocably lose</strong> your .torrent files!
من خلال تمكين هذه الخيارات ، يمكنك أن <strong>تفقد</strong> ملفات .torrent الخاصة بك بشكل نهائي!
-
+
If you enable the second option (“Also when addition is cancelled”) the .torrent file <strong>will be deleted</strong> even if you press “<strong>Cancel</strong>” in the “Add torrent” dialog
إذا قمت بتفعيل الخيار الثاني ("أيضًا عند إلغاء الإضافة") ، ملف torrent. <strong>سيتم حذفه</strong> حتى لو ضغطت على " <strong>إلغاء</strong> "في مربع حوار "إضافة تورنت"
-
+
Select qBittorrent UI Theme file
حدد ملف سمة واجهة مستخدم رسومية كيوبتتورنت
-
+
Choose Alternative UI files location
اختر موقع ملفات واجهة المستخدم البديلة
-
+
Supported parameters (case sensitive):
المعلمات المدعومة (حساس لحالة الأحرف):
-
+
Minimized
مصغر
-
+
Hidden
مخفي
-
+
Disabled due to failed to detect system tray presence
مُعطل بسبب الفشل في اكتشاف وجود علبة النظام (system tray)
-
+
No stop condition is set.
لم يتم وضع شرط للتوقف
-
+
Torrent will stop after metadata is received.
سيتوقف التورنت بعد استقبال البيانات الوصفية
- Torrents that have metadata initially aren't affected.
- التورنت الذي يحتوي على بيانات وصفية ابتدائية لن يتأثر
-
-
-
+
Torrent will stop after files are initially checked.
سيتوقف التورنت بعد الملفات التي تم فحصحها
-
+
This will also download metadata if it wasn't there initially.
سيؤدي هذا أيضًا إلى تنزيل البيانات الوصفية إذا لم تكن موجودة في البداية.
-
+
%N: Torrent name
%N: اسم التورنت
-
+
%L: Category
%L: الفئة
-
+
%F: Content path (same as root path for multifile torrent)
%F: مسار المحتوى (نفس مسار الجذر لملفات التورنت المتعددة)
-
+
%R: Root path (first torrent subdirectory path)
%R: مسار الجذر (مسار الدليل الفرعي الأول للتورنت)
-
+
%D: Save path
%D: مسار الحفظ
-
+
%C: Number of files
%C: عدد الملفات
-
+
%Z: Torrent size (bytes)
%Z: حجم التونت (بالبايتات)
-
+
%T: Current tracker
%T: المتتبع الحالي
-
+
Tip: Encapsulate parameter with quotation marks to avoid text being cut off at whitespace (e.g., "%N")
نصيحة: غلف المعلمات بعلامات اقتباس لتجنب قطع النص عند مسافة بيضاء (على سبيل المثال، "%N")
-
+
+ Test email
+ بريد إلكتروني اختباري
+
+
+
+ Attempted to send email. Check your inbox to confirm success
+
+
+
+
(None)
(لا شيء)
-
+
A torrent will be considered slow if its download and upload rates stay below these values for "Torrent inactivity timer" seconds
سيتم اعتبار التورنت بطيئًا إذا ظلت معدلات التنزيل والتحميل أقل من هذه القيم لثواني "مؤقت عدم نشاط التورنت"
-
+
Certificate
الشهادة
-
+
Select certificate
حدد الشهادة
-
+
Private key
المفتاح الخاص
-
+
Select private key
حدد المفتاح الخاص
-
+
WebUI configuration failed. Reason: %1
-
+
+ %1 is recommended for best compatibility with Windows dark mode
+ Fusion is recommended for best compatibility with Windows dark mode
+
+
+
+
+ System
+ System default Qt style
+
+
+
+
+ Let Qt decide the style for this system
+
+
+
+
Select folder to monitor
حدد المجلد المراد مراقبته
-
+
Adding entry failed
فشل إضافة الإدخال
-
+
The WebUI username must be at least 3 characters long.
-
+
The WebUI password must be at least 6 characters long.
-
+
Location Error
خطأ في المكان
-
-
+
+
Choose export directory
اختر مكان التصدير
-
+
When these options are enabled, qBittorrent will <strong>delete</strong> .torrent files after they were successfully (the first option) or not (the second option) added to its download queue. This will be applied <strong>not only</strong> to the files opened via “Add torrent” menu action but to those opened via <strong>file type association</strong> as well
عندما يتم تفعيل هذه الخيارات، سيقوم كيوبتتورنت <strong>بحذف</strong> ملفات torrent. بعد إضافتها بنجاح (الخيار الأول) أو عدم إضافتها (الخيار الثاني) إلى قائمة انتظار التنزيل الخاصة به. سيتم تطبيق هذا<strong>ليس فقط</strong> إلى الملفات التي تم فتحها عبر إجراء قائمة "إضافة تورنت" ولكن لتلك التي تم فتحها عبر <strong>اقتران نوع الملف</strong> كذلك
-
+
qBittorrent UI Theme file (*.qbtheme config.json)
ملف سمة واجهة رسومية كيوبتتورنت (*.qbtheme config.json)
-
+
%G: Tags (separated by comma)
%G: وسوم (مفصولة بفاصلة)
-
+
%I: Info hash v1 (or '-' if unavailable)
%I: معلومات التحقق من البيانات (الهاش) الإصدار 1 (أو '-' إذا لم تكن متوفرة)
-
+
%J: Info hash v2 (or '-' if unavailable)
%J: معلومات التحقق من البيانات (الهاش) الإصدار 2 (أو '-' إذا لم تكن متوفرة)
-
+
%K: Torrent ID (either sha-1 info hash for v1 torrent or truncated sha-256 info hash for v2/hybrid torrent)
%K: معرف التورنت (إما تجزئة معلومات sha-1 للإصدار 1 للتورنت أو تجزئة معلومات sha-256 المقطوعة للإصدار 2 / التورنت المختلط)
-
-
-
+
+
+
Choose a save directory
اختر مكان الحفظ
-
+
Torrents that have metadata initially will be added as stopped.
-
+ ستتم إضافة التورينت التي تحتوي على بيانات وصفية في البداية على أنها متوقفة.
-
+
Choose an IP filter file
اختر ملف تصفية آي بي
-
+
All supported filters
جميع التصفيات المدعومة
-
+
The alternative WebUI files location cannot be blank.
-
+
Parsing error
خطأ تحليل
-
+
Failed to parse the provided IP filter
فشل تحليل عامل تصفية آي بي المقدم
-
+
Successfully refreshed
تم التحديث بنجاح
-
+
Successfully parsed the provided IP filter: %1 rules were applied.
%1 is a number
تم تحليل عامل تصفية الآي بي المقدم بنجاح: تم تطبيق %1 قواعد.
-
+
Preferences
التفضيلات
-
+
Time Error
خطأ في الوقت
-
+
The start time and the end time can't be the same.
لا يمكن أن يكون وقت البدء مطابق لوقت الانتهاء.
-
-
+
+
Length Error
خطأ في الطول
@@ -7336,80 +7506,85 @@ readme.txt: تصفية اسم الملف الدقيق.
PeerInfo
-
+
Unknown
غير معروف
-
+
Interested (local) and choked (peer)
مهتم (محلي) ومختنق (قرين)
-
+
Interested (local) and unchoked (peer)
مهتم (محلي) وغير مختنق (قرين)
-
+
Interested (peer) and choked (local)
مهتم (قرين) وغير مختنق (محلي)
-
+
Interested (peer) and unchoked (local)
مهتم (قرين) وغير مختنق (محلي)
-
+
Not interested (local) and unchoked (peer)
غير مهتم (محلي) وغير مختنق (قرين)
-
+
Not interested (peer) and unchoked (local)
غير مهتم (قرين) وغير مختنق (محلي)
-
+
Optimistic unchoke
متفائل غير مختنق
-
+
Peer snubbed
تجاهل القرين
-
+
Incoming connection
الاتصالات الواردة
-
+
Peer from DHT
قرين من DHT
-
+
Peer from PEX
قرين من PEX
-
+
Peer from LSD
قرين من LSD
-
+
Encrypted traffic
حركة مرور مشفرة
-
+
Encrypted handshake
مصافحة مشفرة
+
+
+ Peer is using NAT hole punching
+
+
PeerListWidget
@@ -7565,7 +7740,7 @@ readme.txt: تصفية اسم الملف الدقيق.
تم حظر القرين "%1" يدويًا
-
+
N/A
لا يوجد
@@ -7629,27 +7804,27 @@ readme.txt: تصفية اسم الملف الدقيق.
PiecesBar
-
+
Files in this piece:
الملفات في هذا الجزء:
-
+
File in this piece:
الملف في هذه القطعة:
-
+
File in these pieces:
الملف في هذه القطع:
-
+
Wait until metadata become available to see detailed information
انتظر حتى تصبح البيانات الوصفية متاحة لرؤية المعلومات التفصيلية
-
+
Hold Shift key for detailed information
اضغط مع الاستمرار على مفتاح Shift للحصول على معلومات مفصلة
@@ -7937,27 +8112,27 @@ Those plugins were disabled.
Private::FileLineEdit
-
+
Path does not exist
المسار غير موجود
-
+
Path does not point to a directory
المسار لا يشير إلى الدليل
-
+
Path does not point to a file
المسار لا يشير إلى ملف
-
+
Don't have read permission to path
ليس لديك إذن القراءة للمسار
-
+
Don't have write permission to path
ليس لديك إذن الكتابة إلى المسار
@@ -7998,7 +8173,7 @@ Those plugins were disabled.
PropertiesWidget
-
+
Downloaded:
تم تنزيل:
@@ -8018,28 +8193,28 @@ Those plugins were disabled.
النقل
-
+
Time Active:
- Time (duration) the torrent is active (not paused)
+ Time (duration) the torrent is active (not stopped)
فترة النشاط
-
+
ETA:
الوقت المتبقي:
-
+
Uploaded:
تم رفع:
-
+
Seeds:
البذور:
-
+
Download Speed:
سرعة التنزيل:
@@ -8059,12 +8234,12 @@ Those plugins were disabled.
حد التنزيل:
-
+
Upload Limit:
حد الرفع:
-
+
Wasted:
تم تضييع:
@@ -8074,32 +8249,32 @@ Those plugins were disabled.
الاتصالات:
-
+
Information
المعلومات
-
+
Info Hash v1:
معلومات التحقق من البيانات (الهاش) الإصدار 1:
-
+
Info Hash v2:
معلومات التحقق من البيانات (الهاش) الإصدار 2:
-
+
Comment:
التعليق:
-
+
Select All
اختيار الكل
-
+
Select None
اختيار لا شئ
@@ -8109,158 +8284,185 @@ Those plugins were disabled.
نسبة المشاركة:
-
+
Reannounce In:
إعادة الإعلان خلال:
-
+
Last Seen Complete:
آخر إكمال شوهِد في:
-
+
+
+ Ratio / Time Active (in months), indicates how popular the torrent is
+
+
+
+
+ Popularity:
+
+
+
+
Total Size:
إجمالي الحجم:
-
+
Pieces:
القطع:
-
+
Created By:
أنشئ باستخدام:
-
+
Added On:
تاريخ الإضافة:
-
+
Completed On:
تاريخ الاكتمال:
-
+
Created On:
تاريخ الإنشاء:
-
+
+ Private:
+
+
+
+
Save Path:
مسار الحفظ:
-
+
Never
أبدًا
-
+
%1 x %2 (have %3)
(torrent pieces) eg 152 x 4MB (have 25)
%1 x %2 (لديك %3)
-
-
+
+
%1 (%2 this session)
%1 (%2 هذه الجلسة)
-
-
+
+
+
N/A
غير متاح
-
+
+ Yes
+ نعم
+
+
+
+ No
+ لا
+
+
+
%1 (seeded for %2)
e.g. 4m39s (seeded for 3m10s)
%1 (بذرت لـ %2)
-
+
%1 (%2 max)
%1 and %2 are numbers, e.g. 3 (10 max)
%1 (%2 كحد أقصى)
-
-
+
+
%1 (%2 total)
%1 and %2 are numbers, e.g. 3 (10 total)
%1 (من إجمالي %2)
-
-
+
+
%1 (%2 avg.)
%1 and %2 are speed rates, e.g. 200KiB/s (100KiB/s avg.)
%1 (بمعدّل %2)
-
+
New Web seed
رابط للقرين عبر الويب
-
+
Remove Web seed
ازالة رابط القرين عبر الويب
-
+
Copy Web seed URL
نسخ رابط القرين عبر الويب
-
+
Edit Web seed URL
تعديل رابط القرين عبر الويب
-
+
Filter files...
تصفية الملفات...
-
+
Speed graphs are disabled
تم تعطيل الرسوم البيانية للسرعة
-
+
You can enable it in Advanced Options
يمكنك تفعيله في الخيارات المتقدمة
-
+
New URL seed
New HTTP source
URL بذر جديد
-
+
New URL seed:
URL بذر جديد:
-
-
+
+
This URL seed is already in the list.
URL البذر هذا موجود بالفعل في القائمة.
-
+
Web seed editing
تعديل القرين عبر الويب
-
+
Web seed URL:
رابط القرين عبر الويب:
@@ -8353,12 +8555,12 @@ Those plugins were disabled.
RSS::Private::Parser
-
+
Invalid RSS feed.
موجز RSS غير صالح.
-
+
%1 (line: %2, column: %3, offset: %4).
%1 (السطر: %2, عمود: %3, الإزاحة: %4).
@@ -8571,69 +8773,69 @@ Those plugins were disabled.
تحرير رابط الموجز
-
+
Please choose a folder name
يرجى اختيار اسم المجلد
-
+
Folder name:
اسم المجلد:
-
+
New folder
مجلد جديد
-
-
+
+
Please type a RSS feed URL
يرجى كتابة رابط موجز RSS
-
-
+
+
Feed URL:
رابط الموجز:
-
+
Deletion confirmation
تأكيد الحذف
-
+
Are you sure you want to delete the selected RSS feeds?
هل أنت متأكد من رغبتك في حذف موجز RSS المحددة؟
-
+
Please choose a new name for this RSS feed
يرجى اختيار اسمًا جديدًا لهذا موجز RSS
-
+
New feed name:
اسم الموجز الجديد:
-
+
Rename failed
فشل إعادة التسمية
-
+
Date:
التاريخ:
-
+
Feed:
-
+
Author:
المؤلف:
@@ -8641,38 +8843,38 @@ Those plugins were disabled.
SearchController
-
+
Python must be installed to use the Search Engine.
يجب تثبيت بيثون (Python) لاستخدام محرك البحث.
-
+
Unable to create more than %1 concurrent searches.
تعذر إنشاء أكثر من %1 عملية بحث متزامنة.
-
-
+
+
Offset is out of range
الإزاحة خارج النطاق
-
+
All plugins are already up to date.
جميع الملحقات محدّثة.
-
+
Updating %1 plugins
تحديث %1 ملحقات
-
+
Updating plugin %1
تحديث ملحق %1
-
+
Failed to check for plugin updates: %1
فشل البحث عن تحديثات الملحقات: %1
@@ -8747,132 +8949,142 @@ Those plugins were disabled.
الحجم:
-
+
Name
i.e: file name
الاسم
-
+
Size
i.e: file size
الحجم
-
+
Seeders
i.e: Number of full sources
الباذرون
-
+
Leechers
i.e: Number of partial sources
المحمِّلون
-
- Search engine
- محرّك البحث
+
+ Engine
+
-
+
+ Engine URL
+
+
+
+
+ Published On
+
+
+
+
Filter search results...
تصفية نتائج البحث...
-
+
Results (showing <i>%1</i> out of <i>%2</i>):
i.e: Search results
النتائج (يظهر %1 من إجمالي %2):
-
+
Torrent names only
أسماء التورنتات فقط
-
+
Everywhere
في كل مكان
-
+
Use regular expressions
استخدام التعبيرات العادية
-
+
Open download window
افتح نافذة التنزيل
-
+
Download
تنزيل
-
+
Open description page
افتح صفحة الوصف
-
+
Copy
نسخ
-
+
Name
الاسم
-
+
Download link
رابط التنزيل
-
+
Description page URL
URL صفحة الوصف
-
+
Searching...
يبحث...
-
+
Search has finished
انتهى البحث
-
+
Search aborted
تم إلغاء البحث
-
+
An error occurred during search...
حدث خطأ أثناء البحث...
-
+
Search returned no results
البحث لم يسفر عن أي نتائج
-
+
Column visibility
وضوح العامود
-
+
Resize columns
تغيير حجم الأعمدة
-
+
Resize all non-hidden columns to the size of their contents
قم بتغيير حجم جميع الأعمدة غير المخفية إلى حجم محتوياتها
@@ -8880,104 +9092,104 @@ Those plugins were disabled.
SearchPluginManager
-
+
Unknown search engine plugin file format.
تنسيق ملحق محرك البحث غير معروف.
-
+
Plugin already at version %1, which is greater than %2
الملحق موجود بالفعل في الإصدار %1، وهو أكبر من %2
-
+
A more recent version of this plugin is already installed.
تم بالفعل تثبيت إصدار أحدث من هذا الملحق.
-
+
Plugin %1 is not supported.
الملحقة %1 غير مدعومة.
-
-
+
+
Plugin is not supported.
المُلحقة غير مدعومة.
-
+
Plugin %1 has been successfully updated.
تم تحديث المُلحقة %1 بنجاح.
-
+
All categories
كل الفئات
-
+
Movies
أفلام
-
+
TV shows
برامج تلفزيونية
-
+
Music
موسيقى
-
+
Games
ألعاب
-
+
Anime
رسوم متحركة
-
+
Software
برمجيات
-
+
Pictures
صور
-
+
Books
كتب
-
+
Update server is temporarily unavailable. %1
خادوم التحديث غير متاح مؤقتا. %1
-
-
+
+
Failed to download the plugin file. %1
فشل في تنزيل ملف المُلحقة. %1
-
+
Plugin "%1" is outdated, updating to version %2
الملحق "%1" قديم ، ويتم التحديث إلى الإصدار %2
-
+
Incorrect update info received for %1 out of %2 plugins.
تلقي معلومات تحديث غير صحيحة لـ %1 من %2 ملحق.
-
+
Search plugin '%1' contains invalid version string ('%2')
يحتوي ملحق البحث '%1' على سلسلة إصدار غير صالح ('%2')
@@ -8987,10 +9199,10 @@ Those plugins were disabled.
-
-
-
-
+
+
+
+
Search
البحث
@@ -9002,7 +9214,7 @@ Click the "Search plugins..." button at the bottom right of the window
انقر فوق زر "مُلحقات البحث..." في الجزء السفلي الأيسر من النافذة لتثبيت البعض.
-
+
Search plugins...
مُلحقات البحث...
@@ -9029,12 +9241,12 @@ Click the "Search plugins..." button at the bottom right of the window
<b>"السلام عليكم"</b>: يبحث عن<b>السلام عليكم</b>
-
+
All plugins
جميع الملحقات
-
+
Only enabled
المُفعلة فقط
@@ -9045,54 +9257,54 @@ Click the "Search plugins..." button at the bottom right of the window
<b>السلام عليكم</b>: يبحث عن<b>السلام</b>و<b>عليكم</b>
-
+
Close tab
إغلاق علامة التبويب
-
+
Close all tabs
أغلق كل علامات التبويب
-
+
Select...
اختر...
-
-
-
+
+
+
Search Engine
مُحرك البحث
-
+
Please install Python to use the Search Engine.
برجاء تثبيت Python لاستخدام محرك البحث.
-
+
Empty search pattern
نمط البحث فارغ
-
+
Please type a search pattern first
الرجاء كتابة نمط البحث اولا
-
+
Stop
أوقف
-
+
Search has finished
اكتمل البحث
-
+
Search has failed
فشلت عملية البحث
@@ -9564,13 +9776,13 @@ Click the "Search plugins..." button at the bottom right of the window
- Resumed (0)
- المُستأنف (0)
+ Running (0)
+
- Paused (0)
- المُلبث (0)
+ Stopped (0)
+
@@ -9632,36 +9844,36 @@ Click the "Search plugins..." button at the bottom right of the window
Completed (%1)
المُكتمل (%1)
+
+
+ Running (%1)
+
+
- Paused (%1)
- المُلبث (%1)
+ Stopped (%1)
+
+
+
+
+ Start torrents
+
+
+
+
+ Stop torrents
+
Moving (%1)
نقل (%1)
-
-
- Resume torrents
- استئناف التورنتات
-
-
-
- Pause torrents
- إلباث التورنتات
-
Remove torrents
إزالة التورنت
-
-
- Resumed (%1)
- المُستأنف (%1)
-
Active (%1)
@@ -9735,13 +9947,13 @@ Click the "Search plugins..." button at the bottom right of the window
- Resume torrents
- استئناف التورنتات
+ Start torrents
+
- Pause torrents
- إلباث التورنتات
+ Stop torrents
+
@@ -9904,32 +10116,32 @@ Please choose a different name and try again.
TorrentContentModel
-
+
Name
الاسم
-
+
Progress
التقدّم
-
+
Download Priority
أولوية التنزيل
-
+
Remaining
إعادة التسمية
-
+
Availability
التوافر
-
+
Total Size
الحجم الكلي
@@ -9974,98 +10186,98 @@ Please choose a different name and try again.
TorrentContentWidget
-
+
Rename error
خطأ في إعادة التسمية
-
+
Renaming
إعادة التسمية
-
+
New name:
الاسم الجديد:
-
+
Column visibility
وضوح الصفوف
-
+
Resize columns
تغيير حجم الأعمدة
-
+
Resize all non-hidden columns to the size of their contents
قم بتغيير حجم جميع الأعمدة غير المخفية إلى حجم محتوياتها
-
+
Open
فتح
-
+
Open containing folder
افتح محتوى الملف
-
+
Rename...
إعادة التسمية...
-
+
Priority
الأولوية
-
-
+
+
Do not download
لا تنزّل
-
+
Normal
عادي
-
+
High
مرتفع
-
+
Maximum
الحد الأقصى
-
+
By shown file order
حسب ترتيب الملف الموضح
-
+
Normal priority
الأولوية العادية
-
+
High priority
ذا أهيمة عليا
-
+
Maximum priority
الأولوية القصوى
-
+
Priority by shown file order
الأولوية حسب ترتيب الملف المعروض
@@ -10112,13 +10324,13 @@ Please choose a different name and try again.
-
+
Select file
اختر ملفا
-
+
Select folder
اختر مجلدا
@@ -10223,57 +10435,53 @@ Please choose a different name and try again.
التقدم:
-
+
Create Torrent
إنشاء التورنت
-
-
+
+
Torrent creation failed
فشل إنشاء التورنت
-
+
Reason: Path to file/folder is not readable.
السبب: مسار الملف أو المجلد غير قابل للقراءة.
-
+
Select where to save the new torrent
حدد مكان حفظ التورنت الجديد
-
+
Torrent Files (*.torrent)
ملفات التورنت (torrent.*)
- Reason: %1
- السبب: %1
-
-
-
+
Add torrent to transfer list failed.
-
+
Reason: "%1"
-
+
Add torrent failed
-
+ فشل إضافة تورنت
-
+
Torrent creator
مُنشئ التورنت
-
+
Torrent created:
التورنت المُنشئ:
@@ -10422,131 +10630,119 @@ Please choose a different name and try again.
حدود مشاركة التورنت
-
- Use global share limit
- استخدام حد المشاركة العامة
-
-
-
- Set no share limit
- تعيين بدون حد مشاركة
-
-
-
- Set share limit to
- تعيين حد المشاركة إلى
-
-
-
- ratio
- النسبة
-
-
-
- total minutes
- إجمالي الدقائق
-
-
-
- inactive minutes
- دقائق غير نشطة
-
-
-
+
Disable DHT for this torrent
تعطيل DHT لهذا التورنت
-
+
Download in sequential order
تنزيل بترتيب تسلسلي
-
+
Disable PeX for this torrent
تعطيل PeX لهذا التورنت
-
+
Download first and last pieces first
تنزيل أول وآخر قطعة أولًا
-
+
Disable LSD for this torrent
تعطيل LSD لهذا التورنت
-
+
Currently used categories
الفئات المستخدمة حاليا
-
-
+
+
Choose save path
اختر مسار الحفظ
-
+
Not applicable to private torrents
لا ينطبق على التورنتات الخاصة
-
-
- No share limit method selected
- لم يتم تحديد طريقة حد المشاركة
-
-
-
- Please select a limit method first
- الرجاء تحديد طريقة الحد أولا
-
TorrentShareLimitsWidget
-
-
-
+
+
+
+
Default
-
+ إهمال
-
-
-
+
+
+
Unlimited
-
-
-
+
+
+
Set to
-
+
Seeding time:
-
-
-
-
- min
- minutes
+
+ Action when the limit is reached:
-
+
+ Stop torrent
+
+
+
+
+ Remove torrent
+ إزالة التورنت
+
+
+
+ Remove torrent and its content
+
+
+
+
+ Enable super seeding for torrent
+ تفعيل البذر الخارق للتورنت
+
+
+
+
+
+
+
+
+ min
+ minutes
+ د
+
+
+
Inactive seeding time:
-
+
Ratio:
@@ -10559,32 +10755,32 @@ Please choose a different name and try again.
وسوم تورنت
-
+
New Tag
وسم جديد
-
+
Tag:
الوسم:
-
+
Invalid tag name
اسم وسم غير سليم
-
+
Tag name '%1' is invalid.
وسم '%1' غير صالح.
-
+
Tag exists
الوسم موجود
-
+
Tag name already exists.
اسم الوسم موجود بالفعل.
@@ -10592,115 +10788,115 @@ Please choose a different name and try again.
TorrentsController
-
+
Error: '%1' is not a valid torrent file.
خطأ: ملف التورنت '%1' غير صالح.
-
+
Priority must be an integer
يجب أن تكون الأولوية عددًا صحيحًا
-
+
Priority is not valid
الأولوية غير صالحة
-
+
Torrent's metadata has not yet downloaded
البيانات الوصفية للتورنت لم تنزل بعد
-
+
File IDs must be integers
يجب أن تكون معرفات الملفات أعدادًا صحيحة
-
+
File ID is not valid
معرف الملف غير صالح
-
-
-
-
+
+
+
+
Torrent queueing must be enabled
يجب تفعيل قائمة اصطفاف التورنت
-
-
+
+
Save path cannot be empty
مسار الحفظ لا يمكن أن يكون فارغا
-
-
+
+
Cannot create target directory
لا يمكن إنشاء الدليل الهدف
-
-
+
+
Category cannot be empty
لا يمكن أن يكون الفئة فارغة
-
+
Unable to create category
تعذّر إنشاء الفئة
-
+
Unable to edit category
تعذّر تعديل الفئة
-
+
Unable to export torrent file. Error: %1
غير قادر على تصدير ملف تورنت. الخطأ: %1
-
+
Cannot make save path
تعذّر إنشاء مسار الحفظ
-
+
'sort' parameter is invalid
معلمة "sort" غير صالح
-
+
"%1" is not a valid file index.
"%1" ليس فهرس ملف صالح.
-
+
Index %1 is out of bounds.
الفهرس %1 خارج الحدود.
-
-
+
+
Cannot write to directory
تعذّر الكتابة إلى المجلد
-
+
WebUI Set location: moving "%1", from "%2" to "%3"
تعيين وجهة واجهة الوِب الرسومية: ينقل "%1" من "%2" إلى "%3"
-
+
Incorrect torrent name
اسم تورنت غير صحيح
-
-
+
+
Incorrect category name
اسم الفئة غير صحيحة
@@ -10730,196 +10926,191 @@ Please choose a different name and try again.
TrackerListModel
-
+
Working
يعمل
-
+
Disabled
مُعطّل
-
+
Disabled for this torrent
معطل لهذا التورنت
-
+
This torrent is private
هذا التورنت خاص
-
+
N/A
لا يوجد
-
+
Updating...
يُحدّث...
-
+
Not working
لا يعمل
-
+
Tracker error
-
+
Unreachable
-
+
Not contacted yet
لم يتصل بعد
-
- Invalid status!
+
+ Invalid state!
-
- URL/Announce endpoint
+
+ URL/Announce Endpoint
-
+
+ BT Protocol
+
+
+
+
+ Next Announce
+
+
+
+
+ Min Announce
+
+
+
+
Tier
مستوى
-
- Protocol
-
-
-
-
+
Status
الحالة
-
+
Peers
القرناء
-
+
Seeds
البذور
-
+
Leeches
المُحمّلِين
-
+
Times Downloaded
مرات التنزيل
-
+
Message
الرسالة
-
-
- Next announce
-
-
-
-
- Min announce
-
-
-
-
- v%1
-
-
TrackerListWidget
-
+
This torrent is private
هذا التورنت خاص
-
+
Tracker editing
تعديل المتتبع
-
+
Tracker URL:
رابط المتتبع:
-
-
+
+
Tracker editing failed
فشل تعديل المتتبع
-
+
The tracker URL entered is invalid.
رابط المتتبع الذي أدخلته غير صالح.
-
+
The tracker URL already exists.
رابط المتتبع موجود بالفعل.
-
+
Edit tracker URL...
تعديل رابط المتتبع...
-
+
Remove tracker
إزالة المتتبع
-
+
Copy tracker URL
نسخ رابط المتتبع
-
+
Force reannounce to selected trackers
إجبار إعادة الإعلان للمتتبعات المحددة
-
+
Force reannounce to all trackers
إجبار إعادة الإعلان لجميع المتتبعات
-
+
Resize columns
تغيير حجم الأعمدة
-
+
Resize all non-hidden columns to the size of their contents
قم بتغيير حجم جميع الأعمدة غير المخفية إلى حجم محتوياتها
-
+
Add trackers...
إضافة متتبعات...
-
+
Column visibility
وضوح العامود
@@ -10947,27 +11138,27 @@ Please choose a different name and try again.
تحميل قائمة المتتبعات
-
+
Add
إضافة
-
+
Trackers list URL error
خطأ في عنوان URL لقائمة المتتبعات
-
+
The trackers list URL cannot be empty
لا يمكن أن يكون عنوان URL لقائمة المتتبعات فارغًا
-
+
Download trackers list error
تنزيل خطأ قائمة المتتبعات
-
+
Error occurred when downloading the trackers list. Reason: "%1"
حدث خطأ أثناء تنزيل قائمة المتتبعات. السبب: "%1"
@@ -10975,62 +11166,62 @@ Please choose a different name and try again.
TrackersFilterWidget
-
+
Warning (%1)
تحذير (%1)
-
+
Trackerless (%1)
بدون متتبعات (%1)
-
+
Tracker error (%1)
-
+
Other error (%1)
-
+
Remove tracker
إزالة المتتبع
-
- Resume torrents
- استئناف التورنتات
+
+ Start torrents
+
-
- Pause torrents
- إلباث التورنتات
+
+ Stop torrents
+
-
+
Remove torrents
إزالة التورنت
-
+
Removal confirmation
-
+
Are you sure you want to remove tracker "%1" from all torrents?
-
+
Don't ask me again.
-
+
All (%1)
this is for the tracker filter
الكل (%1)
@@ -11131,11 +11322,6 @@ Please choose a different name and try again.
Used when loading the torrents from disk after qbt is launched. It checks the correctness of the .fastresume file. Normally it is completed in a fraction of a second, unless loading many many torrents.
يتحقق من بيانات الاستئناف
-
-
- Paused
- مُلبث
-
Completed
@@ -11159,220 +11345,252 @@ Please choose a different name and try again.
خطأ
-
+
Name
i.e: torrent name
الاسم
-
+
Size
i.e: torrent size
الحجم
-
+
Progress
% Done
التقدّم
-
+
+ Stopped
+ متوقف
+
+
+
Status
- Torrent status (e.g. downloading, seeding, paused)
+ Torrent status (e.g. downloading, seeding, stopped)
الحالة
-
+
Seeds
i.e. full sources (often untranslated)
البذور
-
+
Peers
i.e. partial sources (often untranslated)
القرناء
-
+
Down Speed
i.e: Download speed
سرعة التنزيل
-
+
Up Speed
i.e: Upload speed
سرعة الرفع
-
+
Ratio
Share ratio
النسبة
-
+
+ Popularity
+
+
+
+
ETA
i.e: Estimated Time of Arrival / Time left
الوقت المتبقي
-
+
Category
الفئة
-
+
Tags
الوسوم
-
+
Added On
Torrent was added to transfer list on 01/01/2010 08:00
أُضيف في
-
+
Completed On
Torrent was completed on 01/01/2010 08:00
أكتمل في
-
+
Tracker
المتتبع
-
+
Down Limit
i.e: Download limit
حدّ التنزيل
-
+
Up Limit
i.e: Upload limit
حدّ الرفع
-
+
Downloaded
Amount of data downloaded (e.g. in MB)
تم تنزيله
-
+
Uploaded
Amount of data uploaded (e.g. in MB)
رُفعت
-
+
Session Download
Amount of data downloaded since program open (e.g. in MB)
تنزيل الجلسة
-
+
Session Upload
Amount of data uploaded since program open (e.g. in MB)
رفع الجلسة
-
+
Remaining
Amount of data left to download (e.g. in MB)
المتبقي
-
+
Time Active
- Time (duration) the torrent is active (not paused)
+ Time (duration) the torrent is active (not stopped)
فترة النشاط
-
+
+ Yes
+ نعم
+
+
+
+ No
+ لا
+
+
+
Save Path
Torrent save path
حفظ المسار
-
+
Incomplete Save Path
Torrent incomplete save path
مسار الحفظ غير مكتمل
-
+
Completed
Amount of data completed (e.g. in MB)
تم تنزيل
-
+
Ratio Limit
Upload share ratio limit
حد نسبة المشاركة
-
+
Last Seen Complete
Indicates the time when the torrent was last seen complete/whole
آخر إكمال شوهِد في
-
+
Last Activity
Time passed since a chunk was downloaded/uploaded
آخر نشاط
-
+
Total Size
i.e. Size including unwanted data
الحجم الكلي
-
+
Availability
The number of distributed copies of the torrent
التوافر
-
+
Info Hash v1
i.e: torrent info hash v1
تجزئة المعلومات v1
-
+
Info Hash v2
i.e: torrent info hash v2
تجزئة المعلومات v2
-
+
Reannounce In
Indicates the time until next trackers reannounce
-
-
+
+ Private
+ Flags private torrents
+
+
+
+
+ Ratio / Time Active (in months), indicates how popular the torrent is
+
+
+
+
+
+
N/A
لا يوجد
-
+
%1 ago
e.g.: 1h 20m ago
قبل %1
-
+
%1 (seeded for %2)
e.g. 4m39s (seeded for 3m10s)
%1 (بذرت لـ %2)
@@ -11381,339 +11599,319 @@ Please choose a different name and try again.
TransferListWidget
-
+
Column visibility
وضوح الصفوف
-
+
Recheck confirmation
اعادة التأكد
-
+
Are you sure you want to recheck the selected torrent(s)?
هل أنت متأكد من رغبتك في اعادة التأكد من الملفات المختارة؟
-
+
Rename
تغيير التسمية
-
+
New name:
الاسم الجديد:
-
+
Choose save path
اختر مسار الحفظ
-
- Confirm pause
- تأكيد الإيقاف المؤقت
-
-
-
- Would you like to pause all torrents?
- هل ترغب في إيقاف جميع ملفات التورنت مؤقتًا؟
-
-
-
- Confirm resume
- تأكيد الاستئناف
-
-
-
- Would you like to resume all torrents?
- هل ترغب في استئناف جميع ملفات التورنت؟
-
-
-
+
Unable to preview
غير قادر على المعاينة
-
+
The selected torrent "%1" does not contain previewable files
لا يحتوي التورنت المحدد "%1" على ملفات قابلة للمعاينة
-
+
Resize columns
تغيير حجم الأعمدة
-
+
Resize all non-hidden columns to the size of their contents
قم بتغيير حجم جميع الأعمدة غير المخفية إلى حجم محتوياتها
-
+
Enable automatic torrent management
تفعيل الإدارة التلقائية للتورنت
-
+
Are you sure you want to enable Automatic Torrent Management for the selected torrent(s)? They may be relocated.
هل أنت متأكد من أنك تريد تفعيل الإدارة التلقائية للتورنت المحدد؟ قد يتم نقلهم.
-
+
Add Tags
إضافة وسوم
-
+
Choose folder to save exported .torrent files
اختر مجلدًا لحفظ ملفات torrent. المصدرة
-
+
Export .torrent file failed. Torrent: "%1". Save path: "%2". Reason: "%3"
فشل تصدير ملف .torrent. تورنت: "%1". حفظ المسار: "%2". السبب: "%3"
-
+
A file with the same name already exists
يوجد ملف بنفس الاسم بالفعل
-
+
Export .torrent file error
خطأ في تصدير ملف torrent.
-
+
Remove All Tags
إزالة جميع الوسوم
-
+
Remove all tags from selected torrents?
إزالة جميع الوسوم من التورنتات المُختارة؟
-
+
Comma-separated tags:
وسوم مفصولة بفواصل:
-
+
Invalid tag
وسم غير صالح
-
+
Tag name: '%1' is invalid
اسم الوسم: '%1' غير صالح
-
- &Resume
- Resume/start the torrent
- ا&ستئناف
-
-
-
- &Pause
- Pause the torrent
- إ&لباث
-
-
-
- Force Resu&me
- Force Resume/start the torrent
- فرض الا&ستئناف
-
-
-
+
Pre&view file...
م&عاينة الملف...
-
+
Torrent &options...
&خيارات التورنت...
-
+
Open destination &folder
فتح وج&هة المجلد
-
+
Move &up
i.e. move up in the queue
&حرّك لأعلى
-
+
Move &down
i.e. Move down in the queue
حرّك لأس&فل
-
+
Move to &top
i.e. Move to top of the queue
حرّك لأقمة
-
+
Move to &bottom
i.e. Move to bottom of the queue
انتق&ل لأسفل
-
+
Set loc&ation...
تحديد المك&ان...
-
+
Force rec&heck
فرض إعا&دة التحقق
-
+
Force r&eannounce
فر&ض الإعلان
-
+
&Magnet link
&رابط المغناطيس
-
+
Torrent &ID
مع&رف التورنت
-
+
&Comment
-
+
&Name
ا&سم
-
+
Info &hash v1
ت&جزئة المعلومات v1
-
+
Info h&ash v2
ت&جزئة المعلومات v2
-
+
Re&name...
&غيّر الاسم
-
+
Edit trac&kers...
تحر&ير التتبع...
-
+
E&xport .torrent...
&تصدير .torrent...
-
+
Categor&y
ال&فئة
-
+
&New...
New category...
جدي&د...
-
+
&Reset
Reset category
إعادة ت&عيين
-
+
Ta&gs
الوس&وم
-
+
&Add...
Add / assign multiple tags...
إ&ضافة...
-
+
&Remove All
Remove all tags
إزالة الك&ل
-
+
+ Can not force reannounce if torrent is Stopped/Queued/Errored/Checking
+
+
+
+
&Queue
&صف
-
+
&Copy
ن&سخ
-
+
Exported torrent is not necessarily the same as the imported
التورنت المُصدَّر ليس بالضرورة نفس المستورد
-
+
Download in sequential order
تنزيل بترتيب تسلسلي
-
+
Errors occurred when exporting .torrent files. Check execution log for details.
حدثت أخطاء عند تصدير ملفات .torrent. تحقق من سجل التنفيذ للحصول على التفاصيل.
-
+
+ &Start
+ Resume/start the torrent
+
+
+
+
+ Sto&p
+ Stop the torrent
+
+
+
+
+ Force Star&t
+ Force Resume/start the torrent
+
+
+
+
&Remove
Remove the torrent
&إزالة
-
+
Download first and last pieces first
تنزيل أول وآخر قطعة أولًا
-
+
Automatic Torrent Management
إدارة ذاتية للتورنت
-
+
Automatic mode means that various torrent properties (e.g. save path) will be decided by the associated category
الوضع التلقائي يعني أن العديد من خصائص التورنت (مثل مسار الحفظ) سيتم تحديده عن طريق الفئة المرتبطة بها
-
- Can not force reannounce if torrent is Paused/Queued/Errored/Checking
- لا يمكن فرض إعادة الإعلان إذا كان التورنت متوقفًا مؤقتًا/في الصف/خطأ/جارٍ التحقق
-
-
-
+
Super seeding mode
نمط البذر الخارق
@@ -11758,28 +11956,28 @@ Please choose a different name and try again.
معرف الأيقونة
-
+
UI Theme Configuration.
تضبيط سمة واجهة المستخدم
-
+
The UI Theme changes could not be fully applied. The details can be found in the Log.
لا يمكن تطبيق تغييرات سمة واجهة المستخدم بشكل كامل. يمكن العثور على التفاصيل في السجل.
-
+
Couldn't save UI Theme configuration. Reason: %1
تعذر حفظ تضبيط سمة واجهة المستخدم. السبب: %1
-
-
+
+
Couldn't remove icon file. File: %1.
لا يمكن إزالة ملف الأيقونة. الملف: %1.
-
+
Couldn't copy icon file. Source: %1. Destination: %2.
لا يمكن نسخ ملف الأيقونة. المصدر: %1. الوجهة: %2.
@@ -11787,7 +11985,12 @@ Please choose a different name and try again.
UIThemeManager
-
+
+ Set app style failed. Unknown style: "%1"
+
+
+
+
Failed to load UI theme from file: "%1"
فشل تحميل سمة الواجهة الرسومية من الملف: "%1"
@@ -11818,20 +12021,21 @@ Please choose a different name and try again.
Upgrade
-
+
Migrate preferences failed: WebUI https, file: "%1", error: "%2"
فشل ترحيل التفضيلات: واجهة الوِب الرسومية https ، الملف: "%1"، الخطأ: "%2"
-
+
Migrated preferences: WebUI https, exported data to file: "%1"
التفضيلات التي تم ترحيلها: واجهة الوِب الرسومية https ، البيانات المصدرة إلى ملف: "%1"
-
-
-
-
+
+
+
+
+
Invalid value found in configuration file, reverting it to default. Key: "%1". Invalid value: "%2".
تم العثور على قيمة غير صالحة في ملف التكوين ، وإعادتها إلى الوضع الافتراضي. المفتاح: "%1". قيمة غير صالحة: "%2".
@@ -11996,32 +12200,32 @@ Please choose a different name and try again.
فاصل ':' مفقودة في رأس HTTP المخصص لواجهة الوِب الرسومية: "%1"
-
+
Web server error. %1
خطأ في خادم الويب. %1
-
+
Web server error. Unknown error.
خطأ في خادم الويب. خطأ غير معروف.
-
+
WebUI: Origin header & Target origin mismatch! Source IP: '%1'. Origin header: '%2'. Target origin: '%3'
واجهة الوِب الرسومية: رأس الأصل وعدم تطابق أصل الهدف! آي بي المصدر: '%1'. رأس الأصل: '%2'. أصل الهدف: '%3'
-
+
WebUI: Referer header & Target origin mismatch! Source IP: '%1'. Referer header: '%2'. Target origin: '%3'
واجهة الوِب الرسومية: رأس المُحيل وعدم تطابق أصل الهدف! آي بي المصدر: '%1'. رأس المُحيل: '%2'. أصل الهدف: '%3'
-
+
WebUI: Invalid Host header, port mismatch. Request source IP: '%1'. Server port: '%2'. Received Host header: '%3'
واجهة الوِب الرسومية: رأس مضيف غير صالح، عدم تطابق المنفذ. طلب الآي بي المصدر: '%1'. منفذ الخادم: '%2'. رأس المضيف المتلقى: '%3'
-
+
WebUI: Invalid Host header. Request source IP: '%1'. Received Host header: '%2'
واجهة الوِب الرسومية: رأس مضيف غير صالح. طلب آي بي المصدر: '%1'. رأس المضيف المتلقى: '%2'
@@ -12054,6 +12258,14 @@ Please choose a different name and try again.
+
+ fs
+
+
+ Unknown error
+ خطأ غير معروف
+
+
misc
@@ -12108,7 +12320,7 @@ Please choose a different name and try again.
%1s
e.g: 10 seconds
- %1د {1s?}
+
@@ -12142,7 +12354,7 @@ Please choose a different name and try again.
غير معروف
-
+
qBittorrent will shutdown the computer now because all downloads are complete.
سيتم إطفاء تشغيل الحاسوب الآن لأن جميع التنزيلات اكتملت.
diff --git a/src/lang/qbittorrent_az@latin.ts b/src/lang/qbittorrent_az@latin.ts
index eeaf15052..55553457d 100644
--- a/src/lang/qbittorrent_az@latin.ts
+++ b/src/lang/qbittorrent_az@latin.ts
@@ -91,8 +91,8 @@
- Copyright %1 2006-2024 The qBittorrent project
- Müəllif Hüquqları: %1 2006-2024 qBittorrent layihəsi
+ Copyright %1 2006-2025 The qBittorrent project
+ Müəllif Hüquqları: %1 2006-2025 qBittorrent layihəsi
@@ -164,7 +164,7 @@
Saxlama yeri
-
+
Never show again
Bir daha göstərmə
@@ -189,12 +189,12 @@
Torrenti başlat
-
+
Torrent information
Torrent məlumatı
-
+
Skip hash check
Heş yoxlamasını ötürmək
@@ -226,73 +226,78 @@
Stop condition:
- Dayandma vəziyyəti:
+ Dayanma vəziyyəti:
-
-
+
+
None
Heç nə
-
-
+
+
Metadata received
Meta məlumatları alındı
-
-
+
+ Torrents that have metadata initially will be added as stopped.
+ Öncədən meta məlumatlara malik olan torrentlər dayandırılmış kimi əılavə ediləcək.
+
+
+
+
Files checked
Fayllar yoxlanıldı
-
+
Add to top of queue
Növbənin ən üst sırasına əlavə et
-
+
When checked, the .torrent file will not be deleted regardless of the settings at the "Download" page of the Options dialog
Əgər bu xana işarələnərsə, seçimlər pəncərəsindəki "Yükləmə" səhifəsinin ayarlarına baxmayaraq .torrent faylı silinməyəcək
-
+
Content layout:
Məzmun maketi:
-
+
Original
Orijinal
-
+
Create subfolder
Alt qovluq yarat
-
+
Don't create subfolder
Alt qovluq yaratmamaq
-
+
Info hash v1:
məlumat heş'i v1
-
+
Size:
Ölçü:
-
+
Comment:
Şərh:
-
+
Date:
Tarix:
@@ -322,152 +327,147 @@
Son istifadə olunan saxlama yolunu xatırla
-
+
Do not delete .torrent file
.torrent faylını silməmək
-
+
Download in sequential order
Ardıcıl şəkildə yüklə
-
+
Download first and last pieces first
İlk öncə birinci və sonuncu parçaları yükləmək
-
+
Info hash v2:
Məlumat heş'i v2:
-
+
Select All
Hamısını seçin
-
+
Select None
Heç birini seçməyin
-
+
Save as .torrent file...
.torrent faylı kimi saxla...
-
+
I/O Error
Giriş/Çıxış Xətası
-
+
Not Available
This comment is unavailable
Mövcud Deyil
-
+
Not Available
This date is unavailable
Mövcud Deyil
-
+
Not available
Mövcud Deyil
-
+
Magnet link
Magnet linki
-
+
Retrieving metadata...
Meta məlumatlar alınır...
-
-
+
+
Choose save path
Saxlama yolunu seçin
-
+
No stop condition is set.
Dayanma vəziyyəti təyin edilməyib.
-
+
Torrent will stop after metadata is received.
Meta məlumatları alındıqdan sonra torrent dayanacaq.
-
- Torrents that have metadata initially aren't affected.
- İlkin meta məlumatları olan torrentlər dəyişilməz qalır.
-
-
-
+
Torrent will stop after files are initially checked.
Faylların ilkin yoxlanışından sonra torrrent daynacaq.
-
+
This will also download metadata if it wasn't there initially.
Əgər başlanğıcda meta məlumatlar olmasa onlar da yüklənəcək.
-
-
+
+
N/A
Əlçatmaz
-
+
%1 (Free space on disk: %2)
%1 (Diskin boş sahəsi: %2)
-
+
Not available
This size is unavailable.
Mövcud deyil
-
+
Torrent file (*%1)
Torrent fayl (*%1)
-
+
Save as torrent file
Torrent faylı kimi saxlamaq
-
+
Couldn't export torrent metadata file '%1'. Reason: %2.
'%1' meta verilənləri faylı ixrac edilə bilmədi. Səbəb: %2.
-
+
Cannot create v2 torrent until its data is fully downloaded.
Tam verilənləri endirilməyənədək v2 torrent yaradıla bilməz.
-
+
Filter files...
Faylları süzgəclə...
-
+
Parsing metadata...
Meta məlumatlarının analizi...
-
+
Metadata retrieval complete
Meta məlumatlarının alınması başa çatdı
@@ -485,22 +485,22 @@
Torrent əlavə edilə bilmədi. Mənbə: "%1", Səbəb: "%2"
-
+
Detected an attempt to add a duplicate torrent. Source: %1. Existing torrent: %2. Result: %3
Torrentin dublikatının əlavə edilməsinə cəhd aşkarlandı. Mənbə: %1. Mövcud torrent: %2. Nəticə: %3
-
+
Merging of trackers is disabled
İzləyicilərin birləşdirilməsi söndürülüb
-
+
Trackers cannot be merged because it is a private torrent
izləyicilər birləşdirilə bilməz, çünki bu fərdi torrentdir
-
+
Trackers are merged from new source
Yeni torrentdən izləyicilər birləşdirildi
@@ -575,7 +575,7 @@
Stop condition:
- Dayandma vəziyyəti:
+ Dayanma vəziyyəti:
@@ -587,6 +587,11 @@
Skip hash check
Heş yoxlamasını ötürün
+
+
+ Torrent share limits
+ Torrent paylaşım limitləri
+
@@ -661,753 +666,834 @@
AdvancedSettings
-
-
-
-
+
+
+
+
MiB
MB
-
+
Recheck torrents on completion
Yüklənmə tamamlandıqdan sonra torrentləri yoxlamaq
-
-
+
+
ms
milliseconds
msan
-
+
Setting
Ayarlar
-
+
Value
Value set for this setting
Dəyər
-
+
(disabled)
(söndürülüb)
-
+
(auto)
(avtomatik)
-
+
min
minutes
dəq
-
+
All addresses
Bütün ünvanlar
-
+
qBittorrent Section
qBittorrent Bölməsi
-
-
+
+
Open documentation
Sənədləri açmaq
-
+
All IPv4 addresses
Bütün İPv4 ünvanları
-
+
All IPv6 addresses
Bütün İPv6 ünvanları
-
+
libtorrent Section
libtorrent bölməsi
-
+
Fastresume files
Tez bərpa olunan fayllar
-
+
SQLite database (experimental)
SQLite verilənlər bazası (təcrübi)
-
+
Resume data storage type (requires restart)
Verilənləri saxlama növünü davam etdirin (yenidən başlatmaq tələb olunur)
-
+
Normal
Normal
-
+
Below normal
Normadan aşağı
-
+
Medium
Orta
-
+
Low
Aşağı
-
+
Very low
Çox aşağı
-
+
Physical memory (RAM) usage limit
Fiziki yaddaş (RAM) istifadəsi limiti
-
+
Asynchronous I/O threads
Zamanla bir birinə uzlaşmayan Giriş/Çıxış axınları
-
+
Hashing threads
Ünvanlanan axınlar
-
+
File pool size
Dinamik yaddaş ehtiyatı faylının ölçüsü
-
+
Outstanding memory when checking torrents
Torrentləri yoxlayarkən icrası gözlənilən yaddaş
-
+
Disk cache
Disk keşi
-
-
-
-
+
+
+
+
s
seconds
san
-
+
Disk cache expiry interval
Disk keşinin sona çatma müddəti
-
+
Disk queue size
Disk növbəsi ölçüsü
-
-
+
+
Enable OS cache
ƏS keşini aktiv etmək
-
+
Coalesce reads & writes
Oxuma, yazma əməliyyatlarını birləşdirmək
-
+
Use piece extent affinity
Hissələrin yaxınlıq dərəcəsindən istifadə etmək
-
+
Send upload piece suggestions
Göndərmə parçası təkliflərini göndərmək
-
-
-
-
+
+
+
+
0 (disabled)
0 (söndürülüb)
-
+
Save resume data interval [0: disabled]
How often the fastresume file is saved.
Davametmə məlumatlarının saxlanılması aralığı (0: söndürülüb)
-
+
Outgoing ports (Min) [0: disabled]
Çıxış portları (Ən az)[0: söndürülüb]
-
+
Outgoing ports (Max) [0: disabled]
Çıxış portları (Ən çox) [0: söndürülüb]
-
+
0 (permanent lease)
0 (daimi icarə)
-
+
UPnP lease duration [0: permanent lease]
UPnP icarə müddəti [0: daimi icarə]
-
+
Stop tracker timeout [0: disabled]
İzləyici vaxtını dayandır [0: söndürülb]
-
+
Notification timeout [0: infinite, -1: system default]
Bildirişin bitmə vaxtı [0: sonsuz, -1: sistemdəki standart]
-
+
Maximum outstanding requests to a single peer
Hər iştirakçıya düşən ən çox icra olunmamış sorğu
-
-
-
-
-
+
+
+
+
+
KiB
KB
-
+
(infinite)
(sonsuz)
-
+
(system default)
(sistemdəki standart)
-
+
+ Delete files permanently
+
+
+
+
+ Move files to trash (if possible)
+
+
+
+
+ Torrent content removing mode
+
+
+
+
This option is less effective on Linux
Bu seçim Linuxda az effektlidir
-
+
Process memory priority
Proses yaddaşının üstünlüyü
-
+
Bdecode depth limit
Bdecode dərinliyi həddi
-
+
Bdecode token limit
Bdecode tokenləri həddi
-
+
Default
Standart
-
+
Memory mapped files
Yaddaş ilə əlaqəli fayllar
-
+
POSIX-compliant
POSİX ilə uyğun
-
+
+ Simple pread/pwrite
+
+
+
+
Disk IO type (requires restart)
Disk giriş/çıxış növü (yenidən başladılmalıdır)
-
-
+
+
Disable OS cache
ƏS keşini söndür
-
+
Disk IO read mode
Diskin giriş/çıxışının oxu rejimi
-
+
Write-through
Başdan sona yazma
-
+
Disk IO write mode
Diskin giriş/çıxışının yazı rejimi
-
+
Send buffer watermark
Buferin su nişanını göndərmək
-
+
Send buffer low watermark
Buferin zəif su nişanını göndərin
-
+
Send buffer watermark factor
Bufer su nişanı əmsalını göndərmək
-
+
Outgoing connections per second
Hər saniyədə sərf olunan bağlantı
-
-
+
+
0 (system default)
0 (sistemdəki standart)
-
+
Socket send buffer size [0: system default]
Soket göndərmə bufer ölçüsü [0: sistemdəki standart]
-
+
Socket receive buffer size [0: system default]
Soket qəbul etmə bufer ölçüsü [0: sistemdəki standart]
-
+
Socket backlog size
Soket yığma ölçüsü
-
+
.torrent file size limit
.torrent faylı ölçüsünün həddi
-
+
Type of service (ToS) for connections to peers
Iştirakçılarla bağlantı üçün xidmət növü (ToS)
-
+
Prefer TCP
TCP tərcihi
-
+
Peer proportional (throttles TCP)
İştirakçılarla mütənasib (TCP'ni məhdudlaşdırır)
-
+
Support internationalized domain name (IDN)
Beynəlxalq domen adı (İDN) dəstəkləmək
-
+
Allow multiple connections from the same IP address
Eyni İP ünvanından çoxsaylı bağlantılara icazə vermək
-
+
Validate HTTPS tracker certificates
HTTPS izləyici sertifikatlarını təsdiq etmək
-
+
Server-side request forgery (SSRF) mitigation
Server tərəfindən saxta sorğulardan (SSRF) qorunma
-
+
Disallow connection to peers on privileged ports
İmtiyazlı portlarda iştirakçılara qoşulmanı qadağan etmək
-
+
+ It appends the text to the window title to help distinguish qBittorent instances
+ O, qBittorent nümunələrini fərqləndirmək üçün pəncərə başlığına mətn əlavə edir.
+
+
+
+ Customize application instance name
+ Tətbiq nümunəsi adının dəyişdirilməsi
+
+
+
It controls the internal state update interval which in turn will affect UI updates
Bu yenilənmə tezliyinin daxili vəziyətini idarə edir, bu da öz növəsində İİ yenilənmələrinə təsir edəcək
-
+
Refresh interval
Yenilənmə aralığı
-
+
Resolve peer host names
İştirakçıların host adlarını müəyyən etmək
-
+
IP address reported to trackers (requires restart)
İP ünvanı izləyicilərə bildirildi (yenidən başladılmalıdır)
-
+
Reannounce to all trackers when IP or port changed
İP və ya port dəyişdirildiyi zaman təkrar bildirmək
-
+
Enable icons in menus
Menyudakı nişanları aktiv edin
-
+
Enable port forwarding for embedded tracker
Daxildə olan izləyicilər üçün port yönləndirməsini aktiv et.
-
+
Enable quarantine for downloaded files
Endirilmiş fayllar üçün qarantini aktiv edin
-
+
Enable Mark-of-the-Web (MOTW) for downloaded files
Endirilmiş fayllar üçün veb markasını (Mark-of-the-Web - MOTW) aktiv edin
-
+
+ Affects certificate validation and non-torrent protocol activities (e.g. RSS feeds, program updates, torrent files, geoip db, etc)
+
+
+
+
+ Ignore SSL errors
+
+
+
+
(Auto detect if empty)
(Boş olmasının avtomatik aşkarlanması)
-
+
Python executable path (may require restart)
Python icra faylı yolu (yenidən başlatmaq tələb oluna bilər)
-
+
+ Start BitTorrent session in paused state
+
+
+
+
+ sec
+ seconds
+ san
+
+
+
+ -1 (unlimited)
+
+
+
+
+ BitTorrent session shutdown timeout [-1: unlimited]
+
+
+
+
Confirm removal of tracker from all torrents
Bütün torrentlərdən izləyicilərin kənarlaşdırılmasını təsdiq etmək
-
+
Peer turnover disconnect percentage
İştirakçı axınının kəsilməsi faizi
-
+
Peer turnover threshold percentage
İştirakçı axını həddinin faizi
-
+
Peer turnover disconnect interval
İştirakçı axınının kəsilmə müddəti
-
+
Resets to default if empty
Boş olduqda ilkin vəziyyətinə qaytarmaq
-
+
DHT bootstrap nodes
DHT özüyükləmə qovşaqları
-
+
I2P inbound quantity
I2P daxilolma miqdarı
-
+
I2P outbound quantity
I2P çıxma miqdarı
-
+
I2P inbound length
I2P daxilolma uzunluğu
-
+
I2P outbound length
I2P çıxma uzunluğu
-
+
Display notifications
Bildirişləri göstərmək
-
+
Display notifications for added torrents
Əlavə edilmiş torrentlər üçün bildirişləri göstərmək
-
+
Download tracker's favicon
İzləyici nişanlarını yükləmək
-
+
Save path history length
Saxlama yolunun tarixçəsinin uzunluğu
-
+
Enable speed graphs
Sürət qrafikini aktiv etmək
-
+
Fixed slots
Sabitləşdirilmiş yuvalar
-
+
Upload rate based
Yükləmə sürəti əsasında
-
+
Upload slots behavior
Göndərmə yuvalarının davranışı
-
+
Round-robin
Dairəvi
-
+
Fastest upload
Ən sürətli yükləmə
-
+
Anti-leech
Sui-istifadəni əngəlləmək
-
+
Upload choking algorithm
Göndərmənin məhdudlaşdırılması alqoritmi
-
+
Confirm torrent recheck
Torrentin yenidən yoxlanılmasını təsdiqləmək
-
+
Confirm removal of all tags
Bütün yarlıqların silinməsini təsdiq etmək
-
+
Always announce to all trackers in a tier
Bir səviyyədəki bütün iştirakçılara həmişə bildirmək
-
+
Always announce to all tiers
Bütün səviyyələrə həmişə bildirmək
-
+
Any interface
i.e. Any network interface
İstənilən interfeys
-
+
%1-TCP mixed mode algorithm
uTP-TCP mixed mode algorithm
Qarışıq %1-TCP rejimi alqoritmi
-
+
Resolve peer countries
İştirakçıların ölkələrini müəyyən etmək
-
+
Network interface
Şəbəkə interfeysi
-
+
Optional IP address to bind to
Qoşulmaq üçün ixtiyari İP ünvanı
-
+
Max concurrent HTTP announces
Ən çox paralel HTTP elanıları
-
+
Enable embedded tracker
Yerləşdirilmiş izləyicini aktiv etmək
-
+
Embedded tracker port
Yerləşdirilmiş izləyici portu
+
+ AppController
+
+
+
+ Invalid directory path
+
+
+
+
+ Directory does not exist
+
+
+
+
+ Invalid mode, allowed values: %1
+
+
+
Application
-
+
Running in portable mode. Auto detected profile folder at: %1
Portativ rejimdə işləyir. Burada avtomatik profil qovluğu aşkar edildi: %1
-
+
Redundant command line flag detected: "%1". Portable mode implies relative fastresume.
Lazımsız əmr sətri bayrağı aşkarlandı: "%1". Portativ rejim işin nisbətən daha tez bərpa olunması anlamına gəlir.
-
+
Using config directory: %1
Bu ayarlar qovluğu istifadə olunur: %1
-
+
Torrent name: %1
Torrentin adı: %1
-
+
Torrent size: %1
Torrentin ölçüsü: %1
-
+
Save path: %1
Saxlama yolu: %1
-
+
The torrent was downloaded in %1.
The torrent was downloaded in 1 hour and 20 seconds
Torrent %1 qovluğuna yükləndi.
-
+
+
Thank you for using qBittorrent.
qBittorrent istifadə etdiyiniz üçün sizə təşəkkür edirik.
-
+
Torrent: %1, sending mail notification
Torrent: %1, poçt bildirişi göndərmək
-
+
Add torrent failed
Torrent əlavə edilməsi baş tutmadı
-
+
Couldn't add torrent '%1', reason: %2.
"%1" torrentini əlavə etmək mümkün olmadı, səbəb: %2
-
+
The WebUI administrator username is: %1
Veb istfadəçi interfeysi inzibatçısının istifadəçi adı: %1
-
+
The WebUI administrator password was not set. A temporary password is provided for this session: %1
Veb istifadəçi interfeysi inzibatçı şifrəsi təyin edilməyib. Bu sesiya üçün müvəqqəti şifrə təqdim olunur: %1
-
+
You should set your own password in program preferences.
Öz şifrənizi proramın ayarlarında təyin etməlisiniz.
-
+
The WebUI is disabled! To enable the WebUI, edit the config file manually.
Veb istifadəçi interfeysi söndürülüb. Onu aktiv etmək üçün tənzimləmə faylınında dəyişiklik edin.
-
+
Running external program. Torrent: "%1". Command: `%2`
Xarici proqram işə düşür. Torrent: "%1". Əmr: "%2"
-
+
Failed to run external program. Torrent: "%1". Command: `%2`
Xarici proqramı başlatmaq mümkün olmadı. Torrent: "%1". Əmr: "%2"
-
+
Torrent "%1" has finished downloading
"%1" torrenti yükləməni başa çatdırdı
-
+
WebUI will be started shortly after internal preparations. Please wait...
Veb İİ daxili hazırlıqdan sonra qısa zamanda başladılacaqdır. Lütfən gözləyin...
-
-
+
+
Loading torrents...
Torrentlər yüklənir...
-
+
E&xit
Çı&xış
-
+
I/O Error
i.e: Input/Output Error
Giriş/Çıxış xətası
-
+
An I/O error occurred for torrent '%1'.
Reason: %2
e.g: An error occurred for torrent 'xxx.avi'.
@@ -1416,100 +1502,110 @@
Səbəb: %2
-
+
Torrent added
Torrent əlavə edildi
-
+
'%1' was added.
e.g: xxx.avi was added.
"%1" əlavə edildi.
-
+
Download completed
Endirmə tamamlandı
-
+
qBittorrent %1 started. Process ID: %2
qBittorrent v3.2.0alpha started
qBittorrent %1 başladıldı. Proses İD-si: %2
-
+
+ This is a test email.
+
+
+
+
+ Test email
+
+
+
+
'%1' has finished downloading.
e.g: xxx.avi has finished downloading.
"%1" endirməni tamamladı.
-
+
Information
Məlumat
-
+
To fix the error, you may need to edit the config file manually.
Xətanı aradan qaldırmaq üçün tənzimləmə faylında dəyişiklik etməniz lazımdır.
-
+
To control qBittorrent, access the WebUI at: %1
qBittorrent'i idarə etmək üçün, bu ünvandan Veb istifadəçi interfeysinə daxil olun: %1
-
+
Exit
Çıxış
-
+
Recursive download confirmation
Rekursiv endirmənin təsdiqi
-
+
The torrent '%1' contains .torrent files, do you want to proceed with their downloads?
"%1" torrenti torrent fayllarından ibarətdir, endirilməsinə davam etmək istəyirsinizmi?
-
+
Never
Heç vaxt
-
+
Recursive download .torrent file within torrent. Source torrent: "%1". File: "%2"
Torrentdən .torrent faylnın rekursiv endirilməsi. Torrentin mənbəyi: "%1". Fayl: "%2"
-
+
Failed to set physical memory (RAM) usage limit. Error code: %1. Error message: "%2"
Fiziki yaddaş (RAM) limitini təyin etmək mümkün olmadı. Xəta kodu: %1. Xəta bildirişi: "%2"
-
+
Failed to set physical memory (RAM) usage hard limit. Requested size: %1. System hard limit: %2. Error code: %3. Error message: "%4"
Fiziki yaddaşın (RAM) ciddi limitini təyin etmək mümkün olmadı. Tələb olunan ölçü: %1. Sistemin ciddi limiti: %2. Xəta kodu: %3. Xəta ismarıcı: "%4"
-
+
qBittorrent termination initiated
qBittorrent-in bağlanması başladıldı
-
+
qBittorrent is shutting down...
qBittorrent söndürülür...
-
+
Saving torrent progress...
Torrentin vəziyyəti saxlanılır...
-
+
qBittorrent is now ready to exit
qBittorrent indi çıxışa hazırdır
@@ -1517,7 +1613,7 @@
AsyncFileStorage
-
+
Could not create directory '%1'.
"%1" qovluğu yaradıla bilmədi.
@@ -1944,58 +2040,58 @@ Bu formatlar dəstəklənir: S01E01, 1x1, 2017.12.31 və 31.12.2017 (Həmçinin
BitTorrent::BencodeResumeDataStorage
-
+
Cannot create torrent resume folder: "%1"
Torrenti davam etdirmək üçün qovluq yaradıla bilmir: "%1"
-
+
Cannot parse resume data: invalid format
Davam etmək üçün verilənlər təmin edilmədi: torrent formatı səhvdir
-
-
+
+
Cannot parse torrent info: %1
Torrent məlumatı təmin edilə bilmədi: %1
-
+
Cannot parse torrent info: invalid format
Torrent təhlil edilə bilmədi: format səhvdir
-
+
Mismatching info-hash detected in resume data
Bərpaetmə verilənlərində heş daxili uyğunsuzluq aşkarlandı
-
+
Couldn't save torrent metadata to '%1'. Error: %2.
Torrent meta verilənləri "%1"-də/da saxılanıla bilmədi. Xəta: %2.
-
+
Couldn't save torrent resume data to '%1'. Error: %2.
Torrentin bərpası üçün verilənlər '%1'-də/da saxlanıla bilmədi. Xəta: %2.
-
+
Couldn't load torrents queue: %1
Torrent növbəsini yükləmək mümkün olmadı: %1
-
+
Cannot parse resume data: %1
Davam etmək üçün verilənlər təmin edilmədi: %1
-
+
Resume data is invalid: neither metadata nor info-hash was found
Davam etdirmək üçün verilənlər səhvdir: nə meta verilənləri nə də heş-məlumat tapılmadı
-
+
Couldn't save data to '%1'. Error: %2
Verilənləri "%1"-də/da saxlamaq mümkün olmadı. Xəta: %2
@@ -2003,38 +2099,38 @@ Bu formatlar dəstəklənir: S01E01, 1x1, 2017.12.31 və 31.12.2017 (Həmçinin
BitTorrent::DBResumeDataStorage
-
+
Not found.
Tapılmadı
-
+
Couldn't load resume data of torrent '%1'. Error: %2
"%1" torentinin bərpa üçün məlumatlarını göndərmək mümkün olmadı. Xəta: %2
-
-
+
+
Database is corrupted.
Verilənlər bazası zədələnib.
-
+
Couldn't enable Write-Ahead Logging (WAL) journaling mode. Error: %1.
Öncədən Yazma Gündəliyi (ing. - WAL) jurnallama rejimi. Xəta: %1
-
+
Couldn't obtain query result.
Sorğu nəticələrini əldə etmək mümkün olmadı.
-
+
WAL mode is probably unsupported due to filesystem limitations.
Öncədən Yazma Gündəliyi rejimi, ehtimal ki, fayl sistemindəki məhdudiyyət səbəbindən dəstəklənmir.
-
+
Couldn't begin transaction. Error: %1
Köçürməni başlatmaq mümkün olmadı. Xəta: %1
@@ -2042,22 +2138,22 @@ Bu formatlar dəstəklənir: S01E01, 1x1, 2017.12.31 və 31.12.2017 (Həmçinin
BitTorrent::ResumeDataStorage
-
+
Couldn't save torrent metadata. Error: %1.
Torrent meta verilənləri saxlanıla bilmədi. Xəta: %1.
-
+
Couldn't store resume data for torrent '%1'. Error: %2
"%1" torrenti üçün bərpa məlumatlarını saxlamaq mümkün olmadı. Xəta: %2
-
+
Couldn't delete resume data of torrent '%1'. Error: %2
"%1" torentinin bərpa üçün məlumatlarını silmək mümkün olmadı. Xəta: %2
-
+
Couldn't store torrents queue positions. Error: %1
Torrentin növbədəki yerini saxlamaq mümkün olmadı. Xəta: %1
@@ -2065,466 +2161,510 @@ Bu formatlar dəstəklənir: S01E01, 1x1, 2017.12.31 və 31.12.2017 (Həmçinin
BitTorrent::SessionImpl
-
-
+
+
Distributed Hash Table (DHT) support: %1
Bölüşdürülən heş cədvəli (DHT) cədvəli: %1
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
ON
AÇIQ
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
OFF
BAĞLI
-
-
+
+
Local Peer Discovery support: %1
Yerli iştirakçəların aşkarlanması: %1
-
+
Restart is required to toggle Peer Exchange (PeX) support
İştirakçı mübadiləsi (PeX) dəstəklənməsini aktiv etmək üçün yenidən başlatmaq tələb olunur
-
+
Failed to resume torrent. Torrent: "%1". Reason: "%2"
Torrenti davam etdirmək mümkün olmadı: "%1". Səbəb: "%2"
-
-
+
+
Failed to resume torrent: inconsistent torrent ID is detected. Torrent: "%1"
Torrenti davam etdirmək mümkün olmadı: ziddiyyətli torrent İD aşkarlandı. Torrent: "%1"
-
+
Detected inconsistent data: category is missing from the configuration file. Category will be recovered but its settings will be reset to default. Torrent: "%1". Category: "%2"
Zİddiyyətli məluymat aşkarlandı: tənzimləmə faylında kateqoriya çatışmır. Kateqoriya bərpa olunacaq, lakin onun ayarları ilkin vəziyyətə sıfırlanacaq. Torrent: "%1". Kateqoriya: "%2"
-
+
Detected inconsistent data: invalid category. Torrent: "%1". Category: "%2"
Ziddiyyətli məlumat aşkarlandı: kateqoriya səhvdir. Torrent: "%1". Kateqoriya: "%2"
-
+
Detected mismatch between the save paths of the recovered category and the current save path of the torrent. Torrent is now switched to Manual mode. Torrent: "%1". Category: "%2"
Bərpa olunmuş kateqoriyanın saxlanma yolları və hazırkı torrentin saxlama yolu araında uyğunsuzluq aşkarlandı. Torrent indi əl ilə ayarlama rejiminə dəyişdirildi. Torrent: "%1". Kateqorya: "%2"
-
+
Detected inconsistent data: tag is missing from the configuration file. Tag will be recovered. Torrent: "%1". Tag: "%2"
Tutarsız verilənlər aşkarlandı: tənzimləmə faylında etiketlər çatımır. Etiket bərpa olunacaqdır. Torrent: "%1". Etiket: "%2"
-
+
Detected inconsistent data: invalid tag. Torrent: "%1". Tag: "%2"
Tutarsız verilənlər aşkarlandı: etiket səhvdir. Torrent: "%1". Etiket: "%2"
-
+
System wake-up event detected. Re-announcing to all the trackers...
Sistemin oyanması hadisəsi aşkar edildi. Bütün izləyicilərə yenidən bildirilir...
-
+
Peer ID: "%1"
İştirakçı İD-si: "%1"
-
+
HTTP User-Agent: "%1"
HTTP İstifadəçi Tanıtımı: "%1"
-
+
Peer Exchange (PeX) support: %1
İştirakçı mübadiləsi (PeX) dəstəkkənməsi: %1
-
-
+
+
Anonymous mode: %1
Anonim rejim: %1
-
-
+
+
Encryption support: %1
Şifrələmə dəstəyi: %1
-
-
+
+
FORCED
MƏCBURİ
-
+
Could not find GUID of network interface. Interface: "%1"
Şəbəkə interfeysinə aid GUİD tapılmadı: İnterfeys: "%1"
-
+
Trying to listen on the following list of IP addresses: "%1"
Aşağıdakı İP ünvanları siyahısını dinləməyə cəhd edilir: "%1"
-
+
Torrent reached the share ratio limit.
Torrent paylaşım nisbəti həddinə çatdı.
-
-
-
+
Torrent: "%1".
Torrent: "%1".
-
-
-
- Removed torrent.
- Torrent silinib.
+
+
+
+ Detected an attempt to add a duplicate torrent. Existing torrent: %1. Result: %2
+
-
-
-
- Removed torrent and deleted its content.
- Torrent və onun tərkibləri silinib.
+
+ Merging of trackers is disabled
+ İzləyicilərin birləşdirilməsi söndürülüb
-
-
-
- Torrent paused.
- Torrent fasilədədir.
+
+ Trackers cannot be merged because it is a private torrent
+ izləyicilər birləşdirilə bilməz, çünki bu fərdi torrentdir
-
-
-
+
+ Trackers are merged from new source
+ Yeni torrentdən izləyicilər birləşdirildi
+
+
+
+ Failed to remove partfile. Torrent: "%1". Reason: "%2".
+
+
+
+
Super seeding enabled.
Super göndərmə aktiv edildi.
-
+
Torrent reached the seeding time limit.
Torrent göndərmə vaxtı limitinə çatdı.
-
+
Torrent reached the inactive seeding time limit.
Torrent qeyri-aktiv göndərmə vaxtı həddinə çatdı.
-
+
Failed to load torrent. Reason: "%1"
Torrent yüklənə bimədi. Səbəb: "%1"
-
+
I2P error. Message: "%1".
I2P xətası. Bildiriş: "%1".
-
+
UPnP/NAT-PMP support: ON
UPnP/NAT-PMP dəstəkləməsi: AÇIQ
-
+
+ Saving resume data completed.
+
+
+
+
+ BitTorrent session successfully finished.
+
+
+
+
+ Session shutdown timed out.
+
+
+
+
+ Removing torrent.
+
+
+
+
+ Removing torrent and deleting its content.
+
+
+
+
+ Torrent stopped.
+
+
+
+
+ Torrent content removed. Torrent: "%1"
+
+
+
+
+ Failed to remove torrent content. Torrent: "%1". Error: "%2"
+
+
+
+
+ Torrent removed. Torrent: "%1"
+
+
+
+
UPnP/NAT-PMP support: OFF
UPnP / NAT-PMP dəstəklənməsi: BAĞLI
-
+
Failed to export torrent. Torrent: "%1". Destination: "%2". Reason: "%3"
Torrent ixrac edilmədi. Torrent: "%1". Təyinat: "%2". Səbəb: "%3"
-
+
Aborted saving resume data. Number of outstanding torrents: %1
Davam etdirmə məlumatları ləğv edildi. İcra olunmamış torrentlərin sayı: %1
-
+
The configured network address is invalid. Address: "%1"
Ayarlanmış şəbəkə ünvanı səhvdir. Ünvan: "%1"
-
-
+
+
Failed to find the configured network address to listen on. Address: "%1"
Dinləmək üçün ayarlanmış şəbəkə ünvanını tapmaq mümkün olmadı. Ünvan: "%1"
-
+
The configured network interface is invalid. Interface: "%1"
Ayarlanmış şəbəkə ünvanı interfeysi səhvdir. İnterfeys: "%1"
-
+
Rejected invalid IP address while applying the list of banned IP addresses. IP: "%1"
Qadağan olunmuş İP ünvanları siyahısını tətbiq edərkən səhv İP ünvanları rədd edildi. İP: "%1"
-
+
Added tracker to torrent. Torrent: "%1". Tracker: "%2"
Torrentə izləyici əlavə olundu. Torrent: "%1". İzləyici: "%2"
-
+
Removed tracker from torrent. Torrent: "%1". Tracker: "%2"
İzləyici torrentdən çıxarıldı. Torrent: "%1". İzləyici: "%2"
-
+
Added URL seed to torrent. Torrent: "%1". URL: "%2"
Torrent URL göndərişi əlavə olundu. Torrent: "%1". URL: "%2"
-
+
Removed URL seed from torrent. Torrent: "%1". URL: "%2"
URL göndərişi torrentdən çıxarıldı. Torrent: "%1". URL: "%2"
-
- Torrent paused. Torrent: "%1"
- Torrent fasilədədir. Torrent: "%1"
-
-
-
+
Torrent resumed. Torrent: "%1"
Torrent davam etdirildi: Torrent: "%1"
-
+
Torrent download finished. Torrent: "%1"
Torrent endirilməsi başa çatdı. Torrent: "%1"
-
+
Torrent move canceled. Torrent: "%1". Source: "%2". Destination: "%3"
Torrentin köçürülməsi ləğv edildi. Torrent: "%1". Mənbə: "%2". Təyinat: "%3"
-
+
+ Torrent stopped. Torrent: "%1"
+
+
+
+
Failed to enqueue torrent move. Torrent: "%1". Source: "%2". Destination: "%3". Reason: torrent is currently moving to the destination
Torrentin köçürülməsini növbələmək mümkün olmadı. Torrent: "%1". Mənbə; "%2". Təyinat: "%3". Səbəb: torrent hal-hazırda təyinat yerinə köçürülür
-
+
Failed to enqueue torrent move. Torrent: "%1". Source: "%2" Destination: "%3". Reason: both paths point to the same location
Torrentin köçürülməsini növbələmək mümkün olmadı. Torrent: "%1". Mənbə; "%2". Təyinat: "%3". Səbəb: hər iki yol eyni məkanı göstərir
-
+
Enqueued torrent move. Torrent: "%1". Source: "%2". Destination: "%3"
Torrentin köçürülməsi növbəyə qoyuıdu. Torrent: "%1". Mənbə: "%2". Təyinat: "%3"
-
+
Start moving torrent. Torrent: "%1". Destination: "%2"
Torrent köçürülməsini başladın. Torrent: "%1". Təyinat: "%2"
-
+
Failed to save Categories configuration. File: "%1". Error: "%2"
Kateqoriyalar tənzimləmələrini saxlamaq mümkün olmadı. Fayl: "%1". Xəta: "%2"
-
+
Failed to parse Categories configuration. File: "%1". Error: "%2"
Kateoriya tənzimləmələrini təhlil etmək mümkün olmadı. Fayl: "%1". Xəta: "%2"
-
+
Successfully parsed the IP filter file. Number of rules applied: %1
İP filter faylı təhlili uğurlu oldu. Tətbiq olunmuş qaydaların sayı: %1
-
+
Failed to parse the IP filter file
İP filter faylının təhlili uğursuz oldu
-
+
Restored torrent. Torrent: "%1"
Bərpa olunmuş torrent. Torrent; "%1"
-
+
Added new torrent. Torrent: "%1"
Əlavə olunmuş yeni torrent. Torrent: "%1"
-
+
Torrent errored. Torrent: "%1". Error: "%2"
Xətalı torrent. Torrent: "%1". Xəta: "%2"
-
-
- Removed torrent. Torrent: "%1"
- Ləğv edilmiş torrent. Torrent; "%1"
+
+ Torrent is missing SSL parameters. Torrent: "%1". Message: "%2"
+ Torrentdə SSL parametrləri çatışmır. Torrent: "%1". İsmarıc: "%2"
-
- Removed torrent and deleted its content. Torrent: "%1"
- Ləğv edilmiş və tərkibləri silinmiş torrent. Torrent: "%1"
-
-
-
+
File error alert. Torrent: "%1". File: "%2". Reason: "%3"
Fayldakı xəta bildirişi. Torrent: "%1". Fayl: "%2". Səbəb: "%3"
-
+
UPnP/NAT-PMP port mapping failed. Message: "%1"
UPnP/NAT-PMP: Portun palanması uğursuz oldu. Bildiriş: %1
-
+
UPnP/NAT-PMP port mapping succeeded. Message: "%1"
UPnP/NAT-PMP: Portun palanması uğurlu oldu. Bildiriş: %1
-
+
IP filter
this peer was blocked. Reason: IP filter.
İP filtr
-
+
filtered port (%1)
this peer was blocked. Reason: filtered port (8899).
filtrlənmiş port (%1)
-
+
privileged port (%1)
this peer was blocked. Reason: privileged port (80).
imtiyazlı port (%1)
-
+
BitTorrent session encountered a serious error. Reason: "%1"
BitTorrent sesiyası bir sıra xətalarla qarşılaşdı. Səbəb: "%1"
-
+
SOCKS5 proxy error. Address: %1. Message: "%2".
SOCKS5 proksi xətası. Ünvan: %1. İsmarıc: "%2".
-
+
%1 mixed mode restrictions
this peer was blocked. Reason: I2P mixed mode restrictions.
%1 qarışıq rejimi məhdudiyyətləri
-
+
Failed to load Categories. %1
Kateqoriyaları yükləmək mümkün olmadı. %1
-
+
Failed to load Categories configuration. File: "%1". Error: "Invalid data format"
Kateqoriya tənzimləmələrini yükləmək mümkün olmadı. Fayl: "%1". Xəta: "Səhv verilən formatı"
-
- Removed torrent but failed to delete its content and/or partfile. Torrent: "%1". Error: "%2"
- Ləğv edilmiş, lakin tərkiblərinin silinməsi mümkün olmayan və/və ya yarımçıq torrent faylı. Torrent: "%1". Xəta: "%2"
-
-
-
+
%1 is disabled
this peer was blocked. Reason: uTP is disabled.
%1 söndürülüb
-
+
%1 is disabled
this peer was blocked. Reason: TCP is disabled.
%1 söndürülüb
-
+
URL seed DNS lookup failed. Torrent: "%1". URL: "%2". Error: "%3"
İştirakçı ünvanının DNS-də axtarışı uğursuz oldu. Torrent: "%1". URL: "%2". Xəta: "%3"
-
+
Received error message from URL seed. Torrent: "%1". URL: "%2". Message: "%3"
İştirakçının ünvanından xəta haqqında bildiriş alındı. Torrent: "%1". URL: "%2". Bildiriş: "%3"
-
+
Successfully listening on IP. IP: "%1". Port: "%2/%3"
İP uöurla dinlənilir. İP: "%1". port: "%2/%3"
-
+
Failed to listen on IP. IP: "%1". Port: "%2/%3". Reason: "%4"
İP-nin dinlənilməsi uğursuz oldu. İP: "%1". port: "%2/%3". Səbəb: "%4"
-
+
Detected external IP. IP: "%1"
Kənar İP aşkarlandı. İP: "%1"
-
+
Error: Internal alert queue is full and alerts are dropped, you might see degraded performance. Dropped alert type: "%1". Message: "%2"
Xəta: Daxili xəbərdarlıq sırası doludur və xəbərdarlıq bildirişlər kənarlaşdırıldı, sistemin işinin zəiflədiyini görə bilərsiniz. Kənarlaşdırılan xəbərdarlıq növləri: %1. Bildiriş: %2
-
+
Moved torrent successfully. Torrent: "%1". Destination: "%2"
Torrent uğurla köçürüldü. Torrent: "%1". Təyinat: "%2"
-
+
Failed to move torrent. Torrent: "%1". Source: "%2". Destination: "%3". Reason: "%4"
Torrentin köçürülməsi uğursuz oldu. Torrent: "%1". Mənbə: "%2". Təyinat: "%3". Səbəb: "%4"
+
+ BitTorrent::TorrentCreationTask
+
+
+ Failed to start seeding.
+ Paylamanı başlatmaq uğursuz oldu.
+
+
BitTorrent::TorrentCreator
-
+
Operation aborted
Əməliyyat ləğv edildi
-
-
+
+
Create new torrent file failed. Reason: %1.
Yeni torrent faylın yaradılması baş tutmadı. Səbəb: %1.
@@ -2532,67 +2672,67 @@ Bu formatlar dəstəklənir: S01E01, 1x1, 2017.12.31 və 31.12.2017 (Həmçinin
BitTorrent::TorrentImpl
-
+
Failed to add peer "%1" to torrent "%2". Reason: %3
"%1" iştirakçının "%2" teorrentinə əlavə edilməsi alınmadı. Səbəb: %3
-
+
Peer "%1" is added to torrent "%2"
"%1" iştirakçısı "%2" torrentinə əlavə edildi
-
+
Unexpected data detected. Torrent: %1. Data: total_wanted=%2 total_wanted_done=%3.
Gözlənilməyən verilən aşkarlandı. Torrent: %1. Verilən: total_wanted=%2 total_wanted_done=%3.
-
+
Couldn't write to file. Reason: "%1". Torrent is now in "upload only" mode.
Fayla yazıla bilmir. Səbəb: "%1" Torrent indi "yalnız göndərmək" rejimindədir.
-
+
Download first and last piece first: %1, torrent: '%2'
Öncə ilk və son hissəni endirmək: %1, torrent: "%2"
-
+
On
Açıq
-
+
Off
Bağlı
-
+
Failed to reload torrent. Torrent: %1. Reason: %2
Torrenti yenidən başlatmaq mümkün olmadı. Torrent: %1. Səbəb: %2
-
+
Generate resume data failed. Torrent: "%1". Reason: "%2"
Torrenti davam etdirmək üçün məlumatlar yaradıla bilmədi: "%1". Səbəb: "%2"
-
+
Failed to restore torrent. Files were probably moved or storage isn't accessible. Torrent: "%1". Reason: "%2"
Torrent bərpa oluna bilmədi. Güman ki, fayl köçürülüb və ya yaddaşa giriş əlçatmazdır. Torrent: "%1". Səbəb: "%2"
-
+
Missing metadata
Meta verilənləri çatışmır
-
+
File rename failed. Torrent: "%1", file: "%2", reason: "%3"
Faylın adı dəyişdirilmədi. Torrent: "%1", fayl: "%2", səbəb: "%3"
-
+
Performance alert: %1. More info: %2
Performans xəbərdarlığı: %1. Daha çox məlumat: %2
@@ -2629,12 +2769,6 @@ Bu formatlar dəstəklənir: S01E01, 1x1, 2017.12.31 və 31.12.2017 (Həmçinin
Expected integer number in environment variable '%1', but got '%2'
Dəyişən mühitdə "%1" gözlənilən tam ədəddir, lakin "%2" alındı
-
-
- Parameter '%1' must follow syntax '%1=%2'
- e.g. Parameter '--add-paused' must follow syntax '--add-paused=<true|false>'
- "%1" parametri '%1=%2' sintaksisin ilə uzlaşmalıdır
-
Expected %1 in environment variable '%2', but got '%3'
@@ -2671,6 +2805,12 @@ Bu formatlar dəstəklənir: S01E01, 1x1, 2017.12.31 və 31.12.2017 (Həmçinin
Display this help message and exit
Bu kömək bildirişini göstərmək və çıxmaq
+
+
+ Parameter '%1' must follow syntax '%1=%2'
+ e.g. Parameter '--add-stopped' must follow syntax '--add-stopped=<true|false>'
+ "%1" parametri '%1=%2' sintaksisin ilə uzlaşmalıdır
+
Confirm the legal notice
@@ -2756,8 +2896,8 @@ Bu formatlar dəstəklənir: S01E01, 1x1, 2017.12.31 və 31.12.2017 (Həmçinin
- Add torrents as started or paused
- Torrentləri başladılan və ya fasilədə olan kimi əlavə etmək
+ Add torrents as running or stopped
+
@@ -2847,13 +2987,13 @@ Bu formatlar dəstəklənir: S01E01, 1x1, 2017.12.31 və 31.12.2017 (Həmçinin
- Resume torrents
- Torrentləri davam etdirmək
+ Start torrents
+
- Pause torrents
- Torrentlərə fasilə
+ Stop torrents
+
@@ -2864,15 +3004,20 @@ Bu formatlar dəstəklənir: S01E01, 1x1, 2017.12.31 və 31.12.2017 (Həmçinin
ColorWidget
-
+
Edit...
Düzəliş et...
-
+
Reset
Sıfırlamaq
+
+
+ System
+
+
CookiesDialog
@@ -2913,12 +3058,12 @@ Bu formatlar dəstəklənir: S01E01, 1x1, 2017.12.31 və 31.12.2017 (Həmçinin
CustomThemeSource
-
+
Failed to load custom theme style sheet. %1
Fərdi mövzu cədvəlini yükləməkl mümkün olmadı. %1
-
+
Failed to load custom theme colors. %1
Fərdi mövzu rənglərini yükləmək mümkün olmadı. %1
@@ -2926,7 +3071,7 @@ Bu formatlar dəstəklənir: S01E01, 1x1, 2017.12.31 və 31.12.2017 (Həmçinin
DefaultThemeSource
-
+
Failed to load default theme colors. %1
Standart mövzu rənglərini yükləmək mümkün olmadı. %1
@@ -2945,23 +3090,23 @@ Bu formatlar dəstəklənir: S01E01, 1x1, 2017.12.31 və 31.12.2017 (Həmçinin
- Also permanently delete the files
- Həmçinin bu faylı birdəfəlik silin
+ Also remove the content files
+
-
+
Are you sure you want to remove '%1' from the transfer list?
Are you sure you want to remove 'ubuntu-linux-iso' from the transfer list?
"%1" faylını köçürmə sayahısından silmək istədiyinizə əminsiz?
-
+
Are you sure you want to remove these %1 torrents from the transfer list?
Are you sure you want to remove these 5 torrents from the transfer list?
%1 torrentlərini köçürmə siyasından silmək istədiyinizə əminsiniz?
-
+
Remove
Silin
@@ -2989,12 +3134,12 @@ Bu formatlar dəstəklənir: S01E01, 1x1, 2017.12.31 və 31.12.2017 (Həmçinin
Endirmək
-
+
No URL entered
URL daxil edilməyib
-
+
Please type at least one URL.
Lütfən, ən azı bir URL daxil edin
@@ -3153,25 +3298,48 @@ Bu formatlar dəstəklənir: S01E01, 1x1, 2017.12.31 və 31.12.2017 (Həmçinin
Təhlil xətası: Filtr faylı, düzgün PeerGuardian P2B faylı deyil.
+
+ FilterPatternFormatMenu
+
+
+ Pattern Format
+
+
+
+
+ Plain text
+
+
+
+
+ Wildcards
+
+
+
+
+ Regular expression
+
+
+
GUIAddTorrentManager
-
+
Downloading torrent... Source: "%1"
Torrent endirilir... Mənbə: "%1"
-
- Trackers cannot be merged because it is a private torrent
- izləyicilər birləşdirilə bilməz, çünki bu fərdi torrentdir
-
-
-
+
Torrent is already present
Torrent artıq mövcuddur
-
+
+ Trackers cannot be merged because it is a private torrent.
+
+
+
+
Torrent '%1' is already in the transfer list. Do you want to merge trackers from new source?
Torrent '%1' artıq köçürülmə siyahısındadır. Mənbədən izləyiciləri birləçdirmək istəyirsiniz?
@@ -3218,17 +3386,17 @@ Bu formatlar dəstəklənir: S01E01, 1x1, 2017.12.31 və 31.12.2017 (Həmçinin
Http::Connection
-
+
Http request size exceeds limitation, closing socket. Limit: %1, IP: %2
Tələb olunan Http ölçüsü limiti aşır, socket bağlanır. Limit: %1, İP: %2
-
+
Bad Http request method, closing socket. IP: %1. Method: "%2"
Səhv Http sorğu üsulu, soket bağlanır. İP: %1. Üsul: "%2"
-
+
Bad Http request, closing socket. IP: %1
Səhv Http tələbi, socket bağlanır. İP: %1
@@ -3269,22 +3437,22 @@ Bu formatlar dəstəklənir: S01E01, 1x1, 2017.12.31 və 31.12.2017 (Həmçinin
IconWidget
-
+
Browse...
Baxmaq...
-
+
Reset
Sıfırlamaq
-
+
Select icon
Nişan seç
-
+
Supported image files
Dəstəklənən şəkil faylları
@@ -3320,13 +3488,13 @@ Bu formatlar dəstəklənir: S01E01, 1x1, 2017.12.31 və 31.12.2017 (Həmçinin
LogPeerModel
-
+
%1 was blocked. Reason: %2.
0.0.0.0 was blocked. Reason: reason for blocking.
%1 bloklandı. Səbəb: %2.
-
+
%1 was banned
0.0.0.0 was banned
%1 qadağan edildi
@@ -3335,60 +3503,60 @@ Bu formatlar dəstəklənir: S01E01, 1x1, 2017.12.31 və 31.12.2017 (Həmçinin
Main
-
+
%1 is an unknown command line parameter.
--random-parameter is an unknown command line parameter.
%1, naməlum əmr sətiri parametridir.
-
-
+
+
%1 must be the single command line parameter.
%1, tək əmr sətri parametri olmalıdır.
-
+
Run application with -h option to read about command line parameters.
Əmr sətri parametrləri haqqında oxumaq üçün tətbiqi -h seçimi ilə başladın.
-
+
Bad command line
Xətalı əmr sətri
-
+
Bad command line:
Xətalı əmr sətri:
-
+
An unrecoverable error occurred.
Sazlana bilməyən xəta baş verdi.
+
-
qBittorrent has encountered an unrecoverable error.
qBittorrent sazlana bilməyən bir xəta ilə qarşılaşdı.
-
+
You cannot use %1: qBittorrent is already running.
Siz %1 istifadə edə bilməzsiniz: qBittorrent artıq işləkdir.
-
+
Another qBittorrent instance is already running.
Başqa bir qBittorrent nümunəsi artıq işləkdir.
-
+
Found unexpected qBittorrent instance. Exiting this instance. Current process ID: %1.
Gözlənilməz qBittorent nüsxəsi tapıldı. Bu nüsxədən çıxılır. Cari proses İD-si: %1.
-
+
Error when daemonizing. Reason: "%1". Error code: %2.
Demonizasiya zamanı xəta. Səbəb: "%1". Xəta kodu: %2
@@ -3401,604 +3569,615 @@ Bu formatlar dəstəklənir: S01E01, 1x1, 2017.12.31 və 31.12.2017 (Həmçinin
&Düzəliş etmək
-
+
&Tools
Alə&tlər
-
+
&File
&Fayl
-
+
&Help
&Kömək
-
+
On Downloads &Done
Endirmələr başa çat&dıqda
-
+
&View
&Baxış
-
+
&Options...
&Seçimlər...
-
- &Resume
- Davam etdi&rmək
-
-
-
+
&Remove
Silin
-
+
Torrent &Creator
Torrent Yaradı&cı
-
-
+
+
Alternative Speed Limits
Alternativ sürət hədləri
-
+
&Top Toolbar
Üs&t alətlər paneli
-
+
Display Top Toolbar
Üst alətlər panelini göstərmək
-
+
Status &Bar
Vəziyyət çu&buğu
-
+
Filters Sidebar
Filtrlər yan paneli
-
+
S&peed in Title Bar
Sürət başlıq &panelində
-
+
Show Transfer Speed in Title Bar
Köçürmə sürətini başlıq panelində göstərmək
-
+
&RSS Reader
&RSS oxuyucu
-
+
Search &Engine
Axtarış &vasitəsi
-
+
L&ock qBittorrent
qBittorrent'i kilidləmək
-
+
Do&nate!
İa&nə vermək!
-
+
&Do nothing
&Heç nə etməmək
-
+
Close Window
Pəncərəni bağlamaq
-
- R&esume All
- Hamısına dava&m
-
-
-
+
Manage Cookies...
Kikilər Meneceri...
-
+
Manage stored network cookies
Saxlanılmış şəbəkə kukilərini idarə etmək
-
+
Normal Messages
Normal Bildirişlər
-
+
Information Messages
Məlumat Bildirişləri
-
+
Warning Messages
Xəbərdarlıq Bildirişlər
-
+
Critical Messages
Kritik Bildirişlər
-
+
&Log
Jurna&l
-
+
+ Sta&rt
+
+
+
+
+ Sto&p
+
+
+
+
+ &Resume Session
+
+
+
+
+ Pau&se Session
+
+
+
+
Set Global Speed Limits...
Ümumi sürət limitlərini təyin edin...
-
+
Bottom of Queue
Növbənin sonu
-
+
Move to the bottom of the queue
Növbənin sonuna köçürmək
-
+
Top of Queue
Növbənin əvvəli
-
+
Move to the top of the queue
Növbənin əvvəlinə köçürmək
-
+
Move Down Queue
Növbəni aşağı köçürmək
-
+
Move down in the queue
Növbənin aşağısına doğru
-
+
Move Up Queue
Növbəni yuxarı köçürmək
-
+
Move up in the queue
Növbənin yuxarısına doğru
-
+
&Exit qBittorrent
qBittorrent'dən çıxma&q
-
+
&Suspend System
&Sistemi dayandırmaq
-
+
&Hibernate System
&Yuxu rejimi
-
+
S&hutdown System
Sistemi sö&ndürmək
-
+
&Statistics
&Statistikalar
-
+
Check for Updates
Yenilənmələri yoxlamaq
-
+
Check for Program Updates
Proqram yenilənmələrini yoxlamaq
-
+
&About
H&aqqında
-
- &Pause
- &Fasilə
-
-
-
- P&ause All
- Hamısına F&asilə
-
-
-
+
&Add Torrent File...
Torrent faylı əl&avə edin...
-
+
Open
Açmaq
-
+
E&xit
Çı&xış
-
+
Open URL
URL açmaq
-
+
&Documentation
Sənə&dləşmə
-
+
Lock
Kilidləmək
-
-
-
+
+
+
Show
Göstərmək
-
+
Check for program updates
Proqram yenilənmələrini yoxlamaq
-
+
Add Torrent &Link...
Torrent keçidi ə&lavə edin...
-
+
If you like qBittorrent, please donate!
qBittorrent'i bəyənirsinizsə ianə edin!
-
-
+
+
Execution Log
İcra jurnalı
-
+
Clear the password
Şifrəni silmək
-
+
&Set Password
Şifrə &təyin etmək
-
+
Preferences
Tərcihlər
-
+
&Clear Password
Şifrəni silmə&k
-
+
Transfers
Köçürmələr
-
-
+
+
qBittorrent is minimized to tray
qBittorent treyə yığıldı
-
-
-
+
+
+
This behavior can be changed in the settings. You won't be reminded again.
Bu davranış ayarlarda dəyişdirilə bilər. Sizə bir daha xatırladılmayacaq.
-
+
Icons Only
Yalnız Nişanlar
-
+
Text Only
Yalnlız Mətn
-
+
Text Alongside Icons
Nişanlar yanında mətn
-
+
Text Under Icons
Nişanlar altında mətn
-
+
Follow System Style
Sistem üslubuna uyğun
-
-
+
+
UI lock password
İİ-nin kilid şifrəsi
-
-
+
+
Please type the UI lock password:
Lütfən, İİ-nin kilid şifrəsini yazın
-
+
Are you sure you want to clear the password?
Şifrəni silmək istədiyinizə əminsiniz?
-
+
Use regular expressions
Müntəzəm ifadədən istifadə etmək
-
+
Search
Axtarış
-
+
Transfers (%1)
Köçürmələr (%1)
-
+
qBittorrent was just updated and needs to be restarted for the changes to be effective.
qBittorrent indicə yeniləndi və dəyişikliklərin qüvvəyə minməsi üçün yenidən başladılmalıdır.
-
+
qBittorrent is closed to tray
qBittorrent treyə yığıldı
-
+
Some files are currently transferring.
Hazırda bəzi fayllar ötürülür
-
+
Are you sure you want to quit qBittorrent?
qBittorent'dən çıxmaq istədiyinizə əminsiniz?
-
+
&No
&Xeyr
-
+
&Yes
&Bəli
-
+
&Always Yes
&Həmişə bəli
-
+
Options saved.
Parametrlər saxlanıldı.
-
-
+
+ [PAUSED] %1
+ %1 is the rest of the window title
+
+
+
+
+ [D: %1, U: %2] %3
+ D = Download; U = Upload; %3 is the rest of the window title
+ [D: %1, U: %2] %3
+
+
+
+
Missing Python Runtime
Python icraçısı çatışmır
-
+
qBittorrent Update Available
qBittorrent yenilənməsi mövcuddur
-
+
Python is required to use the search engine but it does not seem to be installed.
Do you want to install it now?
Python axtarş vasitəsindən istifadə etməyi tələb edir, lakin, belə görünür ki, bu vasitə
quraşdırılmayıb. Bunu indi quraşdırmaq istəyirsiniz?
-
+
Python is required to use the search engine but it does not seem to be installed.
Python axtarış vasitəsi istifadə etməyi tələb edir, lakin belə görünür ki, o quraşdırılmayıb.
-
-
+
+
Old Python Runtime
Köhnə Python iş mühiti
-
+
A new version is available.
Yeni versiya mövcuddur.
-
+
Do you want to download %1?
%1 yükləmək istəyirsiniz?
-
+
Open changelog...
Dəyişikliklər jurnalını açın...
-
+
No updates available.
You are already using the latest version.
Yenilənmələr yoxdur.
Siz artıq sonuncu versiyadan istifadə edirsiniz.
-
+
&Check for Updates
Yenilənmələri yo&xlamaq
-
+
Your Python version (%1) is outdated. Minimum requirement: %2.
Do you want to install a newer version now?
Sizin Python versiyanız (%1) köhnədir. Minimum tələb olunan versiya: %2.
Yeni versiyanı quraşdırmaq istəyirsiniz?
-
+
Your Python version (%1) is outdated. Please upgrade to latest version for search engines to work.
Minimum requirement: %2.
Sizin Python versiyanız (%1) köhnədir. Lütfən axtarış vasitələrinin işləməsi üçün son versiyaya yeniləyin.
Minimum tələb olunan versiya: %2.
-
+
+ Paused
+ Fasilədə
+
+
+
Checking for Updates...
Yenilənmələr yoxlanılır...
-
+
Already checking for program updates in the background
Proqramın yenilənmələri, artıq arxa planda yoxlanılır
-
+
Download error
Endirilmə xətası
-
+
Python setup could not be downloaded, reason: %1.
Please install it manually.
Python quraşdırmasını yükləmək mümkün olmadı: %1
Lütfən, əl ilə qyraşdırın.
-
-
+
+
Invalid password
Səhv şifrə
-
+
Filter torrents...
Torrentləri süzgəclə...
-
+
Filter by:
Buna görə süzgəclə:
-
+
The password must be at least 3 characters long
Şifrə ən az 3 işarədən ibarət olmalıdır
-
-
-
+
+
+
RSS (%1)
RSS (%1)
-
+
The password is invalid
Şifrə səhvdir
-
+
DL speed: %1
e.g: Download speed: 10 KiB/s
EN sürəti: %1
-
+
UP speed: %1
e.g: Upload speed: 10 KiB/s
GN sürəti: %1
-
- [D: %1, U: %2] qBittorrent %3
- D = Download; U = Upload; %3 is qBittorrent version
- [E: %1, G: %2] qBittorrent %3
-
-
-
+
Hide
Gizlətmək
-
+
Exiting qBittorrent
qBittorrentü'dən çıxılır
-
+
Open Torrent Files
Torrent faylları açmaq
-
+
Torrent Files
Torrent faylları
@@ -4059,133 +4238,133 @@ Lütfən, əl ilə qyraşdırın.
Net::DownloadHandlerImpl
-
-
+
+
I/O Error: %1
Giriş/Çıxış xətası: %1
-
+
The file size (%1) exceeds the download limit (%2)
Fayl ölçüsü (%1), endirmə limitini (%2) aşır
-
+
Exceeded max redirections (%1)
Maksimum yönləndirmə həddini aşdı (% 1)
-
+
Redirected to magnet URI
Maqnit URI-yə yönləndirildi
-
+
The remote host name was not found (invalid hostname)
Uzaq host adı tapılmadı (səhv host adı)
-
+
The operation was canceled
Əməliyyat ləğv edildi
-
+
The remote server closed the connection prematurely, before the entire reply was received and processed
Bütün cavablar alınmadan və işlənmədən uzaq server bağlantını vaxtından əvvəl kəsdi
-
+
The connection to the remote server timed out
Uzaq serverə bağlantının gözləmə vaxtı sona çatdı
-
+
SSL/TLS handshake failed
SSl/TLS bağlantısı alınmadı
-
+
The remote server refused the connection
Uzaq server bağlantıdan imtina etdi
-
+
The connection to the proxy server was refused
Proksi serverə bağlantı rədd edildi
-
+
The proxy server closed the connection prematurely
Proksi server bağlantını vaxtından əvvəl kəsdi
-
+
The proxy host name was not found
Proksi host adı tapılmadı
-
+
The connection to the proxy timed out or the proxy did not reply in time to the request sent
Proksi serverə bağlantının vaxtı sona çatdı və ya proksi göndərilən tələbə vaxtında cavab vermədi
-
+
The proxy requires authentication in order to honor the request but did not accept any credentials offered
Proxy, bu tələbi yerinə yetirmək üçün doğrulama tələb edir, lakin təqdim olunan hər hansı bir istifadəçi adı və şifrəni qəbul etməyib
-
+
The access to the remote content was denied (401)
Uzaq serverdəki tərkiblərə giriş qadağan edildi (401)
-
+
The operation requested on the remote content is not permitted
Uzaq serverdəki tərkiblər üzərində tətləb olunan əməliyyata icazə verilmədi
-
+
The remote content was not found at the server (404)
Uzaq tərkiblər serverdə tapılmadı (404)
-
+
The remote server requires authentication to serve the content but the credentials provided were not accepted
Uzaq server tərkiblər üzərində işləmək üçün kimlik doğrulaması tələb edir, lakin, verilən istifadəçi adı və şifrəni qəbul etmir.
-
+
The Network Access API cannot honor the request because the protocol is not known
Şəbəkəyə Giriş APİ-si, protokol naməlum olduğu üçün tələbi yerinə yetirə bilmir
-
+
The requested operation is invalid for this protocol
Bu protokol üçün tələb olunan əməliyyat səhvdir
-
+
An unknown network-related error was detected
Şəbəkə ilə əlaqəli naməlum bir xəta aşkar edildi
-
+
An unknown proxy-related error was detected
Proksi ilə əlaqəli naməlum bir xəta aşkarlandı
-
+
An unknown error related to the remote content was detected
Uzaq tərkiblərlə əlaqəli naməlum xəta aşkarlandı
-
+
A breakdown in protocol was detected
Protokolda nasazlıq aşkar edildi
-
+
Unknown error
Naməlum xəta
@@ -4193,7 +4372,12 @@ Lütfən, əl ilə qyraşdırın.
Net::DownloadManager
-
+
+ SSL error, URL: "%1", errors: "%2"
+
+
+
+
Ignoring SSL error, URL: "%1", errors: "%2"
SSL xətasını nəzərə almadan, URL: !%1", xəta: "%2"
@@ -5580,284 +5764,284 @@ Lütfən, əl ilə qyraşdırın.
Əlavə
-
+
+ Style:
+
+
+
+
Customize UI Theme...
Fərdi İİ mövzusu...
-
+
Transfer List
Köçürmə siyahısı
-
+
Confirm when deleting torrents
Torrentlərin silinməsinin təsdiq edilməsi
-
- Shows a confirmation dialog upon pausing/resuming all the torrents
- Bütün torrentlərin dayandırılması/davam etdirilməsi üzərində təsdiqlənmə dialoqunu göstərir
-
-
-
- Confirm "Pause/Resume all" actions
- "Hamısını Dayandırın/Davam etdirin" əməlləri
-
-
-
+
Use alternating row colors
In table elements, every other row will have a grey background.
Alternativ sıra rənglərindən istifadə edin
-
+
Hide zero and infinity values
Sıfır və sonsuzluq göstəricilərini gizlətmək
-
+
Always
Həmişə
-
- Paused torrents only
- Yalnız fasilədəki torrentlər
-
-
-
+
Action on double-click
İki dəfə klik əməli
-
+
Downloading torrents:
Torrentlər yüklənir:
-
-
+
+
Start / Stop Torrent
Torrenti Başlatmaq / Dayandırmaq
-
-
+
+
Open destination folder
Təyinat qovluğunu açmaq
-
-
+
+
No action
Əməl yoxdur
-
+
Completed torrents:
Tamamlanmış torrentlər
-
+
Auto hide zero status filters
Sıfır süzgəc nəticələrini avtomatik gizlətmək
-
+
Desktop
İş Masası
-
+
Start qBittorrent on Windows start up
ƏS işə düşdükdə qBittorrent'i başlatmaq
-
+
Show splash screen on start up
Başlanğıcda qarşılama ekranını göstərmək
-
+
Confirmation on exit when torrents are active
Aktiv torrenlər olduqda çıxarkən təsdiq etmək
-
+
Confirmation on auto-exit when downloads finish
Endirmələr sona çatdıqda avtomtik çıxışı təsdiq etmək
-
+
<html><head/><body><p>To set qBittorrent as default program for .torrent files and/or Magnet links<br/>you can use <span style=" font-weight:600;">Default Programs</span> dialog from <span style=" font-weight:600;">Control Panel</span>.</p></body></html>
<html><body><p>qBitttorenti, .torrent faylları və/vəya Magnet keçidləri<br/>üçün standart proqram kimi, <span style=" font-weight:600;">Standart proqramlar</span> dialoquna <span style=" font-weight:600;">İdarəetmə paneli bölməsindən</span> daxil olaraq təyin edə bilərsiniz.</p></body><head/></html>
-
+
KiB
KB
-
+
Torrent content layout:
Torrent məzmunu maketi:
-
+
Original
Orijinal
-
+
Create subfolder
Alt qovluq yaratmaq
-
+
Don't create subfolder
Alt qovluq yaratmamaq
-
+
The torrent will be added to the top of the download queue
Torrent, fasilə vəziyyətində yükləmə siyahısına əlavə ediləcək
-
+
Add to top of queue
The torrent will be added to the top of the download queue
Növbənin ən üst sırasına əlavə et
-
+
+ The torrent will be added to download list in a stopped state
+
+
+
+
When duplicate torrent is being added
Torrentin təkrar nüsxəsi əlavə olunduqda
-
+
Merge trackers to existing torrent
İzləyiciləri mövcud torrentdə birləşdirin
-
+
Keep unselected files in ".unwanted" folder
Seçilməmiş faylları "baxılmamışlar" qovluğunda saxlamaq
-
+
Add...
Əlavə edin...
-
+
Options..
Seçimlər...
-
+
Remove
Silin
-
+
Email notification &upon download completion
Endirilmə başa çatdıqdan so&nra e-poçt bildirişi
-
+
+ Send test email
+
+
+
+
Peer connection protocol:
İştirakçı bağlantı protokolu
-
+
Any
Hər hansı
-
+
I2P (experimental)
I2P (təcrübə üçün)
-
+
<html><head/><body><p>If "mixed mode" is enabled I2P torrents are allowed to also get peers from other sources than the tracker, and connect to regular IPs, not providing any anonymization. This may be useful if the user is not interested in the anonymization of I2P, but still wants to be able to connect to I2P peers.</p></body></html>
<html><head/><body><p>Əgər "qarışıq rejim" aktiv edilərsə I2P torrentlərə izləyicidən başqa digər mənbələrdən iştirakçılar əldə etməyə və heç bir anonimləşdirmə təmin etməyən adi IP-lərə qoşulmağa icazə verilir. Bu, istifadəçiyə I2P-nin anonimləşdirilmə maraqlı deyilsə, lakin yenə də I2P iştirakçılarına qoşulmaq istədiyi halda faydalı ola bilər.</p></body></html>
-
+
Mixed mode
Qarışıq rejim
-
+
Some options are incompatible with the chosen proxy type!
Bəzi parametrlıər seçilmiş proksi növü ilə uyğun gəlmir!
-
+
If checked, hostname lookups are done via the proxy
Əgər işarələnərsə, host adı axtarışı proksi ilə icra olunur.
-
+
Perform hostname lookup via proxy
Proksi vasitəsilə host adı axtarışını icra etmək
-
+
Use proxy for BitTorrent purposes
Proksini BitTorrent məqsədləri üçün istifadə et
-
+
RSS feeds will use proxy
RSS xəbər lentləri proksi istifadə edəcək
-
+
Use proxy for RSS purposes
RSS məqsədləri üçün proksi istifadə et
-
+
Search engine, software updates or anything else will use proxy
Axtarış mühərriki, proqram təminatı yenilənmələri və başqaları proksi istifdə edəcək
-
+
Use proxy for general purposes
Əsas məqsədlər üçün proksi istifadə et
-
+
IP Fi<ering
İP fi<irləmə
-
+
Schedule &the use of alternative rate limits
Alternativ sürət limitinin istifadəsini planlaşdırmaq
-
+
From:
From start time
Bu vaxtdan:
-
+
To:
To end time
Bu vaxta:
-
+
Find peers on the DHT network
DHT şəbəkəsindəki iştirakçıları tapmaq
-
+
Allow encryption: Connect to peers regardless of setting
Require encryption: Only connect to peers with protocol encryption
Disable encryption: Only connect to peers without protocol encryption
@@ -5866,140 +6050,135 @@ Disable encryption: Only connect to peers without protocol encryption
Şifrələməni söndürmək: İştirakşılara yalnız şifrələmə protokolu olmadan qoşulmaq
-
+
Allow encryption
Şifrələməyə icazə vermək
-
+
(<a href="https://github.com/qbittorrent/qBittorrent/wiki/Anonymous-Mode">More information</a>)
(<a href="https://github.com/qbittorrent/qBittorrent/wiki/Anonymous-Mode">Daha ətraflı</a>)
-
+
Maximum active checking torrents:
Maksimum aktiv torrent yoxlamaları:
-
+
&Torrent Queueing
&Torrent növbələnməsi
-
+
When total seeding time reaches
Ümumi göndərmə həddinə çatdıqda
-
+
When inactive seeding time reaches
Qeyri-aktiv göndərmə həddinə çatdıqda
-
- A&utomatically add these trackers to new downloads:
- Bu izləyiciləri a&vtomatik yükləmələrə əlavə edin:
-
-
-
+
RSS Reader
RSS Oxuyucu
-
+
Enable fetching RSS feeds
RSS lentlərinin alınmasını aktiv etmək
-
+
Feeds refresh interval:
Lentlərin yenilənmə intervalı:
-
+
+ Same host request delay:
+ Eyni host tələbi gecikməsi:
+
+
+
Maximum number of articles per feed:
Hər iştirakçıya ən çox məqalə sayı:
-
-
-
+
+
+
min
minutes
dəq
-
+
Seeding Limits
Paylaşım limitləri
-
- Pause torrent
- Torrentə fasilə
-
-
-
+
Remove torrent
Torrenti silmək
-
+
Remove torrent and its files
Torrenti ə fayllarını silmək
-
+
Enable super seeding for torrent
Torrent üçün super göndərişi aktivləşdirmək
-
+
When ratio reaches
Göstəricini aşdıqda
-
+
RSS Torrent Auto Downloader
RSS torrent avto yükləyici
-
+
Enable auto downloading of RSS torrents
RSS torrentlərinin avtomatik yüklənməsini aktiv etmək
-
+
Edit auto downloading rules...
Avtomatik yükləmə qaydalarına düzəliş...
-
+
RSS Smart Episode Filter
RSS Ağıllı Bölmə Filtri
-
+
Download REPACK/PROPER episodes
REPACK/PROPER bölümlərini endirmək
-
+
Filters:
Filtrlər:
-
+
Web User Interface (Remote control)
Veb İstifadəçi İnterfeysi (Uzaqdan idarəetmə)
-
+
IP address:
İP ünvanları:
-
+
IP address that the Web UI will bind to.
Specify an IPv4 or IPv6 address. You can specify "0.0.0.0" for any IPv4 address,
"::" for any IPv6 address, or "*" for both IPv4 and IPv6.
@@ -6007,85 +6186,85 @@ Specify an IPv4 or IPv6 address. You can specify "0.0.0.0" for any IPv
İPv4 və ya İPv6 ünvanı göstərin. Siz hər hansı İPv4 ünvanı üçün "0.0.0.0", hər hansı İPv6 ünvanı üçün "::", və ya İPv4 və İPv6-lərin hər ikisi üçün "*" göstərə bilərsiniz.
-
+
Ban client after consecutive failures:
Belə ardıcıl xətalardan sonra müştərini bloklamaq:
-
+
Never
Heç vaxt
-
+
ban for:
bundan sonra bloklamaq:
-
+
Session timeout:
Sessiya bitmə vaxtı:
-
+
Disabled
Söndürülüb
-
+
Enable cookie Secure flag (requires HTTPS)
Kukilərin təhlükəsizliyini aktiv etmək (HTTPS tələb olunur)
-
+
Server domains:
Server domenləri:
-
+
Whitelist for filtering HTTP Host header values.
In order to defend against DNS rebinding attack,
you should put in domain names used by WebUI server.
Use ';' to split multiple entries. Can use wildcard '*'.
HTTP Host başlıqlarının göstəricilərini filtrləmək üçün ağ siyahı.
-DNS ilə təkrar bağlantı hücumundan qorunmaq üçün WebUI
+DNS ilə təkrar bağlantı hücumundan qorunmaq üçün WebUI
serveri tərəfindən istifadə olunan domen adını göstərməlisiniz.
Çoxsaylı elementləri bölmək üçün ';' istifadə edin. '*' ümumi nişanından istifadə edə bilərsiniz
-
+
&Use HTTPS instead of HTTP
HTTP əvəzinə HTTPS &istifadə edin
-
+
Bypass authentication for clients on localhost
Locahosst-da müştəri üçün kimlik doğrulamasını ötürmək
-
+
Bypass authentication for clients in whitelisted IP subnets
İP alt şəbəkələri ağ siyahısında müştəri üçün kimlik doğrulamasını ötürmək
-
+
IP subnet whitelist...
İP al şəbəkəsi ağ siyahısı...
-
+
Specify reverse proxy IPs (or subnets, e.g. 0.0.0.0/24) in order to use forwarded client address (X-Forwarded-For header). Use ';' to split multiple entries.
Yönləndirilmiş müştəri ünvanından (X-Forwarded-For header) istifadə etmək üçün əks proxy IP-lərini (və ya alt şəbəkələri, məs., 0.0.0.0/24) göstərin. Birdən çox girişi bölmək üçün ';' işarəsindən istifadə edin.
-
+
Upda&te my dynamic domain name
Dinamik domen adını ¥iləmək
-
+
Minimize qBittorrent to notification area
qBittorrent-i bildiriş çubuğuna endirmək
@@ -6100,180 +6279,180 @@ serveri tərəfindən istifadə olunan domen adını göstərməlisiniz.
Dil:
-
+
Tray icon style:
Trey nişanı tərzi:
-
-
+
+
Normal
Normal
-
+
File association
Fayl əlaqələri
-
+
Use qBittorrent for .torrent files
Torrent faylları üçün qBittorrent-i istifadə etmək
-
+
Use qBittorrent for magnet links
Maqnit keçidlər üçün qBittorrent-i istifadə etmək
-
+
Check for program updates
Proqramın yeni versiyasını yoxlamaq
-
+
Power Management
Enerjiyə Nəzarət
-
+
Save path:
Saxlama yolu:
-
+
Backup the log file after:
Bundan sonra jurnal faylını yedəkləmək:
-
+
Delete backup logs older than:
Bundan köhnə jurnal fayllarını silmək:
-
+
When adding a torrent
Torrent əlavə edildikdə:
-
+
Bring torrent dialog to the front
Torrent dialoqunu ön plana çıxarmaq
-
+
Also delete .torrent files whose addition was cancelled
Həmçinin əlavə edilməsi ləğv olunan .torrent fayllarını silmək
-
+
Also when addition is cancelled
Həmçinin əlavə edilməsi ləğv edildikdə
-
+
Warning! Data loss possible!
Xəbərdarlıq! Verilənlərin itirilə bilər!
-
+
Saving Management
Yaddaşa yazılmanın idarə edilməsi
-
+
Default Torrent Management Mode:
Standart Torrent İdarəetmə Rejimi:
-
+
Manual
Əl ilə
-
+
Automatic
Avtomatik
-
+
When Torrent Category changed:
Torrent Kateqoriyaları dəyişdirildikdə:
-
+
Relocate torrent
Torrentin yerini dəyişmək
-
+
Switch torrent to Manual Mode
Torrenti əl ilə idarə rrejiminə keçirmək
-
-
+
+
Relocate affected torrents
Təsirə məruz qalan torrentlərin yerini dəyişmək
-
-
+
+
Switch affected torrents to Manual Mode
Təsirə məruz qalan torrentləri əl ilə idarə rejiminə keçirmək
-
+
Use Subcategories
Alt kateqoriyaları istifadə etmək
-
+
Default Save Path:
Standart saxlama yolu:
-
+
Copy .torrent files to:
Torrent fayllarını buraya kopyalamaq:
-
+
Show &qBittorrent in notification area
&qBittorrenti bu bildiriş sahəsində göstərmək:
-
+
&Log file
Jurna&l faylı
-
+
Display &torrent content and some options
&Torrent tərkibini və bəzi seçimləri göstərmək
-
+
De&lete .torrent files afterwards
Əlavə edildikdən sonra torrent fayllarını si&lmək
-
+
Copy .torrent files for finished downloads to:
Bitmiş yükləmələr üçün .torrent fayllarını buraya kopyalamq:
-
+
Pre-allocate disk space for all files
Bütün fayllar üçün əvvəlcədən yer ayırmaq
-
+
Use custom UI Theme
Başqa İstifadəçi interfeysi mövzusu istifadə etmək
-
+
UI Theme file:
İİ mövzusu faylı:
@@ -6283,214 +6462,214 @@ serveri tərəfindən istifadə olunan domen adını göstərməlisiniz.
İnterfeys ayarlarının dəyişdirilməsi tətbiqi yenidən başlatmağı tələb edir
-
+
Shows a confirmation dialog upon torrent deletion
Torrentin silinməsinin təsdiq edilməsi dialoqunu göstərir
-
-
+
+
Preview file, otherwise open destination folder
Fayla öncədən baxış, əksa halda təyinat qovluğunu açmaq
-
-
+
+
Show torrent options
Torrent parametrlərini göstərmək
-
+
Shows a confirmation dialog when exiting with active torrents
Aktiv torrentlər olduqda tətbiqdən çıxarkən, çıxışı təsdiq etmək
-
+
When minimizing, the main window is closed and must be reopened from the systray icon
Yığıldıqda əsas pəncərə bağlanır və onu sistem treyindən yenidən açmaq olar
-
+
The systray icon will still be visible when closing the main window
Əsas pəncərə bağlandıqda treydəki nişanı hələ də görünəcəkdir
-
+
Close qBittorrent to notification area
The systray icon will still be visible when closing the main window
qBittorrent-i bildiriş çubuğuna endirmək
-
+
Monochrome (for dark theme)
Monoxrom (qara mövzu üçün)
-
+
Monochrome (for light theme)
Monoxrom (işıqlı mövzu üçün)
-
+
Inhibit system sleep when torrents are downloading
Torrentlər endirilən zaman komputerin yuxu rejiminə keçməsini əngəlləmək
-
+
Inhibit system sleep when torrents are seeding
Torrentlər paylaşılarkən komputerin yuxu rejiminə keçməsini əngəlləmək
-
+
Creates an additional log file after the log file reaches the specified file size
Jurnal faylı göstərilmiş ölçüyə çatdıqda sonra əlavə jurnal faylı yaradılır
-
+
days
Delete backup logs older than 10 days
günlər
-
+
months
Delete backup logs older than 10 months
aylar
-
+
years
Delete backup logs older than 10 years
illər
-
+
Log performance warnings
Performans xəbərdarlıqlarını qeydə alamaq
-
- The torrent will be added to download list in a paused state
- Torrent, fasilə vəziyyətində yükləmə siyahısına əlavə ediləcək
-
-
-
+
Do not start the download automatically
- The torrent will be added to download list in a paused state
+ The torrent will be added to download list in a stopped state
Endirməni avtomatik başlatmamaq
-
+
Whether the .torrent file should be deleted after adding it
Əlavə edildikdən sonra .torrent faylın silinib silinməməsi
-
+
Allocate full file sizes on disk before starting downloads, to minimize fragmentation. Only useful for HDDs.
Daha çox hissələrə bölünmənin qarşısını almaq üçün diskdə tam fayl ölçüsündə yer ayrılır. Yalnız HDD-lər (Sərt Disklər) üçün yararlıdır.
-
+
Append .!qB extension to incomplete files
Tamamlanmamış fayllara .!qB uzantısı əlavə etmək
-
+
When a torrent is downloaded, offer to add torrents from any .torrent files found inside it
Torrent endirilən zaman onun daxilindəki .torrent fayllarını endirməyi təklif etmək
-
+
Enable recursive download dialog
Təkrarlanan yükləmə dialoqunu aktiv etmək
-
+
Automatic: Various torrent properties (e.g. save path) will be decided by the associated category
Manual: Various torrent properties (e.g. save path) must be assigned manually
Avtomatik: Müxtəlif torrent xüsusiyyətləri (məs., saxlama yolu) əlaqəli kateqoriyalar tərəfindən təyin ediləcəkdir.
Əl ilə: Müxtəlif torrent xüsusiyyətləri (məs., saxlama yolu) əl ilə daxil edilməlidir
-
+
When Default Save/Incomplete Path changed:
Standart saxlam/tamamlanmamış yolu dəyişdirildiyi zaman:
-
+
When Category Save Path changed:
Saxlama Yolu Kateqoriyası dəyişdirildiyində:
-
+
Use Category paths in Manual Mode
Kateqoriya yollarını Əl ilə Rejimində istifadə edin
-
+
Resolve relative Save Path against appropriate Category path instead of Default one
Nisbi saxlama yolunu, standarta yola görə deyil, uyğun kateqriya yoluna görə təyin edin
-
+
Use icons from system theme
Sistem mövzusundakı nişandan istifadə etmək.
-
+
+ Stopped torrents only
+
+
+
+
Window state on start up:
Sistem açıldıqda pəncərnin vəziyyəti:
-
+
qBittorrent window state on start up
Sistemin açılışında qBittorrent pəncərəsinin vəziyyəti
-
+
Torrent stop condition:
Torrentin dayanma vəziyyəti:
-
-
+
+
None
Heç nə
-
-
+
+
Metadata received
Meta məlumatları alındı
-
-
+
+
Files checked
Fayllar yoxlanıldı
-
+
Ask for merging trackers when torrent is being added manually
Torrent əl ilə əlavə olunduqda izləyicilərin birləşdirilməsini soruşmaq
-
+
Use another path for incomplete torrents:
Tamamlanmamış torrentlər üçün başqa yoldan istifadə edin:
-
+
Automatically add torrents from:
Torrenti buradan avtomatik əlavə etmək:
-
+
Excluded file names
Fayl adları istisna edilir
-
+
Blacklist filtered file names from being downloaded from torrent(s).
Files matching any of the filters in this list will have their priority automatically set to "Do not download".
@@ -6520,765 +6699,803 @@ readme.txt: dəqiq fayl adını seçir.
readme[0-9].txt: "readme1ştxt", "readme2ştxt"-ni seçir, lakin "readme10.txt"-ni seçmir.
-
+
Receiver
Qəbuledici
-
+
To:
To receiver
Buraya:
-
+
SMTP server:
SMTP server:
-
+
Sender
Göndərən
-
+
From:
From sender
Buradan:
-
+
This server requires a secure connection (SSL)
Bu server təhlükəsiz bağlantı (SSL) tələb edir
-
-
+
+
Authentication
Kimlik doğrulaması
-
-
-
-
+
+
+
+
Username:
İstifadəçi adı:
-
-
-
-
+
+
+
+
Password:
Şifrə:
-
+
Run external program
Xarici proqramı başladın
-
+
Run on torrent added
Torrent əlavə edildikdə başlatmaq
-
+
Run on torrent finished
Torrent tamamlandlqda başlatmaq
-
+
Show console window
Konsol pəncərəsini göstərmək
-
+
TCP and μTP
TCP və μTP
-
+
Listening Port
Dinlənilən port
-
+
Port used for incoming connections:
Daxil olan bağlantılar üçün istifadə olunan port
-
+
Set to 0 to let your system pick an unused port
Dəyəri 0 təyin edin ki, sistem istifadə olunmayan portu seçsin
-
+
Random
Təsadüfi
-
+
Use UPnP / NAT-PMP port forwarding from my router
UPnP / NAT-PMP portlarının yönləndirməsi üçün routerimdən istifadə etmək
-
+
Connections Limits
Bağlantı limiti
-
+
Maximum number of connections per torrent:
Hər torrent üçün ən çox bağlantı limiti:
-
+
Global maximum number of connections:
Ən çox ümumi bağlantı sayı:
-
+
Maximum number of upload slots per torrent:
Hər torrent üçün ən çox göndərmə yuvası sayı:
-
+
Global maximum number of upload slots:
Ən çox ümumi göndərmə yuvaları sayı:
-
+
Proxy Server
Proksi server:
-
+
Type:
Növ:
-
+
SOCKS4
SOCKS4
-
+
SOCKS5
SOCKS5
-
+
HTTP
HTTP
-
-
+
+
Host:
Host:
-
-
-
+
+
+
Port:
Port:
-
+
Otherwise, the proxy server is only used for tracker connections
Əks halda proksi server yalnız izləyici bağlantıları üçün istifadə olunur
-
+
Use proxy for peer connections
Proksi serveri, iştirakçı bağlantıları üçün istifadə etmək
-
+
A&uthentication
Kimlik doğr&ulaması
-
+
Info: The password is saved unencrypted
Məlumat: Parol, şifrələnməmiş şəkildə saxlanıldı
-
+
Filter path (.dat, .p2p, .p2b):
Filtr yolu (.dat, .p2p, .p2b):
-
+
Reload the filter
Filtri təkrarlamaq
-
+
Manually banned IP addresses...
İstifadəçinin qadağan etdiyi İP ünvanları...
-
+
Apply to trackers
İzləyicilərə tətbiq etmək
-
+
Global Rate Limits
Ümumi sürət limitləri
-
-
-
-
-
-
-
+
+
+
+
+
+
+
∞
∞
-
-
-
-
-
-
+
+
+
+
+
+
KiB/s
KB/san
-
-
+
+
Upload:
Göndərmə:
-
-
+
+
Download:
Yükləmə:
-
+
Alternative Rate Limits
Alternativ sürət limitləri
-
+
Start time
Başlama vaxtı
-
+
End time
Bitmə tarixi
-
+
When:
Nə zaman:
-
+
Every day
Hər gün
-
+
Weekdays
Həftəiçi:
-
+
Weekends
Həstə sonları:
-
+
Rate Limits Settings
Sürət limitləri ayarları
-
+
Apply rate limit to peers on LAN
Sürət limitini LAN şəbəkəsindəki hər iştirakçıya tətbiq etmək
-
+
Apply rate limit to transport overhead
Sürət limitini trafik mübadiləsinə tətbiq etmək
-
+
Apply rate limit to µTP protocol
Sürət limitini µTP protokoluna tətbiq etmək
-
+
Privacy
Məxfi
-
+
Enable DHT (decentralized network) to find more peers
Daha çox iştirakçılar tapmaq üçün DHT (mərkəzləşməmiş şəbəkə) aktiv etmək
-
+
Exchange peers with compatible Bittorrent clients (µTorrent, Vuze, ...)
İştirakçıları uyğun qBittorrent müştəriləri ilə əvəzləmək (µTorrent, Vuze, ...)
-
+
Enable Peer Exchange (PeX) to find more peers
Daha çox iştirakçılar tapmaq üçün İştirakçı mübadiləsini (PeX) aktiv etmək
-
+
Look for peers on your local network
Yerli şəbəkədəki iştirakçıları axtarmaq
-
+
Enable Local Peer Discovery to find more peers
Daha çox iştirakçılar tapmaq üçün Yerli İştirakçı Axtarışını aktiv etmək
-
+
Encryption mode:
Şifrələmə rejimi:
-
+
Require encryption
Şifrələmə tələbi
-
+
Disable encryption
Şifrələməni söndürmək:
-
+
Enable when using a proxy or a VPN connection
Proksi və ya VPN bağlantıları istifadə oluduqda
-
+
Enable anonymous mode
Anonim rejimi aktiv etmək
-
+
Maximum active downloads:
Ən çox aktiv yükləmələr:
-
+
Maximum active uploads:
Ən çox aktiv göndərmələr:
-
+
Maximum active torrents:
Ən çox aktiv torrentlər:
-
+
Do not count slow torrents in these limits
Bu limitlərdə yavaş torrentləri saymamaq
-
+
Upload rate threshold:
Göndərmə sürəti həddi:
-
+
Download rate threshold:
Yükləmə sürəti həddi:
-
-
-
+
+
+
+
sec
seconds
san
-
+
Torrent inactivity timer:
Torrent boşdayanma zamanlayıcısı:
-
+
then
sonra
-
+
+ Stop torrent
+
+
+
+
+ A&utomatically append these trackers to new downloads:
+
+
+
+
Use UPnP / NAT-PMP to forward the port from my router
UPnP / NAT-PMP portlarının yönləndirməsi üçün routerimdən istifadə etmək
-
+
Certificate:
Sertifikat:
-
+
Key:
Açar:
-
+
<a href=https://httpd.apache.org/docs/current/ssl/ssl_faq.html#aboutcerts>Information about certificates</a>
<a href=https://httpd.apache.org/docs/current/ssl/ssl_faq.html#aboutcerts>sertifikatlar haqqında məlumat</a>
-
+
Change current password
Hazırkı şifrəni dəyişmək
-
+
Use alternative Web UI
Alternativ Web İstifadəçi İnterfeysindən istifadə etmək
-
+
Files location:
Fayl yerləşməsi:
-
+
Security
Təhlükəsizlik
-
+
Enable clickjacking protection
Klikdən sui-istifadənin qarşısının alınmasını aktiv etnək
-
+
Enable Cross-Site Request Forgery (CSRF) protection
Saytlar arası sorğuların saxtalaşdırılmasından (CSRF) mühafizəni aktiv etmək
-
+
Enable Host header validation
Host başlığı doğrulamasını aktiv etmək
-
+
Add custom HTTP headers
Başqa HTTP başlıqları əlavə etmək
-
+
Header: value pairs, one per line
Başlıq: hər sətir başına bir dəyər cütü
-
+
Enable reverse proxy support
Əks proksi dəstəklənməsini açın
-
+
Trusted proxies list:
Etibarlı proksilər siyahısı:
-
+
Service:
Xidmət:
-
+
Register
Qeydiyyat
-
+
Domain name:
Domen adı:
-
+
By enabling these options, you can <strong>irrevocably lose</strong> your .torrent files!
Bu seçimi aktiv etmək torrent fayllarınızı <strong>birdəfəlik itirmək</strong> ilə nəticələnə bilər!
-
+
If you enable the second option (“Also when addition is cancelled”) the .torrent file <strong>will be deleted</strong> even if you press “<strong>Cancel</strong>” in the “Add torrent” dialog
İkinci seçimi aktiv etdikdə (“Həmçinin əlavə edilmə ləğv edildikdə”) torrent faylları hətta “Torrent əlavə etmək” dialoqunda “<strong>İmtina</strong>” vurduqda belə <strong>silinəcəkdir</strong>
-
+
Select qBittorrent UI Theme file
qBittorrent İstifadəçi İnterfeysi mövzusu faylını seçmək
-
+
Choose Alternative UI files location
Alternativ İİ faylları yerini seçmək
-
+
Supported parameters (case sensitive):
Dəstəklnən parametrlər (böyük-kiçik hərflərə həssas)
-
+
Minimized
Yığılmış
-
+
Hidden
Gizli
-
+
Disabled due to failed to detect system tray presence
Sistem çəkməcəsinin mövcudluğunu aşkar edə bilmədiyinə görə söndürüldü
-
+
No stop condition is set.
Dayanma vəziyyəti təyin edilməyib.
-
+
Torrent will stop after metadata is received.
Meta məlumatları alındıqdan sonra torrent dayanacaq.
-
- Torrents that have metadata initially aren't affected.
- İlkin meta məlumatları olan torrentlər dəyişilməz qalır.
-
-
-
+
Torrent will stop after files are initially checked.
Faylların ilkin yoxlanışından sonra torrrent daynacaq.
-
+
This will also download metadata if it wasn't there initially.
Əgər başlanğıcda meta məlumatlar olmasa onlar da yüklənəcək.
-
+
%N: Torrent name
%N: Torrentin adı
-
+
%L: Category
%L: Kateqoriyası
-
+
%F: Content path (same as root path for multifile torrent)
%F: Məzmun yolu (çoxsaylı torrentlər üçün kök (root) yolu kimi)
-
+
%R: Root path (first torrent subdirectory path)
%R: Kök (root) yolu (ilk torrent alt qovluqları yolu)
-
+
%D: Save path
%D: Saxlama yolu
-
+
%C: Number of files
%C: Faylların sayı
-
+
%Z: Torrent size (bytes)
%Z: Torrentin ölçüsü (bayt)
-
+
%T: Current tracker
%T: Cari izləyici
-
+
Tip: Encapsulate parameter with quotation marks to avoid text being cut off at whitespace (e.g., "%N")
Növ: Mətni, ara boşluğunda kəsilmələrndən qorumaq üçün parametrləri dırnaq işarəsinə alın (məs., "%N")
-
+
+ Test email
+
+
+
+
+ Attempted to send email. Check your inbox to confirm success
+
+
+
+
(None)
(Heç nə)
-
+
A torrent will be considered slow if its download and upload rates stay below these values for "Torrent inactivity timer" seconds
Bir torrent endirmə və göndərmə sürəti, "Torrent boşdayanma zamanlayıcısı"nın saniyələrlə dəyərindən az olarsa, o, yavaş torrent hesab olunacaq
-
+
Certificate
Sertifikat
-
+
Select certificate
Sertifakatı seçin
-
+
Private key
Məxfi açar
-
+
Select private key
Məxfi açarı seçin
-
+
WebUI configuration failed. Reason: %1
Veb İİ tənzimləməsini dəyişmək mümkün olmadı. Səbəb: %1
-
+
+ %1 is recommended for best compatibility with Windows dark mode
+ Fusion is recommended for best compatibility with Windows dark mode
+
+
+
+
+ System
+ System default Qt style
+
+
+
+
+ Let Qt decide the style for this system
+
+
+
+
Select folder to monitor
İzləmək üçün qovluğu seçin
-
+
Adding entry failed
Girişin əlavə edilməsi alınmadı
-
+
The WebUI username must be at least 3 characters long.
Veb İİ istifadəçi adı ən az 3 işarədən ibarət olmalıdır.
-
+
The WebUI password must be at least 6 characters long.
Veb İİ şifrəsi ən az 6 işarədən ibarət olmalıdır.
-
+
Location Error
Yerləşmə xətası
-
-
+
+
Choose export directory
İxrac qovluğunu seçmək
-
+
When these options are enabled, qBittorrent will <strong>delete</strong> .torrent files after they were successfully (the first option) or not (the second option) added to its download queue. This will be applied <strong>not only</strong> to the files opened via “Add torrent” menu action but to those opened via <strong>file type association</strong> as well
Bu seçim aktiv olduqda qBittorrent, yükləmə növbəsinə uğurla əlavə olunduqdan (ilk seçim) və ya olunmadıqdan (ikinci seçim) sonra, .torrent fayllarını <strong>siləcək</strong>. Bu sadəcə “Torrent əlavə etmək” menyusu vasitəsi ilə açılmış fayllara <strong>deyil</strong>, həmçinin, <strong>fayl növü əlaqələri</strong> vasitəsi ilə açılanlara da tətbiq ediləcəkdir
-
+
qBittorrent UI Theme file (*.qbtheme config.json)
qBittorrent İİ mövzusu faylı (*.qbtheme config.json)
-
+
%G: Tags (separated by comma)
%G: Etiketlər (vergüllə ayrılmış)
-
+
%I: Info hash v1 (or '-' if unavailable)
%I: Məlumat heş'i v1 (və ya əgər əlçatmazdırsa '-')
-
+
%J: Info hash v2 (or '-' if unavailable)
%J: məlumat heş'i v2 (və ya əgər əlçatmazdırsa '-')
-
+
%K: Torrent ID (either sha-1 info hash for v1 torrent or truncated sha-256 info hash for v2/hybrid torrent)
%K: Torrent İD-si (ya məlumat heş'i sha-1 v1 üçün və ya v2/hibrid torrenti üçün qısaldılmış sha-256 məlumat heş' i)
-
-
-
+
+
+
Choose a save directory
Saxlama qovluğunu seçmək
-
+
+ Torrents that have metadata initially will be added as stopped.
+ Əvvəlcədən meta məlumatlara malik olan torrentlər dayandırılmış kimi əılavə ediləcək.
+
+
+
Choose an IP filter file
İP filtri faylını seçmək
-
+
All supported filters
Bütün dəstəklənən filtrlər
-
+
The alternative WebUI files location cannot be blank.
Alternativ Veb İİ faylları üçün boş ola bilməz.
-
+
Parsing error
Təhlil xətası
-
+
Failed to parse the provided IP filter
Təqdim olunan İP filtrinin təhlil baş tutmadı
-
+
Successfully refreshed
Uğurla təzələndi
-
+
Successfully parsed the provided IP filter: %1 rules were applied.
%1 is a number
Təqdim olunan İP filtri uğurla təhlil olundu: %1 qayda tətbiq olundu.
-
+
Preferences
Tərcihlər
-
+
Time Error
Vaxt xətası
-
+
The start time and the end time can't be the same.
Başlama və bitmə vaxtı eyni ola bilməz.
-
-
+
+
Length Error
Ölçü xətası
@@ -7286,80 +7503,85 @@ readme[0-9].txt: "readme1ştxt", "readme2ştxt"-ni seçir, l
PeerInfo
-
+
Unknown
Naməlum
-
+
Interested (local) and choked (peer)
Maraqlanan (müştəri) və məşğul (iştirakçı)
-
+
Interested (local) and unchoked (peer)
Maraqlanmır (müştəri) və məğul deyil (iştirakçı)
-
+
Interested (peer) and choked (local)
Maraqlanan (iştirakçı) və məşğuldur (müştəri)
-
+
Interested (peer) and unchoked (local)
Maraqlanmır (iştirakçı) və məşğul deyil (müştəri)
-
+
Not interested (local) and unchoked (peer)
Maraqlanmır (müştəri) və məşğul deyil (iştirakçı)
-
+
Not interested (peer) and unchoked (local)
Maraqlanmır (iştirakşı) və məşğul deyil (müştəri)
-
+
Optimistic unchoke
Tezliklə endirilməyə başlanacaq
-
+
Peer snubbed
İştirakçıya irad tutuldu
-
+
Incoming connection
Daxil olan bağlantı
-
+
Peer from DHT
DHT-dən iştirakçı
-
+
Peer from PEX
PEX-dən iştirakçı
-
+
Peer from LSD
LSD-dən iştirakçı
-
+
Encrypted traffic
Şifrələnmiş trafik
-
+
Encrypted handshake
Şifrələnmiş görüşmə
+
+
+ Peer is using NAT hole punching
+
+
PeerListWidget
@@ -7579,27 +7801,27 @@ readme[0-9].txt: "readme1ştxt", "readme2ştxt"-ni seçir, l
PiecesBar
-
+
Files in this piece:
Bu hissədəki fayllar:
-
+
File in this piece:
Bu hissədəki fayl:
-
+
File in these pieces:
Bu hissələrdəki fayl:
-
+
Wait until metadata become available to see detailed information
Ətraflı məlumatı görmək üçün meta verilənlərinin daxil olmasını gözləyin
-
+
Hold Shift key for detailed information
Ətraflı məlumat üçün Shift düyməsini basıb saxlayın
@@ -7887,27 +8109,27 @@ Bu qoşmalar söndürülüb.
Private::FileLineEdit
-
+
Path does not exist
Yol mövcud deyil
-
+
Path does not point to a directory
Yol qovluğu göstərmir
-
+
Path does not point to a file
Yol fayla aparmır
-
+
Don't have read permission to path
Yol üçün oxumaq icazəsi yoxdur
-
+
Don't have write permission to path
Yol üçün yazmaq icazəsi yoxdur
@@ -7948,7 +8170,7 @@ Bu qoşmalar söndürülüb.
PropertiesWidget
-
+
Downloaded:
Endirilən:
@@ -7968,28 +8190,28 @@ Bu qoşmalar söndürülüb.
Köçürmə
-
+
Time Active:
- Time (duration) the torrent is active (not paused)
+ Time (duration) the torrent is active (not stopped)
Aktivlik müddəti:
-
+
ETA:
Qalan Vaxt:
-
+
Uploaded:
Göndərilən:
-
+
Seeds:
Göndərənlər:
-
+
Download Speed:
Endirmə sürəti:
@@ -8009,12 +8231,12 @@ Bu qoşmalar söndürülüb.
Endirmə limiti:
-
+
Upload Limit:
Göndərmə limiti:
-
+
Wasted:
İtirilən:
@@ -8024,32 +8246,32 @@ Bu qoşmalar söndürülüb.
Bağlantılar
-
+
Information
Məlumat
-
+
Info Hash v1:
Məlumat heş'i v1:
-
+
Info Hash v2:
Məlumat heş'i v2:
-
+
Comment:
Şərh:
-
+
Select All
Hamısını seçmək
-
+
Select None
Heç birini seçməmək
@@ -8059,158 +8281,185 @@ Bu qoşmalar söndürülüb.
Paylaşım nisbəti:
-
+
Reannounce In:
Növbəti anons:
-
+
Last Seen Complete:
Son görünən tamamlanmış:
-
+
+
+ Ratio / Time Active (in months), indicates how popular the torrent is
+
+
+
+
+ Popularity:
+
+
+
+
Total Size:
Ümumi ölçüsü:
-
+
Pieces:
Hissələr:
-
+
Created By:
Yaradan:
-
+
Added On:
Əlavə edilib:
-
+
Completed On:
Tamamlanıb:
-
+
Created On:
Yaradılıb:
-
+
+ Private:
+
+
+
+
Save Path:
Saxlama yolu:
-
+
Never
Heç zaman
-
+
%1 x %2 (have %3)
(torrent pieces) eg 152 x 4MB (have 25)
%1 x %2 (%3 var)
-
-
+
+
%1 (%2 this session)
%1 (%2 bu sesiyada)
-
-
+
+
+
N/A
Əlçatmaz
-
+
+ Yes
+ Bəli
+
+
+
+ No
+ Xeyr
+
+
+
%1 (seeded for %2)
e.g. 4m39s (seeded for 3m10s)
%1 (%2 üçün göndərilmə)
-
+
%1 (%2 max)
%1 and %2 are numbers, e.g. 3 (10 max)
%1 (%2 ən çox)
-
-
+
+
%1 (%2 total)
%1 and %2 are numbers, e.g. 3 (10 total)
%1 (%2 ümumi)
-
-
+
+
%1 (%2 avg.)
%1 and %2 are speed rates, e.g. 200KiB/s (100KiB/s avg.)
%1 (%2 orta.)
-
+
New Web seed
Yeni veb göndərimi
-
+
Remove Web seed
Veb göndərimini silmək
-
+
Copy Web seed URL
Veb göndərim keçidini kopyalamaq
-
+
Edit Web seed URL
Veb göndərim keçidinə düzəliş
-
+
Filter files...
Faylları filtrləmək...
-
+
Speed graphs are disabled
Tezlik qrafiki söndürülüb
-
+
You can enable it in Advanced Options
Siz bunu Əlavə Seçimlər-də aktiv edə bilərsiniz
-
+
New URL seed
New HTTP source
Yeni URL göndərimi
-
+
New URL seed:
Yeni URL göndərimi:
-
-
+
+
This URL seed is already in the list.
Bu YRL göndərimi artıq bu siyahıdadır.
-
+
Web seed editing
Veb göndəriminə düzəliş edilir
-
+
Web seed URL:
Veb göndərim URL-u:
@@ -8252,22 +8501,22 @@ Bu qoşmalar söndürülüb.
RSS::Feed
-
+
Failed to download RSS feed at '%1'. Reason: %2
RSS lentini "%1"-də/da yükləmək baş tutmadı. Səbəb: %2
-
+
RSS feed at '%1' updated. Added %2 new articles.
RSS lenti "%1"-də/da yeniləndi. %2 yeni məqalə əlavə edildi.
-
+
Failed to parse RSS feed at '%1'. Reason: %2
RSS lentini "%1"-də/da analiz etmək baş alınmadı. Səbəb: %2
-
+
RSS feed at '%1' is successfully downloaded. Starting to parse it.
RSS lenti "%1"-də/da uğurla yükləndi. Təhlili başlayır.
@@ -8303,12 +8552,12 @@ Bu qoşmalar söndürülüb.
RSS::Private::Parser
-
+
Invalid RSS feed.
Səhv RSS lenti.
-
+
%1 (line: %2, column: %3, offset: %4).
%1 (sətir: %2, sütun: %3, sürüşmə: %4).
@@ -8316,99 +8565,99 @@ Bu qoşmalar söndürülüb.
RSS::Session
-
+
Couldn't save RSS session configuration. File: "%1". Error: "%2"
RSS sessiyası tənzimləməsi saxlanıla bilmədi. Fayl: "%1". Xəta:"%2"
-
+
Couldn't save RSS session data. File: "%1". Error: "%2"
RSS sessiyası verilənləri saxlanıla bilmədi. Fayl: "%1". Xəta: "%2"
-
-
+
+
RSS feed with given URL already exists: %1.
Verilmiş URL ilə RSS lenti artıq mövcuddur: %1
-
+
Feed doesn't exist: %1.
Xəbər lenti mövcud deyil: %1
-
+
Cannot move root folder.
Kök (root) qovluğu köçürülə bilmir.
-
-
+
+
Item doesn't exist: %1.
Element tapılmadı: %1.
-
+
Couldn't move folder into itself.
Qovluğu öz daxilinə köçürmək mümkün deyil
-
+
Cannot delete root folder.
Kök qovluğu silinə bilmir.
-
+
Failed to read RSS session data. %1
RSS sesiya verilənlərini oxumaq mümkün olmadı. %1
-
+
Failed to parse RSS session data. File: "%1". Error: "%2"
RSS sesiya verilənlərini həll etmək mümkün olmadı. Fayl: "%1". Xəta: "%2"
-
+
Failed to load RSS session data. File: "%1". Error: "Invalid data format."
RSS sesiya verilənlərini yükləmək mümkün olmadı. Fayl: "%1". Xəta: "Səhv verilənlər formatı."
-
+
Couldn't load RSS feed. Feed: "%1". Reason: URL is required.
RSS xəbər lenti yüklənə bilmədi. Xəbər lenti: "%1". Səbəb: URL tələb olunur.
-
+
Couldn't load RSS feed. Feed: "%1". Reason: UID is invalid.
RSS xəbər lentini yükləmək alınmadı. Xəbər lenti: "%1". Səbəb: UİD səhvdir.
-
+
Duplicate RSS feed found. UID: "%1". Error: Configuration seems to be corrupted.
RSS xəbər lentinin təkrarı aşkarlandı. UİD: "%1". Xəta: Belə görünür ki, tənzimləmə pozulub.
-
+
Couldn't load RSS item. Item: "%1". Invalid data format.
RSS elemntlərini yüləmək mümkün olmadı. Element: "%1". Verilənlər formatı səhvdir.
-
+
Corrupted RSS list, not loading it.
RSS siyahısı pozulub, o, yüklənmir.
-
+
Incorrect RSS Item path: %1.
Düzgün olmayan RSS elementi yolu: %1
-
+
RSS item with given path already exists: %1.
Verilmiş yol ilə RSS elementi artıq mövcuddur: %1
-
+
Parent folder doesn't exist: %1.
Ana qovluq yoxdur; %1.
@@ -8521,69 +8770,69 @@ Bu qoşmalar söndürülüb.
Xəbər lenti ünvanına düzəliş et
-
+
Please choose a folder name
Qovluğu ad verin
-
+
Folder name:
Qovluğun adı:
-
+
New folder
Yeni qovluq
-
-
+
+
Please type a RSS feed URL
RSS lenti URL-nu yazın
-
-
+
+
Feed URL:
Lent URL-u:
-
+
Deletion confirmation
Silinmənin təsdiqlənməsi
-
+
Are you sure you want to delete the selected RSS feeds?
Seçilmiş RSS lentlərini silmək istədiyinizə əminsiniz?
-
+
Please choose a new name for this RSS feed
RSS lenti üçün yeni ad seçin
-
+
New feed name:
Yeni lent adı:
-
+
Rename failed
Adı dəyişdirilə bilmədi
-
+
Date:
Tarix:
-
+
Feed:
Lent:
-
+
Author:
Müəllif:
@@ -8591,38 +8840,38 @@ Bu qoşmalar söndürülüb.
SearchController
-
+
Python must be installed to use the Search Engine.
Axtarış sistemini istifadə etmək üçün Python quraşdırılmalıdır.
-
+
Unable to create more than %1 concurrent searches.
%1-dən/dan çox paralel axtarışlar yaratmaq mümkün deyil.
-
-
+
+
Offset is out of range
Sürüşmə əhatə dairəsindən kənardadır
-
+
All plugins are already up to date.
Bütün qoşmalar artıq yenilənib.
-
+
Updating %1 plugins
%1 qoşmaları yenilənir
-
+
Updating plugin %1
%1 qoşması yenilənir
-
+
Failed to check for plugin updates: %1
Qoşmanın yenilənməsini yoxlamaq baş tutmadı: %1
@@ -8697,132 +8946,142 @@ Bu qoşmalar söndürülüb.
Ölçüsü:
-
+
Name
i.e: file name
Adı
-
+
Size
i.e: file size
Ölçüsü
-
+
Seeders
i.e: Number of full sources
Göndəricilər
-
+
Leechers
i.e: Number of partial sources
İstismar edənlər
-
- Search engine
- Axtarış vasitəsi
+
+ Engine
+
-
+
+ Engine URL
+
+
+
+
+ Published On
+
+
+
+
Filter search results...
Axtarış nəticələrini filtrləmək...
-
+
Results (showing <i>%1</i> out of <i>%2</i>):
i.e: Search results
Nəticələr (<i>%2</i>dən/dan <i>%1</i> göstərmək):
-
+
Torrent names only
Torrent adı yalnız
-
+
Everywhere
Hər yerdə
-
+
Use regular expressions
Müntəzəm ifadələri istiadə etmək
-
+
Open download window
Endirmə pəncrəsini açın
-
+
Download
Endirmək
-
+
Open description page
Tanıtma səhifəsini açmaq
-
+
Copy
Kopyalamaq
-
+
Name
Adı
-
+
Download link
Endirmə keçidi
-
+
Description page URL
Tanıtma səhifəsi URL-u
-
+
Searching...
Axtarılır...
-
+
Search has finished
Axtarış sona çatdı
-
+
Search aborted
Axtarış ləğv edildi
-
+
An error occurred during search...
Axtarış zamanı xəta baş verdi...
-
+
Search returned no results
Axtarış nəticə vermədi
-
+
Column visibility
Sütunun görünməsi
-
+
Resize columns
Sütunların ölçüsünü dəyişin
-
+
Resize all non-hidden columns to the size of their contents
Bütün gizli olmayan sütunların ölçüsünü tərkiblərinin ölçüsünə görə dəyişmək
@@ -8830,104 +9089,104 @@ Bu qoşmalar söndürülüb.
SearchPluginManager
-
+
Unknown search engine plugin file format.
Naməlum axtarış vasitəsi qoşması fayl formatı.
-
+
Plugin already at version %1, which is greater than %2
Qoşma artıq %2 versiyasından böyük olan %1 versiyasındadır
-
+
A more recent version of this plugin is already installed.
Bu qoşmanın artıq ən son versiyası quraşdırılıb.
-
+
Plugin %1 is not supported.
%1 qoşması dəstəklənmir.
-
-
+
+
Plugin is not supported.
Qoşma dəstəklənmir.
-
+
Plugin %1 has been successfully updated.
%1 qoşması uğurla yeniləndi.
-
+
All categories
Bütün kateqoriyalar
-
+
Movies
Filmlər
-
+
TV shows
TV verilişləri
-
+
Music
Musiqi
-
+
Games
Oyun
-
+
Anime
Cizgi filmləri
-
+
Software
Proqram təminatı
-
+
Pictures
Şəkillər
-
+
Books
Kitablar
-
+
Update server is temporarily unavailable. %1
Yeniləmə serveri müvəqqəti işləmir. %1
-
-
+
+
Failed to download the plugin file. %1
Qoşma faylının endrilməsi alınmadı. %1
-
+
Plugin "%1" is outdated, updating to version %2
"%1" qoşmasının bersiyası köhnədir, %2 versiyasına yenilənir
-
+
Incorrect update info received for %1 out of %2 plugins.
%2 qoşmalarından %1 yenilənməsi haqqında səhv məlumatı alındı.
-
+
Search plugin '%1' contains invalid version string ('%2')
'%1' axtarış qoşması versiyası ('%2') səhv sətirlərdən ibarətdir
@@ -8937,10 +9196,10 @@ Bu qoşmalar söndürülüb.
-
-
-
-
+
+
+
+
Search
Axtarış
@@ -8952,7 +9211,7 @@ Click the "Search plugins..." button at the bottom right of the window
Onlardan bəzilərini quraşdırmaq üçün pəncərənin aşağı-sağındakı "Axtarış qoşmaları..." düyməsinə vurun.
-
+
Search plugins...
Axtarış qoşmaları...
@@ -8979,12 +9238,12 @@ Onlardan bəzilərini quraşdırmaq üçün pəncərənin aşağı-sağındakı
<b>"foo bar"</b>: <b>foo bar</b> axtarmaq üçün
-
+
All plugins
Bütün qoşmalar
-
+
Only enabled
Yalnız aktiv edilənlər
@@ -8995,54 +9254,54 @@ Onlardan bəzilərini quraşdırmaq üçün pəncərənin aşağı-sağındakı
<b>foo bar</b>: <b>foo</b> və <b>bar</b> axtarmaq üçün
-
+
Close tab
Vərəqi bağlayın
-
+
Close all tabs
Bütün vərəqləri bağlayın
-
+
Select...
Seçin...
-
-
-
+
+
+
Search Engine
Axtarış sistemi
-
+
Please install Python to use the Search Engine.
Axtarış sistemini istifadə etmək üçün Python quraşdırın.
-
+
Empty search pattern
Boş axtarış nümunəsi
-
+
Please type a search pattern first
Öncə axtarış nümunəsini daxil edin
-
+
Stop
Dayandırmaq
-
+
Search has finished
Axtarış sona çatdı
-
+
Search has failed
Axtarış alınmadı
@@ -9514,13 +9773,13 @@ Onlardan bəzilərini quraşdırmaq üçün pəncərənin aşağı-sağındakı
- Resumed (0)
- Davm etdirilən (0)
+ Running (0)
+
- Paused (0)
- Fasilədə (0)
+ Stopped (0)
+
@@ -9582,36 +9841,36 @@ Onlardan bəzilərini quraşdırmaq üçün pəncərənin aşağı-sağındakı
Completed (%1)
Başa çatdı (%1)
+
+
+ Running (%1)
+
+
- Paused (%1)
- Fasilədə (%1)
+ Stopped (%1)
+
+
+
+
+ Start torrents
+
+
+
+
+ Stop torrents
+
Moving (%1)
Köçürülür (%1)
-
-
- Resume torrents
- Torrentləri davam etdirmək
-
-
-
- Pause torrents
- Torrentlərə fasilə
-
Remove torrents
Torrentləri silin
-
-
- Resumed (%1)
- Davam etdirilən (%1)
-
Active (%1)
@@ -9685,13 +9944,13 @@ Onlardan bəzilərini quraşdırmaq üçün pəncərənin aşağı-sağındakı
- Resume torrents
- Torrentləri davam etdirmək
+ Start torrents
+
- Pause torrents
- Torrentlərə fasilə
+ Stop torrents
+
@@ -9854,32 +10113,32 @@ Başqa ad verin və yenidən cəhd edin.
TorrentContentModel
-
+
Name
Ad
-
+
Progress
Gedişat
-
+
Download Priority
Endirmə üstünlüyü
-
+
Remaining
Qalır
-
+
Availability
Mövcuddur
-
+
Total Size
Ümumi ölçü
@@ -9924,102 +10183,120 @@ Başqa ad verin və yenidən cəhd edin.
TorrentContentWidget
-
+
Rename error
Ad dəyişmədə xəta
-
+
Renaming
Adı dəyişdirilir
-
+
New name:
Yeni ad:
-
+
Column visibility
Sütunun görünməsi
-
+
Resize columns
Sütunların ölçüsünü dəyişin
-
+
Resize all non-hidden columns to the size of their contents
Bütün gizli olmayan sütunların ölçüsünü tərkiblərinin ölçüsünə görə dəyişmək
-
+
Open
Açın
-
+
Open containing folder
Bu tərkibli qovluğu aç
-
+
Rename...
Adını dəyişin..
-
+
Priority
Üstünlük
-
-
+
+
Do not download
Endirməyin
-
+
Normal
Normal
-
+
High
Yüksək
-
+
Maximum
Ən çox
-
+
By shown file order
Göstərilən fayl sırasına görə
-
+
Normal priority
Adi üstünlük
-
+
High priority
Yüksək üstünlük
-
+
Maximum priority
Ən yüksək üstünlük
-
+
Priority by shown file order
Göstərilən fayl sırasına görə üstünlük
+
+ TorrentCreatorController
+
+
+ Too many active tasks
+ Həddindən çox aktiv tapşırıqlar
+
+
+
+ Torrent creation is still unfinished.
+ Torrent yaradılması hələ başa çatmayıb.
+
+
+
+ Torrent creation failed.
+ Torrent yaradılması uğursuz oldu
+
+
TorrentCreatorDialog
@@ -10044,13 +10321,13 @@ Başqa ad verin və yenidən cəhd edin.
-
+
Select file
Faylı seçmək
-
+
Select folder
Qovluğu seçmək
@@ -10075,7 +10352,7 @@ Başqa ad verin və yenidən cəhd edin.
Hissənin ölçüsü:
-
+
Auto
Avtomatik
@@ -10155,58 +10432,53 @@ Başqa ad verin və yenidən cəhd edin.
Gedişat:
-
+
Create Torrent
Torrent yaratmaq
-
-
+
+
Torrent creation failed
Torrent yaratmaq alınmadı
-
+
Reason: Path to file/folder is not readable.
Səbəbi: Fayla/qovluğa yol oxuna bilən deyil.
-
+
Select where to save the new torrent
Yeni torrenti harada saxlayacağınızı seçin
-
+
Torrent Files (*.torrent)
Torrent faylları (*.torrent)
-
- Reason: %1
- Səbəbi: %1
-
-
-
+
Add torrent to transfer list failed.
Köçürmə siyahısına torrent əlavə etmək baş tutmadı.
-
+
Reason: "%1"
Səbəb: "%1"
-
+
Add torrent failed
Torrent əlavə edilməsi baş tutmadı
-
+
Torrent creator
Torrent yaradıcı
-
+
Torrent created:
Yaradılan torrent:
@@ -10355,85 +10627,121 @@ Başqa ad verin və yenidən cəhd edin.
Torrent paylaşım limitləri
-
- Use global share limit
- Ümumi paylaşım limitindən istifadə edin
-
-
-
- Set no share limit
- Paylaşma limiti təyin etməyin
-
-
-
- Set share limit to
- Paylaşma limiti təyin etmək
-
-
-
- ratio
- nisbət
-
-
-
- total minutes
- ümumi dəqiqələr
-
-
-
- inactive minutes
- qeyri-aktiv dəqiqlələr
-
-
-
+
Disable DHT for this torrent
Bu torrent üçün DHT-ni söndürmək
-
+
Download in sequential order
Ardıcıl şəkildə yükləmək
-
+
Disable PeX for this torrent
Bu torrent üçün PeX-i söndürmək
-
+
Download first and last pieces first
Öncə İlk və son hissələri endirmək
-
+
Disable LSD for this torrent
Bu torrent üçün LSD-ni söndürmək
-
+
Currently used categories
Hazırda istifadə olunan kateqoriyalar
-
-
+
+
Choose save path
Saxlama yolunu seçin
-
+
Not applicable to private torrents
Şəxsi torrentlərə tətbiq olunmur
+
+
+ TorrentShareLimitsWidget
-
- No share limit method selected
- Paylaşma limiti üsulu seçilməyib
+
+
+
+
+ Default
+ Standart
-
- Please select a limit method first
- Öncə paylaşma limitini seçin
+
+
+
+ Unlimited
+ Limitsiz
+
+
+
+
+
+ Set to
+ Təyin edin
+
+
+
+ Seeding time:
+ Paylama vaxtı:
+
+
+
+ Action when the limit is reached:
+
+
+
+
+ Stop torrent
+
+
+
+
+ Remove torrent
+ Torrenti silmək
+
+
+
+ Remove torrent and its content
+
+
+
+
+ Enable super seeding for torrent
+ Torrent üçün super göndərişi aktivləşdirmək
+
+
+
+
+
+
+
+
+ min
+ minutes
+ dəq
+
+
+
+ Inactive seeding time:
+ Qeyri-aktiv paylama vaxtı:
+
+
+
+ Ratio:
+ Nisbət:
@@ -10444,32 +10752,32 @@ Başqa ad verin və yenidən cəhd edin.
Torrent etiketləri
-
+
New Tag
Yeni etiket
-
+
Tag:
Etiket:
-
+
Invalid tag name
Səhv etiket adı
-
+
Tag name '%1' is invalid.
"%1" etiket adı qəbul edilmir
-
+
Tag exists
Etiket mövcuddur
-
+
Tag name already exists.
Etiket adı artıq mövcuddur.
@@ -10477,115 +10785,115 @@ Başqa ad verin və yenidən cəhd edin.
TorrentsController
-
+
Error: '%1' is not a valid torrent file.
Xəta: '%1' torrent faylı düzgün deyil.
-
+
Priority must be an integer
Üstünlük tam ədəd olmalıdır
-
+
Priority is not valid
Üstünlük etibarsızdır
-
+
Torrent's metadata has not yet downloaded
Torrent meta verilənləri hələlik yüklənməyib
-
+
File IDs must be integers
Fayl İD-ləri uyğunlaşdırılmalıdır
-
+
File ID is not valid
Fayl İD-ləri etibarlı deyil
-
-
-
-
+
+
+
+
Torrent queueing must be enabled
Torrent növbələnməsi aktiv edilməlidir
-
-
+
+
Save path cannot be empty
Saxlama yolu boş ola bilməz
-
-
+
+
Cannot create target directory
Hədəf kataloqu yaradıla bilmir
-
-
+
+
Category cannot be empty
Kateqoriya boş ola bilməz
-
+
Unable to create category
Kateqoriya yaratmaq mümkün olmadı
-
+
Unable to edit category
Kateqoriyaya düzəliş etmək mümkün olmadı
-
+
Unable to export torrent file. Error: %1
Torrent faylın ixracı mümkün deyil. Xəta: %1
-
+
Cannot make save path
Saxlama yolu yaradıla bilmədi
-
+
'sort' parameter is invalid
'çeşid' parametri səhvdir
-
+
"%1" is not a valid file index.
"%1" düzgün indeks faylı deyil.
-
+
Index %1 is out of bounds.
%1 indeksi hüdülardan kənardadır.
-
-
+
+
Cannot write to directory
Qovluğa yazmaq mümkün olmadı
-
+
WebUI Set location: moving "%1", from "%2" to "%3"
Veb İİ, yerdəyişmə: "%1" "%2"-dən/dan "%3"-ə\a
-
+
Incorrect torrent name
Səhv torrent adı
-
-
+
+
Incorrect category name
Səhv kateqoriya adı
@@ -10616,196 +10924,191 @@ Başqa ad verin və yenidən cəhd edin.
TrackerListModel
-
+
Working
İşləyir
-
+
Disabled
Söndürülüb
-
+
Disabled for this torrent
Bu torrent söndürülüb
-
+
This torrent is private
Bu torrent məxfidir
-
+
N/A
Əlçatmaz
-
+
Updating...
Yenilənir...
-
+
Not working
İşləmir
-
+
Tracker error
İzləyici xətası
-
+
Unreachable
Əlçatmaz
-
+
Not contacted yet
Hələ qoşulmayıb
-
- Invalid status!
- Xətalı vəziyyət!
+
+ Invalid state!
+
-
- URL/Announce endpoint
- Keçid ünvanını/son nöqtəni elan edin
+
+ URL/Announce Endpoint
+
-
+
+ BT Protocol
+
+
+
+
+ Next Announce
+
+
+
+
+ Min Announce
+
+
+
+
Tier
Səviyyə
-
- Protocol
- Protokol
-
-
-
+
Status
Vəziyyəti
-
+
Peers
İştirakçılar
-
+
Seeds
Göndəricilər
-
+
Leeches
Sui-istifadə edənlər
-
+
Times Downloaded
Endirilmə sayı
-
+
Message
İsmarıc
-
-
- Next announce
- Növbəti anons
-
-
-
- Min announce
- Ən az anons
-
-
-
- v%1
- v%1
-
TrackerListWidget
-
+
This torrent is private
Bu torrent məxfidir
-
+
Tracker editing
İzləyicilərə düzəliş edilir
-
+
Tracker URL:
İzləyici URL-u:
-
-
+
+
Tracker editing failed
İzləyicilərə düzəliş alınmadı
-
+
The tracker URL entered is invalid.
Daxil edilən izləyici URL-u səhvdir
-
+
The tracker URL already exists.
İzləyici URL-u artıq mövcuddur.
-
+
Edit tracker URL...
İzləyici URL-na düzəliş edin...
-
+
Remove tracker
İzləyicini silmək
-
+
Copy tracker URL
İzləyici URL-nu kopyalamaq
-
+
Force reannounce to selected trackers
Seçilmiş izləyicilərə məcburi təkrar anons etmək
-
+
Force reannounce to all trackers
Bütün izləyicilərə məcburi təkrar anons etmək
-
+
Resize columns
Sütunların ölçüsünü dəyişin
-
+
Resize all non-hidden columns to the size of their contents
Bütün gizli olmayan sütunların ölçüsünü tərkiblərinin ölçüsünə görə dəyişmək
-
+
Add trackers...
İzləyicilər əlavə edin...
-
+
Column visibility
Sütunun görünməsi
@@ -10833,27 +11136,27 @@ Başqa ad verin və yenidən cəhd edin.
İzləyici siyahısını endirin
-
+
Add
Əlavə edin
-
+
Trackers list URL error
İzləyici siyahısı ünvanı səhvdir
-
+
The trackers list URL cannot be empty
İzləyici siyahısı ünvanı boş ola bilməz
-
+
Download trackers list error
İzləyici siyahısını endirilməsində xəta
-
+
Error occurred when downloading the trackers list. Reason: "%1"
İzləyici siyahısı endirilən zaman xəta baş verdi. Səbəb: "%1"
@@ -10861,62 +11164,62 @@ Başqa ad verin və yenidən cəhd edin.
TrackersFilterWidget
-
+
Warning (%1)
Xəbərdarlıq (%1)
-
+
Trackerless (%1)
İzləyicilərsiz (%1)
-
+
Tracker error (%1)
İzləyici xətası (%1)
-
+
Other error (%1)
Başqa xəta (%1)
-
+
Remove tracker
İzləyicini silmək
-
- Resume torrents
- Torrentləri davam etdirmək
+
+ Start torrents
+
-
- Pause torrents
- Torrentlərə fasilə
+
+ Stop torrents
+
-
+
Remove torrents
Torrentləri silin
-
+
Removal confirmation
Silinmənin təsdiqi
-
+
Are you sure you want to remove tracker "%1" from all torrents?
"%1" izləyicisini bütün torrentlərdən silmək istədiyinizə əminisiniz?
-
+
Don't ask me again.
Bir daha soruşmamaq.
-
+
All (%1)
this is for the tracker filter
Hamısı (%1)
@@ -11017,11 +11320,6 @@ Başqa ad verin və yenidən cəhd edin.
Used when loading the torrents from disk after qbt is launched. It checks the correctness of the .fastresume file. Normally it is completed in a fraction of a second, unless loading many many torrents.
Bərpa olunma tarixi yoxlanılır
-
-
- Paused
- Fasilədə
-
Completed
@@ -11045,220 +11343,252 @@ Başqa ad verin və yenidən cəhd edin.
Xətalı
-
+
Name
i.e: torrent name
Ad
-
+
Size
i.e: torrent size
Ölçü
-
+
Progress
% Done
Gedişat
-
+
+ Stopped
+
+
+
+
Status
- Torrent status (e.g. downloading, seeding, paused)
+ Torrent status (e.g. downloading, seeding, stopped)
Vəziyyət
-
+
Seeds
i.e. full sources (often untranslated)
Göndəricilər
-
+
Peers
i.e. partial sources (often untranslated)
İştirakçılar
-
+
Down Speed
i.e: Download speed
Endirmə sürəti
-
+
Up Speed
i.e: Upload speed
Göndərmə sürəti
-
+
Ratio
Share ratio
Reytinq
-
+
+ Popularity
+
+
+
+
ETA
i.e: Estimated Time of Arrival / Time left
Qalan Vaxt
-
+
Category
Kateqoriya
-
+
Tags
Etiketlər
-
+
Added On
Torrent was added to transfer list on 01/01/2010 08:00
Əlavə edilib
-
+
Completed On
Torrent was completed on 01/01/2010 08:00
Tamamlanıb
-
+
Tracker
İzləyici
-
+
Down Limit
i.e: Download limit
Endirmə limiti
-
+
Up Limit
i.e: Upload limit
Göndərmə limiti
-
+
Downloaded
Amount of data downloaded (e.g. in MB)
Endirildi
-
+
Uploaded
Amount of data uploaded (e.g. in MB)
Göndərildi
-
+
Session Download
Amount of data downloaded since program open (e.g. in MB)
Sesiyada yüklənən
-
+
Session Upload
Amount of data uploaded since program open (e.g. in MB)
Sesiyada göndərilən
-
+
Remaining
Amount of data left to download (e.g. in MB)
Qalır
-
+
Time Active
- Time (duration) the torrent is active (not paused)
+ Time (duration) the torrent is active (not stopped)
Aktivlik müddəti
-
+
+ Yes
+ Bəli
+
+
+
+ No
+ Xeyr
+
+
+
Save Path
Torrent save path
Yolu saxla
-
+
Incomplete Save Path
Torrent incomplete save path
Tamamlanmayanların saxlama yolu
-
+
Completed
Amount of data completed (e.g. in MB)
Başa çatdı
-
+
Ratio Limit
Upload share ratio limit
Nisbət həddi
-
+
Last Seen Complete
Indicates the time when the torrent was last seen complete/whole
Son görünən tamamlanmış
-
+
Last Activity
Time passed since a chunk was downloaded/uploaded
Sonuncu aktiv
-
+
Total Size
i.e. Size including unwanted data
Ümumi ölçü
-
+
Availability
The number of distributed copies of the torrent
Mövcud
-
+
Info Hash v1
i.e: torrent info hash v1
Məlumat heş-i v1
-
+
Info Hash v2
i.e: torrent info hash v2
Məlumat heş-i v2
-
+
Reannounce In
Indicates the time until next trackers reannounce
Növbəti anons vaxtı
-
-
+
+ Private
+ Flags private torrents
+
+
+
+
+ Ratio / Time Active (in months), indicates how popular the torrent is
+
+
+
+
+
+
N/A
Ə/D
-
+
%1 ago
e.g.: 1h 20m ago
%1 əvvəl
-
+
%1 (seeded for %2)
e.g. 4m39s (seeded for 3m10s)
%1 (%2 üçün göndərildi)
@@ -11267,339 +11597,319 @@ Başqa ad verin və yenidən cəhd edin.
TransferListWidget
-
+
Column visibility
Sütunun görünməsi
-
+
Recheck confirmation
Yenidən yoxlamanı təsdiq etmək
-
+
Are you sure you want to recheck the selected torrent(s)?
Seçilmiş torrent(lər)i yenidən yoxlamaq istədiyinizə əminsiniz?
-
+
Rename
Adını dəyişmək
-
+
New name:
Yeni ad:
-
+
Choose save path
Saxlama yolunu seçmək
-
- Confirm pause
- Fasiləni təsdiq et
-
-
-
- Would you like to pause all torrents?
- Bütün torrenlərə fasilə verilsin?
-
-
-
- Confirm resume
- Davam etdirməni təsdiqlə
-
-
-
- Would you like to resume all torrents?
- Bütün torrentlər davam etdirilsin?
-
-
-
+
Unable to preview
Öncədən baxış alınmadı
-
+
The selected torrent "%1" does not contain previewable files
"%1" seçilmiş torrent öncədən baxıla bilən fayllardan ibarət deyil
-
+
Resize columns
Sütunların ölçüsünü dəyişin
-
+
Resize all non-hidden columns to the size of their contents
Bütün gizli olmayan sütunların ölçüsünü tərkiblərinin ölçüsünə görə dəyişmək
-
+
Enable automatic torrent management
Avtomatik Torrent İdarəetməsini aktiv edin
-
+
Are you sure you want to enable Automatic Torrent Management for the selected torrent(s)? They may be relocated.
Seçilmiş torrent(lər) üçün avtomatik torrent idarəetməsini aktiv etmək istədiyinizə əminsiniz? Torrentlər başqa yerə köçürülə bilər.
-
+
Add Tags
Etiketlər əlavə etmək
-
+
Choose folder to save exported .torrent files
İxrac edilmiş .torrent fayllarının saxlanılması üçün qovluq seçin
-
+
Export .torrent file failed. Torrent: "%1". Save path: "%2". Reason: "%3"
ştorrent faylın ixracı baş tutmadı. Torrent: "%1". Saxlama yolu: "%2". Səbəb: "%3"
-
+
A file with the same name already exists
Eyni adlı fayl artıq mövcuddur
-
+
Export .torrent file error
.torrent faylın ixracı xətası
-
+
Remove All Tags
Bütün etiketləri silmək
-
+
Remove all tags from selected torrents?
Seçilmiş torrentlərdən bütün etiketlər silinsin?
-
+
Comma-separated tags:
Vergüllə ayrılan etiketlər:
-
+
Invalid tag
Yalnış etiket
-
+
Tag name: '%1' is invalid
Etiket adı: "%1" səhvdir
-
- &Resume
- Resume/start the torrent
- Davam etdi&rin
-
-
-
- &Pause
- Pause the torrent
- &Fasilə
-
-
-
- Force Resu&me
- Force Resume/start the torrent
- &Məcburi davam etdirin
-
-
-
+
Pre&view file...
&Fayla öncədən baxış...
-
+
Torrent &options...
T&orrent seçimləri...
-
+
Open destination &folder
Təyinat &qovluğunu açın
-
+
Move &up
i.e. move up in the queue
Y&uxarı köçürün
-
+
Move &down
i.e. Move down in the queue
&Aşağı köçürün
-
+
Move to &top
i.e. Move to top of the queue
Ən üs&tə köçürün
-
+
Move to &bottom
i.e. Move to bottom of the queue
Ən aşağı&ya köçürün
-
+
Set loc&ation...
Y&er təyin edin...
-
+
Force rec&heck
Məcburi tə&krar yoxlayın
-
+
Force r&eannounce
Məcburi təkrar anons &edin
-
+
&Magnet link
&Maqnit keçid
-
+
Torrent &ID
Torrent &İD-si
-
+
&Comment
&Şərh
-
+
&Name
A&d
-
+
Info &hash v1
Məlumat &heşi v1
-
+
Info h&ash v2
Məlum&at heşi v2
-
+
Re&name...
Adı&nı dəyişin...
-
+
Edit trac&kers...
İz&ləyicilərə düzəliş...
-
+
E&xport .torrent...
.torrent faylı i&xrac edin...
-
+
Categor&y
Kateqori&ya
-
+
&New...
New category...
Ye&ni...
-
+
&Reset
Reset category
Sıfı&rlayın
-
+
Ta&gs
Etike&tlər
-
+
&Add...
Add / assign multiple tags...
Əl&avə edin...
-
+
&Remove All
Remove all tags
&Hamısını silin
-
+
+ Can not force reannounce if torrent is Stopped/Queued/Errored/Checking
+
+
+
+
&Queue
&Növbə
-
+
&Copy
&Kopyalayın
-
+
Exported torrent is not necessarily the same as the imported
İxrac edilən torrent idxal edilən torrent kimi vacib deyil
-
+
Download in sequential order
Ardıcıl şəkildə yükləmək
-
+
Errors occurred when exporting .torrent files. Check execution log for details.
Torrent faylı ixrac olunarkən xətalar baş verdi. Ətraflı məlumat üçün icra olunma jurnalına baxın.
-
+
+ &Start
+ Resume/start the torrent
+
+
+
+
+ Sto&p
+ Stop the torrent
+
+
+
+
+ Force Star&t
+ Force Resume/start the torrent
+
+
+
+
&Remove
Remove the torrent
&Silin
-
+
Download first and last pieces first
Öncə İlk və son hissələri endirmək
-
+
Automatic Torrent Management
Avtomatik Torrent İdarəetməsi
-
+
Automatic mode means that various torrent properties (e.g. save path) will be decided by the associated category
Avtomatik rejim o deməkdir ki, müxtəlif torrent xüsusiyyətləri (məs., saxlama yolu) uyğun kateqoriyalara görə müəyyən ediləcəkdir
-
- Can not force reannounce if torrent is Paused/Queued/Errored/Checking
- Fasilədə/Növbədə/Xətalı/Yoxlamada olduqda torrent təkrar məcburi anons edilə bilməz
-
-
-
+
Super seeding mode
Super göndərmə rejimi
@@ -11644,28 +11954,28 @@ Başqa ad verin və yenidən cəhd edin.
Nişan İD-si
-
+
UI Theme Configuration.
İİ mövzusu tənzimləməsi.
-
+
The UI Theme changes could not be fully applied. The details can be found in the Log.
İİ mövzusu dəyişikliklərini tam olaraq tətbiq etmək mümkün olmadı. Ətraflı məlumat üçün Jurnala bax.
-
+
Couldn't save UI Theme configuration. Reason: %1
İİ mövzusu tənzimləməsini saxlamaq mümkün olmadı. Səbəb: %1
-
-
+
+
Couldn't remove icon file. File: %1.
Nişan faylını silmək mümkün olmadı. Fayl: %1
-
+
Couldn't copy icon file. Source: %1. Destination: %2.
Nişan faylını kopyalamaq mümkün olmadı. Mənbə: %1. Hədəf: %2
@@ -11673,7 +11983,12 @@ Başqa ad verin və yenidən cəhd edin.
UIThemeManager
-
+
+ Set app style failed. Unknown style: "%1"
+
+
+
+
Failed to load UI theme from file: "%1"
İİ mövzusunu fayldan yükləmək alınmadı: "%1"
@@ -11704,20 +12019,21 @@ Başqa ad verin və yenidən cəhd edin.
Upgrade
-
+
Migrate preferences failed: WebUI https, file: "%1", error: "%2"
Miqrasiya tərcihləri uğursuz oldu: WebUI https, fayl: "%1", xəta: "%2"
-
+
Migrated preferences: WebUI https, exported data to file: "%1"
Miqrasiya tərcihləri: WebUI https, fayla ixrac tarixi: "%1"
-
-
-
-
+
+
+
+
+
Invalid value found in configuration file, reverting it to default. Key: "%1". Invalid value: "%2".
Tənzimləmə faylında səhv dəyər tapıldı, ilkin vəziyyətinə qaytarılır. Açar: "%1". Səhv dəyər: "%2".
@@ -11758,27 +12074,27 @@ Başqa ad verin və yenidən cəhd edin.
Utils::IO
-
+
File open error. File: "%1". Error: "%2"
Faylın açılması xətası. Fayl: "%1". Xəta: "%2"
-
+
File size exceeds limit. File: "%1". File size: %2. Size limit: %3
Fayl ölçüsü limiti aşır. Fayl: "%1". Faylın ölçüsü: %2. Ölçünün limiti: %3
-
+
File size exceeds data size limit. File: "%1". File size: %2. Array limit: %3
Faylın ölçüsü verilənlər ölçüsünün limitini aşır. Fayl: "%1". Faylın ölçüsü: "%2" Massiv limiti: "%3"
-
+
File read error. File: "%1". Error: "%2"
Faylın oxunması xətası. Fayl: "%1". Xəta: "%2"
-
+
Read size mismatch. File: "%1". Expected: %2. Actual: %3
Ölçü uyğunsuzluğunu oxuyun. Fayl: "%1". Gözlənilən: %2. Aktual: %3
@@ -11842,72 +12158,72 @@ Başqa ad verin və yenidən cəhd edin.
WebApplication
-
+
Unacceptable session cookie name is specified: '%1'. Default one is used.
Sessiya kuki faylına verilmiş bu ad qəbuledilməzdir: "%1". Standart bir ad istifadə edildi.
-
+
Unacceptable file type, only regular file is allowed.
Qəbuledilməz fayl növü, yalnız müntəzəm fayllar qəbul edilir.
-
+
Symlinks inside alternative UI folder are forbidden.
Alternativ İstifadəçi İnterfeysi daxilində simvolik bağlantılar qadağandır.
-
+
Using built-in WebUI.
Daxili Veb İİ istifadə edilir.
-
+
Using custom WebUI. Location: "%1".
Xüsusi Veb İİ-nin istifadəsi. Yeri: "%1".
-
+
WebUI translation for selected locale (%1) has been successfully loaded.
Seçilmiş məkan (%1) üçün Veb İİ tərcüməsi uğurla yükləndi.
-
+
Couldn't load WebUI translation for selected locale (%1).
Seçilmiş məkan (%1) üçün Veb İİ tərcüməsini yükləmək mümkün olmadı.
-
+
Missing ':' separator in WebUI custom HTTP header: "%1"
Veb İİ fərdi HTTP başlığında ":" ayırıcısı çatışmır: "%1"
-
+
Web server error. %1
Veb server xətası. %1
-
+
Web server error. Unknown error.
Veb server xətası. Naməlum xəta.
-
+
WebUI: Origin header & Target origin mismatch! Source IP: '%1'. Origin header: '%2'. Target origin: '%3'
Veb İİ: Mənbə başlığı və Hədəf Mənbəyi uyğun gəlmir! İP mənbəyi: "%1". Orojonal başlıq: "%2". Hədəf mənbəyi: "%3"
-
+
WebUI: Referer header & Target origin mismatch! Source IP: '%1'. Referer header: '%2'. Target origin: '%3'
Veb İİ: İstinad başllğı və Hədəf mənşəyi uyğun gəlmir! İP mənbəyi: "%1". İstinad başlığı: "%2". Hədəf mənşəyi: "%3"
-
+
WebUI: Invalid Host header, port mismatch. Request source IP: '%1'. Server port: '%2'. Received Host header: '%3'
Veb İİ: Səhv host başlığı və port uyğun gəlmir. Tələb olunan İP mənbəyi: "%1". Server portu: "%2". Alınan host başlığı: "%3"
-
+
WebUI: Invalid Host header. Request source IP: '%1'. Received Host header: '%2'
Veb İİ səhv host başlığı. Tələb olunan İP mənbəyi: "%1". Alınan host başlığı: "%2"
@@ -11940,103 +12256,111 @@ Başqa ad verin və yenidən cəhd edin.
Bağlantı alınmayan İP: %1, port: %2. Səbəb: %3
+
+ fs
+
+
+ Unknown error
+ Naməlum xəta
+
+
misc
-
+
B
bytes
B
-
+
KiB
kibibytes (1024 bytes)
KB
-
+
MiB
mebibytes (1024 kibibytes)
MB
-
+
GiB
gibibytes (1024 mibibytes)
QB
-
+
TiB
tebibytes (1024 gibibytes)
TB
-
+
PiB
pebibytes (1024 tebibytes)
PB
-
+
EiB
exbibytes (1024 pebibytes)
EB
-
+
/s
per second
/san
-
+
%1s
e.g: 10 seconds
%1s
-
+
%1m
e.g: 10 minutes
%1dəq
-
+
%1h %2m
e.g: 3 hours 5 minutes
%1s %2 d
-
+
%1d %2h
e.g: 2 days 10 hours
%1g %2s
-
+
%1y %2d
e.g: 2 years 10 days
%1y %2d
-
-
+
+
Unknown
Unknown (size)
Naməlum
-
+
qBittorrent will shutdown the computer now because all downloads are complete.
qBittorrent, komputeri indi söndürəcəkdir, çünki bütün torrentlərin endirilməsi başa çatdı.
-
+
< 1m
< 1 minute
< 1dəq
-
\ No newline at end of file
+
diff --git a/src/lang/qbittorrent_be.ts b/src/lang/qbittorrent_be.ts
index 5faaba0fe..69033351f 100644
--- a/src/lang/qbittorrent_be.ts
+++ b/src/lang/qbittorrent_be.ts
@@ -11,7 +11,7 @@
About
- Пра праґраму
+ Аб праграме
@@ -32,7 +32,7 @@
Nationality:
- Грамадзянства:
+ Краіна:
@@ -64,7 +64,7 @@
Translators
- Перакладнікі
+ Перакладчыкі
@@ -79,7 +79,7 @@
qBittorrent was built with the following libraries:
- qBittorrent быў сабраны з гэтымі бібліятэкамі:
+ qBittorrent сабраны з выкарыстаннем наступных бібліятэк:
@@ -93,8 +93,8 @@
- Copyright %1 2006-2024 The qBittorrent project
- Аўтарскае права %1 2006-2024 The qBittorrent project
+ Copyright %1 2006-2025 The qBittorrent project
+ Аўтарскае права %1 2006-2025 The qBittorrent project
@@ -140,7 +140,7 @@
The file already exists: '%1'.
- Файл ўжо існуе: «%1».
+ Файл ужо існуе: «%1».
@@ -213,7 +213,7 @@
Click [...] button to add/remove tags.
- Націсніце [...] кнопку, каб дадаць/выдаліць тэгі.
+ Націсніце кнопку [...], каб дадаць/выдаліць тэгі.
@@ -231,25 +231,25 @@
Умова спынення:
-
-
+
+
None
Нічога
-
-
+
+
Metadata received
Метаданыя атрыманы
-
+
Torrents that have metadata initially will be added as stopped.
-
+ Торэнты, якія адпачатку ўтрымліваюць метаданыя, будуць дададзеныя як спыненыя.
-
-
+
+
Files checked
Файлы правераны
@@ -266,12 +266,12 @@
Content layout:
- Макет кантэнту:
+ Структура змесціва:
Original
- Арыгінал
+ Зыходная
@@ -364,118 +364,114 @@
Захаваць як файл .torrent...
-
+
I/O Error
Памылка ўводу/вываду
-
+
Not Available
This comment is unavailable
Недаступны
-
+
Not Available
This date is unavailable
Недаступна
-
+
Not available
Недаступна
-
+
Magnet link
Magnet-спасылка
-
+
Retrieving metadata...
Атрыманне метаданых...
-
-
+
+
Choose save path
- Абярыце лякацыю захаваньня
+ Выберыце шлях захавання
-
+
No stop condition is set.
Умова спынення не зададзена.
-
+
Torrent will stop after metadata is received.
Торэнт спыніцца пасля атрымання метаданых.
- Torrents that have metadata initially aren't affected.
- Торэнты, якія першапачаткова маюць метаданыя, не закранаюцца.
-
-
-
+
Torrent will stop after files are initially checked.
Торэнт спыніцца пасля першапачатковай праверкі файлаў.
-
+
This will also download metadata if it wasn't there initially.
Гэта таксама спампуе метаданыя, калі іх не было першапачаткова.
-
-
+
+
N/A
Н/Д
-
+
%1 (Free space on disk: %2)
%1 (на дыску вольна: %2)
-
+
Not available
This size is unavailable.
Недаступна
-
+
Torrent file (*%1)
Торэнт-файл (*%1)
-
+
Save as torrent file
Захаваць як файл торэнт
-
+
Couldn't export torrent metadata file '%1'. Reason: %2.
Не ўдалося экспартаваць метаданыя торэнта '%1' з прычыны: %2
-
+
Cannot create v2 torrent until its data is fully downloaded.
- Немагчыма стварыць торэнт v2, пакуль яго дадзеныя не будуць цалкам загружаны.
+ Немагчыма стварыць торэнт v2, пакуль яго даныя не будуць цалкам спампаваны.
-
+
Filter files...
- Фільтраваць файлы...
+ Фільтр файлаў...
-
+
Parsing metadata...
Аналіз метаданых...
-
+
Metadata retrieval complete
- Атрыманне метаданых скончана
+ Атрыманне метаданых завершана
@@ -491,22 +487,22 @@
Не ўдалося дадаць торэнт. Крыніца: "%1". Прычына: "%2"
-
+
Detected an attempt to add a duplicate torrent. Source: %1. Existing torrent: %2. Result: %3
- Выяўленая спроба паўторнага даданьня існага торэнта. Крыніца: %1. Існы торэнт: %2. Вынік: %3
+ Выяўлена спроба паўторнага дадавання наяўнага торэнта. Крыніца: %1. Наяўны торэнт: %2. Вынік: %3
-
+
Merging of trackers is disabled
Аб'яднанне трэкераў адключана
-
+
Trackers cannot be merged because it is a private torrent
Немагчыма дадаць трэкеры, бо гэта прыватны торэнт
-
+
Trackers are merged from new source
Трэкеры з новай крыніцы дададзены
@@ -536,7 +532,7 @@
Note: the current defaults are displayed for reference.
- Нататка: бягучыя значэнні па змаўчанні адлюстроўваюцца для даведкі.
+ Заўвага: бягучыя значэнні па змаўчанні паказваюцца для даведкі.
@@ -556,7 +552,7 @@
Click [...] button to add/remove tags.
- Націсніце [...] кнопку, каб дадаць/выдаліць тэгі.
+ Націсніце кнопку [...], каб дадаць/выдаліць тэгі.
@@ -576,7 +572,7 @@
Content layout:
- Макет кантэнту:
+ Структура змесціва:
@@ -591,12 +587,12 @@
Skip hash check
- Прапусціць праверку хэша
+ Прапусціць праверку хэшу
Torrent share limits
- Абмежаванні раздачы торэнта
+ Абмежаванні раздачы торэнта
@@ -641,7 +637,7 @@
Original
- Арыгінал
+ Зыходная
@@ -656,7 +652,7 @@
None
- Нічога
+ Няма
@@ -672,763 +668,834 @@
AdvancedSettings
-
-
-
-
+
+
+
+
MiB
МБ
-
+
Recheck torrents on completion
Пераправераць торэнты пасля спампоўвання
-
-
+
+
ms
milliseconds
мс
-
+
Setting
Параметр
-
+
Value
Value set for this setting
Значэнне
-
+
(disabled)
(адключана)
-
+
(auto)
(аўта)
-
+
min
minutes
хв
-
+
All addresses
Усе адрасы
-
+
qBittorrent Section
Раздзел qBittorrent
-
-
+
+
Open documentation
Адкрыць дакументацыю
-
+
All IPv4 addresses
Усе адрасы IPv4
-
+
All IPv6 addresses
Усе адрасы IPv6
-
+
libtorrent Section
Раздзел libtorrent
-
+
Fastresume files
Хуткае аднаўленне файлаў
-
+
SQLite database (experimental)
База даных SQLite (эксперыментальная)
-
+
Resume data storage type (requires restart)
- Працягнуць тып захавання даных (патрабуецца перазапуск)
+ Тып захавання даных узнаўлення (патрабуецца перазапуск)
-
+
Normal
Звычайны
-
+
Below normal
Ніжэй звычайнага
-
+
Medium
Сярэдні
-
+
Low
Нізкі
-
+
Very low
Вельмі нізкі
-
+
Physical memory (RAM) usage limit
- Ліміт выкарыстання фізічнай памяці (RAM).
+ Абмежаванне выкарыстання фізічнай памяці (RAM)
-
+
Asynchronous I/O threads
Патокі асінхроннага ўводу/вываду
-
+
Hashing threads
Патокі хэшавання
-
+
File pool size
Памер пула файлаў
-
+
Outstanding memory when checking torrents
Дадатковая памяць пры праверцы торэнтаў
-
+
Disk cache
Кэш дыска
-
-
-
-
+
+
+
+
s
seconds
с
-
+
Disk cache expiry interval
Інтэрвал ачысткі дыскавага кэшу
-
+
Disk queue size
Памер чаргі дыска
-
-
+
+
Enable OS cache
Уключыць кэш АС
-
+
Coalesce reads & writes
Узбуйненне чытання і запісу
-
+
Use piece extent affinity
- Use piece extent affinity
+ Групаваць сумежныя часткі
-
+
Send upload piece suggestions
Адпраўляць прапановы частак раздачы
-
-
-
-
+
+
+
+
0 (disabled)
0 (адключана)
-
+
Save resume data interval [0: disabled]
How often the fastresume file is saved.
Інтэрвал захавання даных аднаўлення [0: адключана]
-
+
Outgoing ports (Min) [0: disabled]
Выходныя парты (мін) [0: адключана]
-
+
Outgoing ports (Max) [0: disabled]
Выходныя парты (макс) [0: адключана]
-
+
0 (permanent lease)
0 (пастаянная арэнда)
-
+
UPnP lease duration [0: permanent lease]
Працягласць арэнды UPnP [0: пастаянная арэнда]
-
+
Stop tracker timeout [0: disabled]
- Таймаўт прыпынку трэкера [0: адключана]
+ Час чакання спынення трэкера [0: адключана]
-
+
Notification timeout [0: infinite, -1: system default]
- Перапынак ў паведамленнях [0: бясконца, -1: сістэмнае значэнне]
+ Час чакання паведамлення [0: бясконца, -1: сістэмнае значэнне]
-
+
Maximum outstanding requests to a single peer
- Максімальная колькасць невыкананых запытаў да аднаго піра
+ Максімум нявырашаных запытаў да аднаго піра:
-
-
-
-
-
+
+
+
+
+
KiB
КБ
-
+
(infinite)
(бясконца)
-
+
(system default)
(сістэмнае значэнне)
-
+
+ Delete files permanently
+ Выдаляць файлы незваротна
+
+
+
+ Move files to trash (if possible)
+ Перамяшчаць файлы ў сметніцу (калі магчыма)
+
+
+
+ Torrent content removing mode
+ Рэжым выдалення змесціва торэнта
+
+
+
This option is less effective on Linux
Гэты варыянт меней эфектыўны ў Linux.
-
+
Process memory priority
Прыярытэт памяці працэсу
-
+
Bdecode depth limit
- Абмежаваньне глыбіні Bdecode
+ Абмежаванне глыбіні Bdecode
-
+
Bdecode token limit
- Абмежаваньне токена Bdecode
+ Абмежаванне токена Bdecode
-
+
Default
Па змаўчанні
-
+
Memory mapped files
- Файлы размешчаныя у памяці
+ Файлы размешчаныя ў памяці
-
+
POSIX-compliant
POSIX-сумяшчальны
-
- Disk IO type (requires restart)
- Тып дыскавага ўводу-вываду (патрабуецца перазагрузка)
+
+ Simple pread/pwrite
+
-
-
+
+ Disk IO type (requires restart)
+ Тып дыскавага ўводу-вываду (патрабуецца перазапуск)
+
+
+
+
Disable OS cache
Адключыць кэш АС
-
+
Disk IO read mode
Рэжым чытання дыскавага ўводу-вываду
-
+
Write-through
Скразны запіс
-
+
Disk IO write mode
Рэжым запісу дыскавага ўводу-вываду
-
+
Send buffer watermark
Адправіць вадзяны знак буфера
-
+
Send buffer low watermark
Адправіць нізкі вадзяны знак буфера
-
+
Send buffer watermark factor
Адправіць фактар вадзянога знака буфера
-
+
Outgoing connections per second
Выходныя злучэнні ў секунду
-
-
+
+
0 (system default)
0 (сістэмнае значэнне)
-
+
Socket send buffer size [0: system default]
Памер буфера адпраўлення сокета [0: сістэмнае значэнне]
-
+
Socket receive buffer size [0: system default]
Памер буфера прыёму сокета [0: сістэмнае значэнне]
-
+
Socket backlog size
- Socket backlog size
+ Памер чаргі сокета
-
+
.torrent file size limit
Абмежаванне памеру файла .torrent
-
+
Type of service (ToS) for connections to peers
- Type of service (ToS) for connections to peers
+ Тып абслугоўвання (ToS) для злучэння з пірамі
-
+
Prefer TCP
Перавага за TCP
-
+
Peer proportional (throttles TCP)
Прапарцыянальна пірам (рэгулюе TCP)
-
+
Support internationalized domain name (IDN)
- Support internationalized domain name (IDN)
+ Падтрымліваць інтэрнацыянальныя імёны даменаў (IDN)
-
+
Allow multiple connections from the same IP address
Дазволіць некалькі злучэнняў з аднаго IP-адраса
-
+
Validate HTTPS tracker certificates
- Validate HTTPS tracker certificates
-
-
-
- Server-side request forgery (SSRF) mitigation
- Server-side request forgery (SSRF) mitigation
-
-
-
- Disallow connection to peers on privileged ports
- Disallow connection to peers on privileged ports
-
-
-
- It appends the text to the window title to help distinguish qBittorent instances
-
-
-
-
- Customize application instance name
-
+ Правяраць сертыфікаты трэкераў HTTPS
- It controls the internal state update interval which in turn will affect UI updates
- It controls the internal state update interval which in turn will affect UI updates
+ Server-side request forgery (SSRF) mitigation
+ Папярэджваць серверную падробку запыту (SSRF)
-
+
+ Disallow connection to peers on privileged ports
+ Забараніць злучэнне з пірамі на прывілеяваных партах
+
+
+
+ It appends the text to the window title to help distinguish qBittorent instances
+ Дадае тэкст да загалоўка акна з мэтай адрознення экзэмпляраў qBittorent
+
+
+
+ Customize application instance name
+ Дапоўніць назву гэтага экзэмпляра праграмы
+
+
+
+ It controls the internal state update interval which in turn will affect UI updates
+ Кіруе інтэрвалам абнаўлення ўнутранага стану, які ўплывае на абнаўленне інтэрфейсу
+
+
+
Refresh interval
Інтэрвал абнаўлення
-
+
Resolve peer host names
Вызначыць назву хоста піра
-
+
IP address reported to trackers (requires restart)
Паведамляць трэкерам гэты IP-адрас (патрабуецца перазапуск)
-
+
Reannounce to all trackers when IP or port changed
- Reannounce to all trackers when IP or port changed
+ Пераанансаваць на ўсе трэкеры пры змене IP або порта
-
+
Enable icons in menus
Уключыць значкі ў меню
-
+
Enable port forwarding for embedded tracker
- Enable port forwarding for embedded tracker
+ Уключыць пракід партоў для ўбудаванага трэкера
-
+
Enable quarantine for downloaded files
- Увамкнуць карантын для сьцягнутых файлаў
+ Уключыць каранцін для спампаваных файлаў
-
+
Enable Mark-of-the-Web (MOTW) for downloaded files
+ Ставіць вэб-пазнаку (MOTW) на спампаваныя файлы
+
+
+
+ Affects certificate validation and non-torrent protocol activities (e.g. RSS feeds, program updates, torrent files, geoip db, etc)
-
- (Auto detect if empty)
- (Аўтавызначаць, калі пуста)
+
+ Ignore SSL errors
+ Ігнараваць памылкі SSL
-
+
+ (Auto detect if empty)
+ (Аўтавызначэнне, калі пуста)
+
+
+
Python executable path (may require restart)
Шлях да выконвальнага файла Python (можа спатрэбіцца перазапуск)
+ Start BitTorrent session in paused state
+ Запускаць сеанс qBittorrent спыненым
+
+
+
+ sec
+ seconds
+ с
+
+
+
+ -1 (unlimited)
+ -1 (неабмежавана)
+
+
+
+ BitTorrent session shutdown timeout [-1: unlimited]
+ Час чакання адключэння сеанса BitTorrent [-1: неабмежавана]
+
+
+
Confirm removal of tracker from all torrents
-
+ Пацвярджаць выдаленне трэкера з усіх торэнтаў
-
+
Peer turnover disconnect percentage
- Peer turnover disconnect percentage
-
-
-
- Peer turnover threshold percentage
- Peer turnover threshold percentage
-
-
-
- Peer turnover disconnect interval
- Peer turnover disconnect interval
-
-
-
- Resets to default if empty
-
-
-
-
- DHT bootstrap nodes
- Вузлы заладаваньня DHT
-
-
-
- I2P inbound quantity
- Колькасьць ўваходных паведамленьняў I2P
-
-
-
- I2P outbound quantity
- Колькасьць выходных паведамленьняў I2P
+ Працэнт адключэння для абароту піраў
+ Peer turnover threshold percentage
+ Працэнт абмежавання для абароту піраў
+
+
+
+ Peer turnover disconnect interval
+ Інтэрвал адключэння для абароту піраў
+
+
+
+ Resets to default if empty
+ Скінуць на значэнне па змаўчанні, калі пуста
+
+
+
+ DHT bootstrap nodes
+ Вузлы самазагрузкі DHT
+
+
+
+ I2P inbound quantity
+ Колькасць уваходных паведамленняў I2P
+
+
+
+ I2P outbound quantity
+ Колькасць выходных паведамленняў I2P
+
+
+
I2P inbound length
- Даўжыня ўваходных паведамленьняў I2P
+ Даўжыня ўваходных паведамленняў I2P
-
+
I2P outbound length
- Даўжыня выходных паведамленьняў I2P
+ Даўжыня выходных паведамленняў I2P
-
+
Display notifications
Паказваць апавяшчэнні
-
+
Display notifications for added torrents
- Паказваць апавяшчэнні для даданых торэнтаў
+ Паказваць апавяшчэнні для дададзеных торэнтаў
-
+
Download tracker's favicon
Загружаць значкі трэкераў
-
+
Save path history length
- Глыбіня гісторыя шляхоў захаваньня
+ Глыбіня гісторыя шляхоў захавання
-
+
Enable speed graphs
Уключыць графікі хуткасці
-
+
Fixed slots
Фіксаваныя слоты
-
+
Upload rate based
На аснове хуткасці раздачы
-
+
Upload slots behavior
Паводзіны слотаў раздачы
-
+
Round-robin
Кругавы
-
+
Fastest upload
Хутчэйшая раздача
-
+
Anti-leech
Анты-ліч
-
+
Upload choking algorithm
Алгарытм прыглушэння раздачы
-
+
Confirm torrent recheck
Пацвярджаць пераправерку торэнта
-
+
Confirm removal of all tags
Пацвярджаць выдаленне ўсіх тэгаў
-
+
Always announce to all trackers in a tier
Заўсёды анансаваць на ўсе трэкеры ва ўзроўні
-
+
Always announce to all tiers
Заўсёды анансаваць на ўсе ўзроўні
-
+
Any interface
i.e. Any network interface
Любы інтэрфейс
-
+
%1-TCP mixed mode algorithm
uTP-TCP mixed mode algorithm
- Алгарытм змешанага %1-TCP рэжыму
+ Алгарытм змяшанага %1-TCP рэжыму
-
+
Resolve peer countries
Вызначаць краіну піра
-
+
Network interface
- Сеткавы інтэрфэйс
+ Сеткавы інтэрфейс
-
+
Optional IP address to bind to
- Optional IP address to bind to
+ Неабавязковы IP-адрас для прывязкі
-
+
Max concurrent HTTP announces
- Max concurrent HTTP announces
+ Максімум адначасовых анонсаў HTTP
-
+
Enable embedded tracker
Задзейнічаць убудаваны трэкер
-
+
Embedded tracker port
Порт убудаванага трэкеру
+
+ AppController
+
+
+
+ Invalid directory path
+ Недапушчальны шлях каталога
+
+
+
+ Directory does not exist
+ Каталог не існуе
+
+
+
+ Invalid mode, allowed values: %1
+ Недапушчальны рэжым, магчымыя значэнні: %1
+
+
Application
-
+
Running in portable mode. Auto detected profile folder at: %1
- Running in portable mode. Auto detected profile folder at: %1
+ Выконваецца ў партатыўным рэжыме. Аўтаматычна вызначаная папка профілю: %1
-
+
Redundant command line flag detected: "%1". Portable mode implies relative fastresume.
- Redundant command line flag detected: "%1". Portable mode implies relative fastresume.
+
-
+
Using config directory: %1
- Using config directory: %1
+ Выкарыстоўваецца каталог налад: %1
-
+
Torrent name: %1
Імя торэнта: %1
-
+
Torrent size: %1
Памер торэнта: %1
-
+
Save path: %1
Шлях захавання: %1
-
+
The torrent was downloaded in %1.
The torrent was downloaded in 1 hour and 20 seconds
Торэнт быў спампаваны за %1.
-
+
+
Thank you for using qBittorrent.
Дзякуй за выкарыстанне qBittorrent.
-
+
Torrent: %1, sending mail notification
Торэнт: %1, адпраўка апавяшчэння на пошту
-
+
Add torrent failed
Не ўдалося дадаць торэнт
-
+
Couldn't add torrent '%1', reason: %2.
Не ўдалося дадаць торэнт «%1» з прычыны: %2.
-
+
The WebUI administrator username is: %1
- Імя адміністратара вэб-інтэрфейса: %1
+ Імя адміністратара вэб-інтэрфейсу: %1
-
+
The WebUI administrator password was not set. A temporary password is provided for this session: %1
- Пароль адміністратара вэб-інтэрфейса не быў зададзены. Для гэтага сеанса дадзены часовы пароль: %1
+ Пароль адміністратара вэб-інтэрфейсу не быў зададзены. Для гэтага сеанса дадзены часовы пароль: %1
-
+
You should set your own password in program preferences.
- Вам варта ўсталяваць уласны пароль у наладах праґрамы.
+ Вам варта задаць уласны пароль у наладах праграмы.
-
+
The WebUI is disabled! To enable the WebUI, edit the config file manually.
Вэб-інтэрфейс адключаны! Каб уключыць вэб-інтэрфейс, адрэдагуйце файл канфігурацыі ўручную.
-
+
Running external program. Torrent: "%1". Command: `%2`
Запуск знешняй праграмы. Торэнт: «%1». Каманда: `%2`
-
+
Failed to run external program. Torrent: "%1". Command: `%2`
Не ўдалося запусціць знешнюю праграму. Торэнт: «%1». Каманда: `%2`
-
+
Torrent "%1" has finished downloading
Спампоўванне торэнта '%1' завершана
-
+
WebUI will be started shortly after internal preparations. Please wait...
- Вэб-інтэрфейс хутка запусціцца пасля ўнутраннай падрыхтоўкі, Пачакайце...
+ Вэб-інтэрфейс хутка запусціцца пасля ўнутранай падрыхтоўкі. Пачакайце...
-
-
+
+
Loading torrents...
Загрузка торэнтаў...
-
+
E&xit
В&ыйсці
-
+
I/O Error
i.e: Input/Output Error
Памылка ўводу/вываду
-
+
An I/O error occurred for torrent '%1'.
Reason: %2
e.g: An error occurred for torrent 'xxx.avi'.
@@ -1437,100 +1504,110 @@
Прычына: %2
-
+
Torrent added
Торэнт дададзены
-
+
'%1' was added.
e.g: xxx.avi was added.
'%1' дададзены.
-
+
Download completed
Спампоўванне завершана
-
+
qBittorrent %1 started. Process ID: %2
qBittorrent v3.2.0alpha started
qBittorrent %1 запушчаны. Ідэнтыфікатар працэсу: %2
-
+
+ This is a test email.
+ Гэта праверачны электронны ліст.
+
+
+
+ Test email
+ Праверыць эл. пошту
+
+
+
'%1' has finished downloading.
e.g: xxx.avi has finished downloading.
Спампоўванне '%1' завершана.
-
+
Information
Інфармацыя
-
+
To fix the error, you may need to edit the config file manually.
- Для выпраўленьня памылкі Вам, відаць, спатрэбіцца ўласнаруч адрэдаґаваць канфігурацыйны файл.
+ Каб выправіць памылку, можа спатрэбіцца адрэдагаваць файл канфігурацыі ўручную.
-
+
To control qBittorrent, access the WebUI at: %1
Увайдзіце ў вэб-інтэрфейс для кіравання qBittorrent: %1
-
+
Exit
Выйсці
-
+
Recursive download confirmation
Пацвярджэнне рэкурсіўнага спампоўвання
-
+
The torrent '%1' contains .torrent files, do you want to proceed with their downloads?
- Торэнт '%1' змяшчае файлы .torrent, хочаце працягнуць спампоўванне з іх?
+ Торэнт «%1» змяшчае файлы .torrent, хочаце працягнуць спампоўванне з іх?
-
+
Never
Ніколі
-
+
Recursive download .torrent file within torrent. Source torrent: "%1". File: "%2"
Рэкурсіўнае спампоўванне файла .torrent з торэнта. Зыходны торэнт: «%1». Файл: «%2»
-
+
Failed to set physical memory (RAM) usage limit. Error code: %1. Error message: "%2"
Не ўдалося задаць абмежаванне на выкарыстанне фізічнай памяці (RAM). Код памылкі: %1. Тэкст памылкі: «%2»
-
+
Failed to set physical memory (RAM) usage hard limit. Requested size: %1. System hard limit: %2. Error code: %3. Error message: "%4"
Не ўдалося задаць жорсткае абмежаванне на выкарыстанне фізічнай памяці (RAM). Запытаны памер: %1. Жорсткае абмежаванне сістэмы: %2. Код памылкі: %3. Тэкст памылкі: «%4»
-
+
qBittorrent termination initiated
Пачалося завяршэнне працы qBittorrent
-
+
qBittorrent is shutting down...
Завяршэнне працы qBittorrent...
-
+
Saving torrent progress...
Захаванне стану торэнта...
-
+
qBittorrent is now ready to exit
Цяпер qBittorrent гатовы да выхаду
@@ -1548,7 +1625,7 @@
WebAPI login failure. Reason: IP has been banned, IP: %1, username: %2
- WebAPI login failure. Reason: IP has been banned, IP: %1, username: %2
+ Не ўдалося ўвайсці ў WebAPI. Прычына: IP быў забаронены, IP: %1, імя карыстальніка: %2
@@ -1558,7 +1635,7 @@
WebAPI login success. IP: %1
- WebAPI login success. IP: %1
+ Паспяховы ўваход у WebAPI. IP: %1
@@ -1596,12 +1673,12 @@
Auto downloading of RSS torrents is currently disabled. You can enable it in application settings.
- Аўтаспампоўванне торэнтаў з RSS на дадзены момант адключанае. Вы можаце ўключыць яго ў наладах праграмы.
+ Аўтаспампоўванне торэнтаў з RSS у бягучы момант адключана. Вы можаце ўключыць яго ў наладах праграмы.
Rename selected rule. You can also use the F2 hotkey to rename.
- Зьмена назвы абранага правіла. Для пераназваньня Вы таксама можаце выкарыстоўваць клявішу F2.
+ Перайменаванне выбранага правіла. Вы таксама можаце выкарыстоўваць клавішу F2.
@@ -1622,7 +1699,7 @@
Smart Episode Filter will check the episode number to prevent downloading of duplicates.
Supports the formats: S01E01, 1x1, 2017.12.31 and 31.12.2017 (Date formats also support - as a separator)
- Разумны фільтр праверыць нумары эпізодаў, каб прадухіліць спампоўванне паўтораў.
+ Разумны фільтр правярае нумары эпізодаў, каб прадухіліць паўторнае спампоўванне.
Падтрымліваюцца фарматы: S01E01, 1x1, 2017.12.31 і 31.12.2017 (таксама, як раздзяляльнік у датах, падтрымліваецца злучок - )
@@ -1634,17 +1711,17 @@ Supports the formats: S01E01, 1x1, 2017.12.31 and 31.12.2017 (Date formats also
Ignore Subsequent Matches for (0 to Disable)
... X days
- Ігнараваць наступныя супадзенні цягам (0 - адключана)
+ Ігнараваць наступныя супадзенні (0 - адключана)
Disabled
- Адключаны
+ Адключана
days
- дзён
+ дні/дзён
@@ -1715,7 +1792,7 @@ Supports the formats: S01E01, 1x1, 2017.12.31 and 31.12.2017 (Date formats also
Episode number is a mandatory positive value
- Нумар выпуску абавязкова павінен быць дадатным значэннем
+ Нумар эпізоду абавязкова павінен мець дадатнае значэнне
@@ -1735,12 +1812,12 @@ Supports the formats: S01E01, 1x1, 2017.12.31 and 31.12.2017 (Date formats also
Last Match: %1 days ago
- Апошні вынік: %1 дзён таму
+ Апошняе супадзенне: %1 дзён таму
Last Match: Unknown
- Апошні вынік: невядома
+ Апошняе супадзенне: невядома
@@ -1862,7 +1939,7 @@ Supports the formats: S01E01, 1x1, 2017.12.31 and 31.12.2017 (Date formats also
Regex mode: use Perl-compatible regular expressions
- Regex mode: use Perl-compatible regular expressions
+ Рэжым Regex: выкарыстоўваце рэгулярныя выразы як у Perl
@@ -1873,7 +1950,7 @@ Supports the formats: S01E01, 1x1, 2017.12.31 and 31.12.2017 (Date formats also
Wildcard mode: you can use
- Wildcard mode: you can use
+
@@ -1899,7 +1976,7 @@ Supports the formats: S01E01, 1x1, 2017.12.31 and 31.12.2017 (Date formats also
Whitespaces count as AND operators (all words, any order)
- Whitespaces count as AND operators (all words, any order)
+ Прабелы лічацца аператарам «І» (усе словы, любы парадак)
@@ -1915,7 +1992,7 @@ Supports the formats: S01E01, 1x1, 2017.12.31 and 31.12.2017 (Date formats also
An expression with an empty %1 clause (e.g. %2)
We talk about regex/wildcards in the RSS filters section here. So a valid sentence would be: An expression with an empty | clause (e.g. expr|)
- An expression with an empty %1 clause (e.g. %2)
+ Выраз з пустым аператарам %1 (прыклад %2)
@@ -1965,578 +2042,609 @@ Supports the formats: S01E01, 1x1, 2017.12.31 and 31.12.2017 (Date formats also
BitTorrent::BencodeResumeDataStorage
-
+
Cannot create torrent resume folder: "%1"
- Не атрымалася стварыць папку аднаўлення торэнта: «%1»
+ Не ўдалося стварыць папку ўзнаўлення торэнта: «%1»
-
+
Cannot parse resume data: invalid format
- Не ўдаецца праналізаваць даныя аднаўлення: памылковы фармат
+ Немагчыма прааналізаваць даныя ўзнаўлення: памылковы фармат
-
-
+
+
Cannot parse torrent info: %1
- Cannot parse torrent info: %1
+ Не ўдаецца прааналізаваць звесткі пра торэнт: : %1
-
+
Cannot parse torrent info: invalid format
- Не ўдаецца праналізаваць звесткі аб торэнце: памылковы фармат
+ Не ўдаецца прааналізаваць звесткі пра торэнт: памылковы фармат
-
+
Mismatching info-hash detected in resume data
- У дадзеных рэзюмэ выяўлены неадпаведны інфармацыйны хэш
+ У даных узнаўлення выяўлены неадпаведны хэш
-
+
Couldn't save torrent metadata to '%1'. Error: %2.
- Couldn't save torrent metadata to '%1'. Error: %2.
+ Не ўдалося захаваць метаданыя торэнта ў «%1». Памылка: %2
-
+
Couldn't save torrent resume data to '%1'. Error: %2.
- Couldn't save torrent resume data to '%1'. Error: %2.
+ Не ўдалося захаваць даныя ўзнаўлення торэнта ў «%1». Памылка: %2
-
+
Couldn't load torrents queue: %1
- Couldn't load torrents queue: %1
+ Не ўдалося загрузіць чаргу торэнтаў: %1
-
+
Cannot parse resume data: %1
- Cannot parse resume data: %1
+ Немагчыма прааналізаваць даныя ўзнаўлення: %1
-
+
Resume data is invalid: neither metadata nor info-hash was found
- Даныя аднаўлення памылковыя: метаданыя або інфа-хэш не знойдзеныя
+ Памылковыя даныя ўзнаўлення: метаданыя або інфа-хэш не знойдзены
-
+
Couldn't save data to '%1'. Error: %2
- Couldn't save data to '%1'. Error: %2
+ Не ўдалося захаваць даныя ў «%1». Памылка: %2
BitTorrent::DBResumeDataStorage
-
+
Not found.
Не знойдзена.
-
+
Couldn't load resume data of torrent '%1'. Error: %2
- Couldn't load resume data of torrent '%1'. Error: %2
+ Не ўдалося загрузіць даныя ўзнаўлення торэнта «%1». Памылка: %2
-
-
+
+
Database is corrupted.
База даных пашкоджана.
-
+
Couldn't enable Write-Ahead Logging (WAL) journaling mode. Error: %1.
-
+ Не ўдалося ўключыць рэжым папераджальнай журналізацыі. Памылка: %1.
-
+
Couldn't obtain query result.
- Ня выйшла атрымаць вынік запыту.
+ Не ўдалося атрымаць вынік запыту.
-
+
WAL mode is probably unsupported due to filesystem limitations.
-
+ Рэжым папераджальнай журналізацыі, імаверна, не падтрымліваецца праз абмежаванні файлавай сістэмы.
-
+
Couldn't begin transaction. Error: %1
- Немажліва пачаць транзакцыю. Памылка: %1
+ Не ўдалося пачаць трансакцыю. Памылка: %1
BitTorrent::ResumeDataStorage
-
+
Couldn't save torrent metadata. Error: %1.
- Couldn't save torrent metadata. Error: %1.
+ Не ўдалося захаваць метаданыя торэнта. Памылка: %1.
-
+
Couldn't store resume data for torrent '%1'. Error: %2
- Couldn't store resume data for torrent '%1'. Error: %2
+ Не ўдалося захаваць даныя ўзнаўлення торэнта «%1». Памылка: %2
-
+
Couldn't delete resume data of torrent '%1'. Error: %2
- Couldn't delete resume data of torrent '%1'. Error: %2
+ Не ўдалося выдаліць даныя ўзнаўлення торэнта «%1». Памылка: %2
-
+
Couldn't store torrents queue positions. Error: %1
- Couldn't store torrents queue positions. Error: %1
+ Не ўдалося захаваць чарговасць торэнтаў. Памылка: %1
BitTorrent::SessionImpl
-
-
+
+
Distributed Hash Table (DHT) support: %1
- Distributed Hash Table (DHT) support: %1
+ Падтрымка DHT: %1
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
ON
УКЛ
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
OFF
ВЫКЛ
-
-
+
+
Local Peer Discovery support: %1
- Local Peer Discovery support: %1
+ Падтрымка выяўлення лакальных піраў: %1
-
+
Restart is required to toggle Peer Exchange (PeX) support
- Restart is required to toggle Peer Exchange (PeX) support
+ Пераключэнне стану для падтрымкі абмену пірамі (PeX) патрабуе перазапуску
-
+
Failed to resume torrent. Torrent: "%1". Reason: "%2"
Не ўдалося ўзнавіць торэнт. Торэнт: «%1». Прычына: «%2»
-
-
+
+
Failed to resume torrent: inconsistent torrent ID is detected. Torrent: "%1"
- Failed to resume torrent: inconsistent torrent ID is detected. Torrent: "%1"
+ Не ўдалося ўзнавіць торэнт: выяўлены няўзгоднены ідэнтыфікатар. Прычына: «%1»
-
+
Detected inconsistent data: category is missing from the configuration file. Category will be recovered but its settings will be reset to default. Torrent: "%1". Category: "%2"
- Detected inconsistent data: category is missing from the configuration file. Category will be recovered but its settings will be reset to default. Torrent: "%1". Category: "%2"
+
-
+
Detected inconsistent data: invalid category. Torrent: "%1". Category: "%2"
Выяўленыя няўзгодненыя даныя: памылковая катэгорыя. Торэнт: «%1». Катэгорыя: «%2»
-
+
Detected mismatch between the save paths of the recovered category and the current save path of the torrent. Torrent is now switched to Manual mode. Torrent: "%1". Category: "%2"
- Detected mismatch between the save paths of the recovered category and the current save path of the torrent. Torrent is now switched to Manual mode. Torrent: "%1". Category: "%2"
+
-
+
Detected inconsistent data: tag is missing from the configuration file. Tag will be recovered. Torrent: "%1". Tag: "%2"
- Detected inconsistent data: tag is missing from the configuration file. Tag will be recovered. Torrent: "%1". Tag: "%2"
+
-
+
Detected inconsistent data: invalid tag. Torrent: "%1". Tag: "%2"
Выяўленыя няўзгодненыя даныя: памылковы тэг. Торэнт: «%1». Катэгорыя: «%2»
-
+
System wake-up event detected. Re-announcing to all the trackers...
- Выяўленая падзея абуджэньня сыстэмы. Паўторная абвестка для ўсіх трэкераў...
+ Выяўленая падзея абуджэння сістэмы. Паўторная абвестка для ўсіх трэкераў...
-
+
Peer ID: "%1"
- Peer ID: "%1"
+ ID піра: «%1»
-
+
HTTP User-Agent: "%1"
- HTTP User-Agent: "%1"
+ HTTP User-Agent: «%1»
-
+
Peer Exchange (PeX) support: %1
- Peer Exchange (PeX) support: %1
+ Падтрымка PeX (абмен пірамі): %1
-
-
+
+
Anonymous mode: %1
Ананімны рэжым: %1
-
-
+
+
Encryption support: %1
- Encryption support: %1
+ Падтрымка шыфравання: %1
-
-
+
+
FORCED
ПРЫМУСОВА
-
+
Could not find GUID of network interface. Interface: "%1"
- Could not find GUID of network interface. Interface: "%1"
+ Не ўдалося знайсці GUID сеткавага інтэрфейсу. Інтэрфейс: «%1»
-
+
Trying to listen on the following list of IP addresses: "%1"
- Trying to listen on the following list of IP addresses: "%1"
+ Спроба праслухоўвання наступнага спіса IP-адрасоў: «%1»
-
+
Torrent reached the share ratio limit.
Торэнт дасягнуў абмежавання рэйтынгу раздачы.
-
-
-
+
Torrent: "%1".
- Torrent: "%1".
+ Торэнт: «%1».
-
-
-
- Removed torrent.
- Выдалены торэнт.
+
+
+
+ Detected an attempt to add a duplicate torrent. Existing torrent: %1. Result: %2
+ Выяўлена спроба паўторнага дадавання наяўнага торэнта. Наяўны торэнт: %1. Вынік: %2
-
-
-
- Removed torrent and deleted its content.
- Removed torrent and deleted its content.
+
+ Merging of trackers is disabled
+ Аб'яднанне трэкераў адключана
-
-
-
- Torrent paused.
- Торэнт спынены.
+
+ Trackers cannot be merged because it is a private torrent
+ Немагчыма дадаць трэкеры, бо гэта прыватны торэнт
-
-
-
+
+ Trackers are merged from new source
+ Трэкеры з новай крыніцы дададзены
+
+
+
+ Failed to remove partfile. Torrent: "%1". Reason: "%2".
+ Не ўдалося выдаліць часткова спампаваны файл. Торэнт: «%1». Прычына: «%2»
+
+
+
Super seeding enabled.
- Super seeding enabled.
+ Суперраздача ўключана.
-
+
Torrent reached the seeding time limit.
- Torrent reached the seeding time limit.
+ Торэнт дасягнуў абмежавання часу раздачы.
-
+
Torrent reached the inactive seeding time limit.
-
+ Торэнт дасягнуў абмежавання часу бяздзейнасці раздачы.
-
+
Failed to load torrent. Reason: "%1"
Не ўдалося загрузіць торэнт. Прычына «%1»
-
+
I2P error. Message: "%1".
Памылка I2P. Паведамленне: «%1».
-
+
UPnP/NAT-PMP support: ON
Падтрымка UPnP/ AT-PMP: Укл
-
+
+ Saving resume data completed.
+ Запіс даных аднаўлення завершаны.
+
+
+
+ BitTorrent session successfully finished.
+ Сеанс BitTorrent паспяхова завершаны.
+
+
+
+ Session shutdown timed out.
+ Скончыўся час чакання для завяршэння сеанса.
+
+
+
+ Removing torrent.
+ Выдаленне торэнта.
+
+
+
+ Removing torrent and deleting its content.
+ Выдаленне торэнта і яго змесціва.
+
+
+
+ Torrent stopped.
+ Торэнт спынены.
+
+
+
+ Torrent content removed. Torrent: "%1"
+ Змесціва торэнта выдалена. Торэнт: «%1»
+
+
+
+ Failed to remove torrent content. Torrent: "%1". Error: "%2"
+ Не ўдалося выдаліць змесціва торэнта. Торэнт: «%1». Памылка: «%2»
+
+
+
+ Torrent removed. Torrent: "%1"
+ Торэнт выдалены. Торэнт: «%1»
+
+
+
UPnP/NAT-PMP support: OFF
Падтрымка UPnP/ AT-PMP: Адкл
-
+
Failed to export torrent. Torrent: "%1". Destination: "%2". Reason: "%3"
Не ўдалося экспартаваць торэнт «%1». Месца прызначэння: «%2». Прычына: «%3»
-
+
Aborted saving resume data. Number of outstanding torrents: %1
- Aborted saving resume data. Number of outstanding torrents: %1
+ Запіс даных узнаўлення перарваны. Колькасць неапрацаваных торэнтаў: %1
-
+
The configured network address is invalid. Address: "%1"
Наладжаны сеткавы адрас памылковы. Адрас: «%1»
-
-
+
+
Failed to find the configured network address to listen on. Address: "%1"
- Failed to find the configured network address to listen on. Address: "%1"
+ Не ўдалося знайсці наладжаны сеткавы адрас для праслухоўвання. Адрас: «%1»
-
+
The configured network interface is invalid. Interface: "%1"
Наладжаны сеткавы інтэрфейс памылковы. Інтэрфейс: «%1»
-
+
Rejected invalid IP address while applying the list of banned IP addresses. IP: "%1"
- Адхілены памылковы IP-адрас падчас ўжывання спісу забароненых IP-адрасоў. IP: «%1»
+ Адхілены памылковы IP-адрас падчас ужывання спіса забароненых IP-адрасоў. IP: «%1»
-
+
Added tracker to torrent. Torrent: "%1". Tracker: "%2"
- Added tracker to torrent. Torrent: "%1". Tracker: "%2"
+ Трэкер дададзены ў торэнт. Торэнт: «%1». Трэкер: «%2»
-
+
Removed tracker from torrent. Torrent: "%1". Tracker: "%2"
- Removed tracker from torrent. Torrent: "%1". Tracker: "%2"
+ Трэкер выдалены з торэнта. Торэнт: «%1». Трэкер: «%2»
-
+
Added URL seed to torrent. Torrent: "%1". URL: "%2"
- Added URL seed to torrent. Torrent: "%1". URL: "%2"
+ Дададзены адрас сіда ў торэнт. Торэнт: «%1». Адрас: «%2»
-
+
Removed URL seed from torrent. Torrent: "%1". URL: "%2"
- Removed URL seed from torrent. Torrent: "%1". URL: "%2"
+ Выдалены адрас сіда з торэнта. Торэнт: «%1». Адрас: «%2»
-
- Torrent paused. Torrent: "%1"
- Торэнт спынены. Торэнт: «%1»
-
-
-
+
Torrent resumed. Torrent: "%1"
- Torrent resumed. Torrent: "%1"
+ Торэнт узноўлены. Торэнт: «%1»
-
+
Torrent download finished. Torrent: "%1"
- Torrent download finished. Torrent: "%1"
+ Спампоўванне торэнта завершана. Торэнт: «%1»
-
+
Torrent move canceled. Torrent: "%1". Source: "%2". Destination: "%3"
Перамяшчэнне торэнта скасавана. Торэнт: «%1». Крыніца: «%2». Месца прызначэння: «%3»
-
+
+ Torrent stopped. Torrent: "%1"
+ Торэнт спынены. Торэнт: «%1»
+
+
+
Failed to enqueue torrent move. Torrent: "%1". Source: "%2". Destination: "%3". Reason: torrent is currently moving to the destination
Не ўдалося паставіць перамяшчэнне торэнта ў чаргу. Торэнт: «%1». Крыніца: «%2». Месца прызначэння: «%3». Прычына: торэнт зараз перамяшчаецца ў месца прызначэння
-
+
Failed to enqueue torrent move. Torrent: "%1". Source: "%2" Destination: "%3". Reason: both paths point to the same location
Не ўдалося паставіць перамяшчэнне торэнта ў чаргу. Торэнт: «%1». Крыніца: «%2». Месца прызначэння: «%3». Прычына: абодва шляхі ўказваюць на адно размяшчэнне
-
+
Enqueued torrent move. Torrent: "%1". Source: "%2". Destination: "%3"
Перамяшчэнне торэнта пастаўлена ў чаргу. Торэнт: «%1». Крыніца: «%2». Месца прызначэння: «%3»
-
+
Start moving torrent. Torrent: "%1". Destination: "%2"
Пачалося перамяшчэнне торэнта. Торэнт: «%1». Месца прызначэння: «%2»
-
+
Failed to save Categories configuration. File: "%1". Error: "%2"
- Failed to save Categories configuration. File: "%1". Error: "%2"
+ Не ўдалося захаваць канфігурацыю катэгорый. Файл: «%1». Памылка: «%2»
-
+
Failed to parse Categories configuration. File: "%1". Error: "%2"
- Failed to parse Categories configuration. File: "%1". Error: "%2"
+ Не ўдалося прааналізаваць канфігурацыю катэгорый. Файл: «%1». Памылка: «%2»
-
+
Successfully parsed the IP filter file. Number of rules applied: %1
- Successfully parsed the IP filter file. Number of rules applied: %1
-
-
-
- Failed to parse the IP filter file
- Failed to parse the IP filter file
-
-
-
- Restored torrent. Torrent: "%1"
- Restored torrent. Torrent: "%1"
-
-
-
- Added new torrent. Torrent: "%1"
- Added new torrent. Torrent: "%1"
-
-
-
- Torrent errored. Torrent: "%1". Error: "%2"
- Torrent errored. Torrent: "%1". Error: "%2"
-
-
-
-
- Removed torrent. Torrent: "%1"
- Removed torrent. Torrent: "%1"
-
-
-
- Removed torrent and deleted its content. Torrent: "%1"
- Removed torrent and deleted its content. Torrent: "%1"
-
-
-
- Torrent is missing SSL parameters. Torrent: "%1". Message: "%2"
-
+
+ Failed to parse the IP filter file
+ Не ўдалося прааналізаваць файл IP-фільтра
+
+
+
+ Restored torrent. Torrent: "%1"
+ Торэнт адноўлены. Торэнт: «%1»
+
+
+
+ Added new torrent. Torrent: "%1"
+ Дададзены новы торэнт. Торэнт: «%1»
+
+
+
+ Torrent errored. Torrent: "%1". Error: "%2"
+ Памылка торэнта .Торэнт: «%1». Памылка: «%2»
+
+
+
+ Torrent is missing SSL parameters. Torrent: "%1". Message: "%2"
+ У торэнце прапушчаныя параметры SSL. Торэнт: «%1». Паведамленне: «%2»
+
+
+
File error alert. Torrent: "%1". File: "%2". Reason: "%3"
- File error alert. Torrent: "%1". File: "%2". Reason: "%3"
+ Папярэджанне пра памылку файла. Торэнт: «%1». Файл: «%2». Прычына: «%3»
-
+
UPnP/NAT-PMP port mapping failed. Message: "%1"
- UPnP/NAT-PMP port mapping failed. Message: "%1"
+ Не ўдалося перанакіраваць парты UPnP/NAT-PMP. Паведамленне: «%1»
-
+
UPnP/NAT-PMP port mapping succeeded. Message: "%1"
- UPnP/NAT-PMP port mapping succeeded. Message: "%1"
+ Перанакіраванне партоў UPnP/NAT-PMP выканана. Паведамленне: «%1»
-
+
IP filter
this peer was blocked. Reason: IP filter.
IP-фільтр
-
+
filtered port (%1)
this peer was blocked. Reason: filtered port (8899).
-
+ адфільтраваны порт (%1)
-
+
privileged port (%1)
this peer was blocked. Reason: privileged port (80).
-
+ прывілеяваны порт (%1)
-
+
BitTorrent session encountered a serious error. Reason: "%1"
- У сэансе BitTorrent выявілася сур'ёзная памылка. Чыньнік: "%1"
+ У сеансе BitTorrent выявілася сур'ёзная памылка. Прычына: «%1»
-
+
SOCKS5 proxy error. Address: %1. Message: "%2".
- Памылка проксі SOCKS5. Адрас: %1. Паведамленьне: "%2".
+ Памылка проксі SOCKS5. Адрас: %1. Паведамленне: «%2».
-
+
%1 mixed mode restrictions
this peer was blocked. Reason: I2P mixed mode restrictions.
- %1 абмежаванні ў змешаным рэжыме
+ %1 абмежаванні ў змяшаным рэжыме
-
+
Failed to load Categories. %1
Не ўдалося загрузіць катэгорыі. %1
-
+
Failed to load Categories configuration. File: "%1". Error: "Invalid data format"
Не ўдалося загрузіць канфігурацыю катэгорый. Файл: «%1». Памылка: «Памылковы фармат даных»
-
- Removed torrent but failed to delete its content and/or partfile. Torrent: "%1". Error: "%2"
- Removed torrent but failed to delete its content and/or partfile. Torrent: "%1". Error: "%2"
-
-
-
+
%1 is disabled
this peer was blocked. Reason: uTP is disabled.
%1 адключаны
-
+
%1 is disabled
this peer was blocked. Reason: TCP is disabled.
%1 адключаны
-
+
URL seed DNS lookup failed. Torrent: "%1". URL: "%2". Error: "%3"
- URL seed DNS lookup failed. Torrent: "%1". URL: "%2". Error: "%3"
+ Пошук адраса сіда ў DNS не ўдаўся. Торэнт: «%1». Адрас: «%2». Памылка: «%3»
-
+
Received error message from URL seed. Torrent: "%1". URL: "%2". Message: "%3"
- Received error message from URL seed. Torrent: "%1". URL: "%2". Message: "%3"
+ Атрымана паведамленне пра памылку ад адраса сіда. Торэнт: «%1». Адрас: «%2». Паведамленне: «%3»
-
+
Successfully listening on IP. IP: "%1". Port: "%2/%3"
- Successfully listening on IP. IP: "%1". Port: "%2/%3"
+ Паспяховае праслухоўванне IP. IP: «%1». Порт: «%2/%3»
-
+
Failed to listen on IP. IP: "%1". Port: "%2/%3". Reason: "%4"
- Failed to listen on IP. IP: "%1". Port: "%2/%3". Reason: "%4"
+ Не ўдалося праслухаць IP. IP: «%1». Порт: «%2/%3». Прычына: «%4»
-
+
Detected external IP. IP: "%1"
- Detected external IP. IP: "%1"
+ Выяўлены знешні IP. IP: «%1»
-
+
Error: Internal alert queue is full and alerts are dropped, you might see degraded performance. Dropped alert type: "%1". Message: "%2"
- Error: Internal alert queue is full and alerts are dropped, you might see degraded performance. Dropped alert type: "%1". Message: "%2"
+
-
+
Moved torrent successfully. Torrent: "%1". Destination: "%2"
- Торэнт паспяхова перамяшчэнны. Торэнт: «%1». Месца прызначэння: «%2»
+ Торэнт паспяхова перамешчаны. Торэнт: «%1». Месца прызначэння: «%2»
-
+
Failed to move torrent. Torrent: "%1". Source: "%2". Destination: "%3". Reason: "%4"
Не ўдалося перамясціць торэнт; «%1». Крыніца: «%2». Месца прызначэння: «%3». Прычына: «%4»
@@ -2546,89 +2654,89 @@ Supports the formats: S01E01, 1x1, 2017.12.31 and 31.12.2017 (Date formats also
Failed to start seeding.
-
+ Не ўдалося запусціць раздачу.
BitTorrent::TorrentCreator
-
+
Operation aborted
- Operation aborted
+ Аперацыя перапынена
-
-
+
+
Create new torrent file failed. Reason: %1.
- Create new torrent file failed. Reason: %1.
+ Не ўдалася стварыць новы торэнт. Прычына: %1.
BitTorrent::TorrentImpl
-
+
Failed to add peer "%1" to torrent "%2". Reason: %3
- Failed to add peer "%1" to torrent "%2". Reason: %3
+ Не ўдалося дадаць пір «%1» у торэнт «%2». Прычына: %3
-
+
Peer "%1" is added to torrent "%2"
- Peer "%1" is added to torrent "%2"
+ Пір «%1» дададзены ў торэнт «%2»
-
+
Unexpected data detected. Torrent: %1. Data: total_wanted=%2 total_wanted_done=%3.
Выяўлены нечаканыя даныя. Торэнт: %1. Даныя: total_wanted=%2 total_wanted_done=%3.
-
+
Couldn't write to file. Reason: "%1". Torrent is now in "upload only" mode.
- Couldn't write to file. Reason: "%1". Torrent is now in "upload only" mode.
+ Не ўдалося запісаць у файл. Прычына: «%1». Торэнт цяпер у рэжыме «толькі аддача».
-
+
Download first and last piece first: %1, torrent: '%2'
Спачатку пампаваць першую і апошнюю часткі: %1, торэнт: '%2'
-
+
On
Укл.
-
+
Off
Выкл.
-
+
Failed to reload torrent. Torrent: %1. Reason: %2
- Збой паўторнага заладаваньня торэнта. Торэнт: %1. Чыньнік: %2
+ Збой паўторнай загрузкі торэнта. Торэнт: %1. Прычына: %2
-
+
Generate resume data failed. Torrent: "%1". Reason: "%2"
- Generate resume data failed. Torrent: "%1". Reason: "%2"
+ Не ўдалося стварыць даныя ўзнаўлення. Торэнт: «%1». Прычына: «%2»
-
+
Failed to restore torrent. Files were probably moved or storage isn't accessible. Torrent: "%1". Reason: "%2"
- Failed to restore torrent. Files were probably moved or storage isn't accessible. Torrent: "%1". Reason: "%2"
+ Не ўдалося аднавіць торэнт. Магчыма, файлы перамешчаны або сховішча недаступна. Торэнт: «%1». Прычына: «%2»
-
+
Missing metadata
- Missing metadata
+ Метаданыя адсутнічаюць
-
+
File rename failed. Torrent: "%1", file: "%2", reason: "%3"
Не ўдалося перайменаваць файл. Торэнт: «%1», файл: «%2», прычына: «%3»
-
+
Performance alert: %1. More info: %2
- Performance alert: %1. More info: %2
+ Папярэджанне аб прадукцыйнасці: %1. Больш інфармацыі: %2
@@ -2636,12 +2744,12 @@ Supports the formats: S01E01, 1x1, 2017.12.31 and 31.12.2017 (Date formats also
Embedded Tracker: Now listening on IP: %1, port: %2
- Embedded Tracker: Now listening on IP: %1, port: %2
+ Убудаваны трэкер: зараз праслухоўваецца IP: %1, порт: %2
Embedded Tracker: Unable to bind to IP: %1, port: %2. Reason: %3
- Embedded Tracker: Unable to bind to IP: %1, port: %2. Reason: %3
+ Убудаваны трэкер: немагчыма прывязаць IP: %1, порт: %2. Прычына: %3
@@ -2663,12 +2771,6 @@ Supports the formats: S01E01, 1x1, 2017.12.31 and 31.12.2017 (Date formats also
Expected integer number in environment variable '%1', but got '%2'
Чакаўся цэлы лік у пераменнай асяроддзя − '%1', але атрымана '%2'
-
-
- Parameter '%1' must follow syntax '%1=%2'
- e.g. Parameter '--add-paused' must follow syntax '--add-paused=<true|false>'
- Параметр '%1' павінен прытрымлівацца сінтаксісу '%1=%2'
-
Expected %1 in environment variable '%2', but got '%3'
@@ -2698,17 +2800,23 @@ Supports the formats: S01E01, 1x1, 2017.12.31 and 31.12.2017 (Date formats also
Display program version and exit
- Паказваць версію праграмы і выхад
+ Паказаць версію праграмы і выйсці
Display this help message and exit
- Паказваць гэтую даведку і выхад
+ Паказаць гэтую даведку і выйсці
+
+
+
+ Parameter '%1' must follow syntax '%1=%2'
+ e.g. Parameter '--add-stopped' must follow syntax '--add-stopped=<true|false>'
+ Параметр '%1' павінен прытрымлівацца сінтаксісу '%1=%2'
Confirm the legal notice
-
+ Пацвердзіце афіцыйнае апавяшчэнне
@@ -2719,12 +2827,12 @@ Supports the formats: S01E01, 1x1, 2017.12.31 and 31.12.2017 (Date formats also
Change the WebUI port
- Змяніць порт вэб-інтэрфейса
+ Змяніць порт вэб-інтэрфейсу
Change the torrenting port
- Change the torrenting port
+ Змяніць порт торэнта
@@ -2761,7 +2869,7 @@ Supports the formats: S01E01, 1x1, 2017.12.31 and 31.12.2017 (Date formats also
Hack into libtorrent fastresume files and make file paths relative to the profile directory
- Hack into libtorrent fastresume files and make file paths relative to the profile directory
+
@@ -2790,13 +2898,13 @@ Supports the formats: S01E01, 1x1, 2017.12.31 and 31.12.2017 (Date formats also
- Add torrents as started or paused
+ Add torrents as running or stopped
Дадаваць торэнты як запушчаныя або спыненыя
Skip hash check
- Прапусціць праверку хэша
+ Прапусціць праверку хэшу
@@ -2821,7 +2929,7 @@ Supports the formats: S01E01, 1x1, 2017.12.31 and 31.12.2017 (Date formats also
Option values may be supplied via environment variables. For option named 'parameter-name', environment variable name is 'QBT_PARAMETER_NAME' (in upper case, '-' replaced with '_'). To pass flag values, set the variable to '1' or 'TRUE'. For example, to disable the splash screen:
- Option values may be supplied via environment variables. For option named 'parameter-name', environment variable name is 'QBT_PARAMETER_NAME' (in upper case, '-' replaced with '_'). To pass flag values, set the variable to '1' or 'TRUE'. For example, to disable the splash screen:
+
@@ -2857,12 +2965,12 @@ Supports the formats: S01E01, 1x1, 2017.12.31 and 31.12.2017 (Date formats also
Add category...
- Дадаць катэґорыю...
+ Дадаць катэгорыю...
Add subcategory...
- Дадаць падкатэґорыю...
+ Дадаць падкатэгорыю...
@@ -2881,12 +2989,12 @@ Supports the formats: S01E01, 1x1, 2017.12.31 and 31.12.2017 (Date formats also
- Resume torrents
- Узнавіць торэнты
+ Start torrents
+ Запусціць торэнты
- Pause torrents
+ Stop torrents
Спыніць торэнты
@@ -2898,15 +3006,20 @@ Supports the formats: S01E01, 1x1, 2017.12.31 and 31.12.2017 (Date formats also
ColorWidget
-
+
Edit...
- Рэдаґаваць...
+ Рэдагаваць...
-
+
Reset
Скінуць
+
+
+ System
+ Сістэма
+
CookiesDialog
@@ -2947,12 +3060,12 @@ Supports the formats: S01E01, 1x1, 2017.12.31 and 31.12.2017 (Date formats also
CustomThemeSource
-
+
Failed to load custom theme style sheet. %1
Не ўдалося загрузіць табліцу стыляў уласнай тэмы. %1
-
+
Failed to load custom theme colors. %1
Не ўдалося загрузіць уласныя колеры тэмы. %1
@@ -2960,9 +3073,9 @@ Supports the formats: S01E01, 1x1, 2017.12.31 and 31.12.2017 (Date formats also
DefaultThemeSource
-
+
Failed to load default theme colors. %1
- Не ўдалося загрузіць прадвызначаныя колеры тэмы. %1
+ Не ўдалося загрузіць колеры тэмы па змаўчанні. %1
@@ -2979,23 +3092,23 @@ Supports the formats: S01E01, 1x1, 2017.12.31 and 31.12.2017 (Date formats also
- Also permanently delete the files
- Таксама незваротна выдаліць файлы
+ Also remove the content files
+ Таксама выдаліць спампаваныя файлы
-
+
Are you sure you want to remove '%1' from the transfer list?
Are you sure you want to remove 'ubuntu-linux-iso' from the transfer list?
Сапраўды хочаце выдаліць «%1» са спіса?
-
+
Are you sure you want to remove these %1 torrents from the transfer list?
Are you sure you want to remove these 5 torrents from the transfer list?
- Сапраўды хочаце выдаліць %1 торэнты(аў) са спісу?
+ Сапраўды хочаце выдаліць %1 торэнты(аў) са спіса?
-
+
Remove
Выдаліць
@@ -3010,7 +3123,7 @@ Supports the formats: S01E01, 1x1, 2017.12.31 and 31.12.2017 (Date formats also
Add torrent links
- Дадаць спасылкі на торэнты
+ Дадайце спасылкі на торэнт
@@ -3023,14 +3136,14 @@ Supports the formats: S01E01, 1x1, 2017.12.31 and 31.12.2017 (Date formats also
Спампаваць
-
+
No URL entered
Няма URL адраса
-
+
Please type at least one URL.
- Увядзіце хаця б адзін адрас URL.
+ Увядзіце прынамсі адзін URL.
@@ -3135,45 +3248,45 @@ Supports the formats: S01E01, 1x1, 2017.12.31 and 31.12.2017 (Date formats also
I/O Error: Could not open IP filter file in read mode.
- I/O Error: Could not open IP filter file in read mode.
+ Памылка ўводу/вываду: Не ўдалося адкрыць файл IP-фільтра ў рэжыме чытання.
IP filter line %1 is malformed.
- IP filter line %1 is malformed.
+ Радок IP-фільтра %1 мае няправільны фармат.
IP filter line %1 is malformed. Start IP of the range is malformed.
- IP filter line %1 is malformed. Start IP of the range is malformed.
+ Радок IP-фільтра %1 мае няправільны фармат. Няправільны фармат пачатковага IP у дыяпазоне адрасоў.
IP filter line %1 is malformed. End IP of the range is malformed.
- IP filter line %1 is malformed. End IP of the range is malformed.
+ Радок IP-фільтра %1 мае няправільны фармат. Няправільны фармат канцавога IP у дыяпазоне адрасоў.
IP filter line %1 is malformed. One IP is IPv4 and the other is IPv6!
- IP filter line %1 is malformed. One IP is IPv4 and the other is IPv6!
+ Радок IP-фільтра %1 мае няправільны фармат. Адзін IP-адрас у фармаце IPv4, а другі — у IPv6.
IP filter exception thrown for line %1. Exception is: %2
- IP filter exception thrown for line %1. Exception is: %2
+
%1 extra IP filter parsing errors occurred.
513 extra IP filter parsing errors occurred.
- %1 extra IP filter parsing errors occurred.
+
@@ -3187,25 +3300,48 @@ Supports the formats: S01E01, 1x1, 2017.12.31 and 31.12.2017 (Date formats also
Памылка разбору: Файл фільтра не з'яўляецца правільным файлам PeerGuardian P2B.
+
+ FilterPatternFormatMenu
+
+
+ Pattern Format
+ Фармат шаблона
+
+
+
+ Plain text
+ Звычайны тэкст
+
+
+
+ Wildcards
+
+
+
+
+ Regular expression
+ Рэгулярны выраз
+
+
GUIAddTorrentManager
-
+
Downloading torrent... Source: "%1"
Спампоўванне торэнта... Крыніца: «%1»
-
- Trackers cannot be merged because it is a private torrent
- Немагчыма дадаць трэкеры, бо гэта прыватны торэнт
-
-
-
+
Torrent is already present
Торэнт ужо існуе
-
+
+ Trackers cannot be merged because it is a private torrent.
+
+
+
+
Torrent '%1' is already in the transfer list. Do you want to merge trackers from new source?
Торэнт «%1» ужо ёсць у спісе. Хочаце дадаць трэкеры з новай крыніцы?
@@ -3252,19 +3388,19 @@ Supports the formats: S01E01, 1x1, 2017.12.31 and 31.12.2017 (Date formats also
Http::Connection
-
+
Http request size exceeds limitation, closing socket. Limit: %1, IP: %2
- Http request size exceeds limitation, closing socket. Limit: %1, IP: %2
+ Памер HTTP-запыту перавышае абмежаванне, сокет закрываецца. Абмежаванне: %1, IP: %2
-
+
Bad Http request method, closing socket. IP: %1. Method: "%2"
- Хібны мэтад запыту Http, закрыцьцё сокета. IP: %1. Мэтад: "%2"
+ Хібны метад запыту Http, закрыццё сокета. IP: %1. Метад: «%2»
-
+
Bad Http request, closing socket. IP: %1
- Bad Http request, closing socket. IP: %1
+ Хібны метад запыту Http, закрыццё сокета. IP: %1
@@ -3303,22 +3439,22 @@ Supports the formats: S01E01, 1x1, 2017.12.31 and 31.12.2017 (Date formats also
IconWidget
-
+
Browse...
Агляд...
-
+
Reset
Скінуць
-
+
Select icon
Выбраць значок
-
+
Supported image files
Файлы відарысаў, якія падтрымліваюцца
@@ -3333,34 +3469,34 @@ Supports the formats: S01E01, 1x1, 2017.12.31 and 31.12.2017 (Date formats also
qBittorrent is a file sharing program. When you run a torrent, its data will be made available to others by means of upload. Any content you share is your sole responsibility.
- qBittorrent is a file sharing program. When you run a torrent, its data will be made available to others by means of upload. Any content you share is your sole responsibility.
+ qBittorrent - гэта праграма для абмену файламі. Пры запуску торэнта, даныя з яго пачынаюць раздавацца і становяцца даступны іншым карыстальнікам. Вы несяце персанальную адказнасць за ўсё змесціва, якім дзеліцеся.
No further notices will be issued.
- No further notices will be issued.
+ Ніякіх дадатковых перасцярог паказвацца не будзе.
If you have read the legal notice, you can use command line option `--confirm-legal-notice` to suppress this message.
-
+ Калі вы прачыталі афіцыйную перасцярогу, можаце выкарыстоўваць параметр каманднага радка `--confirm-legal-notice`, каб адключыць гэтае паведамленне.
Press 'Enter' key to continue...
- Для працягу націсьніце "Enter"...
+ Каб працягнуць, націсніце «Enter»…
LogPeerModel
-
+
%1 was blocked. Reason: %2.
0.0.0.0 was blocked. Reason: reason for blocking.
- %1 was blocked. Reason: %2.
+ %1 заблакаваны. Прычына: %2.
-
+
%1 was banned
0.0.0.0 was banned
%1 заблакаваны
@@ -3369,62 +3505,62 @@ Supports the formats: S01E01, 1x1, 2017.12.31 and 31.12.2017 (Date formats also
Main
-
+
%1 is an unknown command line parameter.
--random-parameter is an unknown command line parameter.
%1 - невядомы параметр .каманднага радка.
-
-
+
+
%1 must be the single command line parameter.
%1 павінна быць адзіным параметрам каманднага радка.
-
+
Run application with -h option to read about command line parameters.
Запусціце праграму з параметрам -h, каб атрымаць даведку па параметрах каманднага радка.
-
+
Bad command line
Праблемны камандны радок
-
+
Bad command line:
Праблемны камандны радок:
-
+
An unrecoverable error occurred.
- Узьнікла неадольная памылка.
+ Узнікла невырашальная памылка.
+
-
qBittorrent has encountered an unrecoverable error.
qBittorrent выявіў неадольную памылку.
-
+
You cannot use %1: qBittorrent is already running.
- Немажліва выкарыстаць %1: qBittorrent ужо запушчаны.
+ Немагчыма выкарыстаць %1: qBittorrent ужо запушчаны.
-
+
Another qBittorrent instance is already running.
- Іншы асобнік qBittorrent ужо запушчаны.
+ Іншы экзэмпляр qBittorrent ужо запушчаны.
+
+
+
+ Found unexpected qBittorrent instance. Exiting this instance. Current process ID: %1.
+ Знойдзены нечаканы экзэмпляр qBittorrent. Гэты экзэмпляр будзе закрыты. Ідэнтыфікатар бягучага працэсу: %1.
- Found unexpected qBittorrent instance. Exiting this instance. Current process ID: %1.
- Выяўлены нечаканы асобнік qBittorrent. Гэты асобнік будзе закрыты. Ідэнтыфікатар актыўнага працэсу:% 1.
-
-
-
Error when daemonizing. Reason: "%1". Error code: %2.
- Памылка ў час ''дэманізацыі''. Чыньнік: "%1". Код памылкі: %2.
+ Памылка ў час дэманізацыі. Прычына: «%1». Код памылкі: %2.
@@ -3432,612 +3568,617 @@ Supports the formats: S01E01, 1x1, 2017.12.31 and 31.12.2017 (Date formats also
&Edit
- &Рэдаґаваць
+ &Рэдагаваць
-
+
&Tools
&Інструменты
-
+
&File
&Файл
-
+
&Help
&Даведка
-
+
On Downloads &Done
Па сканчэнні &спампоўванняў
-
+
&View
&Выгляд
-
+
&Options...
&Параметры...
-
- &Resume
- &Узнавіць
-
-
-
+
&Remove
&Выдаліць
-
+
Torrent &Creator
Стварыць &торэнт
-
-
+
+
Alternative Speed Limits
Альтэрнатыўныя абмежаванні хуткасці
-
+
&Top Toolbar
- Верхняя &панэль
+ &Верхняя панэль
-
+
Display Top Toolbar
Паказаць верхнюю панэль
-
+
Status &Bar
Панэль &стану
-
+
Filters Sidebar
Бакавая панэль
-
+
S&peed in Title Bar
- Х&уткасць у загалоўку
+ &Хуткасць у загалоўку
-
+
Show Transfer Speed in Title Bar
Паказваць хуткасць перадачы ў загалоўку акна
-
+
&RSS Reader
- Менеджар &RSS
+ &Менеджар RSS
-
+
Search &Engine
&Пошук
-
+
L&ock qBittorrent
- З&аблакіраваць qBittorrent
+ &Заблакіраваць qBittorrent
-
+
Do&nate!
Ах&вяраваць!
-
+
&Do nothing
&Нічога не рабіць
-
+
Close Window
Закрыць акно
-
- R&esume All
- У&знавіць усё
-
-
-
+
Manage Cookies...
Кіраванне cookie...
-
+
Manage stored network cookies
Кіраванне захаванымі файламі cookie
-
+
Normal Messages
Звычайныя паведамленні
-
+
Information Messages
Інфармацыйныя паведамленні
-
+
Warning Messages
Папярэджанні
-
+
Critical Messages
Крытычныя паведамленні
-
+
&Log
&Журнал
-
- Set Global Speed Limits...
- Set Global Speed Limits...
+
+ Sta&rt
+ &Запусціць
-
+
+ Sto&p
+ &Спыніць
+
+
+
+ &Resume Session
+ &Працягнуць сеанс
+
+
+
+ Pau&se Session
+ П&рыпыніць сеанс
+
+
+
+ Set Global Speed Limits...
+ Наладзіць хуткасць...
+
+
+
Bottom of Queue
У канец чаргі
-
+
Move to the bottom of the queue
Перамясціць у канец чаргі
-
+
Top of Queue
У пачатак чаргі
-
+
Move to the top of the queue
Перамясціць у пачатак чаргі
-
+
Move Down Queue
Панізіць у чарзе
-
+
Move down in the queue
Перамясціць у чарзе ніжэй
-
+
Move Up Queue
Падняць у чарзе
-
+
Move up in the queue
Перамясціць у чарзе вышэй
-
+
&Exit qBittorrent
&Выйсці з qBittorrent
-
+
&Suspend System
&Прыпыніць камп'ютар
-
+
&Hibernate System
- &Усыпіць камп'ютар
+ Перайсці ў &гібернацыю
-
+
S&hutdown System
- А&дключыць камп'ютар
+ Вы&ключыць камп'ютар
-
+
&Statistics
- &Статыстыка
+ С&татыстыка
-
+
Check for Updates
Праверыць абнаўленні
-
+
Check for Program Updates
Праверыць абнаўленні праграмы
-
+
&About
&Пра qBittorrent
-
- &Pause
- &Спыніць
-
-
-
- P&ause All
- С&пыніць усе
-
-
-
+
&Add Torrent File...
&Дадаць торэнт-файл...
-
+
Open
Адкрыць
-
+
E&xit
В&ыйсці
-
+
Open URL
Адкрыць URL
-
+
&Documentation
- &Дакумэнтацыя
+ &Дакументацыя
-
+
Lock
Заблакіраваць
-
-
-
+
+
+
Show
Паказаць
-
+
Check for program updates
Праверыць абнаўленні праграмы
-
+
Add Torrent &Link...
Дадаць &спасылку на торэнт...
-
+
If you like qBittorrent, please donate!
Калі вам падабаецца qBittorrent, калі ласка, зрабіце ахвяраванне!
-
-
+
+
Execution Log
Журнал выканання
-
+
Clear the password
Прыбраць пароль
-
+
&Set Password
&Задаць пароль
-
+
Preferences
Налады
-
+
&Clear Password
&Прыбраць пароль
-
+
Transfers
Перадачы
-
-
+
+
qBittorrent is minimized to tray
qBittorrent згорнуты ў вобласць апавяшчэнняў
-
-
-
+
+
+
This behavior can be changed in the settings. You won't be reminded again.
- This behavior can be changed in the settings. You won't be reminded again.
+
-
+
Icons Only
Толькі значкі
-
+
Text Only
Толькі тэкст
-
+
Text Alongside Icons
Тэкст поруч са значкамі
-
+
Text Under Icons
Тэкст пад значкамі
-
+
Follow System Style
Паводле сістэмнага стылю
-
-
+
+
UI lock password
Пароль блакіроўкі інтэрфейсу
-
-
+
+
Please type the UI lock password:
Увядзіце пароль, каб заблакіраваць інтэрфейс:
-
+
Are you sure you want to clear the password?
Сапраўды хочаце ачысціць пароль?
-
+
Use regular expressions
Выкарыстоўваць рэгулярныя выразы
-
+
Search
Пошук
-
+
Transfers (%1)
Перадачы (%1)
-
+
qBittorrent was just updated and needs to be restarted for the changes to be effective.
qBittorrent абнавіўся і патрабуе перазапуску для актывацыі новых функцый.
-
+
qBittorrent is closed to tray
qBittorrent закрыты ў вобласць апавяшчэнняў
-
+
Some files are currently transferring.
Некаторыя файлы зараз перадаюцца.
-
+
Are you sure you want to quit qBittorrent?
Сапраўды хочаце выйсці з qBittorrent?
-
+
&No
&Не
-
+
&Yes
&Так
-
+
&Always Yes
&Заўсёды Так
-
+
Options saved.
Параметры захаваны.
-
+
+ [PAUSED] %1
+ %1 is the rest of the window title
+ [ПРЫПЫНЕНЫ] %1
+
+
+
[D: %1, U: %2] %3
D = Download; U = Upload; %3 is the rest of the window title
-
+ [С: %1, З: %2] %3
-
-
+
+
Missing Python Runtime
- Missing Python Runtime
+ Адсутнічае асяроддзе выканання Python
-
+
qBittorrent Update Available
- Ёсць абнаўленне для qBittorrent
+ Даступна абнаўленне qBittorrent
-
+
Python is required to use the search engine but it does not seem to be installed.
Do you want to install it now?
Для выкарыстання пошукавай сістэмы патрабуецца Python, але падобна, што ён не ўсталяваны.
Хочаце ўсталяваць?
-
+
Python is required to use the search engine but it does not seem to be installed.
Для выкарыстання пошукавай сістэмы патрабуецца Python, але падобна, што ён не ўсталяваны.
-
-
+
+
Old Python Runtime
- Old Python Runtime
+ Старое асяроддзе выканання Python
-
+
A new version is available.
Даступна новая версія.
-
+
Do you want to download %1?
Хочаце спампаваць %1?
-
+
Open changelog...
Адкрыць спіс змен...
-
+
No updates available.
You are already using the latest version.
Няма абнаўленняў.
Вы ўжо карыстаецеся апошняй версіяй.
-
+
&Check for Updates
- &Праверыць абнаўленні
+ Праверыць &абнаўленні
-
+
Your Python version (%1) is outdated. Minimum requirement: %2.
Do you want to install a newer version now?
Ваша версія Python (%1) састарэла. Патрабуецца мінімум: %2.
Хочаце ўсталяваць навейшую версію?
-
+
Your Python version (%1) is outdated. Please upgrade to latest version for search engines to work.
Minimum requirement: %2.
- Your Python version (%1) is outdated. Please upgrade to latest version for search engines to work.
-Minimum requirement: %2.
+ У вас састарэлая версія Python (%1). Абнавіце яго да апошняй версіі, каб пошукавая сістэма працавала. Патрабуецца прынамсі %2
-
+
+ Paused
+ Прыпынены
+
+
+
Checking for Updates...
Праверка абнаўленняў...
-
+
Already checking for program updates in the background
У фоне ўжо ідзе праверка абнаўленняў праграмы
-
+
Download error
Памылка спампоўвання
-
+
Python setup could not be downloaded, reason: %1.
Please install it manually.
- Усталёўнік Python не можа быць спампаваны з прычыны: %1.
-Усталюйце яго ўласнаручна.
+ Не ўдалося спампаваць праграму ўсталявання Python, прычына: %1.
+Усталюйце яго ўручную.
-
-
+
+
Invalid password
Памылковы пароль
-
+
Filter torrents...
Фільтраваць торэнты...
-
+
Filter by:
Фільтраваць паводле:
-
+
The password must be at least 3 characters long
Пароль павінен змяшчаць не менш за 3 сімвалы.
-
-
+
+
RSS (%1)
RSS (%1)
-
+
The password is invalid
Уведзены пароль памылковы
-
+
DL speed: %1
e.g: Download speed: 10 KiB/s
Спамп. %1
-
+
UP speed: %1
e.g: Upload speed: 10 KiB/s
Разд: %1
- [D: %1, U: %2] qBittorrent %3
- D = Download; U = Upload; %3 is qBittorrent version
- [С: %1, Р: %2] qBittorrent %3
-
-
-
+
Hide
Схаваць
-
+
Exiting qBittorrent
Сканчэнне працы qBittorrent
-
+
Open Torrent Files
Адкрыць Torrent-файлы
-
+
Torrent Files
Torrent-файлы
@@ -4067,12 +4208,12 @@ Please install it manually.
Dynamic DNS error: qBittorrent was blacklisted by the service, please submit a bug report at https://bugs.qbittorrent.org.
- Памылка дынамічнага DNS: qBittorrent занесены ў чорны сьпіс, калі ласка, дашліце справаздачу пра памылку на https://bugs.qbittorrent.org.
+ Памылка дынамічнага DNS: qBittorrent занесены ў чорны спіс, адпраўце справаздачу пра памылку на https://bugs.qbittorrent.org.
Dynamic DNS error: %1 was returned by the service, please submit a bug report at https://bugs.qbittorrent.org.
-
+ Памылка дынамічнага DNS: служба вярнула %1. Паведаміце пра памылку на https://bugs.qbittorrent.org.
@@ -4106,12 +4247,12 @@ Please install it manually.
The file size (%1) exceeds the download limit (%2)
- The file size (%1) exceeds the download limit (%2)
+ Памер файла (%1) перавышае абмежаванне спампоўкі (%2)
Exceeded max redirections (%1)
- Exceeded max redirections (%1)
+
@@ -4131,7 +4272,7 @@ Please install it manually.
The remote server closed the connection prematurely, before the entire reply was received and processed
- Адлеглы сервер закрыў злучэнне перад тым, як увесь адказ быў атрыманы і апрацаваны
+ Аддалены сервер закрыў злучэнне да таго, як увесь адказ быў атрыманы і апрацаваны
@@ -4191,7 +4332,7 @@ Please install it manually.
The remote server requires authentication to serve the content but the credentials provided were not accepted
- Адлеглы сервер патрабуе аўтэнтыфікацыі для доступа да змесціва, але прадастаўленныя ўліковыя звесткі не прыняў
+ Аддалены сервер патрабуе аўтэнтыфікацыі для доступу да змесціва, але ўказаныя ўліковыя даныя не прыняў
@@ -4232,9 +4373,14 @@ Please install it manually.
Net::DownloadManager
-
+
+ SSL error, URL: "%1", errors: "%2"
+ Памылка SSL, адрас: «%1», памылкі: «%2»
+
+
+
Ignoring SSL error, URL: "%1", errors: "%2"
- Ignoring SSL error, URL: "%1", errors: "%2"
+ Ігнаруецца памылка SSL, адрас: «%1», памылкі: «%2»
@@ -4242,7 +4388,7 @@ Please install it manually.
Venezuela, Bolivarian Republic of
- Венесуэла, Баліварыянская Рэспубліка
+ Венесуэла
@@ -4259,13 +4405,13 @@ Please install it manually.
IP geolocation database loaded. Type: %1. Build time: %2.
- IP geolocation database loaded. Type: %1. Build time: %2.
+ База даных геалакацыі IP загружана. Тып: %1. Час зборкі: %2.
Couldn't load IP geolocation database. Reason: %1
- Couldn't load IP geolocation database. Reason: %1
+ Не ўдалося загрузіць базу даных геалакацыі IP. Прычына: %1
@@ -4390,7 +4536,7 @@ Please install it manually.
Brunei Darussalam
- Бруней-Даруссалам
+ Бруней-Дарусалам
@@ -4440,7 +4586,7 @@ Please install it manually.
Congo, The Democratic Republic of the
- Конга, Дэмакратычная Рэспубліка
+ Дэмакратычная Рэспубліка Конга
@@ -4505,7 +4651,7 @@ Please install it manually.
Christmas Island
- Востраў Ражства
+ Востраў Каляд
@@ -4515,7 +4661,7 @@ Please install it manually.
Czech Republic
- Чэшская Рэспубліка
+ Чэхія
@@ -4595,17 +4741,17 @@ Please install it manually.
Falkland Islands (Malvinas)
- Фалкленскія выспы (Мальдзівы)
+ Фалклендскія астравы (Мальдывы)
Micronesia, Federated States of
- Мікранезія, Фэдэратыўныя Штаты
+ Мікранезія
Faroe Islands
- Фарэрскія выспы
+ Фарэрскія астравы
@@ -4620,7 +4766,7 @@ Please install it manually.
United Kingdom
- Злучанае Каралеўства
+ Вялікабрытанія
@@ -4680,7 +4826,7 @@ Please install it manually.
South Georgia and the South Sandwich Islands
- Паўднёвая Джорджыя і Паўднёвыя Сандвічавы выспы
+ Паўднёвая Георгія і Паўднёвыя Сандвічавы астравы
@@ -4695,7 +4841,7 @@ Please install it manually.
Guinea-Bissau
- Гвінея-Бісаў
+ Гвінея-Бісау
@@ -4710,7 +4856,7 @@ Please install it manually.
Heard Island and McDonald Islands
- Выспа Херд і выспы Макдональд
+ Востраў Херд і астравы Макдональд
@@ -4765,7 +4911,7 @@ Please install it manually.
Iran, Islamic Republic of
- Іран, Ісламская Рэспубліка
+ Іран
@@ -4800,7 +4946,7 @@ Please install it manually.
Kyrgyzstan
- Кіргізія
+ Кыргызстан
@@ -4815,12 +4961,12 @@ Please install it manually.
Comoros
- Каморскія выспы
+ Каморскія астравы
Saint Kitts and Nevis
- Сэнт-Кітс і Нэвіс
+ Сент-Кітс і Невіс
@@ -4830,7 +4976,7 @@ Please install it manually.
Korea, Republic of
- Карэя, Рэспубліка
+ Паўднёвая Карэя
@@ -4840,7 +4986,7 @@ Please install it manually.
Cayman Islands
- Кайманавы выспы
+ Кайманавы астравы
@@ -4850,7 +4996,7 @@ Please install it manually.
Lao People's Democratic Republic
- Лаоская Народна-Дэмакратычная Рэспубліка
+ Лаос
@@ -4860,7 +5006,7 @@ Please install it manually.
Saint Lucia
- Сэнт-Люсія
+ Сент-Люсія
@@ -4870,7 +5016,7 @@ Please install it manually.
Sri Lanka
- Шры Ланка
+ Шры-Ланка
@@ -4910,7 +5056,7 @@ Please install it manually.
Moldova, Republic of
- Малдова, Рэспубліка
+ Малдова
@@ -4940,7 +5086,7 @@ Please install it manually.
Northern Mariana Islands
- Паўночныя Марыянскія выспы
+ Паўночныя Марыянскія астравы
@@ -5010,7 +5156,7 @@ Please install it manually.
Norfolk Island
- Выспа Норфалк
+ Востраў Норфалк
@@ -5110,7 +5256,7 @@ Please install it manually.
Palau
- Палаў
+ Палау
@@ -5125,7 +5271,7 @@ Please install it manually.
Reunion
- Уз'яднанне
+ Рэюньён
@@ -5135,7 +5281,7 @@ Please install it manually.
Russian Federation
- Расійская Федэрацыя
+ Расія
@@ -5150,12 +5296,12 @@ Please install it manually.
Solomon Islands
- Саламонавы выспы
+ Саламонавы астравы
Seychelles
- Сейшэльскія выспы
+ Сейшэльскія астравы
@@ -5180,7 +5326,7 @@ Please install it manually.
Svalbard and Jan Mayen
- Шпіцбэрген і Ян-Майен
+ Шпіцберген і Ян-Маен
@@ -5215,7 +5361,7 @@ Please install it manually.
Sao Tome and Principe
- Сан-Томе і Прынсэп
+ Сан-Тамэ і Прынсіпі
@@ -5225,7 +5371,7 @@ Please install it manually.
Syrian Arab Republic
- Сірыйская Арабская Рэспубліка
+ Сірыя
@@ -5250,7 +5396,7 @@ Please install it manually.