mirror of
https://github.com/qbittorrent/qBittorrent.git
synced 2025-12-19 15:07:22 -06:00
Compare commits
54 Commits
release-4.
...
release-4.
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
da0b276d5f | ||
|
|
2d73bc9e7d | ||
|
|
fdd54fe568 | ||
|
|
e5ce24e55e | ||
|
|
d90349709b | ||
|
|
adb0fe6582 | ||
|
|
5ed81580c9 | ||
|
|
86d6fb86d7 | ||
|
|
ddec247d4f | ||
|
|
d431ecbe00 | ||
|
|
be929ed88c | ||
|
|
2e1f9bf8be | ||
|
|
7fff393b0e | ||
|
|
a669ec49ad | ||
|
|
1880082017 | ||
|
|
0cbd15890a | ||
|
|
7fe7c6c277 | ||
|
|
e4c177fec7 | ||
|
|
77f4e6c2cf | ||
|
|
4563b11a2e | ||
|
|
cb477f9a29 | ||
|
|
58ac07667e | ||
|
|
74bf3af41c | ||
|
|
9317071122 | ||
|
|
dab32f2090 | ||
|
|
dc464d4d41 | ||
|
|
e7e3f6a9db | ||
|
|
5a1c4e79b3 | ||
|
|
c6d9ab6810 | ||
|
|
d7afad835e | ||
|
|
8608d7b9da | ||
|
|
72970602af | ||
|
|
86579ca87d | ||
|
|
e55582124c | ||
|
|
bd8b06c607 | ||
|
|
230fedf069 | ||
|
|
7bea10f507 | ||
|
|
7cde969b90 | ||
|
|
a3b8f6880b | ||
|
|
ad79fc8d43 | ||
|
|
fb4bf94a56 | ||
|
|
1c184944fd | ||
|
|
ec420f6617 | ||
|
|
d908227619 | ||
|
|
ac8167410b | ||
|
|
26ce187b30 | ||
|
|
2c4e04e537 | ||
|
|
b418f65c2f | ||
|
|
dd3a8d5d56 | ||
|
|
49e54a55df | ||
|
|
8cd0a7ae85 | ||
|
|
442f0df613 | ||
|
|
f9ee5bdb59 | ||
|
|
b9602cc6ab |
10
.github/workflows/ci.yaml
vendored
10
.github/workflows/ci.yaml
vendored
@@ -72,7 +72,7 @@ jobs:
|
|||||||
- name: upload artifact as zip
|
- name: upload artifact as zip
|
||||||
uses: actions/upload-artifact@v2
|
uses: actions/upload-artifact@v2
|
||||||
with:
|
with:
|
||||||
name: qBittorrent-CI-Ubuntu_${{ matrix.os }}-${{ matrix.qbt_gui }}
|
name: qBittorrent-CI_${{ matrix.os }}-x64_${{ matrix.qbt_gui }}
|
||||||
path: |
|
path: |
|
||||||
build/compile_commands.json
|
build/compile_commands.json
|
||||||
build/target_graph.dot
|
build/target_graph.dot
|
||||||
@@ -151,7 +151,7 @@ jobs:
|
|||||||
- name: upload artifact as zip
|
- name: upload artifact as zip
|
||||||
uses: actions/upload-artifact@v2
|
uses: actions/upload-artifact@v2
|
||||||
with:
|
with:
|
||||||
name: qBittorrent-CI-Windows_x64-static-release
|
name: qBittorrent-CI_Windows-x64
|
||||||
path: |
|
path: |
|
||||||
build/compile_commands.json
|
build/compile_commands.json
|
||||||
build/target_graph.dot
|
build/target_graph.dot
|
||||||
@@ -200,10 +200,10 @@ jobs:
|
|||||||
-Value "set(VCPKG_BUILD_TYPE release)","set(VCPKG_OSX_DEPLOYMENT_TARGET 10.15)"
|
-Value "set(VCPKG_BUILD_TYPE release)","set(VCPKG_OSX_DEPLOYMENT_TARGET 10.15)"
|
||||||
|
|
||||||
# NOTE: Avoids a libtorrent ABI issue. See https://github.com/arvidn/libtorrent/issues/4965
|
# NOTE: Avoids a libtorrent ABI issue. See https://github.com/arvidn/libtorrent/issues/4965
|
||||||
- name: force AppleClang to compile libtorrent with C++14
|
- name: force AppleClang to compile libtorrent with C++17
|
||||||
run: |
|
run: |
|
||||||
(Get-Content -path ${{ env.RUNVCPKG_VCPKG_ROOT }}/ports/libtorrent/portfile.cmake).Replace( `
|
(Get-Content -path ${{ env.RUNVCPKG_VCPKG_ROOT }}/ports/libtorrent/portfile.cmake).Replace( `
|
||||||
'${FEATURE_OPTIONS}', '${FEATURE_OPTIONS} -DCMAKE_CXX_STANDARD=14') `
|
'${FEATURE_OPTIONS}', '${FEATURE_OPTIONS} -DCMAKE_CXX_STANDARD=17') `
|
||||||
| Set-Content -Path ${{ env.RUNVCPKG_VCPKG_ROOT }}/ports/libtorrent/portfile.cmake
|
| Set-Content -Path ${{ env.RUNVCPKG_VCPKG_ROOT }}/ports/libtorrent/portfile.cmake
|
||||||
|
|
||||||
- name: install dependencies via vcpkg
|
- name: install dependencies via vcpkg
|
||||||
@@ -236,7 +236,7 @@ jobs:
|
|||||||
- name: upload artifact as zip
|
- name: upload artifact as zip
|
||||||
uses: actions/upload-artifact@v2
|
uses: actions/upload-artifact@v2
|
||||||
with:
|
with:
|
||||||
name: qBittorrent-CI-macOS_x64-static-release_${{ matrix.qbt_gui }}
|
name: qBittorrent-CI_macOS_${{ matrix.qbt_gui }}
|
||||||
path: |
|
path: |
|
||||||
build/compile_commands.json
|
build/compile_commands.json
|
||||||
build/target_graph.dot
|
build/target_graph.dot
|
||||||
|
|||||||
2
.github/workflows/file_health.sh
vendored
2
.github/workflows/file_health.sh
vendored
@@ -12,6 +12,7 @@ regressions=0
|
|||||||
exclusions_nonutf8='(.*(7z|gif|ic(ns|o)|png|qm|zip))'
|
exclusions_nonutf8='(.*(7z|gif|ic(ns|o)|png|qm|zip))'
|
||||||
exclusions_bom='src/base/unicodestrings.h'
|
exclusions_bom='src/base/unicodestrings.h'
|
||||||
exclusions_tw='(*.ts)|src/webui/www/private/scripts/lib/mootools-1.2-more.js'
|
exclusions_tw='(*.ts)|src/webui/www/private/scripts/lib/mootools-1.2-more.js'
|
||||||
|
exclusions_trailing_newline='configure'
|
||||||
exclusions_no_lf='(*.ts)|(.*svg)|compile_commands.json|src/webui/www/private/scripts/lib/mootools-1.2-(core-yc.js|more.js)'
|
exclusions_no_lf='(*.ts)|(.*svg)|compile_commands.json|src/webui/www/private/scripts/lib/mootools-1.2-(core-yc.js|more.js)'
|
||||||
|
|
||||||
echo -e "\n*** Detect files not encoded in UTF-8 ***\n"
|
echo -e "\n*** Detect files not encoded in UTF-8 ***\n"
|
||||||
@@ -50,6 +51,7 @@ echo -e "\n*** Detect too many trailing newlines ***\n"
|
|||||||
|
|
||||||
find . -path ./build -prune -false -o -path ./.git -prune -false -o -type f -exec file --mime {} \; | sort \
|
find . -path ./build -prune -false -o -path ./.git -prune -false -o -type f -exec file --mime {} \; | sort \
|
||||||
| grep -e "charset=us-ascii" -e "charset=utf-8" | cut -d ":" -f 1 \
|
| grep -e "charset=us-ascii" -e "charset=utf-8" | cut -d ":" -f 1 \
|
||||||
|
| grep -E -v -e "${exclusions_trailing_newline}" \
|
||||||
| xargs -L1 -I my_input bash -c 'test "$(tail -q -c2 "my_input" | hexdump -C | grep "0a 0a")" && echo "my_input"' \
|
| xargs -L1 -I my_input bash -c 'test "$(tail -q -c2 "my_input" | hexdump -C | grep "0a 0a")" && echo "my_input"' \
|
||||||
| tee >(echo -e "--> Too many trailing newlines: found" "$(wc -l < /dev/stdin)" "regression(s)\n") \
|
| tee >(echo -e "--> Too many trailing newlines: found" "$(wc -l < /dev/stdin)" "regression(s)\n") \
|
||||||
| xargs -I my_input -0 bash -c 'echo "my_input"; test "$(echo -n "my_input" | wc -l)" -eq 0'
|
| xargs -I my_input -0 bash -c 'echo "my_input"; test "$(echo -n "my_input" | wc -l)" -eq 0'
|
||||||
|
|||||||
1
.gitignore
vendored
1
.gitignore
vendored
@@ -4,6 +4,7 @@ src/qbittorrent
|
|||||||
src/qbittorrent-nox
|
src/qbittorrent-nox
|
||||||
src/release
|
src/release
|
||||||
src/debug
|
src/debug
|
||||||
|
src/base/version.h
|
||||||
CMakeLists.txt.user*
|
CMakeLists.txt.user*
|
||||||
qbittorrent.pro.user*
|
qbittorrent.pro.user*
|
||||||
conf.pri
|
conf.pri
|
||||||
|
|||||||
@@ -129,7 +129,7 @@ install:
|
|||||||
|
|
||||||
cmake \
|
cmake \
|
||||||
-DCMAKE_BUILD_TYPE=Release \
|
-DCMAKE_BUILD_TYPE=Release \
|
||||||
-DCMAKE_CXX_STANDARD=14 \
|
-DCMAKE_CXX_STANDARD=17 \
|
||||||
-Ddeprecated-functions=OFF \
|
-Ddeprecated-functions=OFF \
|
||||||
-DOPENSSL_ROOT_DIR="$openssl_root_path" \
|
-DOPENSSL_ROOT_DIR="$openssl_root_path" \
|
||||||
./
|
./
|
||||||
@@ -145,7 +145,7 @@ install:
|
|||||||
|
|
||||||
cmake \
|
cmake \
|
||||||
-DCMAKE_BUILD_TYPE=Release \
|
-DCMAKE_BUILD_TYPE=Release \
|
||||||
-DCMAKE_CXX_STANDARD=14 \
|
-DCMAKE_CXX_STANDARD=17 \
|
||||||
-Ddeprecated-functions=ON \
|
-Ddeprecated-functions=ON \
|
||||||
-DOPENSSL_ROOT_DIR="$openssl_root_path" \
|
-DOPENSSL_ROOT_DIR="$openssl_root_path" \
|
||||||
./
|
./
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ cmake_minimum_required(VERSION 3.16 FATAL_ERROR) # Policies <= CMP0097 default t
|
|||||||
list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake/Modules)
|
list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake/Modules)
|
||||||
|
|
||||||
project(qBittorrent
|
project(qBittorrent
|
||||||
VERSION 4.3.2.0
|
|
||||||
DESCRIPTION "The qBittorrent BitTorrent client"
|
DESCRIPTION "The qBittorrent BitTorrent client"
|
||||||
HOMEPAGE_URL "https://www.qbittorrent.org/"
|
HOMEPAGE_URL "https://www.qbittorrent.org/"
|
||||||
LANGUAGES CXX
|
LANGUAGES CXX
|
||||||
@@ -51,8 +50,6 @@ elseif (MSVC)
|
|||||||
feature_option(MSVC_RUNTIME_DYNAMIC "Use MSVC dynamic runtime library (-MD) instead of static (-MT)" ON)
|
feature_option(MSVC_RUNTIME_DYNAMIC "Use MSVC dynamic runtime library (-MD) instead of static (-MT)" ON)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
set(QBT_VER_STATUS "alpha1" CACHE STRING "Project status version. Should be empty for release builds.")
|
|
||||||
|
|
||||||
include(GNUInstallDirs)
|
include(GNUInstallDirs)
|
||||||
add_subdirectory(src)
|
add_subdirectory(src)
|
||||||
add_subdirectory(dist)
|
add_subdirectory(dist)
|
||||||
@@ -62,3 +59,7 @@ if (VERBOSE_CONFIGURE)
|
|||||||
else()
|
else()
|
||||||
feature_summary(WHAT ENABLED_FEATURES DISABLED_FEATURES)
|
feature_summary(WHAT ENABLED_FEATURES DISABLED_FEATURES)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
# Generate version header
|
||||||
|
file(READ "src/base/version.h.in" versionHeader)
|
||||||
|
file(WRITE "src/base/version.h" "${versionHeader}")
|
||||||
|
|||||||
18
Changelog
18
Changelog
@@ -1,3 +1,21 @@
|
|||||||
|
Tue Jan 19 2021 - sledgehammer999 <sledgehammer999@qbittorrent.org> - v4.3.3
|
||||||
|
- FEATURE: New languages: Azerbaijani, Estonian
|
||||||
|
- BUGFIX: Unify global speed dialogs for normal/alternative speeds (thalieht)
|
||||||
|
- BUGFIX: Increase maximum global speed limits ~2 GiB/s (thalieht)
|
||||||
|
- BUGFIX: Save fastresume when setting torrent speed limits (thalieht)
|
||||||
|
- BUGFIX: Group several torrent options into one dialog (thalieht)
|
||||||
|
- BUGFIX: Capitalize locale names (Chocobo1)
|
||||||
|
- BUGFIX: Improve content file/folder names handling (glassez)
|
||||||
|
- BUGFIX: Drop notification about move storage finished or failed (glassez)
|
||||||
|
- BUGFIX: Reload "missing files" torrent instead of re-checking (glassez)
|
||||||
|
- BUGFIX: Remember dialog sizes (Chocobo1)
|
||||||
|
- BUGFIX: Improve detection of file extension string (Chocobo1)
|
||||||
|
- WEBUI: Don't call non-existent elements (glassez)
|
||||||
|
- WEBUI: Update "Keep top-level folder" in WebUI options (thalieht)
|
||||||
|
- MACOS: QMake: Raise minimal macOS target version to 10.14 (glassez)
|
||||||
|
- LINUX: Use legacy 'data' directory only as a fallback (lbilli)
|
||||||
|
- OTHER: Bump project requirement to C++17 (Chocobo1)
|
||||||
|
|
||||||
Sun Dec 27 2020 - sledgehammer999 <sledgehammer999@qbittorrent.org> - v4.3.2
|
Sun Dec 27 2020 - sledgehammer999 <sledgehammer999@qbittorrent.org> - v4.3.2
|
||||||
- FEATURE: Allow to add root folder to torrent content (glassez)
|
- FEATURE: Allow to add root folder to torrent content (glassez)
|
||||||
- FEATURE: "HTTPS tracker validation" option is available on all platforms with latest libtorrent (Chocobo1)
|
- FEATURE: "HTTPS tracker validation" option is available on all platforms with latest libtorrent (Chocobo1)
|
||||||
|
|||||||
19
build_dist.sh
Executable file
19
build_dist.sh
Executable file
@@ -0,0 +1,19 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
# get version numbers
|
||||||
|
versionSrc="src/base/version.h.in"
|
||||||
|
versionMajor="$(grep -Po '(?<=QBT_VERSION_MAJOR )\d+' "$versionSrc")"
|
||||||
|
versionMinor="$(grep -Po '(?<=QBT_VERSION_MINOR )\d+' "$versionSrc")"
|
||||||
|
versionBugfix="$(grep -Po '(?<=QBT_VERSION_BUGFIX )\d+' "$versionSrc")"
|
||||||
|
versionBuild="$(grep -Po '(?<=QBT_VERSION_BUILD )\d+' "$versionSrc")"
|
||||||
|
versionStatus="$(grep -Po '(?<=QBT_VERSION_STATUS ")\w+' "$versionSrc")"
|
||||||
|
|
||||||
|
if [ "$versionBuild" != "0" ]; then
|
||||||
|
projectVersion="$versionMajor.$versionMinor.$versionBugfix.$versionBuild$versionStatus"
|
||||||
|
else
|
||||||
|
projectVersion="$versionMajor.$versionMinor.$versionBugfix$versionStatus"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# pack archives
|
||||||
|
git archive --format=tar --prefix="qbittorrent-$projectVersion/" HEAD | gzip -9 > "qbittorrent-$projectVersion.tar.gz"
|
||||||
|
git archive --format=tar --prefix="qbittorrent-$projectVersion/" HEAD | xz -9 > "qbittorrent-$projectVersion.tar.xz"
|
||||||
@@ -7,47 +7,16 @@ macro(qbt_common_config)
|
|||||||
# treat value specified by the CXX_STANDARD target property as a requirement by default
|
# treat value specified by the CXX_STANDARD target property as a requirement by default
|
||||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||||
|
|
||||||
# these definitions are only needed for calls to
|
|
||||||
# lt::generate_fingerprint and for the qbittorrent.rc file on Windows
|
|
||||||
add_library(qbt_version_definitions INTERFACE)
|
|
||||||
|
|
||||||
target_compile_definitions(qbt_version_definitions INTERFACE
|
|
||||||
QBT_VERSION_MAJOR=${qBittorrent_VERSION_MAJOR}
|
|
||||||
QBT_VERSION_MINOR=${qBittorrent_VERSION_MINOR}
|
|
||||||
QBT_VERSION_BUGFIX=${qBittorrent_VERSION_PATCH}
|
|
||||||
QBT_VERSION_BUILD=${qBittorrent_VERSION_TWEAK}
|
|
||||||
)
|
|
||||||
|
|
||||||
add_library(qbt_common_cfg INTERFACE)
|
add_library(qbt_common_cfg INTERFACE)
|
||||||
|
|
||||||
# Full C++ 14 support is required
|
# Full C++ 17 support is required
|
||||||
# See also https://cmake.org/cmake/help/latest/prop_gbl/CMAKE_CXX_KNOWN_FEATURES.html
|
# See also https://cmake.org/cmake/help/latest/prop_gbl/CMAKE_CXX_KNOWN_FEATURES.html
|
||||||
# for a breakdown of the features that CMake recognizes for each C++ standard
|
# for a breakdown of the features that CMake recognizes for each C++ standard
|
||||||
target_compile_features(qbt_common_cfg INTERFACE
|
target_compile_features(qbt_common_cfg INTERFACE
|
||||||
cxx_std_14
|
cxx_std_17
|
||||||
cxx_aggregate_default_initializers
|
|
||||||
cxx_attribute_deprecated
|
|
||||||
cxx_binary_literals
|
|
||||||
cxx_contextual_conversions
|
|
||||||
cxx_decltype_auto
|
|
||||||
cxx_digit_separators
|
|
||||||
cxx_generic_lambdas
|
|
||||||
cxx_lambda_init_captures
|
|
||||||
cxx_relaxed_constexpr
|
|
||||||
cxx_return_type_deduction
|
|
||||||
cxx_variable_templates
|
|
||||||
)
|
)
|
||||||
|
|
||||||
set(QBT_PROJECT_VERSION "${qBittorrent_VERSION_MAJOR}.${qBittorrent_VERSION_MINOR}.${qBittorrent_VERSION_PATCH}")
|
|
||||||
if (NOT ${qBittorrent_VERSION_TWEAK} EQUAL 0)
|
|
||||||
set(QBT_PROJECT_VERSION "${QBT_PROJECT_VERSION}.${qBittorrent_VERSION_TWEAK}")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
set(QBT_FULL_VERSION "${QBT_PROJECT_VERSION}${QBT_VER_STATUS}")
|
|
||||||
|
|
||||||
target_compile_definitions(qbt_common_cfg INTERFACE
|
target_compile_definitions(qbt_common_cfg INTERFACE
|
||||||
QBT_VERSION="v${QBT_FULL_VERSION}"
|
|
||||||
QBT_VERSION_2="${QBT_FULL_VERSION}"
|
|
||||||
QT_DEPRECATED_WARNINGS
|
QT_DEPRECATED_WARNINGS
|
||||||
QT_NO_CAST_TO_ASCII
|
QT_NO_CAST_TO_ASCII
|
||||||
QT_NO_CAST_FROM_BYTEARRAY
|
QT_NO_CAST_FROM_BYTEARRAY
|
||||||
@@ -90,6 +59,12 @@ macro(qbt_common_config)
|
|||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
if ((CXX_COMPILER_ID STREQUAL "Clang") OR (CXX_COMPILER_ID STREQUAL "AppleClang"))
|
||||||
|
target_compile_options(qbt_common_cfg INTERFACE
|
||||||
|
-Wno-range-loop-analysis
|
||||||
|
)
|
||||||
|
endif()
|
||||||
|
|
||||||
if (MINGW)
|
if (MINGW)
|
||||||
target_link_options(qbt_common_cfg INTERFACE $<$<OR:$<CONFIG:Debug>,$<CONFIG:RelWithDebInfo>>:LINKER:--dynamicbase>)
|
target_link_options(qbt_common_cfg INTERFACE $<$<OR:$<CONFIG:Debug>,$<CONFIG:RelWithDebInfo>>:LINKER:--dynamicbase>)
|
||||||
endif()
|
endif()
|
||||||
@@ -101,8 +76,12 @@ macro(qbt_common_config)
|
|||||||
endif()
|
endif()
|
||||||
|
|
||||||
if (MSVC)
|
if (MSVC)
|
||||||
target_compile_options(qbt_common_cfg INTERFACE /guard:cf)
|
target_compile_options(qbt_common_cfg INTERFACE
|
||||||
target_link_options(qbt_common_cfg INTERFACE /guard:cf
|
/guard:cf
|
||||||
|
/utf-8
|
||||||
|
)
|
||||||
|
target_link_options(qbt_common_cfg INTERFACE
|
||||||
|
/guard:cf
|
||||||
$<$<NOT:$<CONFIG:Debug>>:/OPT:REF /OPT:ICF>
|
$<$<NOT:$<CONFIG:Debug>>:/OPT:REF /OPT:ICF>
|
||||||
# suppress linking warning due to /INCREMENTAL and /OPT:ICF being both ON
|
# suppress linking warning due to /INCREMENTAL and /OPT:ICF being both ON
|
||||||
$<$<CONFIG:RelWithDebInfo>:/INCREMENTAL:NO>
|
$<$<CONFIG:RelWithDebInfo>:/INCREMENTAL:NO>
|
||||||
|
|||||||
44
configure.ac
44
configure.ac
@@ -1,4 +1,4 @@
|
|||||||
AC_INIT([qbittorrent], [v4.3.2], [bugs.qbittorrent.org], [], [https://www.qbittorrent.org/])
|
AC_INIT([qbittorrent], [v4.3.3], [bugs.qbittorrent.org], [], [https://www.qbittorrent.org/])
|
||||||
AC_CONFIG_AUX_DIR([build-aux])
|
AC_CONFIG_AUX_DIR([build-aux])
|
||||||
AC_CONFIG_MACRO_DIR([m4])
|
AC_CONFIG_MACRO_DIR([m4])
|
||||||
: ${CFLAGS=""}
|
: ${CFLAGS=""}
|
||||||
@@ -194,34 +194,34 @@ PKG_CHECK_MODULES(zlib,
|
|||||||
[CXXFLAGS="$zlib_CFLAGS $CXXFLAGS"
|
[CXXFLAGS="$zlib_CFLAGS $CXXFLAGS"
|
||||||
LIBS="$zlib_LIBS $LIBS"])
|
LIBS="$zlib_LIBS $LIBS"])
|
||||||
|
|
||||||
# Check if already in >= C++14 mode because of the flags returned by one of the above packages
|
# Check if already in >= C++17 mode because of the flags returned by one of the above packages
|
||||||
TMP_CXXFLAGS="$CXXFLAGS"
|
TMP_CXXFLAGS="$CXXFLAGS"
|
||||||
CXXFLAGS=""
|
CXXFLAGS=""
|
||||||
AC_MSG_CHECKING([if compiler defaults to C++14 or later mode])
|
AC_MSG_CHECKING([if compiler defaults to C++17 or later mode])
|
||||||
AC_COMPILE_IFELSE([DETECT_CPP14_PROGRAM()],
|
AC_COMPILE_IFELSE([DETECT_CPP17_PROGRAM()],
|
||||||
[AC_MSG_RESULT([yes])
|
[AC_MSG_RESULT([yes])
|
||||||
QBT_CXX14_FOUND="yes"],
|
QBT_CXX17_FOUND="yes"],
|
||||||
[AC_MSG_RESULT([no])
|
[AC_MSG_RESULT([no])
|
||||||
QBT_CXX14_FOUND="no"])
|
QBT_CXX17_FOUND="no"])
|
||||||
|
|
||||||
# In case of no, check if the compiler can support at least C++14
|
# In case of no, check if the compiler can support at least C++17
|
||||||
# and if yes, enable it leaving a warning to the user
|
# and if yes, enable it leaving a warning to the user
|
||||||
AS_IF([test "x$QBT_CXX14_FOUND" = "xno"],
|
AS_IF([test "x$QBT_CXX17_FOUND" = "xno"],
|
||||||
[AC_MSG_CHECKING([if compiler supports C++14])
|
[AC_MSG_CHECKING([if compiler supports C++17])
|
||||||
CXXFLAGS="-std=c++14"
|
CXXFLAGS="-std=c++17"
|
||||||
AC_COMPILE_IFELSE([DETECT_CPP14_PROGRAM()],
|
AC_COMPILE_IFELSE([DETECT_CPP17_PROGRAM()],
|
||||||
[AC_MSG_RESULT([yes])
|
[AC_MSG_RESULT([yes])
|
||||||
AC_MSG_CHECKING([if C++14 is disabled by the set compiler flags])
|
AC_MSG_CHECKING([if C++17 is disabled by the set compiler flags])
|
||||||
# prepend the flag so it won't override conflicting user defined flags
|
# prepend the flag so it won't override conflicting user defined flags
|
||||||
CXXFLAGS="-std=c++14 $TMP_CXXFLAGS"
|
CXXFLAGS="-std=c++17 $TMP_CXXFLAGS"
|
||||||
AC_COMPILE_IFELSE([DETECT_CPP14_PROGRAM()],
|
AC_COMPILE_IFELSE([DETECT_CPP17_PROGRAM()],
|
||||||
[AC_MSG_RESULT([no])
|
[AC_MSG_RESULT([no])
|
||||||
QBT_ADD_CONFIG="$QBT_ADD_CONFIG c++14"
|
QBT_ADD_CONFIG="$QBT_ADD_CONFIG c++1z"
|
||||||
AC_MSG_WARN([C++14 mode is now force enabled. The C++ mode should match the mode that other libraries were built with, otherwise you'll likely get linking errors.])],
|
AC_MSG_WARN([C++17 mode is now force enabled. The C++ mode should match the mode that other libraries were built with, otherwise you'll likely get linking errors.])],
|
||||||
[AC_MSG_RESULT([yes])
|
[AC_MSG_RESULT([yes])
|
||||||
AC_MSG_ERROR([The compiler supports C++14 but the user or a dependency has explicitly enabled a lower mode.])])],
|
AC_MSG_ERROR([The compiler supports C++17 but the user or a dependency has explicitly enabled a lower mode.])])],
|
||||||
[AC_MSG_RESULT([no])
|
[AC_MSG_RESULT([no])
|
||||||
AC_MSG_ERROR([A compiler supporting C++14 is required.])])
|
AC_MSG_ERROR([A compiler supporting C++17 is required.])])
|
||||||
])
|
])
|
||||||
CXXFLAGS="$TMP_CXXFLAGS"
|
CXXFLAGS="$TMP_CXXFLAGS"
|
||||||
|
|
||||||
@@ -272,9 +272,13 @@ AC_SUBST(QBT_REMOVE_CONFIG)
|
|||||||
AC_SUBST(QBT_ADD_DEFINES)
|
AC_SUBST(QBT_ADD_DEFINES)
|
||||||
AC_SUBST(QBT_REMOVE_DEFINES)
|
AC_SUBST(QBT_REMOVE_DEFINES)
|
||||||
|
|
||||||
AC_OUTPUT(conf.pri)
|
QBT_CONFIG_FILES="conf.pri"
|
||||||
|
|
||||||
AS_IF([test "x$enable_systemd" = "xyes"],
|
AS_IF([test "x$enable_systemd" = "xyes"],
|
||||||
[AC_OUTPUT(dist/unix/systemd/qbittorrent-nox@.service)])
|
[QBT_CONFIG_FILES="$QBT_CONFIG_FILES dist/unix/systemd/qbittorrent-nox@.service"])
|
||||||
|
|
||||||
|
AC_CONFIG_FILES(["$QBT_CONFIG_FILES"])
|
||||||
|
AC_OUTPUT
|
||||||
|
|
||||||
AC_MSG_NOTICE([Running qmake to generate the makefile...])
|
AC_MSG_NOTICE([Running qmake to generate the makefile...])
|
||||||
TOPDIR="$(cd "$(dirname "$0")" && pwd)"
|
TOPDIR="$(cd "$(dirname "$0")" && pwd)"
|
||||||
|
|||||||
4
dist/mac/Info.plist
vendored
4
dist/mac/Info.plist
vendored
@@ -55,7 +55,7 @@
|
|||||||
<key>CFBundlePackageType</key>
|
<key>CFBundlePackageType</key>
|
||||||
<string>APPL</string>
|
<string>APPL</string>
|
||||||
<key>CFBundleShortVersionString</key>
|
<key>CFBundleShortVersionString</key>
|
||||||
<string>4.3.2</string>
|
<string>4.3.3</string>
|
||||||
<key>CFBundleExecutable</key>
|
<key>CFBundleExecutable</key>
|
||||||
<string>@EXECUTABLE@</string>
|
<string>@EXECUTABLE@</string>
|
||||||
<key>CFBundleIdentifier</key>
|
<key>CFBundleIdentifier</key>
|
||||||
@@ -67,7 +67,7 @@
|
|||||||
<key>NSAppleScriptEnabled</key>
|
<key>NSAppleScriptEnabled</key>
|
||||||
<string>YES</string>
|
<string>YES</string>
|
||||||
<key>NSHumanReadableCopyright</key>
|
<key>NSHumanReadableCopyright</key>
|
||||||
<string>Copyright © 2006-2020 The qBittorrent project</string>
|
<string>Copyright © 2006-2021 The qBittorrent project</string>
|
||||||
<key>UTExportedTypeDeclarations</key>
|
<key>UTExportedTypeDeclarations</key>
|
||||||
<array>
|
<array>
|
||||||
<dict>
|
<dict>
|
||||||
|
|||||||
@@ -74,6 +74,6 @@
|
|||||||
<url type="translate">https://github.com/qbittorrent/qBittorrent/wiki/How-to-translate-qBittorrent</url>
|
<url type="translate">https://github.com/qbittorrent/qBittorrent/wiki/How-to-translate-qBittorrent</url>
|
||||||
<content_rating type="oars-1.1"/>
|
<content_rating type="oars-1.1"/>
|
||||||
<releases>
|
<releases>
|
||||||
<release version="4.3.2" date="2020-12-27"/>
|
<release version="4.3.3" date="2021-01-19"/>
|
||||||
</releases>
|
</releases>
|
||||||
</component>
|
</component>
|
||||||
|
|||||||
14
dist/unix/org.qbittorrent.qBittorrent.desktop
vendored
14
dist/unix/org.qbittorrent.qBittorrent.desktop
vendored
@@ -12,6 +12,9 @@ StartupNotify=false
|
|||||||
StartupWMClass=qbittorrent
|
StartupWMClass=qbittorrent
|
||||||
Keywords=bittorrent;torrent;magnet;download;p2p;
|
Keywords=bittorrent;torrent;magnet;download;p2p;
|
||||||
|
|
||||||
|
# Translations
|
||||||
|
|
||||||
|
|
||||||
# Translations
|
# Translations
|
||||||
Comment[oc]=Telecargar e partejar de fichièrs amb BitTorrent
|
Comment[oc]=Telecargar e partejar de fichièrs amb BitTorrent
|
||||||
GenericName[oc]=Client BitTorrent
|
GenericName[oc]=Client BitTorrent
|
||||||
@@ -85,6 +88,9 @@ Name[hr]=qBittorrent
|
|||||||
Comment[hu]=Fájlok letöltése és megosztása a BitTorrent hálózaton keresztül
|
Comment[hu]=Fájlok letöltése és megosztása a BitTorrent hálózaton keresztül
|
||||||
GenericName[hu]=BitTorrent kliens
|
GenericName[hu]=BitTorrent kliens
|
||||||
Name[hu]=qBittorrent
|
Name[hu]=qBittorrent
|
||||||
|
Comment[hy]=Նիշքերի փոխանցում BitTorrent-ի միջոցով
|
||||||
|
GenericName[hy]=BitTorrent սպասառու
|
||||||
|
Name[hy]=qBittorrent
|
||||||
Comment[id]=Unduh dan berbagi berkas melalui BitTorrent
|
Comment[id]=Unduh dan berbagi berkas melalui BitTorrent
|
||||||
GenericName[id]=Klien BitTorrent
|
GenericName[id]=Klien BitTorrent
|
||||||
Name[id]=qBittorrent
|
Name[id]=qBittorrent
|
||||||
@@ -100,8 +106,8 @@ Name[ja]=qBittorrent
|
|||||||
Comment[ka]=ჩამოტვირთე და გააზიარე ფაილები Bittorrent-ის საშუალებით
|
Comment[ka]=ჩამოტვირთე და გააზიარე ფაილები Bittorrent-ის საშუალებით
|
||||||
GenericName[ka]=BitTorrent კლიენტი
|
GenericName[ka]=BitTorrent კლიენტი
|
||||||
Name[ka]=qBittorrent
|
Name[ka]=qBittorrent
|
||||||
Comment[ko]=비트토런트를 통해 파일을 받고 공유합니다
|
Comment[ko]=비트토렌트를 통해 파일을 받고 공유합니다
|
||||||
GenericName[ko]=비트토런트 클라이언트
|
GenericName[ko]=비트토렌트 클라이언트
|
||||||
Name[ko]=qBittorrent
|
Name[ko]=qBittorrent
|
||||||
Comment[zh]=通过 BitTorrent 下载和分享文件
|
Comment[zh]=通过 BitTorrent 下载和分享文件
|
||||||
GenericName[zh]=BitTorrent 客户端
|
GenericName[zh]=BitTorrent 客户端
|
||||||
@@ -189,8 +195,8 @@ Name[ms_MY]=qBittorrent
|
|||||||
Comment[eo]=Elŝutu kaj kunhavigu dosierojn per BitTorrent
|
Comment[eo]=Elŝutu kaj kunhavigu dosierojn per BitTorrent
|
||||||
GenericName[eo]=BitTorrent-kliento
|
GenericName[eo]=BitTorrent-kliento
|
||||||
Name[eo]=qBittorrent
|
Name[eo]=qBittorrent
|
||||||
Comment[mn_MN]=BitTorrent ашиглан файлуудыг татаж түгээх
|
Comment[mn_MN]=BitTorrent-оор файлуудаа тат, түгээ
|
||||||
GenericName[mn_MN]=BitTorrent үйлчлүүлэгч
|
GenericName[mn_MN]=BitTorrent татагч
|
||||||
Name[mn_MN]=qBittorrent
|
Name[mn_MN]=qBittorrent
|
||||||
Comment[ta]=BitTorrent வழியாக கோப்புகளை பதிவிறக்க மற்றும் பகிர
|
Comment[ta]=BitTorrent வழியாக கோப்புகளை பதிவிறக்க மற்றும் பகிர
|
||||||
GenericName[ta]=BitTorrent வாடிக்கையாளர்
|
GenericName[ta]=BitTorrent வாடிக்கையாளர்
|
||||||
|
|||||||
4
dist/windows/options.nsi
vendored
4
dist/windows/options.nsi
vendored
@@ -28,7 +28,7 @@ XPStyle on
|
|||||||
!define CSIDL_LOCALAPPDATA '0x1C' ;Local Application Data path
|
!define CSIDL_LOCALAPPDATA '0x1C' ;Local Application Data path
|
||||||
|
|
||||||
; Program specific
|
; Program specific
|
||||||
!define PROG_VERSION "4.3.2"
|
!define PROG_VERSION "4.3.3"
|
||||||
|
|
||||||
!define MUI_FINISHPAGE_RUN
|
!define MUI_FINISHPAGE_RUN
|
||||||
!define MUI_FINISHPAGE_RUN_FUNCTION PageFinishRun
|
!define MUI_FINISHPAGE_RUN_FUNCTION PageFinishRun
|
||||||
@@ -51,7 +51,7 @@ XPStyle on
|
|||||||
;Installer Version Information
|
;Installer Version Information
|
||||||
VIAddVersionKey "ProductName" "qBittorrent"
|
VIAddVersionKey "ProductName" "qBittorrent"
|
||||||
VIAddVersionKey "CompanyName" "The qBittorrent project"
|
VIAddVersionKey "CompanyName" "The qBittorrent project"
|
||||||
VIAddVersionKey "LegalCopyright" "Copyright ©2006-2020 The qBittorrent project"
|
VIAddVersionKey "LegalCopyright" "Copyright ©2006-2021 The qBittorrent project"
|
||||||
VIAddVersionKey "FileDescription" "qBittorrent - A Bittorrent Client"
|
VIAddVersionKey "FileDescription" "qBittorrent - A Bittorrent Client"
|
||||||
VIAddVersionKey "FileVersion" "${PROG_VERSION}"
|
VIAddVersionKey "FileVersion" "${PROG_VERSION}"
|
||||||
|
|
||||||
|
|||||||
@@ -37,15 +37,15 @@ AC_DEFUN([FIND_QTDBUS],
|
|||||||
HAVE_QTDBUS=[false]])
|
HAVE_QTDBUS=[false]])
|
||||||
])
|
])
|
||||||
|
|
||||||
# DETECT_CPP14_PROGRAM()
|
# DETECT_CPP17_PROGRAM()
|
||||||
# Detects if at least C++14 mode is enabled.
|
# Detects if at least C++17 mode is enabled.
|
||||||
# --------------------------------------
|
# --------------------------------------
|
||||||
AC_DEFUN([DETECT_CPP14_PROGRAM],
|
AC_DEFUN([DETECT_CPP17_PROGRAM],
|
||||||
[AC_LANG_PROGRAM([[
|
[AC_LANG_PROGRAM([[
|
||||||
#ifndef __cplusplus
|
#ifndef __cplusplus
|
||||||
#error "This is not a C++ compiler"
|
#error "This is not a C++ compiler"
|
||||||
#elif __cplusplus < 201402L
|
#elif __cplusplus < 201703L
|
||||||
#error "This is not a C++14 compiler"
|
#error "This is not a C++17 compiler"
|
||||||
#endif]],
|
#endif]],
|
||||||
[[]])
|
[[]])
|
||||||
])
|
])
|
||||||
|
|||||||
@@ -7,6 +7,8 @@ else {
|
|||||||
include(conf.pri)
|
include(conf.pri)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QMAKE_MACOSX_DEPLOYMENT_TARGET = 10.14
|
||||||
|
|
||||||
LIBS += -framework Carbon -framework IOKit -framework AppKit
|
LIBS += -framework Carbon -framework IOKit -framework AppKit
|
||||||
|
|
||||||
QT_LANG_PATH = ../dist/qt-translations
|
QT_LANG_PATH = ../dist/qt-translations
|
||||||
|
|||||||
@@ -4,19 +4,6 @@ SUBDIRS += src
|
|||||||
|
|
||||||
include(version.pri)
|
include(version.pri)
|
||||||
|
|
||||||
# Make target to create release tarball. Use 'make tarball'
|
|
||||||
tarball.commands += rm -fR ../$${PROJECT_NAME}-$${PROJECT_VERSION}/ &&
|
|
||||||
tarball.commands += git clone . ../$${PROJECT_NAME}-$${PROJECT_VERSION} &&
|
|
||||||
tarball.commands += rm -fR ../$${PROJECT_NAME}-$${PROJECT_VERSION}/.git &&
|
|
||||||
tarball.commands += rm -f ../$${PROJECT_NAME}-$${PROJECT_VERSION}/.gitignore &&
|
|
||||||
tarball.commands += cd .. &&
|
|
||||||
tarball.commands += tar czf $${PROJECT_NAME}-$${PROJECT_VERSION}.tar.gz $${PROJECT_NAME}-$${PROJECT_VERSION} &&
|
|
||||||
tarball.commands += tar cf $${PROJECT_NAME}-$${PROJECT_VERSION}.tar $${PROJECT_NAME}-$${PROJECT_VERSION} &&
|
|
||||||
tarball.commands += xz -f $${PROJECT_NAME}-$${PROJECT_VERSION}.tar &&
|
|
||||||
tarball.commands += rm -fR $${PROJECT_NAME}-$${PROJECT_VERSION}
|
|
||||||
|
|
||||||
QMAKE_EXTRA_TARGETS += tarball
|
|
||||||
|
|
||||||
# For Qt Creator beautifier
|
# For Qt Creator beautifier
|
||||||
DISTFILES += \
|
DISTFILES += \
|
||||||
uncrustify.cfg
|
uncrustify.cfg
|
||||||
|
|||||||
@@ -61,7 +61,6 @@ target_sources(qbt_app PRIVATE
|
|||||||
|
|
||||||
target_link_libraries(qbt_app PRIVATE
|
target_link_libraries(qbt_app PRIVATE
|
||||||
qbt_base
|
qbt_base
|
||||||
qbt_version_definitions
|
|
||||||
)
|
)
|
||||||
|
|
||||||
set_target_properties(qbt_app PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}")
|
set_target_properties(qbt_app PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}")
|
||||||
|
|||||||
@@ -63,7 +63,7 @@
|
|||||||
|
|
||||||
#include "base/bittorrent/infohash.h"
|
#include "base/bittorrent/infohash.h"
|
||||||
#include "base/bittorrent/session.h"
|
#include "base/bittorrent/session.h"
|
||||||
#include "base/bittorrent/torrenthandle.h"
|
#include "base/bittorrent/torrent.h"
|
||||||
#include "base/exceptions.h"
|
#include "base/exceptions.h"
|
||||||
#include "base/iconprovider.h"
|
#include "base/iconprovider.h"
|
||||||
#include "base/logger.h"
|
#include "base/logger.h"
|
||||||
@@ -81,6 +81,7 @@
|
|||||||
#include "base/utils/fs.h"
|
#include "base/utils/fs.h"
|
||||||
#include "base/utils/misc.h"
|
#include "base/utils/misc.h"
|
||||||
#include "base/utils/string.h"
|
#include "base/utils/string.h"
|
||||||
|
#include "base/version.h"
|
||||||
#include "applicationinstancemanager.h"
|
#include "applicationinstancemanager.h"
|
||||||
#include "filelogger.h"
|
#include "filelogger.h"
|
||||||
|
|
||||||
@@ -214,7 +215,7 @@ const QBtCommandLineParameters &Application::commandLineArgs() const
|
|||||||
|
|
||||||
bool Application::isFileLoggerEnabled() const
|
bool Application::isFileLoggerEnabled() const
|
||||||
{
|
{
|
||||||
return settings()->loadValue(KEY_FILELOGGER_ENABLED, true).toBool();
|
return settings()->loadValue(KEY_FILELOGGER_ENABLED, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Application::setFileLoggerEnabled(const bool value)
|
void Application::setFileLoggerEnabled(const bool value)
|
||||||
@@ -228,8 +229,8 @@ void Application::setFileLoggerEnabled(const bool value)
|
|||||||
|
|
||||||
QString Application::fileLoggerPath() const
|
QString Application::fileLoggerPath() const
|
||||||
{
|
{
|
||||||
return settings()->loadValue(KEY_FILELOGGER_PATH,
|
return settings()->loadValue(KEY_FILELOGGER_PATH
|
||||||
{specialFolderLocation(SpecialFolder::Data) + LOG_FOLDER}).toString();
|
, QString {specialFolderLocation(SpecialFolder::Data) + LOG_FOLDER});
|
||||||
}
|
}
|
||||||
|
|
||||||
void Application::setFileLoggerPath(const QString &path)
|
void Application::setFileLoggerPath(const QString &path)
|
||||||
@@ -241,7 +242,7 @@ void Application::setFileLoggerPath(const QString &path)
|
|||||||
|
|
||||||
bool Application::isFileLoggerBackup() const
|
bool Application::isFileLoggerBackup() const
|
||||||
{
|
{
|
||||||
return settings()->loadValue(KEY_FILELOGGER_BACKUP, true).toBool();
|
return settings()->loadValue(KEY_FILELOGGER_BACKUP, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Application::setFileLoggerBackup(const bool value)
|
void Application::setFileLoggerBackup(const bool value)
|
||||||
@@ -253,7 +254,7 @@ void Application::setFileLoggerBackup(const bool value)
|
|||||||
|
|
||||||
bool Application::isFileLoggerDeleteOld() const
|
bool Application::isFileLoggerDeleteOld() const
|
||||||
{
|
{
|
||||||
return settings()->loadValue(KEY_FILELOGGER_DELETEOLD, true).toBool();
|
return settings()->loadValue(KEY_FILELOGGER_DELETEOLD, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Application::setFileLoggerDeleteOld(const bool value)
|
void Application::setFileLoggerDeleteOld(const bool value)
|
||||||
@@ -265,7 +266,7 @@ void Application::setFileLoggerDeleteOld(const bool value)
|
|||||||
|
|
||||||
int Application::fileLoggerMaxSize() const
|
int Application::fileLoggerMaxSize() const
|
||||||
{
|
{
|
||||||
const int val = settings()->loadValue(KEY_FILELOGGER_MAXSIZEBYTES, DEFAULT_FILELOG_SIZE).toInt();
|
const int val = settings()->loadValue(KEY_FILELOGGER_MAXSIZEBYTES, DEFAULT_FILELOG_SIZE);
|
||||||
return std::min(std::max(val, MIN_FILELOG_SIZE), MAX_FILELOG_SIZE);
|
return std::min(std::max(val, MIN_FILELOG_SIZE), MAX_FILELOG_SIZE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -279,7 +280,7 @@ void Application::setFileLoggerMaxSize(const int bytes)
|
|||||||
|
|
||||||
int Application::fileLoggerAge() const
|
int Application::fileLoggerAge() const
|
||||||
{
|
{
|
||||||
const int val = settings()->loadValue(KEY_FILELOGGER_AGE, 1).toInt();
|
const int val = settings()->loadValue(KEY_FILELOGGER_AGE, 1);
|
||||||
return std::min(std::max(val, 1), 365);
|
return std::min(std::max(val, 1), 365);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -290,7 +291,7 @@ void Application::setFileLoggerAge(const int value)
|
|||||||
|
|
||||||
int Application::fileLoggerAgeType() const
|
int Application::fileLoggerAgeType() const
|
||||||
{
|
{
|
||||||
const int val = settings()->loadValue(KEY_FILELOGGER_AGETYPE, 1).toInt();
|
const int val = settings()->loadValue(KEY_FILELOGGER_AGETYPE, 1);
|
||||||
return ((val < 0) || (val > 2)) ? 1 : val;
|
return ((val < 0) || (val > 2)) ? 1 : val;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -310,7 +311,7 @@ void Application::processMessage(const QString &message)
|
|||||||
m_paramsQueue.append(params);
|
m_paramsQueue.append(params);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Application::runExternalProgram(const BitTorrent::TorrentHandle *torrent) const
|
void Application::runExternalProgram(const BitTorrent::Torrent *torrent) const
|
||||||
{
|
{
|
||||||
QString program = Preferences::instance()->getAutoRunProgram().trimmed();
|
QString program = Preferences::instance()->getAutoRunProgram().trimmed();
|
||||||
program.replace("%N", torrent->name());
|
program.replace("%N", torrent->name());
|
||||||
@@ -404,7 +405,7 @@ void Application::runExternalProgram(const BitTorrent::TorrentHandle *torrent) c
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void Application::sendNotificationEmail(const BitTorrent::TorrentHandle *torrent)
|
void Application::sendNotificationEmail(const BitTorrent::Torrent *torrent)
|
||||||
{
|
{
|
||||||
// Prepare mail content
|
// Prepare mail content
|
||||||
const QString content = tr("Torrent name: %1").arg(torrent->name()) + '\n'
|
const QString content = tr("Torrent name: %1").arg(torrent->name()) + '\n'
|
||||||
@@ -423,7 +424,7 @@ void Application::sendNotificationEmail(const BitTorrent::TorrentHandle *torrent
|
|||||||
content);
|
content);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Application::torrentFinished(BitTorrent::TorrentHandle *const torrent)
|
void Application::torrentFinished(BitTorrent::Torrent *const torrent)
|
||||||
{
|
{
|
||||||
Preferences *const pref = Preferences::instance();
|
Preferences *const pref = Preferences::instance();
|
||||||
|
|
||||||
@@ -505,7 +506,7 @@ void Application::processParams(const QStringList ¶ms)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
BitTorrent::AddTorrentParams torrentParams;
|
BitTorrent::AddTorrentParams torrentParams;
|
||||||
TriStateBool skipTorrentDialog;
|
std::optional<bool> skipTorrentDialog;
|
||||||
|
|
||||||
for (QString param : params)
|
for (QString param : params)
|
||||||
{
|
{
|
||||||
@@ -521,7 +522,7 @@ void Application::processParams(const QStringList ¶ms)
|
|||||||
|
|
||||||
if (param.startsWith(QLatin1String("@addPaused=")))
|
if (param.startsWith(QLatin1String("@addPaused=")))
|
||||||
{
|
{
|
||||||
torrentParams.addPaused = param.midRef(11).toInt() ? TriStateBool::True : TriStateBool::False;
|
torrentParams.addPaused = (param.midRef(11).toInt() != 0);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -551,7 +552,7 @@ void Application::processParams(const QStringList ¶ms)
|
|||||||
|
|
||||||
if (param.startsWith(QLatin1String("@skipDialog=")))
|
if (param.startsWith(QLatin1String("@skipDialog=")))
|
||||||
{
|
{
|
||||||
skipTorrentDialog = param.midRef(12).toInt() ? TriStateBool::True : TriStateBool::False;
|
skipTorrentDialog = (param.midRef(12).toInt() != 0);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -561,9 +562,7 @@ void Application::processParams(const QStringList ¶ms)
|
|||||||
// be shown and skipTorrentDialog is undefined. The other is when
|
// be shown and skipTorrentDialog is undefined. The other is when
|
||||||
// skipTorrentDialog is false, meaning that the application setting
|
// skipTorrentDialog is false, meaning that the application setting
|
||||||
// should be overridden.
|
// should be overridden.
|
||||||
const bool showDialogForThisTorrent =
|
const bool showDialogForThisTorrent = !skipTorrentDialog.value_or(!AddNewTorrentDialog::isEnabled());
|
||||||
((AddNewTorrentDialog::isEnabled() && skipTorrentDialog == TriStateBool::Undefined)
|
|
||||||
|| skipTorrentDialog == TriStateBool::False);
|
|
||||||
if (showDialogForThisTorrent)
|
if (showDialogForThisTorrent)
|
||||||
AddNewTorrentDialog::show(param, torrentParams, m_window);
|
AddNewTorrentDialog::show(param, torrentParams, m_window);
|
||||||
else
|
else
|
||||||
|
|||||||
@@ -59,7 +59,7 @@ class FileLogger;
|
|||||||
|
|
||||||
namespace BitTorrent
|
namespace BitTorrent
|
||||||
{
|
{
|
||||||
class TorrentHandle;
|
class Torrent;
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace RSS
|
namespace RSS
|
||||||
@@ -112,7 +112,7 @@ protected:
|
|||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void processMessage(const QString &message);
|
void processMessage(const QString &message);
|
||||||
void torrentFinished(BitTorrent::TorrentHandle *const torrent);
|
void torrentFinished(BitTorrent::Torrent *const torrent);
|
||||||
void allTorrentsFinished();
|
void allTorrentsFinished();
|
||||||
void cleanup();
|
void cleanup();
|
||||||
#if (!defined(DISABLE_GUI) && defined(Q_OS_WIN))
|
#if (!defined(DISABLE_GUI) && defined(Q_OS_WIN))
|
||||||
@@ -142,6 +142,6 @@ private:
|
|||||||
|
|
||||||
void initializeTranslation();
|
void initializeTranslation();
|
||||||
void processParams(const QStringList ¶ms);
|
void processParams(const QStringList ¶ms);
|
||||||
void runExternalProgram(const BitTorrent::TorrentHandle *torrent) const;
|
void runExternalProgram(const BitTorrent::Torrent *torrent) const;
|
||||||
void sendNotificationEmail(const BitTorrent::TorrentHandle *torrent);
|
void sendNotificationEmail(const BitTorrent::Torrent *torrent);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -254,13 +254,13 @@ namespace
|
|||||||
return padUsageText(fullParameter() + QLatin1String("=<true|false>"));
|
return padUsageText(fullParameter() + QLatin1String("=<true|false>"));
|
||||||
}
|
}
|
||||||
|
|
||||||
TriStateBool value(const QString &arg) const
|
std::optional<bool> value(const QString &arg) const
|
||||||
{
|
{
|
||||||
QStringList parts = arg.split(QLatin1Char('='));
|
QStringList parts = arg.split(QLatin1Char('='));
|
||||||
|
|
||||||
if (parts.size() == 1)
|
if (parts.size() == 1)
|
||||||
{
|
{
|
||||||
return TriStateBool(m_defaultValue);
|
return m_defaultValue;
|
||||||
}
|
}
|
||||||
if (parts.size() == 2)
|
if (parts.size() == 2)
|
||||||
{
|
{
|
||||||
@@ -268,11 +268,11 @@ namespace
|
|||||||
|
|
||||||
if ((val.toUpper() == QLatin1String("TRUE")) || (val == QLatin1String("1")))
|
if ((val.toUpper() == QLatin1String("TRUE")) || (val == QLatin1String("1")))
|
||||||
{
|
{
|
||||||
return TriStateBool::True;
|
return true;
|
||||||
}
|
}
|
||||||
if ((val.toUpper() == QLatin1String("FALSE")) || (val == QLatin1String("0")))
|
if ((val.toUpper() == QLatin1String("FALSE")) || (val == QLatin1String("0")))
|
||||||
{
|
{
|
||||||
return TriStateBool::False;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -282,30 +282,30 @@ namespace
|
|||||||
.arg(fullParameter(), QLatin1String("<true|false>")));
|
.arg(fullParameter(), QLatin1String("<true|false>")));
|
||||||
}
|
}
|
||||||
|
|
||||||
TriStateBool value(const QProcessEnvironment &env) const
|
std::optional<bool> value(const QProcessEnvironment &env) const
|
||||||
{
|
{
|
||||||
const QString val = env.value(envVarName(), "-1");
|
const QString val = env.value(envVarName(), "-1");
|
||||||
|
|
||||||
if (val.isEmpty())
|
if (val.isEmpty())
|
||||||
{
|
{
|
||||||
return TriStateBool(m_defaultValue);
|
return m_defaultValue;
|
||||||
}
|
}
|
||||||
if (val == QLatin1String("-1"))
|
if (val == QLatin1String("-1"))
|
||||||
{
|
{
|
||||||
return TriStateBool::Undefined;
|
return std::nullopt;
|
||||||
}
|
}
|
||||||
if ((val.toUpper() == QLatin1String("TRUE")) || (val == QLatin1String("1")))
|
if ((val.toUpper() == QLatin1String("TRUE")) || (val == QLatin1String("1")))
|
||||||
{
|
{
|
||||||
return TriStateBool::True;
|
return true;
|
||||||
}
|
}
|
||||||
if ((val.toUpper() == QLatin1String("FALSE")) || (val == QLatin1String("0")))
|
if ((val.toUpper() == QLatin1String("FALSE")) || (val == QLatin1String("0")))
|
||||||
{
|
{
|
||||||
return TriStateBool::False;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
qDebug() << QObject::tr("Expected %1 in environment variable '%2', but got '%3'")
|
qDebug() << QObject::tr("Expected %1 in environment variable '%2', but got '%3'")
|
||||||
.arg(QLatin1String("true|false"), envVarName(), val);
|
.arg(QLatin1String("true|false"), envVarName(), val);
|
||||||
return TriStateBool::Undefined;
|
return std::nullopt;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool m_defaultValue;
|
bool m_defaultValue;
|
||||||
@@ -374,14 +374,8 @@ QStringList QBtCommandLineParameters::paramList() const
|
|||||||
if (!savePath.isEmpty())
|
if (!savePath.isEmpty())
|
||||||
result.append(QLatin1String("@savePath=") + savePath);
|
result.append(QLatin1String("@savePath=") + savePath);
|
||||||
|
|
||||||
if (addPaused == TriStateBool::True)
|
if (addPaused.has_value())
|
||||||
{
|
result.append(*addPaused ? QLatin1String {"@addPaused=1"} : QLatin1String {"@addPaused=0"});
|
||||||
result.append(QLatin1String("@addPaused=1"));
|
|
||||||
}
|
|
||||||
else if (addPaused == TriStateBool::False)
|
|
||||||
{
|
|
||||||
result.append(QLatin1String("@addPaused=0"));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (skipChecking)
|
if (skipChecking)
|
||||||
result.append(QLatin1String("@skipChecking"));
|
result.append(QLatin1String("@skipChecking"));
|
||||||
@@ -395,14 +389,8 @@ QStringList QBtCommandLineParameters::paramList() const
|
|||||||
if (firstLastPiecePriority)
|
if (firstLastPiecePriority)
|
||||||
result.append(QLatin1String("@firstLastPiecePriority"));
|
result.append(QLatin1String("@firstLastPiecePriority"));
|
||||||
|
|
||||||
if (skipDialog == TriStateBool::True)
|
if (skipDialog.has_value())
|
||||||
{
|
result.append(*skipDialog ? QLatin1String {"@skipDialog=1"} : QLatin1String {"@skipDialog=0"});
|
||||||
result.append(QLatin1String("@skipDialog=1"));
|
|
||||||
}
|
|
||||||
else if (skipDialog == TriStateBool::False)
|
|
||||||
{
|
|
||||||
result.append(QLatin1String("@skipDialog=0"));
|
|
||||||
}
|
|
||||||
|
|
||||||
result += torrents;
|
result += torrents;
|
||||||
return result;
|
return result;
|
||||||
|
|||||||
@@ -30,13 +30,12 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <optional>
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
|
|
||||||
#include <QString>
|
#include <QString>
|
||||||
#include <QStringList>
|
#include <QStringList>
|
||||||
|
|
||||||
#include "base/tristatebool.h"
|
|
||||||
|
|
||||||
class QProcessEnvironment;
|
class QProcessEnvironment;
|
||||||
|
|
||||||
struct QBtCommandLineParameters
|
struct QBtCommandLineParameters
|
||||||
@@ -55,8 +54,8 @@ struct QBtCommandLineParameters
|
|||||||
bool shouldDaemonize;
|
bool shouldDaemonize;
|
||||||
#endif
|
#endif
|
||||||
int webUiPort;
|
int webUiPort;
|
||||||
TriStateBool addPaused;
|
std::optional<bool> addPaused;
|
||||||
TriStateBool skipDialog;
|
std::optional<bool> skipDialog;
|
||||||
QStringList torrents;
|
QStringList torrents;
|
||||||
QString profileDir;
|
QString profileDir;
|
||||||
QString configurationName;
|
QString configurationName;
|
||||||
|
|||||||
@@ -78,6 +78,7 @@ Q_IMPORT_PLUGIN(QICOPlugin)
|
|||||||
|
|
||||||
#include "base/preferences.h"
|
#include "base/preferences.h"
|
||||||
#include "base/profile.h"
|
#include "base/profile.h"
|
||||||
|
#include "base/version.h"
|
||||||
#include "application.h"
|
#include "application.h"
|
||||||
#include "cmdoptions.h"
|
#include "cmdoptions.h"
|
||||||
#include "upgrade.h"
|
#include "upgrade.h"
|
||||||
|
|||||||
@@ -152,7 +152,7 @@ bool QtLocalPeer::isClient()
|
|||||||
#endif
|
#endif
|
||||||
if (!res)
|
if (!res)
|
||||||
qWarning("QtSingleCoreApplication: listen on local socket failed, %s", qPrintable(server->errorString()));
|
qWarning("QtSingleCoreApplication: listen on local socket failed, %s", qPrintable(server->errorString()));
|
||||||
QObject::connect(server, SIGNAL(newConnection()), SLOT(receiveConnection()));
|
connect(server, &QLocalServer::newConnection, this, &QtLocalPeer::receiveConnection);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -32,6 +32,7 @@
|
|||||||
#include <QString>
|
#include <QString>
|
||||||
|
|
||||||
#include "base/utils/misc.h"
|
#include "base/utils/misc.h"
|
||||||
|
#include "base/version.h"
|
||||||
#include "ui_stacktracedialog.h"
|
#include "ui_stacktracedialog.h"
|
||||||
|
|
||||||
StacktraceDialog::StacktraceDialog(QWidget *parent)
|
StacktraceDialog::StacktraceDialog(QWidget *parent)
|
||||||
|
|||||||
@@ -46,8 +46,8 @@ namespace
|
|||||||
const auto migrate = [](const QString &oldKey, const QString &newKey, const QString &savePath)
|
const auto migrate = [](const QString &oldKey, const QString &newKey, const QString &savePath)
|
||||||
{
|
{
|
||||||
SettingsStorage *settingsStorage {SettingsStorage::instance()};
|
SettingsStorage *settingsStorage {SettingsStorage::instance()};
|
||||||
const QByteArray oldData {settingsStorage->loadValue(oldKey).toByteArray()};
|
const auto oldData {settingsStorage->loadValue<QByteArray>(oldKey)};
|
||||||
const QString newData {settingsStorage->loadValue(newKey).toString()};
|
const auto newData {settingsStorage->loadValue<QString>(newKey)};
|
||||||
const QString errorMsgFormat {QObject::tr("Migrate preferences failed: WebUI https, file: \"%1\", error: \"%2\"")};
|
const QString errorMsgFormat {QObject::tr("Migrate preferences failed: WebUI https, file: \"%1\", error: \"%2\"")};
|
||||||
|
|
||||||
if (!newData.isEmpty() || oldData.isEmpty())
|
if (!newData.isEmpty() || oldData.isEmpty())
|
||||||
@@ -89,8 +89,8 @@ namespace
|
|||||||
const QString newKey {QLatin1String {"BitTorrent/Session/TorrentContentLayout"}};
|
const QString newKey {QLatin1String {"BitTorrent/Session/TorrentContentLayout"}};
|
||||||
|
|
||||||
SettingsStorage *settingsStorage {SettingsStorage::instance()};
|
SettingsStorage *settingsStorage {SettingsStorage::instance()};
|
||||||
const QVariant oldData {settingsStorage->loadValue(oldKey)};
|
const auto oldData {settingsStorage->loadValue<QVariant>(oldKey)};
|
||||||
const QString newData {settingsStorage->loadValue(newKey).toString()};
|
const auto newData {settingsStorage->loadValue<QString>(newKey)};
|
||||||
|
|
||||||
if (!newData.isEmpty() || !oldData.isValid())
|
if (!newData.isEmpty() || !oldData.isValid())
|
||||||
return;
|
return;
|
||||||
@@ -128,7 +128,7 @@ void handleChangedDefaults(const DefaultPreferencesMode mode)
|
|||||||
SettingsStorage *settingsStorage {SettingsStorage::instance()};
|
SettingsStorage *settingsStorage {SettingsStorage::instance()};
|
||||||
for (auto it = changedDefaults.cbegin(); it != changedDefaults.cend(); ++it)
|
for (auto it = changedDefaults.cbegin(); it != changedDefaults.cend(); ++it)
|
||||||
{
|
{
|
||||||
if (settingsStorage->loadValue(it->name).isNull())
|
if (settingsStorage->loadValue<QVariant>(it->name).isNull())
|
||||||
settingsStorage->storeValue(it->name, (mode == DefaultPreferencesMode::Legacy ? it->legacy : it->current));
|
settingsStorage->storeValue(it->name, (mode == DefaultPreferencesMode::Legacy ? it->legacy : it->current));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ add_library(qbt_base STATIC
|
|||||||
# headers
|
# headers
|
||||||
algorithm.h
|
algorithm.h
|
||||||
asyncfilestorage.h
|
asyncfilestorage.h
|
||||||
|
bittorrent/abstractfilestorage.h
|
||||||
bittorrent/addtorrentparams.h
|
bittorrent/addtorrentparams.h
|
||||||
bittorrent/bandwidthscheduler.h
|
bittorrent/bandwidthscheduler.h
|
||||||
bittorrent/cachestatus.h
|
bittorrent/cachestatus.h
|
||||||
@@ -24,10 +25,10 @@ add_library(qbt_base STATIC
|
|||||||
bittorrent/sessionstatus.h
|
bittorrent/sessionstatus.h
|
||||||
bittorrent/speedmonitor.h
|
bittorrent/speedmonitor.h
|
||||||
bittorrent/statistics.h
|
bittorrent/statistics.h
|
||||||
|
bittorrent/torrent.h
|
||||||
bittorrent/torrentcontentlayout.h
|
bittorrent/torrentcontentlayout.h
|
||||||
bittorrent/torrentcreatorthread.h
|
bittorrent/torrentcreatorthread.h
|
||||||
bittorrent/torrenthandle.h
|
bittorrent/torrentimpl.h
|
||||||
bittorrent/torrenthandleimpl.h
|
|
||||||
bittorrent/torrentinfo.h
|
bittorrent/torrentinfo.h
|
||||||
bittorrent/tracker.h
|
bittorrent/tracker.h
|
||||||
bittorrent/trackerentry.h
|
bittorrent/trackerentry.h
|
||||||
@@ -72,7 +73,6 @@ add_library(qbt_base STATIC
|
|||||||
settingsstorage.h
|
settingsstorage.h
|
||||||
torrentfileguard.h
|
torrentfileguard.h
|
||||||
torrentfilter.h
|
torrentfilter.h
|
||||||
tristatebool.h
|
|
||||||
types.h
|
types.h
|
||||||
unicodestrings.h
|
unicodestrings.h
|
||||||
utils/bytearray.h
|
utils/bytearray.h
|
||||||
@@ -86,9 +86,11 @@ add_library(qbt_base STATIC
|
|||||||
utils/random.h
|
utils/random.h
|
||||||
utils/string.h
|
utils/string.h
|
||||||
utils/version.h
|
utils/version.h
|
||||||
|
version.h
|
||||||
|
|
||||||
# sources
|
# sources
|
||||||
asyncfilestorage.cpp
|
asyncfilestorage.cpp
|
||||||
|
bittorrent/abstractfilestorage.cpp
|
||||||
bittorrent/bandwidthscheduler.cpp
|
bittorrent/bandwidthscheduler.cpp
|
||||||
bittorrent/customstorage.cpp
|
bittorrent/customstorage.cpp
|
||||||
bittorrent/downloadpriority.cpp
|
bittorrent/downloadpriority.cpp
|
||||||
@@ -105,9 +107,9 @@ add_library(qbt_base STATIC
|
|||||||
bittorrent/session.cpp
|
bittorrent/session.cpp
|
||||||
bittorrent/speedmonitor.cpp
|
bittorrent/speedmonitor.cpp
|
||||||
bittorrent/statistics.cpp
|
bittorrent/statistics.cpp
|
||||||
|
bittorrent/torrent.cpp
|
||||||
bittorrent/torrentcreatorthread.cpp
|
bittorrent/torrentcreatorthread.cpp
|
||||||
bittorrent/torrenthandle.cpp
|
bittorrent/torrentimpl.cpp
|
||||||
bittorrent/torrenthandleimpl.cpp
|
|
||||||
bittorrent/torrentinfo.cpp
|
bittorrent/torrentinfo.cpp
|
||||||
bittorrent/tracker.cpp
|
bittorrent/tracker.cpp
|
||||||
bittorrent/trackerentry.cpp
|
bittorrent/trackerentry.cpp
|
||||||
@@ -148,7 +150,6 @@ add_library(qbt_base STATIC
|
|||||||
settingsstorage.cpp
|
settingsstorage.cpp
|
||||||
torrentfileguard.cpp
|
torrentfileguard.cpp
|
||||||
torrentfilter.cpp
|
torrentfilter.cpp
|
||||||
tristatebool.cpp
|
|
||||||
utils/bytearray.cpp
|
utils/bytearray.cpp
|
||||||
utils/foreignapps.cpp
|
utils/foreignapps.cpp
|
||||||
utils/fs.cpp
|
utils/fs.cpp
|
||||||
@@ -165,7 +166,6 @@ target_link_libraries(qbt_base
|
|||||||
PRIVATE
|
PRIVATE
|
||||||
OpenSSL::Crypto OpenSSL::SSL
|
OpenSSL::Crypto OpenSSL::SSL
|
||||||
ZLIB::ZLIB
|
ZLIB::ZLIB
|
||||||
qbt_version_definitions
|
|
||||||
PUBLIC
|
PUBLIC
|
||||||
LibtorrentRasterbar::torrent-rasterbar
|
LibtorrentRasterbar::torrent-rasterbar
|
||||||
Qt5::Core Qt5::Network Qt5::Xml
|
Qt5::Core Qt5::Network Qt5::Xml
|
||||||
|
|||||||
@@ -32,9 +32,6 @@
|
|||||||
|
|
||||||
namespace Algorithm
|
namespace Algorithm
|
||||||
{
|
{
|
||||||
template <typename ...>
|
|
||||||
using void_t = void; // replace this with std::void_t in C++17
|
|
||||||
|
|
||||||
template <typename T, typename = void>
|
template <typename T, typename = void>
|
||||||
struct HasMappedType
|
struct HasMappedType
|
||||||
: std::false_type
|
: std::false_type
|
||||||
@@ -42,7 +39,7 @@ namespace Algorithm
|
|||||||
};
|
};
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
struct HasMappedType<T, void_t<typename T::mapped_type>>
|
struct HasMappedType<T, std::void_t<typename T::mapped_type>>
|
||||||
: std::true_type
|
: std::true_type
|
||||||
{
|
{
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
HEADERS += \
|
HEADERS += \
|
||||||
$$PWD/algorithm.h \
|
$$PWD/algorithm.h \
|
||||||
$$PWD/asyncfilestorage.h \
|
$$PWD/asyncfilestorage.h \
|
||||||
|
$$PWD/bittorrent/abstractfilestorage.h \
|
||||||
$$PWD/bittorrent/addtorrentparams.h \
|
$$PWD/bittorrent/addtorrentparams.h \
|
||||||
$$PWD/bittorrent/bandwidthscheduler.h \
|
$$PWD/bittorrent/bandwidthscheduler.h \
|
||||||
$$PWD/bittorrent/cachestatus.h \
|
$$PWD/bittorrent/cachestatus.h \
|
||||||
@@ -23,10 +24,10 @@ HEADERS += \
|
|||||||
$$PWD/bittorrent/sessionstatus.h \
|
$$PWD/bittorrent/sessionstatus.h \
|
||||||
$$PWD/bittorrent/speedmonitor.h \
|
$$PWD/bittorrent/speedmonitor.h \
|
||||||
$$PWD/bittorrent/statistics.h \
|
$$PWD/bittorrent/statistics.h \
|
||||||
|
$$PWD/bittorrent/torrent.h \
|
||||||
$$PWD/bittorrent/torrentcontentlayout.h \
|
$$PWD/bittorrent/torrentcontentlayout.h \
|
||||||
$$PWD/bittorrent/torrentcreatorthread.h \
|
$$PWD/bittorrent/torrentcreatorthread.h \
|
||||||
$$PWD/bittorrent/torrenthandle.h \
|
$$PWD/bittorrent/torrentimpl.h \
|
||||||
$$PWD/bittorrent/torrenthandleimpl.h \
|
|
||||||
$$PWD/bittorrent/torrentinfo.h \
|
$$PWD/bittorrent/torrentinfo.h \
|
||||||
$$PWD/bittorrent/tracker.h \
|
$$PWD/bittorrent/tracker.h \
|
||||||
$$PWD/bittorrent/trackerentry.h \
|
$$PWD/bittorrent/trackerentry.h \
|
||||||
@@ -72,7 +73,6 @@ HEADERS += \
|
|||||||
$$PWD/settingvalue.h \
|
$$PWD/settingvalue.h \
|
||||||
$$PWD/torrentfileguard.h \
|
$$PWD/torrentfileguard.h \
|
||||||
$$PWD/torrentfilter.h \
|
$$PWD/torrentfilter.h \
|
||||||
$$PWD/tristatebool.h \
|
|
||||||
$$PWD/types.h \
|
$$PWD/types.h \
|
||||||
$$PWD/unicodestrings.h \
|
$$PWD/unicodestrings.h \
|
||||||
$$PWD/utils/bytearray.h \
|
$$PWD/utils/bytearray.h \
|
||||||
@@ -85,10 +85,12 @@ HEADERS += \
|
|||||||
$$PWD/utils/password.h \
|
$$PWD/utils/password.h \
|
||||||
$$PWD/utils/random.h \
|
$$PWD/utils/random.h \
|
||||||
$$PWD/utils/string.h \
|
$$PWD/utils/string.h \
|
||||||
$$PWD/utils/version.h
|
$$PWD/utils/version.h \
|
||||||
|
$$PWD/version.h
|
||||||
|
|
||||||
SOURCES += \
|
SOURCES += \
|
||||||
$$PWD/asyncfilestorage.cpp \
|
$$PWD/asyncfilestorage.cpp \
|
||||||
|
$$PWD/bittorrent/abstractfilestorage.cpp \
|
||||||
$$PWD/bittorrent/bandwidthscheduler.cpp \
|
$$PWD/bittorrent/bandwidthscheduler.cpp \
|
||||||
$$PWD/bittorrent/customstorage.cpp \
|
$$PWD/bittorrent/customstorage.cpp \
|
||||||
$$PWD/bittorrent/downloadpriority.cpp \
|
$$PWD/bittorrent/downloadpriority.cpp \
|
||||||
@@ -105,9 +107,9 @@ SOURCES += \
|
|||||||
$$PWD/bittorrent/session.cpp \
|
$$PWD/bittorrent/session.cpp \
|
||||||
$$PWD/bittorrent/speedmonitor.cpp \
|
$$PWD/bittorrent/speedmonitor.cpp \
|
||||||
$$PWD/bittorrent/statistics.cpp \
|
$$PWD/bittorrent/statistics.cpp \
|
||||||
|
$$PWD/bittorrent/torrent.cpp \
|
||||||
$$PWD/bittorrent/torrentcreatorthread.cpp \
|
$$PWD/bittorrent/torrentcreatorthread.cpp \
|
||||||
$$PWD/bittorrent/torrenthandle.cpp \
|
$$PWD/bittorrent/torrentimpl.cpp \
|
||||||
$$PWD/bittorrent/torrenthandleimpl.cpp \
|
|
||||||
$$PWD/bittorrent/torrentinfo.cpp \
|
$$PWD/bittorrent/torrentinfo.cpp \
|
||||||
$$PWD/bittorrent/tracker.cpp \
|
$$PWD/bittorrent/tracker.cpp \
|
||||||
$$PWD/bittorrent/trackerentry.cpp \
|
$$PWD/bittorrent/trackerentry.cpp \
|
||||||
@@ -148,7 +150,6 @@ SOURCES += \
|
|||||||
$$PWD/settingsstorage.cpp \
|
$$PWD/settingsstorage.cpp \
|
||||||
$$PWD/torrentfileguard.cpp \
|
$$PWD/torrentfileguard.cpp \
|
||||||
$$PWD/torrentfilter.cpp \
|
$$PWD/torrentfilter.cpp \
|
||||||
$$PWD/tristatebool.cpp \
|
|
||||||
$$PWD/utils/bytearray.cpp \
|
$$PWD/utils/bytearray.cpp \
|
||||||
$$PWD/utils/foreignapps.cpp \
|
$$PWD/utils/foreignapps.cpp \
|
||||||
$$PWD/utils/fs.cpp \
|
$$PWD/utils/fs.cpp \
|
||||||
|
|||||||
140
src/base/bittorrent/abstractfilestorage.cpp
Normal file
140
src/base/bittorrent/abstractfilestorage.cpp
Normal file
@@ -0,0 +1,140 @@
|
|||||||
|
/*
|
||||||
|
* Bittorrent Client using Qt and libtorrent.
|
||||||
|
* Copyright (C) 2020 Vladimir Golovnev <glassez@yandex.ru>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* 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 "abstractfilestorage.h"
|
||||||
|
|
||||||
|
#include <QDir>
|
||||||
|
#include <QHash>
|
||||||
|
#include <QVector>
|
||||||
|
|
||||||
|
#include "base/bittorrent/common.h"
|
||||||
|
#include "base/exceptions.h"
|
||||||
|
#include "base/utils/fs.h"
|
||||||
|
|
||||||
|
#if defined(Q_OS_WIN)
|
||||||
|
const Qt::CaseSensitivity CASE_SENSITIVITY {Qt::CaseInsensitive};
|
||||||
|
#else
|
||||||
|
const Qt::CaseSensitivity CASE_SENSITIVITY {Qt::CaseSensitive};
|
||||||
|
#endif
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
bool areSameFileNames(QString first, QString second)
|
||||||
|
{
|
||||||
|
if (first.endsWith(QB_EXT, Qt::CaseInsensitive))
|
||||||
|
first.chop(QB_EXT.size());
|
||||||
|
if (second.endsWith(QB_EXT, Qt::CaseInsensitive))
|
||||||
|
second.chop(QB_EXT.size());
|
||||||
|
return QString::compare(first, second, CASE_SENSITIVITY) == 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void BitTorrent::AbstractFileStorage::renameFile(const QString &oldPath, const QString &newPath)
|
||||||
|
{
|
||||||
|
if (!Utils::Fs::isValidFileSystemName(oldPath, true))
|
||||||
|
throw RuntimeError {tr("The old path is invalid: '%1'.").arg(oldPath)};
|
||||||
|
if (!Utils::Fs::isValidFileSystemName(newPath, true))
|
||||||
|
throw RuntimeError {tr("The new path is invalid: '%1'.").arg(newPath)};
|
||||||
|
|
||||||
|
const QString oldFilePath = Utils::Fs::toUniformPath(oldPath);
|
||||||
|
if (oldFilePath.endsWith(QLatin1Char {'/'}))
|
||||||
|
throw RuntimeError {tr("Invalid file path: '%1'.").arg(oldFilePath)};
|
||||||
|
|
||||||
|
const QString newFilePath = Utils::Fs::toUniformPath(newPath);
|
||||||
|
if (newFilePath.endsWith(QLatin1Char {'/'}))
|
||||||
|
throw RuntimeError {tr("Invalid file path: '%1'.").arg(newFilePath)};
|
||||||
|
if (QDir().isAbsolutePath(newFilePath))
|
||||||
|
throw RuntimeError {tr("Absolute path isn't allowed: '%1'.").arg(newFilePath)};
|
||||||
|
|
||||||
|
int renamingFileIndex = -1;
|
||||||
|
for (int i = 0; i < filesCount(); ++i)
|
||||||
|
{
|
||||||
|
const QString path = filePath(i);
|
||||||
|
|
||||||
|
if ((renamingFileIndex < 0) && areSameFileNames(path, oldFilePath))
|
||||||
|
renamingFileIndex = i;
|
||||||
|
|
||||||
|
if (areSameFileNames(path, newFilePath))
|
||||||
|
throw RuntimeError {tr("The file already exists: '%1'.").arg(newFilePath)};
|
||||||
|
}
|
||||||
|
|
||||||
|
if (renamingFileIndex < 0)
|
||||||
|
throw RuntimeError {tr("No such file: '%1'.").arg(oldFilePath)};
|
||||||
|
|
||||||
|
const auto extAdjusted = [](const QString &path, const bool needExt) -> QString
|
||||||
|
{
|
||||||
|
if (path.endsWith(QB_EXT, Qt::CaseInsensitive) == needExt)
|
||||||
|
return path;
|
||||||
|
|
||||||
|
return (needExt ? (path + QB_EXT) : (path.left(path.size() - QB_EXT.size())));
|
||||||
|
};
|
||||||
|
|
||||||
|
renameFile(renamingFileIndex, extAdjusted(newFilePath, filePath(renamingFileIndex).endsWith(QB_EXT, Qt::CaseInsensitive)));
|
||||||
|
}
|
||||||
|
|
||||||
|
void BitTorrent::AbstractFileStorage::renameFolder(const QString &oldPath, const QString &newPath)
|
||||||
|
{
|
||||||
|
if (!Utils::Fs::isValidFileSystemName(oldPath, true))
|
||||||
|
throw RuntimeError {tr("The old path is invalid: '%1'.").arg(oldPath)};
|
||||||
|
if (!Utils::Fs::isValidFileSystemName(newPath, true))
|
||||||
|
throw RuntimeError {tr("The new path is invalid: '%1'.").arg(newPath)};
|
||||||
|
|
||||||
|
const auto cleanFolderPath = [](const QString &path) -> QString
|
||||||
|
{
|
||||||
|
const QString uniformPath = Utils::Fs::toUniformPath(path);
|
||||||
|
return (uniformPath.endsWith(QLatin1Char {'/'}) ? uniformPath : uniformPath + QLatin1Char {'/'});
|
||||||
|
};
|
||||||
|
|
||||||
|
const QString oldFolderPath = cleanFolderPath(oldPath);
|
||||||
|
const QString newFolderPath = cleanFolderPath(newPath);
|
||||||
|
if (QDir().isAbsolutePath(newFolderPath))
|
||||||
|
throw RuntimeError {tr("Absolute path isn't allowed: '%1'.").arg(newFolderPath)};
|
||||||
|
|
||||||
|
QVector<int> renamingFileIndexes;
|
||||||
|
renamingFileIndexes.reserve(filesCount());
|
||||||
|
|
||||||
|
for (int i = 0; i < filesCount(); ++i)
|
||||||
|
{
|
||||||
|
const QString path = filePath(i);
|
||||||
|
|
||||||
|
if (path.startsWith(oldFolderPath, CASE_SENSITIVITY))
|
||||||
|
renamingFileIndexes.append(i);
|
||||||
|
|
||||||
|
if (path.startsWith(newFolderPath, CASE_SENSITIVITY))
|
||||||
|
throw RuntimeError {tr("The folder already exists: '%1'.").arg(newFolderPath)};
|
||||||
|
}
|
||||||
|
|
||||||
|
if (renamingFileIndexes.isEmpty())
|
||||||
|
throw RuntimeError {tr("No such folder: '%1'.").arg(oldFolderPath)};
|
||||||
|
|
||||||
|
for (const int index : renamingFileIndexes)
|
||||||
|
{
|
||||||
|
const QString newFilePath = newFolderPath + filePath(index).mid(oldFolderPath.size());
|
||||||
|
renameFile(index, newFilePath);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* Bittorrent Client using Qt and libtorrent.
|
* Bittorrent Client using Qt and libtorrent.
|
||||||
* Copyright (C) 2011 Christian Kandeler
|
* Copyright (C) 2020 Vladimir Golovnev <glassez@yandex.ru>
|
||||||
* Copyright (C) 2011 Christophe Dumez <chris@qbittorrent.org>
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License
|
* modify it under the terms of the GNU General Public License
|
||||||
* as published by the Free Software Foundation; either version 2
|
* as published by the Free Software Foundation; either version 2
|
||||||
@@ -28,35 +28,26 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <QDialog>
|
#include <QtGlobal>
|
||||||
|
#include <QCoreApplication>
|
||||||
|
|
||||||
namespace Ui
|
class QString;
|
||||||
|
|
||||||
|
namespace BitTorrent
|
||||||
{
|
{
|
||||||
class UpDownRatioDialog;
|
class AbstractFileStorage
|
||||||
|
{
|
||||||
|
Q_DECLARE_TR_FUNCTIONS(AbstractFileStorage)
|
||||||
|
|
||||||
|
public:
|
||||||
|
virtual int filesCount() const = 0;
|
||||||
|
virtual QString filePath(int index) const = 0;
|
||||||
|
virtual QString fileName(int index) const = 0;
|
||||||
|
virtual qlonglong fileSize(int index) const = 0;
|
||||||
|
|
||||||
|
virtual void renameFile(int index, const QString &name) = 0;
|
||||||
|
|
||||||
|
void renameFile(const QString &oldPath, const QString &newPath);
|
||||||
|
void renameFolder(const QString &oldPath, const QString &newPath);
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
class UpDownRatioDialog final : public QDialog
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
|
|
||||||
public:
|
|
||||||
UpDownRatioDialog(bool useDefault, qreal initialValue, qreal maxValue,
|
|
||||||
int initialTimeValue, int maxTimeValue,
|
|
||||||
QWidget *parent = nullptr);
|
|
||||||
~UpDownRatioDialog();
|
|
||||||
|
|
||||||
bool useDefault() const;
|
|
||||||
qreal ratio() const;
|
|
||||||
int seedingTime() const;
|
|
||||||
|
|
||||||
public slots:
|
|
||||||
void accept() override;
|
|
||||||
|
|
||||||
private slots:
|
|
||||||
void handleRatioTypeChanged();
|
|
||||||
void enableRatioSpin();
|
|
||||||
void enableTimeSpin();
|
|
||||||
|
|
||||||
private:
|
|
||||||
Ui::UpDownRatioDialog *m_ui;
|
|
||||||
};
|
|
||||||
@@ -28,14 +28,13 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <boost/optional.hpp>
|
#include <optional>
|
||||||
|
|
||||||
#include <QSet>
|
#include <QSet>
|
||||||
#include <QString>
|
#include <QString>
|
||||||
#include <QVector>
|
#include <QVector>
|
||||||
|
|
||||||
#include "base/tristatebool.h"
|
#include "torrent.h"
|
||||||
#include "torrenthandle.h"
|
|
||||||
#include "torrentcontentlayout.h"
|
#include "torrentcontentlayout.h"
|
||||||
|
|
||||||
namespace BitTorrent
|
namespace BitTorrent
|
||||||
@@ -51,15 +50,15 @@ namespace BitTorrent
|
|||||||
bool disableTempPath = false; // e.g. for imported torrents
|
bool disableTempPath = false; // e.g. for imported torrents
|
||||||
bool sequential = false;
|
bool sequential = false;
|
||||||
bool firstLastPiecePriority = false;
|
bool firstLastPiecePriority = false;
|
||||||
TriStateBool addForced;
|
bool addForced = false;
|
||||||
TriStateBool addPaused;
|
std::optional<bool> addPaused;
|
||||||
QVector<DownloadPriority> filePriorities; // used if TorrentInfo is set
|
QVector<DownloadPriority> filePriorities; // used if TorrentInfo is set
|
||||||
bool skipChecking = false;
|
bool skipChecking = false;
|
||||||
boost::optional<BitTorrent::TorrentContentLayout> contentLayout;
|
std::optional<BitTorrent::TorrentContentLayout> contentLayout;
|
||||||
TriStateBool useAutoTMM;
|
std::optional<bool> useAutoTMM;
|
||||||
int uploadLimit = -1;
|
int uploadLimit = -1;
|
||||||
int downloadLimit = -1;
|
int downloadLimit = -1;
|
||||||
int seedingTimeLimit = TorrentHandle::USE_GLOBAL_SEEDING_TIME;
|
int seedingTimeLimit = Torrent::USE_GLOBAL_SEEDING_TIME;
|
||||||
qreal ratioLimit = TorrentHandle::USE_GLOBAL_RATIO;
|
qreal ratioLimit = Torrent::USE_GLOBAL_RATIO;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,5 +30,4 @@
|
|||||||
|
|
||||||
#include <QString>
|
#include <QString>
|
||||||
|
|
||||||
// TODO: Make it inline in C++17
|
inline const QString QB_EXT {QStringLiteral(".!qB")};
|
||||||
extern const QString QB_EXT;
|
|
||||||
|
|||||||
@@ -30,9 +30,6 @@
|
|||||||
|
|
||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
|
|
||||||
template <typename ...>
|
|
||||||
using void_t = void; // replace this with std::void_t in C++17
|
|
||||||
|
|
||||||
template <typename T, typename = void>
|
template <typename T, typename = void>
|
||||||
struct HasUnderlyingType
|
struct HasUnderlyingType
|
||||||
: std::false_type
|
: std::false_type
|
||||||
@@ -40,7 +37,7 @@ struct HasUnderlyingType
|
|||||||
};
|
};
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
struct HasUnderlyingType<T, void_t<typename T::underlying_type>>
|
struct HasUnderlyingType<T, std::void_t<typename T::underlying_type>>
|
||||||
: std::true_type
|
: std::true_type
|
||||||
{
|
{
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -30,14 +30,14 @@
|
|||||||
|
|
||||||
#include <QBitArray>
|
#include <QBitArray>
|
||||||
|
|
||||||
#include "base/bittorrent/torrenthandle.h"
|
#include "base/bittorrent/torrent.h"
|
||||||
#include "base/net/geoipmanager.h"
|
#include "base/net/geoipmanager.h"
|
||||||
#include "base/unicodestrings.h"
|
#include "base/unicodestrings.h"
|
||||||
#include "peeraddress.h"
|
#include "peeraddress.h"
|
||||||
|
|
||||||
using namespace BitTorrent;
|
using namespace BitTorrent;
|
||||||
|
|
||||||
PeerInfo::PeerInfo(const TorrentHandle *torrent, const lt::peer_info &nativeInfo)
|
PeerInfo::PeerInfo(const Torrent *torrent, const lt::peer_info &nativeInfo)
|
||||||
: m_nativeInfo(nativeInfo)
|
: m_nativeInfo(nativeInfo)
|
||||||
{
|
{
|
||||||
calcRelevance(torrent);
|
calcRelevance(torrent);
|
||||||
@@ -226,7 +226,7 @@ QString PeerInfo::connectionType() const
|
|||||||
: QLatin1String {"Web"};
|
: QLatin1String {"Web"};
|
||||||
}
|
}
|
||||||
|
|
||||||
void PeerInfo::calcRelevance(const TorrentHandle *torrent)
|
void PeerInfo::calcRelevance(const Torrent *torrent)
|
||||||
{
|
{
|
||||||
const QBitArray allPieces = torrent->pieces();
|
const QBitArray allPieces = torrent->pieces();
|
||||||
const QBitArray peerPieces = pieces();
|
const QBitArray peerPieces = pieces();
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ class QBitArray;
|
|||||||
|
|
||||||
namespace BitTorrent
|
namespace BitTorrent
|
||||||
{
|
{
|
||||||
class TorrentHandle;
|
class Torrent;
|
||||||
struct PeerAddress;
|
struct PeerAddress;
|
||||||
|
|
||||||
class PeerInfo
|
class PeerInfo
|
||||||
@@ -45,7 +45,7 @@ namespace BitTorrent
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
PeerInfo() = default;
|
PeerInfo() = default;
|
||||||
PeerInfo(const TorrentHandle *torrent, const lt::peer_info &nativeInfo);
|
PeerInfo(const Torrent *torrent, const lt::peer_info &nativeInfo);
|
||||||
|
|
||||||
bool fromDHT() const;
|
bool fromDHT() const;
|
||||||
bool fromPeX() const;
|
bool fromPeX() const;
|
||||||
@@ -92,7 +92,7 @@ namespace BitTorrent
|
|||||||
int downloadingPieceIndex() const;
|
int downloadingPieceIndex() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void calcRelevance(const TorrentHandle *torrent);
|
void calcRelevance(const Torrent *torrent);
|
||||||
void determineFlags();
|
void determineFlags();
|
||||||
|
|
||||||
lt::peer_info m_nativeInfo = {};
|
lt::peer_info m_nativeInfo = {};
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ const QString KEY_ENABLED = QStringLiteral("Network/PortForwardingEnabled");
|
|||||||
|
|
||||||
PortForwarderImpl::PortForwarderImpl(lt::session *provider, QObject *parent)
|
PortForwarderImpl::PortForwarderImpl(lt::session *provider, QObject *parent)
|
||||||
: Net::PortForwarder {parent}
|
: Net::PortForwarder {parent}
|
||||||
, m_active {SettingsStorage::instance()->loadValue(KEY_ENABLED, true).toBool()}
|
, m_active {SettingsStorage::instance()->loadValue(KEY_ENABLED, true)}
|
||||||
, m_provider {provider}
|
, m_provider {provider}
|
||||||
{
|
{
|
||||||
if (m_active)
|
if (m_active)
|
||||||
|
|||||||
@@ -78,13 +78,13 @@
|
|||||||
#include "base/profile.h"
|
#include "base/profile.h"
|
||||||
#include "base/torrentfileguard.h"
|
#include "base/torrentfileguard.h"
|
||||||
#include "base/torrentfilter.h"
|
#include "base/torrentfilter.h"
|
||||||
#include "base/tristatebool.h"
|
|
||||||
#include "base/unicodestrings.h"
|
#include "base/unicodestrings.h"
|
||||||
#include "base/utils/bytearray.h"
|
#include "base/utils/bytearray.h"
|
||||||
#include "base/utils/fs.h"
|
#include "base/utils/fs.h"
|
||||||
#include "base/utils/misc.h"
|
#include "base/utils/misc.h"
|
||||||
#include "base/utils/net.h"
|
#include "base/utils/net.h"
|
||||||
#include "base/utils/random.h"
|
#include "base/utils/random.h"
|
||||||
|
#include "base/version.h"
|
||||||
#include "bandwidthscheduler.h"
|
#include "bandwidthscheduler.h"
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
#include "customstorage.h"
|
#include "customstorage.h"
|
||||||
@@ -96,7 +96,7 @@
|
|||||||
#include "portforwarderimpl.h"
|
#include "portforwarderimpl.h"
|
||||||
#include "resumedatasavingmanager.h"
|
#include "resumedatasavingmanager.h"
|
||||||
#include "statistics.h"
|
#include "statistics.h"
|
||||||
#include "torrenthandleimpl.h"
|
#include "torrentimpl.h"
|
||||||
#include "tracker.h"
|
#include "tracker.h"
|
||||||
#include "trackerentry.h"
|
#include "trackerentry.h"
|
||||||
|
|
||||||
@@ -291,9 +291,8 @@ namespace
|
|||||||
LowerLimited<T> lowerLimited(T limit, T ret) { return LowerLimited<T>(limit, ret); }
|
LowerLimited<T> lowerLimited(T limit, T ret) { return LowerLimited<T>(limit, ret); }
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
std::function<T (const T&)> clampValue(const T lower, const T upper)
|
auto clampValue(const T lower, const T upper)
|
||||||
{
|
{
|
||||||
// TODO: change return type to `auto` when using C++17
|
|
||||||
return [lower, upper](const T value) -> T
|
return [lower, upper](const T value) -> T
|
||||||
{
|
{
|
||||||
if (value < lower)
|
if (value < lower)
|
||||||
@@ -482,7 +481,7 @@ Session::Session(QObject *parent)
|
|||||||
m_storedCategories = map_cast(m_categories);
|
m_storedCategories = map_cast(m_categories);
|
||||||
}
|
}
|
||||||
|
|
||||||
m_tags = List::toSet(m_storedTags.value());
|
m_tags = List::toSet(m_storedTags.get());
|
||||||
|
|
||||||
enqueueRefresh();
|
enqueueRefresh();
|
||||||
updateSeedingLimitTimer();
|
updateSeedingLimitTimer();
|
||||||
@@ -579,7 +578,7 @@ void Session::setTempPathEnabled(const bool enabled)
|
|||||||
if (enabled != isTempPathEnabled())
|
if (enabled != isTempPathEnabled())
|
||||||
{
|
{
|
||||||
m_isTempPathEnabled = enabled;
|
m_isTempPathEnabled = enabled;
|
||||||
for (TorrentHandleImpl *const torrent : asConst(m_torrents))
|
for (TorrentImpl *const torrent : asConst(m_torrents))
|
||||||
torrent->handleTempPathChanged();
|
torrent->handleTempPathChanged();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -596,7 +595,7 @@ void Session::setAppendExtensionEnabled(const bool enabled)
|
|||||||
m_isAppendExtensionEnabled = enabled;
|
m_isAppendExtensionEnabled = enabled;
|
||||||
|
|
||||||
// append or remove .!qB extension for incomplete files
|
// append or remove .!qB extension for incomplete files
|
||||||
for (TorrentHandleImpl *const torrent : asConst(m_torrents))
|
for (TorrentImpl *const torrent : asConst(m_torrents))
|
||||||
torrent->handleAppendExtensionToggled();
|
torrent->handleAppendExtensionToggled();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -749,13 +748,13 @@ bool Session::editCategory(const QString &name, const QString &savePath)
|
|||||||
m_storedCategories = map_cast(m_categories);
|
m_storedCategories = map_cast(m_categories);
|
||||||
if (isDisableAutoTMMWhenCategorySavePathChanged())
|
if (isDisableAutoTMMWhenCategorySavePathChanged())
|
||||||
{
|
{
|
||||||
for (TorrentHandleImpl *const torrent : asConst(m_torrents))
|
for (TorrentImpl *const torrent : asConst(m_torrents))
|
||||||
if (torrent->category() == name)
|
if (torrent->category() == name)
|
||||||
torrent->setAutoTMMEnabled(false);
|
torrent->setAutoTMMEnabled(false);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
for (TorrentHandleImpl *const torrent : asConst(m_torrents))
|
for (TorrentImpl *const torrent : asConst(m_torrents))
|
||||||
if (torrent->category() == name)
|
if (torrent->category() == name)
|
||||||
torrent->handleCategorySavePathChanged();
|
torrent->handleCategorySavePathChanged();
|
||||||
}
|
}
|
||||||
@@ -765,7 +764,7 @@ bool Session::editCategory(const QString &name, const QString &savePath)
|
|||||||
|
|
||||||
bool Session::removeCategory(const QString &name)
|
bool Session::removeCategory(const QString &name)
|
||||||
{
|
{
|
||||||
for (TorrentHandleImpl *const torrent : asConst(m_torrents))
|
for (TorrentImpl *const torrent : asConst(m_torrents))
|
||||||
if (torrent->belongsToCategory(name))
|
if (torrent->belongsToCategory(name))
|
||||||
torrent->setCategory("");
|
torrent->setCategory("");
|
||||||
|
|
||||||
@@ -859,7 +858,7 @@ bool Session::removeTag(const QString &tag)
|
|||||||
{
|
{
|
||||||
if (m_tags.remove(tag))
|
if (m_tags.remove(tag))
|
||||||
{
|
{
|
||||||
for (TorrentHandleImpl *const torrent : asConst(m_torrents))
|
for (TorrentImpl *const torrent : asConst(m_torrents))
|
||||||
torrent->removeTag(tag);
|
torrent->removeTag(tag);
|
||||||
m_storedTags = m_tags.values();
|
m_storedTags = m_tags.values();
|
||||||
emit tagRemoved(tag);
|
emit tagRemoved(tag);
|
||||||
@@ -1130,7 +1129,7 @@ void Session::initializeNativeSession()
|
|||||||
void Session::processBannedIPs(lt::ip_filter &filter)
|
void Session::processBannedIPs(lt::ip_filter &filter)
|
||||||
{
|
{
|
||||||
// First, import current filter
|
// First, import current filter
|
||||||
for (const QString &ip : asConst(m_bannedIPs.value()))
|
for (const QString &ip : asConst(m_bannedIPs.get()))
|
||||||
{
|
{
|
||||||
lt::error_code ec;
|
lt::error_code ec;
|
||||||
const lt::address addr = lt::make_address(ip.toLatin1().constData(), ec);
|
const lt::address addr = lt::make_address(ip.toLatin1().constData(), ec);
|
||||||
@@ -1619,16 +1618,16 @@ void Session::processShareLimits()
|
|||||||
|
|
||||||
// We shouldn't iterate over `m_torrents` in the loop below
|
// We shouldn't iterate over `m_torrents` in the loop below
|
||||||
// since `deleteTorrent()` modifies it indirectly
|
// since `deleteTorrent()` modifies it indirectly
|
||||||
const QHash<InfoHash, TorrentHandleImpl *> torrents {m_torrents};
|
const QHash<InfoHash, TorrentImpl *> torrents {m_torrents};
|
||||||
for (TorrentHandleImpl *const torrent : torrents)
|
for (TorrentImpl *const torrent : torrents)
|
||||||
{
|
{
|
||||||
if (torrent->isSeed() && !torrent->isForced())
|
if (torrent->isSeed() && !torrent->isForced())
|
||||||
{
|
{
|
||||||
if (torrent->ratioLimit() != TorrentHandle::NO_RATIO_LIMIT)
|
if (torrent->ratioLimit() != Torrent::NO_RATIO_LIMIT)
|
||||||
{
|
{
|
||||||
const qreal ratio = torrent->realRatio();
|
const qreal ratio = torrent->realRatio();
|
||||||
qreal ratioLimit = torrent->ratioLimit();
|
qreal ratioLimit = torrent->ratioLimit();
|
||||||
if (ratioLimit == TorrentHandle::USE_GLOBAL_RATIO)
|
if (ratioLimit == Torrent::USE_GLOBAL_RATIO)
|
||||||
// If Global Max Ratio is really set...
|
// If Global Max Ratio is really set...
|
||||||
ratioLimit = globalMaxRatio();
|
ratioLimit = globalMaxRatio();
|
||||||
|
|
||||||
@@ -1636,7 +1635,7 @@ void Session::processShareLimits()
|
|||||||
{
|
{
|
||||||
qDebug("Ratio: %f (limit: %f)", ratio, ratioLimit);
|
qDebug("Ratio: %f (limit: %f)", ratio, ratioLimit);
|
||||||
|
|
||||||
if ((ratio <= TorrentHandle::MAX_RATIO) && (ratio >= ratioLimit))
|
if ((ratio <= Torrent::MAX_RATIO) && (ratio >= ratioLimit))
|
||||||
{
|
{
|
||||||
if (m_maxRatioAction == Remove)
|
if (m_maxRatioAction == Remove)
|
||||||
{
|
{
|
||||||
@@ -1646,7 +1645,7 @@ void Session::processShareLimits()
|
|||||||
else if (m_maxRatioAction == DeleteFiles)
|
else if (m_maxRatioAction == DeleteFiles)
|
||||||
{
|
{
|
||||||
LogMsg(tr("'%1' reached the maximum ratio you set. Removed torrent and its files.").arg(torrent->name()));
|
LogMsg(tr("'%1' reached the maximum ratio you set. Removed torrent and its files.").arg(torrent->name()));
|
||||||
deleteTorrent(torrent->hash(), TorrentAndFiles);
|
deleteTorrent(torrent->hash(), DeleteTorrentAndFiles);
|
||||||
}
|
}
|
||||||
else if ((m_maxRatioAction == Pause) && !torrent->isPaused())
|
else if ((m_maxRatioAction == Pause) && !torrent->isPaused())
|
||||||
{
|
{
|
||||||
@@ -1663,11 +1662,11 @@ void Session::processShareLimits()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (torrent->seedingTimeLimit() != TorrentHandle::NO_SEEDING_TIME_LIMIT)
|
if (torrent->seedingTimeLimit() != Torrent::NO_SEEDING_TIME_LIMIT)
|
||||||
{
|
{
|
||||||
const qlonglong seedingTimeInMinutes = torrent->seedingTime() / 60;
|
const qlonglong seedingTimeInMinutes = torrent->seedingTime() / 60;
|
||||||
int seedingTimeLimit = torrent->seedingTimeLimit();
|
int seedingTimeLimit = torrent->seedingTimeLimit();
|
||||||
if (seedingTimeLimit == TorrentHandle::USE_GLOBAL_SEEDING_TIME)
|
if (seedingTimeLimit == Torrent::USE_GLOBAL_SEEDING_TIME)
|
||||||
{
|
{
|
||||||
// If Global Seeding Time Limit is really set...
|
// If Global Seeding Time Limit is really set...
|
||||||
seedingTimeLimit = globalMaxSeedingMinutes();
|
seedingTimeLimit = globalMaxSeedingMinutes();
|
||||||
@@ -1675,7 +1674,7 @@ void Session::processShareLimits()
|
|||||||
|
|
||||||
if (seedingTimeLimit >= 0)
|
if (seedingTimeLimit >= 0)
|
||||||
{
|
{
|
||||||
if ((seedingTimeInMinutes <= TorrentHandle::MAX_SEEDING_TIME) && (seedingTimeInMinutes >= seedingTimeLimit))
|
if ((seedingTimeInMinutes <= Torrent::MAX_SEEDING_TIME) && (seedingTimeInMinutes >= seedingTimeLimit))
|
||||||
{
|
{
|
||||||
if (m_maxRatioAction == Remove)
|
if (m_maxRatioAction == Remove)
|
||||||
{
|
{
|
||||||
@@ -1685,7 +1684,7 @@ void Session::processShareLimits()
|
|||||||
else if (m_maxRatioAction == DeleteFiles)
|
else if (m_maxRatioAction == DeleteFiles)
|
||||||
{
|
{
|
||||||
LogMsg(tr("'%1' reached the maximum seeding time you set. Removed torrent and its files.").arg(torrent->name()));
|
LogMsg(tr("'%1' reached the maximum seeding time you set. Removed torrent and its files.").arg(torrent->name()));
|
||||||
deleteTorrent(torrent->hash(), TorrentAndFiles);
|
deleteTorrent(torrent->hash(), DeleteTorrentAndFiles);
|
||||||
}
|
}
|
||||||
else if ((m_maxRatioAction == Pause) && !torrent->isPaused())
|
else if ((m_maxRatioAction == Pause) && !torrent->isPaused())
|
||||||
{
|
{
|
||||||
@@ -1724,7 +1723,7 @@ void Session::handleDownloadFinished(const Net::DownloadResult &result)
|
|||||||
|
|
||||||
void Session::fileSearchFinished(const InfoHash &id, const QString &savePath, const QStringList &fileNames)
|
void Session::fileSearchFinished(const InfoHash &id, const QString &savePath, const QStringList &fileNames)
|
||||||
{
|
{
|
||||||
TorrentHandleImpl *torrent = m_torrents.value(id);
|
TorrentImpl *torrent = m_torrents.value(id);
|
||||||
if (torrent)
|
if (torrent)
|
||||||
{
|
{
|
||||||
torrent->fileSearchFinished(savePath, fileNames);
|
torrent->fileSearchFinished(savePath, fileNames);
|
||||||
@@ -1748,14 +1747,14 @@ void Session::fileSearchFinished(const InfoHash &id, const QString &savePath, co
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Return the torrent handle, given its hash
|
// Return the torrent handle, given its hash
|
||||||
TorrentHandle *Session::findTorrent(const InfoHash &hash) const
|
Torrent *Session::findTorrent(const InfoHash &hash) const
|
||||||
{
|
{
|
||||||
return m_torrents.value(hash);
|
return m_torrents.value(hash);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Session::hasActiveTorrents() const
|
bool Session::hasActiveTorrents() const
|
||||||
{
|
{
|
||||||
return std::any_of(m_torrents.begin(), m_torrents.end(), [](TorrentHandleImpl *torrent)
|
return std::any_of(m_torrents.begin(), m_torrents.end(), [](TorrentImpl *torrent)
|
||||||
{
|
{
|
||||||
return TorrentFilter::ActiveTorrent.match(torrent);
|
return TorrentFilter::ActiveTorrent.match(torrent);
|
||||||
});
|
});
|
||||||
@@ -1763,7 +1762,7 @@ bool Session::hasActiveTorrents() const
|
|||||||
|
|
||||||
bool Session::hasUnfinishedTorrents() const
|
bool Session::hasUnfinishedTorrents() const
|
||||||
{
|
{
|
||||||
return std::any_of(m_torrents.begin(), m_torrents.end(), [](const TorrentHandleImpl *torrent)
|
return std::any_of(m_torrents.begin(), m_torrents.end(), [](const TorrentImpl *torrent)
|
||||||
{
|
{
|
||||||
return (!torrent->isSeed() && !torrent->isPaused());
|
return (!torrent->isSeed() && !torrent->isPaused());
|
||||||
});
|
});
|
||||||
@@ -1771,7 +1770,7 @@ bool Session::hasUnfinishedTorrents() const
|
|||||||
|
|
||||||
bool Session::hasRunningSeed() const
|
bool Session::hasRunningSeed() const
|
||||||
{
|
{
|
||||||
return std::any_of(m_torrents.begin(), m_torrents.end(), [](const TorrentHandleImpl *torrent)
|
return std::any_of(m_torrents.begin(), m_torrents.end(), [](const TorrentImpl *torrent)
|
||||||
{
|
{
|
||||||
return (torrent->isSeed() && !torrent->isPaused());
|
return (torrent->isSeed() && !torrent->isPaused());
|
||||||
});
|
});
|
||||||
@@ -1800,14 +1799,14 @@ void Session::banIP(const QString &ip)
|
|||||||
// and from the disk, if the corresponding deleteOption is chosen
|
// and from the disk, if the corresponding deleteOption is chosen
|
||||||
bool Session::deleteTorrent(const InfoHash &hash, const DeleteOption deleteOption)
|
bool Session::deleteTorrent(const InfoHash &hash, const DeleteOption deleteOption)
|
||||||
{
|
{
|
||||||
TorrentHandleImpl *const torrent = m_torrents.take(hash);
|
TorrentImpl *const torrent = m_torrents.take(hash);
|
||||||
if (!torrent) return false;
|
if (!torrent) return false;
|
||||||
|
|
||||||
qDebug("Deleting torrent with hash: %s", qUtf8Printable(torrent->hash()));
|
qDebug("Deleting torrent with hash: %s", qUtf8Printable(torrent->hash()));
|
||||||
emit torrentAboutToBeRemoved(torrent);
|
emit torrentAboutToBeRemoved(torrent);
|
||||||
|
|
||||||
// Remove it from session
|
// Remove it from session
|
||||||
if (deleteOption == Torrent)
|
if (deleteOption == DeleteTorrent)
|
||||||
{
|
{
|
||||||
m_removingTorrents[torrent->hash()] = {torrent->name(), "", deleteOption};
|
m_removingTorrents[torrent->hash()] = {torrent->name(), "", deleteOption};
|
||||||
|
|
||||||
@@ -1888,7 +1887,7 @@ bool Session::cancelDownloadMetadata(const InfoHash &hash)
|
|||||||
|
|
||||||
void Session::increaseTorrentsQueuePos(const QVector<InfoHash> &hashes)
|
void Session::increaseTorrentsQueuePos(const QVector<InfoHash> &hashes)
|
||||||
{
|
{
|
||||||
using ElementType = std::pair<int, TorrentHandleImpl *>;
|
using ElementType = std::pair<int, TorrentImpl *>;
|
||||||
std::priority_queue<ElementType
|
std::priority_queue<ElementType
|
||||||
, std::vector<ElementType>
|
, std::vector<ElementType>
|
||||||
, std::greater<ElementType>> torrentQueue;
|
, std::greater<ElementType>> torrentQueue;
|
||||||
@@ -1896,7 +1895,7 @@ void Session::increaseTorrentsQueuePos(const QVector<InfoHash> &hashes)
|
|||||||
// Sort torrents by queue position
|
// Sort torrents by queue position
|
||||||
for (const InfoHash &infoHash : hashes)
|
for (const InfoHash &infoHash : hashes)
|
||||||
{
|
{
|
||||||
TorrentHandleImpl *const torrent = m_torrents.value(infoHash);
|
TorrentImpl *const torrent = m_torrents.value(infoHash);
|
||||||
if (torrent && !torrent->isSeed())
|
if (torrent && !torrent->isSeed())
|
||||||
torrentQueue.emplace(torrent->queuePosition(), torrent);
|
torrentQueue.emplace(torrent->queuePosition(), torrent);
|
||||||
}
|
}
|
||||||
@@ -1904,7 +1903,7 @@ void Session::increaseTorrentsQueuePos(const QVector<InfoHash> &hashes)
|
|||||||
// Increase torrents queue position (starting with the one in the highest queue position)
|
// Increase torrents queue position (starting with the one in the highest queue position)
|
||||||
while (!torrentQueue.empty())
|
while (!torrentQueue.empty())
|
||||||
{
|
{
|
||||||
const TorrentHandleImpl *torrent = torrentQueue.top().second;
|
const TorrentImpl *torrent = torrentQueue.top().second;
|
||||||
torrentQueuePositionUp(torrent->nativeHandle());
|
torrentQueuePositionUp(torrent->nativeHandle());
|
||||||
torrentQueue.pop();
|
torrentQueue.pop();
|
||||||
}
|
}
|
||||||
@@ -1914,13 +1913,13 @@ void Session::increaseTorrentsQueuePos(const QVector<InfoHash> &hashes)
|
|||||||
|
|
||||||
void Session::decreaseTorrentsQueuePos(const QVector<InfoHash> &hashes)
|
void Session::decreaseTorrentsQueuePos(const QVector<InfoHash> &hashes)
|
||||||
{
|
{
|
||||||
using ElementType = std::pair<int, TorrentHandleImpl *>;
|
using ElementType = std::pair<int, TorrentImpl *>;
|
||||||
std::priority_queue<ElementType> torrentQueue;
|
std::priority_queue<ElementType> torrentQueue;
|
||||||
|
|
||||||
// Sort torrents by queue position
|
// Sort torrents by queue position
|
||||||
for (const InfoHash &infoHash : hashes)
|
for (const InfoHash &infoHash : hashes)
|
||||||
{
|
{
|
||||||
TorrentHandleImpl *const torrent = m_torrents.value(infoHash);
|
TorrentImpl *const torrent = m_torrents.value(infoHash);
|
||||||
if (torrent && !torrent->isSeed())
|
if (torrent && !torrent->isSeed())
|
||||||
torrentQueue.emplace(torrent->queuePosition(), torrent);
|
torrentQueue.emplace(torrent->queuePosition(), torrent);
|
||||||
}
|
}
|
||||||
@@ -1928,7 +1927,7 @@ void Session::decreaseTorrentsQueuePos(const QVector<InfoHash> &hashes)
|
|||||||
// Decrease torrents queue position (starting with the one in the lowest queue position)
|
// Decrease torrents queue position (starting with the one in the lowest queue position)
|
||||||
while (!torrentQueue.empty())
|
while (!torrentQueue.empty())
|
||||||
{
|
{
|
||||||
const TorrentHandleImpl *torrent = torrentQueue.top().second;
|
const TorrentImpl *torrent = torrentQueue.top().second;
|
||||||
torrentQueuePositionDown(torrent->nativeHandle());
|
torrentQueuePositionDown(torrent->nativeHandle());
|
||||||
torrentQueue.pop();
|
torrentQueue.pop();
|
||||||
}
|
}
|
||||||
@@ -1941,13 +1940,13 @@ void Session::decreaseTorrentsQueuePos(const QVector<InfoHash> &hashes)
|
|||||||
|
|
||||||
void Session::topTorrentsQueuePos(const QVector<InfoHash> &hashes)
|
void Session::topTorrentsQueuePos(const QVector<InfoHash> &hashes)
|
||||||
{
|
{
|
||||||
using ElementType = std::pair<int, TorrentHandleImpl *>;
|
using ElementType = std::pair<int, TorrentImpl *>;
|
||||||
std::priority_queue<ElementType> torrentQueue;
|
std::priority_queue<ElementType> torrentQueue;
|
||||||
|
|
||||||
// Sort torrents by queue position
|
// Sort torrents by queue position
|
||||||
for (const InfoHash &infoHash : hashes)
|
for (const InfoHash &infoHash : hashes)
|
||||||
{
|
{
|
||||||
TorrentHandleImpl *const torrent = m_torrents.value(infoHash);
|
TorrentImpl *const torrent = m_torrents.value(infoHash);
|
||||||
if (torrent && !torrent->isSeed())
|
if (torrent && !torrent->isSeed())
|
||||||
torrentQueue.emplace(torrent->queuePosition(), torrent);
|
torrentQueue.emplace(torrent->queuePosition(), torrent);
|
||||||
}
|
}
|
||||||
@@ -1955,7 +1954,7 @@ void Session::topTorrentsQueuePos(const QVector<InfoHash> &hashes)
|
|||||||
// Top torrents queue position (starting with the one in the lowest queue position)
|
// Top torrents queue position (starting with the one in the lowest queue position)
|
||||||
while (!torrentQueue.empty())
|
while (!torrentQueue.empty())
|
||||||
{
|
{
|
||||||
const TorrentHandleImpl *torrent = torrentQueue.top().second;
|
const TorrentImpl *torrent = torrentQueue.top().second;
|
||||||
torrentQueuePositionTop(torrent->nativeHandle());
|
torrentQueuePositionTop(torrent->nativeHandle());
|
||||||
torrentQueue.pop();
|
torrentQueue.pop();
|
||||||
}
|
}
|
||||||
@@ -1965,7 +1964,7 @@ void Session::topTorrentsQueuePos(const QVector<InfoHash> &hashes)
|
|||||||
|
|
||||||
void Session::bottomTorrentsQueuePos(const QVector<InfoHash> &hashes)
|
void Session::bottomTorrentsQueuePos(const QVector<InfoHash> &hashes)
|
||||||
{
|
{
|
||||||
using ElementType = std::pair<int, TorrentHandleImpl *>;
|
using ElementType = std::pair<int, TorrentImpl *>;
|
||||||
std::priority_queue<ElementType
|
std::priority_queue<ElementType
|
||||||
, std::vector<ElementType>
|
, std::vector<ElementType>
|
||||||
, std::greater<ElementType>> torrentQueue;
|
, std::greater<ElementType>> torrentQueue;
|
||||||
@@ -1973,7 +1972,7 @@ void Session::bottomTorrentsQueuePos(const QVector<InfoHash> &hashes)
|
|||||||
// Sort torrents by queue position
|
// Sort torrents by queue position
|
||||||
for (const InfoHash &infoHash : hashes)
|
for (const InfoHash &infoHash : hashes)
|
||||||
{
|
{
|
||||||
TorrentHandleImpl *const torrent = m_torrents.value(infoHash);
|
TorrentImpl *const torrent = m_torrents.value(infoHash);
|
||||||
if (torrent && !torrent->isSeed())
|
if (torrent && !torrent->isSeed())
|
||||||
torrentQueue.emplace(torrent->queuePosition(), torrent);
|
torrentQueue.emplace(torrent->queuePosition(), torrent);
|
||||||
}
|
}
|
||||||
@@ -1981,7 +1980,7 @@ void Session::bottomTorrentsQueuePos(const QVector<InfoHash> &hashes)
|
|||||||
// Bottom torrents queue position (starting with the one in the highest queue position)
|
// Bottom torrents queue position (starting with the one in the highest queue position)
|
||||||
while (!torrentQueue.empty())
|
while (!torrentQueue.empty())
|
||||||
{
|
{
|
||||||
const TorrentHandleImpl *torrent = torrentQueue.top().second;
|
const TorrentImpl *torrent = torrentQueue.top().second;
|
||||||
torrentQueuePositionBottom(torrent->nativeHandle());
|
torrentQueuePositionBottom(torrent->nativeHandle());
|
||||||
torrentQueue.pop();
|
torrentQueue.pop();
|
||||||
}
|
}
|
||||||
@@ -1992,17 +1991,17 @@ void Session::bottomTorrentsQueuePos(const QVector<InfoHash> &hashes)
|
|||||||
saveTorrentsQueue();
|
saveTorrentsQueue();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Session::handleTorrentSaveResumeDataRequested(const TorrentHandleImpl *torrent)
|
void Session::handleTorrentSaveResumeDataRequested(const TorrentImpl *torrent)
|
||||||
{
|
{
|
||||||
qDebug("Saving resume data is requested for torrent '%s'...", qUtf8Printable(torrent->name()));
|
qDebug("Saving resume data is requested for torrent '%s'...", qUtf8Printable(torrent->name()));
|
||||||
++m_numResumeData;
|
++m_numResumeData;
|
||||||
}
|
}
|
||||||
|
|
||||||
QVector<TorrentHandle *> Session::torrents() const
|
QVector<Torrent *> Session::torrents() const
|
||||||
{
|
{
|
||||||
QVector<TorrentHandle *> result;
|
QVector<Torrent *> result;
|
||||||
result.reserve(m_torrents.size());
|
result.reserve(m_torrents.size());
|
||||||
for (TorrentHandleImpl *torrent : asConst(m_torrents))
|
for (TorrentImpl *torrent : asConst(m_torrents))
|
||||||
result << torrent;
|
result << torrent;
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
@@ -2040,14 +2039,14 @@ bool Session::addTorrent(const MagnetUri &magnetUri, const AddTorrentParams &par
|
|||||||
{
|
{
|
||||||
if (!magnetUri.isValid()) return false;
|
if (!magnetUri.isValid()) return false;
|
||||||
|
|
||||||
return addTorrent_impl(params, magnetUri);
|
return addTorrent_impl(magnetUri, params);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Session::addTorrent(const TorrentInfo &torrentInfo, const AddTorrentParams ¶ms)
|
bool Session::addTorrent(const TorrentInfo &torrentInfo, const AddTorrentParams ¶ms)
|
||||||
{
|
{
|
||||||
if (!torrentInfo.isValid()) return false;
|
if (!torrentInfo.isValid()) return false;
|
||||||
|
|
||||||
return addTorrent_impl(params, MagnetUri(), torrentInfo);
|
return addTorrent_impl(torrentInfo, params);
|
||||||
}
|
}
|
||||||
|
|
||||||
LoadTorrentParams Session::initLoadTorrentParams(const AddTorrentParams &addTorrentParams)
|
LoadTorrentParams Session::initLoadTorrentParams(const AddTorrentParams &addTorrentParams)
|
||||||
@@ -2058,19 +2057,13 @@ LoadTorrentParams Session::initLoadTorrentParams(const AddTorrentParams &addTorr
|
|||||||
loadTorrentParams.tags = addTorrentParams.tags;
|
loadTorrentParams.tags = addTorrentParams.tags;
|
||||||
loadTorrentParams.firstLastPiecePriority = addTorrentParams.firstLastPiecePriority;
|
loadTorrentParams.firstLastPiecePriority = addTorrentParams.firstLastPiecePriority;
|
||||||
loadTorrentParams.hasSeedStatus = addTorrentParams.skipChecking; // do not react on 'torrent_finished_alert' when skipping
|
loadTorrentParams.hasSeedStatus = addTorrentParams.skipChecking; // do not react on 'torrent_finished_alert' when skipping
|
||||||
loadTorrentParams.contentLayout = (addTorrentParams.contentLayout
|
loadTorrentParams.contentLayout = addTorrentParams.contentLayout.value_or(torrentContentLayout());
|
||||||
? *addTorrentParams.contentLayout
|
loadTorrentParams.forced = addTorrentParams.addForced;
|
||||||
: torrentContentLayout());
|
loadTorrentParams.paused = addTorrentParams.addPaused.value_or(isAddTorrentPaused());
|
||||||
loadTorrentParams.forced = (addTorrentParams.addForced == TriStateBool::True);
|
|
||||||
loadTorrentParams.paused = ((addTorrentParams.addPaused == TriStateBool::Undefined)
|
|
||||||
? isAddTorrentPaused()
|
|
||||||
: (addTorrentParams.addPaused == TriStateBool::True));
|
|
||||||
loadTorrentParams.ratioLimit = addTorrentParams.ratioLimit;
|
loadTorrentParams.ratioLimit = addTorrentParams.ratioLimit;
|
||||||
loadTorrentParams.seedingTimeLimit = addTorrentParams.seedingTimeLimit;
|
loadTorrentParams.seedingTimeLimit = addTorrentParams.seedingTimeLimit;
|
||||||
|
|
||||||
const bool useAutoTMM = ((addTorrentParams.useAutoTMM == TriStateBool::Undefined)
|
const bool useAutoTMM = addTorrentParams.useAutoTMM.value_or(!isAutoTMMDisabledByDefault());
|
||||||
? !isAutoTMMDisabledByDefault()
|
|
||||||
: (addTorrentParams.useAutoTMM == TriStateBool::True));
|
|
||||||
if (useAutoTMM)
|
if (useAutoTMM)
|
||||||
loadTorrentParams.savePath = "";
|
loadTorrentParams.savePath = "";
|
||||||
else if (addTorrentParams.savePath.trimmed().isEmpty())
|
else if (addTorrentParams.savePath.trimmed().isEmpty())
|
||||||
@@ -2088,9 +2081,11 @@ LoadTorrentParams Session::initLoadTorrentParams(const AddTorrentParams &addTorr
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Add a torrent to the BitTorrent session
|
// Add a torrent to the BitTorrent session
|
||||||
bool Session::addTorrent_impl(const AddTorrentParams &addTorrentParams, const MagnetUri &magnetUri, TorrentInfo metadata)
|
bool Session::addTorrent_impl(const std::variant<MagnetUri, TorrentInfo> &source, const AddTorrentParams &addTorrentParams)
|
||||||
{
|
{
|
||||||
const bool hasMetadata = metadata.isValid();
|
const bool hasMetadata = std::holds_alternative<TorrentInfo>(source);
|
||||||
|
TorrentInfo metadata = (hasMetadata ? std::get<TorrentInfo>(source) : TorrentInfo {});
|
||||||
|
const MagnetUri &magnetUri = (hasMetadata ? MagnetUri {} : std::get<MagnetUri>(source));
|
||||||
const InfoHash hash = (hasMetadata ? metadata.hash() : magnetUri.hash());
|
const InfoHash hash = (hasMetadata ? metadata.hash() : magnetUri.hash());
|
||||||
|
|
||||||
// It looks illogical that we don't just use an existing handle,
|
// It looks illogical that we don't just use an existing handle,
|
||||||
@@ -2104,7 +2099,7 @@ bool Session::addTorrent_impl(const AddTorrentParams &addTorrentParams, const Ma
|
|||||||
if (m_loadingTorrents.contains(hash))
|
if (m_loadingTorrents.contains(hash))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
TorrentHandleImpl *const torrent = m_torrents.value(hash);
|
TorrentImpl *const torrent = m_torrents.value(hash);
|
||||||
if (torrent)
|
if (torrent)
|
||||||
{ // a duplicate torrent is added
|
{ // a duplicate torrent is added
|
||||||
if (torrent->isPrivate() || (hasMetadata && metadata.isPrivate()))
|
if (torrent->isPrivate() || (hasMetadata && metadata.isPrivate()))
|
||||||
@@ -2298,7 +2293,7 @@ bool Session::downloadMetadata(const MagnetUri &magnetUri)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Session::exportTorrentFile(const TorrentHandle *torrent, TorrentExportFolder folder)
|
void Session::exportTorrentFile(const Torrent *torrent, TorrentExportFolder folder)
|
||||||
{
|
{
|
||||||
Q_ASSERT(((folder == TorrentExportFolder::Regular) && !torrentExportDirectory().isEmpty()) ||
|
Q_ASSERT(((folder == TorrentExportFolder::Regular) && !torrentExportDirectory().isEmpty()) ||
|
||||||
((folder == TorrentExportFolder::Finished) && !finishedTorrentExportDirectory().isEmpty()));
|
((folder == TorrentExportFolder::Finished) && !finishedTorrentExportDirectory().isEmpty()));
|
||||||
@@ -2326,7 +2321,7 @@ void Session::exportTorrentFile(const TorrentHandle *torrent, TorrentExportFolde
|
|||||||
|
|
||||||
void Session::generateResumeData()
|
void Session::generateResumeData()
|
||||||
{
|
{
|
||||||
for (TorrentHandleImpl *const torrent : asConst(m_torrents))
|
for (TorrentImpl *const torrent : asConst(m_torrents))
|
||||||
{
|
{
|
||||||
if (!torrent->isValid()) continue;
|
if (!torrent->isValid()) continue;
|
||||||
|
|
||||||
@@ -2372,7 +2367,7 @@ void Session::saveTorrentsQueue()
|
|||||||
{
|
{
|
||||||
// store hash in textual representation
|
// store hash in textual representation
|
||||||
QMap<int, QString> queue; // Use QMap since it should be ordered by key
|
QMap<int, QString> queue; // Use QMap since it should be ordered by key
|
||||||
for (const TorrentHandleImpl *torrent : asConst(m_torrents))
|
for (const TorrentImpl *torrent : asConst(m_torrents))
|
||||||
{
|
{
|
||||||
// We require actual (non-cached) queue position here!
|
// We require actual (non-cached) queue position here!
|
||||||
const int queuePos = static_cast<LTUnderlyingType<lt::queue_position_t>>(torrent->nativeHandle().queue_position());
|
const int queuePos = static_cast<LTUnderlyingType<lt::queue_position_t>>(torrent->nativeHandle().queue_position());
|
||||||
@@ -2414,10 +2409,10 @@ void Session::setDefaultSavePath(QString path)
|
|||||||
m_defaultSavePath = path;
|
m_defaultSavePath = path;
|
||||||
|
|
||||||
if (isDisableAutoTMMWhenDefaultSavePathChanged())
|
if (isDisableAutoTMMWhenDefaultSavePathChanged())
|
||||||
for (TorrentHandleImpl *const torrent : asConst(m_torrents))
|
for (TorrentImpl *const torrent : asConst(m_torrents))
|
||||||
torrent->setAutoTMMEnabled(false);
|
torrent->setAutoTMMEnabled(false);
|
||||||
else
|
else
|
||||||
for (TorrentHandleImpl *const torrent : asConst(m_torrents))
|
for (TorrentImpl *const torrent : asConst(m_torrents))
|
||||||
torrent->handleCategorySavePathChanged();
|
torrent->handleCategorySavePathChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2428,7 +2423,7 @@ void Session::setTempPath(QString path)
|
|||||||
|
|
||||||
m_tempPath = path;
|
m_tempPath = path;
|
||||||
|
|
||||||
for (TorrentHandleImpl *const torrent : asConst(m_torrents))
|
for (TorrentImpl *const torrent : asConst(m_torrents))
|
||||||
torrent->handleTempPathChanged();
|
torrent->handleTempPathChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3142,7 +3137,7 @@ void Session::setPeerTurnoverInterval(const int val)
|
|||||||
|
|
||||||
int Session::asyncIOThreads() const
|
int Session::asyncIOThreads() const
|
||||||
{
|
{
|
||||||
return qBound(1, m_asyncIOThreads.value(), 1024);
|
return qBound(1, m_asyncIOThreads.get(), 1024);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Session::setAsyncIOThreads(const int num)
|
void Session::setAsyncIOThreads(const int num)
|
||||||
@@ -3156,7 +3151,7 @@ void Session::setAsyncIOThreads(const int num)
|
|||||||
|
|
||||||
int Session::hashingThreads() const
|
int Session::hashingThreads() const
|
||||||
{
|
{
|
||||||
return qBound(1, m_hashingThreads.value(), 1024);
|
return qBound(1, m_hashingThreads.get(), 1024);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Session::setHashingThreads(const int num)
|
void Session::setHashingThreads(const int num)
|
||||||
@@ -3184,7 +3179,7 @@ void Session::setFilePoolSize(const int size)
|
|||||||
|
|
||||||
int Session::checkingMemUsage() const
|
int Session::checkingMemUsage() const
|
||||||
{
|
{
|
||||||
return qMax(1, m_checkingMemUsage.value());
|
return qMax(1, m_checkingMemUsage.get());
|
||||||
}
|
}
|
||||||
|
|
||||||
void Session::setCheckingMemUsage(int size)
|
void Session::setCheckingMemUsage(int size)
|
||||||
@@ -3201,11 +3196,11 @@ void Session::setCheckingMemUsage(int size)
|
|||||||
int Session::diskCacheSize() const
|
int Session::diskCacheSize() const
|
||||||
{
|
{
|
||||||
#ifdef QBT_APP_64BIT
|
#ifdef QBT_APP_64BIT
|
||||||
return qMin(m_diskCacheSize.value(), 33554431); // 32768GiB
|
return qMin(m_diskCacheSize.get(), 33554431); // 32768GiB
|
||||||
#else
|
#else
|
||||||
// When build as 32bit binary, set the maximum at less than 2GB to prevent crashes
|
// When build as 32bit binary, set the maximum at less than 2GB to prevent crashes
|
||||||
// allocate 1536MiB and leave 512MiB to the rest of program data in RAM
|
// allocate 1536MiB and leave 512MiB to the rest of program data in RAM
|
||||||
return qMin(m_diskCacheSize.value(), 1536);
|
return qMin(m_diskCacheSize.get(), 1536);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3737,7 +3732,7 @@ bool Session::isListening() const
|
|||||||
|
|
||||||
MaxRatioAction Session::maxRatioAction() const
|
MaxRatioAction Session::maxRatioAction() const
|
||||||
{
|
{
|
||||||
return static_cast<MaxRatioAction>(m_maxRatioAction.value());
|
return static_cast<MaxRatioAction>(m_maxRatioAction.get());
|
||||||
}
|
}
|
||||||
|
|
||||||
void Session::setMaxRatioAction(const MaxRatioAction act)
|
void Session::setMaxRatioAction(const MaxRatioAction act)
|
||||||
@@ -3756,8 +3751,8 @@ bool Session::isKnownTorrent(const InfoHash &hash) const
|
|||||||
|
|
||||||
void Session::updateSeedingLimitTimer()
|
void Session::updateSeedingLimitTimer()
|
||||||
{
|
{
|
||||||
if ((globalMaxRatio() == TorrentHandle::NO_RATIO_LIMIT) && !hasPerTorrentRatioLimit()
|
if ((globalMaxRatio() == Torrent::NO_RATIO_LIMIT) && !hasPerTorrentRatioLimit()
|
||||||
&& (globalMaxSeedingMinutes() == TorrentHandle::NO_SEEDING_TIME_LIMIT) && !hasPerTorrentSeedingTimeLimit())
|
&& (globalMaxSeedingMinutes() == Torrent::NO_SEEDING_TIME_LIMIT) && !hasPerTorrentSeedingTimeLimit())
|
||||||
{
|
{
|
||||||
if (m_seedingLimitTimer->isActive())
|
if (m_seedingLimitTimer->isActive())
|
||||||
m_seedingLimitTimer->stop();
|
m_seedingLimitTimer->stop();
|
||||||
@@ -3768,48 +3763,48 @@ void Session::updateSeedingLimitTimer()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Session::handleTorrentShareLimitChanged(TorrentHandleImpl *const torrent)
|
void Session::handleTorrentShareLimitChanged(TorrentImpl *const torrent)
|
||||||
{
|
{
|
||||||
torrent->saveResumeData();
|
torrent->saveResumeData();
|
||||||
updateSeedingLimitTimer();
|
updateSeedingLimitTimer();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Session::handleTorrentNameChanged(TorrentHandleImpl *const torrent)
|
void Session::handleTorrentNameChanged(TorrentImpl *const torrent)
|
||||||
{
|
{
|
||||||
torrent->saveResumeData();
|
torrent->saveResumeData();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Session::handleTorrentSavePathChanged(TorrentHandleImpl *const torrent)
|
void Session::handleTorrentSavePathChanged(TorrentImpl *const torrent)
|
||||||
{
|
{
|
||||||
torrent->saveResumeData();
|
torrent->saveResumeData();
|
||||||
emit torrentSavePathChanged(torrent);
|
emit torrentSavePathChanged(torrent);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Session::handleTorrentCategoryChanged(TorrentHandleImpl *const torrent, const QString &oldCategory)
|
void Session::handleTorrentCategoryChanged(TorrentImpl *const torrent, const QString &oldCategory)
|
||||||
{
|
{
|
||||||
torrent->saveResumeData();
|
torrent->saveResumeData();
|
||||||
emit torrentCategoryChanged(torrent, oldCategory);
|
emit torrentCategoryChanged(torrent, oldCategory);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Session::handleTorrentTagAdded(TorrentHandleImpl *const torrent, const QString &tag)
|
void Session::handleTorrentTagAdded(TorrentImpl *const torrent, const QString &tag)
|
||||||
{
|
{
|
||||||
torrent->saveResumeData();
|
torrent->saveResumeData();
|
||||||
emit torrentTagAdded(torrent, tag);
|
emit torrentTagAdded(torrent, tag);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Session::handleTorrentTagRemoved(TorrentHandleImpl *const torrent, const QString &tag)
|
void Session::handleTorrentTagRemoved(TorrentImpl *const torrent, const QString &tag)
|
||||||
{
|
{
|
||||||
torrent->saveResumeData();
|
torrent->saveResumeData();
|
||||||
emit torrentTagRemoved(torrent, tag);
|
emit torrentTagRemoved(torrent, tag);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Session::handleTorrentSavingModeChanged(TorrentHandleImpl *const torrent)
|
void Session::handleTorrentSavingModeChanged(TorrentImpl *const torrent)
|
||||||
{
|
{
|
||||||
torrent->saveResumeData();
|
torrent->saveResumeData();
|
||||||
emit torrentSavingModeChanged(torrent);
|
emit torrentSavingModeChanged(torrent);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Session::handleTorrentTrackersAdded(TorrentHandleImpl *const torrent, const QVector<TrackerEntry> &newTrackers)
|
void Session::handleTorrentTrackersAdded(TorrentImpl *const torrent, const QVector<TrackerEntry> &newTrackers)
|
||||||
{
|
{
|
||||||
torrent->saveResumeData();
|
torrent->saveResumeData();
|
||||||
|
|
||||||
@@ -3821,7 +3816,7 @@ void Session::handleTorrentTrackersAdded(TorrentHandleImpl *const torrent, const
|
|||||||
emit trackersChanged(torrent);
|
emit trackersChanged(torrent);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Session::handleTorrentTrackersRemoved(TorrentHandleImpl *const torrent, const QVector<TrackerEntry> &deletedTrackers)
|
void Session::handleTorrentTrackersRemoved(TorrentImpl *const torrent, const QVector<TrackerEntry> &deletedTrackers)
|
||||||
{
|
{
|
||||||
torrent->saveResumeData();
|
torrent->saveResumeData();
|
||||||
|
|
||||||
@@ -3833,27 +3828,27 @@ void Session::handleTorrentTrackersRemoved(TorrentHandleImpl *const torrent, con
|
|||||||
emit trackersChanged(torrent);
|
emit trackersChanged(torrent);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Session::handleTorrentTrackersChanged(TorrentHandleImpl *const torrent)
|
void Session::handleTorrentTrackersChanged(TorrentImpl *const torrent)
|
||||||
{
|
{
|
||||||
torrent->saveResumeData();
|
torrent->saveResumeData();
|
||||||
emit trackersChanged(torrent);
|
emit trackersChanged(torrent);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Session::handleTorrentUrlSeedsAdded(TorrentHandleImpl *const torrent, const QVector<QUrl> &newUrlSeeds)
|
void Session::handleTorrentUrlSeedsAdded(TorrentImpl *const torrent, const QVector<QUrl> &newUrlSeeds)
|
||||||
{
|
{
|
||||||
torrent->saveResumeData();
|
torrent->saveResumeData();
|
||||||
for (const QUrl &newUrlSeed : newUrlSeeds)
|
for (const QUrl &newUrlSeed : newUrlSeeds)
|
||||||
LogMsg(tr("URL seed '%1' was added to torrent '%2'").arg(newUrlSeed.toString(), torrent->name()));
|
LogMsg(tr("URL seed '%1' was added to torrent '%2'").arg(newUrlSeed.toString(), torrent->name()));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Session::handleTorrentUrlSeedsRemoved(TorrentHandleImpl *const torrent, const QVector<QUrl> &urlSeeds)
|
void Session::handleTorrentUrlSeedsRemoved(TorrentImpl *const torrent, const QVector<QUrl> &urlSeeds)
|
||||||
{
|
{
|
||||||
torrent->saveResumeData();
|
torrent->saveResumeData();
|
||||||
for (const QUrl &urlSeed : urlSeeds)
|
for (const QUrl &urlSeed : urlSeeds)
|
||||||
LogMsg(tr("URL seed '%1' was removed from torrent '%2'").arg(urlSeed.toString(), torrent->name()));
|
LogMsg(tr("URL seed '%1' was removed from torrent '%2'").arg(urlSeed.toString(), torrent->name()));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Session::handleTorrentMetadataReceived(TorrentHandleImpl *const torrent)
|
void Session::handleTorrentMetadataReceived(TorrentImpl *const torrent)
|
||||||
{
|
{
|
||||||
// Save metadata
|
// Save metadata
|
||||||
const QDir resumeDataDir {m_resumeFolderPath};
|
const QDir resumeDataDir {m_resumeFolderPath};
|
||||||
@@ -3874,24 +3869,24 @@ void Session::handleTorrentMetadataReceived(TorrentHandleImpl *const torrent)
|
|||||||
emit torrentMetadataReceived(torrent);
|
emit torrentMetadataReceived(torrent);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Session::handleTorrentPaused(TorrentHandleImpl *const torrent)
|
void Session::handleTorrentPaused(TorrentImpl *const torrent)
|
||||||
{
|
{
|
||||||
torrent->saveResumeData();
|
torrent->saveResumeData();
|
||||||
emit torrentPaused(torrent);
|
emit torrentPaused(torrent);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Session::handleTorrentResumed(TorrentHandleImpl *const torrent)
|
void Session::handleTorrentResumed(TorrentImpl *const torrent)
|
||||||
{
|
{
|
||||||
torrent->saveResumeData();
|
torrent->saveResumeData();
|
||||||
emit torrentResumed(torrent);
|
emit torrentResumed(torrent);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Session::handleTorrentChecked(TorrentHandleImpl *const torrent)
|
void Session::handleTorrentChecked(TorrentImpl *const torrent)
|
||||||
{
|
{
|
||||||
emit torrentFinishedChecking(torrent);
|
emit torrentFinishedChecking(torrent);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Session::handleTorrentFinished(TorrentHandleImpl *const torrent)
|
void Session::handleTorrentFinished(TorrentImpl *const torrent)
|
||||||
{
|
{
|
||||||
if (!torrent->hasError() && !torrent->hasMissingFiles())
|
if (!torrent->hasError() && !torrent->hasMissingFiles())
|
||||||
torrent->saveResumeData();
|
torrent->saveResumeData();
|
||||||
@@ -3930,7 +3925,7 @@ void Session::handleTorrentFinished(TorrentHandleImpl *const torrent)
|
|||||||
emit allTorrentsFinished();
|
emit allTorrentsFinished();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Session::handleTorrentResumeDataReady(TorrentHandleImpl *const torrent, const std::shared_ptr<lt::entry> &data)
|
void Session::handleTorrentResumeDataReady(TorrentImpl *const torrent, const std::shared_ptr<lt::entry> &data)
|
||||||
{
|
{
|
||||||
--m_numResumeData;
|
--m_numResumeData;
|
||||||
|
|
||||||
@@ -3947,17 +3942,17 @@ void Session::handleTorrentResumeDataReady(TorrentHandleImpl *const torrent, con
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void Session::handleTorrentTrackerReply(TorrentHandleImpl *const torrent, const QString &trackerUrl)
|
void Session::handleTorrentTrackerReply(TorrentImpl *const torrent, const QString &trackerUrl)
|
||||||
{
|
{
|
||||||
emit trackerSuccess(torrent, trackerUrl);
|
emit trackerSuccess(torrent, trackerUrl);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Session::handleTorrentTrackerError(TorrentHandleImpl *const torrent, const QString &trackerUrl)
|
void Session::handleTorrentTrackerError(TorrentImpl *const torrent, const QString &trackerUrl)
|
||||||
{
|
{
|
||||||
emit trackerError(torrent, trackerUrl);
|
emit trackerError(torrent, trackerUrl);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Session::addMoveTorrentStorageJob(TorrentHandleImpl *torrent, const QString &newPath, const MoveStorageMode mode)
|
bool Session::addMoveTorrentStorageJob(TorrentImpl *torrent, const QString &newPath, const MoveStorageMode mode)
|
||||||
{
|
{
|
||||||
Q_ASSERT(torrent);
|
Q_ASSERT(torrent);
|
||||||
|
|
||||||
@@ -4014,7 +4009,7 @@ bool Session::addMoveTorrentStorageJob(TorrentHandleImpl *torrent, const QString
|
|||||||
void Session::moveTorrentStorage(const MoveStorageJob &job) const
|
void Session::moveTorrentStorage(const MoveStorageJob &job) const
|
||||||
{
|
{
|
||||||
const InfoHash infoHash = job.torrentHandle.info_hash();
|
const InfoHash infoHash = job.torrentHandle.info_hash();
|
||||||
const TorrentHandleImpl *torrent = m_torrents.value(infoHash);
|
const TorrentImpl *torrent = m_torrents.value(infoHash);
|
||||||
const QString torrentName = (torrent ? torrent->name() : QString {infoHash});
|
const QString torrentName = (torrent ? torrent->name() : QString {infoHash});
|
||||||
LogMsg(tr("Moving \"%1\" to \"%2\"...").arg(torrentName, job.path));
|
LogMsg(tr("Moving \"%1\" to \"%2\"...").arg(torrentName, job.path));
|
||||||
|
|
||||||
@@ -4037,7 +4032,7 @@ void Session::handleMoveTorrentStorageJobFinished()
|
|||||||
|
|
||||||
const bool torrentHasOutstandingJob = (iter != m_moveStorageQueue.cend());
|
const bool torrentHasOutstandingJob = (iter != m_moveStorageQueue.cend());
|
||||||
|
|
||||||
TorrentHandleImpl *torrent = m_torrents.value(finishedJob.torrentHandle.info_hash());
|
TorrentImpl *torrent = m_torrents.value(finishedJob.torrentHandle.info_hash());
|
||||||
if (torrent)
|
if (torrent)
|
||||||
{
|
{
|
||||||
torrent->handleMoveStorageJobFinished(torrentHasOutstandingJob);
|
torrent->handleMoveStorageJobFinished(torrentHasOutstandingJob);
|
||||||
@@ -4047,19 +4042,19 @@ void Session::handleMoveTorrentStorageJobFinished()
|
|||||||
// Last job is completed for torrent that being removing, so actually remove it
|
// Last job is completed for torrent that being removing, so actually remove it
|
||||||
const lt::torrent_handle nativeHandle {finishedJob.torrentHandle};
|
const lt::torrent_handle nativeHandle {finishedJob.torrentHandle};
|
||||||
const RemovingTorrentData &removingTorrentData = m_removingTorrents[nativeHandle.info_hash()];
|
const RemovingTorrentData &removingTorrentData = m_removingTorrents[nativeHandle.info_hash()];
|
||||||
if (removingTorrentData.deleteOption == Torrent)
|
if (removingTorrentData.deleteOption == DeleteTorrent)
|
||||||
m_nativeSession->remove_torrent(nativeHandle, lt::session::delete_partfile);
|
m_nativeSession->remove_torrent(nativeHandle, lt::session::delete_partfile);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Session::handleTorrentTrackerWarning(TorrentHandleImpl *const torrent, const QString &trackerUrl)
|
void Session::handleTorrentTrackerWarning(TorrentImpl *const torrent, const QString &trackerUrl)
|
||||||
{
|
{
|
||||||
emit trackerWarning(torrent, trackerUrl);
|
emit trackerWarning(torrent, trackerUrl);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Session::hasPerTorrentRatioLimit() const
|
bool Session::hasPerTorrentRatioLimit() const
|
||||||
{
|
{
|
||||||
return std::any_of(m_torrents.cbegin(), m_torrents.cend(), [](const TorrentHandleImpl *torrent)
|
return std::any_of(m_torrents.cbegin(), m_torrents.cend(), [](const TorrentImpl *torrent)
|
||||||
{
|
{
|
||||||
return (torrent->ratioLimit() >= 0);
|
return (torrent->ratioLimit() >= 0);
|
||||||
});
|
});
|
||||||
@@ -4067,7 +4062,7 @@ bool Session::hasPerTorrentRatioLimit() const
|
|||||||
|
|
||||||
bool Session::hasPerTorrentSeedingTimeLimit() const
|
bool Session::hasPerTorrentSeedingTimeLimit() const
|
||||||
{
|
{
|
||||||
return std::any_of(m_torrents.cbegin(), m_torrents.cend(), [](const TorrentHandleImpl *torrent)
|
return std::any_of(m_torrents.cbegin(), m_torrents.cend(), [](const TorrentImpl *torrent)
|
||||||
{
|
{
|
||||||
return (torrent->seedingTimeLimit() >= 0);
|
return (torrent->seedingTimeLimit() >= 0);
|
||||||
});
|
});
|
||||||
@@ -4148,7 +4143,7 @@ void Session::disableIPFilter()
|
|||||||
|
|
||||||
void Session::recursiveTorrentDownload(const InfoHash &hash)
|
void Session::recursiveTorrentDownload(const InfoHash &hash)
|
||||||
{
|
{
|
||||||
TorrentHandleImpl *const torrent = m_torrents.value(hash);
|
TorrentImpl *const torrent = m_torrents.value(hash);
|
||||||
if (!torrent) return;
|
if (!torrent) return;
|
||||||
|
|
||||||
for (int i = 0; i < torrent->filesCount(); ++i)
|
for (int i = 0; i < torrent->filesCount(); ++i)
|
||||||
@@ -4194,7 +4189,7 @@ bool Session::loadTorrentResumeData(const QByteArray &data, const TorrentInfo &m
|
|||||||
Utils::Fs::toUniformPath(fromLTString(root.dict_find_string_value("qBt-savePath"))));
|
Utils::Fs::toUniformPath(fromLTString(root.dict_find_string_value("qBt-savePath"))));
|
||||||
torrentParams.hasSeedStatus = root.dict_find_int_value("qBt-seedStatus");
|
torrentParams.hasSeedStatus = root.dict_find_int_value("qBt-seedStatus");
|
||||||
torrentParams.firstLastPiecePriority = root.dict_find_int_value("qBt-firstLastPiecePriority");
|
torrentParams.firstLastPiecePriority = root.dict_find_int_value("qBt-firstLastPiecePriority");
|
||||||
torrentParams.seedingTimeLimit = root.dict_find_int_value("qBt-seedingTimeLimit", TorrentHandle::USE_GLOBAL_SEEDING_TIME);
|
torrentParams.seedingTimeLimit = root.dict_find_int_value("qBt-seedingTimeLimit", Torrent::USE_GLOBAL_SEEDING_TIME);
|
||||||
|
|
||||||
// TODO: The following code is deprecated. Replace with the commented one after several releases in 4.4.x.
|
// TODO: The following code is deprecated. Replace with the commented one after several releases in 4.4.x.
|
||||||
// === BEGIN DEPRECATED CODE === //
|
// === BEGIN DEPRECATED CODE === //
|
||||||
@@ -4217,7 +4212,7 @@ bool Session::loadTorrentResumeData(const QByteArray &data, const TorrentInfo &m
|
|||||||
|
|
||||||
const lt::string_view ratioLimitString = root.dict_find_string_value("qBt-ratioLimit");
|
const lt::string_view ratioLimitString = root.dict_find_string_value("qBt-ratioLimit");
|
||||||
if (ratioLimitString.empty())
|
if (ratioLimitString.empty())
|
||||||
torrentParams.ratioLimit = root.dict_find_int_value("qBt-ratioLimit", TorrentHandle::USE_GLOBAL_RATIO * 1000) / 1000.0;
|
torrentParams.ratioLimit = root.dict_find_int_value("qBt-ratioLimit", Torrent::USE_GLOBAL_RATIO * 1000) / 1000.0;
|
||||||
else
|
else
|
||||||
torrentParams.ratioLimit = fromLTString(ratioLimitString).toDouble();
|
torrentParams.ratioLimit = fromLTString(ratioLimitString).toDouble();
|
||||||
|
|
||||||
@@ -4551,7 +4546,7 @@ void Session::handleAlert(const lt::alert *a)
|
|||||||
|
|
||||||
void Session::dispatchTorrentAlert(const lt::alert *a)
|
void Session::dispatchTorrentAlert(const lt::alert *a)
|
||||||
{
|
{
|
||||||
TorrentHandleImpl *const torrent = m_torrents.value(static_cast<const lt::torrent_alert*>(a)->handle.info_hash());
|
TorrentImpl *const torrent = m_torrents.value(static_cast<const lt::torrent_alert*>(a)->handle.info_hash());
|
||||||
if (torrent)
|
if (torrent)
|
||||||
{
|
{
|
||||||
torrent->handleAlert(a);
|
torrent->handleAlert(a);
|
||||||
@@ -4566,13 +4561,13 @@ void Session::dispatchTorrentAlert(const lt::alert *a)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Session::createTorrentHandle(const lt::torrent_handle &nativeHandle)
|
void Session::createTorrent(const lt::torrent_handle &nativeHandle)
|
||||||
{
|
{
|
||||||
Q_ASSERT(m_loadingTorrents.contains(nativeHandle.info_hash()));
|
Q_ASSERT(m_loadingTorrents.contains(nativeHandle.info_hash()));
|
||||||
|
|
||||||
const LoadTorrentParams params = m_loadingTorrents.take(nativeHandle.info_hash());
|
const LoadTorrentParams params = m_loadingTorrents.take(nativeHandle.info_hash());
|
||||||
|
|
||||||
auto *const torrent = new TorrentHandleImpl {this, m_nativeSession, nativeHandle, params};
|
auto *const torrent = new TorrentImpl {this, m_nativeSession, nativeHandle, params};
|
||||||
m_torrents.insert(torrent->hash(), torrent);
|
m_torrents.insert(torrent->hash(), torrent);
|
||||||
|
|
||||||
const bool hasMetadata = torrent->hasMetadata();
|
const bool hasMetadata = torrent->hasMetadata();
|
||||||
@@ -4640,7 +4635,7 @@ void Session::handleAddTorrentAlert(const lt::add_torrent_alert *p)
|
|||||||
}
|
}
|
||||||
else if (m_loadingTorrents.contains(p->handle.info_hash()))
|
else if (m_loadingTorrents.contains(p->handle.info_hash()))
|
||||||
{
|
{
|
||||||
createTorrentHandle(p->handle);
|
createTorrent(p->handle);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -4651,7 +4646,7 @@ void Session::handleTorrentRemovedAlert(const lt::torrent_removed_alert *p)
|
|||||||
const auto removingTorrentDataIter = m_removingTorrents.find(infoHash);
|
const auto removingTorrentDataIter = m_removingTorrents.find(infoHash);
|
||||||
if (removingTorrentDataIter != m_removingTorrents.end())
|
if (removingTorrentDataIter != m_removingTorrents.end())
|
||||||
{
|
{
|
||||||
if (removingTorrentDataIter->deleteOption == Torrent)
|
if (removingTorrentDataIter->deleteOption == DeleteTorrent)
|
||||||
{
|
{
|
||||||
LogMsg(tr("'%1' was removed from the transfer list.", "'xxx.avi' was removed...").arg(removingTorrentDataIter->name));
|
LogMsg(tr("'%1' was removed from the transfer list.", "'xxx.avi' was removed...").arg(removingTorrentDataIter->name));
|
||||||
m_removingTorrents.erase(removingTorrentDataIter);
|
m_removingTorrents.erase(removingTorrentDataIter);
|
||||||
@@ -4717,7 +4712,7 @@ void Session::handleMetadataReceivedAlert(const lt::metadata_received_alert *p)
|
|||||||
|
|
||||||
void Session::handleFileErrorAlert(const lt::file_error_alert *p)
|
void Session::handleFileErrorAlert(const lt::file_error_alert *p)
|
||||||
{
|
{
|
||||||
TorrentHandleImpl *const torrent = m_torrents.value(p->handle.info_hash());
|
TorrentImpl *const torrent = m_torrents.value(p->handle.info_hash());
|
||||||
if (!torrent)
|
if (!torrent)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@@ -4787,7 +4782,7 @@ void Session::handlePeerBanAlert(const lt::peer_ban_alert *p)
|
|||||||
|
|
||||||
void Session::handleUrlSeedAlert(const lt::url_seed_alert *p)
|
void Session::handleUrlSeedAlert(const lt::url_seed_alert *p)
|
||||||
{
|
{
|
||||||
const TorrentHandleImpl *torrent = m_torrents.value(p->handle.info_hash());
|
const TorrentImpl *torrent = m_torrents.value(p->handle.info_hash());
|
||||||
if (!torrent)
|
if (!torrent)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@@ -4925,13 +4920,10 @@ void Session::handleStorageMovedAlert(const lt::storage_moved_alert *p)
|
|||||||
Q_ASSERT(newPath == currentJob.path);
|
Q_ASSERT(newPath == currentJob.path);
|
||||||
|
|
||||||
const InfoHash infoHash = currentJob.torrentHandle.info_hash();
|
const InfoHash infoHash = currentJob.torrentHandle.info_hash();
|
||||||
TorrentHandleImpl *torrent = m_torrents.value(infoHash);
|
TorrentImpl *torrent = m_torrents.value(infoHash);
|
||||||
const QString torrentName = (torrent ? torrent->name() : QString {infoHash});
|
const QString torrentName = (torrent ? torrent->name() : QString {infoHash});
|
||||||
LogMsg(tr("\"%1\" is successfully moved to \"%2\".").arg(torrentName, newPath));
|
LogMsg(tr("\"%1\" is successfully moved to \"%2\".").arg(torrentName, newPath));
|
||||||
|
|
||||||
if (torrent)
|
|
||||||
emit torrentStorageMoveFinished(torrent, newPath);
|
|
||||||
|
|
||||||
handleMoveTorrentStorageJobFinished();
|
handleMoveTorrentStorageJobFinished();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -4943,27 +4935,24 @@ void Session::handleStorageMovedFailedAlert(const lt::storage_moved_failed_alert
|
|||||||
Q_ASSERT(currentJob.torrentHandle == p->handle);
|
Q_ASSERT(currentJob.torrentHandle == p->handle);
|
||||||
|
|
||||||
const InfoHash infoHash = currentJob.torrentHandle.info_hash();
|
const InfoHash infoHash = currentJob.torrentHandle.info_hash();
|
||||||
TorrentHandleImpl *torrent = m_torrents.value(infoHash);
|
TorrentImpl *torrent = m_torrents.value(infoHash);
|
||||||
const QString torrentName = (torrent ? torrent->name() : QString {infoHash});
|
const QString torrentName = (torrent ? torrent->name() : QString {infoHash});
|
||||||
const QString currentLocation = QString::fromStdString(p->handle.status(lt::torrent_handle::query_save_path).save_path);
|
const QString currentLocation = QString::fromStdString(p->handle.status(lt::torrent_handle::query_save_path).save_path);
|
||||||
const QString errorMessage = QString::fromStdString(p->message());
|
const QString errorMessage = QString::fromStdString(p->message());
|
||||||
LogMsg(tr("Failed to move \"%1\" from \"%2\" to \"%3\". Reason: %4.")
|
LogMsg(tr("Failed to move \"%1\" from \"%2\" to \"%3\". Reason: %4.")
|
||||||
.arg(torrentName, currentLocation, currentJob.path, errorMessage), Log::CRITICAL);
|
.arg(torrentName, currentLocation, currentJob.path, errorMessage), Log::CRITICAL);
|
||||||
|
|
||||||
if (torrent)
|
|
||||||
emit torrentStorageMoveFailed(torrent, currentJob.path, errorMessage);
|
|
||||||
|
|
||||||
handleMoveTorrentStorageJobFinished();
|
handleMoveTorrentStorageJobFinished();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Session::handleStateUpdateAlert(const lt::state_update_alert *p)
|
void Session::handleStateUpdateAlert(const lt::state_update_alert *p)
|
||||||
{
|
{
|
||||||
QVector<TorrentHandle *> updatedTorrents;
|
QVector<Torrent *> updatedTorrents;
|
||||||
updatedTorrents.reserve(p->status.size());
|
updatedTorrents.reserve(p->status.size());
|
||||||
|
|
||||||
for (const lt::torrent_status &status : p->status)
|
for (const lt::torrent_status &status : p->status)
|
||||||
{
|
{
|
||||||
TorrentHandleImpl *const torrent = m_torrents.value(status.info_hash);
|
TorrentImpl *const torrent = m_torrents.value(status.info_hash);
|
||||||
|
|
||||||
if (!torrent)
|
if (!torrent)
|
||||||
continue;
|
continue;
|
||||||
|
|||||||
@@ -30,6 +30,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
#include <variant>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include <libtorrent/add_torrent_params.hpp>
|
#include <libtorrent/add_torrent_params.hpp>
|
||||||
@@ -84,8 +85,8 @@ enum MaxRatioAction
|
|||||||
|
|
||||||
enum DeleteOption
|
enum DeleteOption
|
||||||
{
|
{
|
||||||
Torrent,
|
DeleteTorrent,
|
||||||
TorrentAndFiles
|
DeleteTorrentAndFiles
|
||||||
};
|
};
|
||||||
|
|
||||||
enum TorrentExportFolder
|
enum TorrentExportFolder
|
||||||
@@ -103,8 +104,8 @@ namespace BitTorrent
|
|||||||
{
|
{
|
||||||
class InfoHash;
|
class InfoHash;
|
||||||
class MagnetUri;
|
class MagnetUri;
|
||||||
class TorrentHandle;
|
class Torrent;
|
||||||
class TorrentHandleImpl;
|
class TorrentImpl;
|
||||||
class Tracker;
|
class Tracker;
|
||||||
class TrackerEntry;
|
class TrackerEntry;
|
||||||
struct LoadTorrentParams;
|
struct LoadTorrentParams;
|
||||||
@@ -439,8 +440,8 @@ namespace BitTorrent
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
void startUpTorrents();
|
void startUpTorrents();
|
||||||
TorrentHandle *findTorrent(const InfoHash &hash) const;
|
Torrent *findTorrent(const InfoHash &hash) const;
|
||||||
QVector<TorrentHandle *> torrents() const;
|
QVector<Torrent *> torrents() const;
|
||||||
bool hasActiveTorrents() const;
|
bool hasActiveTorrents() const;
|
||||||
bool hasUnfinishedTorrents() const;
|
bool hasUnfinishedTorrents() const;
|
||||||
bool hasRunningSeed() const;
|
bool hasRunningSeed() const;
|
||||||
@@ -459,7 +460,7 @@ namespace BitTorrent
|
|||||||
bool addTorrent(const QString &source, const AddTorrentParams ¶ms = AddTorrentParams());
|
bool addTorrent(const QString &source, const AddTorrentParams ¶ms = AddTorrentParams());
|
||||||
bool addTorrent(const MagnetUri &magnetUri, const AddTorrentParams ¶ms = AddTorrentParams());
|
bool addTorrent(const MagnetUri &magnetUri, const AddTorrentParams ¶ms = AddTorrentParams());
|
||||||
bool addTorrent(const TorrentInfo &torrentInfo, const AddTorrentParams ¶ms = AddTorrentParams());
|
bool addTorrent(const TorrentInfo &torrentInfo, const AddTorrentParams ¶ms = AddTorrentParams());
|
||||||
bool deleteTorrent(const InfoHash &hash, DeleteOption deleteOption = Torrent);
|
bool deleteTorrent(const InfoHash &hash, DeleteOption deleteOption = DeleteTorrent);
|
||||||
bool downloadMetadata(const MagnetUri &magnetUri);
|
bool downloadMetadata(const MagnetUri &magnetUri);
|
||||||
bool cancelDownloadMetadata(const InfoHash &hash);
|
bool cancelDownloadMetadata(const InfoHash &hash);
|
||||||
|
|
||||||
@@ -469,31 +470,31 @@ namespace BitTorrent
|
|||||||
void topTorrentsQueuePos(const QVector<InfoHash> &hashes);
|
void topTorrentsQueuePos(const QVector<InfoHash> &hashes);
|
||||||
void bottomTorrentsQueuePos(const QVector<InfoHash> &hashes);
|
void bottomTorrentsQueuePos(const QVector<InfoHash> &hashes);
|
||||||
|
|
||||||
// TorrentHandle interface
|
// Torrent interface
|
||||||
void handleTorrentSaveResumeDataRequested(const TorrentHandleImpl *torrent);
|
void handleTorrentSaveResumeDataRequested(const TorrentImpl *torrent);
|
||||||
void handleTorrentShareLimitChanged(TorrentHandleImpl *const torrent);
|
void handleTorrentShareLimitChanged(TorrentImpl *const torrent);
|
||||||
void handleTorrentNameChanged(TorrentHandleImpl *const torrent);
|
void handleTorrentNameChanged(TorrentImpl *const torrent);
|
||||||
void handleTorrentSavePathChanged(TorrentHandleImpl *const torrent);
|
void handleTorrentSavePathChanged(TorrentImpl *const torrent);
|
||||||
void handleTorrentCategoryChanged(TorrentHandleImpl *const torrent, const QString &oldCategory);
|
void handleTorrentCategoryChanged(TorrentImpl *const torrent, const QString &oldCategory);
|
||||||
void handleTorrentTagAdded(TorrentHandleImpl *const torrent, const QString &tag);
|
void handleTorrentTagAdded(TorrentImpl *const torrent, const QString &tag);
|
||||||
void handleTorrentTagRemoved(TorrentHandleImpl *const torrent, const QString &tag);
|
void handleTorrentTagRemoved(TorrentImpl *const torrent, const QString &tag);
|
||||||
void handleTorrentSavingModeChanged(TorrentHandleImpl *const torrent);
|
void handleTorrentSavingModeChanged(TorrentImpl *const torrent);
|
||||||
void handleTorrentMetadataReceived(TorrentHandleImpl *const torrent);
|
void handleTorrentMetadataReceived(TorrentImpl *const torrent);
|
||||||
void handleTorrentPaused(TorrentHandleImpl *const torrent);
|
void handleTorrentPaused(TorrentImpl *const torrent);
|
||||||
void handleTorrentResumed(TorrentHandleImpl *const torrent);
|
void handleTorrentResumed(TorrentImpl *const torrent);
|
||||||
void handleTorrentChecked(TorrentHandleImpl *const torrent);
|
void handleTorrentChecked(TorrentImpl *const torrent);
|
||||||
void handleTorrentFinished(TorrentHandleImpl *const torrent);
|
void handleTorrentFinished(TorrentImpl *const torrent);
|
||||||
void handleTorrentTrackersAdded(TorrentHandleImpl *const torrent, const QVector<TrackerEntry> &newTrackers);
|
void handleTorrentTrackersAdded(TorrentImpl *const torrent, const QVector<TrackerEntry> &newTrackers);
|
||||||
void handleTorrentTrackersRemoved(TorrentHandleImpl *const torrent, const QVector<TrackerEntry> &deletedTrackers);
|
void handleTorrentTrackersRemoved(TorrentImpl *const torrent, const QVector<TrackerEntry> &deletedTrackers);
|
||||||
void handleTorrentTrackersChanged(TorrentHandleImpl *const torrent);
|
void handleTorrentTrackersChanged(TorrentImpl *const torrent);
|
||||||
void handleTorrentUrlSeedsAdded(TorrentHandleImpl *const torrent, const QVector<QUrl> &newUrlSeeds);
|
void handleTorrentUrlSeedsAdded(TorrentImpl *const torrent, const QVector<QUrl> &newUrlSeeds);
|
||||||
void handleTorrentUrlSeedsRemoved(TorrentHandleImpl *const torrent, const QVector<QUrl> &urlSeeds);
|
void handleTorrentUrlSeedsRemoved(TorrentImpl *const torrent, const QVector<QUrl> &urlSeeds);
|
||||||
void handleTorrentResumeDataReady(TorrentHandleImpl *const torrent, const std::shared_ptr<lt::entry> &data);
|
void handleTorrentResumeDataReady(TorrentImpl *const torrent, const std::shared_ptr<lt::entry> &data);
|
||||||
void handleTorrentTrackerReply(TorrentHandleImpl *const torrent, const QString &trackerUrl);
|
void handleTorrentTrackerReply(TorrentImpl *const torrent, const QString &trackerUrl);
|
||||||
void handleTorrentTrackerWarning(TorrentHandleImpl *const torrent, const QString &trackerUrl);
|
void handleTorrentTrackerWarning(TorrentImpl *const torrent, const QString &trackerUrl);
|
||||||
void handleTorrentTrackerError(TorrentHandleImpl *const torrent, const QString &trackerUrl);
|
void handleTorrentTrackerError(TorrentImpl *const torrent, const QString &trackerUrl);
|
||||||
|
|
||||||
bool addMoveTorrentStorageJob(TorrentHandleImpl *torrent, const QString &newPath, MoveStorageMode mode);
|
bool addMoveTorrentStorageJob(TorrentImpl *torrent, const QString &newPath, MoveStorageMode mode);
|
||||||
|
|
||||||
void findIncompleteFiles(const TorrentInfo &torrentInfo, const QString &savePath) const;
|
void findIncompleteFiles(const TorrentInfo &torrentInfo, const QString &savePath) const;
|
||||||
|
|
||||||
@@ -503,39 +504,37 @@ namespace BitTorrent
|
|||||||
void categoryRemoved(const QString &categoryName);
|
void categoryRemoved(const QString &categoryName);
|
||||||
void downloadFromUrlFailed(const QString &url, const QString &reason);
|
void downloadFromUrlFailed(const QString &url, const QString &reason);
|
||||||
void downloadFromUrlFinished(const QString &url);
|
void downloadFromUrlFinished(const QString &url);
|
||||||
void fullDiskError(TorrentHandle *torrent, const QString &msg);
|
void fullDiskError(Torrent *torrent, const QString &msg);
|
||||||
void IPFilterParsed(bool error, int ruleCount);
|
void IPFilterParsed(bool error, int ruleCount);
|
||||||
void loadTorrentFailed(const QString &error);
|
void loadTorrentFailed(const QString &error);
|
||||||
void metadataDownloaded(const TorrentInfo &info);
|
void metadataDownloaded(const TorrentInfo &info);
|
||||||
void recursiveTorrentDownloadPossible(TorrentHandle *torrent);
|
void recursiveTorrentDownloadPossible(Torrent *torrent);
|
||||||
void speedLimitModeChanged(bool alternative);
|
void speedLimitModeChanged(bool alternative);
|
||||||
void statsUpdated();
|
void statsUpdated();
|
||||||
void subcategoriesSupportChanged();
|
void subcategoriesSupportChanged();
|
||||||
void tagAdded(const QString &tag);
|
void tagAdded(const QString &tag);
|
||||||
void tagRemoved(const QString &tag);
|
void tagRemoved(const QString &tag);
|
||||||
void torrentAboutToBeRemoved(TorrentHandle *torrent);
|
void torrentAboutToBeRemoved(Torrent *torrent);
|
||||||
void torrentAdded(TorrentHandle *torrent);
|
void torrentAdded(Torrent *torrent);
|
||||||
void torrentCategoryChanged(TorrentHandle *torrent, const QString &oldCategory);
|
void torrentCategoryChanged(Torrent *torrent, const QString &oldCategory);
|
||||||
void torrentFinished(TorrentHandle *torrent);
|
void torrentFinished(Torrent *torrent);
|
||||||
void torrentFinishedChecking(TorrentHandle *torrent);
|
void torrentFinishedChecking(Torrent *torrent);
|
||||||
void torrentLoaded(TorrentHandle *torrent);
|
void torrentLoaded(Torrent *torrent);
|
||||||
void torrentMetadataReceived(TorrentHandle *torrent);
|
void torrentMetadataReceived(Torrent *torrent);
|
||||||
void torrentPaused(TorrentHandle *torrent);
|
void torrentPaused(Torrent *torrent);
|
||||||
void torrentResumed(TorrentHandle *torrent);
|
void torrentResumed(Torrent *torrent);
|
||||||
void torrentSavePathChanged(TorrentHandle *torrent);
|
void torrentSavePathChanged(Torrent *torrent);
|
||||||
void torrentSavingModeChanged(TorrentHandle *torrent);
|
void torrentSavingModeChanged(Torrent *torrent);
|
||||||
void torrentStorageMoveFailed(TorrentHandle *torrent, const QString &targetPath, const QString &error);
|
void torrentsUpdated(const QVector<Torrent *> &torrents);
|
||||||
void torrentStorageMoveFinished(TorrentHandle *torrent, const QString &newPath);
|
void torrentTagAdded(Torrent *torrent, const QString &tag);
|
||||||
void torrentsUpdated(const QVector<TorrentHandle *> &torrents);
|
void torrentTagRemoved(Torrent *torrent, const QString &tag);
|
||||||
void torrentTagAdded(TorrentHandle *torrent, const QString &tag);
|
void trackerError(Torrent *torrent, const QString &tracker);
|
||||||
void torrentTagRemoved(TorrentHandle *torrent, const QString &tag);
|
void trackerlessStateChanged(Torrent *torrent, bool trackerless);
|
||||||
void trackerError(TorrentHandle *torrent, const QString &tracker);
|
void trackersAdded(Torrent *torrent, const QVector<TrackerEntry> &trackers);
|
||||||
void trackerlessStateChanged(TorrentHandle *torrent, bool trackerless);
|
void trackersChanged(Torrent *torrent);
|
||||||
void trackersAdded(TorrentHandle *torrent, const QVector<TrackerEntry> &trackers);
|
void trackersRemoved(Torrent *torrent, const QVector<TrackerEntry> &trackers);
|
||||||
void trackersChanged(TorrentHandle *torrent);
|
void trackerSuccess(Torrent *torrent, const QString &tracker);
|
||||||
void trackersRemoved(TorrentHandle *torrent, const QVector<TrackerEntry> &trackers);
|
void trackerWarning(Torrent *torrent, const QString &tracker);
|
||||||
void trackerSuccess(TorrentHandle *torrent, const QString &tracker);
|
|
||||||
void trackerWarning(TorrentHandle *torrent, const QString &tracker);
|
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void configureDeferred();
|
void configureDeferred();
|
||||||
@@ -602,10 +601,10 @@ namespace BitTorrent
|
|||||||
bool loadTorrentResumeData(const QByteArray &data, const TorrentInfo &metadata, LoadTorrentParams &torrentParams);
|
bool loadTorrentResumeData(const QByteArray &data, const TorrentInfo &metadata, LoadTorrentParams &torrentParams);
|
||||||
bool loadTorrent(LoadTorrentParams params);
|
bool loadTorrent(LoadTorrentParams params);
|
||||||
LoadTorrentParams initLoadTorrentParams(const AddTorrentParams &addTorrentParams);
|
LoadTorrentParams initLoadTorrentParams(const AddTorrentParams &addTorrentParams);
|
||||||
bool addTorrent_impl(const AddTorrentParams &addTorrentParams, const MagnetUri &magnetUri, TorrentInfo torrentInfo = TorrentInfo());
|
bool addTorrent_impl(const std::variant<MagnetUri, TorrentInfo> &source, const AddTorrentParams &addTorrentParams);
|
||||||
|
|
||||||
void updateSeedingLimitTimer();
|
void updateSeedingLimitTimer();
|
||||||
void exportTorrentFile(const TorrentHandle *torrent, TorrentExportFolder folder = TorrentExportFolder::Regular);
|
void exportTorrentFile(const Torrent *torrent, TorrentExportFolder folder = TorrentExportFolder::Regular);
|
||||||
|
|
||||||
void handleAlert(const lt::alert *a);
|
void handleAlert(const lt::alert *a);
|
||||||
void dispatchTorrentAlert(const lt::alert *a);
|
void dispatchTorrentAlert(const lt::alert *a);
|
||||||
@@ -630,7 +629,7 @@ namespace BitTorrent
|
|||||||
void handleStorageMovedFailedAlert(const lt::storage_moved_failed_alert *p);
|
void handleStorageMovedFailedAlert(const lt::storage_moved_failed_alert *p);
|
||||||
void handleSocks5Alert(const lt::socks5_alert *p) const;
|
void handleSocks5Alert(const lt::socks5_alert *p) const;
|
||||||
|
|
||||||
void createTorrentHandle(const lt::torrent_handle &nativeHandle);
|
void createTorrent(const lt::torrent_handle &nativeHandle);
|
||||||
|
|
||||||
void saveResumeData();
|
void saveResumeData();
|
||||||
void saveTorrentsQueue();
|
void saveTorrentsQueue();
|
||||||
@@ -772,7 +771,7 @@ namespace BitTorrent
|
|||||||
|
|
||||||
QSet<InfoHash> m_downloadedMetadata;
|
QSet<InfoHash> m_downloadedMetadata;
|
||||||
|
|
||||||
QHash<InfoHash, TorrentHandleImpl *> m_torrents;
|
QHash<InfoHash, TorrentImpl *> m_torrents;
|
||||||
QHash<InfoHash, LoadTorrentParams> m_loadingTorrents;
|
QHash<InfoHash, LoadTorrentParams> m_loadingTorrents;
|
||||||
QHash<QString, AddTorrentParams> m_downloadedTorrents;
|
QHash<QString, AddTorrentParams> m_downloadedTorrents;
|
||||||
QHash<InfoHash, RemovingTorrentData> m_removingTorrents;
|
QHash<InfoHash, RemovingTorrentData> m_removingTorrents;
|
||||||
|
|||||||
@@ -27,7 +27,7 @@
|
|||||||
* exception statement from your version.
|
* exception statement from your version.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "torrenthandle.h"
|
#include "torrent.h"
|
||||||
|
|
||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
|
|
||||||
@@ -40,33 +40,33 @@ namespace BitTorrent
|
|||||||
return ::qHash(static_cast<std::underlying_type_t<TorrentState>>(key), seed);
|
return ::qHash(static_cast<std::underlying_type_t<TorrentState>>(key), seed);
|
||||||
}
|
}
|
||||||
|
|
||||||
// TorrentHandle
|
// Torrent
|
||||||
|
|
||||||
const qreal TorrentHandle::USE_GLOBAL_RATIO = -2.;
|
const qreal Torrent::USE_GLOBAL_RATIO = -2.;
|
||||||
const qreal TorrentHandle::NO_RATIO_LIMIT = -1.;
|
const qreal Torrent::NO_RATIO_LIMIT = -1.;
|
||||||
|
|
||||||
const int TorrentHandle::USE_GLOBAL_SEEDING_TIME = -2;
|
const int Torrent::USE_GLOBAL_SEEDING_TIME = -2;
|
||||||
const int TorrentHandle::NO_SEEDING_TIME_LIMIT = -1;
|
const int Torrent::NO_SEEDING_TIME_LIMIT = -1;
|
||||||
|
|
||||||
const qreal TorrentHandle::MAX_RATIO = 9999.;
|
const qreal Torrent::MAX_RATIO = 9999.;
|
||||||
const int TorrentHandle::MAX_SEEDING_TIME = 525600;
|
const int Torrent::MAX_SEEDING_TIME = 525600;
|
||||||
|
|
||||||
bool TorrentHandle::isResumed() const
|
bool Torrent::isResumed() const
|
||||||
{
|
{
|
||||||
return !isPaused();
|
return !isPaused();
|
||||||
}
|
}
|
||||||
|
|
||||||
qlonglong TorrentHandle::remainingSize() const
|
qlonglong Torrent::remainingSize() const
|
||||||
{
|
{
|
||||||
return wantedSize() - completedSize();
|
return wantedSize() - completedSize();
|
||||||
}
|
}
|
||||||
|
|
||||||
void TorrentHandle::toggleSequentialDownload()
|
void Torrent::toggleSequentialDownload()
|
||||||
{
|
{
|
||||||
setSequentialDownload(!isSequentialDownload());
|
setSequentialDownload(!isSequentialDownload());
|
||||||
}
|
}
|
||||||
|
|
||||||
void TorrentHandle::toggleFirstLastPiecePriority()
|
void Torrent::toggleFirstLastPiecePriority()
|
||||||
{
|
{
|
||||||
setFirstLastPiecePriority(!hasFirstLastPiecePriority());
|
setFirstLastPiecePriority(!hasFirstLastPiecePriority());
|
||||||
}
|
}
|
||||||
@@ -33,6 +33,8 @@
|
|||||||
#include <QString>
|
#include <QString>
|
||||||
#include <QtContainerFwd>
|
#include <QtContainerFwd>
|
||||||
|
|
||||||
|
#include "abstractfilestorage.h"
|
||||||
|
|
||||||
class QBitArray;
|
class QBitArray;
|
||||||
class QDateTime;
|
class QDateTime;
|
||||||
class QUrl;
|
class QUrl;
|
||||||
@@ -89,7 +91,7 @@ namespace BitTorrent
|
|||||||
|
|
||||||
uint qHash(TorrentState key, uint seed);
|
uint qHash(TorrentState key, uint seed);
|
||||||
|
|
||||||
class TorrentHandle
|
class Torrent : public AbstractFileStorage
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
static const qreal USE_GLOBAL_RATIO;
|
static const qreal USE_GLOBAL_RATIO;
|
||||||
@@ -101,7 +103,7 @@ namespace BitTorrent
|
|||||||
static const qreal MAX_RATIO;
|
static const qreal MAX_RATIO;
|
||||||
static const int MAX_SEEDING_TIME;
|
static const int MAX_SEEDING_TIME;
|
||||||
|
|
||||||
virtual ~TorrentHandle() = default;
|
virtual ~Torrent() = default;
|
||||||
|
|
||||||
virtual InfoHash hash() const = 0;
|
virtual InfoHash hash() const = 0;
|
||||||
virtual QString name() const = 0;
|
virtual QString name() const = 0;
|
||||||
@@ -177,7 +179,6 @@ namespace BitTorrent
|
|||||||
virtual bool removeTag(const QString &tag) = 0;
|
virtual bool removeTag(const QString &tag) = 0;
|
||||||
virtual void removeAllTags() = 0;
|
virtual void removeAllTags() = 0;
|
||||||
|
|
||||||
virtual int filesCount() const = 0;
|
|
||||||
virtual int piecesCount() const = 0;
|
virtual int piecesCount() const = 0;
|
||||||
virtual int piecesHave() const = 0;
|
virtual int piecesHave() const = 0;
|
||||||
virtual qreal progress() const = 0;
|
virtual qreal progress() const = 0;
|
||||||
@@ -185,9 +186,6 @@ namespace BitTorrent
|
|||||||
virtual qreal ratioLimit() const = 0;
|
virtual qreal ratioLimit() const = 0;
|
||||||
virtual int seedingTimeLimit() const = 0;
|
virtual int seedingTimeLimit() const = 0;
|
||||||
|
|
||||||
virtual QString filePath(int index) const = 0;
|
|
||||||
virtual QString fileName(int index) const = 0;
|
|
||||||
virtual qlonglong fileSize(int index) const = 0;
|
|
||||||
virtual QStringList absoluteFilePaths() const = 0;
|
virtual QStringList absoluteFilePaths() const = 0;
|
||||||
virtual QVector<DownloadPriority> filePriorities() const = 0;
|
virtual QVector<DownloadPriority> filePriorities() const = 0;
|
||||||
|
|
||||||
@@ -238,6 +236,9 @@ namespace BitTorrent
|
|||||||
virtual int downloadLimit() const = 0;
|
virtual int downloadLimit() const = 0;
|
||||||
virtual int uploadLimit() const = 0;
|
virtual int uploadLimit() const = 0;
|
||||||
virtual bool superSeeding() const = 0;
|
virtual bool superSeeding() const = 0;
|
||||||
|
virtual bool isDHTDisabled() const = 0;
|
||||||
|
virtual bool isPEXDisabled() const = 0;
|
||||||
|
virtual bool isLSDDisabled() const = 0;
|
||||||
virtual QVector<PeerInfo> peers() const = 0;
|
virtual QVector<PeerInfo> peers() const = 0;
|
||||||
virtual QBitArray pieces() const = 0;
|
virtual QBitArray pieces() const = 0;
|
||||||
virtual QBitArray downloadingPieces() const = 0;
|
virtual QBitArray downloadingPieces() const = 0;
|
||||||
@@ -270,13 +271,15 @@ namespace BitTorrent
|
|||||||
virtual void forceReannounce(int index = -1) = 0;
|
virtual void forceReannounce(int index = -1) = 0;
|
||||||
virtual void forceDHTAnnounce() = 0;
|
virtual void forceDHTAnnounce() = 0;
|
||||||
virtual void forceRecheck() = 0;
|
virtual void forceRecheck() = 0;
|
||||||
virtual void renameFile(int index, const QString &name) = 0;
|
|
||||||
virtual void prioritizeFiles(const QVector<DownloadPriority> &priorities) = 0;
|
virtual void prioritizeFiles(const QVector<DownloadPriority> &priorities) = 0;
|
||||||
virtual void setRatioLimit(qreal limit) = 0;
|
virtual void setRatioLimit(qreal limit) = 0;
|
||||||
virtual void setSeedingTimeLimit(int limit) = 0;
|
virtual void setSeedingTimeLimit(int limit) = 0;
|
||||||
virtual void setUploadLimit(int limit) = 0;
|
virtual void setUploadLimit(int limit) = 0;
|
||||||
virtual void setDownloadLimit(int limit) = 0;
|
virtual void setDownloadLimit(int limit) = 0;
|
||||||
virtual void setSuperSeeding(bool enable) = 0;
|
virtual void setSuperSeeding(bool enable) = 0;
|
||||||
|
virtual void setDHTDisabled(bool disable) = 0;
|
||||||
|
virtual void setPEXDisabled(bool disable) = 0;
|
||||||
|
virtual void setLSDDisabled(bool disable) = 0;
|
||||||
virtual void flushCache() const = 0;
|
virtual void flushCache() const = 0;
|
||||||
virtual void addTrackers(const QVector<TrackerEntry> &trackers) = 0;
|
virtual void addTrackers(const QVector<TrackerEntry> &trackers) = 0;
|
||||||
virtual void replaceTrackers(const QVector<TrackerEntry> &trackers) = 0;
|
virtual void replaceTrackers(const QVector<TrackerEntry> &trackers) = 0;
|
||||||
@@ -45,6 +45,7 @@
|
|||||||
#include "base/utils/fs.h"
|
#include "base/utils/fs.h"
|
||||||
#include "base/utils/io.h"
|
#include "base/utils/io.h"
|
||||||
#include "base/utils/string.h"
|
#include "base/utils/string.h"
|
||||||
|
#include "base/version.h"
|
||||||
#include "ltunderlyingtype.h"
|
#include "ltunderlyingtype.h"
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -46,7 +46,7 @@
|
|||||||
|
|
||||||
#include "infohash.h"
|
#include "infohash.h"
|
||||||
#include "speedmonitor.h"
|
#include "speedmonitor.h"
|
||||||
#include "torrenthandle.h"
|
#include "torrent.h"
|
||||||
#include "torrentinfo.h"
|
#include "torrentinfo.h"
|
||||||
|
|
||||||
namespace BitTorrent
|
namespace BitTorrent
|
||||||
@@ -69,8 +69,8 @@ namespace BitTorrent
|
|||||||
bool paused = false;
|
bool paused = false;
|
||||||
|
|
||||||
|
|
||||||
qreal ratioLimit = TorrentHandle::USE_GLOBAL_RATIO;
|
qreal ratioLimit = Torrent::USE_GLOBAL_RATIO;
|
||||||
int seedingTimeLimit = TorrentHandle::USE_GLOBAL_SEEDING_TIME;
|
int seedingTimeLimit = Torrent::USE_GLOBAL_SEEDING_TIME;
|
||||||
|
|
||||||
bool restored = false; // is existing torrent job?
|
bool restored = false; // is existing torrent job?
|
||||||
};
|
};
|
||||||
@@ -87,15 +87,15 @@ namespace BitTorrent
|
|||||||
HandleMetadata
|
HandleMetadata
|
||||||
};
|
};
|
||||||
|
|
||||||
class TorrentHandleImpl final : public QObject, public TorrentHandle
|
class TorrentImpl final : public QObject, public Torrent
|
||||||
{
|
{
|
||||||
Q_DISABLE_COPY(TorrentHandleImpl)
|
Q_DISABLE_COPY(TorrentImpl)
|
||||||
Q_DECLARE_TR_FUNCTIONS(BitTorrent::TorrentHandleImpl)
|
Q_DECLARE_TR_FUNCTIONS(BitTorrent::TorrentImpl)
|
||||||
|
|
||||||
public:
|
public:
|
||||||
TorrentHandleImpl(Session *session, lt::session *nativeSession
|
TorrentImpl(Session *session, lt::session *nativeSession
|
||||||
, const lt::torrent_handle &nativeHandle, const LoadTorrentParams ¶ms);
|
, const lt::torrent_handle &nativeHandle, const LoadTorrentParams ¶ms);
|
||||||
~TorrentHandleImpl() override;
|
~TorrentImpl() override;
|
||||||
|
|
||||||
bool isValid() const;
|
bool isValid() const;
|
||||||
|
|
||||||
@@ -191,6 +191,9 @@ namespace BitTorrent
|
|||||||
int downloadLimit() const override;
|
int downloadLimit() const override;
|
||||||
int uploadLimit() const override;
|
int uploadLimit() const override;
|
||||||
bool superSeeding() const override;
|
bool superSeeding() const override;
|
||||||
|
bool isDHTDisabled() const override;
|
||||||
|
bool isPEXDisabled() const override;
|
||||||
|
bool isLSDDisabled() const override;
|
||||||
QVector<PeerInfo> peers() const override;
|
QVector<PeerInfo> peers() const override;
|
||||||
QBitArray pieces() const override;
|
QBitArray pieces() const override;
|
||||||
QBitArray downloadingPieces() const override;
|
QBitArray downloadingPieces() const override;
|
||||||
@@ -217,13 +220,16 @@ namespace BitTorrent
|
|||||||
void forceReannounce(int index = -1) override;
|
void forceReannounce(int index = -1) override;
|
||||||
void forceDHTAnnounce() override;
|
void forceDHTAnnounce() override;
|
||||||
void forceRecheck() override;
|
void forceRecheck() override;
|
||||||
void renameFile(int index, const QString &name) override;
|
void renameFile(int index, const QString &path) override;
|
||||||
void prioritizeFiles(const QVector<DownloadPriority> &priorities) override;
|
void prioritizeFiles(const QVector<DownloadPriority> &priorities) override;
|
||||||
void setRatioLimit(qreal limit) override;
|
void setRatioLimit(qreal limit) override;
|
||||||
void setSeedingTimeLimit(int limit) override;
|
void setSeedingTimeLimit(int limit) override;
|
||||||
void setUploadLimit(int limit) override;
|
void setUploadLimit(int limit) override;
|
||||||
void setDownloadLimit(int limit) override;
|
void setDownloadLimit(int limit) override;
|
||||||
void setSuperSeeding(bool enable) override;
|
void setSuperSeeding(bool enable) override;
|
||||||
|
void setDHTDisabled(bool disable) override;
|
||||||
|
void setPEXDisabled(bool disable) override;
|
||||||
|
void setLSDDisabled(bool disable) override;
|
||||||
void flushCache() const override;
|
void flushCache() const override;
|
||||||
void addTrackers(const QVector<TrackerEntry> &trackers) override;
|
void addTrackers(const QVector<TrackerEntry> &trackers) override;
|
||||||
void replaceTrackers(const QVector<TrackerEntry> &trackers) override;
|
void replaceTrackers(const QVector<TrackerEntry> &trackers) override;
|
||||||
@@ -285,6 +291,7 @@ namespace BitTorrent
|
|||||||
void applyFirstLastPiecePriority(bool enabled, const QVector<DownloadPriority> &updatedFilePrio = {});
|
void applyFirstLastPiecePriority(bool enabled, const QVector<DownloadPriority> &updatedFilePrio = {});
|
||||||
|
|
||||||
void endReceivedMetadataHandling(const QString &savePath, const QStringList &fileNames);
|
void endReceivedMetadataHandling(const QString &savePath, const QStringList &fileNames);
|
||||||
|
void reload();
|
||||||
|
|
||||||
Session *const m_session;
|
Session *const m_session;
|
||||||
lt::session *m_nativeSession;
|
lt::session *m_nativeSession;
|
||||||
@@ -34,6 +34,7 @@
|
|||||||
#include <QtContainerFwd>
|
#include <QtContainerFwd>
|
||||||
|
|
||||||
#include "base/indexrange.h"
|
#include "base/indexrange.h"
|
||||||
|
#include "abstractfilestorage.h"
|
||||||
#include "torrentcontentlayout.h"
|
#include "torrentcontentlayout.h"
|
||||||
|
|
||||||
class QByteArray;
|
class QByteArray;
|
||||||
@@ -46,7 +47,7 @@ namespace BitTorrent
|
|||||||
class InfoHash;
|
class InfoHash;
|
||||||
class TrackerEntry;
|
class TrackerEntry;
|
||||||
|
|
||||||
class TorrentInfo
|
class TorrentInfo final : public AbstractFileStorage
|
||||||
{
|
{
|
||||||
Q_DECLARE_TR_FUNCTIONS(TorrentInfo)
|
Q_DECLARE_TR_FUNCTIONS(TorrentInfo)
|
||||||
|
|
||||||
@@ -68,15 +69,15 @@ namespace BitTorrent
|
|||||||
QString comment() const;
|
QString comment() const;
|
||||||
bool isPrivate() const;
|
bool isPrivate() const;
|
||||||
qlonglong totalSize() const;
|
qlonglong totalSize() const;
|
||||||
int filesCount() const;
|
int filesCount() const override;
|
||||||
int pieceLength() const;
|
int pieceLength() const;
|
||||||
int pieceLength(int index) const;
|
int pieceLength(int index) const;
|
||||||
int piecesCount() const;
|
int piecesCount() const;
|
||||||
QString filePath(int index) const;
|
QString filePath(int index) const override;
|
||||||
QStringList filePaths() const;
|
QStringList filePaths() const;
|
||||||
QString fileName(int index) const;
|
QString fileName(int index) const override;
|
||||||
QString origFilePath(int index) const;
|
QString origFilePath(int index) const;
|
||||||
qlonglong fileSize(int index) const;
|
qlonglong fileSize(int index) const override;
|
||||||
qlonglong fileOffset(int index) const;
|
qlonglong fileOffset(int index) const;
|
||||||
QVector<TrackerEntry> trackers() const;
|
QVector<TrackerEntry> trackers() const;
|
||||||
QVector<QUrl> urlSeeds() const;
|
QVector<QUrl> urlSeeds() const;
|
||||||
@@ -91,7 +92,7 @@ namespace BitTorrent
|
|||||||
PieceRange filePieces(const QString &file) const;
|
PieceRange filePieces(const QString &file) const;
|
||||||
PieceRange filePieces(int fileIndex) const;
|
PieceRange filePieces(int fileIndex) const;
|
||||||
|
|
||||||
void renameFile(int index, const QString &newPath);
|
void renameFile(int index, const QString &newPath) override;
|
||||||
|
|
||||||
QString rootFolder() const;
|
QString rootFolder() const;
|
||||||
bool hasRootFolder() const;
|
bool hasRootFolder() const;
|
||||||
|
|||||||
@@ -37,8 +37,7 @@ class IndexInterval
|
|||||||
public:
|
public:
|
||||||
using IndexType = Index;
|
using IndexType = Index;
|
||||||
|
|
||||||
// TODO: add constexpr when using C++17
|
constexpr IndexInterval(const IndexType first, const IndexType last)
|
||||||
IndexInterval(const IndexType first, const IndexType last)
|
|
||||||
: m_first {first}
|
: m_first {first}
|
||||||
, m_last {last}
|
, m_last {last}
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -34,6 +34,7 @@
|
|||||||
|
|
||||||
#include "base/logger.h"
|
#include "base/logger.h"
|
||||||
#include "base/net/downloadmanager.h"
|
#include "base/net/downloadmanager.h"
|
||||||
|
#include "base/version.h"
|
||||||
|
|
||||||
using namespace Net;
|
using namespace Net;
|
||||||
|
|
||||||
|
|||||||
@@ -64,15 +64,15 @@ ProxyConfigurationManager *ProxyConfigurationManager::m_instance = nullptr;
|
|||||||
ProxyConfigurationManager::ProxyConfigurationManager(QObject *parent)
|
ProxyConfigurationManager::ProxyConfigurationManager(QObject *parent)
|
||||||
: QObject(parent)
|
: QObject(parent)
|
||||||
{
|
{
|
||||||
m_isProxyOnlyForTorrents = settings()->loadValue(KEY_ONLY_FOR_TORRENTS, false).toBool();
|
m_isProxyOnlyForTorrents = settings()->loadValue(KEY_ONLY_FOR_TORRENTS, false);
|
||||||
m_config.type = static_cast<ProxyType>(
|
m_config.type = static_cast<ProxyType>(
|
||||||
settings()->loadValue(KEY_TYPE, static_cast<int>(ProxyType::None)).toInt());
|
settings()->loadValue(KEY_TYPE, static_cast<int>(ProxyType::None)));
|
||||||
if ((m_config.type < ProxyType::None) || (m_config.type > ProxyType::SOCKS4))
|
if ((m_config.type < ProxyType::None) || (m_config.type > ProxyType::SOCKS4))
|
||||||
m_config.type = ProxyType::None;
|
m_config.type = ProxyType::None;
|
||||||
m_config.ip = settings()->loadValue(KEY_IP, "0.0.0.0").toString();
|
m_config.ip = settings()->loadValue<QString>(KEY_IP, "0.0.0.0");
|
||||||
m_config.port = static_cast<ushort>(settings()->loadValue(KEY_PORT, 8080).toUInt());
|
m_config.port = settings()->loadValue<ushort>(KEY_PORT, 8080);
|
||||||
m_config.username = settings()->loadValue(KEY_USERNAME).toString();
|
m_config.username = settings()->loadValue<QString>(KEY_USERNAME);
|
||||||
m_config.password = settings()->loadValue(KEY_PASSWORD).toString();
|
m_config.password = settings()->loadValue<QString>(KEY_PASSWORD);
|
||||||
configureProxy();
|
configureProxy();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1241,26 +1241,6 @@ void Preferences::setMainLastDir(const QString &path)
|
|||||||
setValue("MainWindowLastDir", path);
|
setValue("MainWindowLastDir", path);
|
||||||
}
|
}
|
||||||
|
|
||||||
QSize Preferences::getPrefSize() const
|
|
||||||
{
|
|
||||||
return value("Preferences/State/size").toSize();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Preferences::setPrefSize(const QSize &size)
|
|
||||||
{
|
|
||||||
setValue("Preferences/State/size", size);
|
|
||||||
}
|
|
||||||
|
|
||||||
QStringList Preferences::getPrefHSplitterSizes() const
|
|
||||||
{
|
|
||||||
return value("Preferences/State/hSplitterSizes").toStringList();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Preferences::setPrefHSplitterSizes(const QStringList &sizes)
|
|
||||||
{
|
|
||||||
setValue("Preferences/State/hSplitterSizes", sizes);
|
|
||||||
}
|
|
||||||
|
|
||||||
QByteArray Preferences::getPeerListState() const
|
QByteArray Preferences::getPeerListState() const
|
||||||
{
|
{
|
||||||
return value("TorrentProperties/Peers/qt5/PeerListState").toByteArray();
|
return value("TorrentProperties/Peers/qt5/PeerListState").toByteArray();
|
||||||
|
|||||||
@@ -329,10 +329,6 @@ public:
|
|||||||
void setMainVSplitterState(const QByteArray &state);
|
void setMainVSplitterState(const QByteArray &state);
|
||||||
QString getMainLastDir() const;
|
QString getMainLastDir() const;
|
||||||
void setMainLastDir(const QString &path);
|
void setMainLastDir(const QString &path);
|
||||||
QSize getPrefSize() const;
|
|
||||||
void setPrefSize(const QSize &size);
|
|
||||||
QStringList getPrefHSplitterSizes() const;
|
|
||||||
void setPrefHSplitterSizes(const QStringList &sizes);
|
|
||||||
QByteArray getPeerListState() const;
|
QByteArray getPeerListState() const;
|
||||||
void setPeerListState(const QByteArray &state);
|
void setPeerListState(const QByteArray &state);
|
||||||
QString getPropSplitterSizes() const;
|
QString getPropSplitterSizes() const;
|
||||||
|
|||||||
@@ -83,7 +83,7 @@ QString Private::DefaultProfile::dataLocation() const
|
|||||||
const QString dataDir = QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation)
|
const QString dataDir = QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation)
|
||||||
+ QLatin1Char('/') + profileName() + QLatin1Char('/');
|
+ QLatin1Char('/') + profileName() + QLatin1Char('/');
|
||||||
|
|
||||||
if (QDir(legacyDir).exists())
|
if (!QDir(dataDir).exists() && QDir(legacyDir).exists())
|
||||||
{
|
{
|
||||||
qWarning("The legacy data directory '%s' is used. It is recommended to move its content to '%s'",
|
qWarning("The legacy data directory '%s' is used. It is recommended to move its content to '%s'",
|
||||||
qUtf8Printable(legacyDir), qUtf8Printable(dataDir));
|
qUtf8Printable(legacyDir), qUtf8Printable(dataDir));
|
||||||
|
|||||||
@@ -47,7 +47,6 @@
|
|||||||
#include "../logger.h"
|
#include "../logger.h"
|
||||||
#include "../profile.h"
|
#include "../profile.h"
|
||||||
#include "../settingsstorage.h"
|
#include "../settingsstorage.h"
|
||||||
#include "../tristatebool.h"
|
|
||||||
#include "../utils/fs.h"
|
#include "../utils/fs.h"
|
||||||
#include "rss_article.h"
|
#include "rss_article.h"
|
||||||
#include "rss_autodownloadrule.h"
|
#include "rss_autodownloadrule.h"
|
||||||
@@ -105,7 +104,7 @@ QString computeSmartFilterRegex(const QStringList &filters)
|
|||||||
}
|
}
|
||||||
|
|
||||||
AutoDownloader::AutoDownloader()
|
AutoDownloader::AutoDownloader()
|
||||||
: m_processingEnabled(SettingsStorage::instance()->loadValue(SettingsKey_ProcessingEnabled, false).toBool())
|
: m_processingEnabled(SettingsStorage::instance()->loadValue(SettingsKey_ProcessingEnabled, false))
|
||||||
, m_processingTimer(new QTimer(this))
|
, m_processingTimer(new QTimer(this))
|
||||||
, m_ioThread(new QThread(this))
|
, m_ioThread(new QThread(this))
|
||||||
{
|
{
|
||||||
@@ -290,7 +289,7 @@ void AutoDownloader::importRulesFromLegacyFormat(const QByteArray &data)
|
|||||||
|
|
||||||
QStringList AutoDownloader::smartEpisodeFilters() const
|
QStringList AutoDownloader::smartEpisodeFilters() const
|
||||||
{
|
{
|
||||||
const QVariant filtersSetting = SettingsStorage::instance()->loadValue(SettingsKey_SmartEpisodeFilter);
|
const auto filtersSetting = SettingsStorage::instance()->loadValue<QVariant>(SettingsKey_SmartEpisodeFilter);
|
||||||
|
|
||||||
if (filtersSetting.isNull())
|
if (filtersSetting.isNull())
|
||||||
{
|
{
|
||||||
@@ -323,7 +322,7 @@ void AutoDownloader::setSmartEpisodeFilters(const QStringList &filters)
|
|||||||
|
|
||||||
bool AutoDownloader::downloadRepacks() const
|
bool AutoDownloader::downloadRepacks() const
|
||||||
{
|
{
|
||||||
return SettingsStorage::instance()->loadValue(SettingsKey_DownloadRepacks, true).toBool();
|
return SettingsStorage::instance()->loadValue(SettingsKey_DownloadRepacks, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AutoDownloader::setDownloadRepacks(const bool downloadRepacks)
|
void AutoDownloader::setDownloadRepacks(const bool downloadRepacks)
|
||||||
@@ -398,7 +397,7 @@ void AutoDownloader::processJob(const QSharedPointer<ProcessingJob> &job)
|
|||||||
params.addPaused = rule.addPaused();
|
params.addPaused = rule.addPaused();
|
||||||
params.contentLayout = rule.torrentContentLayout();
|
params.contentLayout = rule.torrentContentLayout();
|
||||||
if (!rule.savePath().isEmpty())
|
if (!rule.savePath().isEmpty())
|
||||||
params.useAutoTMM = TriStateBool::False;
|
params.useAutoTMM = false;
|
||||||
const auto torrentURL = job->articleData.value(Article::KeyTorrentURL).toString();
|
const auto torrentURL = job->articleData.value(Article::KeyTorrentURL).toString();
|
||||||
BitTorrent::Session::instance()->addTorrent(torrentURL, params);
|
BitTorrent::Session::instance()->addTorrent(torrentURL, params);
|
||||||
|
|
||||||
|
|||||||
@@ -42,7 +42,6 @@
|
|||||||
|
|
||||||
#include "base/global.h"
|
#include "base/global.h"
|
||||||
#include "base/preferences.h"
|
#include "base/preferences.h"
|
||||||
#include "base/tristatebool.h"
|
|
||||||
#include "base/utils/fs.h"
|
#include "base/utils/fs.h"
|
||||||
#include "base/utils/string.h"
|
#include "base/utils/string.h"
|
||||||
#include "rss_article.h"
|
#include "rss_article.h"
|
||||||
@@ -51,56 +50,49 @@
|
|||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
TriStateBool jsonValueToTriStateBool(const QJsonValue &jsonVal)
|
std::optional<bool> toOptionalBool(const QJsonValue &jsonVal)
|
||||||
{
|
{
|
||||||
if (jsonVal.isBool())
|
if (jsonVal.isBool())
|
||||||
return TriStateBool(jsonVal.toBool());
|
return jsonVal.toBool();
|
||||||
|
|
||||||
if (!jsonVal.isNull())
|
return std::nullopt;
|
||||||
qDebug() << Q_FUNC_INFO << "Incorrect value" << jsonVal.toVariant();
|
|
||||||
|
|
||||||
return TriStateBool::Undefined;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QJsonValue triStateBoolToJsonValue(const TriStateBool triStateBool)
|
QJsonValue toJsonValue(const std::optional<bool> boolValue)
|
||||||
{
|
{
|
||||||
switch (static_cast<signed char>(triStateBool))
|
return boolValue.has_value() ? *boolValue : QJsonValue {};
|
||||||
{
|
|
||||||
case 0: return false;
|
|
||||||
case 1: return true;
|
|
||||||
default: return {};
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TriStateBool addPausedLegacyToTriStateBool(const int val)
|
std::optional<bool> addPausedLegacyToOptionalBool(const int val)
|
||||||
{
|
{
|
||||||
switch (val)
|
switch (val)
|
||||||
{
|
{
|
||||||
case 1: return TriStateBool::True; // always
|
case 1:
|
||||||
case 2: return TriStateBool::False; // never
|
return true; // always
|
||||||
default: return TriStateBool::Undefined; // default
|
case 2:
|
||||||
|
return false; // never
|
||||||
|
default:
|
||||||
|
return std::nullopt; // default
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int triStateBoolToAddPausedLegacy(const TriStateBool triStateBool)
|
int toAddPausedLegacy(const std::optional<bool> boolValue)
|
||||||
{
|
{
|
||||||
switch (static_cast<signed char>(triStateBool))
|
if (!boolValue.has_value())
|
||||||
{
|
return 0; // default
|
||||||
case 0: return 2; // never
|
|
||||||
case 1: return 1; // always
|
return (*boolValue ? 1 /* always */ : 2 /* never */);
|
||||||
default: return 0; // default
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
boost::optional<BitTorrent::TorrentContentLayout> jsonValueToContentLayout(const QJsonValue &jsonVal)
|
std::optional<BitTorrent::TorrentContentLayout> jsonValueToContentLayout(const QJsonValue &jsonVal)
|
||||||
{
|
{
|
||||||
const QString str = jsonVal.toString();
|
const QString str = jsonVal.toString();
|
||||||
if (str.isEmpty())
|
if (str.isEmpty())
|
||||||
return {};
|
return std::nullopt;
|
||||||
return Utils::String::toEnum(str, BitTorrent::TorrentContentLayout::Original);
|
return Utils::String::toEnum(str, BitTorrent::TorrentContentLayout::Original);
|
||||||
}
|
}
|
||||||
|
|
||||||
QJsonValue contentLayoutToJsonValue(const boost::optional<BitTorrent::TorrentContentLayout> contentLayout)
|
QJsonValue contentLayoutToJsonValue(const std::optional<BitTorrent::TorrentContentLayout> contentLayout)
|
||||||
{
|
{
|
||||||
if (!contentLayout)
|
if (!contentLayout)
|
||||||
return {};
|
return {};
|
||||||
@@ -142,8 +134,8 @@ namespace RSS
|
|||||||
|
|
||||||
QString savePath;
|
QString savePath;
|
||||||
QString category;
|
QString category;
|
||||||
TriStateBool addPaused = TriStateBool::Undefined;
|
std::optional<bool> addPaused;
|
||||||
boost::optional<BitTorrent::TorrentContentLayout> contentLayout;
|
std::optional<BitTorrent::TorrentContentLayout> contentLayout;
|
||||||
|
|
||||||
bool smartFilter = false;
|
bool smartFilter = false;
|
||||||
QStringList previouslyMatchedEpisodes;
|
QStringList previouslyMatchedEpisodes;
|
||||||
@@ -477,7 +469,7 @@ QJsonObject AutoDownloadRule::toJsonObject() const
|
|||||||
, {Str_AssignedCategory, assignedCategory()}
|
, {Str_AssignedCategory, assignedCategory()}
|
||||||
, {Str_LastMatch, lastMatch().toString(Qt::RFC2822Date)}
|
, {Str_LastMatch, lastMatch().toString(Qt::RFC2822Date)}
|
||||||
, {Str_IgnoreDays, ignoreDays()}
|
, {Str_IgnoreDays, ignoreDays()}
|
||||||
, {Str_AddPaused, triStateBoolToJsonValue(addPaused())}
|
, {Str_AddPaused, toJsonValue(addPaused())}
|
||||||
, {Str_ContentLayout, contentLayoutToJsonValue(torrentContentLayout())}
|
, {Str_ContentLayout, contentLayoutToJsonValue(torrentContentLayout())}
|
||||||
, {Str_SmartFilter, useSmartFilter()}
|
, {Str_SmartFilter, useSmartFilter()}
|
||||||
, {Str_PreviouslyMatched, QJsonArray::fromStringList(previouslyMatchedEpisodes())}};
|
, {Str_PreviouslyMatched, QJsonArray::fromStringList(previouslyMatchedEpisodes())}};
|
||||||
@@ -494,7 +486,7 @@ AutoDownloadRule AutoDownloadRule::fromJsonObject(const QJsonObject &jsonObj, co
|
|||||||
rule.setEnabled(jsonObj.value(Str_Enabled).toBool(true));
|
rule.setEnabled(jsonObj.value(Str_Enabled).toBool(true));
|
||||||
rule.setSavePath(jsonObj.value(Str_SavePath).toString());
|
rule.setSavePath(jsonObj.value(Str_SavePath).toString());
|
||||||
rule.setCategory(jsonObj.value(Str_AssignedCategory).toString());
|
rule.setCategory(jsonObj.value(Str_AssignedCategory).toString());
|
||||||
rule.setAddPaused(jsonValueToTriStateBool(jsonObj.value(Str_AddPaused)));
|
rule.setAddPaused(toOptionalBool(jsonObj.value(Str_AddPaused)));
|
||||||
|
|
||||||
// TODO: The following code is deprecated. Replace with the commented one after several releases in 4.4.x.
|
// TODO: The following code is deprecated. Replace with the commented one after several releases in 4.4.x.
|
||||||
// === BEGIN DEPRECATED CODE === //
|
// === BEGIN DEPRECATED CODE === //
|
||||||
@@ -504,12 +496,14 @@ AutoDownloadRule AutoDownloadRule::fromJsonObject(const QJsonObject &jsonObj, co
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
const TriStateBool createSubfolder = jsonValueToTriStateBool(jsonObj.value(Str_CreateSubfolder));
|
const std::optional<bool> createSubfolder = toOptionalBool(jsonObj.value(Str_CreateSubfolder));
|
||||||
boost::optional<BitTorrent::TorrentContentLayout> contentLayout;
|
std::optional<BitTorrent::TorrentContentLayout> contentLayout;
|
||||||
if (createSubfolder == TriStateBool::True)
|
if (createSubfolder.has_value())
|
||||||
contentLayout = BitTorrent::TorrentContentLayout::Original;
|
{
|
||||||
else if (createSubfolder == TriStateBool::False)
|
contentLayout = (*createSubfolder
|
||||||
contentLayout = BitTorrent::TorrentContentLayout::NoSubfolder;
|
? BitTorrent::TorrentContentLayout::Original
|
||||||
|
: BitTorrent::TorrentContentLayout::NoSubfolder);
|
||||||
|
}
|
||||||
|
|
||||||
rule.setTorrentContentLayout(contentLayout);
|
rule.setTorrentContentLayout(contentLayout);
|
||||||
}
|
}
|
||||||
@@ -556,7 +550,7 @@ QVariantHash AutoDownloadRule::toLegacyDict() const
|
|||||||
{"enabled", isEnabled()},
|
{"enabled", isEnabled()},
|
||||||
{"category_assigned", assignedCategory()},
|
{"category_assigned", assignedCategory()},
|
||||||
{"use_regex", useRegex()},
|
{"use_regex", useRegex()},
|
||||||
{"add_paused", triStateBoolToAddPausedLegacy(addPaused())},
|
{"add_paused", toAddPausedLegacy(addPaused())},
|
||||||
{"episode_filter", episodeFilter()},
|
{"episode_filter", episodeFilter()},
|
||||||
{"last_match", lastMatch()},
|
{"last_match", lastMatch()},
|
||||||
{"ignore_days", ignoreDays()}};
|
{"ignore_days", ignoreDays()}};
|
||||||
@@ -574,7 +568,7 @@ AutoDownloadRule AutoDownloadRule::fromLegacyDict(const QVariantHash &dict)
|
|||||||
rule.setEnabled(dict.value("enabled", false).toBool());
|
rule.setEnabled(dict.value("enabled", false).toBool());
|
||||||
rule.setSavePath(dict.value("save_path").toString());
|
rule.setSavePath(dict.value("save_path").toString());
|
||||||
rule.setCategory(dict.value("category_assigned").toString());
|
rule.setCategory(dict.value("category_assigned").toString());
|
||||||
rule.setAddPaused(addPausedLegacyToTriStateBool(dict.value("add_paused").toInt()));
|
rule.setAddPaused(addPausedLegacyToOptionalBool(dict.value("add_paused").toInt()));
|
||||||
rule.setLastMatch(dict.value("last_match").toDateTime());
|
rule.setLastMatch(dict.value("last_match").toDateTime());
|
||||||
rule.setIgnoreDays(dict.value("ignore_days").toInt());
|
rule.setIgnoreDays(dict.value("ignore_days").toInt());
|
||||||
|
|
||||||
@@ -639,22 +633,22 @@ void AutoDownloadRule::setSavePath(const QString &savePath)
|
|||||||
m_dataPtr->savePath = Utils::Fs::toUniformPath(savePath);
|
m_dataPtr->savePath = Utils::Fs::toUniformPath(savePath);
|
||||||
}
|
}
|
||||||
|
|
||||||
TriStateBool AutoDownloadRule::addPaused() const
|
std::optional<bool> AutoDownloadRule::addPaused() const
|
||||||
{
|
{
|
||||||
return m_dataPtr->addPaused;
|
return m_dataPtr->addPaused;
|
||||||
}
|
}
|
||||||
|
|
||||||
void AutoDownloadRule::setAddPaused(const TriStateBool addPaused)
|
void AutoDownloadRule::setAddPaused(const std::optional<bool> addPaused)
|
||||||
{
|
{
|
||||||
m_dataPtr->addPaused = addPaused;
|
m_dataPtr->addPaused = addPaused;
|
||||||
}
|
}
|
||||||
|
|
||||||
boost::optional<BitTorrent::TorrentContentLayout> AutoDownloadRule::torrentContentLayout() const
|
std::optional<BitTorrent::TorrentContentLayout> AutoDownloadRule::torrentContentLayout() const
|
||||||
{
|
{
|
||||||
return m_dataPtr->contentLayout;
|
return m_dataPtr->contentLayout;
|
||||||
}
|
}
|
||||||
|
|
||||||
void AutoDownloadRule::setTorrentContentLayout(const boost::optional<BitTorrent::TorrentContentLayout> contentLayout)
|
void AutoDownloadRule::setTorrentContentLayout(const std::optional<BitTorrent::TorrentContentLayout> contentLayout)
|
||||||
{
|
{
|
||||||
m_dataPtr->contentLayout = contentLayout;
|
m_dataPtr->contentLayout = contentLayout;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,7 +29,7 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <boost/optional.hpp>
|
#include <optional>
|
||||||
|
|
||||||
#include <QSharedDataPointer>
|
#include <QSharedDataPointer>
|
||||||
#include <QVariant>
|
#include <QVariant>
|
||||||
@@ -40,8 +40,6 @@ class QDateTime;
|
|||||||
class QJsonObject;
|
class QJsonObject;
|
||||||
class QRegularExpression;
|
class QRegularExpression;
|
||||||
|
|
||||||
class TriStateBool;
|
|
||||||
|
|
||||||
namespace RSS
|
namespace RSS
|
||||||
{
|
{
|
||||||
struct AutoDownloadRuleData;
|
struct AutoDownloadRuleData;
|
||||||
@@ -81,10 +79,10 @@ namespace RSS
|
|||||||
|
|
||||||
QString savePath() const;
|
QString savePath() const;
|
||||||
void setSavePath(const QString &savePath);
|
void setSavePath(const QString &savePath);
|
||||||
TriStateBool addPaused() const;
|
std::optional<bool> addPaused() const;
|
||||||
void setAddPaused(TriStateBool addPaused);
|
void setAddPaused(std::optional<bool> addPaused);
|
||||||
boost::optional<BitTorrent::TorrentContentLayout> torrentContentLayout() const;
|
std::optional<BitTorrent::TorrentContentLayout> torrentContentLayout() const;
|
||||||
void setTorrentContentLayout(boost::optional<BitTorrent::TorrentContentLayout> contentLayout);
|
void setTorrentContentLayout(std::optional<BitTorrent::TorrentContentLayout> contentLayout);
|
||||||
QString assignedCategory() const;
|
QString assignedCategory() const;
|
||||||
void setCategory(const QString &category);
|
void setCategory(const QString &category);
|
||||||
|
|
||||||
|
|||||||
@@ -63,10 +63,10 @@ using namespace RSS;
|
|||||||
QPointer<Session> Session::m_instance = nullptr;
|
QPointer<Session> Session::m_instance = nullptr;
|
||||||
|
|
||||||
Session::Session()
|
Session::Session()
|
||||||
: m_processingEnabled(SettingsStorage::instance()->loadValue(SettingsKey_ProcessingEnabled, false).toBool())
|
: m_processingEnabled(SettingsStorage::instance()->loadValue(SettingsKey_ProcessingEnabled, false))
|
||||||
, m_workingThread(new QThread(this))
|
, m_workingThread(new QThread(this))
|
||||||
, m_refreshInterval(SettingsStorage::instance()->loadValue(SettingsKey_RefreshInterval, 30).toInt())
|
, m_refreshInterval(SettingsStorage::instance()->loadValue(SettingsKey_RefreshInterval, 30))
|
||||||
, m_maxArticlesPerFeed(SettingsStorage::instance()->loadValue(SettingsKey_MaxArticlesPerFeed, 50).toInt())
|
, m_maxArticlesPerFeed(SettingsStorage::instance()->loadValue(SettingsKey_MaxArticlesPerFeed, 50))
|
||||||
{
|
{
|
||||||
Q_ASSERT(!m_instance); // only one instance is allowed
|
Q_ASSERT(!m_instance); // only one instance is allowed
|
||||||
m_instance = this;
|
m_instance = this;
|
||||||
@@ -362,8 +362,8 @@ void Session::loadFolder(const QJsonObject &jsonObj, Folder *folder)
|
|||||||
|
|
||||||
void Session::loadLegacy()
|
void Session::loadLegacy()
|
||||||
{
|
{
|
||||||
const QStringList legacyFeedPaths = SettingsStorage::instance()->loadValue("Rss/streamList").toStringList();
|
const auto legacyFeedPaths = SettingsStorage::instance()->loadValue<QStringList>("Rss/streamList");
|
||||||
const QStringList feedAliases = SettingsStorage::instance()->loadValue("Rss/streamAlias").toStringList();
|
const auto feedAliases = SettingsStorage::instance()->loadValue<QStringList>("Rss/streamAlias");
|
||||||
if (legacyFeedPaths.size() != feedAliases.size())
|
if (legacyFeedPaths.size() != feedAliases.size())
|
||||||
{
|
{
|
||||||
Logger::instance()->addMessage("Corrupted RSS list, not loading it.", Log::WARNING);
|
Logger::instance()->addMessage("Corrupted RSS list, not loading it.", Log::WARNING);
|
||||||
|
|||||||
@@ -366,12 +366,12 @@ void ScanFoldersModel::addTorrentsToSession(const QStringList &pathList)
|
|||||||
if (downloadInWatchFolder(file))
|
if (downloadInWatchFolder(file))
|
||||||
{
|
{
|
||||||
params.savePath = QFileInfo(file).dir().path();
|
params.savePath = QFileInfo(file).dir().path();
|
||||||
params.useAutoTMM = TriStateBool::False;
|
params.useAutoTMM = false;
|
||||||
}
|
}
|
||||||
else if (!downloadInDefaultFolder(file))
|
else if (!downloadInDefaultFolder(file))
|
||||||
{
|
{
|
||||||
params.savePath = downloadPathTorrentFolder(file);
|
params.savePath = downloadPathTorrentFolder(file);
|
||||||
params.useAutoTMM = TriStateBool::False;
|
params.useAutoTMM = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (file.endsWith(".magnet", Qt::CaseInsensitive))
|
if (file.endsWith(".magnet", Qt::CaseInsensitive))
|
||||||
|
|||||||
@@ -153,8 +153,7 @@ namespace
|
|||||||
SettingsStorage *SettingsStorage::m_instance = nullptr;
|
SettingsStorage *SettingsStorage::m_instance = nullptr;
|
||||||
|
|
||||||
SettingsStorage::SettingsStorage()
|
SettingsStorage::SettingsStorage()
|
||||||
: m_data{TransactionalSettings(QLatin1String("qBittorrent")).read()}
|
: m_data {TransactionalSettings(QLatin1String("qBittorrent")).read()}
|
||||||
, m_dirty(false)
|
|
||||||
{
|
{
|
||||||
m_timer.setSingleShot(true);
|
m_timer.setSingleShot(true);
|
||||||
m_timer.setInterval(5 * 1000);
|
m_timer.setInterval(5 * 1000);
|
||||||
@@ -200,14 +199,14 @@ bool SettingsStorage::save()
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
QVariant SettingsStorage::loadValue(const QString &key, const QVariant &defaultValue) const
|
QVariant SettingsStorage::loadValueImpl(const QString &key, const QVariant &defaultValue) const
|
||||||
{
|
{
|
||||||
const QString realKey = mapKey(key);
|
const QString realKey = mapKey(key);
|
||||||
const QReadLocker locker(&m_lock);
|
const QReadLocker locker(&m_lock);
|
||||||
return m_data.value(realKey, defaultValue);
|
return m_data.value(realKey, defaultValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SettingsStorage::storeValue(const QString &key, const QVariant &value)
|
void SettingsStorage::storeValueImpl(const QString &key, const QVariant &value)
|
||||||
{
|
{
|
||||||
const QString realKey = mapKey(key);
|
const QString realKey = mapKey(key);
|
||||||
const QWriteLocker locker(&m_lock);
|
const QWriteLocker locker(&m_lock);
|
||||||
@@ -295,7 +294,11 @@ QString TransactionalSettings::deserialize(const QString &name, QVariantHash &da
|
|||||||
// or that we don't touch directly in this code (eg disabled by ifdef). This ensures
|
// or that we don't touch directly in this code (eg disabled by ifdef). This ensures
|
||||||
// that they will be copied over when save our settings to disk.
|
// that they will be copied over when save our settings to disk.
|
||||||
for (const QString &key : asConst(settings->allKeys()))
|
for (const QString &key : asConst(settings->allKeys()))
|
||||||
data.insert(key, settings->value(key));
|
{
|
||||||
|
const QVariant value = settings->value(key);
|
||||||
|
if (value.isValid())
|
||||||
|
data[key] = value;
|
||||||
|
}
|
||||||
|
|
||||||
return settings->fileName();
|
return settings->fileName();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,11 +29,15 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <type_traits>
|
||||||
|
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
#include <QReadWriteLock>
|
#include <QReadWriteLock>
|
||||||
#include <QTimer>
|
#include <QTimer>
|
||||||
#include <QVariantHash>
|
#include <QVariantHash>
|
||||||
|
|
||||||
|
#include "utils/string.h"
|
||||||
|
|
||||||
class SettingsStorage : public QObject
|
class SettingsStorage : public QObject
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
@@ -45,18 +49,48 @@ public:
|
|||||||
static void freeInstance();
|
static void freeInstance();
|
||||||
static SettingsStorage *instance();
|
static SettingsStorage *instance();
|
||||||
|
|
||||||
QVariant loadValue(const QString &key, const QVariant &defaultValue = {}) const;
|
template <typename T>
|
||||||
void storeValue(const QString &key, const QVariant &value);
|
T loadValue(const QString &key, const T &defaultValue = {}) const
|
||||||
|
{
|
||||||
|
if constexpr (std::is_enum_v<T>)
|
||||||
|
{
|
||||||
|
const auto value = loadValueImpl(key).toString();
|
||||||
|
return Utils::String::toEnum(value, defaultValue);
|
||||||
|
}
|
||||||
|
else if constexpr (std::is_same_v<T, QVariant>)
|
||||||
|
{
|
||||||
|
return loadValueImpl(key, defaultValue);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
const QVariant value = loadValueImpl(key);
|
||||||
|
// check if retrieved value is convertible to T
|
||||||
|
return value.template canConvert<T>() ? value.template value<T>() : defaultValue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
void storeValue(const QString &key, const T &value)
|
||||||
|
{
|
||||||
|
if constexpr (std::is_enum_v<T>)
|
||||||
|
storeValueImpl(key, Utils::String::fromEnum(value));
|
||||||
|
else
|
||||||
|
storeValueImpl(key, value);
|
||||||
|
}
|
||||||
|
|
||||||
void removeValue(const QString &key);
|
void removeValue(const QString &key);
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
bool save();
|
bool save();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
QVariant loadValueImpl(const QString &key, const QVariant &defaultValue = {}) const;
|
||||||
|
void storeValueImpl(const QString &key, const QVariant &value);
|
||||||
|
|
||||||
static SettingsStorage *m_instance;
|
static SettingsStorage *m_instance;
|
||||||
|
|
||||||
|
bool m_dirty = false;
|
||||||
QVariantHash m_data;
|
QVariantHash m_data;
|
||||||
bool m_dirty;
|
|
||||||
QTimer m_timer;
|
QTimer m_timer;
|
||||||
mutable QReadWriteLock m_lock;
|
mutable QReadWriteLock m_lock;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -28,82 +28,81 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <type_traits>
|
|
||||||
|
|
||||||
#include <QMetaEnum>
|
|
||||||
#include <QString>
|
#include <QString>
|
||||||
|
|
||||||
#include "settingsstorage.h"
|
#include "settingsstorage.h"
|
||||||
#include "utils/string.h"
|
|
||||||
|
// This is a thin/handy wrapper over `SettingsStorage`. Use it when store/load value
|
||||||
|
// rarely occurs, otherwise use `CachedSettingValue`.
|
||||||
|
template <typename T>
|
||||||
|
class SettingValue
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
explicit SettingValue(const char *keyName)
|
||||||
|
: m_keyName {QLatin1String {keyName}}
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
T get(const T &defaultValue = {}) const
|
||||||
|
{
|
||||||
|
return SettingsStorage::instance()->loadValue(m_keyName, defaultValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
operator T() const
|
||||||
|
{
|
||||||
|
return get();
|
||||||
|
}
|
||||||
|
|
||||||
|
SettingValue<T> &operator=(const T &value)
|
||||||
|
{
|
||||||
|
SettingsStorage::instance()->storeValue(m_keyName, value);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
const QString m_keyName;
|
||||||
|
};
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
class CachedSettingValue
|
class CachedSettingValue
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
explicit CachedSettingValue(const char *keyName, const T &defaultValue = T())
|
explicit CachedSettingValue(const char *keyName, const T &defaultValue = {})
|
||||||
: m_keyName(QLatin1String(keyName))
|
: m_setting {keyName}
|
||||||
, m_value(loadValue(defaultValue))
|
, m_cache {m_setting.get(defaultValue)}
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
// The signature of the ProxyFunc should be equivalent to the following:
|
// The signature of the ProxyFunc should be equivalent to the following:
|
||||||
// T proxyFunc(const T &a);
|
// T proxyFunc(const T &a);
|
||||||
template <typename ProxyFunc>
|
template <typename ProxyFunc>
|
||||||
explicit CachedSettingValue(const char *keyName, const T &defaultValue
|
explicit CachedSettingValue(const char *keyName, const T &defaultValue, ProxyFunc &&proxyFunc)
|
||||||
, ProxyFunc &&proxyFunc)
|
: m_setting {keyName}
|
||||||
: m_keyName(QLatin1String(keyName))
|
, m_cache {proxyFunc(m_setting.get(defaultValue))}
|
||||||
, m_value(proxyFunc(loadValue(defaultValue)))
|
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
T value() const
|
T get() const
|
||||||
{
|
{
|
||||||
return m_value;
|
return m_cache;
|
||||||
}
|
}
|
||||||
|
|
||||||
operator T() const
|
operator T() const
|
||||||
{
|
{
|
||||||
return value();
|
return get();
|
||||||
}
|
}
|
||||||
|
|
||||||
CachedSettingValue<T> &operator=(const T &newValue)
|
CachedSettingValue<T> &operator=(const T &value)
|
||||||
{
|
{
|
||||||
if (m_value == newValue)
|
if (m_cache == value)
|
||||||
return *this;
|
return *this;
|
||||||
|
|
||||||
m_value = newValue;
|
m_setting = value;
|
||||||
storeValue(m_value);
|
m_cache = value;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// regular load/save pair
|
SettingValue<T> m_setting;
|
||||||
template <typename U, typename std::enable_if_t<!std::is_enum<U>::value, int> = 0>
|
T m_cache;
|
||||||
U loadValue(const U &defaultValue)
|
|
||||||
{
|
|
||||||
return SettingsStorage::instance()->loadValue(m_keyName, defaultValue).template value<T>();
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename U, typename std::enable_if_t<!std::is_enum<U>::value, int> = 0>
|
|
||||||
void storeValue(const U &value)
|
|
||||||
{
|
|
||||||
SettingsStorage::instance()->storeValue(m_keyName, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
// load/save pair for an enum
|
|
||||||
// saves literal value of the enum constant, obtained from QMetaEnum
|
|
||||||
template <typename U, typename std::enable_if_t<std::is_enum<U>::value, int> = 0>
|
|
||||||
U loadValue(const U &defaultValue)
|
|
||||||
{
|
|
||||||
return Utils::String::toEnum(SettingsStorage::instance()->loadValue(m_keyName).toString(), defaultValue);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename U, typename std::enable_if_t<std::is_enum<U>::value, int> = 0>
|
|
||||||
void storeValue(const U &value)
|
|
||||||
{
|
|
||||||
SettingsStorage::instance()->storeValue(m_keyName, Utils::String::fromEnum(value));
|
|
||||||
}
|
|
||||||
|
|
||||||
const QString m_keyName;
|
|
||||||
T m_value;
|
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -73,7 +73,7 @@ void TorrentFileGuard::markAsAddedToSession()
|
|||||||
|
|
||||||
TorrentFileGuard::AutoDeleteMode TorrentFileGuard::autoDeleteMode()
|
TorrentFileGuard::AutoDeleteMode TorrentFileGuard::autoDeleteMode()
|
||||||
{
|
{
|
||||||
return autoDeleteModeSetting();
|
return autoDeleteModeSetting().get(AutoDeleteMode::Never);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TorrentFileGuard::setAutoDeleteMode(TorrentFileGuard::AutoDeleteMode mode)
|
void TorrentFileGuard::setAutoDeleteMode(TorrentFileGuard::AutoDeleteMode mode)
|
||||||
@@ -81,8 +81,8 @@ void TorrentFileGuard::setAutoDeleteMode(TorrentFileGuard::AutoDeleteMode mode)
|
|||||||
autoDeleteModeSetting() = mode;
|
autoDeleteModeSetting() = mode;
|
||||||
}
|
}
|
||||||
|
|
||||||
CachedSettingValue<TorrentFileGuard::AutoDeleteMode> &TorrentFileGuard::autoDeleteModeSetting()
|
SettingValue<TorrentFileGuard::AutoDeleteMode> &TorrentFileGuard::autoDeleteModeSetting()
|
||||||
{
|
{
|
||||||
static CachedSettingValue<AutoDeleteMode> setting("Core/AutoDeleteAddedTorrentFile", AutoDeleteMode::Never);
|
static SettingValue<AutoDeleteMode> setting {"Core/AutoDeleteAddedTorrentFile"};
|
||||||
return setting;
|
return setting;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -31,7 +31,7 @@
|
|||||||
#include <QObject>
|
#include <QObject>
|
||||||
#include <QString>
|
#include <QString>
|
||||||
|
|
||||||
template <typename T> class CachedSettingValue;
|
template <typename T> class SettingValue;
|
||||||
|
|
||||||
/// Utility class to defer file deletion
|
/// Utility class to defer file deletion
|
||||||
class FileGuard
|
class FileGuard
|
||||||
@@ -75,7 +75,7 @@ public:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
TorrentFileGuard(const QString &path, AutoDeleteMode mode);
|
TorrentFileGuard(const QString &path, AutoDeleteMode mode);
|
||||||
static CachedSettingValue<AutoDeleteMode> &autoDeleteModeSetting();
|
static SettingValue<AutoDeleteMode> &autoDeleteModeSetting();
|
||||||
|
|
||||||
Q_ENUM(AutoDeleteMode)
|
Q_ENUM(AutoDeleteMode)
|
||||||
AutoDeleteMode m_mode;
|
AutoDeleteMode m_mode;
|
||||||
|
|||||||
@@ -29,7 +29,7 @@
|
|||||||
#include "torrentfilter.h"
|
#include "torrentfilter.h"
|
||||||
|
|
||||||
#include "bittorrent/infohash.h"
|
#include "bittorrent/infohash.h"
|
||||||
#include "bittorrent/torrenthandle.h"
|
#include "bittorrent/torrent.h"
|
||||||
|
|
||||||
const QString TorrentFilter::AnyCategory;
|
const QString TorrentFilter::AnyCategory;
|
||||||
const InfoHashSet TorrentFilter::AnyHash {{}};
|
const InfoHashSet TorrentFilter::AnyHash {{}};
|
||||||
@@ -47,7 +47,7 @@ const TorrentFilter TorrentFilter::StalledUploadingTorrent(TorrentFilter::Stalle
|
|||||||
const TorrentFilter TorrentFilter::StalledDownloadingTorrent(TorrentFilter::StalledDownloading);
|
const TorrentFilter TorrentFilter::StalledDownloadingTorrent(TorrentFilter::StalledDownloading);
|
||||||
const TorrentFilter TorrentFilter::ErroredTorrent(TorrentFilter::Errored);
|
const TorrentFilter TorrentFilter::ErroredTorrent(TorrentFilter::Errored);
|
||||||
|
|
||||||
using BitTorrent::TorrentHandle;
|
using BitTorrent::Torrent;
|
||||||
|
|
||||||
TorrentFilter::TorrentFilter(const Type type, const InfoHashSet &hashSet, const QString &category, const QString &tag)
|
TorrentFilter::TorrentFilter(const Type type, const InfoHashSet &hashSet, const QString &category, const QString &tag)
|
||||||
: m_type(type)
|
: m_type(type)
|
||||||
@@ -146,14 +146,14 @@ bool TorrentFilter::setTag(const QString &tag)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TorrentFilter::match(const TorrentHandle *const torrent) const
|
bool TorrentFilter::match(const Torrent *const torrent) const
|
||||||
{
|
{
|
||||||
if (!torrent) return false;
|
if (!torrent) return false;
|
||||||
|
|
||||||
return (matchState(torrent) && matchHash(torrent) && matchCategory(torrent) && matchTag(torrent));
|
return (matchState(torrent) && matchHash(torrent) && matchCategory(torrent) && matchTag(torrent));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TorrentFilter::matchState(const BitTorrent::TorrentHandle *const torrent) const
|
bool TorrentFilter::matchState(const BitTorrent::Torrent *const torrent) const
|
||||||
{
|
{
|
||||||
switch (m_type)
|
switch (m_type)
|
||||||
{
|
{
|
||||||
@@ -187,21 +187,21 @@ bool TorrentFilter::matchState(const BitTorrent::TorrentHandle *const torrent) c
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TorrentFilter::matchHash(const BitTorrent::TorrentHandle *const torrent) const
|
bool TorrentFilter::matchHash(const BitTorrent::Torrent *const torrent) const
|
||||||
{
|
{
|
||||||
if (m_hashSet == AnyHash) return true;
|
if (m_hashSet == AnyHash) return true;
|
||||||
|
|
||||||
return m_hashSet.contains(torrent->hash());
|
return m_hashSet.contains(torrent->hash());
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TorrentFilter::matchCategory(const BitTorrent::TorrentHandle *const torrent) const
|
bool TorrentFilter::matchCategory(const BitTorrent::Torrent *const torrent) const
|
||||||
{
|
{
|
||||||
if (m_category.isNull()) return true;
|
if (m_category.isNull()) return true;
|
||||||
|
|
||||||
return (torrent->belongsToCategory(m_category));
|
return (torrent->belongsToCategory(m_category));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TorrentFilter::matchTag(const BitTorrent::TorrentHandle *const torrent) const
|
bool TorrentFilter::matchTag(const BitTorrent::Torrent *const torrent) const
|
||||||
{
|
{
|
||||||
// Empty tag is a special value to indicate we're filtering for untagged torrents.
|
// Empty tag is a special value to indicate we're filtering for untagged torrents.
|
||||||
if (m_tag.isNull()) return true;
|
if (m_tag.isNull()) return true;
|
||||||
|
|||||||
@@ -35,7 +35,7 @@
|
|||||||
|
|
||||||
namespace BitTorrent
|
namespace BitTorrent
|
||||||
{
|
{
|
||||||
class TorrentHandle;
|
class Torrent;
|
||||||
}
|
}
|
||||||
|
|
||||||
using InfoHashSet = QSet<BitTorrent::InfoHash>;
|
using InfoHashSet = QSet<BitTorrent::InfoHash>;
|
||||||
@@ -88,13 +88,13 @@ public:
|
|||||||
bool setCategory(const QString &category);
|
bool setCategory(const QString &category);
|
||||||
bool setTag(const QString &tag);
|
bool setTag(const QString &tag);
|
||||||
|
|
||||||
bool match(const BitTorrent::TorrentHandle *torrent) const;
|
bool match(const BitTorrent::Torrent *torrent) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool matchState(const BitTorrent::TorrentHandle *torrent) const;
|
bool matchState(const BitTorrent::Torrent *torrent) const;
|
||||||
bool matchHash(const BitTorrent::TorrentHandle *torrent) const;
|
bool matchHash(const BitTorrent::Torrent *torrent) const;
|
||||||
bool matchCategory(const BitTorrent::TorrentHandle *torrent) const;
|
bool matchCategory(const BitTorrent::Torrent *torrent) const;
|
||||||
bool matchTag(const BitTorrent::TorrentHandle *torrent) const;
|
bool matchTag(const BitTorrent::Torrent *torrent) const;
|
||||||
|
|
||||||
Type m_type {All};
|
Type m_type {All};
|
||||||
QString m_category;
|
QString m_category;
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
/*
|
/*
|
||||||
* Bittorrent Client using Qt and libtorrent.
|
* Bittorrent Client using Qt and libtorrent.
|
||||||
* Copyright (C) 2015 Mike Tzou
|
* Copyright (C) 2015 Mike Tzou
|
||||||
*
|
*
|
||||||
@@ -28,16 +28,12 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
// This file must be encoded in "UTF-8 with BOM"
|
|
||||||
#ifdef _MSC_VER
|
|
||||||
#pragma execution_character_set("utf-8")
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Because of the poor handling of UTF-8 characters in MSVC (emits warning C4819),
|
// Because of the poor handling of UTF-8 characters in MSVC (emits warning C4819),
|
||||||
// we put all problematic UTF-8 chars/strings in this file.
|
// we put all problematic UTF-8 chars/strings in this file.
|
||||||
// See issue #3059 for more details (https://github.com/qbittorrent/qBittorrent/issues/3059).
|
// See issue #3059 for more details (https://github.com/qbittorrent/qBittorrent/issues/3059).
|
||||||
|
|
||||||
const char C_COPYRIGHT[] = "©";
|
const char C_COPYRIGHT[] = "©";
|
||||||
|
const char C_INEQUALITY[] = "≠";
|
||||||
const char C_INFINITY[] = "∞";
|
const char C_INFINITY[] = "∞";
|
||||||
const char C_NON_BREAKING_SPACE[] = " ";
|
const char C_NON_BREAKING_SPACE[] = " ";
|
||||||
const char C_THIN_SPACE[] = " ";
|
const char C_THIN_SPACE[] = " ";
|
||||||
@@ -45,6 +41,7 @@ const char C_UTP[] = "μTP";
|
|||||||
|
|
||||||
const char C_LOCALE_ARABIC[] = "عربي";
|
const char C_LOCALE_ARABIC[] = "عربي";
|
||||||
const char C_LOCALE_ARMENIAN[] = "Հայերեն";
|
const char C_LOCALE_ARMENIAN[] = "Հայերեն";
|
||||||
|
const char C_LOCALE_AZERBAIJANI[] = "Azərbaycan dili";
|
||||||
const char C_LOCALE_BASQUE[] = "Euskara";
|
const char C_LOCALE_BASQUE[] = "Euskara";
|
||||||
const char C_LOCALE_BULGARIAN[] = "Български";
|
const char C_LOCALE_BULGARIAN[] = "Български";
|
||||||
const char C_LOCALE_BYELORUSSIAN[] = "Беларуская";
|
const char C_LOCALE_BYELORUSSIAN[] = "Беларуская";
|
||||||
@@ -57,9 +54,10 @@ const char C_LOCALE_CZECH[] = "Čeština";
|
|||||||
const char C_LOCALE_DANISH[] = "Dansk";
|
const char C_LOCALE_DANISH[] = "Dansk";
|
||||||
const char C_LOCALE_DUTCH[] = "Nederlands";
|
const char C_LOCALE_DUTCH[] = "Nederlands";
|
||||||
const char C_LOCALE_ENGLISH[] = "English";
|
const char C_LOCALE_ENGLISH[] = "English";
|
||||||
const char C_LOCALE_ENGLISH_AUSTRALIA[] = "English(Australia)";
|
const char C_LOCALE_ENGLISH_AUSTRALIA[] = "English (Australia)";
|
||||||
const char C_LOCALE_ENGLISH_UNITEDKINGDOM[] = "English(United Kingdom)";
|
const char C_LOCALE_ENGLISH_UNITEDKINGDOM[] = "English (United Kingdom)";
|
||||||
const char C_LOCALE_ESPERANTO[] = "Esperanto";
|
const char C_LOCALE_ESPERANTO[] = "Esperanto";
|
||||||
|
const char C_LOCALE_ESTONIAN[] = "Eesti, eesti keel";
|
||||||
const char C_LOCALE_FINNISH[] = "Suomi";
|
const char C_LOCALE_FINNISH[] = "Suomi";
|
||||||
const char C_LOCALE_FRENCH[] = "Français";
|
const char C_LOCALE_FRENCH[] = "Français";
|
||||||
const char C_LOCALE_GALICIAN[] = "Galego";
|
const char C_LOCALE_GALICIAN[] = "Galego";
|
||||||
@@ -74,8 +72,8 @@ const char C_LOCALE_INDONESIAN[] = "Bahasa Indonesia";
|
|||||||
const char C_LOCALE_ITALIAN[] = "Italiano";
|
const char C_LOCALE_ITALIAN[] = "Italiano";
|
||||||
const char C_LOCALE_JAPANESE[] = "日本語";
|
const char C_LOCALE_JAPANESE[] = "日本語";
|
||||||
const char C_LOCALE_KOREAN[] = "한글";
|
const char C_LOCALE_KOREAN[] = "한글";
|
||||||
const char C_LOCALE_LATGALIAN[] = "latgalīšu volūda";
|
const char C_LOCALE_LATGALIAN[] = "Latgalīšu volūda";
|
||||||
const char C_LOCALE_LATVIAN[] = "latviešu valoda";
|
const char C_LOCALE_LATVIAN[] = "Latviešu valoda";
|
||||||
const char C_LOCALE_LITHUANIAN[] = "Lietuvių";
|
const char C_LOCALE_LITHUANIAN[] = "Lietuvių";
|
||||||
const char C_LOCALE_MALAY[] = "بهاس ملايو";
|
const char C_LOCALE_MALAY[] = "بهاس ملايو";
|
||||||
const char C_LOCALE_NORWEGIAN[] = "Norsk";
|
const char C_LOCALE_NORWEGIAN[] = "Norsk";
|
||||||
@@ -93,4 +91,4 @@ const char C_LOCALE_SWEDISH[] = "Svenska";
|
|||||||
const char C_LOCALE_TURKISH[] = "Türkçe";
|
const char C_LOCALE_TURKISH[] = "Türkçe";
|
||||||
const char C_LOCALE_UKRAINIAN[] = "Українська";
|
const char C_LOCALE_UKRAINIAN[] = "Українська";
|
||||||
const char C_LOCALE_UZBEK[] = "أۇزبېك";
|
const char C_LOCALE_UZBEK[] = "أۇزبېك";
|
||||||
const char C_LOCALE_VIETNAMESE[] = "tiếng Việt";
|
const char C_LOCALE_VIETNAMESE[] = "Tiếng Việt";
|
||||||
|
|||||||
@@ -33,15 +33,12 @@
|
|||||||
|
|
||||||
class QByteArray;
|
class QByteArray;
|
||||||
|
|
||||||
namespace Utils
|
namespace Utils::ByteArray
|
||||||
{
|
{
|
||||||
namespace ByteArray
|
// Mimic QString::splitRef(sep, behavior)
|
||||||
{
|
QVector<QByteArray> splitToViews(const QByteArray &in, const QByteArray &sep, const QString::SplitBehavior behavior = QString::KeepEmptyParts);
|
||||||
// Mimic QString::splitRef(sep, behavior)
|
|
||||||
QVector<QByteArray> splitToViews(const QByteArray &in, const QByteArray &sep, const QString::SplitBehavior behavior = QString::KeepEmptyParts);
|
|
||||||
|
|
||||||
// Mimic QByteArray::mid(pos, len) but instead of returning a full-copy,
|
// Mimic QByteArray::mid(pos, len) but instead of returning a full-copy,
|
||||||
// we only return a partial view
|
// we only return a partial view
|
||||||
const QByteArray midView(const QByteArray &in, int pos, int len = -1);
|
const QByteArray midView(const QByteArray &in, int pos, int len = -1);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -33,21 +33,18 @@
|
|||||||
|
|
||||||
#include "base/utils/version.h"
|
#include "base/utils/version.h"
|
||||||
|
|
||||||
namespace Utils
|
namespace Utils::ForeignApps
|
||||||
{
|
{
|
||||||
namespace ForeignApps
|
struct PythonInfo
|
||||||
{
|
{
|
||||||
struct PythonInfo
|
using Version = Utils::Version<quint8, 3, 1>;
|
||||||
{
|
|
||||||
using Version = Utils::Version<quint8, 3, 1>;
|
|
||||||
|
|
||||||
bool isValid() const;
|
bool isValid() const;
|
||||||
bool isSupportedVersion() const;
|
bool isSupportedVersion() const;
|
||||||
|
|
||||||
QString executableName;
|
QString executableName;
|
||||||
Version version;
|
Version version;
|
||||||
};
|
};
|
||||||
|
|
||||||
PythonInfo pythonInfo();
|
PythonInfo pythonInfo();
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -55,6 +55,7 @@
|
|||||||
#include <QDirIterator>
|
#include <QDirIterator>
|
||||||
#include <QFile>
|
#include <QFile>
|
||||||
#include <QFileInfo>
|
#include <QFileInfo>
|
||||||
|
#include <QMimeDatabase>
|
||||||
#include <QStorageInfo>
|
#include <QStorageInfo>
|
||||||
#include <QRegularExpression>
|
#include <QRegularExpression>
|
||||||
|
|
||||||
@@ -76,9 +77,14 @@ QString Utils::Fs::toUniformPath(const QString &path)
|
|||||||
*/
|
*/
|
||||||
QString Utils::Fs::fileExtension(const QString &filename)
|
QString Utils::Fs::fileExtension(const QString &filename)
|
||||||
{
|
{
|
||||||
const QString ext = QString(filename).remove(QB_EXT);
|
const QString name = filename.endsWith(QB_EXT)
|
||||||
const int pointIndex = ext.lastIndexOf('.');
|
#if (QT_VERSION >= QT_VERSION_CHECK(5, 10, 0))
|
||||||
return (pointIndex >= 0) ? ext.mid(pointIndex + 1) : QString();
|
? filename.chopped(QB_EXT.length())
|
||||||
|
#else
|
||||||
|
? filename.left(filename.length() - QB_EXT.length())
|
||||||
|
#endif
|
||||||
|
: filename;
|
||||||
|
return QMimeDatabase().suffixForFileName(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
QString Utils::Fs::fileName(const QString &filePath)
|
QString Utils::Fs::fileName(const QString &filePath)
|
||||||
@@ -95,7 +101,7 @@ QString Utils::Fs::folderName(const QString &filePath)
|
|||||||
const QString path = toUniformPath(filePath);
|
const QString path = toUniformPath(filePath);
|
||||||
const int slashIndex = path.lastIndexOf('/');
|
const int slashIndex = path.lastIndexOf('/');
|
||||||
if (slashIndex == -1)
|
if (slashIndex == -1)
|
||||||
return path;
|
return {};
|
||||||
return path.left(slashIndex);
|
return path.left(slashIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -267,8 +273,6 @@ bool Utils::Fs::isValidFileSystemName(const QString &name, const bool allowSepar
|
|||||||
|
|
||||||
qint64 Utils::Fs::freeDiskSpaceOnPath(const QString &path)
|
qint64 Utils::Fs::freeDiskSpaceOnPath(const QString &path)
|
||||||
{
|
{
|
||||||
if (path.isEmpty()) return -1;
|
|
||||||
|
|
||||||
return QStorageInfo(path).bytesAvailable();
|
return QStorageInfo(path).bytesAvailable();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -34,47 +34,44 @@
|
|||||||
|
|
||||||
#include <QString>
|
#include <QString>
|
||||||
|
|
||||||
namespace Utils
|
namespace Utils::Fs
|
||||||
{
|
{
|
||||||
namespace Fs
|
/**
|
||||||
{
|
* Converts a path to a string suitable for display.
|
||||||
/**
|
* This function makes sure the directory separator used is consistent
|
||||||
* Converts a path to a string suitable for display.
|
* with the OS being run.
|
||||||
* This function makes sure the directory separator used is consistent
|
*/
|
||||||
* with the OS being run.
|
QString toNativePath(const QString &path);
|
||||||
*/
|
/**
|
||||||
QString toNativePath(const QString &path);
|
* Converts a path to a string suitable for processing.
|
||||||
/**
|
* This function makes sure the directory separator used is independent
|
||||||
* Converts a path to a string suitable for processing.
|
* from the OS being run so it is the same on all supported platforms.
|
||||||
* This function makes sure the directory separator used is independent
|
* Slash ('/') is used as "uniform" directory separator.
|
||||||
* from the OS being run so it is the same on all supported platforms.
|
*/
|
||||||
* Slash ('/') is used as "uniform" directory separator.
|
QString toUniformPath(const QString &path);
|
||||||
*/
|
|
||||||
QString toUniformPath(const QString &path);
|
|
||||||
|
|
||||||
QString fileExtension(const QString &filename);
|
QString fileExtension(const QString &filename);
|
||||||
QString fileName(const QString &filePath);
|
QString fileName(const QString &filePath);
|
||||||
QString folderName(const QString &filePath);
|
QString folderName(const QString &filePath);
|
||||||
qint64 computePathSize(const QString &path);
|
qint64 computePathSize(const QString &path);
|
||||||
bool sameFiles(const QString &path1, const QString &path2);
|
bool sameFiles(const QString &path1, const QString &path2);
|
||||||
QString toValidFileSystemName(const QString &name, bool allowSeparators = false
|
QString toValidFileSystemName(const QString &name, bool allowSeparators = false
|
||||||
, const QString &pad = QLatin1String(" "));
|
, const QString &pad = QLatin1String(" "));
|
||||||
bool isValidFileSystemName(const QString &name, bool allowSeparators = false);
|
bool isValidFileSystemName(const QString &name, bool allowSeparators = false);
|
||||||
qint64 freeDiskSpaceOnPath(const QString &path);
|
qint64 freeDiskSpaceOnPath(const QString &path);
|
||||||
QString branchPath(const QString &filePath, QString *removed = nullptr);
|
QString branchPath(const QString &filePath, QString *removed = nullptr);
|
||||||
bool sameFileNames(const QString &first, const QString &second);
|
bool sameFileNames(const QString &first, const QString &second);
|
||||||
QString expandPath(const QString &path);
|
QString expandPath(const QString &path);
|
||||||
QString expandPathAbs(const QString &path);
|
QString expandPathAbs(const QString &path);
|
||||||
bool isRegularFile(const QString &path);
|
bool isRegularFile(const QString &path);
|
||||||
|
|
||||||
bool smartRemoveEmptyFolderTree(const QString &path);
|
bool smartRemoveEmptyFolderTree(const QString &path);
|
||||||
bool forceRemove(const QString &filePath);
|
bool forceRemove(const QString &filePath);
|
||||||
void removeDirRecursive(const QString &path);
|
void removeDirRecursive(const QString &path);
|
||||||
|
|
||||||
QString tempPath();
|
QString tempPath();
|
||||||
|
|
||||||
#if !defined Q_OS_HAIKU
|
#if !defined Q_OS_HAIKU
|
||||||
bool isNetworkFileSystem(const QString &path);
|
bool isNetworkFileSystem(const QString &path);
|
||||||
#endif
|
#endif
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -31,11 +31,8 @@
|
|||||||
|
|
||||||
class QByteArray;
|
class QByteArray;
|
||||||
|
|
||||||
namespace Utils
|
namespace Utils::Gzip
|
||||||
{
|
{
|
||||||
namespace Gzip
|
QByteArray compress(const QByteArray &data, int level = 6, bool *ok = nullptr);
|
||||||
{
|
QByteArray decompress(const QByteArray &data, bool *ok = nullptr);
|
||||||
QByteArray compress(const QByteArray &data, int level = 6, bool *ok = nullptr);
|
|
||||||
QByteArray decompress(const QByteArray &data, bool *ok = nullptr);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -60,18 +60,3 @@ Utils::IO::FileDeviceOutputIterator &Utils::IO::FileDeviceOutputIterator::operat
|
|||||||
}
|
}
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
Utils::IO::FileDeviceOutputIterator &Utils::IO::FileDeviceOutputIterator::operator*()
|
|
||||||
{
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
Utils::IO::FileDeviceOutputIterator &Utils::IO::FileDeviceOutputIterator::operator++()
|
|
||||||
{
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
Utils::IO::FileDeviceOutputIterator &Utils::IO::FileDeviceOutputIterator::operator++(int)
|
|
||||||
{
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -34,30 +34,44 @@
|
|||||||
class QByteArray;
|
class QByteArray;
|
||||||
class QFileDevice;
|
class QFileDevice;
|
||||||
|
|
||||||
namespace Utils
|
namespace Utils::IO
|
||||||
{
|
{
|
||||||
namespace IO
|
// A wrapper class that satisfy LegacyOutputIterator requirement
|
||||||
|
class FileDeviceOutputIterator
|
||||||
{
|
{
|
||||||
// A wrapper class that satisfy LegacyOutputIterator requirement
|
public:
|
||||||
class FileDeviceOutputIterator
|
// std::iterator_traits
|
||||||
: public std::iterator<std::output_iterator_tag, void, void, void, void>
|
using iterator_category = std::output_iterator_tag;
|
||||||
|
using difference_type = void;
|
||||||
|
using value_type = void;
|
||||||
|
using pointer = void;
|
||||||
|
using reference = void;
|
||||||
|
|
||||||
|
explicit FileDeviceOutputIterator(QFileDevice &device, const int bufferSize = (4 * 1024));
|
||||||
|
FileDeviceOutputIterator(const FileDeviceOutputIterator &other) = default;
|
||||||
|
~FileDeviceOutputIterator();
|
||||||
|
|
||||||
|
// mimic std::ostream_iterator behavior
|
||||||
|
FileDeviceOutputIterator &operator=(char c);
|
||||||
|
|
||||||
|
constexpr FileDeviceOutputIterator &operator*()
|
||||||
{
|
{
|
||||||
public:
|
return *this;
|
||||||
explicit FileDeviceOutputIterator(QFileDevice &device, const int bufferSize = (4 * 1024));
|
}
|
||||||
FileDeviceOutputIterator(const FileDeviceOutputIterator &other) = default;
|
|
||||||
~FileDeviceOutputIterator();
|
|
||||||
|
|
||||||
// mimic std::ostream_iterator behavior
|
constexpr FileDeviceOutputIterator &operator++()
|
||||||
FileDeviceOutputIterator &operator=(char c);
|
{
|
||||||
// TODO: make these `constexpr` in C++17
|
return *this;
|
||||||
FileDeviceOutputIterator &operator*();
|
}
|
||||||
FileDeviceOutputIterator &operator++();
|
|
||||||
FileDeviceOutputIterator &operator++(int);
|
|
||||||
|
|
||||||
private:
|
constexpr FileDeviceOutputIterator &operator++(int)
|
||||||
QFileDevice *m_device;
|
{
|
||||||
std::shared_ptr<QByteArray> m_buffer;
|
return *this;
|
||||||
int m_bufferSize;
|
}
|
||||||
};
|
|
||||||
}
|
private:
|
||||||
|
QFileDevice *m_device;
|
||||||
|
std::shared_ptr<QByteArray> m_buffer;
|
||||||
|
int m_bufferSize;
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -41,69 +41,66 @@ enum class ShutdownDialogAction;
|
|||||||
|
|
||||||
/* Miscellaneous functions that can be useful */
|
/* Miscellaneous functions that can be useful */
|
||||||
|
|
||||||
namespace Utils
|
namespace Utils::Misc
|
||||||
{
|
{
|
||||||
namespace Misc
|
// use binary prefix standards from IEC 60027-2
|
||||||
|
// see http://en.wikipedia.org/wiki/Kilobyte
|
||||||
|
enum class SizeUnit
|
||||||
{
|
{
|
||||||
// use binary prefix standards from IEC 60027-2
|
Byte, // 1024^0,
|
||||||
// see http://en.wikipedia.org/wiki/Kilobyte
|
KibiByte, // 1024^1,
|
||||||
enum class SizeUnit
|
MebiByte, // 1024^2,
|
||||||
{
|
GibiByte, // 1024^3,
|
||||||
Byte, // 1024^0,
|
TebiByte, // 1024^4,
|
||||||
KibiByte, // 1024^1,
|
PebiByte, // 1024^5,
|
||||||
MebiByte, // 1024^2,
|
ExbiByte // 1024^6,
|
||||||
GibiByte, // 1024^3,
|
// int64 is used for sizes and thus the next units can not be handled
|
||||||
TebiByte, // 1024^4,
|
// ZebiByte, // 1024^7,
|
||||||
PebiByte, // 1024^5,
|
// YobiByte, // 1024^8
|
||||||
ExbiByte // 1024^6,
|
};
|
||||||
// int64 is used for sizes and thus the next units can not be handled
|
|
||||||
// ZebiByte, // 1024^7,
|
|
||||||
// YobiByte, // 1024^8
|
|
||||||
};
|
|
||||||
|
|
||||||
QString parseHtmlLinks(const QString &rawText);
|
QString parseHtmlLinks(const QString &rawText);
|
||||||
|
|
||||||
void shutdownComputer(const ShutdownDialogAction &action);
|
void shutdownComputer(const ShutdownDialogAction &action);
|
||||||
|
|
||||||
QString osName();
|
QString osName();
|
||||||
QString boostVersionString();
|
QString boostVersionString();
|
||||||
QString libtorrentVersionString();
|
QString libtorrentVersionString();
|
||||||
QString opensslVersionString();
|
QString opensslVersionString();
|
||||||
QString zlibVersionString();
|
QString zlibVersionString();
|
||||||
|
|
||||||
QString unitString(SizeUnit unit, bool isSpeed = false);
|
QString unitString(SizeUnit unit, bool isSpeed = false);
|
||||||
|
|
||||||
// return the best user friendly storage unit (B, KiB, MiB, GiB, TiB)
|
// return the best user friendly storage unit (B, KiB, MiB, GiB, TiB)
|
||||||
// value must be given in bytes
|
// value must be given in bytes
|
||||||
QString friendlyUnit(qint64 bytesValue, bool isSpeed = false);
|
QString friendlyUnit(qint64 bytesValue, bool isSpeed = false);
|
||||||
int friendlyUnitPrecision(SizeUnit unit);
|
int friendlyUnitPrecision(SizeUnit unit);
|
||||||
qint64 sizeInBytes(qreal size, SizeUnit unit);
|
qint64 sizeInBytes(qreal size, SizeUnit unit);
|
||||||
|
|
||||||
bool isPreviewable(const QString &extension);
|
bool isPreviewable(const QString &extension);
|
||||||
|
|
||||||
// Take a number of seconds and return a user-friendly
|
// Take a number of seconds and return a user-friendly
|
||||||
// time duration like "1d 2h 10m".
|
// time duration like "1d 2h 10m".
|
||||||
QString userFriendlyDuration(qlonglong seconds, qlonglong maxCap = -1);
|
QString userFriendlyDuration(qlonglong seconds, qlonglong maxCap = -1);
|
||||||
QString getUserIDString();
|
QString getUserIDString();
|
||||||
|
|
||||||
#ifdef Q_OS_WIN
|
#ifdef Q_OS_WIN
|
||||||
QString windowsSystemPath();
|
QString windowsSystemPath();
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
T loadWinAPI(const QString &source, const char *funcName)
|
T loadWinAPI(const QString &source, const char *funcName)
|
||||||
{
|
{
|
||||||
QString path = windowsSystemPath();
|
QString path = windowsSystemPath();
|
||||||
if (!path.endsWith('\\'))
|
if (!path.endsWith('\\'))
|
||||||
path += '\\';
|
path += '\\';
|
||||||
|
|
||||||
path += source;
|
path += source;
|
||||||
|
|
||||||
auto pathWchar = std::make_unique<wchar_t[]>(path.length() + 1);
|
auto pathWchar = std::make_unique<wchar_t[]>(path.length() + 1);
|
||||||
path.toWCharArray(pathWchar.get());
|
path.toWCharArray(pathWchar.get());
|
||||||
|
|
||||||
return reinterpret_cast<T>(
|
return reinterpret_cast<T>(
|
||||||
::GetProcAddress(::LoadLibraryW(pathWchar.get()), funcName));
|
::GetProcAddress(::LoadLibraryW(pathWchar.get()), funcName));
|
||||||
}
|
|
||||||
#endif // Q_OS_WIN
|
|
||||||
}
|
}
|
||||||
|
#endif // Q_OS_WIN
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -35,24 +35,21 @@ class QSslCertificate;
|
|||||||
class QSslKey;
|
class QSslKey;
|
||||||
class QString;
|
class QString;
|
||||||
|
|
||||||
namespace Utils
|
namespace Utils::Net
|
||||||
{
|
{
|
||||||
namespace Net
|
using Subnet = QPair<QHostAddress, int>;
|
||||||
{
|
|
||||||
using Subnet = QPair<QHostAddress, int>;
|
|
||||||
|
|
||||||
bool isValidIP(const QString &ip);
|
bool isValidIP(const QString &ip);
|
||||||
Subnet parseSubnet(const QString &subnetStr, bool *ok = nullptr);
|
Subnet parseSubnet(const QString &subnetStr, bool *ok = nullptr);
|
||||||
bool canParseSubnet(const QString &subnetStr);
|
bool canParseSubnet(const QString &subnetStr);
|
||||||
bool isLoopbackAddress(const QHostAddress &addr);
|
bool isLoopbackAddress(const QHostAddress &addr);
|
||||||
bool isIPInRange(const QHostAddress &addr, const QVector<Subnet> &subnets);
|
bool isIPInRange(const QHostAddress &addr, const QVector<Subnet> &subnets);
|
||||||
QString subnetToString(const Subnet &subnet);
|
QString subnetToString(const Subnet &subnet);
|
||||||
QHostAddress canonicalIPv6Addr(const QHostAddress &addr);
|
QHostAddress canonicalIPv6Addr(const QHostAddress &addr);
|
||||||
|
|
||||||
const int MAX_SSL_FILE_SIZE = 1024 * 1024;
|
const int MAX_SSL_FILE_SIZE = 1024 * 1024;
|
||||||
QList<QSslCertificate> loadSSLCertificate(const QByteArray &data);
|
QList<QSslCertificate> loadSSLCertificate(const QByteArray &data);
|
||||||
bool isSSLCertificatesValid(const QByteArray &data);
|
bool isSSLCertificatesValid(const QByteArray &data);
|
||||||
QSslKey loadSSLKey(const QByteArray &data);
|
QSslKey loadSSLKey(const QByteArray &data);
|
||||||
bool isSSLKeyValid(const QByteArray &data);
|
bool isSSLKeyValid(const QByteArray &data);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -31,21 +31,18 @@
|
|||||||
class QByteArray;
|
class QByteArray;
|
||||||
class QString;
|
class QString;
|
||||||
|
|
||||||
namespace Utils
|
namespace Utils::Password
|
||||||
{
|
{
|
||||||
namespace Password
|
// Implements constant-time comparison to protect against timing attacks
|
||||||
|
// Taken from https://crackstation.net/hashing-security.htm
|
||||||
|
bool slowEquals(const QByteArray &a, const QByteArray &b);
|
||||||
|
|
||||||
|
namespace PBKDF2
|
||||||
{
|
{
|
||||||
// Implements constant-time comparison to protect against timing attacks
|
QByteArray generate(const QString &password);
|
||||||
// Taken from https://crackstation.net/hashing-security.htm
|
QByteArray generate(const QByteArray &password);
|
||||||
bool slowEquals(const QByteArray &a, const QByteArray &b);
|
|
||||||
|
|
||||||
namespace PBKDF2
|
bool verify(const QByteArray &secret, const QString &password);
|
||||||
{
|
bool verify(const QByteArray &secret, const QByteArray &password);
|
||||||
QByteArray generate(const QString &password);
|
|
||||||
QByteArray generate(const QByteArray &password);
|
|
||||||
|
|
||||||
bool verify(const QByteArray &secret, const QString &password);
|
|
||||||
bool verify(const QByteArray &secret, const QByteArray &password);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -31,10 +31,7 @@
|
|||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <limits>
|
#include <limits>
|
||||||
|
|
||||||
namespace Utils
|
namespace Utils::Random
|
||||||
{
|
{
|
||||||
namespace Random
|
uint32_t rand(uint32_t min = 0, uint32_t max = std::numeric_limits<uint32_t>::max());
|
||||||
{
|
|
||||||
uint32_t rand(uint32_t min = 0, uint32_t max = std::numeric_limits<uint32_t>::max());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -42,8 +42,6 @@
|
|||||||
#include <QThreadStorage>
|
#include <QThreadStorage>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "base/tristatebool.h"
|
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
class NaturalCompare
|
class NaturalCompare
|
||||||
@@ -192,20 +190,14 @@ QString Utils::String::wildcardToRegex(const QString &pattern)
|
|||||||
return qt_regexp_toCanonical(pattern, QRegExp::Wildcard);
|
return qt_regexp_toCanonical(pattern, QRegExp::Wildcard);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Utils::String::parseBool(const QString &string, const bool defaultValue)
|
std::optional<bool> Utils::String::parseBool(const QString &string)
|
||||||
{
|
|
||||||
if (defaultValue)
|
|
||||||
return (string.compare("false", Qt::CaseInsensitive) == 0) ? false : true;
|
|
||||||
return (string.compare("true", Qt::CaseInsensitive) == 0) ? true : false;
|
|
||||||
}
|
|
||||||
|
|
||||||
TriStateBool Utils::String::parseTriStateBool(const QString &string)
|
|
||||||
{
|
{
|
||||||
if (string.compare("true", Qt::CaseInsensitive) == 0)
|
if (string.compare("true", Qt::CaseInsensitive) == 0)
|
||||||
return TriStateBool::True;
|
return true;
|
||||||
if (string.compare("false", Qt::CaseInsensitive) == 0)
|
if (string.compare("false", Qt::CaseInsensitive) == 0)
|
||||||
return TriStateBool::False;
|
return false;
|
||||||
return TriStateBool::Undefined;
|
|
||||||
|
return std::nullopt;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString Utils::String::join(const QVector<QStringRef> &strings, const QString &separator)
|
QString Utils::String::join(const QVector<QStringRef> &strings, const QString &separator)
|
||||||
|
|||||||
@@ -29,6 +29,8 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <optional>
|
||||||
|
|
||||||
#include <QChar>
|
#include <QChar>
|
||||||
#include <QMetaEnum>
|
#include <QMetaEnum>
|
||||||
#include <QString>
|
#include <QString>
|
||||||
@@ -37,62 +39,56 @@
|
|||||||
|
|
||||||
class QStringRef;
|
class QStringRef;
|
||||||
|
|
||||||
class TriStateBool;
|
namespace Utils::String
|
||||||
|
|
||||||
namespace Utils
|
|
||||||
{
|
{
|
||||||
namespace String
|
QString fromDouble(double n, int precision);
|
||||||
|
|
||||||
|
int naturalCompare(const QString &left, const QString &right, const Qt::CaseSensitivity caseSensitivity);
|
||||||
|
template <Qt::CaseSensitivity caseSensitivity>
|
||||||
|
bool naturalLessThan(const QString &left, const QString &right)
|
||||||
{
|
{
|
||||||
QString fromDouble(double n, int precision);
|
return (naturalCompare(left, right, caseSensitivity) < 0);
|
||||||
|
}
|
||||||
|
|
||||||
int naturalCompare(const QString &left, const QString &right, const Qt::CaseSensitivity caseSensitivity);
|
QString wildcardToRegex(const QString &pattern);
|
||||||
template <Qt::CaseSensitivity caseSensitivity>
|
|
||||||
bool naturalLessThan(const QString &left, const QString &right)
|
template <typename T>
|
||||||
|
T unquote(const T &str, const QString "es = QChar('"'))
|
||||||
|
{
|
||||||
|
if (str.length() < 2) return str;
|
||||||
|
|
||||||
|
for (const QChar quote : quotes)
|
||||||
{
|
{
|
||||||
return (naturalCompare(left, right, caseSensitivity) < 0);
|
if (str.startsWith(quote) && str.endsWith(quote))
|
||||||
|
return str.mid(1, (str.length() - 2));
|
||||||
}
|
}
|
||||||
|
|
||||||
QString wildcardToRegex(const QString &pattern);
|
return str;
|
||||||
|
}
|
||||||
|
|
||||||
template <typename T>
|
std::optional<bool> parseBool(const QString &string);
|
||||||
T unquote(const T &str, const QString "es = QChar('"'))
|
|
||||||
{
|
|
||||||
if (str.length() < 2) return str;
|
|
||||||
|
|
||||||
for (const QChar quote : quotes)
|
QString join(const QVector<QStringRef> &strings, const QString &separator);
|
||||||
{
|
|
||||||
if (str.startsWith(quote) && str.endsWith(quote))
|
|
||||||
return str.mid(1, (str.length() - 2));
|
|
||||||
}
|
|
||||||
|
|
||||||
return str;
|
template <typename T, typename std::enable_if_t<std::is_enum_v<T>, int> = 0>
|
||||||
}
|
QString fromEnum(const T &value)
|
||||||
|
{
|
||||||
|
static_assert(std::is_same_v<int, typename std::underlying_type_t<T>>,
|
||||||
|
"Enumeration underlying type has to be int.");
|
||||||
|
|
||||||
bool parseBool(const QString &string, bool defaultValue);
|
const auto metaEnum = QMetaEnum::fromType<T>();
|
||||||
TriStateBool parseTriStateBool(const QString &string);
|
return QString::fromLatin1(metaEnum.valueToKey(static_cast<int>(value)));
|
||||||
|
}
|
||||||
|
|
||||||
QString join(const QVector<QStringRef> &strings, const QString &separator);
|
template <typename T, typename std::enable_if_t<std::is_enum_v<T>, int> = 0>
|
||||||
|
T toEnum(const QString &serializedValue, const T &defaultValue)
|
||||||
|
{
|
||||||
|
static_assert(std::is_same_v<int, typename std::underlying_type_t<T>>,
|
||||||
|
"Enumeration underlying type has to be int.");
|
||||||
|
|
||||||
template <typename T, typename std::enable_if_t<std::is_enum<T>::value, int> = 0>
|
const auto metaEnum = QMetaEnum::fromType<T>();
|
||||||
QString fromEnum(const T &value)
|
bool ok = false;
|
||||||
{
|
const T value = static_cast<T>(metaEnum.keyToValue(serializedValue.toLatin1().constData(), &ok));
|
||||||
static_assert(std::is_same<int, typename std::underlying_type_t<T>>::value,
|
return (ok ? value : defaultValue);
|
||||||
"Enumeration underlying type has to be int.");
|
|
||||||
|
|
||||||
const auto metaEnum = QMetaEnum::fromType<T>();
|
|
||||||
return QString::fromLatin1(metaEnum.valueToKey(static_cast<int>(value)));
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T, typename std::enable_if_t<std::is_enum<T>::value, int> = 0>
|
|
||||||
T toEnum(const QString &serializedValue, const T &defaultValue)
|
|
||||||
{
|
|
||||||
static_assert(std::is_same<int, typename std::underlying_type_t<T>>::value,
|
|
||||||
"Enumeration underlying type has to be int.");
|
|
||||||
|
|
||||||
const auto metaEnum = QMetaEnum::fromType<T>();
|
|
||||||
bool ok = false;
|
|
||||||
const T value = static_cast<T>(metaEnum.keyToValue(serializedValue.toLatin1().constData(), &ok));
|
|
||||||
return (ok ? value : defaultValue);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Bittorrent Client using Qt and libtorrent.
|
* Bittorrent Client using Qt and libtorrent.
|
||||||
* Copyright (C) 2015 Vladimir Golovnev <glassez@yandex.ru>
|
* Copyright (C) 2021 Mike Tzou (Chocobo1)
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License
|
* modify it under the terms of the GNU General Public License
|
||||||
@@ -26,8 +26,22 @@
|
|||||||
* exception statement from your version.
|
* exception statement from your version.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "tristatebool.h"
|
#pragma once
|
||||||
|
|
||||||
const TriStateBool TriStateBool::Undefined(-1);
|
#define QBT_VERSION_MAJOR 4
|
||||||
const TriStateBool TriStateBool::False(0);
|
#define QBT_VERSION_MINOR 3
|
||||||
const TriStateBool TriStateBool::True(1);
|
#define QBT_VERSION_BUGFIX 3
|
||||||
|
#define QBT_VERSION_BUILD 0
|
||||||
|
#define QBT_VERSION_STATUS "" // Should be empty for stable releases!
|
||||||
|
|
||||||
|
#define QBT__STRINGIFY(x) #x
|
||||||
|
#define QBT_STRINGIFY(x) QBT__STRINGIFY(x)
|
||||||
|
|
||||||
|
#if (QBT_VERSION_BUILD != 0)
|
||||||
|
#define PROJECT_VERSION QBT_STRINGIFY(QBT_VERSION_MAJOR.QBT_VERSION_MINOR.QBT_VERSION_BUGFIX.QBT_VERSION_BUILD) QBT_VERSION_STATUS
|
||||||
|
#else
|
||||||
|
#define PROJECT_VERSION QBT_STRINGIFY(QBT_VERSION_MAJOR.QBT_VERSION_MINOR.QBT_VERSION_BUGFIX) QBT_VERSION_STATUS
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define QBT_VERSION "v" PROJECT_VERSION
|
||||||
|
#define QBT_VERSION_2 PROJECT_VERSION
|
||||||
@@ -67,6 +67,7 @@ add_library(qbt_gui STATIC
|
|||||||
torrentcontentmodelitem.h
|
torrentcontentmodelitem.h
|
||||||
torrentcontenttreeview.h
|
torrentcontenttreeview.h
|
||||||
torrentcreatordialog.h
|
torrentcreatordialog.h
|
||||||
|
torrentoptionsdialog.h
|
||||||
trackerentriesdialog.h
|
trackerentriesdialog.h
|
||||||
transferlistdelegate.h
|
transferlistdelegate.h
|
||||||
transferlistfilterswidget.h
|
transferlistfilterswidget.h
|
||||||
@@ -76,7 +77,6 @@ add_library(qbt_gui STATIC
|
|||||||
tristateaction.h
|
tristateaction.h
|
||||||
tristatewidget.h
|
tristatewidget.h
|
||||||
uithememanager.h
|
uithememanager.h
|
||||||
updownratiodialog.h
|
|
||||||
utils.h
|
utils.h
|
||||||
|
|
||||||
# sources
|
# sources
|
||||||
@@ -147,6 +147,7 @@ add_library(qbt_gui STATIC
|
|||||||
torrentcontentmodelitem.cpp
|
torrentcontentmodelitem.cpp
|
||||||
torrentcontenttreeview.cpp
|
torrentcontenttreeview.cpp
|
||||||
torrentcreatordialog.cpp
|
torrentcreatordialog.cpp
|
||||||
|
torrentoptionsdialog.cpp
|
||||||
trackerentriesdialog.cpp
|
trackerentriesdialog.cpp
|
||||||
transferlistdelegate.cpp
|
transferlistdelegate.cpp
|
||||||
transferlistfilterswidget.cpp
|
transferlistfilterswidget.cpp
|
||||||
@@ -156,7 +157,6 @@ add_library(qbt_gui STATIC
|
|||||||
tristateaction.cpp
|
tristateaction.cpp
|
||||||
tristatewidget.cpp
|
tristatewidget.cpp
|
||||||
uithememanager.cpp
|
uithememanager.cpp
|
||||||
updownratiodialog.cpp
|
|
||||||
utils.cpp
|
utils.cpp
|
||||||
|
|
||||||
# forms
|
# forms
|
||||||
@@ -186,8 +186,8 @@ add_library(qbt_gui STATIC
|
|||||||
statsdialog.ui
|
statsdialog.ui
|
||||||
torrentcategorydialog.ui
|
torrentcategorydialog.ui
|
||||||
torrentcreatordialog.ui
|
torrentcreatordialog.ui
|
||||||
|
torrentoptionsdialog.ui
|
||||||
trackerentriesdialog.ui
|
trackerentriesdialog.ui
|
||||||
updownratiodialog.ui
|
|
||||||
)
|
)
|
||||||
|
|
||||||
target_sources(qbt_gui INTERFACE about.qrc)
|
target_sources(qbt_gui INTERFACE about.qrc)
|
||||||
|
|||||||
@@ -32,13 +32,17 @@
|
|||||||
|
|
||||||
#include "base/unicodestrings.h"
|
#include "base/unicodestrings.h"
|
||||||
#include "base/utils/misc.h"
|
#include "base/utils/misc.h"
|
||||||
|
#include "base/version.h"
|
||||||
#include "ui_aboutdialog.h"
|
#include "ui_aboutdialog.h"
|
||||||
#include "uithememanager.h"
|
#include "uithememanager.h"
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
|
|
||||||
|
#define SETTINGS_KEY(name) "AboutDialog/" name
|
||||||
|
|
||||||
AboutDialog::AboutDialog(QWidget *parent)
|
AboutDialog::AboutDialog(QWidget *parent)
|
||||||
: QDialog(parent)
|
: QDialog(parent)
|
||||||
, m_ui(new Ui::AboutDialog)
|
, m_ui(new Ui::AboutDialog)
|
||||||
|
, m_storeDialogSize(SETTINGS_KEY("Size"))
|
||||||
{
|
{
|
||||||
m_ui->setupUi(this);
|
m_ui->setupUi(this);
|
||||||
setAttribute(Qt::WA_DeleteOnClose);
|
setAttribute(Qt::WA_DeleteOnClose);
|
||||||
@@ -60,7 +64,7 @@ AboutDialog::AboutDialog(QWidget *parent)
|
|||||||
"</table>"
|
"</table>"
|
||||||
"</p>")
|
"</p>")
|
||||||
.arg(tr("An advanced BitTorrent client programmed in C++, based on Qt toolkit and libtorrent-rasterbar.")
|
.arg(tr("An advanced BitTorrent client programmed in C++, based on Qt toolkit and libtorrent-rasterbar.")
|
||||||
, tr("Copyright %1 2006-2020 The qBittorrent project").arg(QString::fromUtf8(C_COPYRIGHT))
|
, tr("Copyright %1 2006-2021 The qBittorrent project").arg(QString::fromUtf8(C_COPYRIGHT))
|
||||||
, tr("Home Page:")
|
, tr("Home Page:")
|
||||||
, tr("Forum:")
|
, tr("Forum:")
|
||||||
, tr("Bug Tracker:"));
|
, tr("Bug Tracker:"));
|
||||||
@@ -107,11 +111,12 @@ AboutDialog::AboutDialog(QWidget *parent)
|
|||||||
"The database is licensed under the Creative Commons Attribution 4.0 International License"));
|
"The database is licensed under the Creative Commons Attribution 4.0 International License"));
|
||||||
m_ui->labelDBIP->setText(DBIPText);
|
m_ui->labelDBIP->setText(DBIPText);
|
||||||
|
|
||||||
Utils::Gui::resize(this);
|
Utils::Gui::resize(this, m_storeDialogSize);
|
||||||
show();
|
show();
|
||||||
}
|
}
|
||||||
|
|
||||||
AboutDialog::~AboutDialog()
|
AboutDialog::~AboutDialog()
|
||||||
{
|
{
|
||||||
|
m_storeDialogSize = size();
|
||||||
delete m_ui;
|
delete m_ui;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,12 +30,14 @@
|
|||||||
|
|
||||||
#include <QDialog>
|
#include <QDialog>
|
||||||
|
|
||||||
|
#include "base/settingvalue.h"
|
||||||
|
|
||||||
namespace Ui
|
namespace Ui
|
||||||
{
|
{
|
||||||
class AboutDialog;
|
class AboutDialog;
|
||||||
}
|
}
|
||||||
|
|
||||||
class AboutDialog : public QDialog
|
class AboutDialog final : public QDialog
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
Q_DISABLE_COPY(AboutDialog)
|
Q_DISABLE_COPY(AboutDialog)
|
||||||
@@ -46,4 +48,5 @@ public:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
Ui::AboutDialog *m_ui;
|
Ui::AboutDialog *m_ui;
|
||||||
|
SettingValue<QSize> m_storeDialogSize;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -42,7 +42,7 @@
|
|||||||
#include "base/bittorrent/infohash.h"
|
#include "base/bittorrent/infohash.h"
|
||||||
#include "base/bittorrent/magneturi.h"
|
#include "base/bittorrent/magneturi.h"
|
||||||
#include "base/bittorrent/session.h"
|
#include "base/bittorrent/session.h"
|
||||||
#include "base/bittorrent/torrenthandle.h"
|
#include "base/bittorrent/torrent.h"
|
||||||
#include "base/exceptions.h"
|
#include "base/exceptions.h"
|
||||||
#include "base/global.h"
|
#include "base/global.h"
|
||||||
#include "base/net/downloadmanager.h"
|
#include "base/net/downloadmanager.h"
|
||||||
@@ -107,12 +107,7 @@ AddNewTorrentDialog::AddNewTorrentDialog(const BitTorrent::AddTorrentParams &inP
|
|||||||
|
|
||||||
const auto *session = BitTorrent::Session::instance();
|
const auto *session = BitTorrent::Session::instance();
|
||||||
|
|
||||||
if (m_torrentParams.addPaused == TriStateBool::True)
|
m_ui->startTorrentCheckBox->setChecked(!m_torrentParams.addPaused.value_or(session->isAddTorrentPaused()));
|
||||||
m_ui->startTorrentCheckBox->setChecked(false);
|
|
||||||
else if (m_torrentParams.addPaused == TriStateBool::False)
|
|
||||||
m_ui->startTorrentCheckBox->setChecked(true);
|
|
||||||
else
|
|
||||||
m_ui->startTorrentCheckBox->setChecked(!session->isAddTorrentPaused());
|
|
||||||
|
|
||||||
m_ui->comboTTM->blockSignals(true); // the TreeView size isn't correct if the slot does it job at this point
|
m_ui->comboTTM->blockSignals(true); // the TreeView size isn't correct if the slot does it job at this point
|
||||||
m_ui->comboTTM->setCurrentIndex(!session->isAutoTMMDisabledByDefault());
|
m_ui->comboTTM->setCurrentIndex(!session->isAutoTMMDisabledByDefault());
|
||||||
@@ -120,11 +115,11 @@ AddNewTorrentDialog::AddNewTorrentDialog(const BitTorrent::AddTorrentParams &inP
|
|||||||
populateSavePathComboBox();
|
populateSavePathComboBox();
|
||||||
connect(m_ui->savePath, &FileSystemPathEdit::selectedPathChanged, this, &AddNewTorrentDialog::onSavePathChanged);
|
connect(m_ui->savePath, &FileSystemPathEdit::selectedPathChanged, this, &AddNewTorrentDialog::onSavePathChanged);
|
||||||
|
|
||||||
const bool rememberLastSavePath = settings()->loadValue(KEY_REMEMBERLASTSAVEPATH, false).toBool();
|
const bool rememberLastSavePath = settings()->loadValue(KEY_REMEMBERLASTSAVEPATH, false);
|
||||||
m_ui->checkBoxRememberLastSavePath->setChecked(rememberLastSavePath);
|
m_ui->checkBoxRememberLastSavePath->setChecked(rememberLastSavePath);
|
||||||
|
|
||||||
m_ui->contentLayoutComboBox->setCurrentIndex(
|
m_ui->contentLayoutComboBox->setCurrentIndex(
|
||||||
static_cast<int>(m_torrentParams.contentLayout ? *m_torrentParams.contentLayout : session->torrentContentLayout()));
|
static_cast<int>(m_torrentParams.contentLayout.value_or(session->torrentContentLayout())));
|
||||||
|
|
||||||
m_ui->sequentialCheckBox->setChecked(m_torrentParams.sequential);
|
m_ui->sequentialCheckBox->setChecked(m_torrentParams.sequential);
|
||||||
m_ui->firstLastCheckBox->setChecked(m_torrentParams.firstLastPiecePriority);
|
m_ui->firstLastCheckBox->setChecked(m_torrentParams.firstLastPiecePriority);
|
||||||
@@ -135,7 +130,7 @@ AddNewTorrentDialog::AddNewTorrentDialog(const BitTorrent::AddTorrentParams &inP
|
|||||||
// Load categories
|
// Load categories
|
||||||
QStringList categories = session->categories().keys();
|
QStringList categories = session->categories().keys();
|
||||||
std::sort(categories.begin(), categories.end(), Utils::String::naturalLessThan<Qt::CaseInsensitive>);
|
std::sort(categories.begin(), categories.end(), Utils::String::naturalLessThan<Qt::CaseInsensitive>);
|
||||||
QString defaultCategory = settings()->loadValue(KEY_DEFAULTCATEGORY).toString();
|
auto defaultCategory = settings()->loadValue<QString>(KEY_DEFAULTCATEGORY);
|
||||||
|
|
||||||
if (!m_torrentParams.category.isEmpty())
|
if (!m_torrentParams.category.isEmpty())
|
||||||
m_ui->categoryComboBox->addItem(m_torrentParams.category);
|
m_ui->categoryComboBox->addItem(m_torrentParams.category);
|
||||||
@@ -170,7 +165,7 @@ AddNewTorrentDialog::~AddNewTorrentDialog()
|
|||||||
|
|
||||||
bool AddNewTorrentDialog::isEnabled()
|
bool AddNewTorrentDialog::isEnabled()
|
||||||
{
|
{
|
||||||
return SettingsStorage::instance()->loadValue(KEY_ENABLED, true).toBool();
|
return SettingsStorage::instance()->loadValue(KEY_ENABLED, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AddNewTorrentDialog::setEnabled(bool value)
|
void AddNewTorrentDialog::setEnabled(bool value)
|
||||||
@@ -180,7 +175,7 @@ void AddNewTorrentDialog::setEnabled(bool value)
|
|||||||
|
|
||||||
bool AddNewTorrentDialog::isTopLevel()
|
bool AddNewTorrentDialog::isTopLevel()
|
||||||
{
|
{
|
||||||
return SettingsStorage::instance()->loadValue(KEY_TOPLEVEL, true).toBool();
|
return SettingsStorage::instance()->loadValue(KEY_TOPLEVEL, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AddNewTorrentDialog::setTopLevel(bool value)
|
void AddNewTorrentDialog::setTopLevel(bool value)
|
||||||
@@ -191,7 +186,7 @@ void AddNewTorrentDialog::setTopLevel(bool value)
|
|||||||
int AddNewTorrentDialog::savePathHistoryLength()
|
int AddNewTorrentDialog::savePathHistoryLength()
|
||||||
{
|
{
|
||||||
const int defaultHistoryLength = 8;
|
const int defaultHistoryLength = 8;
|
||||||
const int value = settings()->loadValue(KEY_SAVEPATHHISTORYLENGTH, defaultHistoryLength).toInt();
|
const int value = settings()->loadValue(KEY_SAVEPATHHISTORYLENGTH, defaultHistoryLength);
|
||||||
return qBound(minPathHistoryLength, value, maxPathHistoryLength);
|
return qBound(minPathHistoryLength, value, maxPathHistoryLength);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -204,14 +199,14 @@ void AddNewTorrentDialog::setSavePathHistoryLength(int value)
|
|||||||
|
|
||||||
settings()->storeValue(KEY_SAVEPATHHISTORYLENGTH, clampedValue);
|
settings()->storeValue(KEY_SAVEPATHHISTORYLENGTH, clampedValue);
|
||||||
settings()->storeValue(KEY_SAVEPATHHISTORY
|
settings()->storeValue(KEY_SAVEPATHHISTORY
|
||||||
, QStringList(settings()->loadValue(KEY_SAVEPATHHISTORY).toStringList().mid(0, clampedValue)));
|
, QStringList(settings()->loadValue<QStringList>(KEY_SAVEPATHHISTORY).mid(0, clampedValue)));
|
||||||
}
|
}
|
||||||
|
|
||||||
void AddNewTorrentDialog::loadState()
|
void AddNewTorrentDialog::loadState()
|
||||||
{
|
{
|
||||||
Utils::Gui::resize(this, m_storeDialogSize);
|
Utils::Gui::resize(this, m_storeDialogSize);
|
||||||
m_ui->splitter->restoreState(m_storeSplitterState);
|
m_ui->splitter->restoreState(m_storeSplitterState);
|
||||||
m_headerState = settings()->loadValue(KEY_TREEHEADERSTATE).toByteArray();
|
m_headerState = settings()->loadValue<QByteArray>(KEY_TREEHEADERSTATE);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AddNewTorrentDialog::saveState()
|
void AddNewTorrentDialog::saveState()
|
||||||
@@ -280,7 +275,7 @@ bool AddNewTorrentDialog::loadTorrentImpl()
|
|||||||
// Prevent showing the dialog if download is already present
|
// Prevent showing the dialog if download is already present
|
||||||
if (BitTorrent::Session::instance()->isKnownTorrent(infoHash))
|
if (BitTorrent::Session::instance()->isKnownTorrent(infoHash))
|
||||||
{
|
{
|
||||||
BitTorrent::TorrentHandle *const torrent = BitTorrent::Session::instance()->findTorrent(infoHash);
|
BitTorrent::Torrent *const torrent = BitTorrent::Session::instance()->findTorrent(infoHash);
|
||||||
if (torrent)
|
if (torrent)
|
||||||
{
|
{
|
||||||
if (torrent->isPrivate() || m_torrentInfo.isPrivate())
|
if (torrent->isPrivate() || m_torrentInfo.isPrivate())
|
||||||
@@ -321,7 +316,7 @@ bool AddNewTorrentDialog::loadMagnet(const BitTorrent::MagnetUri &magnetUri)
|
|||||||
// Prevent showing the dialog if download is already present
|
// Prevent showing the dialog if download is already present
|
||||||
if (BitTorrent::Session::instance()->isKnownTorrent(infoHash))
|
if (BitTorrent::Session::instance()->isKnownTorrent(infoHash))
|
||||||
{
|
{
|
||||||
BitTorrent::TorrentHandle *const torrent = BitTorrent::Session::instance()->findTorrent(infoHash);
|
BitTorrent::Torrent *const torrent = BitTorrent::Session::instance()->findTorrent(infoHash);
|
||||||
if (torrent)
|
if (torrent)
|
||||||
{
|
{
|
||||||
if (torrent->isPrivate())
|
if (torrent->isPrivate())
|
||||||
@@ -371,7 +366,7 @@ void AddNewTorrentDialog::showEvent(QShowEvent *event)
|
|||||||
void AddNewTorrentDialog::saveSavePathHistory() const
|
void AddNewTorrentDialog::saveSavePathHistory() const
|
||||||
{
|
{
|
||||||
// Get current history
|
// Get current history
|
||||||
QStringList history = settings()->loadValue(KEY_SAVEPATHHISTORY).toStringList();
|
auto history = settings()->loadValue<QStringList>(KEY_SAVEPATHHISTORY);
|
||||||
QVector<QDir> historyDirs;
|
QVector<QDir> historyDirs;
|
||||||
for (const QString &path : asConst(history))
|
for (const QString &path : asConst(history))
|
||||||
historyDirs << QDir {path};
|
historyDirs << QDir {path};
|
||||||
@@ -489,11 +484,11 @@ void AddNewTorrentDialog::populateSavePathComboBox()
|
|||||||
m_ui->savePath->clear();
|
m_ui->savePath->clear();
|
||||||
|
|
||||||
// Load save path history
|
// Load save path history
|
||||||
const QStringList savePathHistory {settings()->loadValue(KEY_SAVEPATHHISTORY).toStringList()};
|
const auto savePathHistory {settings()->loadValue<QStringList>(KEY_SAVEPATHHISTORY)};
|
||||||
for (const QString &savePath : savePathHistory)
|
for (const QString &savePath : savePathHistory)
|
||||||
m_ui->savePath->addItem(savePath);
|
m_ui->savePath->addItem(savePath);
|
||||||
|
|
||||||
const bool rememberLastSavePath {settings()->loadValue(KEY_REMEMBERLASTSAVEPATH, false).toBool()};
|
const bool rememberLastSavePath {settings()->loadValue(KEY_REMEMBERLASTSAVEPATH, false)};
|
||||||
const QString defSavePath {BitTorrent::Session::instance()->defaultSavePath()};
|
const QString defSavePath {BitTorrent::Session::instance()->defaultSavePath()};
|
||||||
|
|
||||||
if (!m_torrentParams.savePath.isEmpty())
|
if (!m_torrentParams.savePath.isEmpty())
|
||||||
@@ -573,7 +568,7 @@ void AddNewTorrentDialog::accept()
|
|||||||
if (m_contentModel)
|
if (m_contentModel)
|
||||||
m_torrentParams.filePriorities = m_contentModel->model()->getFilePriorities();
|
m_torrentParams.filePriorities = m_contentModel->model()->getFilePriorities();
|
||||||
|
|
||||||
m_torrentParams.addPaused = TriStateBool(!m_ui->startTorrentCheckBox->isChecked());
|
m_torrentParams.addPaused = !m_ui->startTorrentCheckBox->isChecked();
|
||||||
m_torrentParams.contentLayout = static_cast<BitTorrent::TorrentContentLayout>(m_ui->contentLayoutComboBox->currentIndex());
|
m_torrentParams.contentLayout = static_cast<BitTorrent::TorrentContentLayout>(m_ui->contentLayoutComboBox->currentIndex());
|
||||||
|
|
||||||
m_torrentParams.sequential = m_ui->sequentialCheckBox->isChecked();
|
m_torrentParams.sequential = m_ui->sequentialCheckBox->isChecked();
|
||||||
@@ -582,13 +577,13 @@ void AddNewTorrentDialog::accept()
|
|||||||
QString savePath = m_ui->savePath->selectedPath();
|
QString savePath = m_ui->savePath->selectedPath();
|
||||||
if (m_ui->comboTTM->currentIndex() != 1)
|
if (m_ui->comboTTM->currentIndex() != 1)
|
||||||
{ // 0 is Manual mode and 1 is Automatic mode. Handle all non 1 values as manual mode.
|
{ // 0 is Manual mode and 1 is Automatic mode. Handle all non 1 values as manual mode.
|
||||||
m_torrentParams.useAutoTMM = TriStateBool::False;
|
m_torrentParams.useAutoTMM = false;
|
||||||
m_torrentParams.savePath = savePath;
|
m_torrentParams.savePath = savePath;
|
||||||
saveSavePathHistory();
|
saveSavePathHistory();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
m_torrentParams.useAutoTMM = TriStateBool::True;
|
m_torrentParams.useAutoTMM = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
setEnabled(!m_ui->checkBoxNeverShow->isChecked());
|
setEnabled(!m_ui->checkBoxNeverShow->isChecked());
|
||||||
@@ -660,7 +655,7 @@ void AddNewTorrentDialog::setupTreeview()
|
|||||||
|
|
||||||
// Set torrent information
|
// Set torrent information
|
||||||
m_ui->labelCommentData->setText(Utils::Misc::parseHtmlLinks(m_torrentInfo.comment().toHtmlEscaped()));
|
m_ui->labelCommentData->setText(Utils::Misc::parseHtmlLinks(m_torrentInfo.comment().toHtmlEscaped()));
|
||||||
m_ui->labelDateData->setText(!m_torrentInfo.creationDate().isNull() ? m_torrentInfo.creationDate().toString(Qt::DefaultLocaleShortDate) : tr("Not available"));
|
m_ui->labelDateData->setText(!m_torrentInfo.creationDate().isNull() ? QLocale().toString(m_torrentInfo.creationDate(), QLocale::ShortFormat) : tr("Not available"));
|
||||||
|
|
||||||
// Prepare content tree
|
// Prepare content tree
|
||||||
m_contentModel = new TorrentContentFilterModel(this);
|
m_contentModel = new TorrentContentFilterModel(this);
|
||||||
|
|||||||
@@ -118,6 +118,6 @@ private:
|
|||||||
std::unique_ptr<TorrentFileGuard> m_torrentGuard;
|
std::unique_ptr<TorrentFileGuard> m_torrentGuard;
|
||||||
BitTorrent::AddTorrentParams m_torrentParams;
|
BitTorrent::AddTorrentParams m_torrentParams;
|
||||||
|
|
||||||
CachedSettingValue<QSize> m_storeDialogSize;
|
SettingValue<QSize> m_storeDialogSize;
|
||||||
CachedSettingValue<QByteArray> m_storeSplitterState;
|
SettingValue<QByteArray> m_storeSplitterState;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -715,12 +715,12 @@ void AdvancedSettings::addRow(const int row, const QString &text, T *widget)
|
|||||||
setCellWidget(row, PROPERTY, label);
|
setCellWidget(row, PROPERTY, label);
|
||||||
setCellWidget(row, VALUE, widget);
|
setCellWidget(row, VALUE, widget);
|
||||||
|
|
||||||
if (std::is_same<T, QCheckBox>::value)
|
if constexpr (std::is_same_v<T, QCheckBox>)
|
||||||
connect(widget, SIGNAL(stateChanged(int)), this, SIGNAL(settingsChanged()));
|
connect(widget, &QCheckBox::stateChanged, this, &AdvancedSettings::settingsChanged);
|
||||||
else if (std::is_same<T, QSpinBox>::value)
|
else if constexpr (std::is_same_v<T, QSpinBox>)
|
||||||
connect(widget, SIGNAL(valueChanged(int)), this, SIGNAL(settingsChanged()));
|
connect(widget, qOverload<int>(&QSpinBox::valueChanged), this, &AdvancedSettings::settingsChanged);
|
||||||
else if (std::is_same<T, QComboBox>::value)
|
else if constexpr (std::is_same_v<T, QComboBox>)
|
||||||
connect(widget, SIGNAL(currentIndexChanged(int)), this, SIGNAL(settingsChanged()));
|
connect(widget, qOverload<int>(&QComboBox::currentIndexChanged), this, &AdvancedSettings::settingsChanged);
|
||||||
else if (std::is_same<T, QLineEdit>::value)
|
else if constexpr (std::is_same_v<T, QLineEdit>)
|
||||||
connect(widget, SIGNAL(textChanged(QString)), this, SIGNAL(settingsChanged()));
|
connect(widget, &QLineEdit::textChanged, this, &AdvancedSettings::settingsChanged);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -28,6 +28,7 @@
|
|||||||
|
|
||||||
#include "autoexpandabledialog.h"
|
#include "autoexpandabledialog.h"
|
||||||
|
|
||||||
|
#include "base/utils/fs.h"
|
||||||
#include "ui_autoexpandabledialog.h"
|
#include "ui_autoexpandabledialog.h"
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
|
|
||||||
@@ -57,12 +58,9 @@ QString AutoExpandableDialog::getText(QWidget *parent, const QString &title, con
|
|||||||
d.m_ui->textEdit->selectAll();
|
d.m_ui->textEdit->selectAll();
|
||||||
if (excludeExtension)
|
if (excludeExtension)
|
||||||
{
|
{
|
||||||
int lastDotIndex = text.lastIndexOf('.');
|
const QString extension = Utils::Fs::fileExtension(text);
|
||||||
if ((lastDotIndex > 3) && (text.mid(lastDotIndex - 4, 4).toLower() == ".tar"))
|
if (!extension.isEmpty())
|
||||||
lastDotIndex -= 4;
|
d.m_ui->textEdit->setSelection(0, (text.length() - extension.length() - 1));
|
||||||
// Select file name without extension, except dot files like .gitignore
|
|
||||||
if (lastDotIndex > 0)
|
|
||||||
d.m_ui->textEdit->setSelection(0, lastDotIndex);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool res = d.exec();
|
bool res = d.exec();
|
||||||
|
|||||||
@@ -38,11 +38,13 @@
|
|||||||
#include "ui_banlistoptionsdialog.h"
|
#include "ui_banlistoptionsdialog.h"
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
|
|
||||||
|
#define SETTINGS_KEY(name) "BanListOptionsDialog/" name
|
||||||
|
|
||||||
BanListOptionsDialog::BanListOptionsDialog(QWidget *parent)
|
BanListOptionsDialog::BanListOptionsDialog(QWidget *parent)
|
||||||
: QDialog(parent)
|
: QDialog(parent)
|
||||||
, m_ui(new Ui::BanListOptionsDialog)
|
, m_ui(new Ui::BanListOptionsDialog)
|
||||||
|
, m_storeDialogSize(SETTINGS_KEY("Size"))
|
||||||
, m_model(new QStringListModel(BitTorrent::Session::instance()->bannedIPs(), this))
|
, m_model(new QStringListModel(BitTorrent::Session::instance()->bannedIPs(), this))
|
||||||
, m_modified(false)
|
|
||||||
{
|
{
|
||||||
m_ui->setupUi(this);
|
m_ui->setupUi(this);
|
||||||
|
|
||||||
@@ -54,11 +56,12 @@ BanListOptionsDialog::BanListOptionsDialog(QWidget *parent)
|
|||||||
m_ui->bannedIPList->sortByColumn(0, Qt::AscendingOrder);
|
m_ui->bannedIPList->sortByColumn(0, Qt::AscendingOrder);
|
||||||
m_ui->buttonBanIP->setEnabled(false);
|
m_ui->buttonBanIP->setEnabled(false);
|
||||||
|
|
||||||
Utils::Gui::resize(this);
|
Utils::Gui::resize(this, m_storeDialogSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
BanListOptionsDialog::~BanListOptionsDialog()
|
BanListOptionsDialog::~BanListOptionsDialog()
|
||||||
{
|
{
|
||||||
|
m_storeDialogSize = size();
|
||||||
delete m_ui;
|
delete m_ui;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -30,6 +30,8 @@
|
|||||||
|
|
||||||
#include <QDialog>
|
#include <QDialog>
|
||||||
|
|
||||||
|
#include "base/settingvalue.h"
|
||||||
|
|
||||||
class QSortFilterProxyModel;
|
class QSortFilterProxyModel;
|
||||||
class QStringListModel;
|
class QStringListModel;
|
||||||
|
|
||||||
@@ -38,13 +40,14 @@ namespace Ui
|
|||||||
class BanListOptionsDialog;
|
class BanListOptionsDialog;
|
||||||
}
|
}
|
||||||
|
|
||||||
class BanListOptionsDialog : public QDialog
|
class BanListOptionsDialog final : public QDialog
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
Q_DISABLE_COPY(BanListOptionsDialog)
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit BanListOptionsDialog(QWidget *parent = nullptr);
|
explicit BanListOptionsDialog(QWidget *parent = nullptr);
|
||||||
~BanListOptionsDialog();
|
~BanListOptionsDialog() override;
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void on_buttonBox_accepted();
|
void on_buttonBox_accepted();
|
||||||
@@ -54,7 +57,8 @@ private slots:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
Ui::BanListOptionsDialog *m_ui;
|
Ui::BanListOptionsDialog *m_ui;
|
||||||
|
SettingValue<QSize> m_storeDialogSize;
|
||||||
QStringListModel *m_model;
|
QStringListModel *m_model;
|
||||||
QSortFilterProxyModel *m_sortFilter;
|
QSortFilterProxyModel *m_sortFilter;
|
||||||
bool m_modified;
|
bool m_modified = false;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -32,7 +32,7 @@
|
|||||||
#include <QIcon>
|
#include <QIcon>
|
||||||
|
|
||||||
#include "base/bittorrent/session.h"
|
#include "base/bittorrent/session.h"
|
||||||
#include "base/bittorrent/torrenthandle.h"
|
#include "base/bittorrent/torrent.h"
|
||||||
#include "base/global.h"
|
#include "base/global.h"
|
||||||
#include "uithememanager.h"
|
#include "uithememanager.h"
|
||||||
|
|
||||||
@@ -336,7 +336,7 @@ void CategoryFilterModel::categoryRemoved(const QString &categoryName)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CategoryFilterModel::torrentAdded(BitTorrent::TorrentHandle *const torrent)
|
void CategoryFilterModel::torrentAdded(BitTorrent::Torrent *const torrent)
|
||||||
{
|
{
|
||||||
CategoryModelItem *item = findItem(torrent->category());
|
CategoryModelItem *item = findItem(torrent->category());
|
||||||
Q_ASSERT(item);
|
Q_ASSERT(item);
|
||||||
@@ -345,7 +345,7 @@ void CategoryFilterModel::torrentAdded(BitTorrent::TorrentHandle *const torrent)
|
|||||||
m_rootItem->childAt(0)->increaseTorrentsCount();
|
m_rootItem->childAt(0)->increaseTorrentsCount();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CategoryFilterModel::torrentAboutToBeRemoved(BitTorrent::TorrentHandle *const torrent)
|
void CategoryFilterModel::torrentAboutToBeRemoved(BitTorrent::Torrent *const torrent)
|
||||||
{
|
{
|
||||||
CategoryModelItem *item = findItem(torrent->category());
|
CategoryModelItem *item = findItem(torrent->category());
|
||||||
Q_ASSERT(item);
|
Q_ASSERT(item);
|
||||||
@@ -354,7 +354,7 @@ void CategoryFilterModel::torrentAboutToBeRemoved(BitTorrent::TorrentHandle *con
|
|||||||
m_rootItem->childAt(0)->decreaseTorrentsCount();
|
m_rootItem->childAt(0)->decreaseTorrentsCount();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CategoryFilterModel::torrentCategoryChanged(BitTorrent::TorrentHandle *const torrent, const QString &oldCategory)
|
void CategoryFilterModel::torrentCategoryChanged(BitTorrent::Torrent *const torrent, const QString &oldCategory)
|
||||||
{
|
{
|
||||||
QModelIndex i;
|
QModelIndex i;
|
||||||
|
|
||||||
@@ -403,7 +403,7 @@ void CategoryFilterModel::populate()
|
|||||||
m_rootItem->addChild(UID_ALL, new CategoryModelItem(nullptr, tr("All"), torrents.count()));
|
m_rootItem->addChild(UID_ALL, new CategoryModelItem(nullptr, tr("All"), torrents.count()));
|
||||||
|
|
||||||
// Uncategorized torrents
|
// Uncategorized torrents
|
||||||
using Torrent = BitTorrent::TorrentHandle;
|
using Torrent = BitTorrent::Torrent;
|
||||||
m_rootItem->addChild(
|
m_rootItem->addChild(
|
||||||
UID_UNCATEGORIZED
|
UID_UNCATEGORIZED
|
||||||
, new CategoryModelItem(
|
, new CategoryModelItem(
|
||||||
@@ -411,7 +411,7 @@ void CategoryFilterModel::populate()
|
|||||||
, std::count_if(torrents.begin(), torrents.end()
|
, std::count_if(torrents.begin(), torrents.end()
|
||||||
, [](Torrent *torrent) { return torrent->category().isEmpty(); })));
|
, [](Torrent *torrent) { return torrent->category().isEmpty(); })));
|
||||||
|
|
||||||
using Torrent = BitTorrent::TorrentHandle;
|
using Torrent = BitTorrent::Torrent;
|
||||||
for (auto i = session->categories().cbegin(); i != session->categories().cend(); ++i)
|
for (auto i = session->categories().cbegin(); i != session->categories().cend(); ++i)
|
||||||
{
|
{
|
||||||
const QString &category = i.key();
|
const QString &category = i.key();
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ class CategoryModelItem;
|
|||||||
|
|
||||||
namespace BitTorrent
|
namespace BitTorrent
|
||||||
{
|
{
|
||||||
class TorrentHandle;
|
class Torrent;
|
||||||
}
|
}
|
||||||
|
|
||||||
class CategoryFilterModel final : public QAbstractItemModel
|
class CategoryFilterModel final : public QAbstractItemModel
|
||||||
@@ -63,9 +63,9 @@ public:
|
|||||||
private slots:
|
private slots:
|
||||||
void categoryAdded(const QString &categoryName);
|
void categoryAdded(const QString &categoryName);
|
||||||
void categoryRemoved(const QString &categoryName);
|
void categoryRemoved(const QString &categoryName);
|
||||||
void torrentAdded(BitTorrent::TorrentHandle *const torrent);
|
void torrentAdded(BitTorrent::Torrent *const torrent);
|
||||||
void torrentAboutToBeRemoved(BitTorrent::TorrentHandle *const torrent);
|
void torrentAboutToBeRemoved(BitTorrent::Torrent *const torrent);
|
||||||
void torrentCategoryChanged(BitTorrent::TorrentHandle *const torrent, const QString &oldCategory);
|
void torrentCategoryChanged(BitTorrent::Torrent *const torrent, const QString &oldCategory);
|
||||||
void subcategoriesSupportChanged();
|
void subcategoriesSupportChanged();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|||||||
@@ -61,9 +61,9 @@ CookiesDialog::CookiesDialog(QWidget *parent)
|
|||||||
m_cookiesModel->index(0, 0),
|
m_cookiesModel->index(0, 0),
|
||||||
QItemSelectionModel::ClearAndSelect | QItemSelectionModel::Rows);
|
QItemSelectionModel::ClearAndSelect | QItemSelectionModel::Rows);
|
||||||
|
|
||||||
Utils::Gui::resize(this, SettingsStorage::instance()->loadValue(KEY_SIZE).toSize());
|
Utils::Gui::resize(this, SettingsStorage::instance()->loadValue<QSize>(KEY_SIZE));
|
||||||
m_ui->treeView->header()->restoreState(
|
m_ui->treeView->header()->restoreState(
|
||||||
SettingsStorage::instance()->loadValue(KEY_COOKIESVIEWSTATE).toByteArray());
|
SettingsStorage::instance()->loadValue<QByteArray>(KEY_COOKIESVIEWSTATE));
|
||||||
}
|
}
|
||||||
|
|
||||||
CookiesDialog::~CookiesDialog()
|
CookiesDialog::~CookiesDialog()
|
||||||
|
|||||||
@@ -39,6 +39,8 @@
|
|||||||
#include "ui_downloadfromurldialog.h"
|
#include "ui_downloadfromurldialog.h"
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
|
|
||||||
|
#define SETTINGS_KEY(name) "DownloadFromURLDialog/" name
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
bool isDownloadable(const QString &str)
|
bool isDownloadable(const QString &str)
|
||||||
@@ -55,6 +57,7 @@ namespace
|
|||||||
DownloadFromURLDialog::DownloadFromURLDialog(QWidget *parent)
|
DownloadFromURLDialog::DownloadFromURLDialog(QWidget *parent)
|
||||||
: QDialog(parent)
|
: QDialog(parent)
|
||||||
, m_ui(new Ui::DownloadFromURLDialog)
|
, m_ui(new Ui::DownloadFromURLDialog)
|
||||||
|
, m_storeDialogSize(SETTINGS_KEY("Size"))
|
||||||
{
|
{
|
||||||
m_ui->setupUi(this);
|
m_ui->setupUi(this);
|
||||||
setAttribute(Qt::WA_DeleteOnClose);
|
setAttribute(Qt::WA_DeleteOnClose);
|
||||||
@@ -82,12 +85,13 @@ DownloadFromURLDialog::DownloadFromURLDialog(QWidget *parent)
|
|||||||
}
|
}
|
||||||
m_ui->textUrls->setText(uniqueURLs.values().join('\n'));
|
m_ui->textUrls->setText(uniqueURLs.values().join('\n'));
|
||||||
|
|
||||||
Utils::Gui::resize(this);
|
Utils::Gui::resize(this, m_storeDialogSize);
|
||||||
show();
|
show();
|
||||||
}
|
}
|
||||||
|
|
||||||
DownloadFromURLDialog::~DownloadFromURLDialog()
|
DownloadFromURLDialog::~DownloadFromURLDialog()
|
||||||
{
|
{
|
||||||
|
m_storeDialogSize = size();
|
||||||
delete m_ui;
|
delete m_ui;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -30,19 +30,21 @@
|
|||||||
|
|
||||||
#include <QDialog>
|
#include <QDialog>
|
||||||
|
|
||||||
|
#include "base/settingvalue.h"
|
||||||
|
|
||||||
namespace Ui
|
namespace Ui
|
||||||
{
|
{
|
||||||
class DownloadFromURLDialog;
|
class DownloadFromURLDialog;
|
||||||
}
|
}
|
||||||
|
|
||||||
class DownloadFromURLDialog : public QDialog
|
class DownloadFromURLDialog final : public QDialog
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
Q_DISABLE_COPY(DownloadFromURLDialog)
|
Q_DISABLE_COPY(DownloadFromURLDialog)
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit DownloadFromURLDialog(QWidget *parent);
|
explicit DownloadFromURLDialog(QWidget *parent);
|
||||||
~DownloadFromURLDialog();
|
~DownloadFromURLDialog() override;
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void urlsReadyToBeDownloaded(const QStringList &torrentURLs);
|
void urlsReadyToBeDownloaded(const QStringList &torrentURLs);
|
||||||
@@ -52,4 +54,5 @@ private slots:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
Ui::DownloadFromURLDialog *m_ui;
|
Ui::DownloadFromURLDialog *m_ui;
|
||||||
|
SettingValue<QSize> m_storeDialogSize;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -68,6 +68,7 @@ HEADERS += \
|
|||||||
$$PWD/torrentcontentmodelitem.h \
|
$$PWD/torrentcontentmodelitem.h \
|
||||||
$$PWD/torrentcontenttreeview.h \
|
$$PWD/torrentcontenttreeview.h \
|
||||||
$$PWD/torrentcreatordialog.h \
|
$$PWD/torrentcreatordialog.h \
|
||||||
|
$$PWD/torrentoptionsdialog.h \
|
||||||
$$PWD/trackerentriesdialog.h \
|
$$PWD/trackerentriesdialog.h \
|
||||||
$$PWD/transferlistdelegate.h \
|
$$PWD/transferlistdelegate.h \
|
||||||
$$PWD/transferlistfilterswidget.h \
|
$$PWD/transferlistfilterswidget.h \
|
||||||
@@ -77,7 +78,6 @@ HEADERS += \
|
|||||||
$$PWD/tristateaction.h \
|
$$PWD/tristateaction.h \
|
||||||
$$PWD/tristatewidget.h \
|
$$PWD/tristatewidget.h \
|
||||||
$$PWD/uithememanager.h \
|
$$PWD/uithememanager.h \
|
||||||
$$PWD/updownratiodialog.h \
|
|
||||||
$$PWD/utils.h
|
$$PWD/utils.h
|
||||||
|
|
||||||
SOURCES += \
|
SOURCES += \
|
||||||
@@ -148,6 +148,7 @@ SOURCES += \
|
|||||||
$$PWD/torrentcontentmodelitem.cpp \
|
$$PWD/torrentcontentmodelitem.cpp \
|
||||||
$$PWD/torrentcontenttreeview.cpp \
|
$$PWD/torrentcontenttreeview.cpp \
|
||||||
$$PWD/torrentcreatordialog.cpp \
|
$$PWD/torrentcreatordialog.cpp \
|
||||||
|
$$PWD/torrentoptionsdialog.cpp \
|
||||||
$$PWD/trackerentriesdialog.cpp \
|
$$PWD/trackerentriesdialog.cpp \
|
||||||
$$PWD/transferlistdelegate.cpp \
|
$$PWD/transferlistdelegate.cpp \
|
||||||
$$PWD/transferlistfilterswidget.cpp \
|
$$PWD/transferlistfilterswidget.cpp \
|
||||||
@@ -157,7 +158,6 @@ SOURCES += \
|
|||||||
$$PWD/tristateaction.cpp \
|
$$PWD/tristateaction.cpp \
|
||||||
$$PWD/tristatewidget.cpp \
|
$$PWD/tristatewidget.cpp \
|
||||||
$$PWD/uithememanager.cpp \
|
$$PWD/uithememanager.cpp \
|
||||||
$$PWD/updownratiodialog.cpp \
|
|
||||||
$$PWD/utils.cpp
|
$$PWD/utils.cpp
|
||||||
|
|
||||||
win32|macx {
|
win32|macx {
|
||||||
@@ -207,7 +207,7 @@ FORMS += \
|
|||||||
$$PWD/statsdialog.ui \
|
$$PWD/statsdialog.ui \
|
||||||
$$PWD/torrentcategorydialog.ui \
|
$$PWD/torrentcategorydialog.ui \
|
||||||
$$PWD/torrentcreatordialog.ui \
|
$$PWD/torrentcreatordialog.ui \
|
||||||
$$PWD/trackerentriesdialog.ui \
|
$$PWD/torrentoptionsdialog.ui \
|
||||||
$$PWD/updownratiodialog.ui
|
$$PWD/trackerentriesdialog.ui
|
||||||
|
|
||||||
RESOURCES += $$PWD/about.qrc
|
RESOURCES += $$PWD/about.qrc
|
||||||
|
|||||||
@@ -38,10 +38,12 @@
|
|||||||
#include "ui_ipsubnetwhitelistoptionsdialog.h"
|
#include "ui_ipsubnetwhitelistoptionsdialog.h"
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
|
|
||||||
|
#define SETTINGS_KEY(name) "IPSubnetWhitelistOptionsDialog/" name
|
||||||
|
|
||||||
IPSubnetWhitelistOptionsDialog::IPSubnetWhitelistOptionsDialog(QWidget *parent)
|
IPSubnetWhitelistOptionsDialog::IPSubnetWhitelistOptionsDialog(QWidget *parent)
|
||||||
: QDialog(parent)
|
: QDialog(parent)
|
||||||
, m_ui(new Ui::IPSubnetWhitelistOptionsDialog)
|
, m_ui(new Ui::IPSubnetWhitelistOptionsDialog)
|
||||||
, m_modified(false)
|
, m_storeDialogSize(SETTINGS_KEY("Size"))
|
||||||
{
|
{
|
||||||
m_ui->setupUi(this);
|
m_ui->setupUi(this);
|
||||||
|
|
||||||
@@ -58,11 +60,12 @@ IPSubnetWhitelistOptionsDialog::IPSubnetWhitelistOptionsDialog(QWidget *parent)
|
|||||||
m_ui->whitelistedIPSubnetList->sortByColumn(0, Qt::AscendingOrder);
|
m_ui->whitelistedIPSubnetList->sortByColumn(0, Qt::AscendingOrder);
|
||||||
m_ui->buttonWhitelistIPSubnet->setEnabled(false);
|
m_ui->buttonWhitelistIPSubnet->setEnabled(false);
|
||||||
|
|
||||||
Utils::Gui::resize(this);
|
Utils::Gui::resize(this, m_storeDialogSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
IPSubnetWhitelistOptionsDialog::~IPSubnetWhitelistOptionsDialog()
|
IPSubnetWhitelistOptionsDialog::~IPSubnetWhitelistOptionsDialog()
|
||||||
{
|
{
|
||||||
|
m_storeDialogSize = size();
|
||||||
delete m_ui;
|
delete m_ui;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -30,6 +30,8 @@
|
|||||||
|
|
||||||
#include <QDialog>
|
#include <QDialog>
|
||||||
|
|
||||||
|
#include "base/settingvalue.h"
|
||||||
|
|
||||||
class QSortFilterProxyModel;
|
class QSortFilterProxyModel;
|
||||||
class QStringListModel;
|
class QStringListModel;
|
||||||
|
|
||||||
@@ -38,14 +40,14 @@ namespace Ui
|
|||||||
class IPSubnetWhitelistOptionsDialog;
|
class IPSubnetWhitelistOptionsDialog;
|
||||||
}
|
}
|
||||||
|
|
||||||
class IPSubnetWhitelistOptionsDialog : public QDialog
|
class IPSubnetWhitelistOptionsDialog final : public QDialog
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
Q_DISABLE_COPY(IPSubnetWhitelistOptionsDialog)
|
Q_DISABLE_COPY(IPSubnetWhitelistOptionsDialog)
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit IPSubnetWhitelistOptionsDialog(QWidget *parent = nullptr);
|
explicit IPSubnetWhitelistOptionsDialog(QWidget *parent = nullptr);
|
||||||
~IPSubnetWhitelistOptionsDialog();
|
~IPSubnetWhitelistOptionsDialog() override;
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void on_buttonBox_accepted();
|
void on_buttonBox_accepted();
|
||||||
@@ -55,7 +57,9 @@ private slots:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
Ui::IPSubnetWhitelistOptionsDialog *m_ui;
|
Ui::IPSubnetWhitelistOptionsDialog *m_ui;
|
||||||
|
SettingValue<QSize> m_storeDialogSize;
|
||||||
|
|
||||||
QStringListModel *m_model;
|
QStringListModel *m_model;
|
||||||
QSortFilterProxyModel *m_sortFilter;
|
QSortFilterProxyModel *m_sortFilter;
|
||||||
bool m_modified;
|
bool m_modified = false;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -155,7 +155,7 @@ LogMessageModel::LogMessageModel(QObject *parent)
|
|||||||
|
|
||||||
void LogMessageModel::handleNewMessage(const Log::Msg &message)
|
void LogMessageModel::handleNewMessage(const Log::Msg &message)
|
||||||
{
|
{
|
||||||
const QString time = QDateTime::fromMSecsSinceEpoch(message.timestamp).toString(Qt::SystemLocaleShortDate);
|
const QString time = QLocale::system().toString(QDateTime::fromMSecsSinceEpoch(message.timestamp), QLocale::ShortFormat);
|
||||||
const QString messageText = message.message;
|
const QString messageText = message.message;
|
||||||
const QColor foreground = m_foregroundForMessageTypes[message.type];
|
const QColor foreground = m_foregroundForMessageTypes[message.type];
|
||||||
|
|
||||||
@@ -173,7 +173,7 @@ LogPeerModel::LogPeerModel(QObject *parent)
|
|||||||
|
|
||||||
void LogPeerModel::handleNewMessage(const Log::Peer &peer)
|
void LogPeerModel::handleNewMessage(const Log::Peer &peer)
|
||||||
{
|
{
|
||||||
const QString time = QDateTime::fromMSecsSinceEpoch(peer.timestamp).toString(Qt::SystemLocaleShortDate);
|
const QString time = QLocale::system().toString(QDateTime::fromMSecsSinceEpoch(peer.timestamp), QLocale::ShortFormat);
|
||||||
const QString message = peer.blocked
|
const QString message = peer.blocked
|
||||||
? tr("%1 was blocked. Reason: %2.", "0.0.0.0 was blocked. Reason: reason for blocking.").arg(peer.ip, peer.reason)
|
? tr("%1 was blocked. Reason: %2.", "0.0.0.0 was blocked. Reason: reason for blocking.").arg(peer.ip, peer.reason)
|
||||||
: tr("%1 was banned", "0.0.0.0 was banned").arg(peer.ip);
|
: tr("%1 was banned", "0.0.0.0 was banned").arg(peer.ip);
|
||||||
|
|||||||
@@ -58,7 +58,7 @@
|
|||||||
|
|
||||||
#include "base/bittorrent/session.h"
|
#include "base/bittorrent/session.h"
|
||||||
#include "base/bittorrent/sessionstatus.h"
|
#include "base/bittorrent/sessionstatus.h"
|
||||||
#include "base/bittorrent/torrenthandle.h"
|
#include "base/bittorrent/torrent.h"
|
||||||
#include "base/global.h"
|
#include "base/global.h"
|
||||||
#include "base/logger.h"
|
#include "base/logger.h"
|
||||||
#include "base/net/downloadmanager.h"
|
#include "base/net/downloadmanager.h"
|
||||||
@@ -70,6 +70,7 @@
|
|||||||
#include "base/utils/fs.h"
|
#include "base/utils/fs.h"
|
||||||
#include "base/utils/misc.h"
|
#include "base/utils/misc.h"
|
||||||
#include "base/utils/password.h"
|
#include "base/utils/password.h"
|
||||||
|
#include "base/version.h"
|
||||||
#include "aboutdialog.h"
|
#include "aboutdialog.h"
|
||||||
#include "addnewtorrentdialog.h"
|
#include "addnewtorrentdialog.h"
|
||||||
#include "autoexpandabledialog.h"
|
#include "autoexpandabledialog.h"
|
||||||
@@ -172,10 +173,7 @@ MainWindow::MainWindow(QWidget *parent)
|
|||||||
|
|
||||||
m_ui->actionOpen->setIcon(UIThemeManager::instance()->getIcon("list-add"));
|
m_ui->actionOpen->setIcon(UIThemeManager::instance()->getIcon("list-add"));
|
||||||
m_ui->actionDownloadFromURL->setIcon(UIThemeManager::instance()->getIcon("insert-link"));
|
m_ui->actionDownloadFromURL->setIcon(UIThemeManager::instance()->getIcon("insert-link"));
|
||||||
m_ui->actionSetUploadLimit->setIcon(UIThemeManager::instance()->getIcon("kt-set-max-upload-speed"));
|
m_ui->actionSetGlobalSpeedLimits->setIcon(UIThemeManager::instance()->getIcon("speedometer"));
|
||||||
m_ui->actionSetDownloadLimit->setIcon(UIThemeManager::instance()->getIcon("kt-set-max-download-speed"));
|
|
||||||
m_ui->actionSetGlobalUploadLimit->setIcon(UIThemeManager::instance()->getIcon("kt-set-max-upload-speed"));
|
|
||||||
m_ui->actionSetGlobalDownloadLimit->setIcon(UIThemeManager::instance()->getIcon("kt-set-max-download-speed"));
|
|
||||||
m_ui->actionCreateTorrent->setIcon(UIThemeManager::instance()->getIcon("document-edit"));
|
m_ui->actionCreateTorrent->setIcon(UIThemeManager::instance()->getIcon("document-edit"));
|
||||||
m_ui->actionAbout->setIcon(UIThemeManager::instance()->getIcon("help-about"));
|
m_ui->actionAbout->setIcon(UIThemeManager::instance()->getIcon("help-about"));
|
||||||
m_ui->actionStatistics->setIcon(UIThemeManager::instance()->getIcon("view-statistics"));
|
m_ui->actionStatistics->setIcon(UIThemeManager::instance()->getIcon("view-statistics"));
|
||||||
@@ -211,8 +209,6 @@ MainWindow::MainWindow(QWidget *parent)
|
|||||||
connect(BitTorrent::Session::instance(), &BitTorrent::Session::downloadFromUrlFailed, this, &MainWindow::handleDownloadFromUrlFailure);
|
connect(BitTorrent::Session::instance(), &BitTorrent::Session::downloadFromUrlFailed, this, &MainWindow::handleDownloadFromUrlFailure);
|
||||||
connect(BitTorrent::Session::instance(), &BitTorrent::Session::speedLimitModeChanged, this, &MainWindow::updateAltSpeedsBtn);
|
connect(BitTorrent::Session::instance(), &BitTorrent::Session::speedLimitModeChanged, this, &MainWindow::updateAltSpeedsBtn);
|
||||||
connect(BitTorrent::Session::instance(), &BitTorrent::Session::recursiveTorrentDownloadPossible, this, &MainWindow::askRecursiveTorrentDownloadConfirmation);
|
connect(BitTorrent::Session::instance(), &BitTorrent::Session::recursiveTorrentDownloadPossible, this, &MainWindow::askRecursiveTorrentDownloadConfirmation);
|
||||||
connect(BitTorrent::Session::instance(), &BitTorrent::Session::torrentStorageMoveFinished, this, &MainWindow::moveTorrentFinished);
|
|
||||||
connect(BitTorrent::Session::instance(), &BitTorrent::Session::torrentStorageMoveFailed, this, &MainWindow::moveTorrentFailed);
|
|
||||||
|
|
||||||
qDebug("create tabWidget");
|
qDebug("create tabWidget");
|
||||||
m_tabs = new HidableTabWidget(this);
|
m_tabs = new HidableTabWidget(this);
|
||||||
@@ -264,11 +260,11 @@ MainWindow::MainWindow(QWidget *parent)
|
|||||||
connect(BitTorrent::Session::instance(), &BitTorrent::Session::trackerlessStateChanged, m_transferListFiltersWidget, &TransferListFiltersWidget::changeTrackerless);
|
connect(BitTorrent::Session::instance(), &BitTorrent::Session::trackerlessStateChanged, m_transferListFiltersWidget, &TransferListFiltersWidget::changeTrackerless);
|
||||||
|
|
||||||
connect(BitTorrent::Session::instance(), &BitTorrent::Session::trackerSuccess
|
connect(BitTorrent::Session::instance(), &BitTorrent::Session::trackerSuccess
|
||||||
, m_transferListFiltersWidget, qOverload<const BitTorrent::TorrentHandle *, const QString &>(&TransferListFiltersWidget::trackerSuccess));
|
, m_transferListFiltersWidget, qOverload<const BitTorrent::Torrent *, const QString &>(&TransferListFiltersWidget::trackerSuccess));
|
||||||
connect(BitTorrent::Session::instance(), &BitTorrent::Session::trackerError
|
connect(BitTorrent::Session::instance(), &BitTorrent::Session::trackerError
|
||||||
, m_transferListFiltersWidget, qOverload<const BitTorrent::TorrentHandle *, const QString &>(&TransferListFiltersWidget::trackerError));
|
, m_transferListFiltersWidget, qOverload<const BitTorrent::Torrent *, const QString &>(&TransferListFiltersWidget::trackerError));
|
||||||
connect(BitTorrent::Session::instance(), &BitTorrent::Session::trackerWarning
|
connect(BitTorrent::Session::instance(), &BitTorrent::Session::trackerWarning
|
||||||
, m_transferListFiltersWidget, qOverload<const BitTorrent::TorrentHandle *, const QString &>(&TransferListFiltersWidget::trackerWarning));
|
, m_transferListFiltersWidget, qOverload<const BitTorrent::Torrent *, const QString &>(&TransferListFiltersWidget::trackerWarning));
|
||||||
|
|
||||||
#ifdef Q_OS_MACOS
|
#ifdef Q_OS_MACOS
|
||||||
// Increase top spacing to avoid tab overlapping
|
// Increase top spacing to avoid tab overlapping
|
||||||
@@ -494,7 +490,7 @@ MainWindow::~MainWindow()
|
|||||||
|
|
||||||
bool MainWindow::isExecutionLogEnabled() const
|
bool MainWindow::isExecutionLogEnabled() const
|
||||||
{
|
{
|
||||||
return settings()->loadValue(KEY_EXECUTIONLOG_ENABLED, false).toBool();
|
return settings()->loadValue(KEY_EXECUTIONLOG_ENABLED, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::setExecutionLogEnabled(bool value)
|
void MainWindow::setExecutionLogEnabled(bool value)
|
||||||
@@ -506,7 +502,7 @@ int MainWindow::executionLogMsgTypes() const
|
|||||||
{
|
{
|
||||||
// as default value we need all the bits set
|
// as default value we need all the bits set
|
||||||
// -1 is considered the portable way to achieve that
|
// -1 is considered the portable way to achieve that
|
||||||
return settings()->loadValue(KEY_EXECUTIONLOG_TYPES, -1).toInt();
|
return settings()->loadValue(KEY_EXECUTIONLOG_TYPES, -1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::setExecutionLogMsgTypes(const int value)
|
void MainWindow::setExecutionLogMsgTypes(const int value)
|
||||||
@@ -517,7 +513,7 @@ void MainWindow::setExecutionLogMsgTypes(const int value)
|
|||||||
|
|
||||||
bool MainWindow::isNotificationsEnabled() const
|
bool MainWindow::isNotificationsEnabled() const
|
||||||
{
|
{
|
||||||
return settings()->loadValue(KEY_NOTIFICATIONS_ENABLED, true).toBool();
|
return settings()->loadValue(KEY_NOTIFICATIONS_ENABLED, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::setNotificationsEnabled(bool value)
|
void MainWindow::setNotificationsEnabled(bool value)
|
||||||
@@ -527,7 +523,7 @@ void MainWindow::setNotificationsEnabled(bool value)
|
|||||||
|
|
||||||
bool MainWindow::isTorrentAddedNotificationsEnabled() const
|
bool MainWindow::isTorrentAddedNotificationsEnabled() const
|
||||||
{
|
{
|
||||||
return settings()->loadValue(KEY_NOTIFICATIONS_TORRENTADDED, false).toBool();
|
return settings()->loadValue(KEY_NOTIFICATIONS_TORRENTADDED, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::setTorrentAddedNotificationsEnabled(bool value)
|
void MainWindow::setTorrentAddedNotificationsEnabled(bool value)
|
||||||
@@ -537,7 +533,7 @@ void MainWindow::setTorrentAddedNotificationsEnabled(bool value)
|
|||||||
|
|
||||||
bool MainWindow::isDownloadTrackerFavicon() const
|
bool MainWindow::isDownloadTrackerFavicon() const
|
||||||
{
|
{
|
||||||
return settings()->loadValue(KEY_DOWNLOAD_TRACKER_FAVICON, false).toBool();
|
return settings()->loadValue(KEY_DOWNLOAD_TRACKER_FAVICON, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::setDownloadTrackerFavicon(bool value)
|
void MainWindow::setDownloadTrackerFavicon(bool value)
|
||||||
@@ -862,30 +858,20 @@ void MainWindow::addTorrentFailed(const QString &error) const
|
|||||||
}
|
}
|
||||||
|
|
||||||
// called when a torrent was added
|
// called when a torrent was added
|
||||||
void MainWindow::torrentNew(BitTorrent::TorrentHandle *const torrent) const
|
void MainWindow::torrentNew(BitTorrent::Torrent *const torrent) const
|
||||||
{
|
{
|
||||||
if (isTorrentAddedNotificationsEnabled())
|
if (isTorrentAddedNotificationsEnabled())
|
||||||
showNotificationBaloon(tr("Torrent added"), tr("'%1' was added.", "e.g: xxx.avi was added.").arg(torrent->name()));
|
showNotificationBaloon(tr("Torrent added"), tr("'%1' was added.", "e.g: xxx.avi was added.").arg(torrent->name()));
|
||||||
}
|
}
|
||||||
|
|
||||||
// called when a torrent has finished
|
// called when a torrent has finished
|
||||||
void MainWindow::finishedTorrent(BitTorrent::TorrentHandle *const torrent) const
|
void MainWindow::finishedTorrent(BitTorrent::Torrent *const torrent) const
|
||||||
{
|
{
|
||||||
showNotificationBaloon(tr("Download completion"), tr("'%1' has finished downloading.", "e.g: xxx.avi has finished downloading.").arg(torrent->name()));
|
showNotificationBaloon(tr("Download completion"), tr("'%1' has finished downloading.", "e.g: xxx.avi has finished downloading.").arg(torrent->name()));
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::moveTorrentFinished(BitTorrent::TorrentHandle *const torrent, const QString &newPath) const
|
|
||||||
{
|
|
||||||
showNotificationBaloon(tr("Torrent moving finished"), tr("'%1' has finished moving files to '%2'.").arg(torrent->name(), newPath));
|
|
||||||
}
|
|
||||||
|
|
||||||
void MainWindow::moveTorrentFailed(BitTorrent::TorrentHandle *const torrent, const QString &targetPath, const QString &error) const
|
|
||||||
{
|
|
||||||
showNotificationBaloon(tr("Torrent moving failed"), tr("'%1' has failed moving files to '%2'. Reason: %3").arg(torrent->name(), targetPath, error));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Notification when disk is full
|
// Notification when disk is full
|
||||||
void MainWindow::fullDiskError(BitTorrent::TorrentHandle *const torrent, const QString &msg) const
|
void MainWindow::fullDiskError(BitTorrent::Torrent *const torrent, const QString &msg) const
|
||||||
{
|
{
|
||||||
showNotificationBaloon(tr("I/O Error", "i.e: Input/Output Error")
|
showNotificationBaloon(tr("I/O Error", "i.e: Input/Output Error")
|
||||||
, tr("An I/O error occurred for torrent '%1'.\n Reason: %2"
|
, tr("An I/O error occurred for torrent '%1'.\n Reason: %2"
|
||||||
@@ -975,7 +961,7 @@ void MainWindow::displayExecutionLogTab()
|
|||||||
|
|
||||||
// End of keyboard shortcuts slots
|
// End of keyboard shortcuts slots
|
||||||
|
|
||||||
void MainWindow::askRecursiveTorrentDownloadConfirmation(BitTorrent::TorrentHandle *const torrent)
|
void MainWindow::askRecursiveTorrentDownloadConfirmation(BitTorrent::Torrent *const torrent)
|
||||||
{
|
{
|
||||||
Preferences *const pref = Preferences::instance();
|
Preferences *const pref = Preferences::instance();
|
||||||
if (pref->recursiveDownloadDisabled()) return;
|
if (pref->recursiveDownloadDisabled()) return;
|
||||||
@@ -1008,36 +994,11 @@ void MainWindow::handleDownloadFromUrlFailure(const QString &url, const QString
|
|||||||
, tr("Couldn't download file at URL '%1', reason: %2.").arg(url, reason));
|
, tr("Couldn't download file at URL '%1', reason: %2.").arg(url, reason));
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::on_actionSetGlobalUploadLimit_triggered()
|
void MainWindow::on_actionSetGlobalSpeedLimits_triggered()
|
||||||
{
|
{
|
||||||
qDebug() << Q_FUNC_INFO;
|
auto dialog = new SpeedLimitDialog {this};
|
||||||
|
dialog->setAttribute(Qt::WA_DeleteOnClose);
|
||||||
BitTorrent::Session *const session = BitTorrent::Session::instance();
|
dialog->open();
|
||||||
bool ok = false;
|
|
||||||
const long newLimit = SpeedLimitDialog::askSpeedLimit(
|
|
||||||
this, &ok, tr("Global Upload Speed Limit"), session->uploadSpeedLimit());
|
|
||||||
|
|
||||||
if (ok)
|
|
||||||
{
|
|
||||||
qDebug("Setting global upload rate limit to %.1fKb/s", newLimit / 1024.);
|
|
||||||
session->setUploadSpeedLimit(newLimit);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void MainWindow::on_actionSetGlobalDownloadLimit_triggered()
|
|
||||||
{
|
|
||||||
qDebug() << Q_FUNC_INFO;
|
|
||||||
|
|
||||||
BitTorrent::Session *const session = BitTorrent::Session::instance();
|
|
||||||
bool ok = false;
|
|
||||||
const long newLimit = SpeedLimitDialog::askSpeedLimit(
|
|
||||||
this, &ok, tr("Global Download Speed Limit"), session->downloadSpeedLimit());
|
|
||||||
|
|
||||||
if (ok)
|
|
||||||
{
|
|
||||||
qDebug("Setting global download rate limit to %.1fKb/s", newLimit / 1024.);
|
|
||||||
session->setDownloadSpeedLimit(newLimit);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Necessary if we want to close the window
|
// Necessary if we want to close the window
|
||||||
@@ -1678,7 +1639,7 @@ void MainWindow::reloadSessionStats()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::reloadTorrentStats(const QVector<BitTorrent::TorrentHandle *> &torrents)
|
void MainWindow::reloadTorrentStats(const QVector<BitTorrent::Torrent *> &torrents)
|
||||||
{
|
{
|
||||||
if (currentTabWidget() == m_transferListWidget)
|
if (currentTabWidget() == m_transferListWidget)
|
||||||
{
|
{
|
||||||
@@ -1808,8 +1769,7 @@ QMenu *MainWindow::trayIconMenu()
|
|||||||
updateAltSpeedsBtn(isAltBWEnabled);
|
updateAltSpeedsBtn(isAltBWEnabled);
|
||||||
m_ui->actionUseAlternativeSpeedLimits->setChecked(isAltBWEnabled);
|
m_ui->actionUseAlternativeSpeedLimits->setChecked(isAltBWEnabled);
|
||||||
m_trayIconMenu->addAction(m_ui->actionUseAlternativeSpeedLimits);
|
m_trayIconMenu->addAction(m_ui->actionUseAlternativeSpeedLimits);
|
||||||
m_trayIconMenu->addAction(m_ui->actionSetGlobalDownloadLimit);
|
m_trayIconMenu->addAction(m_ui->actionSetGlobalSpeedLimits);
|
||||||
m_trayIconMenu->addAction(m_ui->actionSetGlobalUploadLimit);
|
|
||||||
m_trayIconMenu->addSeparator();
|
m_trayIconMenu->addSeparator();
|
||||||
m_trayIconMenu->addAction(m_ui->actionStartAll);
|
m_trayIconMenu->addAction(m_ui->actionStartAll);
|
||||||
m_trayIconMenu->addAction(m_ui->actionPauseAll);
|
m_trayIconMenu->addAction(m_ui->actionPauseAll);
|
||||||
|
|||||||
@@ -58,7 +58,7 @@ class TransferListWidget;
|
|||||||
|
|
||||||
namespace BitTorrent
|
namespace BitTorrent
|
||||||
{
|
{
|
||||||
class TorrentHandle;
|
class Torrent;
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace Net
|
namespace Net
|
||||||
@@ -110,7 +110,7 @@ private slots:
|
|||||||
void balloonClicked();
|
void balloonClicked();
|
||||||
void writeSettings();
|
void writeSettings();
|
||||||
void readSettings();
|
void readSettings();
|
||||||
void fullDiskError(BitTorrent::TorrentHandle *const torrent, const QString &msg) const;
|
void fullDiskError(BitTorrent::Torrent *const torrent, const QString &msg) const;
|
||||||
void handleDownloadFromUrlFailure(const QString &, const QString &) const;
|
void handleDownloadFromUrlFailure(const QString &, const QString &) const;
|
||||||
void tabChanged(int newTab);
|
void tabChanged(int newTab);
|
||||||
bool defineUILockPassword();
|
bool defineUILockPassword();
|
||||||
@@ -127,14 +127,12 @@ private slots:
|
|||||||
void displayExecutionLogTab();
|
void displayExecutionLogTab();
|
||||||
void focusSearchFilter();
|
void focusSearchFilter();
|
||||||
void reloadSessionStats();
|
void reloadSessionStats();
|
||||||
void reloadTorrentStats(const QVector<BitTorrent::TorrentHandle *> &torrents);
|
void reloadTorrentStats(const QVector<BitTorrent::Torrent *> &torrents);
|
||||||
void loadPreferences(bool configureSession = true);
|
void loadPreferences(bool configureSession = true);
|
||||||
void addTorrentFailed(const QString &error) const;
|
void addTorrentFailed(const QString &error) const;
|
||||||
void torrentNew(BitTorrent::TorrentHandle *const torrent) const;
|
void torrentNew(BitTorrent::Torrent *const torrent) const;
|
||||||
void finishedTorrent(BitTorrent::TorrentHandle *const torrent) const;
|
void finishedTorrent(BitTorrent::Torrent *const torrent) const;
|
||||||
void moveTorrentFinished(BitTorrent::TorrentHandle *const torrent, const QString &newPath) const;
|
void askRecursiveTorrentDownloadConfirmation(BitTorrent::Torrent *const torrent);
|
||||||
void moveTorrentFailed(BitTorrent::TorrentHandle *const torrent, const QString &targetPath, const QString &error) const;
|
|
||||||
void askRecursiveTorrentDownloadConfirmation(BitTorrent::TorrentHandle *const torrent);
|
|
||||||
void optionsSaved();
|
void optionsSaved();
|
||||||
#if defined(Q_OS_WIN) || defined(Q_OS_MACOS)
|
#if defined(Q_OS_WIN) || defined(Q_OS_MACOS)
|
||||||
void handleUpdateCheckFinished(bool updateAvailable, QString newVersion, bool invokedByUser);
|
void handleUpdateCheckFinished(bool updateAvailable, QString newVersion, bool invokedByUser);
|
||||||
@@ -171,8 +169,7 @@ private slots:
|
|||||||
void on_actionStatistics_triggered();
|
void on_actionStatistics_triggered();
|
||||||
void on_actionCreateTorrent_triggered();
|
void on_actionCreateTorrent_triggered();
|
||||||
void on_actionOptions_triggered();
|
void on_actionOptions_triggered();
|
||||||
void on_actionSetGlobalUploadLimit_triggered();
|
void on_actionSetGlobalSpeedLimits_triggered();
|
||||||
void on_actionSetGlobalDownloadLimit_triggered();
|
|
||||||
void on_actionDocumentation_triggered() const;
|
void on_actionDocumentation_triggered() const;
|
||||||
void on_actionOpen_triggered();
|
void on_actionOpen_triggered();
|
||||||
void on_actionDownloadFromURL_triggered();
|
void on_actionDownloadFromURL_triggered();
|
||||||
|
|||||||
@@ -223,29 +223,14 @@
|
|||||||
<string>Torrent &Creator</string>
|
<string>Torrent &Creator</string>
|
||||||
</property>
|
</property>
|
||||||
</action>
|
</action>
|
||||||
<action name="actionSetUploadLimit">
|
|
||||||
<property name="text">
|
|
||||||
<string>Set Upload Limit...</string>
|
|
||||||
</property>
|
|
||||||
</action>
|
|
||||||
<action name="actionSetDownloadLimit">
|
|
||||||
<property name="text">
|
|
||||||
<string>Set Download Limit...</string>
|
|
||||||
</property>
|
|
||||||
</action>
|
|
||||||
<action name="actionDocumentation">
|
<action name="actionDocumentation">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>&Documentation</string>
|
<string>&Documentation</string>
|
||||||
</property>
|
</property>
|
||||||
</action>
|
</action>
|
||||||
<action name="actionSetGlobalDownloadLimit">
|
<action name="actionSetGlobalSpeedLimits">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Set Global Download Limit...</string>
|
<string>Set Global Speed Limits...</string>
|
||||||
</property>
|
|
||||||
</action>
|
|
||||||
<action name="actionSetGlobalUploadLimit">
|
|
||||||
<property name="text">
|
|
||||||
<string>Set Global Upload Limit...</string>
|
|
||||||
</property>
|
</property>
|
||||||
</action>
|
</action>
|
||||||
<action name="actionBottomQueuePos">
|
<action name="actionBottomQueuePos">
|
||||||
|
|||||||
@@ -68,6 +68,8 @@
|
|||||||
#include "uithememanager.h"
|
#include "uithememanager.h"
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
|
|
||||||
|
#define SETTINGS_KEY(name) "OptionsDialog/" name
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
QStringList translatedWeekdayNames()
|
QStringList translatedWeekdayNames()
|
||||||
@@ -88,6 +90,7 @@ namespace
|
|||||||
{
|
{
|
||||||
case QLocale::Arabic: return QString::fromUtf8(C_LOCALE_ARABIC);
|
case QLocale::Arabic: return QString::fromUtf8(C_LOCALE_ARABIC);
|
||||||
case QLocale::Armenian: return QString::fromUtf8(C_LOCALE_ARMENIAN);
|
case QLocale::Armenian: return QString::fromUtf8(C_LOCALE_ARMENIAN);
|
||||||
|
case QLocale::Azerbaijani: return QString::fromUtf8(C_LOCALE_AZERBAIJANI);
|
||||||
case QLocale::Basque: return QString::fromUtf8(C_LOCALE_BASQUE);
|
case QLocale::Basque: return QString::fromUtf8(C_LOCALE_BASQUE);
|
||||||
case QLocale::Bulgarian: return QString::fromUtf8(C_LOCALE_BULGARIAN);
|
case QLocale::Bulgarian: return QString::fromUtf8(C_LOCALE_BULGARIAN);
|
||||||
case QLocale::Byelorussian: return QString::fromUtf8(C_LOCALE_BYELORUSSIAN);
|
case QLocale::Byelorussian: return QString::fromUtf8(C_LOCALE_BYELORUSSIAN);
|
||||||
@@ -110,6 +113,7 @@ namespace
|
|||||||
case QLocale::UnitedKingdom: return QString::fromUtf8(C_LOCALE_ENGLISH_UNITEDKINGDOM);
|
case QLocale::UnitedKingdom: return QString::fromUtf8(C_LOCALE_ENGLISH_UNITEDKINGDOM);
|
||||||
default: return QString::fromUtf8(C_LOCALE_ENGLISH);
|
default: return QString::fromUtf8(C_LOCALE_ENGLISH);
|
||||||
}
|
}
|
||||||
|
case QLocale::Estonian: return QString::fromUtf8(C_LOCALE_ESTONIAN);
|
||||||
case QLocale::Finnish: return QString::fromUtf8(C_LOCALE_FINNISH);
|
case QLocale::Finnish: return QString::fromUtf8(C_LOCALE_FINNISH);
|
||||||
case QLocale::French: return QString::fromUtf8(C_LOCALE_FRENCH);
|
case QLocale::French: return QString::fromUtf8(C_LOCALE_FRENCH);
|
||||||
case QLocale::Galician: return QString::fromUtf8(C_LOCALE_GALICIAN);
|
case QLocale::Galician: return QString::fromUtf8(C_LOCALE_GALICIAN);
|
||||||
@@ -127,7 +131,7 @@ namespace
|
|||||||
case QLocale::Latvian: return QString::fromUtf8(C_LOCALE_LATVIAN);
|
case QLocale::Latvian: return QString::fromUtf8(C_LOCALE_LATVIAN);
|
||||||
case QLocale::Lithuanian: return QString::fromUtf8(C_LOCALE_LITHUANIAN);
|
case QLocale::Lithuanian: return QString::fromUtf8(C_LOCALE_LITHUANIAN);
|
||||||
case QLocale::Malay: return QString::fromUtf8(C_LOCALE_MALAY);
|
case QLocale::Malay: return QString::fromUtf8(C_LOCALE_MALAY);
|
||||||
case QLocale::Norwegian: return QString::fromUtf8(C_LOCALE_NORWEGIAN);
|
case QLocale::NorwegianBokmal: return QString::fromUtf8(C_LOCALE_NORWEGIAN);
|
||||||
case QLocale::Occitan: return QString::fromUtf8(C_LOCALE_OCCITAN);
|
case QLocale::Occitan: return QString::fromUtf8(C_LOCALE_OCCITAN);
|
||||||
case QLocale::Polish: return QString::fromUtf8(C_LOCALE_POLISH);
|
case QLocale::Polish: return QString::fromUtf8(C_LOCALE_POLISH);
|
||||||
case QLocale::Portuguese:
|
case QLocale::Portuguese:
|
||||||
@@ -167,9 +171,10 @@ private:
|
|||||||
|
|
||||||
// Constructor
|
// Constructor
|
||||||
OptionsDialog::OptionsDialog(QWidget *parent)
|
OptionsDialog::OptionsDialog(QWidget *parent)
|
||||||
: QDialog(parent)
|
: QDialog {parent}
|
||||||
, m_refreshingIpFilter(false)
|
, m_ui {new Ui::OptionsDialog}
|
||||||
, m_ui(new Ui::OptionsDialog)
|
, m_storeDialogSize {SETTINGS_KEY("Size")}
|
||||||
|
, m_storeHSplitterSize {SETTINGS_KEY("HorizontalSplitterSizes")}
|
||||||
{
|
{
|
||||||
qDebug("-> Constructing Options");
|
qDebug("-> Constructing Options");
|
||||||
m_ui->setupUi(this);
|
m_ui->setupUi(this);
|
||||||
@@ -563,7 +568,7 @@ OptionsDialog::OptionsDialog(QWidget *parent)
|
|||||||
for (QSpinBox *widget : asConst(findChildren<QSpinBox *>()))
|
for (QSpinBox *widget : asConst(findChildren<QSpinBox *>()))
|
||||||
widget->installEventFilter(wheelEventEater);
|
widget->installEventFilter(wheelEventEater);
|
||||||
|
|
||||||
loadWindowState();
|
Utils::Gui::resize(this, m_storeDialogSize);
|
||||||
show();
|
show();
|
||||||
// Have to be called after show(), because splitter width needed
|
// Have to be called after show(), because splitter width needed
|
||||||
loadSplitterState();
|
loadSplitterState();
|
||||||
@@ -604,7 +609,13 @@ OptionsDialog::~OptionsDialog()
|
|||||||
{
|
{
|
||||||
qDebug("-> destructing Options");
|
qDebug("-> destructing Options");
|
||||||
|
|
||||||
saveWindowState();
|
// save dialog states
|
||||||
|
m_storeDialogSize = size();
|
||||||
|
|
||||||
|
QStringList hSplitterSizes;
|
||||||
|
for (const int size : asConst(m_ui->hsplitter->sizes()))
|
||||||
|
hSplitterSizes.append(QString::number(size));
|
||||||
|
m_storeHSplitterSize = hSplitterSizes;
|
||||||
|
|
||||||
for (const QString &path : asConst(m_addedScanDirs))
|
for (const QString &path : asConst(m_addedScanDirs))
|
||||||
ScanFoldersModel::instance()->removePath(path);
|
ScanFoldersModel::instance()->removePath(path);
|
||||||
@@ -619,38 +630,18 @@ void OptionsDialog::changePage(QListWidgetItem *current, QListWidgetItem *previo
|
|||||||
m_ui->tabOption->setCurrentIndex(m_ui->tabSelection->row(current));
|
m_ui->tabOption->setCurrentIndex(m_ui->tabSelection->row(current));
|
||||||
}
|
}
|
||||||
|
|
||||||
void OptionsDialog::loadWindowState()
|
|
||||||
{
|
|
||||||
Utils::Gui::resize(this, Preferences::instance()->getPrefSize());
|
|
||||||
}
|
|
||||||
|
|
||||||
void OptionsDialog::loadSplitterState()
|
void OptionsDialog::loadSplitterState()
|
||||||
{
|
{
|
||||||
const QStringList sizesStr = Preferences::instance()->getPrefHSplitterSizes();
|
|
||||||
|
|
||||||
// width has been modified, use height as width reference instead
|
// width has been modified, use height as width reference instead
|
||||||
const int width = Utils::Gui::scaledSize(this
|
const int width = Utils::Gui::scaledSize(this
|
||||||
, (m_ui->tabSelection->item(TAB_UI)->sizeHint().height() * 2));
|
, (m_ui->tabSelection->item(TAB_UI)->sizeHint().height() * 2));
|
||||||
QList<int> sizes {width, (m_ui->hsplitter->width() - width)};
|
const QStringList defaultSizes = {QString::number(width), QString::number(m_ui->hsplitter->width() - width)};
|
||||||
if (sizesStr.size() == 2)
|
|
||||||
sizes = {sizesStr.first().toInt(), sizesStr.last().toInt()};
|
|
||||||
m_ui->hsplitter->setSizes(sizes);
|
|
||||||
}
|
|
||||||
|
|
||||||
void OptionsDialog::saveWindowState() const
|
QList<int> splitterSizes;
|
||||||
{
|
for (const QString &string : asConst(m_storeHSplitterSize.get(defaultSizes)))
|
||||||
Preferences *const pref = Preferences::instance();
|
splitterSizes.append(string.toInt());
|
||||||
|
|
||||||
// window size
|
m_ui->hsplitter->setSizes(splitterSizes);
|
||||||
pref->setPrefSize(size());
|
|
||||||
|
|
||||||
// Splitter size
|
|
||||||
const QStringList sizesStr =
|
|
||||||
{
|
|
||||||
QString::number(m_ui->hsplitter->sizes().first()),
|
|
||||||
QString::number(m_ui->hsplitter->sizes().last())
|
|
||||||
};
|
|
||||||
pref->setPrefHSplitterSizes(sizesStr);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void OptionsDialog::saveOptions()
|
void OptionsDialog::saveOptions()
|
||||||
@@ -1612,6 +1603,8 @@ void OptionsDialog::setLocale(const QString &localeStr)
|
|||||||
QLocale locale(localeStr);
|
QLocale locale(localeStr);
|
||||||
if (locale.language() == QLocale::Uzbek)
|
if (locale.language() == QLocale::Uzbek)
|
||||||
name = "uz@Latn";
|
name = "uz@Latn";
|
||||||
|
else if (locale.language() == QLocale::Azerbaijani)
|
||||||
|
name = "az@latin";
|
||||||
else
|
else
|
||||||
name = locale.name();
|
name = locale.name();
|
||||||
}
|
}
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user