mirror of
https://github.com/qbittorrent/qBittorrent.git
synced 2025-12-24 01:08:06 -06:00
Compare commits
85 Commits
release-4.
...
release-4.
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3f0e0a319a | ||
|
|
0b4d9c72a7 | ||
|
|
ff71f6bcd9 | ||
|
|
7a5c5baad1 | ||
|
|
a18976d0b5 | ||
|
|
6d836ea49c | ||
|
|
2e97311147 | ||
|
|
57bc564b2c | ||
|
|
1295f1e31f | ||
|
|
4916ed0efb | ||
|
|
f15f99cb27 | ||
|
|
93365d3b20 | ||
|
|
c756ab021d | ||
|
|
34528dd544 | ||
|
|
9380209afb | ||
|
|
be2895ac6f | ||
|
|
e26d4642b8 | ||
|
|
f470972bd4 | ||
|
|
443378c041 | ||
|
|
e20dbe34a4 | ||
|
|
86bde47a06 | ||
|
|
e273c777c7 | ||
|
|
17845c6b25 | ||
|
|
27827ce16a | ||
|
|
b444ecc6af | ||
|
|
34995350ee | ||
|
|
73ceee52f8 | ||
|
|
85a3ba0eed | ||
|
|
86cce76e9d | ||
|
|
3358fd8e91 | ||
|
|
120965f823 | ||
|
|
e70ee9a5b6 | ||
|
|
a2d8e84e83 | ||
|
|
4a3648a693 | ||
|
|
baad45e638 | ||
|
|
d9cb00aab2 | ||
|
|
d703d98836 | ||
|
|
2f0646e7f0 | ||
|
|
1a8a6dcef7 | ||
|
|
990f961126 | ||
|
|
06f04dea19 | ||
|
|
8eced2ef1f | ||
|
|
1e486ea92e | ||
|
|
b47f38675e | ||
|
|
864f3393a0 | ||
|
|
cebef74326 | ||
|
|
e257b35cac | ||
|
|
1f33991e4b | ||
|
|
794053f212 | ||
|
|
3a130e1f74 | ||
|
|
3423f93230 | ||
|
|
2219167253 | ||
|
|
a0a32b89a6 | ||
|
|
59162bf426 | ||
|
|
dfd148f55f | ||
|
|
3af720b3bc | ||
|
|
11240d0837 | ||
|
|
e64fd9c544 | ||
|
|
50ef812427 | ||
|
|
bd4d2fa424 | ||
|
|
e2ee928017 | ||
|
|
62e71a15a4 | ||
|
|
c62127e9f1 | ||
|
|
2171d579ee | ||
|
|
6e5a969e2d | ||
|
|
bfbc7ef28a | ||
|
|
b1cefbf9b5 | ||
|
|
201638854e | ||
|
|
847ecdeedb | ||
|
|
acc159fa60 | ||
|
|
bb7e80a8a6 | ||
|
|
39973f1bb1 | ||
|
|
1e9151364a | ||
|
|
fd50d6e9af | ||
|
|
427acf0c46 | ||
|
|
f0a50424be | ||
|
|
aded9afc0e | ||
|
|
060b7480db | ||
|
|
7f2a01dcd6 | ||
|
|
fef0e70c9f | ||
|
|
9cc112aa4e | ||
|
|
44d4d41365 | ||
|
|
a21c386dbf | ||
|
|
1c4139906a | ||
|
|
1a21f45c75 |
43
.travis.yml
43
.travis.yml
@@ -4,6 +4,8 @@ os:
|
||||
- linux
|
||||
- osx
|
||||
|
||||
dist: xenial
|
||||
|
||||
env:
|
||||
matrix:
|
||||
# Uncomment when Travis upgraded "Ubuntu 12.04 LTS" to a newer version whose repo will have a more up-to-date libtorrent package
|
||||
@@ -37,11 +39,6 @@ cache:
|
||||
directories:
|
||||
- $HOME/hombebrew_cache
|
||||
|
||||
# opt-in Ubuntu Trusty
|
||||
dist: trusty
|
||||
# container-based builds
|
||||
sudo: false
|
||||
|
||||
addons:
|
||||
coverity_scan:
|
||||
project:
|
||||
@@ -53,34 +50,30 @@ addons:
|
||||
notification_email: sledgehammer999@qbittorrent.org
|
||||
apt:
|
||||
sources:
|
||||
# sources list: https://github.com/travis-ci/apt-source-whitelist/blob/master/ubuntu.json
|
||||
- ubuntu-toolchain-r-test
|
||||
#- boost-latest
|
||||
# sources list: https://github.com/travis-ci/apt-source-safelist/blob/master/ubuntu.json
|
||||
- sourceline: 'ppa:qbittorrent-team/qbittorrent-stable'
|
||||
- sourceline: 'ppa:beineri/opt-qt551-trusty'
|
||||
- sourceline: 'ppa:adrozdoff/cmake'
|
||||
packages:
|
||||
# packages list: https://github.com/travis-ci/apt-package-whitelist/blob/master/ubuntu-precise
|
||||
# packages list: https://github.com/travis-ci/apt-package-safelist/blob/master/ubuntu-trusty
|
||||
- [autoconf, automake, colormake]
|
||||
- [cmake, ninja-build]
|
||||
- [ninja-build]
|
||||
- libssl-dev
|
||||
- [libboost-dev, libboost-system-dev]
|
||||
- libtorrent-rasterbar-dev
|
||||
- [qt55base, qt55svg, qt55tools]
|
||||
- [gcc-6, g++-6]
|
||||
- [qtbase5-dev, qttools5-dev-tools, libqt5svg5-dev]
|
||||
|
||||
before_install:
|
||||
# only allow specific build for coverity scan, others will stop
|
||||
- if [ "$TRAVIS_BRANCH" = "$coverity_branch" ] && ! [ "$TRAVIS_OS_NAME" = "linux" -a "$lt_branch" = "RC_1_0" -a "$gui" = true -a "$build_system" = "qmake" ]; then exit ; fi
|
||||
|
||||
- shopt -s expand_aliases
|
||||
- alias make="colormake -j3" # Using nprocs/2 sometimes may fail (gcc is killed by system)
|
||||
- alias make="colormake -j2" # Using nprocs/2 sometimes may fail (gcc is killed by system)
|
||||
- qbt_path="$HOME/qbt_install"
|
||||
- |
|
||||
if [ "$TRAVIS_OS_NAME" = "linux" ]; then
|
||||
qbtconf="$qbtconf --prefix="$qbt_path" PKG_CONFIG_PATH=/opt/qt55/lib/pkgconfig:$PKG_CONFIG_PATH"
|
||||
else
|
||||
qbtconf="$qbtconf --prefix="$qbt_path""
|
||||
CXXFLAGS="$CXXFLAGS -Wno-unused-local-typedefs -Wno-inconsistent-missing-override"
|
||||
fi
|
||||
|
||||
# options for specific branches
|
||||
@@ -89,14 +82,6 @@ before_install:
|
||||
if [ "$TRAVIS_OS_NAME" = "linux" ]; then
|
||||
# setup virtual display for after_success target
|
||||
if [ "$gui" = true ]; then export "DISPLAY=:99.0" && /sbin/start-stop-daemon --start --quiet --pidfile /tmp/custom_xvfb_99.pid --make-pidfile --background --exec /usr/bin/Xvfb -- :99 -ac -screen 0 1280x1024x16 ; fi ;
|
||||
|
||||
# Qt 5
|
||||
PATH=/opt/qt55/bin:${PATH}
|
||||
|
||||
if [ "$build_system" = "cmake" ]; then
|
||||
COMPILER_VERSION=6
|
||||
export CXX="${CXX}-${COMPILER_VERSION}" CC="${CC}-${COMPILER_VERSION}"
|
||||
fi
|
||||
fi
|
||||
|
||||
# print settings
|
||||
@@ -137,6 +122,7 @@ install:
|
||||
- |
|
||||
if [ "$TRAVIS_BRANCH" != "$coverity_branch" ]; then
|
||||
export use_ccache=true
|
||||
ccache -M 512M
|
||||
ccache -V && ccache --show-stats && ccache --zero-stats
|
||||
fi
|
||||
|
||||
@@ -155,16 +141,7 @@ script:
|
||||
BUILD_TOOL="ninja"
|
||||
fi
|
||||
if [ "$build_system" = "qmake" ]; then
|
||||
if [ "$TRAVIS_OS_NAME" = "osx" ]; then
|
||||
# For some reason for RC_1_1 we need to also specify the OpenSSL compiler/linker flags
|
||||
# Homebrew doesn't symlink OpenSSL for security reasons
|
||||
./bootstrap.sh && ./configure $qbtconf CXXFLAGS="$(PKG_CONFIG_PATH="/usr/local/opt/openssl/lib/pkgconfig:$PKG_CONFIG_PATH" pkg-config --cflags openssl)" LDFLAGS="$(PKG_CONFIG_PATH="/usr/local/opt/openssl/lib/pkgconfig:$PKG_CONFIG_PATH" pkg-config --libs openssl)"
|
||||
sed -i "" -e "s/^\(CC.*&&\).*$/\1 $CC/" src/Makefile # workaround for Qt & ccache: https://bugreports.qt.io/browse/QTBUG-31034
|
||||
sed -i "" -e "s/^\(CXX.*&&\).*$/\1 $CXX/" src/Makefile
|
||||
sed -i "" -e 's/^\(CXXFLAGS.*\)$/\1 -Wno-unused-local-typedefs -Wno-inconsistent-missing-override/' src/Makefile
|
||||
else
|
||||
./bootstrap.sh && ./configure $qbtconf
|
||||
fi
|
||||
./bootstrap.sh && ./configure $qbtconf CXXFLAGS="$CXXFLAGS"
|
||||
BUILD_TOOL="make"
|
||||
fi
|
||||
- $BUILD_TOOL && $BUILD_TOOL install
|
||||
|
||||
10
.tx/config
10
.tx/config
@@ -10,10 +10,18 @@ type = QT
|
||||
minimum_perc = 23
|
||||
mode = developer
|
||||
|
||||
|
||||
[qbittorrent.qbittorrentdesktop_master]
|
||||
source_file = dist/unix/qbittorrent.desktop
|
||||
source_lang = en
|
||||
type = DESKTOP
|
||||
minimum_perc = 23
|
||||
mode = developer
|
||||
|
||||
[qbittorrent.qbittorrent_webui]
|
||||
file_filter = src/webui/www/translations/webui_<lang>.ts
|
||||
lang_map = pt: pt_PT
|
||||
source_file = src/webui/www/translations/webui_en.ts
|
||||
source_lang = en
|
||||
type = QT
|
||||
minimum_perc = 23
|
||||
mode = developer
|
||||
|
||||
54
Changelog
54
Changelog
@@ -1,3 +1,57 @@
|
||||
* Mon Dec 24 2018 - sledgehammer999 <sledgehammer999@qbittorrent.org> - v4.1.5
|
||||
- FEATURE: Add checking_mem_usage option to AdvancedSettings (FranciscoPombal)
|
||||
- FEATURE: Save torrents queue in separate file. Now a new file named 'queue' is created, saving on each line the infohash of each queued torrent in sorted order. (glassez)
|
||||
- BUGFIX: Fix regression on resuming torrents without metadata (thalieht)
|
||||
- BUGFIX: Reorder and rename Tracker list context menu option (Thomas Piccirello)
|
||||
- BUGFIX: Rename Tracker List columns (Thomas Piccirello)
|
||||
- BUGFIX: Show error message when Session failed to start (glassez)
|
||||
- BUGFIX: Embedded tracker: Use ip parameter from tracker request if provided (Chocobo1)
|
||||
- BUGFIX: Fix weekday names translations (Chocobo1)
|
||||
- BUGFIX: Fix strings not translated (Chocobo1)
|
||||
- WEBUI: Change qBittorrent exit message to HTML5 (Chocobo1)
|
||||
- WEBUI: Revise CSP header (Chocobo1)
|
||||
- WEBUI: Enforce referrer-policy in WebUI (Chocobo1)
|
||||
- WEBUI: Add torrent name filtering to WebUI (Thomas Piccirello)
|
||||
- WEBUI: Send numeric status without translation (Thomas Piccirello)
|
||||
- WEBUI: Add WebUI Trackers context menu (Thomas Piccirello)
|
||||
- WEBUI: Add DHT, PeX, and LSD to WebUI Tracker list (Thomas Piccirello)
|
||||
- WEBUI: Add additional Tracker columns to WebUI (Thomas Piccirello)
|
||||
- WEBUI: Bump Web API version
|
||||
- WEBUI: Fix display bugs in WebUI Files tab. Remove <IE9 support (Thomas Piccirello)
|
||||
- WEBUI: Fix incorrect priority value sent from WebUI (Thomas Piccirello)
|
||||
- WEBUI: Set priority for multiple files in one WebAPI request (Thomas Piccirello)
|
||||
- WEBUI: Match WebUI Peers table column order to GUI (Thomas Piccirello)
|
||||
- WEBUI: Fetch data less frequently when torrents tab isn't visible (Thomas Piccirello)
|
||||
- WEBUI: Add Search tab to WebUI (Thomas Piccirello)
|
||||
- WEBUI: Add ability to pass urls to the webui download page (Thomas Piccirello)
|
||||
- WEBUI: Fix JavaScript error (Tom Piccirello)
|
||||
- WEBUI: Disallow setting a blank alternative WebUI location (Thomas Piccirello)
|
||||
- WEBUI: Add slow torrent options (Thomas Piccirello)
|
||||
- WEBUI: Add "Use alternative Web UI" option (Thomas Piccirello)
|
||||
- WEBUI: Add "Apply rate limit to peers on LAN" option (Thomas Piccirello)
|
||||
- WEBUI: Add email "From" option (Thomas Piccirello)
|
||||
- WEBUI: Set WebUI download options using set preferences (Thomas Piccirello)
|
||||
- WEBUI: Show list of categories on WebUI download page (Thomas Piccirello)
|
||||
- WEBUI: Hide WebUI text input for custom monitor save locations (Thomas Piccirello)
|
||||
- WEBUI: Add "When adding a torrent" options (Thomas Piccirello)
|
||||
- WEBUI: Add WebUI Auto TMM options (Thomas Piccirello)
|
||||
- WEBUI: Add speed limit icons to WebUI Speed options (Thomas Piccirello)
|
||||
- WEBUI: Add WebUI Random port button and proxy unencrypted password notice (Thomas Piccirello)
|
||||
- WEBUI: Replace WebUI Options fixed-width labels (Thomas Piccirello)
|
||||
- WEBUI: Reorder WebUI options to match GUI (Thomas Piccirello)
|
||||
- WEBUI: Allow WebUI sidebar to be collapsed (Thomas Piccirello)
|
||||
- WEBUI: Show ellipsis when WebUI sidebar is too narrow (Thomas Piccirello)
|
||||
- WEBUI: Fix WebUI bug on override of Start Download option.Closes #9855. (Tom Piccirello)
|
||||
- WEBUI: Fix missing words in WebUI (Chocobo1)
|
||||
- WEBUI: Add SameSite attribute to WebUI session cookie (Thomas Piccirello)
|
||||
- WEBUI: Put WebUI security related options into a groupbox (Chocobo1)
|
||||
- WEBUI: Add option for WebUI Host header validation (Chocobo1)
|
||||
- WEBUI: Show icon in WebUI sorted column (Thomas Piccirello)
|
||||
- RSS: Keep track of REPACK/PROPER downloads. Closes #9898. (Stephen Dawkins)
|
||||
- SEARCH: Only instantiate SearchPluginManager as needed (Thomas Piccirello)
|
||||
- MACOS: Make file icon look like other macOS icons (Nick Korotysh)
|
||||
- MACOS: Save option to start minimized in Mac (thalieht)
|
||||
|
||||
* Mon Nov 19 2018 - sledgehammer999 <sledgehammer999@qbittorrent.org> - v4.1.4
|
||||
- FEATURE: Recognize *.ts files as previewable (silver)
|
||||
- FEATURE: Allow to disable speed graphs (dzmat)
|
||||
|
||||
@@ -5,6 +5,8 @@ BINDIR = @EXPAND_BINDIR@
|
||||
DATADIR = @EXPAND_DATADIR@
|
||||
MANPREFIX = @EXPAND_MANDIR@
|
||||
|
||||
QMAKE_CC = @QBT_CC@
|
||||
QMAKE_CXX = @QBT_CXX@
|
||||
QMAKE_CXXFLAGS += @QBT_CONF_EXTRA_CFLAGS@
|
||||
|
||||
EXTERNAL_INCLUDES = @QBT_CONF_INCLUDES@
|
||||
|
||||
476
configure
vendored
476
configure
vendored
@@ -1,6 +1,6 @@
|
||||
#! /bin/sh
|
||||
# Guess values for system-dependent variables and create Makefiles.
|
||||
# Generated by GNU Autoconf 2.69 for qbittorrent v4.1.4.
|
||||
# Generated by GNU Autoconf 2.69 for qbittorrent v4.1.5.
|
||||
#
|
||||
# Report bugs to <bugs.qbittorrent.org>.
|
||||
#
|
||||
@@ -580,8 +580,8 @@ MAKEFLAGS=
|
||||
# Identity of this package.
|
||||
PACKAGE_NAME='qbittorrent'
|
||||
PACKAGE_TARNAME='qbittorrent'
|
||||
PACKAGE_VERSION='v4.1.4'
|
||||
PACKAGE_STRING='qbittorrent v4.1.4'
|
||||
PACKAGE_VERSION='v4.1.5'
|
||||
PACKAGE_STRING='qbittorrent v4.1.5'
|
||||
PACKAGE_BUGREPORT='bugs.qbittorrent.org'
|
||||
PACKAGE_URL='https://www.qbittorrent.org/'
|
||||
|
||||
@@ -595,6 +595,8 @@ QBT_REMOVE_CONFIG
|
||||
QBT_ADD_CONFIG
|
||||
QBT_CONF_EXTRA_CFLAGS
|
||||
QBT_CONF_INCLUDES
|
||||
QBT_CXX
|
||||
QBT_CC
|
||||
EXPAND_MANDIR
|
||||
EXPAND_DATADIR
|
||||
EXPAND_BINDIR
|
||||
@@ -626,7 +628,6 @@ am__nodep
|
||||
AMDEPBACKSLASH
|
||||
AMDEP_FALSE
|
||||
AMDEP_TRUE
|
||||
am__quote
|
||||
am__include
|
||||
DEPDIR
|
||||
am__untar
|
||||
@@ -709,7 +710,8 @@ PACKAGE_VERSION
|
||||
PACKAGE_TARNAME
|
||||
PACKAGE_NAME
|
||||
PATH_SEPARATOR
|
||||
SHELL'
|
||||
SHELL
|
||||
am__quote'
|
||||
ac_subst_files=''
|
||||
ac_user_opts='
|
||||
enable_option_checking
|
||||
@@ -1297,7 +1299,7 @@ if test "$ac_init_help" = "long"; then
|
||||
# Omit some internal or obsolete options to make the list less imposing.
|
||||
# This message is too long to be a string in the A/UX 3.1 sh.
|
||||
cat <<_ACEOF
|
||||
\`configure' configures qbittorrent v4.1.4 to adapt to many kinds of systems.
|
||||
\`configure' configures qbittorrent v4.1.5 to adapt to many kinds of systems.
|
||||
|
||||
Usage: $0 [OPTION]... [VAR=VALUE]...
|
||||
|
||||
@@ -1368,7 +1370,7 @@ fi
|
||||
|
||||
if test -n "$ac_init_help"; then
|
||||
case $ac_init_help in
|
||||
short | recursive ) echo "Configuration of qbittorrent v4.1.4:";;
|
||||
short | recursive ) echo "Configuration of qbittorrent v4.1.5:";;
|
||||
esac
|
||||
cat <<\_ACEOF
|
||||
|
||||
@@ -1503,7 +1505,7 @@ fi
|
||||
test -n "$ac_init_help" && exit $ac_status
|
||||
if $ac_init_version; then
|
||||
cat <<\_ACEOF
|
||||
qbittorrent configure v4.1.4
|
||||
qbittorrent configure v4.1.5
|
||||
generated by GNU Autoconf 2.69
|
||||
|
||||
Copyright (C) 2012 Free Software Foundation, Inc.
|
||||
@@ -1642,7 +1644,7 @@ cat >config.log <<_ACEOF
|
||||
This file contains any messages produced by compilers while
|
||||
running configure, to aid debugging if configure makes a mistake.
|
||||
|
||||
It was created by qbittorrent $as_me v4.1.4, which was
|
||||
It was created by qbittorrent $as_me v4.1.5, which was
|
||||
generated by GNU Autoconf 2.69. Invocation command line was
|
||||
|
||||
$ $0 $@
|
||||
@@ -3274,7 +3276,7 @@ IFS=$ac_save_IFS
|
||||
case $host_os in *\ *) host_os=`echo "$host_os" | sed 's/ /-/g'`;; esac
|
||||
|
||||
|
||||
am__api_version='1.15'
|
||||
am__api_version='1.16'
|
||||
|
||||
# Find a good install program. We prefer a C program (faster),
|
||||
# so one script is as good as another. But avoid the broken or
|
||||
@@ -3700,45 +3702,45 @@ DEPDIR="${am__leading_dot}deps"
|
||||
|
||||
ac_config_commands="$ac_config_commands depfiles"
|
||||
|
||||
|
||||
am_make=${MAKE-make}
|
||||
cat > confinc << 'END'
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} supports the include directive" >&5
|
||||
$as_echo_n "checking whether ${MAKE-make} supports the include directive... " >&6; }
|
||||
cat > confinc.mk << 'END'
|
||||
am__doit:
|
||||
@echo this is the am__doit target
|
||||
@echo this is the am__doit target >confinc.out
|
||||
.PHONY: am__doit
|
||||
END
|
||||
# If we don't find an include directive, just comment out the code.
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for style of include used by $am_make" >&5
|
||||
$as_echo_n "checking for style of include used by $am_make... " >&6; }
|
||||
am__include="#"
|
||||
am__quote=
|
||||
_am_result=none
|
||||
# First try GNU make style include.
|
||||
echo "include confinc" > confmf
|
||||
# Ignore all kinds of additional output from 'make'.
|
||||
case `$am_make -s -f confmf 2> /dev/null` in #(
|
||||
*the\ am__doit\ target*)
|
||||
am__include=include
|
||||
am__quote=
|
||||
_am_result=GNU
|
||||
;;
|
||||
esac
|
||||
# Now try BSD make style include.
|
||||
if test "$am__include" = "#"; then
|
||||
echo '.include "confinc"' > confmf
|
||||
case `$am_make -s -f confmf 2> /dev/null` in #(
|
||||
*the\ am__doit\ target*)
|
||||
am__include=.include
|
||||
am__quote="\""
|
||||
_am_result=BSD
|
||||
# BSD make does it like this.
|
||||
echo '.include "confinc.mk" # ignored' > confmf.BSD
|
||||
# Other make implementations (GNU, Solaris 10, AIX) do it like this.
|
||||
echo 'include confinc.mk # ignored' > confmf.GNU
|
||||
_am_result=no
|
||||
for s in GNU BSD; do
|
||||
{ echo "$as_me:$LINENO: ${MAKE-make} -f confmf.$s && cat confinc.out" >&5
|
||||
(${MAKE-make} -f confmf.$s && cat confinc.out) >&5 2>&5
|
||||
ac_status=$?
|
||||
echo "$as_me:$LINENO: \$? = $ac_status" >&5
|
||||
(exit $ac_status); }
|
||||
case $?:`cat confinc.out 2>/dev/null` in #(
|
||||
'0:this is the am__doit target') :
|
||||
case $s in #(
|
||||
BSD) :
|
||||
am__include='.include' am__quote='"' ;; #(
|
||||
*) :
|
||||
am__include='include' am__quote='' ;;
|
||||
esac ;; #(
|
||||
*) :
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
|
||||
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $_am_result" >&5
|
||||
$as_echo "$_am_result" >&6; }
|
||||
rm -f confinc confmf
|
||||
esac
|
||||
if test "$am__include" != "#"; then
|
||||
_am_result="yes ($s style)"
|
||||
break
|
||||
fi
|
||||
done
|
||||
rm -f confinc.* confmf.*
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: ${_am_result}" >&5
|
||||
$as_echo "${_am_result}" >&6; }
|
||||
|
||||
# Check whether --enable-dependency-tracking was given.
|
||||
if test "${enable_dependency_tracking+set}" = set; then :
|
||||
@@ -3820,7 +3822,7 @@ fi
|
||||
|
||||
# Define the identity of the package.
|
||||
PACKAGE='qbittorrent'
|
||||
VERSION='v4.1.4'
|
||||
VERSION='v4.1.5'
|
||||
|
||||
|
||||
cat >>confdefs.h <<_ACEOF
|
||||
@@ -3850,8 +3852,8 @@ MAKEINFO=${MAKEINFO-"${am_missing_run}makeinfo"}
|
||||
|
||||
# For better backward compatibility. To be removed once Automake 1.9.x
|
||||
# dies out for good. For more background, see:
|
||||
# <http://lists.gnu.org/archive/html/automake/2012-07/msg00001.html>
|
||||
# <http://lists.gnu.org/archive/html/automake/2012-07/msg00014.html>
|
||||
# <https://lists.gnu.org/archive/html/automake/2012-07/msg00001.html>
|
||||
# <https://lists.gnu.org/archive/html/automake/2012-07/msg00014.html>
|
||||
mkdir_p='$(MKDIR_P)'
|
||||
|
||||
# We need awk for the "check" target (and possibly the TAP driver). The
|
||||
@@ -4158,7 +4160,7 @@ END
|
||||
Aborting the configuration process, to ensure you take notice of the issue.
|
||||
|
||||
You can download and install GNU coreutils to get an 'rm' implementation
|
||||
that behaves properly: <http://www.gnu.org/software/coreutils/>.
|
||||
that behaves properly: <https://www.gnu.org/software/coreutils/>.
|
||||
|
||||
If you want to complete the configuration process using your problematic
|
||||
'rm' anyway, export the environment variable ACCEPT_INFERIOR_RM_PROGRAM
|
||||
@@ -4170,7 +4172,9 @@ END
|
||||
fi
|
||||
|
||||
|
||||
|
||||
# use compiler from env variables if available
|
||||
QBT_CC="$CC"
|
||||
QBT_CXX="$CXX"
|
||||
|
||||
# Define --wth-* and --enable-* arguments
|
||||
|
||||
@@ -4997,10 +5001,10 @@ $as_echo "$as_me: Your boost libraries seems to old (version $_version)." >&6;}
|
||||
$as_echo "#define HAVE_BOOST /**/" >>confdefs.h
|
||||
|
||||
# execute ACTION-IF-FOUND (if present):
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: Boost CPPFLAGS: \"$BOOST_CPPFLAGS\"
|
||||
Boost LDFLAGS: \"$BOOST_LDFLAGS\"" >&5
|
||||
$as_echo "$as_me: Boost CPPFLAGS: \"$BOOST_CPPFLAGS\"
|
||||
Boost LDFLAGS: \"$BOOST_LDFLAGS\"" >&6;}
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: Boost CXXFLAGS: \"$BOOST_CPPFLAGS\"" >&5
|
||||
$as_echo "$as_me: Boost CXXFLAGS: \"$BOOST_CPPFLAGS\"" >&6;}
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: Boost LDFLAGS: \"$BOOST_LDFLAGS\"" >&5
|
||||
$as_echo "$as_me: Boost LDFLAGS: \"$BOOST_LDFLAGS\"" >&6;}
|
||||
fi
|
||||
|
||||
CPPFLAGS="$CPPFLAGS_SAVED"
|
||||
@@ -5011,16 +5015,10 @@ fi
|
||||
|
||||
|
||||
|
||||
CPPFLAGS="$BOOST_CPPFLAGS $CPPFLAGS"
|
||||
CXXFLAGS="$BOOST_CPPFLAGS $CXXFLAGS"
|
||||
LDFLAGS="$BOOST_LDFLAGS $LDFLAGS"
|
||||
|
||||
# add workaround for problematic boost version
|
||||
ac_ext=cpp
|
||||
ac_cpp='$CXXCPP $CPPFLAGS'
|
||||
ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
|
||||
ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
|
||||
ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
|
||||
|
||||
# taken from ax_boost_base.m4
|
||||
|
||||
|
||||
@@ -5041,12 +5039,6 @@ else
|
||||
QBT_ADD_DEFINES="$QBT_ADD_DEFINES BOOST_NO_CXX11_RVALUE_REFERENCES"
|
||||
fi
|
||||
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
|
||||
ac_ext=cpp
|
||||
ac_cpp='$CXXCPP $CPPFLAGS'
|
||||
ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
|
||||
ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
|
||||
ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -5400,7 +5392,7 @@ else
|
||||
libtorrent_LIBS=$pkg_cv_libtorrent_LIBS
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
|
||||
$as_echo "yes" >&6; }
|
||||
CPPFLAGS="$libtorrent_CFLAGS $CPPFLAGS"
|
||||
CXXFLAGS="$libtorrent_CFLAGS $CXXFLAGS"
|
||||
LIBS="$libtorrent_LIBS $LIBS"
|
||||
fi
|
||||
|
||||
@@ -5493,10 +5485,116 @@ else
|
||||
zlib_LIBS=$pkg_cv_zlib_LIBS
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
|
||||
$as_echo "yes" >&6; }
|
||||
CPPFLAGS="$zlib_CFLAGS $CPPFLAGS"
|
||||
CXXFLAGS="$zlib_CFLAGS $CXXFLAGS"
|
||||
LIBS="$zlib_LIBS $LIBS"
|
||||
fi
|
||||
|
||||
# Check if already in >= C++11 mode because of the flags returned by one of the above packages
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if compiler is using C++11 or later mode" >&5
|
||||
$as_echo_n "checking if compiler is using C++11 or later mode... " >&6; }
|
||||
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
||||
/* end confdefs.h. */
|
||||
|
||||
#ifndef __cplusplus
|
||||
#error "This is not a C++ compiler"
|
||||
#elif __cplusplus < 201103L
|
||||
#error "This is not a C++11 compiler"
|
||||
#endif
|
||||
int
|
||||
main ()
|
||||
{
|
||||
|
||||
;
|
||||
return 0;
|
||||
}
|
||||
|
||||
_ACEOF
|
||||
if ac_fn_cxx_try_compile "$LINENO"; then :
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
|
||||
$as_echo "yes" >&6; }
|
||||
QBT_CXX11_FOUND="yes"
|
||||
else
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
|
||||
$as_echo "no" >&6; }
|
||||
QBT_CXX11_FOUND="no"
|
||||
fi
|
||||
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
|
||||
|
||||
# In case of no, check if the compiler can support at least C++11
|
||||
# and if yes, enable it leaving a warning to the user
|
||||
if test "x$QBT_CXX11_FOUND" = "xno"; then :
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if compiler supports C++11" >&5
|
||||
$as_echo_n "checking if compiler supports C++11... " >&6; }
|
||||
TMP_CXXFLAGS="$CXXFLAGS"
|
||||
CXXFLAGS="$CXXFLAGS -std=c++11"
|
||||
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
||||
/* end confdefs.h. */
|
||||
|
||||
#ifndef __cplusplus
|
||||
#error "This is not a C++ compiler"
|
||||
#elif __cplusplus < 201103L
|
||||
#error "This is not a C++11 compiler"
|
||||
#endif
|
||||
int
|
||||
main ()
|
||||
{
|
||||
|
||||
;
|
||||
return 0;
|
||||
}
|
||||
|
||||
_ACEOF
|
||||
if ac_fn_cxx_try_compile "$LINENO"; then :
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
|
||||
$as_echo "yes" >&6; }
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if C++11 is disabled by the set compiler flags" >&5
|
||||
$as_echo_n "checking if C++11 is disabled by the set compiler flags... " >&6; }
|
||||
# prepend the flag so it won't override conflicting user defined flags
|
||||
CXXFLAGS="-std=c++11 $TMP_CXXFLAGS"
|
||||
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
||||
/* end confdefs.h. */
|
||||
|
||||
#ifndef __cplusplus
|
||||
#error "This is not a C++ compiler"
|
||||
#elif __cplusplus < 201103L
|
||||
#error "This is not a C++11 compiler"
|
||||
#endif
|
||||
int
|
||||
main ()
|
||||
{
|
||||
|
||||
;
|
||||
return 0;
|
||||
}
|
||||
|
||||
_ACEOF
|
||||
if ac_fn_cxx_try_compile "$LINENO"; then :
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
|
||||
$as_echo "no" >&6; }
|
||||
CXXFLAGS="$TMP_CXXFLAGS -std=c++11"
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: C++11 mode is now force enabled.
|
||||
Make sure you use the same C++ mode for qBittorrent and its dependencies.
|
||||
To explicitly set qBittorrent to a later mode use CXXFLAGS.
|
||||
Example: \`CXXFLAGS=\"\$CXXFLAGS -std=c++14\" ./configure\`" >&5
|
||||
$as_echo "$as_me: WARNING: C++11 mode is now force enabled.
|
||||
Make sure you use the same C++ mode for qBittorrent and its dependencies.
|
||||
To explicitly set qBittorrent to a later mode use CXXFLAGS.
|
||||
Example: \`CXXFLAGS=\"\$CXXFLAGS -std=c++14\" ./configure\`" >&2;}
|
||||
else
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
|
||||
$as_echo "yes" >&6; }
|
||||
as_fn_error $? "The compiler supports C++11 but the user or a dependency has explicitly enabled a lower mode." "$LINENO" 5
|
||||
fi
|
||||
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
|
||||
else
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
|
||||
$as_echo "no" >&6; }
|
||||
as_fn_error $? "A compiler supporting C++11 is required." "$LINENO" 5
|
||||
fi
|
||||
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
|
||||
|
||||
fi
|
||||
|
||||
# These are required because autoconf doesn't expand these **particular**
|
||||
# vars automatically. And qmake cannot autoexpand them.
|
||||
|
||||
@@ -5583,15 +5681,15 @@ extract() {
|
||||
for i in $string; do
|
||||
case "$(echo "$i" | cut -c1)" in
|
||||
'') ;;
|
||||
D) QBT_CONF_DEFINES="$(echo $i | cut -c2-) $QBT_CONF_DEFINES";;
|
||||
I) QBT_CONF_INCLUDES="$(echo $i | cut -c2-) $QBT_CONF_INCLUDES";;
|
||||
*) QBT_CONF_EXTRA_CFLAGS="-$i $QBT_CONF_EXTRA_CFLAGS";;
|
||||
D) QBT_CONF_DEFINES="$QBT_CONF_DEFINES $(echo $i | cut -c2-)";;
|
||||
I) QBT_CONF_INCLUDES="$QBT_CONF_INCLUDES $(echo $i | cut -c2-)";;
|
||||
*) QBT_CONF_EXTRA_CFLAGS="$QBT_CONF_EXTRA_CFLAGS -$i";;
|
||||
esac
|
||||
done
|
||||
IFS=$SAVEIFS
|
||||
}
|
||||
|
||||
extract "$CFLAGS $CPPFLAGS $CXXFLAGS"
|
||||
extract "$CFLAGS $CXXFLAGS"
|
||||
QBT_ADD_DEFINES="$QBT_ADD_DEFINES $QBT_CONF_DEFINES"
|
||||
|
||||
# Substitute the values of these vars in conf.pri.in
|
||||
@@ -5602,6 +5700,8 @@ QBT_ADD_DEFINES="$QBT_ADD_DEFINES $QBT_CONF_DEFINES"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
ac_config_files="$ac_config_files conf.pri"
|
||||
|
||||
cat >confcache <<\_ACEOF
|
||||
@@ -6174,7 +6274,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
|
||||
# report actual input values of CONFIG_FILES etc. instead of their
|
||||
# values after options handling.
|
||||
ac_log="
|
||||
This file was extended by qbittorrent $as_me v4.1.4, which was
|
||||
This file was extended by qbittorrent $as_me v4.1.5, which was
|
||||
generated by GNU Autoconf 2.69. Invocation command line was
|
||||
|
||||
CONFIG_FILES = $CONFIG_FILES
|
||||
@@ -6232,7 +6332,7 @@ _ACEOF
|
||||
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
|
||||
ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
|
||||
ac_cs_version="\\
|
||||
qbittorrent config.status v4.1.4
|
||||
qbittorrent config.status v4.1.5
|
||||
configured by $0, generated by GNU Autoconf 2.69,
|
||||
with options \\"\$ac_cs_config\\"
|
||||
|
||||
@@ -6340,7 +6440,7 @@ cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
|
||||
#
|
||||
# INIT-COMMANDS
|
||||
#
|
||||
AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"
|
||||
AMDEP_TRUE="$AMDEP_TRUE" MAKE="${MAKE-make}"
|
||||
|
||||
_ACEOF
|
||||
|
||||
@@ -6785,29 +6885,35 @@ $as_echo "$as_me: executing $ac_file commands" >&6;}
|
||||
# Older Autoconf quotes --file arguments for eval, but not when files
|
||||
# are listed without --file. Let's play safe and only enable the eval
|
||||
# if we detect the quoting.
|
||||
case $CONFIG_FILES in
|
||||
*\'*) eval set x "$CONFIG_FILES" ;;
|
||||
*) set x $CONFIG_FILES ;;
|
||||
esac
|
||||
# TODO: see whether this extra hack can be removed once we start
|
||||
# requiring Autoconf 2.70 or later.
|
||||
case $CONFIG_FILES in #(
|
||||
*\'*) :
|
||||
eval set x "$CONFIG_FILES" ;; #(
|
||||
*) :
|
||||
set x $CONFIG_FILES ;; #(
|
||||
*) :
|
||||
;;
|
||||
esac
|
||||
shift
|
||||
for mf
|
||||
# Used to flag and report bootstrapping failures.
|
||||
am_rc=0
|
||||
for am_mf
|
||||
do
|
||||
# Strip MF so we end up with the name of the file.
|
||||
mf=`echo "$mf" | sed -e 's/:.*$//'`
|
||||
# Check whether this is an Automake generated Makefile or not.
|
||||
# We used to match only the files named 'Makefile.in', but
|
||||
# some people rename them; so instead we look at the file content.
|
||||
# Grep'ing the first line is not enough: some people post-process
|
||||
# each Makefile.in and add a new line on top of each file to say so.
|
||||
# Grep'ing the whole file is not good either: AIX grep has a line
|
||||
am_mf=`$as_echo "$am_mf" | sed -e 's/:.*$//'`
|
||||
# Check whether this is an Automake generated Makefile which includes
|
||||
# dependency-tracking related rules and includes.
|
||||
# Grep'ing the whole file directly is not great: AIX grep has a line
|
||||
# limit of 2048, but all sed's we know have understand at least 4000.
|
||||
if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then
|
||||
dirpart=`$as_dirname -- "$mf" ||
|
||||
$as_expr X"$mf" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
|
||||
X"$mf" : 'X\(//\)[^/]' \| \
|
||||
X"$mf" : 'X\(//\)$' \| \
|
||||
X"$mf" : 'X\(/\)' \| . 2>/dev/null ||
|
||||
$as_echo X"$mf" |
|
||||
sed -n 's,^am--depfiles:.*,X,p' "$am_mf" | grep X >/dev/null 2>&1 \
|
||||
|| continue
|
||||
am_dirpart=`$as_dirname -- "$am_mf" ||
|
||||
$as_expr X"$am_mf" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
|
||||
X"$am_mf" : 'X\(//\)[^/]' \| \
|
||||
X"$am_mf" : 'X\(//\)$' \| \
|
||||
X"$am_mf" : 'X\(/\)' \| . 2>/dev/null ||
|
||||
$as_echo X"$am_mf" |
|
||||
sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
|
||||
s//\1/
|
||||
q
|
||||
@@ -6825,53 +6931,48 @@ $as_echo X"$mf" |
|
||||
q
|
||||
}
|
||||
s/.*/./; q'`
|
||||
else
|
||||
continue
|
||||
fi
|
||||
# Extract the definition of DEPDIR, am__include, and am__quote
|
||||
# from the Makefile without running 'make'.
|
||||
DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"`
|
||||
test -z "$DEPDIR" && continue
|
||||
am__include=`sed -n 's/^am__include = //p' < "$mf"`
|
||||
test -z "$am__include" && continue
|
||||
am__quote=`sed -n 's/^am__quote = //p' < "$mf"`
|
||||
# Find all dependency output files, they are included files with
|
||||
# $(DEPDIR) in their names. We invoke sed twice because it is the
|
||||
# simplest approach to changing $(DEPDIR) to its actual value in the
|
||||
# expansion.
|
||||
for file in `sed -n "
|
||||
s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \
|
||||
sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g'`; do
|
||||
# Make sure the directory exists.
|
||||
test -f "$dirpart/$file" && continue
|
||||
fdir=`$as_dirname -- "$file" ||
|
||||
$as_expr X"$file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
|
||||
X"$file" : 'X\(//\)[^/]' \| \
|
||||
X"$file" : 'X\(//\)$' \| \
|
||||
X"$file" : 'X\(/\)' \| . 2>/dev/null ||
|
||||
$as_echo X"$file" |
|
||||
sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
|
||||
am_filepart=`$as_basename -- "$am_mf" ||
|
||||
$as_expr X/"$am_mf" : '.*/\([^/][^/]*\)/*$' \| \
|
||||
X"$am_mf" : 'X\(//\)$' \| \
|
||||
X"$am_mf" : 'X\(/\)' \| . 2>/dev/null ||
|
||||
$as_echo X/"$am_mf" |
|
||||
sed '/^.*\/\([^/][^/]*\)\/*$/{
|
||||
s//\1/
|
||||
q
|
||||
}
|
||||
/^X\(\/\/\)[^/].*/{
|
||||
/^X\/\(\/\/\)$/{
|
||||
s//\1/
|
||||
q
|
||||
}
|
||||
/^X\(\/\/\)$/{
|
||||
s//\1/
|
||||
q
|
||||
}
|
||||
/^X\(\/\).*/{
|
||||
/^X\/\(\/\).*/{
|
||||
s//\1/
|
||||
q
|
||||
}
|
||||
s/.*/./; q'`
|
||||
as_dir=$dirpart/$fdir; as_fn_mkdir_p
|
||||
# echo "creating $dirpart/$file"
|
||||
echo '# dummy' > "$dirpart/$file"
|
||||
done
|
||||
{ echo "$as_me:$LINENO: cd "$am_dirpart" \
|
||||
&& sed -e '/# am--include-marker/d' "$am_filepart" \
|
||||
| $MAKE -f - am--depfiles" >&5
|
||||
(cd "$am_dirpart" \
|
||||
&& sed -e '/# am--include-marker/d' "$am_filepart" \
|
||||
| $MAKE -f - am--depfiles) >&5 2>&5
|
||||
ac_status=$?
|
||||
echo "$as_me:$LINENO: \$? = $ac_status" >&5
|
||||
(exit $ac_status); } || am_rc=$?
|
||||
done
|
||||
if test $am_rc -ne 0; then
|
||||
{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
|
||||
$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
|
||||
as_fn_error $? "Something went wrong bootstrapping makefile fragments
|
||||
for automatic dependency tracking. Try re-running configure with the
|
||||
'--disable-dependency-tracking' option to at least be able to build
|
||||
the package (albeit without support for automatic dependency tracking).
|
||||
See \`config.log' for more details" "$LINENO" 5; }
|
||||
fi
|
||||
{ am_dirpart=; unset am_dirpart;}
|
||||
{ am_filepart=; unset am_filepart;}
|
||||
{ am_mf=; unset am_mf;}
|
||||
{ am_rc=; unset am_rc;}
|
||||
rm -f conftest-deps.mk
|
||||
}
|
||||
;;
|
||||
|
||||
@@ -7489,7 +7590,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
|
||||
# report actual input values of CONFIG_FILES etc. instead of their
|
||||
# values after options handling.
|
||||
ac_log="
|
||||
This file was extended by qbittorrent $as_me v4.1.4, which was
|
||||
This file was extended by qbittorrent $as_me v4.1.5, which was
|
||||
generated by GNU Autoconf 2.69. Invocation command line was
|
||||
|
||||
CONFIG_FILES = $CONFIG_FILES
|
||||
@@ -7547,7 +7648,7 @@ _ACEOF
|
||||
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
|
||||
ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
|
||||
ac_cs_version="\\
|
||||
qbittorrent config.status v4.1.4
|
||||
qbittorrent config.status v4.1.5
|
||||
configured by $0, generated by GNU Autoconf 2.69,
|
||||
with options \\"\$ac_cs_config\\"
|
||||
|
||||
@@ -7655,7 +7756,7 @@ cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
|
||||
#
|
||||
# INIT-COMMANDS
|
||||
#
|
||||
AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"
|
||||
AMDEP_TRUE="$AMDEP_TRUE" MAKE="${MAKE-make}"
|
||||
|
||||
_ACEOF
|
||||
|
||||
@@ -8101,29 +8202,35 @@ $as_echo "$as_me: executing $ac_file commands" >&6;}
|
||||
# Older Autoconf quotes --file arguments for eval, but not when files
|
||||
# are listed without --file. Let's play safe and only enable the eval
|
||||
# if we detect the quoting.
|
||||
case $CONFIG_FILES in
|
||||
*\'*) eval set x "$CONFIG_FILES" ;;
|
||||
*) set x $CONFIG_FILES ;;
|
||||
esac
|
||||
# TODO: see whether this extra hack can be removed once we start
|
||||
# requiring Autoconf 2.70 or later.
|
||||
case $CONFIG_FILES in #(
|
||||
*\'*) :
|
||||
eval set x "$CONFIG_FILES" ;; #(
|
||||
*) :
|
||||
set x $CONFIG_FILES ;; #(
|
||||
*) :
|
||||
;;
|
||||
esac
|
||||
shift
|
||||
for mf
|
||||
# Used to flag and report bootstrapping failures.
|
||||
am_rc=0
|
||||
for am_mf
|
||||
do
|
||||
# Strip MF so we end up with the name of the file.
|
||||
mf=`echo "$mf" | sed -e 's/:.*$//'`
|
||||
# Check whether this is an Automake generated Makefile or not.
|
||||
# We used to match only the files named 'Makefile.in', but
|
||||
# some people rename them; so instead we look at the file content.
|
||||
# Grep'ing the first line is not enough: some people post-process
|
||||
# each Makefile.in and add a new line on top of each file to say so.
|
||||
# Grep'ing the whole file is not good either: AIX grep has a line
|
||||
am_mf=`$as_echo "$am_mf" | sed -e 's/:.*$//'`
|
||||
# Check whether this is an Automake generated Makefile which includes
|
||||
# dependency-tracking related rules and includes.
|
||||
# Grep'ing the whole file directly is not great: AIX grep has a line
|
||||
# limit of 2048, but all sed's we know have understand at least 4000.
|
||||
if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then
|
||||
dirpart=`$as_dirname -- "$mf" ||
|
||||
$as_expr X"$mf" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
|
||||
X"$mf" : 'X\(//\)[^/]' \| \
|
||||
X"$mf" : 'X\(//\)$' \| \
|
||||
X"$mf" : 'X\(/\)' \| . 2>/dev/null ||
|
||||
$as_echo X"$mf" |
|
||||
sed -n 's,^am--depfiles:.*,X,p' "$am_mf" | grep X >/dev/null 2>&1 \
|
||||
|| continue
|
||||
am_dirpart=`$as_dirname -- "$am_mf" ||
|
||||
$as_expr X"$am_mf" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
|
||||
X"$am_mf" : 'X\(//\)[^/]' \| \
|
||||
X"$am_mf" : 'X\(//\)$' \| \
|
||||
X"$am_mf" : 'X\(/\)' \| . 2>/dev/null ||
|
||||
$as_echo X"$am_mf" |
|
||||
sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
|
||||
s//\1/
|
||||
q
|
||||
@@ -8141,53 +8248,48 @@ $as_echo X"$mf" |
|
||||
q
|
||||
}
|
||||
s/.*/./; q'`
|
||||
else
|
||||
continue
|
||||
fi
|
||||
# Extract the definition of DEPDIR, am__include, and am__quote
|
||||
# from the Makefile without running 'make'.
|
||||
DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"`
|
||||
test -z "$DEPDIR" && continue
|
||||
am__include=`sed -n 's/^am__include = //p' < "$mf"`
|
||||
test -z "$am__include" && continue
|
||||
am__quote=`sed -n 's/^am__quote = //p' < "$mf"`
|
||||
# Find all dependency output files, they are included files with
|
||||
# $(DEPDIR) in their names. We invoke sed twice because it is the
|
||||
# simplest approach to changing $(DEPDIR) to its actual value in the
|
||||
# expansion.
|
||||
for file in `sed -n "
|
||||
s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \
|
||||
sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g'`; do
|
||||
# Make sure the directory exists.
|
||||
test -f "$dirpart/$file" && continue
|
||||
fdir=`$as_dirname -- "$file" ||
|
||||
$as_expr X"$file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
|
||||
X"$file" : 'X\(//\)[^/]' \| \
|
||||
X"$file" : 'X\(//\)$' \| \
|
||||
X"$file" : 'X\(/\)' \| . 2>/dev/null ||
|
||||
$as_echo X"$file" |
|
||||
sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
|
||||
am_filepart=`$as_basename -- "$am_mf" ||
|
||||
$as_expr X/"$am_mf" : '.*/\([^/][^/]*\)/*$' \| \
|
||||
X"$am_mf" : 'X\(//\)$' \| \
|
||||
X"$am_mf" : 'X\(/\)' \| . 2>/dev/null ||
|
||||
$as_echo X/"$am_mf" |
|
||||
sed '/^.*\/\([^/][^/]*\)\/*$/{
|
||||
s//\1/
|
||||
q
|
||||
}
|
||||
/^X\(\/\/\)[^/].*/{
|
||||
/^X\/\(\/\/\)$/{
|
||||
s//\1/
|
||||
q
|
||||
}
|
||||
/^X\(\/\/\)$/{
|
||||
s//\1/
|
||||
q
|
||||
}
|
||||
/^X\(\/\).*/{
|
||||
/^X\/\(\/\).*/{
|
||||
s//\1/
|
||||
q
|
||||
}
|
||||
s/.*/./; q'`
|
||||
as_dir=$dirpart/$fdir; as_fn_mkdir_p
|
||||
# echo "creating $dirpart/$file"
|
||||
echo '# dummy' > "$dirpart/$file"
|
||||
done
|
||||
{ echo "$as_me:$LINENO: cd "$am_dirpart" \
|
||||
&& sed -e '/# am--include-marker/d' "$am_filepart" \
|
||||
| $MAKE -f - am--depfiles" >&5
|
||||
(cd "$am_dirpart" \
|
||||
&& sed -e '/# am--include-marker/d' "$am_filepart" \
|
||||
| $MAKE -f - am--depfiles) >&5 2>&5
|
||||
ac_status=$?
|
||||
echo "$as_me:$LINENO: \$? = $ac_status" >&5
|
||||
(exit $ac_status); } || am_rc=$?
|
||||
done
|
||||
if test $am_rc -ne 0; then
|
||||
{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
|
||||
$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
|
||||
as_fn_error $? "Something went wrong bootstrapping makefile fragments
|
||||
for automatic dependency tracking. Try re-running configure with the
|
||||
'--disable-dependency-tracking' option to at least be able to build
|
||||
the package (albeit without support for automatic dependency tracking).
|
||||
See \`config.log' for more details" "$LINENO" 5; }
|
||||
fi
|
||||
{ am_dirpart=; unset am_dirpart;}
|
||||
{ am_filepart=; unset am_filepart;}
|
||||
{ am_mf=; unset am_mf;}
|
||||
{ am_rc=; unset am_rc;}
|
||||
rm -f conftest-deps.mk
|
||||
}
|
||||
;;
|
||||
|
||||
|
||||
60
configure.ac
60
configure.ac
@@ -1,4 +1,4 @@
|
||||
AC_INIT([qbittorrent], [v4.1.4], [bugs.qbittorrent.org], [], [https://www.qbittorrent.org/])
|
||||
AC_INIT([qbittorrent], [v4.1.5], [bugs.qbittorrent.org], [], [https://www.qbittorrent.org/])
|
||||
AC_CONFIG_AUX_DIR([build-aux])
|
||||
AC_CONFIG_MACRO_DIR([m4])
|
||||
AC_PROG_CC
|
||||
@@ -8,7 +8,9 @@ AC_LANG(C++)
|
||||
AC_CANONICAL_HOST
|
||||
AM_INIT_AUTOMAKE
|
||||
|
||||
|
||||
# use compiler from env variables if available
|
||||
QBT_CC="$CC"
|
||||
QBT_CXX="$CXX"
|
||||
|
||||
# Define --wth-* and --enable-* arguments
|
||||
|
||||
@@ -162,14 +164,13 @@ AS_CASE(["x$enable_qt_dbus"],
|
||||
|
||||
|
||||
AX_BOOST_BASE([1.35],
|
||||
[AC_MSG_NOTICE([Boost CPPFLAGS: "$BOOST_CPPFLAGS"
|
||||
Boost LDFLAGS: "$BOOST_LDFLAGS"])],
|
||||
[AC_MSG_NOTICE([Boost CXXFLAGS: "$BOOST_CPPFLAGS"])
|
||||
AC_MSG_NOTICE([Boost LDFLAGS: "$BOOST_LDFLAGS"])],
|
||||
[AC_MSG_ERROR([Could not find Boost])])
|
||||
CPPFLAGS="$BOOST_CPPFLAGS $CPPFLAGS"
|
||||
CXXFLAGS="$BOOST_CPPFLAGS $CXXFLAGS"
|
||||
LDFLAGS="$BOOST_LDFLAGS $LDFLAGS"
|
||||
|
||||
# add workaround for problematic boost version
|
||||
AC_LANG_PUSH(C++)
|
||||
# taken from ax_boost_base.m4
|
||||
m4_define([DETECT_BOOST_VERSION_PROGRAM],
|
||||
[AC_LANG_PROGRAM([[#include <boost/version.hpp>]],
|
||||
@@ -177,7 +178,6 @@ m4_define([DETECT_BOOST_VERSION_PROGRAM],
|
||||
|
||||
AC_COMPILE_IFELSE([DETECT_BOOST_VERSION_PROGRAM(106000)], [],
|
||||
[QBT_ADD_DEFINES="$QBT_ADD_DEFINES BOOST_NO_CXX11_RVALUE_REFERENCES"])
|
||||
AC_LANG_POP([C++])
|
||||
|
||||
AX_BOOST_SYSTEM()
|
||||
AC_MSG_NOTICE([Boost.System LIB: "$BOOST_SYSTEM_LIB"])
|
||||
@@ -196,14 +196,46 @@ AS_CASE(["x$with_qtsingleapplication"],
|
||||
|
||||
PKG_CHECK_MODULES(libtorrent,
|
||||
[libtorrent-rasterbar >= 1.0.6],
|
||||
[CPPFLAGS="$libtorrent_CFLAGS $CPPFLAGS"
|
||||
[CXXFLAGS="$libtorrent_CFLAGS $CXXFLAGS"
|
||||
LIBS="$libtorrent_LIBS $LIBS"])
|
||||
|
||||
PKG_CHECK_MODULES(zlib,
|
||||
[zlib >= 1.2.5.2],
|
||||
[CPPFLAGS="$zlib_CFLAGS $CPPFLAGS"
|
||||
[CXXFLAGS="$zlib_CFLAGS $CXXFLAGS"
|
||||
LIBS="$zlib_LIBS $LIBS"])
|
||||
|
||||
# Check if already in >= C++11 mode because of the flags returned by one of the above packages
|
||||
AC_MSG_CHECKING([if compiler is using C++11 or later mode])
|
||||
AC_COMPILE_IFELSE([DETECT_CPP11_PROGRAM()],
|
||||
[AC_MSG_RESULT([yes])
|
||||
QBT_CXX11_FOUND="yes"],
|
||||
[AC_MSG_RESULT([no])
|
||||
QBT_CXX11_FOUND="no"])
|
||||
|
||||
# In case of no, check if the compiler can support at least C++11
|
||||
# and if yes, enable it leaving a warning to the user
|
||||
AS_IF([test "x$QBT_CXX11_FOUND" = "xno"],
|
||||
[AC_MSG_CHECKING([if compiler supports C++11])
|
||||
TMP_CXXFLAGS="$CXXFLAGS"
|
||||
CXXFLAGS="$CXXFLAGS -std=c++11"
|
||||
AC_COMPILE_IFELSE([DETECT_CPP11_PROGRAM()],
|
||||
[AC_MSG_RESULT([yes])
|
||||
AC_MSG_CHECKING([if C++11 is disabled by the set compiler flags])
|
||||
# prepend the flag so it won't override conflicting user defined flags
|
||||
CXXFLAGS="-std=c++11 $TMP_CXXFLAGS"
|
||||
AC_COMPILE_IFELSE([DETECT_CPP11_PROGRAM()],
|
||||
[AC_MSG_RESULT([no])
|
||||
CXXFLAGS="$TMP_CXXFLAGS -std=c++11"
|
||||
AC_MSG_WARN([C++11 mode is now force enabled.
|
||||
Make sure you use the same C++ mode for qBittorrent and its dependencies.
|
||||
To explicitly set qBittorrent to a later mode use CXXFLAGS.
|
||||
Example: `CXXFLAGS="\$CXXFLAGS -std=c++14" ./configure`])],
|
||||
[AC_MSG_RESULT([yes])
|
||||
AC_MSG_ERROR([The compiler supports C++11 but the user or a dependency has explicitly enabled a lower mode.])])],
|
||||
[AC_MSG_RESULT([no])
|
||||
AC_MSG_ERROR([A compiler supporting C++11 is required.])])
|
||||
])
|
||||
|
||||
# These are required because autoconf doesn't expand these **particular**
|
||||
# vars automatically. And qmake cannot autoexpand them.
|
||||
AX_DEFINE_DIR([EXPAND_PREFIX], [prefix])
|
||||
@@ -230,18 +262,20 @@ extract() {
|
||||
for i in $string; do
|
||||
case "$(echo "$i" | cut -c1)" in
|
||||
'') ;;
|
||||
D) QBT_CONF_DEFINES="$(echo $i | cut -c2-) $QBT_CONF_DEFINES";;
|
||||
I) QBT_CONF_INCLUDES="$(echo $i | cut -c2-) $QBT_CONF_INCLUDES";;
|
||||
*) QBT_CONF_EXTRA_CFLAGS="-$i $QBT_CONF_EXTRA_CFLAGS";;
|
||||
D) QBT_CONF_DEFINES="$QBT_CONF_DEFINES $(echo $i | cut -c2-)";;
|
||||
I) QBT_CONF_INCLUDES="$QBT_CONF_INCLUDES $(echo $i | cut -c2-)";;
|
||||
*) QBT_CONF_EXTRA_CFLAGS="$QBT_CONF_EXTRA_CFLAGS -$i";;
|
||||
esac
|
||||
done
|
||||
IFS=$SAVEIFS
|
||||
}
|
||||
|
||||
extract "$CFLAGS $CPPFLAGS $CXXFLAGS"
|
||||
extract "$CFLAGS $CXXFLAGS"
|
||||
QBT_ADD_DEFINES="$QBT_ADD_DEFINES $QBT_CONF_DEFINES"
|
||||
|
||||
# Substitute the values of these vars in conf.pri.in
|
||||
AC_SUBST(QBT_CC)
|
||||
AC_SUBST(QBT_CXX)
|
||||
AC_SUBST(QBT_CONF_INCLUDES)
|
||||
AC_SUBST(QBT_CONF_EXTRA_CFLAGS)
|
||||
AC_SUBST(QBT_ADD_CONFIG)
|
||||
|
||||
2
dist/mac/Info.plist
vendored
2
dist/mac/Info.plist
vendored
@@ -45,7 +45,7 @@
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>APPL</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>4.1.4</string>
|
||||
<string>4.1.5</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>qBit</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
|
||||
BIN
dist/mac/qBitTorrentDocument.icns
vendored
BIN
dist/mac/qBitTorrentDocument.icns
vendored
Binary file not shown.
2
dist/windows/options.nsi
vendored
2
dist/windows/options.nsi
vendored
@@ -27,7 +27,7 @@ XPStyle on
|
||||
!define CSIDL_LOCALAPPDATA '0x1C' ;Local Application Data path
|
||||
|
||||
; Program specific
|
||||
!define PROG_VERSION "4.1.4"
|
||||
!define PROG_VERSION "4.1.5"
|
||||
|
||||
!define MUI_FINISHPAGE_RUN
|
||||
!define MUI_FINISHPAGE_RUN_FUNCTION PageFinishRun
|
||||
|
||||
@@ -36,3 +36,16 @@ AC_DEFUN([FIND_QTDBUS],
|
||||
[AC_MSG_RESULT([not found])
|
||||
HAVE_QTDBUS=[false]])
|
||||
])
|
||||
|
||||
# DETECT_CPP11_PROGRAM()
|
||||
# Detects if at least C++11 mode is enabled.
|
||||
# --------------------------------------
|
||||
AC_DEFUN([DETECT_CPP11_PROGRAM],
|
||||
[AC_LANG_PROGRAM([[
|
||||
#ifndef __cplusplus
|
||||
#error "This is not a C++ compiler"
|
||||
#elif __cplusplus < 201103L
|
||||
#error "This is not a C++11 compiler"
|
||||
#endif]],
|
||||
[[]])
|
||||
])
|
||||
|
||||
@@ -44,6 +44,7 @@
|
||||
#endif
|
||||
|
||||
#ifndef DISABLE_GUI
|
||||
#include <QMessageBox>
|
||||
#ifdef Q_OS_WIN
|
||||
#include <QSessionManager>
|
||||
#include <QSharedMemory>
|
||||
@@ -61,6 +62,7 @@
|
||||
|
||||
#include "base/bittorrent/session.h"
|
||||
#include "base/bittorrent/torrenthandle.h"
|
||||
#include "base/exceptions.h"
|
||||
#include "base/iconprovider.h"
|
||||
#include "base/logger.h"
|
||||
#include "base/net/downloadmanager.h"
|
||||
@@ -428,7 +430,7 @@ void Application::processParams(const QStringList ¶ms)
|
||||
BitTorrent::AddTorrentParams torrentParams;
|
||||
TriStateBool skipTorrentDialog;
|
||||
|
||||
foreach (QString param, params) {
|
||||
for (QString param : params) {
|
||||
param = param.trimmed();
|
||||
|
||||
// Process strings indicating options specified by the user.
|
||||
@@ -495,27 +497,42 @@ int Application::exec(const QStringList ¶ms)
|
||||
GuiIconProvider::initInstance();
|
||||
#endif
|
||||
|
||||
BitTorrent::Session::initInstance();
|
||||
connect(BitTorrent::Session::instance(), &BitTorrent::Session::torrentFinished, this, &Application::torrentFinished);
|
||||
connect(BitTorrent::Session::instance(), &BitTorrent::Session::allTorrentsFinished, this, &Application::allTorrentsFinished, Qt::QueuedConnection);
|
||||
try {
|
||||
BitTorrent::Session::initInstance();
|
||||
connect(BitTorrent::Session::instance(), &BitTorrent::Session::torrentFinished, this, &Application::torrentFinished);
|
||||
connect(BitTorrent::Session::instance(), &BitTorrent::Session::allTorrentsFinished, this, &Application::allTorrentsFinished, Qt::QueuedConnection);
|
||||
|
||||
#ifndef DISABLE_COUNTRIES_RESOLUTION
|
||||
Net::GeoIPManager::initInstance();
|
||||
Net::GeoIPManager::initInstance();
|
||||
#endif
|
||||
ScanFoldersModel::initInstance(this);
|
||||
ScanFoldersModel::initInstance(this);
|
||||
|
||||
#ifndef DISABLE_WEBUI
|
||||
m_webui = new WebUI;
|
||||
m_webui = new WebUI;
|
||||
#ifdef DISABLE_GUI
|
||||
if (m_webui->isErrored())
|
||||
return 1;
|
||||
connect(m_webui, &WebUI::fatalError, this, []() { QCoreApplication::exit(1); });
|
||||
if (m_webui->isErrored())
|
||||
return 1;
|
||||
connect(m_webui, &WebUI::fatalError, this, []() { QCoreApplication::exit(1); });
|
||||
#endif // DISABLE_GUI
|
||||
#endif // DISABLE_WEBUI
|
||||
|
||||
new RSS::Session; // create RSS::Session singleton
|
||||
new RSS::AutoDownloader; // create RSS::AutoDownloader singleton
|
||||
new SearchPluginManager;
|
||||
new RSS::Session; // create RSS::Session singleton
|
||||
new RSS::AutoDownloader; // create RSS::AutoDownloader singleton
|
||||
}
|
||||
catch (const RuntimeError &err) {
|
||||
#ifdef DISABLE_GUI
|
||||
fprintf(stderr, "%s", err.what());
|
||||
#else
|
||||
QMessageBox msgBox;
|
||||
msgBox.setIcon(QMessageBox::Critical);
|
||||
msgBox.setText(tr("Application failed to start."));
|
||||
msgBox.setInformativeText(err.message());
|
||||
msgBox.show(); // Need to be shown or to moveToCenter does not work
|
||||
msgBox.move(Utils::Misc::screenCenter(&msgBox));
|
||||
msgBox.exec();
|
||||
#endif
|
||||
return 1;
|
||||
}
|
||||
|
||||
#ifdef DISABLE_GUI
|
||||
#ifndef DISABLE_WEBUI
|
||||
@@ -710,7 +727,6 @@ void Application::cleanup()
|
||||
delete m_webui;
|
||||
#endif
|
||||
|
||||
delete SearchPluginManager::instance();
|
||||
delete RSS::AutoDownloader::instance();
|
||||
delete RSS::Session::instance();
|
||||
|
||||
@@ -726,6 +742,7 @@ void Application::cleanup()
|
||||
delete m_fileLogger;
|
||||
Logger::freeInstance();
|
||||
IconProvider::freeInstance();
|
||||
SearchPluginManager::freeInstance();
|
||||
Utils::Fs::removeDirRecursive(Utils::Fs::tempPath());
|
||||
|
||||
#ifndef DISABLE_GUI
|
||||
|
||||
@@ -41,6 +41,7 @@
|
||||
#include <QMessageBox>
|
||||
#endif
|
||||
|
||||
#include "base/global.h"
|
||||
#include "base/utils/misc.h"
|
||||
#include "base/utils/string.h"
|
||||
|
||||
@@ -486,7 +487,7 @@ CommandLineParameterError::CommandLineParameterError(const QString &messageForUs
|
||||
{
|
||||
}
|
||||
|
||||
const QString& CommandLineParameterError::messageForUser() const
|
||||
const QString &CommandLineParameterError::messageForUser() const
|
||||
{
|
||||
return m_messageForUser;
|
||||
}
|
||||
@@ -497,7 +498,7 @@ QString wrapText(const QString &text, int initialIndentation = USAGE_TEXT_COLUMN
|
||||
QStringList lines = {words.first()};
|
||||
int currentLineMaxLength = wrapAtColumn - initialIndentation;
|
||||
|
||||
foreach (const QString &word, words.mid(1)) {
|
||||
for (const QString &word : asConst(words.mid(1))) {
|
||||
if (lines.last().length() + word.length() + 1 < currentLineMaxLength) {
|
||||
lines.last().append(' ' + word);
|
||||
}
|
||||
|
||||
@@ -33,6 +33,7 @@
|
||||
#include <QFile>
|
||||
#include <QTextStream>
|
||||
|
||||
#include "base/global.h"
|
||||
#include "base/logger.h"
|
||||
#include "base/utils/fs.h"
|
||||
|
||||
@@ -50,7 +51,7 @@ FileLogger::FileLogger(const QString &path, const bool backup, const int maxSize
|
||||
this->deleteOld(age, ageType);
|
||||
|
||||
const Logger *const logger = Logger::instance();
|
||||
foreach (const Log::Msg &msg, logger->getMessages())
|
||||
for (const Log::Msg &msg : asConst(logger->getMessages()))
|
||||
addLogMessage(msg);
|
||||
|
||||
connect(logger, &Logger::newLogMessage, this, &FileLogger::addLogMessage);
|
||||
@@ -87,7 +88,7 @@ void FileLogger::deleteOld(const int age, const FileLogAgeType ageType)
|
||||
QDateTime date = QDateTime::currentDateTime();
|
||||
QDir dir(Utils::Fs::branchPath(m_path));
|
||||
|
||||
foreach (const QFileInfo file, dir.entryInfoList(QStringList("qbittorrent.log.bak*"), QDir::Files | QDir::Writable, QDir::Time | QDir::Reversed)) {
|
||||
for (const QFileInfo &file : asConst(dir.entryInfoList(QStringList("qbittorrent.log.bak*"), QDir::Files | QDir::Writable, QDir::Time | QDir::Reversed))) {
|
||||
QDateTime modificationDate = file.lastModified();
|
||||
switch (ageType) {
|
||||
case DAYS:
|
||||
|
||||
@@ -202,7 +202,7 @@ int main(int argc, char *argv[])
|
||||
// this is the default in Qt6
|
||||
app->setAttribute(Qt::AA_DisableWindowContextHelpButton);
|
||||
#endif
|
||||
#endif
|
||||
#endif // Q_OS_WIN
|
||||
|
||||
#if defined(Q_OS_MAC)
|
||||
// Since Apple made difficult for users to set PATH, we set here for convenience.
|
||||
|
||||
@@ -83,7 +83,7 @@ bool userAcceptsUpgrade()
|
||||
msgBox.move(Utils::Misc::screenCenter(&msgBox));
|
||||
if (msgBox.exec() == QMessageBox::Ok)
|
||||
return true;
|
||||
#endif
|
||||
#endif // DISABLE_GUI
|
||||
|
||||
return false;
|
||||
}
|
||||
@@ -179,9 +179,9 @@ bool upgrade(bool ask = true)
|
||||
|
||||
// ****************************************************************************************
|
||||
// Silently converts old v3.3.x .fastresume files
|
||||
QStringList backupFiles_3_3 = backupFolderDir.entryList(
|
||||
const QStringList backupFiles_3_3 = backupFolderDir.entryList(
|
||||
QStringList(QLatin1String("*.fastresume.*")), QDir::Files, QDir::Unsorted);
|
||||
foreach (const QString &backupFile, backupFiles_3_3)
|
||||
for (const QString &backupFile : backupFiles_3_3)
|
||||
upgradeResumeFile(backupFolderDir.absoluteFilePath(backupFile));
|
||||
// ****************************************************************************************
|
||||
|
||||
@@ -197,10 +197,10 @@ bool upgrade(bool ask = true)
|
||||
|
||||
if (ask && !userAcceptsUpgrade()) return false;
|
||||
|
||||
QStringList backupFiles = backupFolderDir.entryList(
|
||||
const QStringList backupFiles = backupFolderDir.entryList(
|
||||
QStringList(QLatin1String("*.fastresume")), QDir::Files, QDir::Unsorted);
|
||||
const QRegularExpression rx(QLatin1String("^([A-Fa-f0-9]{40})\\.fastresume$"));
|
||||
foreach (QString backupFile, backupFiles) {
|
||||
for (const QString &backupFile : backupFiles) {
|
||||
const QRegularExpressionMatch rxMatch = rx.match(backupFile);
|
||||
if (rxMatch.hasMatch()) {
|
||||
const QString hashStr = rxMatch.captured(1);
|
||||
@@ -265,7 +265,7 @@ void migratePlistToIni(const QString &application)
|
||||
plistFile->setFallbacksEnabled(false);
|
||||
const QStringList plist = plistFile->allKeys();
|
||||
if (!plist.isEmpty()) {
|
||||
foreach (const QString &key, plist)
|
||||
for (const QString &key : plist)
|
||||
iniFile.setValue(key, plistFile->value(key));
|
||||
plistFile->clear();
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ add_library(qbt_base STATIC
|
||||
# headers
|
||||
bittorrent/addtorrentparams.h
|
||||
bittorrent/cachestatus.h
|
||||
bittorrent/filepriority.h
|
||||
bittorrent/infohash.h
|
||||
bittorrent/magneturi.h
|
||||
bittorrent/peerinfo.h
|
||||
@@ -76,6 +77,7 @@ types.h
|
||||
unicodestrings.h
|
||||
|
||||
# sources
|
||||
bittorrent/filepriority.cpp
|
||||
bittorrent/infohash.cpp
|
||||
bittorrent/magneturi.cpp
|
||||
bittorrent/peerinfo.cpp
|
||||
|
||||
@@ -38,12 +38,12 @@ AsyncFileStorage::AsyncFileStorage(const QString &storageFolderPath, QObject *pa
|
||||
, m_lockFile(m_storageDir.absoluteFilePath(QStringLiteral("storage.lock")))
|
||||
{
|
||||
if (!m_storageDir.mkpath(m_storageDir.absolutePath()))
|
||||
throw AsyncFileStorageError(
|
||||
QString("Could not create directory '%1'.").arg(m_storageDir.absolutePath()));
|
||||
throw AsyncFileStorageError {tr("Could not create directory '%1'.")
|
||||
.arg(m_storageDir.absolutePath())};
|
||||
|
||||
// TODO: This folder locking approach does not work for UNIX systems. Implement it.
|
||||
if (!m_lockFile.open(QFile::WriteOnly))
|
||||
throw AsyncFileStorageError(m_lockFile.errorString());
|
||||
throw AsyncFileStorageError {m_lockFile.errorString()};
|
||||
}
|
||||
|
||||
AsyncFileStorage::~AsyncFileStorage()
|
||||
@@ -76,13 +76,3 @@ void AsyncFileStorage::store_impl(const QString &fileName, const QByteArray &dat
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
AsyncFileStorageError::AsyncFileStorageError(const QString &message)
|
||||
: std::runtime_error(message.toUtf8().data())
|
||||
{
|
||||
}
|
||||
|
||||
QString AsyncFileStorageError::message() const
|
||||
{
|
||||
return what();
|
||||
}
|
||||
|
||||
@@ -28,22 +28,22 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdexcept>
|
||||
|
||||
#include <QDir>
|
||||
#include <QFile>
|
||||
#include <QObject>
|
||||
|
||||
class AsyncFileStorageError : public std::runtime_error
|
||||
#include "base/exceptions.h"
|
||||
|
||||
class AsyncFileStorageError : public RuntimeError
|
||||
{
|
||||
public:
|
||||
explicit AsyncFileStorageError(const QString &message);
|
||||
QString message() const;
|
||||
using RuntimeError::RuntimeError;
|
||||
};
|
||||
|
||||
class AsyncFileStorage : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_DISABLE_COPY(AsyncFileStorage)
|
||||
|
||||
public:
|
||||
explicit AsyncFileStorage(const QString &storageFolderPath, QObject *parent = nullptr);
|
||||
|
||||
@@ -3,6 +3,7 @@ HEADERS += \
|
||||
$$PWD/asyncfilestorage.h \
|
||||
$$PWD/bittorrent/addtorrentparams.h \
|
||||
$$PWD/bittorrent/cachestatus.h \
|
||||
$$PWD/bittorrent/filepriority.h \
|
||||
$$PWD/bittorrent/infohash.h \
|
||||
$$PWD/bittorrent/magneturi.h \
|
||||
$$PWD/bittorrent/peerinfo.h \
|
||||
@@ -75,6 +76,7 @@ HEADERS += \
|
||||
|
||||
SOURCES += \
|
||||
$$PWD/asyncfilestorage.cpp \
|
||||
$$PWD/bittorrent/filepriority.cpp \
|
||||
$$PWD/bittorrent/infohash.cpp \
|
||||
$$PWD/bittorrent/magneturi.cpp \
|
||||
$$PWD/bittorrent/peerinfo.cpp \
|
||||
|
||||
46
src/base/bittorrent/filepriority.cpp
Normal file
46
src/base/bittorrent/filepriority.cpp
Normal file
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
* Bittorrent Client using Qt and libtorrent.
|
||||
* Copyright (C) 2018 Thomas Piccirello <thomas.piccirello@gmail.com>
|
||||
*
|
||||
* 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 "filepriority.h"
|
||||
|
||||
namespace BitTorrent
|
||||
{
|
||||
bool isValidFilePriority(const BitTorrent::FilePriority priority)
|
||||
{
|
||||
switch (priority) {
|
||||
case BitTorrent::FilePriority::Ignored:
|
||||
case BitTorrent::FilePriority::Normal:
|
||||
case BitTorrent::FilePriority::High:
|
||||
case BitTorrent::FilePriority::Maximum:
|
||||
case BitTorrent::FilePriority::Mixed:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
43
src/base/bittorrent/filepriority.h
Normal file
43
src/base/bittorrent/filepriority.h
Normal file
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
* Bittorrent Client using Qt and libtorrent.
|
||||
* Copyright (C) 2018 Thomas Piccirello <thomas.piccirello@gmail.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* In addition, as a special exception, the copyright holders give permission to
|
||||
* link this program with the OpenSSL project's "OpenSSL" library (or with
|
||||
* modified versions of it that use the same license as the "OpenSSL" library),
|
||||
* and distribute the linked executables. You must obey the GNU General Public
|
||||
* License in all respects for all of the code used other than "OpenSSL". If you
|
||||
* modify file(s), you may extend this exception to your version of the file(s),
|
||||
* but you are not obligated to do so. If you do not wish to do so, delete this
|
||||
* exception statement from your version.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace BitTorrent
|
||||
{
|
||||
enum class FilePriority : int
|
||||
{
|
||||
Ignored = 0,
|
||||
Normal = 1,
|
||||
High = 6,
|
||||
Maximum = 7,
|
||||
Mixed = -1
|
||||
};
|
||||
|
||||
bool isValidFilePriority(BitTorrent::FilePriority priority);
|
||||
}
|
||||
@@ -83,10 +83,10 @@ MagnetUri::MagnetUri(const QString &source)
|
||||
m_hash = m_addTorrentParams.info_hash;
|
||||
m_name = QString::fromStdString(m_addTorrentParams.name);
|
||||
|
||||
foreach (const std::string &tracker, m_addTorrentParams.trackers)
|
||||
for (const std::string &tracker : m_addTorrentParams.trackers)
|
||||
m_trackers.append(QString::fromStdString(tracker));
|
||||
|
||||
foreach (const std::string &urlSeed, m_addTorrentParams.url_seeds)
|
||||
for (const std::string &urlSeed : m_addTorrentParams.url_seeds)
|
||||
m_urlSeeds.append(QUrl(urlSeed.c_str()));
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Bittorrent Client using Qt and libtorrent.
|
||||
* Copyright (C) 2015 Vladimir Golovnev <glassez@yandex.ru>
|
||||
* Copyright (C) 2015, 2018 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
|
||||
@@ -39,18 +39,23 @@ ResumeDataSavingManager::ResumeDataSavingManager(const QString &resumeFolderPath
|
||||
{
|
||||
}
|
||||
|
||||
void ResumeDataSavingManager::saveResumeData(QString infoHash, QByteArray data) const
|
||||
void ResumeDataSavingManager::save(const QString &filename, const QByteArray &data) const
|
||||
{
|
||||
QString filename = QString("%1.fastresume").arg(infoHash);
|
||||
QString filepath = m_resumeDataDir.absoluteFilePath(filename);
|
||||
const QString filepath = m_resumeDataDir.absoluteFilePath(filename);
|
||||
|
||||
qDebug() << "Saving resume data in" << filepath;
|
||||
QSaveFile resumeFile(filepath);
|
||||
if (resumeFile.open(QIODevice::WriteOnly)) {
|
||||
resumeFile.write(data);
|
||||
if (!resumeFile.commit()) {
|
||||
Logger::instance()->addMessage(QString("Couldn't save resume data in %1. Error: %2")
|
||||
.arg(filepath, resumeFile.errorString()), Log::WARNING);
|
||||
QSaveFile file {filepath};
|
||||
if (file.open(QIODevice::WriteOnly)) {
|
||||
file.write(data);
|
||||
if (!file.commit()) {
|
||||
Logger::instance()->addMessage(QString("Couldn't save data in '%1'. Error: %2")
|
||||
.arg(filepath, file.errorString()), Log::WARNING);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ResumeDataSavingManager::remove(const QString &filename) const
|
||||
{
|
||||
const QString filepath = m_resumeDataDir.absoluteFilePath(filename);
|
||||
|
||||
Utils::Fs::forceRemove(filepath);
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Bittorrent Client using Qt and libtorrent.
|
||||
* Copyright (C) 2015 Vladimir Golovnev <glassez@yandex.ru>
|
||||
* Copyright (C) 2015, 2018 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
|
||||
@@ -26,8 +26,7 @@
|
||||
* exception statement from your version.
|
||||
*/
|
||||
|
||||
#ifndef RESUMEDATASAVINGMANAGER_H
|
||||
#define RESUMEDATASAVINGMANAGER_H
|
||||
#pragma once
|
||||
|
||||
#include <QByteArray>
|
||||
#include <QDir>
|
||||
@@ -36,15 +35,15 @@
|
||||
class ResumeDataSavingManager : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_DISABLE_COPY(ResumeDataSavingManager)
|
||||
|
||||
public:
|
||||
explicit ResumeDataSavingManager(const QString &resumeFolderPath);
|
||||
|
||||
public slots:
|
||||
void saveResumeData(QString infoHash, QByteArray data) const;
|
||||
void save(const QString &filename, const QByteArray &data) const;
|
||||
void remove(const QString &filename) const;
|
||||
|
||||
private:
|
||||
QDir m_resumeDataDir;
|
||||
};
|
||||
|
||||
#endif // RESUMEDATASAVINGMANAGER_H
|
||||
|
||||
@@ -69,6 +69,8 @@
|
||||
#endif
|
||||
|
||||
#include "base/algorithm.h"
|
||||
#include "base/exceptions.h"
|
||||
#include "base/global.h"
|
||||
#include "base/logger.h"
|
||||
#include "base/net/downloadhandler.h"
|
||||
#include "base/net/downloadmanager.h"
|
||||
@@ -198,7 +200,7 @@ namespace
|
||||
|
||||
for (auto i = categories.cbegin(); i != categories.cend(); ++i) {
|
||||
const QString &category = i.key();
|
||||
foreach (const QString &subcat, Session::expandCategory(category)) {
|
||||
for (const QString &subcat : asConst(Session::expandCategory(category))) {
|
||||
if (!expanded.contains(subcat))
|
||||
expanded[subcat] = "";
|
||||
}
|
||||
@@ -275,6 +277,7 @@ Session::Session(QObject *parent)
|
||||
, m_announceToAllTrackers(BITTORRENT_SESSION_KEY("AnnounceToAllTrackers"), false)
|
||||
, m_announceToAllTiers(BITTORRENT_SESSION_KEY("AnnounceToAllTiers"), true)
|
||||
, m_asyncIOThreads(BITTORRENT_SESSION_KEY("AsyncIOThreadsCount"), 4)
|
||||
, m_checkingMemUsage(BITTORRENT_SESSION_KEY("CheckingMemUsageSize"), 16)
|
||||
, m_diskCacheSize(BITTORRENT_SESSION_KEY("DiskCacheSize"), 64)
|
||||
, m_diskCacheTTL(BITTORRENT_SESSION_KEY("DiskCacheTTL"), 60)
|
||||
, m_useOSCache(BITTORRENT_SESSION_KEY("UseOSCache"), true)
|
||||
@@ -468,7 +471,7 @@ Session::Session(QObject *parent)
|
||||
});
|
||||
|
||||
configurePeerClasses();
|
||||
#endif
|
||||
#endif // LIBTORRENT_VERSION_NUM < 10100
|
||||
|
||||
// Enabling plugins
|
||||
//m_nativeSession->add_extension(&libt::create_metadata_plugin);
|
||||
@@ -532,7 +535,7 @@ Session::Session(QObject *parent)
|
||||
connect(&m_networkManager, &QNetworkConfigurationManager::configurationChanged, this, &Session::networkConfigurationChange);
|
||||
|
||||
m_ioThread = new QThread(this);
|
||||
m_resumeDataSavingManager = new ResumeDataSavingManager(m_resumeFolderPath);
|
||||
m_resumeDataSavingManager = new ResumeDataSavingManager {m_resumeFolderPath};
|
||||
m_resumeDataSavingManager->moveToThread(m_ioThread);
|
||||
connect(m_ioThread, &QThread::finished, m_resumeDataSavingManager, &QObject::deleteLater);
|
||||
m_ioThread->start();
|
||||
@@ -609,7 +612,7 @@ void Session::setTempPathEnabled(bool enabled)
|
||||
{
|
||||
if (enabled != isTempPathEnabled()) {
|
||||
m_isTempPathEnabled = enabled;
|
||||
foreach (TorrentHandle *const torrent, m_torrents)
|
||||
for (TorrentHandle *const torrent : asConst(m_torrents))
|
||||
torrent->handleTempPathChanged();
|
||||
}
|
||||
}
|
||||
@@ -623,7 +626,7 @@ void Session::setAppendExtensionEnabled(bool enabled)
|
||||
{
|
||||
if (isAppendExtensionEnabled() != enabled) {
|
||||
// append or remove .!qB extension for incomplete files
|
||||
foreach (TorrentHandle *const torrent, m_torrents)
|
||||
for (TorrentHandle *const torrent : asConst(m_torrents))
|
||||
torrent->handleAppendExtensionToggled();
|
||||
|
||||
m_isAppendExtensionEnabled = enabled;
|
||||
@@ -751,7 +754,7 @@ bool Session::addCategory(const QString &name, const QString &savePath)
|
||||
return false;
|
||||
|
||||
if (isSubcategoriesEnabled()) {
|
||||
foreach (const QString &parent, expandCategory(name)) {
|
||||
for (const QString &parent : asConst(expandCategory(name))) {
|
||||
if ((parent != name) && !m_categories.contains(parent)) {
|
||||
m_categories[parent] = "";
|
||||
emit categoryAdded(parent);
|
||||
@@ -774,12 +777,12 @@ bool Session::editCategory(const QString &name, const QString &savePath)
|
||||
m_categories[name] = savePath;
|
||||
m_storedCategories = map_cast(m_categories);
|
||||
if (isDisableAutoTMMWhenCategorySavePathChanged()) {
|
||||
foreach (TorrentHandle *const torrent, torrents())
|
||||
for (TorrentHandle *const torrent : asConst(torrents()))
|
||||
if (torrent->category() == name)
|
||||
torrent->setAutoTMMEnabled(false);
|
||||
}
|
||||
else {
|
||||
foreach (TorrentHandle *const torrent, torrents())
|
||||
for (TorrentHandle *const torrent : asConst(torrents()))
|
||||
if (torrent->category() == name)
|
||||
torrent->handleCategorySavePathChanged();
|
||||
}
|
||||
@@ -789,7 +792,7 @@ bool Session::editCategory(const QString &name, const QString &savePath)
|
||||
|
||||
bool Session::removeCategory(const QString &name)
|
||||
{
|
||||
foreach (TorrentHandle *const torrent, torrents())
|
||||
for (TorrentHandle *const torrent : asConst(torrents()))
|
||||
if (torrent->belongsToCategory(name))
|
||||
torrent->setCategory("");
|
||||
|
||||
@@ -876,7 +879,7 @@ bool Session::addTag(const QString &tag)
|
||||
bool Session::removeTag(const QString &tag)
|
||||
{
|
||||
if (m_tags.remove(tag)) {
|
||||
foreach (TorrentHandle *const torrent, torrents())
|
||||
for (TorrentHandle *const torrent : asConst(torrents()))
|
||||
torrent->removeTag(tag);
|
||||
m_storedTags = m_tags.toList();
|
||||
emit tagRemoved(tag);
|
||||
@@ -1084,7 +1087,7 @@ void Session::configure()
|
||||
void Session::processBannedIPs(libt::ip_filter &filter)
|
||||
{
|
||||
// First, import current filter
|
||||
foreach (const QString &ip, m_bannedIPs.value()) {
|
||||
for (const QString &ip : asConst(m_bannedIPs.value())) {
|
||||
boost::system::error_code ec;
|
||||
libt::address addr = libt::address::from_string(ip.toLatin1().constData(), ec);
|
||||
Q_ASSERT(!ec);
|
||||
@@ -1203,7 +1206,7 @@ void Session::configure(libtorrent::settings_pack &settingsPack)
|
||||
const ushort port = this->port();
|
||||
std::pair<int, int> ports(port, port);
|
||||
settingsPack.set_int(libt::settings_pack::max_retry_port_bind, ports.second - ports.first);
|
||||
foreach (QString ip, getListeningIPs()) {
|
||||
for (QString ip : getListeningIPs()) {
|
||||
libt::error_code ec;
|
||||
std::string interfacesStr;
|
||||
|
||||
@@ -1252,7 +1255,7 @@ void Session::configure(libtorrent::settings_pack &settingsPack)
|
||||
}
|
||||
#else
|
||||
settingsPack.set_str(libt::settings_pack::outgoing_interfaces, networkInterface().toStdString());
|
||||
#endif
|
||||
#endif // Q_OS_WIN
|
||||
m_listenInterfaceChanged = false;
|
||||
}
|
||||
|
||||
@@ -1317,6 +1320,9 @@ void Session::configure(libtorrent::settings_pack &settingsPack)
|
||||
|
||||
settingsPack.set_int(libt::settings_pack::aio_threads, asyncIOThreads());
|
||||
|
||||
const int checkingMemUsageSize = checkingMemUsage() * 64;
|
||||
settingsPack.set_int(libt::settings_pack::checking_mem_usage, checkingMemUsageSize);
|
||||
|
||||
const int cacheSize = (diskCacheSize() > -1) ? (diskCacheSize() * 64) : -1;
|
||||
settingsPack.set_int(libt::settings_pack::cache_size, cacheSize);
|
||||
settingsPack.set_int(libt::settings_pack::cache_expiry, diskCacheTTL());
|
||||
@@ -1461,7 +1467,7 @@ void Session::configurePeerClasses()
|
||||
, 1 << libt::session::global_peer_class_id);
|
||||
}
|
||||
catch (std::exception &) {}
|
||||
#endif
|
||||
#endif // TORRENT_USE_IPV6
|
||||
if (ignoreLimitsOnLAN()) {
|
||||
// local networks
|
||||
f.add_rule(libt::address_v4::from_string("10.0.0.0")
|
||||
@@ -1500,7 +1506,7 @@ void Session::configurePeerClasses()
|
||||
, 1 << libt::session::local_peer_class_id);
|
||||
}
|
||||
catch (std::exception &) {}
|
||||
#endif
|
||||
#endif // TORRENT_USE_IPV6
|
||||
}
|
||||
m_nativeSession->set_peer_class_filter(f);
|
||||
|
||||
@@ -1517,7 +1523,7 @@ void Session::configurePeerClasses()
|
||||
m_nativeSession->set_peer_class_type_filter(peerClassTypeFilter);
|
||||
}
|
||||
|
||||
#else
|
||||
#else // LIBTORRENT_VERSION_NUM >= 10100
|
||||
|
||||
void Session::adjustLimits(libt::session_settings &sessionSettings)
|
||||
{
|
||||
@@ -1734,7 +1740,7 @@ void Session::configure(libtorrent::session_settings &sessionSettings)
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#endif // LIBTORRENT_VERSION_NUM >= 10100
|
||||
|
||||
void Session::enableTracker(bool enable)
|
||||
{
|
||||
@@ -1769,7 +1775,7 @@ void Session::enableBandwidthScheduler()
|
||||
void Session::populateAdditionalTrackers()
|
||||
{
|
||||
m_additionalTrackerList.clear();
|
||||
foreach (QString tracker, additionalTrackers().split('\n')) {
|
||||
for (QString tracker : asConst(additionalTrackers().split('\n'))) {
|
||||
tracker = tracker.trimmed();
|
||||
if (!tracker.isEmpty())
|
||||
m_additionalTrackerList << tracker;
|
||||
@@ -1780,7 +1786,7 @@ void Session::processShareLimits()
|
||||
{
|
||||
qDebug("Processing share limits...");
|
||||
|
||||
foreach (TorrentHandle *const torrent, m_torrents) {
|
||||
for (TorrentHandle *const torrent : asConst(torrents())) {
|
||||
if (torrent->isSeed() && !torrent->isForced()) {
|
||||
if (torrent->ratioLimit() != TorrentHandle::NO_RATIO_LIMIT) {
|
||||
const qreal ratio = torrent->realRatio();
|
||||
@@ -1933,7 +1939,7 @@ bool Session::deleteTorrent(const QString &hash, bool deleteLocalFiles)
|
||||
m_nativeSession->remove_torrent(torrent->nativeHandle(), libt::session::delete_partfile);
|
||||
#endif
|
||||
// Remove unwanted and incomplete files
|
||||
foreach (const QString &unwantedFile, unwantedFiles) {
|
||||
for (const QString &unwantedFile : asConst(unwantedFiles)) {
|
||||
qDebug("Removing unwanted file: %s", qUtf8Printable(unwantedFile));
|
||||
Utils::Fs::forceRemove(unwantedFile);
|
||||
const QString parentFolder = Utils::Fs::branchPath(unwantedFile);
|
||||
@@ -1947,7 +1953,7 @@ bool Session::deleteTorrent(const QString &hash, bool deleteLocalFiles)
|
||||
QStringList filters;
|
||||
filters << QString("%1.*").arg(torrent->hash());
|
||||
const QStringList files = resumeDataDir.entryList(filters, QDir::Files, QDir::Unsorted);
|
||||
foreach (const QString &file, files)
|
||||
for (const QString &file : files)
|
||||
Utils::Fs::forceRemove(resumeDataDir.absoluteFilePath(file));
|
||||
|
||||
delete torrent;
|
||||
@@ -1978,12 +1984,12 @@ bool Session::cancelLoadMetadata(const InfoHash &hash)
|
||||
void Session::increaseTorrentsPriority(const QStringList &hashes)
|
||||
{
|
||||
std::priority_queue<QPair<int, TorrentHandle *>,
|
||||
std::vector<QPair<int, TorrentHandle *> >,
|
||||
std::greater<QPair<int, TorrentHandle *> > > torrentQueue;
|
||||
std::vector<QPair<int, TorrentHandle *>>,
|
||||
std::greater<QPair<int, TorrentHandle *>>> torrentQueue;
|
||||
|
||||
// Sort torrents by priority
|
||||
foreach (const InfoHash &hash, hashes) {
|
||||
TorrentHandle *const torrent = m_torrents.value(hash);
|
||||
for (const InfoHash infoHash : hashes) {
|
||||
TorrentHandle *const torrent = m_torrents.value(infoHash);
|
||||
if (torrent && !torrent->isSeed())
|
||||
torrentQueue.push(qMakePair(torrent->queuePosition(), torrent));
|
||||
}
|
||||
@@ -1995,18 +2001,18 @@ void Session::increaseTorrentsPriority(const QStringList &hashes)
|
||||
torrentQueue.pop();
|
||||
}
|
||||
|
||||
handleTorrentsPrioritiesChanged();
|
||||
saveTorrentsQueue();
|
||||
}
|
||||
|
||||
void Session::decreaseTorrentsPriority(const QStringList &hashes)
|
||||
{
|
||||
std::priority_queue<QPair<int, TorrentHandle *>,
|
||||
std::vector<QPair<int, TorrentHandle *> >,
|
||||
std::less<QPair<int, TorrentHandle *> > > torrentQueue;
|
||||
std::vector<QPair<int, TorrentHandle *>>,
|
||||
std::less<QPair<int, TorrentHandle *>>> torrentQueue;
|
||||
|
||||
// Sort torrents by priority
|
||||
foreach (const InfoHash &hash, hashes) {
|
||||
TorrentHandle *const torrent = m_torrents.value(hash);
|
||||
for (const InfoHash infoHash : hashes) {
|
||||
TorrentHandle *const torrent = m_torrents.value(infoHash);
|
||||
if (torrent && !torrent->isSeed())
|
||||
torrentQueue.push(qMakePair(torrent->queuePosition(), torrent));
|
||||
}
|
||||
@@ -2021,18 +2027,18 @@ void Session::decreaseTorrentsPriority(const QStringList &hashes)
|
||||
for (auto i = m_loadedMetadata.cbegin(); i != m_loadedMetadata.cend(); ++i)
|
||||
torrentQueuePositionBottom(m_nativeSession->find_torrent(i.key()));
|
||||
|
||||
handleTorrentsPrioritiesChanged();
|
||||
saveTorrentsQueue();
|
||||
}
|
||||
|
||||
void Session::topTorrentsPriority(const QStringList &hashes)
|
||||
{
|
||||
std::priority_queue<QPair<int, TorrentHandle *>,
|
||||
std::vector<QPair<int, TorrentHandle *> >,
|
||||
std::greater<QPair<int, TorrentHandle *> > > torrentQueue;
|
||||
std::vector<QPair<int, TorrentHandle *>>,
|
||||
std::greater<QPair<int, TorrentHandle *>>> torrentQueue;
|
||||
|
||||
// Sort torrents by priority
|
||||
foreach (const InfoHash &hash, hashes) {
|
||||
TorrentHandle *const torrent = m_torrents.value(hash);
|
||||
for (const InfoHash infoHash : hashes) {
|
||||
TorrentHandle *const torrent = m_torrents.value(infoHash);
|
||||
if (torrent && !torrent->isSeed())
|
||||
torrentQueue.push(qMakePair(torrent->queuePosition(), torrent));
|
||||
}
|
||||
@@ -2044,18 +2050,18 @@ void Session::topTorrentsPriority(const QStringList &hashes)
|
||||
torrentQueue.pop();
|
||||
}
|
||||
|
||||
handleTorrentsPrioritiesChanged();
|
||||
saveTorrentsQueue();
|
||||
}
|
||||
|
||||
void Session::bottomTorrentsPriority(const QStringList &hashes)
|
||||
{
|
||||
std::priority_queue<QPair<int, TorrentHandle *>,
|
||||
std::vector<QPair<int, TorrentHandle *> >,
|
||||
std::less<QPair<int, TorrentHandle *> > > torrentQueue;
|
||||
std::vector<QPair<int, TorrentHandle *>>,
|
||||
std::less<QPair<int, TorrentHandle *>>> torrentQueue;
|
||||
|
||||
// Sort torrents by priority
|
||||
foreach (const InfoHash &hash, hashes) {
|
||||
TorrentHandle *const torrent = m_torrents.value(hash);
|
||||
for (const InfoHash infoHash : hashes) {
|
||||
TorrentHandle *const torrent = m_torrents.value(infoHash);
|
||||
if (torrent && !torrent->isSeed())
|
||||
torrentQueue.push(qMakePair(torrent->queuePosition(), torrent));
|
||||
}
|
||||
@@ -2070,7 +2076,7 @@ void Session::bottomTorrentsPriority(const QStringList &hashes)
|
||||
for (auto i = m_loadedMetadata.cbegin(); i != m_loadedMetadata.cend(); ++i)
|
||||
torrentQueuePositionBottom(m_nativeSession->find_torrent(i.key()));
|
||||
|
||||
handleTorrentsPrioritiesChanged();
|
||||
saveTorrentsQueue();
|
||||
}
|
||||
|
||||
QHash<InfoHash, TorrentHandle *> Session::torrents() const
|
||||
@@ -2366,7 +2372,7 @@ void Session::exportTorrentFile(TorrentHandle *const torrent, TorrentExportFolde
|
||||
|
||||
void Session::generateResumeData(bool final)
|
||||
{
|
||||
foreach (TorrentHandle *const torrent, m_torrents) {
|
||||
for (TorrentHandle *const torrent : asConst(m_torrents)) {
|
||||
if (!torrent->isValid()) continue;
|
||||
if (torrent->isChecking() || torrent->isPaused()) continue;
|
||||
if (!final && !torrent->needSaveResumeData()) continue;
|
||||
@@ -2379,11 +2385,13 @@ void Session::generateResumeData(bool final)
|
||||
// Called on exit
|
||||
void Session::saveResumeData()
|
||||
{
|
||||
qDebug("Saving fast resume data...");
|
||||
qDebug("Saving resume data...");
|
||||
|
||||
// Pause session
|
||||
m_nativeSession->pause();
|
||||
|
||||
if (isQueueingSystemEnabled())
|
||||
saveTorrentsQueue();
|
||||
generateResumeData(true);
|
||||
|
||||
while (m_numResumeData > 0) {
|
||||
@@ -2394,7 +2402,7 @@ void Session::saveResumeData()
|
||||
break;
|
||||
}
|
||||
|
||||
for (const auto a: alerts) {
|
||||
for (const auto a : alerts) {
|
||||
switch (a->type()) {
|
||||
case libt::save_resume_data_failed_alert::alert_type:
|
||||
case libt::save_resume_data_alert::alert_type:
|
||||
@@ -2408,6 +2416,31 @@ void Session::saveResumeData()
|
||||
}
|
||||
}
|
||||
|
||||
void Session::saveTorrentsQueue()
|
||||
{
|
||||
QMap<int, QString> queue; // Use QMap since it should be ordered by key
|
||||
for (const TorrentHandle *torrent : asConst(torrents())) {
|
||||
// We require actual (non-cached) queue position here!
|
||||
const int queuePos = torrent->nativeHandle().queue_position();
|
||||
if (queuePos >= 0)
|
||||
queue[queuePos] = torrent->hash();
|
||||
}
|
||||
|
||||
QByteArray data;
|
||||
for (const QString &hash : asConst(queue))
|
||||
data += (hash.toLatin1() + '\n');
|
||||
|
||||
const QString filename = QLatin1String {"queue"};
|
||||
QMetaObject::invokeMethod(m_resumeDataSavingManager, "save"
|
||||
, Q_ARG(QString, filename), Q_ARG(QByteArray, data));
|
||||
}
|
||||
|
||||
void Session::removeTorrentsQueue()
|
||||
{
|
||||
const QString filename = QLatin1String {"queue"};
|
||||
QMetaObject::invokeMethod(m_resumeDataSavingManager, "remove", Q_ARG(QString, filename));
|
||||
}
|
||||
|
||||
void Session::setDefaultSavePath(QString path)
|
||||
{
|
||||
path = normalizeSavePath(path);
|
||||
@@ -2416,10 +2449,10 @@ void Session::setDefaultSavePath(QString path)
|
||||
m_defaultSavePath = path;
|
||||
|
||||
if (isDisableAutoTMMWhenDefaultSavePathChanged())
|
||||
foreach (TorrentHandle *const torrent, torrents())
|
||||
for (TorrentHandle *const torrent : asConst(torrents()))
|
||||
torrent->setAutoTMMEnabled(false);
|
||||
else
|
||||
foreach (TorrentHandle *const torrent, torrents())
|
||||
for (TorrentHandle *const torrent : asConst(torrents()))
|
||||
torrent->handleCategorySavePathChanged();
|
||||
}
|
||||
|
||||
@@ -2430,7 +2463,7 @@ void Session::setTempPath(QString path)
|
||||
|
||||
m_tempPath = path;
|
||||
|
||||
foreach (TorrentHandle *const torrent, m_torrents)
|
||||
for (TorrentHandle *const torrent : asConst(m_torrents))
|
||||
torrent->handleTempPathChanged();
|
||||
}
|
||||
|
||||
@@ -2504,7 +2537,7 @@ const QStringList Session::getListeningIPs()
|
||||
QHostAddress ip;
|
||||
QString ipString;
|
||||
QAbstractSocket::NetworkLayerProtocol protocol;
|
||||
foreach (const QNetworkAddressEntry &entry, addresses) {
|
||||
for (const QNetworkAddressEntry &entry : addresses) {
|
||||
ip = entry.ip();
|
||||
ipString = ip.toString();
|
||||
protocol = ip.protocol();
|
||||
@@ -2550,7 +2583,7 @@ void Session::configureListeningInterface()
|
||||
libt::error_code ec;
|
||||
const QStringList IPs = getListeningIPs();
|
||||
|
||||
foreach (const QString ip, IPs) {
|
||||
for (const QString ip : IPs) {
|
||||
if (ip.isEmpty()) {
|
||||
logger->addMessage(tr("qBittorrent is trying to listen on any interface port: %1", "e.g: qBittorrent is trying to listen on any interface port: TCP/6881").arg(QString::number(port)), Log::INFO);
|
||||
m_nativeSession->listen_on(ports, ec, 0, libt::session::listen_no_system_port);
|
||||
@@ -2570,7 +2603,7 @@ void Session::configureListeningInterface()
|
||||
#else
|
||||
m_listenInterfaceChanged = true;
|
||||
configureDeferred();
|
||||
#endif
|
||||
#endif // LIBTORRENT_VERSION_NUM < 10100
|
||||
}
|
||||
|
||||
int Session::globalDownloadSpeedLimit() const
|
||||
@@ -2983,7 +3016,7 @@ void Session::setMaxConnectionsPerTorrent(int max)
|
||||
m_maxConnectionsPerTorrent = max;
|
||||
|
||||
// Apply this to all session torrents
|
||||
for (const auto &handle: m_nativeSession->get_torrents()) {
|
||||
for (const auto &handle : m_nativeSession->get_torrents()) {
|
||||
if (!handle.is_valid()) continue;
|
||||
try {
|
||||
handle.set_max_connections(max);
|
||||
@@ -3005,7 +3038,7 @@ void Session::setMaxUploadsPerTorrent(int max)
|
||||
m_maxUploadsPerTorrent = max;
|
||||
|
||||
// Apply this to all session torrents
|
||||
for (const auto &handle: m_nativeSession->get_torrents()) {
|
||||
for (const auto &handle : m_nativeSession->get_torrents()) {
|
||||
if (!handle.is_valid()) continue;
|
||||
try {
|
||||
handle.set_max_uploads(max);
|
||||
@@ -3055,6 +3088,22 @@ void Session::setAsyncIOThreads(const int num)
|
||||
configureDeferred();
|
||||
}
|
||||
|
||||
int Session::checkingMemUsage() const
|
||||
{
|
||||
return qMax(1, m_checkingMemUsage.value());
|
||||
}
|
||||
|
||||
void Session::setCheckingMemUsage(int size)
|
||||
{
|
||||
size = qMax(size, 1);
|
||||
|
||||
if (size == m_checkingMemUsage)
|
||||
return;
|
||||
|
||||
m_checkingMemUsage = size;
|
||||
configureDeferred();
|
||||
}
|
||||
|
||||
int Session::diskCacheSize() const
|
||||
{
|
||||
int size = m_diskCacheSize;
|
||||
@@ -3213,6 +3262,11 @@ void Session::setQueueingSystemEnabled(bool enabled)
|
||||
if (enabled != m_isQueueingEnabled) {
|
||||
m_isQueueingEnabled = enabled;
|
||||
configureDeferred();
|
||||
|
||||
if (enabled)
|
||||
saveTorrentsQueue();
|
||||
else
|
||||
removeTorrentsQueue();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3543,18 +3597,6 @@ void Session::handleTorrentShareLimitChanged(TorrentHandle *const torrent)
|
||||
updateSeedingLimitTimer();
|
||||
}
|
||||
|
||||
void Session::handleTorrentsPrioritiesChanged()
|
||||
{
|
||||
// Save fastresume for the torrents that changed queue position
|
||||
for (TorrentHandle *const torrent : torrents()) {
|
||||
if (!torrent->isSeed()) {
|
||||
// cached vs actual queue position, qBt starts queue at 1
|
||||
if (torrent->queuePosition() != (torrent->nativeHandle().queue_position() + 1))
|
||||
saveTorrentResumeData(torrent);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Session::saveTorrentResumeData(TorrentHandle *const torrent)
|
||||
{
|
||||
qDebug("Saving fastresume data for %s", qUtf8Printable(torrent->name()));
|
||||
@@ -3677,11 +3719,8 @@ void Session::handleTorrentChecked(TorrentHandle *const torrent)
|
||||
|
||||
void Session::handleTorrentFinished(TorrentHandle *const torrent)
|
||||
{
|
||||
if (!torrent->hasError() && !torrent->hasMissingFiles()) {
|
||||
if (!torrent->hasError() && !torrent->hasMissingFiles())
|
||||
saveTorrentResumeData(torrent);
|
||||
if (isQueueingSystemEnabled())
|
||||
handleTorrentsPrioritiesChanged();
|
||||
}
|
||||
emit torrentFinished(torrent);
|
||||
|
||||
qDebug("Checking if the torrent contains torrent files to download");
|
||||
@@ -3724,8 +3763,9 @@ void Session::handleTorrentResumeDataReady(TorrentHandle *const torrent, const l
|
||||
QByteArray out;
|
||||
libt::bencode(std::back_inserter(out), data);
|
||||
|
||||
QMetaObject::invokeMethod(m_resumeDataSavingManager, "saveResumeData",
|
||||
Q_ARG(QString, torrent->hash()), Q_ARG(QByteArray, out));
|
||||
const QString filename = QString("%1.fastresume").arg(torrent->hash());
|
||||
QMetaObject::invokeMethod(m_resumeDataSavingManager, "save",
|
||||
Q_ARG(QString, filename), Q_ARG(QByteArray, out));
|
||||
}
|
||||
|
||||
void Session::handleTorrentResumeDataFailed(TorrentHandle *const torrent)
|
||||
@@ -3757,7 +3797,7 @@ void Session::handleTorrentTrackerWarning(TorrentHandle *const torrent, const QS
|
||||
|
||||
bool Session::hasPerTorrentRatioLimit() const
|
||||
{
|
||||
foreach (TorrentHandle *const torrent, m_torrents)
|
||||
for (TorrentHandle *const torrent : asConst(m_torrents))
|
||||
if (torrent->ratioLimit() >= 0) return true;
|
||||
|
||||
return false;
|
||||
@@ -3765,7 +3805,7 @@ bool Session::hasPerTorrentRatioLimit() const
|
||||
|
||||
bool Session::hasPerTorrentSeedingTimeLimit() const
|
||||
{
|
||||
foreach (TorrentHandle *const torrent, m_torrents)
|
||||
for (TorrentHandle *const torrent : asConst(m_torrents))
|
||||
if (torrent->seedingTimeLimit() >= 0) return true;
|
||||
|
||||
return false;
|
||||
@@ -3778,11 +3818,11 @@ void Session::initResumeFolder()
|
||||
if (resumeFolderDir.exists() || resumeFolderDir.mkpath(resumeFolderDir.absolutePath())) {
|
||||
m_resumeFolderLock.setFileName(resumeFolderDir.absoluteFilePath("session.lock"));
|
||||
if (!m_resumeFolderLock.open(QFile::WriteOnly)) {
|
||||
throw std::runtime_error("Cannot write to torrent resume folder.");
|
||||
throw RuntimeError {tr("Cannot write to torrent resume folder.")};
|
||||
}
|
||||
}
|
||||
else {
|
||||
throw std::runtime_error("Cannot create torrent resume folder.");
|
||||
throw RuntimeError {tr("Cannot create torrent resume folder.")};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3894,56 +3934,97 @@ void Session::startUpTorrents()
|
||||
++resumedTorrentsCount;
|
||||
};
|
||||
|
||||
qDebug("Starting up torrents");
|
||||
qDebug("Starting up torrents...");
|
||||
qDebug("Queue size: %d", fastresumes.size());
|
||||
// Resume downloads
|
||||
QMap<int, TorrentResumeData> queuedResumeData;
|
||||
int nextQueuePosition = 1;
|
||||
int numOfRemappedFiles = 0;
|
||||
|
||||
const QRegularExpression rx(QLatin1String("^([A-Fa-f0-9]{40})\\.fastresume$"));
|
||||
foreach (const QString &fastresumeName, fastresumes) {
|
||||
|
||||
if (isQueueingSystemEnabled()) {
|
||||
QFile queueFile {resumeDataDir.absoluteFilePath(QLatin1String {"queue"})};
|
||||
|
||||
// TODO: The following code is deprecated in 4.1.5. Remove after several releases in 4.2.x.
|
||||
// === BEGIN DEPRECATED CODE === //
|
||||
if (!queueFile.exists()) {
|
||||
// Resume downloads in a legacy manner
|
||||
QMap<int, TorrentResumeData> queuedResumeData;
|
||||
int nextQueuePosition = 1;
|
||||
int numOfRemappedFiles = 0;
|
||||
for (const QString &fastresumeName : asConst(fastresumes)) {
|
||||
const QRegularExpressionMatch rxMatch = rx.match(fastresumeName);
|
||||
if (!rxMatch.hasMatch()) continue;
|
||||
|
||||
QString hash = rxMatch.captured(1);
|
||||
QString fastresumePath = resumeDataDir.absoluteFilePath(fastresumeName);
|
||||
QByteArray data;
|
||||
CreateTorrentParams torrentParams;
|
||||
MagnetUri magnetUri;
|
||||
int queuePosition;
|
||||
if (readFile(fastresumePath, data) && loadTorrentResumeData(data, torrentParams, queuePosition, magnetUri)) {
|
||||
if (queuePosition <= nextQueuePosition) {
|
||||
startupTorrent({ hash, magnetUri, torrentParams, data });
|
||||
|
||||
if (queuePosition == nextQueuePosition) {
|
||||
++nextQueuePosition;
|
||||
while (queuedResumeData.contains(nextQueuePosition)) {
|
||||
startupTorrent(queuedResumeData.take(nextQueuePosition));
|
||||
++nextQueuePosition;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
int q = queuePosition;
|
||||
for (; queuedResumeData.contains(q); ++q) {}
|
||||
if (q != queuePosition)
|
||||
++numOfRemappedFiles;
|
||||
queuedResumeData[q] = {hash, magnetUri, torrentParams, data};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (numOfRemappedFiles > 0) {
|
||||
logger->addMessage(
|
||||
QString(tr("Queue positions were corrected in %1 resume files")).arg(numOfRemappedFiles),
|
||||
Log::CRITICAL);
|
||||
}
|
||||
|
||||
// starting up downloading torrents (queue position > 0)
|
||||
for (const TorrentResumeData &torrentResumeData : asConst(queuedResumeData))
|
||||
startupTorrent(torrentResumeData);
|
||||
|
||||
return;
|
||||
}
|
||||
// === END DEPRECATED CODE === //
|
||||
|
||||
QStringList queue;
|
||||
if (queueFile.open(QFile::ReadOnly)) {
|
||||
QByteArray line;
|
||||
while (!(line = queueFile.readLine()).isEmpty())
|
||||
queue.append(QString::fromLatin1(line.trimmed()) + QLatin1String {".fastresume"});
|
||||
}
|
||||
else {
|
||||
LogMsg(tr("Couldn't load torrents queue from '%1'. Error: %2")
|
||||
.arg(queueFile.fileName(), queueFile.errorString()), Log::WARNING);
|
||||
}
|
||||
|
||||
if (!queue.empty())
|
||||
fastresumes = queue + fastresumes.toSet().subtract(queue.toSet()).toList();
|
||||
}
|
||||
|
||||
for (const QString &fastresumeName : asConst(fastresumes)) {
|
||||
const QRegularExpressionMatch rxMatch = rx.match(fastresumeName);
|
||||
if (!rxMatch.hasMatch()) continue;
|
||||
|
||||
QString hash = rxMatch.captured(1);
|
||||
QString fastresumePath = resumeDataDir.absoluteFilePath(fastresumeName);
|
||||
const QString hash = rxMatch.captured(1);
|
||||
const QString fastresumePath = resumeDataDir.absoluteFilePath(fastresumeName);
|
||||
QByteArray data;
|
||||
CreateTorrentParams torrentParams;
|
||||
MagnetUri magnetUri;
|
||||
int queuePosition;
|
||||
if (readFile(fastresumePath, data) && loadTorrentResumeData(data, torrentParams, queuePosition, magnetUri)) {
|
||||
if (queuePosition <= nextQueuePosition) {
|
||||
startupTorrent({ hash, magnetUri, torrentParams, data });
|
||||
|
||||
if (queuePosition == nextQueuePosition) {
|
||||
++nextQueuePosition;
|
||||
while (queuedResumeData.contains(nextQueuePosition)) {
|
||||
startupTorrent(queuedResumeData.take(nextQueuePosition));
|
||||
++nextQueuePosition;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
int q = queuePosition;
|
||||
for (; queuedResumeData.contains(q); ++q) {
|
||||
}
|
||||
if (q != queuePosition) {
|
||||
++numOfRemappedFiles;
|
||||
}
|
||||
queuedResumeData[q] = {hash, magnetUri, torrentParams, data};
|
||||
}
|
||||
if (readFile(fastresumePath, data)
|
||||
&& loadTorrentResumeData(data, torrentParams, queuePosition, magnetUri)) {
|
||||
startupTorrent({hash, magnetUri, torrentParams, data});
|
||||
}
|
||||
}
|
||||
|
||||
if (numOfRemappedFiles > 0) {
|
||||
logger->addMessage(
|
||||
QString(tr("Queue positions were corrected in %1 resume files")).arg(numOfRemappedFiles),
|
||||
Log::CRITICAL);
|
||||
}
|
||||
|
||||
// starting up downloading torrents (queue position > 0)
|
||||
foreach (const TorrentResumeData &torrentResumeData, queuedResumeData)
|
||||
startupTorrent(torrentResumeData);
|
||||
}
|
||||
|
||||
quint64 Session::getAlltimeDL() const
|
||||
@@ -4035,7 +4116,7 @@ void Session::readAlerts()
|
||||
std::vector<libt::alert *> alerts;
|
||||
getPendingAlerts(alerts);
|
||||
|
||||
for (const auto a: alerts) {
|
||||
for (const auto a : alerts) {
|
||||
handleAlert(a);
|
||||
#if LIBTORRENT_VERSION_NUM < 10100
|
||||
delete a;
|
||||
@@ -4442,7 +4523,7 @@ void Session::handleSessionStatsAlert(libt::session_stats_alert *p)
|
||||
|
||||
emit statsUpdated();
|
||||
}
|
||||
#else
|
||||
#else // LIBTORRENT_VERSION_NUM >= 10100
|
||||
void Session::updateStats()
|
||||
{
|
||||
libt::session_status ss = m_nativeSession->status();
|
||||
@@ -4479,7 +4560,7 @@ void Session::updateStats()
|
||||
|
||||
emit statsUpdated();
|
||||
}
|
||||
#endif
|
||||
#endif // LIBTORRENT_VERSION_NUM >= 10100
|
||||
|
||||
void Session::handleStateUpdateAlert(libt::state_update_alert *p)
|
||||
{
|
||||
@@ -4487,14 +4568,14 @@ void Session::handleStateUpdateAlert(libt::state_update_alert *p)
|
||||
updateStats();
|
||||
#endif
|
||||
|
||||
foreach (const libt::torrent_status &status, p->status) {
|
||||
for (const libt::torrent_status &status : p->status) {
|
||||
TorrentHandle *const torrent = m_torrents.value(status.info_hash);
|
||||
if (torrent)
|
||||
torrent->handleStateUpdate(status);
|
||||
}
|
||||
|
||||
m_torrentStatusReport = TorrentStatusReport();
|
||||
foreach (TorrentHandle *const torrent, m_torrents) {
|
||||
for (TorrentHandle *const torrent : asConst(m_torrents)) {
|
||||
if (torrent->isDownloading())
|
||||
++m_torrentStatusReport.nbDownloading;
|
||||
if (torrent->isUploading())
|
||||
@@ -4530,7 +4611,7 @@ namespace
|
||||
return true;
|
||||
}
|
||||
|
||||
bool loadTorrentResumeData(const QByteArray &data, CreateTorrentParams &torrentParams, int &prio, MagnetUri &magnetUri)
|
||||
bool loadTorrentResumeData(const QByteArray &data, CreateTorrentParams &torrentParams, int &prio, MagnetUri &magnetUri)
|
||||
{
|
||||
torrentParams = CreateTorrentParams();
|
||||
torrentParams.restored = true;
|
||||
|
||||
@@ -237,7 +237,7 @@ namespace BitTorrent
|
||||
int diskJobTime = 0;
|
||||
} disk;
|
||||
};
|
||||
#endif
|
||||
#endif // LIBTORRENT_VERSION_NUM >= 10100
|
||||
|
||||
class Session : public QObject
|
||||
{
|
||||
@@ -377,6 +377,8 @@ namespace BitTorrent
|
||||
void setAnnounceToAllTiers(bool val);
|
||||
int asyncIOThreads() const;
|
||||
void setAsyncIOThreads(int num);
|
||||
int checkingMemUsage() const;
|
||||
void setCheckingMemUsage(int size);
|
||||
int diskCacheSize() const;
|
||||
void setDiskCacheSize(int size);
|
||||
int diskCacheTTL() const;
|
||||
@@ -481,7 +483,6 @@ namespace BitTorrent
|
||||
|
||||
// TorrentHandle interface
|
||||
void handleTorrentShareLimitChanged(TorrentHandle *const torrent);
|
||||
void handleTorrentsPrioritiesChanged();
|
||||
void handleTorrentNameChanged(TorrentHandle *const torrent);
|
||||
void handleTorrentSavePathChanged(TorrentHandle *const torrent);
|
||||
void handleTorrentCategoryChanged(TorrentHandle *const torrent, const QString &oldCategory);
|
||||
@@ -633,6 +634,8 @@ namespace BitTorrent
|
||||
void createTorrentHandle(const libtorrent::torrent_handle &nativeHandle);
|
||||
|
||||
void saveResumeData();
|
||||
void saveTorrentsQueue();
|
||||
void removeTorrentsQueue();
|
||||
|
||||
#if LIBTORRENT_VERSION_NUM < 10100
|
||||
void dispatchAlerts(libtorrent::alert *alertPtr);
|
||||
@@ -657,6 +660,7 @@ namespace BitTorrent
|
||||
CachedSettingValue<bool> m_announceToAllTrackers;
|
||||
CachedSettingValue<bool> m_announceToAllTiers;
|
||||
CachedSettingValue<int> m_asyncIOThreads;
|
||||
CachedSettingValue<int> m_checkingMemUsage;
|
||||
CachedSettingValue<int> m_diskCacheSize;
|
||||
CachedSettingValue<int> m_diskCacheTTL;
|
||||
CachedSettingValue<bool> m_useOSCache;
|
||||
|
||||
@@ -110,7 +110,7 @@ void TorrentCreatorThread::run()
|
||||
QStringList fileNames;
|
||||
QHash<QString, boost::int64_t> fileSizeMap;
|
||||
|
||||
for (const auto &dir : qAsConst(dirs)) {
|
||||
for (const auto &dir : asConst(dirs)) {
|
||||
QStringList tmpNames; // natural sort files within each dir
|
||||
|
||||
QDirIterator fileIter(dir, QDir::Files);
|
||||
@@ -126,7 +126,7 @@ void TorrentCreatorThread::run()
|
||||
fileNames += tmpNames;
|
||||
}
|
||||
|
||||
for (const auto &fileName : qAsConst(fileNames))
|
||||
for (const auto &fileName : asConst(fileNames))
|
||||
fs.add_file(fileName.toStdString(), fileSizeMap[fileName]);
|
||||
}
|
||||
|
||||
@@ -141,14 +141,14 @@ void TorrentCreatorThread::run()
|
||||
#endif
|
||||
|
||||
// Add url seeds
|
||||
foreach (QString seed, m_params.urlSeeds) {
|
||||
for (QString seed : asConst(m_params.urlSeeds)) {
|
||||
seed = seed.trimmed();
|
||||
if (!seed.isEmpty())
|
||||
newTorrent.add_url_seed(seed.toStdString());
|
||||
}
|
||||
|
||||
int tier = 0;
|
||||
foreach (const QString &tracker, m_params.trackers) {
|
||||
for (const QString &tracker : asConst(m_params.trackers)) {
|
||||
if (tracker.isEmpty())
|
||||
++tier;
|
||||
else
|
||||
|
||||
@@ -55,6 +55,7 @@
|
||||
#include <windows.h>
|
||||
#endif
|
||||
|
||||
#include "base/global.h"
|
||||
#include "base/logger.h"
|
||||
#include "base/preferences.h"
|
||||
#include "base/profile.h"
|
||||
@@ -77,7 +78,7 @@ namespace
|
||||
ListType setToEntryList(const QSet<QString> &input)
|
||||
{
|
||||
ListType entryList;
|
||||
foreach (const QString &setValue, input)
|
||||
for (const QString &setValue : input)
|
||||
entryList.emplace_back(setValue.toStdString());
|
||||
return entryList;
|
||||
}
|
||||
@@ -158,14 +159,14 @@ namespace
|
||||
{
|
||||
// new constructor is available
|
||||
template<typename T, typename std::enable_if<std::is_constructible<T, libt::torrent_info, bool>::value, int>::type = 0>
|
||||
T makeTorrentCreator(const libtorrent::torrent_info & ti)
|
||||
T makeTorrentCreator(const libtorrent::torrent_info &ti)
|
||||
{
|
||||
return T(ti, true);
|
||||
}
|
||||
|
||||
// new constructor isn't available
|
||||
template<typename T, typename std::enable_if<!std::is_constructible<T, libt::torrent_info, bool>::value, int>::type = 0>
|
||||
T makeTorrentCreator(const libtorrent::torrent_info & ti)
|
||||
T makeTorrentCreator(const libtorrent::torrent_info &ti)
|
||||
{
|
||||
return T(ti);
|
||||
}
|
||||
@@ -223,7 +224,7 @@ TorrentHandle::TorrentHandle(Session *session, const libtorrent::torrent_handle
|
||||
if (params.paused) {
|
||||
m_startupState = Started;
|
||||
}
|
||||
else if (!params.restored) {
|
||||
else if (!params.restored || !hasMetadata()) {
|
||||
// Resume torrent because it was added in "resumed" state
|
||||
// but it's actually paused during initialization
|
||||
m_startupState = Starting;
|
||||
@@ -374,10 +375,9 @@ QString TorrentHandle::nativeActualSavePath() const
|
||||
QList<TrackerEntry> TorrentHandle::trackers() const
|
||||
{
|
||||
QList<TrackerEntry> entries;
|
||||
std::vector<libt::announce_entry> announces;
|
||||
const std::vector<libt::announce_entry> announces = m_nativeHandle.trackers();
|
||||
|
||||
announces = m_nativeHandle.trackers();
|
||||
foreach (const libt::announce_entry &tracker, announces)
|
||||
for (const libt::announce_entry &tracker : announces)
|
||||
entries << tracker;
|
||||
|
||||
return entries;
|
||||
@@ -391,7 +391,7 @@ QHash<QString, TrackerInfo> TorrentHandle::trackerInfos() const
|
||||
void TorrentHandle::addTrackers(const QList<TrackerEntry> &trackers)
|
||||
{
|
||||
QList<TrackerEntry> addedTrackers;
|
||||
foreach (const TrackerEntry &tracker, trackers) {
|
||||
for (const TrackerEntry &tracker : trackers) {
|
||||
if (addTracker(tracker))
|
||||
addedTrackers << tracker;
|
||||
}
|
||||
@@ -400,13 +400,13 @@ void TorrentHandle::addTrackers(const QList<TrackerEntry> &trackers)
|
||||
m_session->handleTorrentTrackersAdded(this, addedTrackers);
|
||||
}
|
||||
|
||||
void TorrentHandle::replaceTrackers(QList<TrackerEntry> trackers)
|
||||
void TorrentHandle::replaceTrackers(const QList<TrackerEntry> &trackers)
|
||||
{
|
||||
QList<TrackerEntry> existingTrackers = this->trackers();
|
||||
QList<TrackerEntry> addedTrackers;
|
||||
|
||||
std::vector<libt::announce_entry> announces;
|
||||
foreach (const TrackerEntry &tracker, trackers) {
|
||||
for (const TrackerEntry &tracker : trackers) {
|
||||
announces.push_back(tracker.nativeEntry());
|
||||
if (!existingTrackers.contains(tracker))
|
||||
addedTrackers << tracker;
|
||||
@@ -438,9 +438,9 @@ bool TorrentHandle::addTracker(const TrackerEntry &tracker)
|
||||
QList<QUrl> TorrentHandle::urlSeeds() const
|
||||
{
|
||||
QList<QUrl> urlSeeds;
|
||||
std::set<std::string> seeds = m_nativeHandle.url_seeds();
|
||||
const std::set<std::string> seeds = m_nativeHandle.url_seeds();
|
||||
|
||||
foreach (const std::string &urlSeed, seeds)
|
||||
for (const std::string &urlSeed : seeds)
|
||||
urlSeeds.append(QUrl(urlSeed.c_str()));
|
||||
|
||||
return urlSeeds;
|
||||
@@ -449,7 +449,7 @@ QList<QUrl> TorrentHandle::urlSeeds() const
|
||||
void TorrentHandle::addUrlSeeds(const QList<QUrl> &urlSeeds)
|
||||
{
|
||||
QList<QUrl> addedUrlSeeds;
|
||||
foreach (const QUrl &urlSeed, urlSeeds) {
|
||||
for (const QUrl &urlSeed : urlSeeds) {
|
||||
if (addUrlSeed(urlSeed))
|
||||
addedUrlSeeds << urlSeed;
|
||||
}
|
||||
@@ -461,7 +461,7 @@ void TorrentHandle::addUrlSeeds(const QList<QUrl> &urlSeeds)
|
||||
void TorrentHandle::removeUrlSeeds(const QList<QUrl> &urlSeeds)
|
||||
{
|
||||
QList<QUrl> removedUrlSeeds;
|
||||
foreach (const QUrl &urlSeed, urlSeeds) {
|
||||
for (const QUrl &urlSeed : urlSeeds) {
|
||||
if (removeUrlSeed(urlSeed))
|
||||
removedUrlSeeds << urlSeed;
|
||||
}
|
||||
@@ -596,8 +596,7 @@ bool TorrentHandle::removeTag(const QString &tag)
|
||||
|
||||
void TorrentHandle::removeAllTags()
|
||||
{
|
||||
// QT automatically copies the container in foreach, so it's safe to mutate it.
|
||||
foreach (const QString &tag, m_tags)
|
||||
for (const QString &tag : asConst(tags()))
|
||||
removeTag(tag);
|
||||
}
|
||||
|
||||
@@ -623,7 +622,7 @@ QString TorrentHandle::filePath(int index) const
|
||||
|
||||
QString TorrentHandle::fileName(int index) const
|
||||
{
|
||||
if (!hasMetadata()) return QString();
|
||||
if (!hasMetadata()) return QString();
|
||||
return Utils::Fs::fileName(filePath(index));
|
||||
}
|
||||
|
||||
@@ -636,7 +635,7 @@ qlonglong TorrentHandle::fileSize(int index) const
|
||||
// to all files in a torrent
|
||||
QStringList TorrentHandle::absoluteFilePaths() const
|
||||
{
|
||||
if (!hasMetadata()) return QStringList();
|
||||
if (!hasMetadata()) return QStringList();
|
||||
|
||||
QDir saveDir(savePath(true));
|
||||
QStringList res;
|
||||
@@ -647,7 +646,7 @@ QStringList TorrentHandle::absoluteFilePaths() const
|
||||
|
||||
QStringList TorrentHandle::absoluteFilePathsUnwanted() const
|
||||
{
|
||||
if (!hasMetadata()) return QStringList();
|
||||
if (!hasMetadata()) return QStringList();
|
||||
|
||||
QDir saveDir(savePath(true));
|
||||
QStringList res;
|
||||
@@ -883,9 +882,9 @@ bool TorrentHandle::hasError() const
|
||||
|
||||
bool TorrentHandle::hasFilteredPieces() const
|
||||
{
|
||||
std::vector<int> pp = m_nativeHandle.piece_priorities();
|
||||
const std::vector<int> pp = m_nativeHandle.piece_priorities();
|
||||
|
||||
foreach (const int priority, pp)
|
||||
for (const int priority : pp)
|
||||
if (priority == 0) return true;
|
||||
|
||||
return false;
|
||||
@@ -973,12 +972,13 @@ qulonglong TorrentHandle::eta() const
|
||||
QVector<qreal> TorrentHandle::filesProgress() const
|
||||
{
|
||||
std::vector<boost::int64_t> fp;
|
||||
QVector<qreal> result;
|
||||
m_nativeHandle.file_progress(fp, libt::torrent_handle::piece_granularity);
|
||||
|
||||
int count = static_cast<int>(fp.size());
|
||||
const int count = static_cast<int>(fp.size());
|
||||
QVector<qreal> result;
|
||||
result.reserve(count);
|
||||
for (int i = 0; i < count; ++i) {
|
||||
qlonglong size = fileSize(i);
|
||||
const qlonglong size = fileSize(i);
|
||||
if ((size <= 0) || (fp[i] == size))
|
||||
result << 1;
|
||||
else
|
||||
@@ -1086,7 +1086,7 @@ QList<PeerInfo> TorrentHandle::peers() const
|
||||
|
||||
m_nativeHandle.get_peer_info(nativePeers);
|
||||
|
||||
foreach (const libt::peer_info &peer, nativePeers)
|
||||
for (const libt::peer_info &peer : nativePeers)
|
||||
peers << PeerInfo(this, peer);
|
||||
|
||||
return peers;
|
||||
@@ -1424,16 +1424,6 @@ bool TorrentHandle::saveTorrentFile(const QString &path)
|
||||
return false;
|
||||
}
|
||||
|
||||
void TorrentHandle::setFilePriority(int index, int priority)
|
||||
{
|
||||
std::vector<int> priorities = m_nativeHandle.file_priorities();
|
||||
|
||||
if ((priorities.size() > static_cast<quint64>(index)) && (priorities[index] != priority)) {
|
||||
priorities[index] = priority;
|
||||
prioritizeFiles(QVector<int>::fromStdVector(priorities));
|
||||
}
|
||||
}
|
||||
|
||||
void TorrentHandle::handleStateUpdate(const libt::torrent_status &nativeStatus)
|
||||
{
|
||||
updateStatus(nativeStatus);
|
||||
@@ -2062,7 +2052,7 @@ void TorrentHandle::prioritizeFiles(const QVector<int> &priorities)
|
||||
if (created) {
|
||||
// Hide the folder on Windows
|
||||
qDebug() << "Hiding folder (Windows)";
|
||||
std::wstring winPath = Utils::Fs::toNativePath(unwantedAbsPath).toStdWString();
|
||||
std::wstring winPath = Utils::Fs::toNativePath(unwantedAbsPath).toStdWString();
|
||||
DWORD dwAttrs = ::GetFileAttributesW(winPath.c_str());
|
||||
bool ret = ::SetFileAttributesW(winPath.c_str(), dwAttrs | FILE_ATTRIBUTE_HIDDEN);
|
||||
Q_ASSERT(ret != 0); Q_UNUSED(ret);
|
||||
@@ -2100,7 +2090,7 @@ void TorrentHandle::prioritizeFiles(const QVector<int> &priorities)
|
||||
|
||||
QVector<qreal> TorrentHandle::availableFileFractions() const
|
||||
{
|
||||
const auto filesCount = this->filesCount();
|
||||
const int filesCount = this->filesCount();
|
||||
if (filesCount < 0) return {};
|
||||
|
||||
const QVector<int> piecesAvailability = pieceAvailability();
|
||||
@@ -2109,12 +2099,13 @@ QVector<qreal> TorrentHandle::availableFileFractions() const
|
||||
|
||||
QVector<qreal> res;
|
||||
res.reserve(filesCount);
|
||||
TorrentInfo info = this->info();
|
||||
for (int file = 0; file < filesCount; ++file) {
|
||||
TorrentInfo::PieceRange filePieces = info.filePieces(file);
|
||||
const TorrentInfo info = this->info();
|
||||
for (int i = 0; i < filesCount; ++i) {
|
||||
const TorrentInfo::PieceRange filePieces = info.filePieces(i);
|
||||
|
||||
int availablePieces = 0;
|
||||
for (int piece = filePieces.first(); piece <= filePieces.last(); ++piece) {
|
||||
availablePieces += piecesAvailability[piece] > 0 ? 1 : 0;
|
||||
availablePieces += (piecesAvailability[piece] > 0) ? 1 : 0;
|
||||
}
|
||||
res.push_back(static_cast<qreal>(availablePieces) / filePieces.size());
|
||||
}
|
||||
|
||||
@@ -348,7 +348,6 @@ namespace BitTorrent
|
||||
void renameFile(int index, const QString &name);
|
||||
bool saveTorrentFile(const QString &path);
|
||||
void prioritizeFiles(const QVector<int> &priorities);
|
||||
void setFilePriority(int index, int priority);
|
||||
void setRatioLimit(qreal limit);
|
||||
void setSeedingTimeLimit(int limit);
|
||||
void setUploadLimit(int limit);
|
||||
@@ -356,7 +355,7 @@ namespace BitTorrent
|
||||
void setSuperSeeding(bool enable);
|
||||
void flushCache();
|
||||
void addTrackers(const QList<TrackerEntry> &trackers);
|
||||
void replaceTrackers(QList<TrackerEntry> trackers);
|
||||
void replaceTrackers(const QList<TrackerEntry> &trackers);
|
||||
void addUrlSeeds(const QList<QUrl> &urlSeeds);
|
||||
void removeUrlSeeds(const QList<QUrl> &urlSeeds);
|
||||
bool connectPeer(const PeerAddress &peerAddress);
|
||||
|
||||
@@ -247,7 +247,7 @@ QList<TrackerEntry> TorrentInfo::trackers() const
|
||||
if (!isValid()) return QList<TrackerEntry>();
|
||||
|
||||
QList<TrackerEntry> trackers;
|
||||
foreach (const libt::announce_entry &tracker, m_nativeInfo->trackers())
|
||||
for (const libt::announce_entry &tracker : m_nativeInfo->trackers())
|
||||
trackers.append(tracker);
|
||||
|
||||
return trackers;
|
||||
@@ -258,7 +258,7 @@ QList<QUrl> TorrentInfo::urlSeeds() const
|
||||
if (!isValid()) return QList<QUrl>();
|
||||
|
||||
QList<QUrl> urlSeeds;
|
||||
foreach (const libt::web_seed_entry &webSeed, m_nativeInfo->web_seeds())
|
||||
for (const libt::web_seed_entry &webSeed : m_nativeInfo->web_seeds())
|
||||
if (webSeed.type == libt::web_seed_entry::url_seed)
|
||||
urlSeeds.append(QUrl(webSeed.url.c_str()));
|
||||
|
||||
@@ -350,7 +350,7 @@ void TorrentInfo::renameFile(const int index, const QString &newPath)
|
||||
nativeInfo()->rename_file(index, Utils::Fs::toNativePath(newPath).toStdString());
|
||||
}
|
||||
|
||||
int BitTorrent::TorrentInfo::fileIndex(const QString& fileName) const
|
||||
int BitTorrent::TorrentInfo::fileIndex(const QString &fileName) const
|
||||
{
|
||||
// the check whether the object is valid is not needed here
|
||||
// because if filesCount() returns -1 the loop exits immediately
|
||||
|
||||
@@ -60,7 +60,7 @@ bool Peer::operator==(const Peer &other) const
|
||||
|
||||
QString Peer::uid() const
|
||||
{
|
||||
return ip + ':' + QString::number(port);
|
||||
return ip.toString() + ':' + QString::number(port);
|
||||
}
|
||||
|
||||
libtorrent::entry Peer::toEntry(bool noPeerId) const
|
||||
@@ -68,7 +68,7 @@ libtorrent::entry Peer::toEntry(bool noPeerId) const
|
||||
libtorrent::entry::dictionary_type peerMap;
|
||||
if (!noPeerId)
|
||||
peerMap["id"] = libtorrent::entry(peerId.toStdString());
|
||||
peerMap["ip"] = libtorrent::entry(ip.toStdString());
|
||||
peerMap["ip"] = libtorrent::entry(ip.toString().toStdString());
|
||||
peerMap["port"] = libtorrent::entry(port);
|
||||
|
||||
return libtorrent::entry(peerMap);
|
||||
@@ -136,7 +136,7 @@ void Tracker::respondToAnnounceRequest()
|
||||
QMap<QString, QByteArray> queryParams;
|
||||
// Parse GET parameters
|
||||
using namespace Utils::ByteArray;
|
||||
for (const QByteArray ¶m : copyAsConst(splitToViews(m_request.query, "&"))) {
|
||||
for (const QByteArray ¶m : asConst(splitToViews(m_request.query, "&"))) {
|
||||
const int sepPos = param.indexOf('=');
|
||||
if (sepPos <= 0) continue; // ignores params without name
|
||||
|
||||
@@ -145,10 +145,12 @@ void Tracker::respondToAnnounceRequest()
|
||||
queryParams[paramName] = paramValue;
|
||||
}
|
||||
|
||||
TrackerAnnounceRequest annonceReq;
|
||||
TrackerAnnounceRequest announceReq;
|
||||
|
||||
// IP
|
||||
annonceReq.peer.ip = m_env.clientAddress.toString();
|
||||
// Use the "ip" parameter provided from tracker request first, then fall back to client IP if invalid
|
||||
const QHostAddress paramIP {QString::fromLatin1(queryParams.value("ip"))};
|
||||
announceReq.peer.ip = paramIP.isNull() ? m_env.clientAddress : paramIP;
|
||||
|
||||
// 1. Get info_hash
|
||||
if (!queryParams.contains("info_hash")) {
|
||||
@@ -156,7 +158,7 @@ void Tracker::respondToAnnounceRequest()
|
||||
status(101, "Missing info_hash");
|
||||
return;
|
||||
}
|
||||
annonceReq.infoHash = queryParams.value("info_hash");
|
||||
announceReq.infoHash = queryParams.value("info_hash");
|
||||
// info_hash cannot be longer than 20 bytes
|
||||
/*if (annonce_req.info_hash.toLatin1().length() > 20) {
|
||||
qDebug("Tracker: Info_hash is not 20 byte long: %s (%d)", qUtf8Printable(annonce_req.info_hash), annonce_req.info_hash.toLatin1().length());
|
||||
@@ -170,7 +172,7 @@ void Tracker::respondToAnnounceRequest()
|
||||
status(102, "Missing peer_id");
|
||||
return;
|
||||
}
|
||||
annonceReq.peer.peerId = queryParams.value("peer_id");
|
||||
announceReq.peer.peerId = queryParams.value("peer_id");
|
||||
// peer_id cannot be longer than 20 bytes
|
||||
/*if (annonce_req.peer.peer_id.length() > 20) {
|
||||
qDebug("Tracker: peer_id is not 20 byte long: %s", qUtf8Printable(annonce_req.peer.peer_id));
|
||||
@@ -185,52 +187,52 @@ void Tracker::respondToAnnounceRequest()
|
||||
return;
|
||||
}
|
||||
bool ok = false;
|
||||
annonceReq.peer.port = queryParams.value("port").toInt(&ok);
|
||||
if (!ok || (annonceReq.peer.port < 0) || (annonceReq.peer.port > 65535)) {
|
||||
qDebug("Tracker: Invalid port number (%d)", annonceReq.peer.port);
|
||||
announceReq.peer.port = queryParams.value("port").toInt(&ok);
|
||||
if (!ok || (announceReq.peer.port < 0) || (announceReq.peer.port > 65535)) {
|
||||
qDebug("Tracker: Invalid port number (%d)", announceReq.peer.port);
|
||||
status(103, "Missing port");
|
||||
return;
|
||||
}
|
||||
|
||||
// 4. Get event
|
||||
annonceReq.event = "";
|
||||
announceReq.event = "";
|
||||
if (queryParams.contains("event")) {
|
||||
annonceReq.event = queryParams.value("event");
|
||||
qDebug("Tracker: event is %s", qUtf8Printable(annonceReq.event));
|
||||
announceReq.event = queryParams.value("event");
|
||||
qDebug("Tracker: event is %s", qUtf8Printable(announceReq.event));
|
||||
}
|
||||
|
||||
// 5. Get numwant
|
||||
annonceReq.numwant = 50;
|
||||
announceReq.numwant = 50;
|
||||
if (queryParams.contains("numwant")) {
|
||||
int tmp = queryParams.value("numwant").toInt();
|
||||
if (tmp > 0) {
|
||||
qDebug("Tracker: numwant = %d", tmp);
|
||||
annonceReq.numwant = tmp;
|
||||
announceReq.numwant = tmp;
|
||||
}
|
||||
}
|
||||
|
||||
// 6. no_peer_id (extension)
|
||||
annonceReq.noPeerId = false;
|
||||
announceReq.noPeerId = false;
|
||||
if (queryParams.contains("no_peer_id"))
|
||||
annonceReq.noPeerId = true;
|
||||
announceReq.noPeerId = true;
|
||||
|
||||
// 7. TODO: support "compact" extension
|
||||
|
||||
// Done parsing, now let's reply
|
||||
if (annonceReq.event == "stopped") {
|
||||
unregisterPeer(annonceReq);
|
||||
if (announceReq.event == "stopped") {
|
||||
unregisterPeer(announceReq);
|
||||
}
|
||||
else {
|
||||
registerPeer(annonceReq);
|
||||
replyWithPeerList(annonceReq);
|
||||
registerPeer(announceReq);
|
||||
replyWithPeerList(announceReq);
|
||||
}
|
||||
}
|
||||
|
||||
void Tracker::registerPeer(const TrackerAnnounceRequest &annonceReq)
|
||||
void Tracker::registerPeer(const TrackerAnnounceRequest &announceReq)
|
||||
{
|
||||
if (annonceReq.peer.port == 0) return;
|
||||
if (announceReq.peer.port == 0) return;
|
||||
|
||||
if (!m_torrents.contains(annonceReq.infoHash)) {
|
||||
if (!m_torrents.contains(announceReq.infoHash)) {
|
||||
// Unknown torrent
|
||||
if (m_torrents.size() == MAX_TORRENTS) {
|
||||
// Reached max size, remove a random torrent
|
||||
@@ -239,34 +241,34 @@ void Tracker::registerPeer(const TrackerAnnounceRequest &annonceReq)
|
||||
}
|
||||
|
||||
// Register the user
|
||||
PeerList &peers = m_torrents[annonceReq.infoHash];
|
||||
if (!peers.contains(annonceReq.peer.uid())) {
|
||||
PeerList &peers = m_torrents[announceReq.infoHash];
|
||||
if (!peers.contains(announceReq.peer.uid())) {
|
||||
// Unknown peer
|
||||
if (peers.size() == MAX_PEERS_PER_TORRENT) {
|
||||
// Too many peers, remove a random one
|
||||
peers.erase(peers.begin());
|
||||
}
|
||||
}
|
||||
peers[annonceReq.peer.uid()] = annonceReq.peer;
|
||||
peers[announceReq.peer.uid()] = announceReq.peer;
|
||||
}
|
||||
|
||||
void Tracker::unregisterPeer(const TrackerAnnounceRequest &annonceReq)
|
||||
void Tracker::unregisterPeer(const TrackerAnnounceRequest &announceReq)
|
||||
{
|
||||
if (annonceReq.peer.port == 0) return;
|
||||
if (announceReq.peer.port == 0) return;
|
||||
|
||||
if (m_torrents[annonceReq.infoHash].remove(annonceReq.peer.uid()) > 0)
|
||||
if (m_torrents[announceReq.infoHash].remove(announceReq.peer.uid()) > 0)
|
||||
qDebug("Tracker: Peer stopped downloading, deleting it from the list");
|
||||
}
|
||||
|
||||
void Tracker::replyWithPeerList(const TrackerAnnounceRequest &annonceReq)
|
||||
void Tracker::replyWithPeerList(const TrackerAnnounceRequest &announceReq)
|
||||
{
|
||||
// Prepare the entry for bencoding
|
||||
libtorrent::entry::dictionary_type replyDict;
|
||||
replyDict["interval"] = libtorrent::entry(ANNOUNCE_INTERVAL);
|
||||
|
||||
libtorrent::entry::list_type peerList;
|
||||
for (const Peer &p : m_torrents.value(annonceReq.infoHash))
|
||||
peerList.push_back(p.toEntry(annonceReq.noPeerId));
|
||||
for (const Peer &p : m_torrents.value(announceReq.infoHash))
|
||||
peerList.push_back(p.toEntry(announceReq.noPeerId));
|
||||
replyDict["peers"] = libtorrent::entry(peerList);
|
||||
|
||||
const libtorrent::entry replyEntry(replyDict);
|
||||
|
||||
@@ -32,6 +32,7 @@
|
||||
|
||||
#include <QHash>
|
||||
#include <QObject>
|
||||
#include <QHostAddress>
|
||||
|
||||
#include "base/http/irequesthandler.h"
|
||||
#include "base/http/responsebuilder.h"
|
||||
@@ -51,7 +52,7 @@ namespace BitTorrent
|
||||
{
|
||||
struct Peer
|
||||
{
|
||||
QString ip;
|
||||
QHostAddress ip;
|
||||
QByteArray peerId;
|
||||
int port;
|
||||
|
||||
@@ -90,9 +91,9 @@ namespace BitTorrent
|
||||
|
||||
private:
|
||||
void respondToAnnounceRequest();
|
||||
void registerPeer(const TrackerAnnounceRequest &annonceReq);
|
||||
void unregisterPeer(const TrackerAnnounceRequest &annonceReq);
|
||||
void replyWithPeerList(const TrackerAnnounceRequest &annonceReq);
|
||||
void registerPeer(const TrackerAnnounceRequest &announceReq);
|
||||
void unregisterPeer(const TrackerAnnounceRequest &announceReq);
|
||||
void replyWithPeerList(const TrackerAnnounceRequest &announceReq);
|
||||
|
||||
Http::Server *m_server;
|
||||
TorrentList m_torrents;
|
||||
|
||||
@@ -44,10 +44,10 @@ namespace BitTorrent
|
||||
public:
|
||||
enum Status
|
||||
{
|
||||
NotContacted,
|
||||
Working,
|
||||
Updating,
|
||||
NotWorking
|
||||
NotContacted = 1,
|
||||
Working = 2,
|
||||
Updating = 3,
|
||||
NotWorking = 4
|
||||
};
|
||||
|
||||
TrackerEntry(const QString &url);
|
||||
|
||||
@@ -30,11 +30,10 @@
|
||||
|
||||
RuntimeError::RuntimeError(const QString &message)
|
||||
: std::runtime_error {message.toUtf8().data()}
|
||||
, m_message {message}
|
||||
{
|
||||
}
|
||||
|
||||
QString RuntimeError::message() const
|
||||
{
|
||||
return m_message;
|
||||
return what();
|
||||
}
|
||||
|
||||
@@ -36,7 +36,4 @@ class RuntimeError : public std::runtime_error
|
||||
public:
|
||||
explicit RuntimeError(const QString &message = "");
|
||||
QString message() const;
|
||||
|
||||
private:
|
||||
const QString m_message;
|
||||
};
|
||||
|
||||
@@ -64,7 +64,7 @@ FileSystemWatcher::FileSystemWatcher(QObject *parent)
|
||||
QStringList FileSystemWatcher::directories() const
|
||||
{
|
||||
QStringList dirs = QFileSystemWatcher::directories();
|
||||
for (const QDir &dir : qAsConst(m_watchedFolders))
|
||||
for (const QDir &dir : asConst(m_watchedFolders))
|
||||
dirs << dir.canonicalPath();
|
||||
return dirs;
|
||||
}
|
||||
@@ -113,7 +113,7 @@ void FileSystemWatcher::scanLocalFolder(const QString &path)
|
||||
|
||||
void FileSystemWatcher::scanNetworkFolders()
|
||||
{
|
||||
for (const QDir &dir : qAsConst(m_watchedFolders))
|
||||
for (const QDir &dir : asConst(m_watchedFolders))
|
||||
processTorrentsInDir(dir);
|
||||
}
|
||||
|
||||
|
||||
@@ -33,16 +33,13 @@
|
||||
|
||||
const char C_TORRENT_FILE_EXTENSION[] = ".torrent";
|
||||
|
||||
|
||||
#if QT_VERSION < QT_VERSION_CHECK(5, 7, 0)
|
||||
template <typename T>
|
||||
constexpr typename std::add_const<T>::type &qAsConst(T &t) noexcept { return t; }
|
||||
constexpr typename std::add_const<T>::type &asConst(T &t) noexcept { return t; }
|
||||
|
||||
// prevent rvalue arguments:
|
||||
// Forward rvalue as const
|
||||
template <typename T>
|
||||
void qAsConst(const T &&) = delete;
|
||||
#endif
|
||||
constexpr typename std::add_const<T>::type asConst(T &&t) noexcept { return std::move(t); }
|
||||
|
||||
// returns a const object copy
|
||||
// Prevent const rvalue arguments
|
||||
template <typename T>
|
||||
constexpr typename std::add_const<T>::type copyAsConst(T &&t) noexcept { return std::move(t); }
|
||||
void asConst(const T &&) = delete;
|
||||
|
||||
@@ -133,7 +133,7 @@ bool Connection::acceptsGzipEncoding(QString codings)
|
||||
|
||||
const auto isCodingAvailable = [](const QStringList &list, const QString &encoding) -> bool
|
||||
{
|
||||
foreach (const QString &str, list) {
|
||||
for (const QString &str : list) {
|
||||
if (!str.startsWith(encoding))
|
||||
continue;
|
||||
|
||||
|
||||
@@ -146,9 +146,9 @@ QList<QSslCipher> Server::safeCipherList() const
|
||||
const QStringList badCiphers = {"idea", "rc4"};
|
||||
const QList<QSslCipher> allCiphers = QSslSocket::supportedCiphers();
|
||||
QList<QSslCipher> safeCiphers;
|
||||
foreach (const QSslCipher &cipher, allCiphers) {
|
||||
for (const QSslCipher &cipher : allCiphers) {
|
||||
bool isSafe = true;
|
||||
foreach (const QString &badCipher, badCiphers) {
|
||||
for (const QString &badCipher : badCiphers) {
|
||||
if (cipher.name().contains(badCipher, Qt::CaseInsensitive)) {
|
||||
isSafe = false;
|
||||
break;
|
||||
|
||||
@@ -52,6 +52,7 @@ namespace Http
|
||||
const char HEADER_HOST[] = "host";
|
||||
const char HEADER_ORIGIN[] = "origin";
|
||||
const char HEADER_REFERER[] = "referer";
|
||||
const char HEADER_REFERRER_POLICY[] = "referrer-policy";
|
||||
const char HEADER_SET_COOKIE[] = "set-cookie";
|
||||
const char HEADER_X_CONTENT_TYPE_OPTIONS[] = "x-content-type-options";
|
||||
const char HEADER_X_FORWARDED_HOST[] = "x-forwarded-host";
|
||||
@@ -107,7 +108,7 @@ namespace Http
|
||||
uint code;
|
||||
QString text;
|
||||
|
||||
ResponseStatus(uint code = 200, const QString& text = "OK"): code(code), text(text) {}
|
||||
ResponseStatus(uint code = 200, const QString &text = "OK"): code(code), text(text) {}
|
||||
};
|
||||
|
||||
struct Response
|
||||
@@ -116,7 +117,7 @@ namespace Http
|
||||
QStringMap headers;
|
||||
QByteArray content;
|
||||
|
||||
Response(uint code = 200, const QString& text = "OK"): status(code, text) {}
|
||||
Response(uint code = 200, const QString &text = "OK"): status(code, text) {}
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -39,6 +39,7 @@
|
||||
#include <QSslError>
|
||||
#include <QUrl>
|
||||
|
||||
#include "base/global.h"
|
||||
#include "base/preferences.h"
|
||||
#include "downloadhandler.h"
|
||||
#include "proxyconfigurationmanager.h"
|
||||
@@ -56,7 +57,7 @@ namespace
|
||||
{
|
||||
QDateTime now = QDateTime::currentDateTime();
|
||||
QList<QNetworkCookie> cookies = Preferences::instance()->getNetworkCookies();
|
||||
foreach (const QNetworkCookie &cookie, Preferences::instance()->getNetworkCookies()) {
|
||||
for (const QNetworkCookie &cookie : asConst(Preferences::instance()->getNetworkCookies())) {
|
||||
if (cookie.isSessionCookie() || (cookie.expirationDate() <= now))
|
||||
cookies.removeAll(cookie);
|
||||
}
|
||||
@@ -68,7 +69,7 @@ namespace
|
||||
{
|
||||
QDateTime now = QDateTime::currentDateTime();
|
||||
QList<QNetworkCookie> cookies = allCookies();
|
||||
foreach (const QNetworkCookie &cookie, allCookies()) {
|
||||
for (const QNetworkCookie &cookie : asConst(allCookies())) {
|
||||
if (cookie.isSessionCookie() || (cookie.expirationDate() <= now))
|
||||
cookies.removeAll(cookie);
|
||||
}
|
||||
@@ -83,7 +84,7 @@ namespace
|
||||
{
|
||||
QDateTime now = QDateTime::currentDateTime();
|
||||
QList<QNetworkCookie> cookies = QNetworkCookieJar::cookiesForUrl(url);
|
||||
foreach (const QNetworkCookie &cookie, QNetworkCookieJar::cookiesForUrl(url)) {
|
||||
for (const QNetworkCookie &cookie : asConst(QNetworkCookieJar::cookiesForUrl(url))) {
|
||||
if (!cookie.isSessionCookie() && (cookie.expirationDate() <= now))
|
||||
cookies.removeAll(cookie);
|
||||
}
|
||||
@@ -95,7 +96,7 @@ namespace
|
||||
{
|
||||
QDateTime now = QDateTime::currentDateTime();
|
||||
QList<QNetworkCookie> cookies = cookieList;
|
||||
foreach (const QNetworkCookie &cookie, cookieList) {
|
||||
for (const QNetworkCookie &cookie : cookieList) {
|
||||
if (!cookie.isSessionCookie() && (cookie.expirationDate() <= now))
|
||||
cookies.removeAll(cookie);
|
||||
}
|
||||
|
||||
@@ -40,7 +40,7 @@ const QString KEY_PASSWORD = SETTINGS_KEY("Password");
|
||||
|
||||
namespace
|
||||
{
|
||||
inline SettingsStorage *settings() { return SettingsStorage::instance(); }
|
||||
inline SettingsStorage *settings() { return SettingsStorage::instance(); }
|
||||
|
||||
inline bool isSameConfig(const Net::ProxyConfiguration &conf1, const Net::ProxyConfiguration &conf2)
|
||||
{
|
||||
|
||||
@@ -43,6 +43,7 @@
|
||||
#include <QTcpSocket>
|
||||
#endif
|
||||
|
||||
#include "base/global.h"
|
||||
#include "base/logger.h"
|
||||
#include "base/preferences.h"
|
||||
|
||||
@@ -291,7 +292,7 @@ QByteArray Smtp::encodeMimeHeader(const QString &key, const QString &value, QTex
|
||||
if (!prefix.isEmpty()) line += prefix;
|
||||
if (!value.contains("=?") && latin1->canEncode(value)) {
|
||||
bool firstWord = true;
|
||||
foreach (const QByteArray& word, value.toLatin1().split(' ')) {
|
||||
for (const QByteArray &word : asConst(value.toLatin1().split(' '))) {
|
||||
if (line.size() > 78) {
|
||||
rv = rv + line + "\r\n";
|
||||
line.clear();
|
||||
|
||||
@@ -50,6 +50,7 @@
|
||||
#include <CoreServices/CoreServices.h>
|
||||
#endif
|
||||
|
||||
#include "global.h"
|
||||
#include "logger.h"
|
||||
#include "settingsstorage.h"
|
||||
#include "utils/fs.h"
|
||||
@@ -212,7 +213,7 @@ void Preferences::setCloseToTrayNotified(bool b)
|
||||
{
|
||||
setValue("Preferences/General/CloseToTrayNotified", b);
|
||||
}
|
||||
#endif
|
||||
#endif // Q_OS_MAC
|
||||
|
||||
bool Preferences::isToolbarDisplayed() const
|
||||
{
|
||||
@@ -293,7 +294,7 @@ void Preferences::setWinStartup(bool b)
|
||||
settings.remove("qBittorrent");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#endif // Q_OS_WIN
|
||||
|
||||
// Downloads
|
||||
QString Preferences::lastLocationPath() const
|
||||
@@ -505,7 +506,7 @@ void Preferences::setWebUiAuthSubnetWhitelistEnabled(bool enabled)
|
||||
QList<Utils::Net::Subnet> Preferences::getWebUiAuthSubnetWhitelist() const
|
||||
{
|
||||
QList<Utils::Net::Subnet> subnets;
|
||||
foreach (const QString &rawSubnet, value("Preferences/WebUI/AuthSubnetWhitelist").toStringList()) {
|
||||
for (const QString &rawSubnet : asConst(value("Preferences/WebUI/AuthSubnetWhitelist").toStringList())) {
|
||||
bool ok = false;
|
||||
const Utils::Net::Subnet subnet = Utils::Net::parseSubnet(rawSubnet.trimmed(), &ok);
|
||||
if (ok)
|
||||
@@ -626,6 +627,16 @@ void Preferences::setWebUiCSRFProtectionEnabled(bool enabled)
|
||||
setValue("Preferences/WebUI/CSRFProtection", enabled);
|
||||
}
|
||||
|
||||
bool Preferences::isWebUIHostHeaderValidationEnabled() const
|
||||
{
|
||||
return value("Preferences/WebUI/HostHeaderValidation", true).toBool();
|
||||
}
|
||||
|
||||
void Preferences::setWebUIHostHeaderValidationEnabled(const bool enabled)
|
||||
{
|
||||
setValue("Preferences/WebUI/HostHeaderValidation", enabled);
|
||||
}
|
||||
|
||||
bool Preferences::isWebUiHttpsEnabled() const
|
||||
{
|
||||
return value("Preferences/WebUI/HTTPS/Enabled", false).toBool();
|
||||
@@ -957,7 +968,7 @@ void Preferences::setMagnetLinkAssoc(bool set)
|
||||
|
||||
SHChangeNotify(SHCNE_ASSOCCHANGED, SHCNF_IDLIST, 0, 0);
|
||||
}
|
||||
#endif
|
||||
#endif // Q_OS_WIN
|
||||
|
||||
#ifdef Q_OS_MAC
|
||||
namespace
|
||||
@@ -1013,7 +1024,7 @@ void Preferences::setMagnetLinkAssoc()
|
||||
CFStringRef myBundleId = CFBundleGetIdentifier(CFBundleGetMainBundle());
|
||||
LSSetDefaultHandlerForURLScheme(magnetUrlScheme, myBundleId);
|
||||
}
|
||||
#endif
|
||||
#endif // Q_OS_MAC
|
||||
|
||||
int Preferences::getTrackerPort() const
|
||||
{
|
||||
@@ -1416,8 +1427,8 @@ void Preferences::setToolbarTextPosition(const int position)
|
||||
QList<QNetworkCookie> Preferences::getNetworkCookies() const
|
||||
{
|
||||
QList<QNetworkCookie> cookies;
|
||||
QStringList rawCookies = value("Network/Cookies").toStringList();
|
||||
foreach (const QString &rawCookie, rawCookies)
|
||||
const QStringList rawCookies = value("Network/Cookies").toStringList();
|
||||
for (const QString &rawCookie : rawCookies)
|
||||
cookies << QNetworkCookie::parseCookies(rawCookie.toUtf8());
|
||||
|
||||
return cookies;
|
||||
@@ -1426,7 +1437,7 @@ QList<QNetworkCookie> Preferences::getNetworkCookies() const
|
||||
void Preferences::setNetworkCookies(const QList<QNetworkCookie> &cookies)
|
||||
{
|
||||
QStringList rawCookies;
|
||||
foreach (const QNetworkCookie &cookie, cookies)
|
||||
for (const QNetworkCookie &cookie : cookies)
|
||||
rawCookies << cookie.toRawForm();
|
||||
|
||||
setValue("Network/Cookies", rawCookies);
|
||||
@@ -1467,10 +1478,10 @@ void Preferences::upgrade()
|
||||
{
|
||||
SettingsStorage *settingsStorage = SettingsStorage::instance();
|
||||
|
||||
QStringList labels = value("TransferListFilters/customLabels").toStringList();
|
||||
const QStringList labels = value("TransferListFilters/customLabels").toStringList();
|
||||
if (!labels.isEmpty()) {
|
||||
QVariantMap categories = value("BitTorrent/Session/Categories").toMap();
|
||||
foreach (const QString &label, labels) {
|
||||
for (const QString &label : labels) {
|
||||
if (!categories.contains(label))
|
||||
categories[label] = "";
|
||||
}
|
||||
|
||||
@@ -201,6 +201,8 @@ public:
|
||||
void setWebUiClickjackingProtectionEnabled(bool enabled);
|
||||
bool isWebUiCSRFProtectionEnabled() const;
|
||||
void setWebUiCSRFProtectionEnabled(bool enabled);
|
||||
bool isWebUIHostHeaderValidationEnabled() const;
|
||||
void setWebUIHostHeaderValidationEnabled(bool enabled);
|
||||
|
||||
// HTTPS
|
||||
bool isWebUiHttpsEnabled() const;
|
||||
@@ -297,7 +299,7 @@ public:
|
||||
void setCloseToTrayNotified(bool b);
|
||||
TrayIcon::Style trayIconStyle() const;
|
||||
void setTrayIconStyle(TrayIcon::Style style);
|
||||
#endif
|
||||
#endif // Q_OS_MAC
|
||||
|
||||
// Stuff that don't appear in the Options GUI but are saved
|
||||
// in the same file.
|
||||
|
||||
@@ -435,13 +435,13 @@ namespace
|
||||
if (leapSecond)
|
||||
second = 59; // apparently a leap second - validate below, once time zone is known
|
||||
int month = 0;
|
||||
for ( ; (month < 12) && (parts[nmonth] != shortMonth[month]); ++month);
|
||||
for ( ; (month < 12) && (parts[nmonth] != shortMonth[month]); ++month);
|
||||
int dayOfWeek = -1;
|
||||
if (!parts[nwday].isEmpty()) {
|
||||
// Look up the weekday name
|
||||
while (++dayOfWeek < 7 && (shortDay[dayOfWeek] != parts[nwday]));
|
||||
while ((++dayOfWeek < 7) && (shortDay[dayOfWeek] != parts[nwday]));
|
||||
if (dayOfWeek >= 7)
|
||||
for (dayOfWeek = 0; dayOfWeek < 7 && (longDay[dayOfWeek] != parts[nwday]); ++dayOfWeek);
|
||||
for (dayOfWeek = 0; (dayOfWeek < 7) && (longDay[dayOfWeek] != parts[nwday]); ++dayOfWeek);
|
||||
}
|
||||
|
||||
// if (month >= 12 || dayOfWeek >= 7
|
||||
@@ -450,7 +450,7 @@ namespace
|
||||
int i = parts[nyear].size();
|
||||
if (i < 4) {
|
||||
// It's an obsolete year specification with less than 4 digits
|
||||
year += (i == 2 && year < 50) ? 2000 : 1900;
|
||||
year += ((i == 2) && (year < 50)) ? 2000 : 1900;
|
||||
}
|
||||
|
||||
// Parse the UTC offset part
|
||||
@@ -473,17 +473,17 @@ namespace
|
||||
else {
|
||||
// Check for an obsolete time zone name
|
||||
QByteArray zone = parts[10].toLatin1();
|
||||
if (zone.length() == 1 && isalpha(zone[0]) && toupper(zone[0]) != 'J') {
|
||||
if ((zone.length() == 1) && (isalpha(zone[0])) && (toupper(zone[0]) != 'J')) {
|
||||
negOffset = true; // military zone: RFC 2822 treats as '-0000'
|
||||
}
|
||||
else if (zone != "UT" && zone != "GMT") { // treated as '+0000'
|
||||
else if ((zone != "UT") && (zone != "GMT")) { // treated as '+0000'
|
||||
offset = (zone == "EDT")
|
||||
? -4 * 3600
|
||||
: ((zone == "EST") || (zone == "CDT"))
|
||||
? -5 * 3600
|
||||
: ((zone == "CST") || (zone == "MDT"))
|
||||
? -6 * 3600
|
||||
: (zone == "MST" || zone == "PDT")
|
||||
: ((zone == "MST") || (zone == "PDT"))
|
||||
? -7 * 3600
|
||||
: (zone == "PST")
|
||||
? -8 * 3600
|
||||
@@ -502,12 +502,12 @@ namespace
|
||||
}
|
||||
}
|
||||
|
||||
QDate qdate(year, month + 1, day); // convert date, and check for out-of-range
|
||||
if (!qdate.isValid())
|
||||
QDate qDate(year, month + 1, day); // convert date, and check for out-of-range
|
||||
if (!qDate.isValid())
|
||||
return QDateTime::currentDateTime();
|
||||
|
||||
QTime qTime(hour, minute, second);
|
||||
QDateTime result(qdate, qTime, Qt::UTC);
|
||||
QDateTime result(qDate, qTime, Qt::UTC);
|
||||
if (offset)
|
||||
result = result.addSecs(-offset);
|
||||
if (!result.isValid())
|
||||
|
||||
@@ -241,7 +241,7 @@ void AutoDownloader::importRules(const QByteArray &data, AutoDownloader::RulesFi
|
||||
QByteArray AutoDownloader::exportRulesToJSONFormat() const
|
||||
{
|
||||
QJsonObject jsonObj;
|
||||
for (const auto &rule : copyAsConst(rules()))
|
||||
for (const auto &rule : asConst(rules()))
|
||||
jsonObj.insert(rule.name(), rule.toJsonObject());
|
||||
|
||||
return QJsonDocument(jsonObj).toJson();
|
||||
@@ -249,14 +249,14 @@ QByteArray AutoDownloader::exportRulesToJSONFormat() const
|
||||
|
||||
void AutoDownloader::importRulesFromJSONFormat(const QByteArray &data)
|
||||
{
|
||||
for (const auto &rule : copyAsConst(rulesFromJSON(data)))
|
||||
for (const auto &rule : asConst(rulesFromJSON(data)))
|
||||
insertRule(rule);
|
||||
}
|
||||
|
||||
QByteArray AutoDownloader::exportRulesToLegacyFormat() const
|
||||
{
|
||||
QVariantHash dict;
|
||||
for (const auto &rule : copyAsConst(rules()))
|
||||
for (const auto &rule : asConst(rules()))
|
||||
dict[rule.name()] = rule.toLegacyDict();
|
||||
|
||||
QByteArray data;
|
||||
@@ -276,7 +276,7 @@ void AutoDownloader::importRulesFromLegacyFormat(const QByteArray &data)
|
||||
if (in.status() != QDataStream::Ok)
|
||||
throw ParsingError(tr("Invalid data format"));
|
||||
|
||||
for (const QVariant &val : qAsConst(dict))
|
||||
for (const QVariant &val : asConst(dict))
|
||||
insertRule(AutoDownloadRule::fromLegacyDict(val.toHash()));
|
||||
}
|
||||
|
||||
@@ -373,7 +373,7 @@ void AutoDownloader::addJobForArticle(Article *article)
|
||||
|
||||
void AutoDownloader::processJob(const QSharedPointer<ProcessingJob> &job)
|
||||
{
|
||||
for (AutoDownloadRule &rule: m_rules) {
|
||||
for (AutoDownloadRule &rule : m_rules) {
|
||||
if (!rule.isEnabled()) continue;
|
||||
if (!rule.feedURLs().contains(job->feedURL)) continue;
|
||||
if (!rule.accepts(job->articleData)) continue;
|
||||
@@ -435,8 +435,8 @@ void AutoDownloader::loadRules(const QByteArray &data)
|
||||
void AutoDownloader::loadRulesLegacy()
|
||||
{
|
||||
SettingsPtr settings = Profile::instance().applicationSettings(QStringLiteral("qBittorrent-rss"));
|
||||
QVariantHash rules = settings->value(QStringLiteral("download_rules")).toHash();
|
||||
foreach (const QVariant &ruleVar, rules) {
|
||||
const QVariantHash rules = settings->value(QStringLiteral("download_rules")).toHash();
|
||||
for (const QVariant &ruleVar : rules) {
|
||||
auto rule = AutoDownloadRule::fromLegacyDict(ruleVar.toHash());
|
||||
if (!rule.name().isEmpty())
|
||||
insertRule(rule);
|
||||
@@ -451,7 +451,7 @@ void AutoDownloader::store()
|
||||
m_savingTimer.stop();
|
||||
|
||||
QJsonObject jsonObj;
|
||||
foreach (auto rule, m_rules)
|
||||
for (const auto &rule : asConst(m_rules))
|
||||
jsonObj.insert(rule.name(), rule.toJsonObject());
|
||||
|
||||
m_fileStorage->store(RulesFileName, QJsonDocument(jsonObj).toJson());
|
||||
@@ -473,7 +473,7 @@ void AutoDownloader::resetProcessingQueue()
|
||||
m_processingQueue.clear();
|
||||
if (!m_processingEnabled) return;
|
||||
|
||||
foreach (Article *article, Session::instance()->rootFolder()->articles()) {
|
||||
for (Article *article : asConst(Session::instance()->rootFolder()->articles())) {
|
||||
if (!article->isRead() && !article->torrentUrl().isEmpty())
|
||||
addJobForArticle(article);
|
||||
}
|
||||
|
||||
@@ -126,7 +126,7 @@ namespace RSS
|
||||
bool smartFilter = false;
|
||||
QStringList previouslyMatchedEpisodes;
|
||||
|
||||
mutable QString lastComputedEpisode;
|
||||
mutable QStringList lastComputedEpisodes;
|
||||
mutable QHash<QString, QRegularExpression> cachedRegexes;
|
||||
|
||||
bool operator==(const AutoDownloadRuleData &other) const
|
||||
@@ -237,7 +237,7 @@ bool AutoDownloadRule::matchesMustContainExpression(const QString &articleTitle)
|
||||
|
||||
// Each expression is either a regex, or a set of wildcards separated by whitespace.
|
||||
// Accept if any complete expression matches.
|
||||
for (const QString &expression : qAsConst(m_dataPtr->mustContain)) {
|
||||
for (const QString &expression : asConst(m_dataPtr->mustContain)) {
|
||||
// A regex of the form "expr|" will always match, so do the same for wildcards
|
||||
if (matchesExpression(articleTitle, expression))
|
||||
return true;
|
||||
@@ -246,14 +246,14 @@ bool AutoDownloadRule::matchesMustContainExpression(const QString &articleTitle)
|
||||
return false;
|
||||
}
|
||||
|
||||
bool AutoDownloadRule::matchesMustNotContainExpression(const QString& articleTitle) const
|
||||
bool AutoDownloadRule::matchesMustNotContainExpression(const QString &articleTitle) const
|
||||
{
|
||||
if (m_dataPtr->mustNotContain.empty())
|
||||
return true;
|
||||
|
||||
// Each expression is either a regex, or a set of wildcards separated by whitespace.
|
||||
// Reject if any complete expression matches.
|
||||
for (const QString &expression : qAsConst(m_dataPtr->mustNotContain)) {
|
||||
for (const QString &expression : asConst(m_dataPtr->mustNotContain)) {
|
||||
// A regex of the form "expr|" will always match, so do the same for wildcards
|
||||
if (matchesExpression(articleTitle, expression))
|
||||
return false;
|
||||
@@ -262,10 +262,10 @@ bool AutoDownloadRule::matchesMustNotContainExpression(const QString& articleTit
|
||||
return true;
|
||||
}
|
||||
|
||||
bool AutoDownloadRule::matchesEpisodeFilterExpression(const QString& articleTitle) const
|
||||
bool AutoDownloadRule::matchesEpisodeFilterExpression(const QString &articleTitle) const
|
||||
{
|
||||
// Reset the lastComputedEpisode, we don't want to leak it between matches
|
||||
m_dataPtr->lastComputedEpisode.clear();
|
||||
m_dataPtr->lastComputedEpisodes.clear();
|
||||
|
||||
if (m_dataPtr->episodeFilter.isEmpty())
|
||||
return true;
|
||||
@@ -332,7 +332,7 @@ bool AutoDownloadRule::matchesEpisodeFilterExpression(const QString& articleTitl
|
||||
return false;
|
||||
}
|
||||
|
||||
bool AutoDownloadRule::matchesSmartEpisodeFilter(const QString& articleTitle) const
|
||||
bool AutoDownloadRule::matchesSmartEpisodeFilter(const QString &articleTitle) const
|
||||
{
|
||||
if (!useSmartFilter())
|
||||
return true;
|
||||
@@ -343,11 +343,35 @@ bool AutoDownloadRule::matchesSmartEpisodeFilter(const QString& articleTitle) co
|
||||
|
||||
// See if this episode has been downloaded before
|
||||
const bool previouslyMatched = m_dataPtr->previouslyMatchedEpisodes.contains(episodeStr);
|
||||
const bool isRepack = articleTitle.contains("REPACK", Qt::CaseInsensitive) || articleTitle.contains("PROPER", Qt::CaseInsensitive);
|
||||
if (previouslyMatched && (!isRepack || !AutoDownloader::instance()->downloadRepacks()))
|
||||
return false;
|
||||
if (previouslyMatched) {
|
||||
if (!AutoDownloader::instance()->downloadRepacks())
|
||||
return false;
|
||||
|
||||
m_dataPtr->lastComputedEpisode = episodeStr;
|
||||
// Now see if we've downloaded this particular repack/proper combination
|
||||
const bool isRepack = articleTitle.contains("REPACK", Qt::CaseInsensitive);
|
||||
const bool isProper = articleTitle.contains("PROPER", Qt::CaseInsensitive);
|
||||
|
||||
if (!isRepack && !isProper)
|
||||
return false;
|
||||
|
||||
const QString fullEpisodeStr = QString("%1%2%3").arg(episodeStr,
|
||||
isRepack ? "-REPACK" : "",
|
||||
isProper ? "-PROPER" : "");
|
||||
const bool previouslyMatchedFull = m_dataPtr->previouslyMatchedEpisodes.contains(fullEpisodeStr);
|
||||
if (previouslyMatchedFull)
|
||||
return false;
|
||||
|
||||
m_dataPtr->lastComputedEpisodes.append(fullEpisodeStr);
|
||||
|
||||
// If this is a REPACK and PROPER download, add the individual entries to the list
|
||||
// so we don't download those
|
||||
if (isRepack && isProper) {
|
||||
m_dataPtr->lastComputedEpisodes.append(QString("%1-REPACK").arg(episodeStr));
|
||||
m_dataPtr->lastComputedEpisodes.append(QString("%1-PROPER").arg(episodeStr));
|
||||
}
|
||||
}
|
||||
|
||||
m_dataPtr->lastComputedEpisodes.append(episodeStr);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -379,10 +403,10 @@ bool AutoDownloadRule::accepts(const QVariantHash &articleData)
|
||||
|
||||
setLastMatch(articleData[Article::KeyDate].toDateTime());
|
||||
|
||||
if (!m_dataPtr->lastComputedEpisode.isEmpty()) {
|
||||
// TODO: probably need to add a marker for PROPER/REPACK to avoid duplicate downloads
|
||||
m_dataPtr->previouslyMatchedEpisodes.append(m_dataPtr->lastComputedEpisode);
|
||||
m_dataPtr->lastComputedEpisode.clear();
|
||||
// If there's a matched episode string, add that to the previously matched list
|
||||
if (!m_dataPtr->lastComputedEpisodes.isEmpty()) {
|
||||
m_dataPtr->previouslyMatchedEpisodes.append(m_dataPtr->lastComputedEpisodes);
|
||||
m_dataPtr->lastComputedEpisodes.clear();
|
||||
}
|
||||
|
||||
return true;
|
||||
@@ -442,7 +466,7 @@ AutoDownloadRule AutoDownloadRule::fromJsonObject(const QJsonObject &jsonObj, co
|
||||
QStringList feedURLs;
|
||||
if (feedsVal.isString())
|
||||
feedURLs << feedsVal.toString();
|
||||
else foreach (const QJsonValue &urlVal, feedsVal.toArray())
|
||||
else for (const QJsonValue &urlVal : asConst(feedsVal.toArray()))
|
||||
feedURLs << urlVal.toString();
|
||||
rule.setFeedURLs(feedURLs);
|
||||
|
||||
@@ -452,7 +476,7 @@ AutoDownloadRule AutoDownloadRule::fromJsonObject(const QJsonObject &jsonObj, co
|
||||
previouslyMatched << previouslyMatchedVal.toString();
|
||||
}
|
||||
else {
|
||||
foreach (const QJsonValue &val, previouslyMatchedVal.toArray())
|
||||
for (const QJsonValue &val : asConst(previouslyMatchedVal.toArray()))
|
||||
previouslyMatched << val.toString();
|
||||
}
|
||||
rule.setPreviouslyMatchedEpisodes(previouslyMatched);
|
||||
|
||||
@@ -109,7 +109,7 @@ QList<Article *> Feed::articles() const
|
||||
void Feed::markAsRead()
|
||||
{
|
||||
auto oldUnreadCount = m_unreadCount;
|
||||
foreach (Article *article, m_articles) {
|
||||
for (Article *article : asConst(m_articles)) {
|
||||
if (!article->isRead()) {
|
||||
article->disconnect(this);
|
||||
article->markAsRead();
|
||||
@@ -282,9 +282,9 @@ void Feed::loadArticles(const QByteArray &data)
|
||||
return;
|
||||
}
|
||||
|
||||
QJsonArray jsonArr = jsonDoc.array();
|
||||
const QJsonArray jsonArr = jsonDoc.array();
|
||||
int i = -1;
|
||||
foreach (const QJsonValue &jsonVal, jsonArr) {
|
||||
for (const QJsonValue &jsonVal : jsonArr) {
|
||||
++i;
|
||||
if (!jsonVal.isObject()) {
|
||||
LogMsg(tr("Couldn't load RSS article '%1#%2'. Invalid data format.").arg(m_url).arg(i)
|
||||
@@ -304,9 +304,9 @@ void Feed::loadArticles(const QByteArray &data)
|
||||
void Feed::loadArticlesLegacy()
|
||||
{
|
||||
SettingsPtr qBTRSSFeeds = Profile::instance().applicationSettings(QStringLiteral("qBittorrent-rss-feeds"));
|
||||
QVariantHash allOldItems = qBTRSSFeeds->value("old_items").toHash();
|
||||
const QVariantHash allOldItems = qBTRSSFeeds->value("old_items").toHash();
|
||||
|
||||
foreach (const QVariant &var, allOldItems.value(m_url).toList()) {
|
||||
for (const QVariant &var : asConst(allOldItems.value(m_url).toList())) {
|
||||
auto hash = var.toHash();
|
||||
// update legacy keys
|
||||
hash[Article::KeyLink] = hash.take(QLatin1String("news_link"));
|
||||
@@ -329,7 +329,7 @@ void Feed::store()
|
||||
m_savingTimer.stop();
|
||||
|
||||
QJsonArray jsonArr;
|
||||
foreach (Article *article, m_articles)
|
||||
for (Article *article :asConst(m_articles))
|
||||
jsonArr << article->toJsonObject();
|
||||
|
||||
m_session->dataFileStorage()->store(m_dataFileName, QJsonDocument(jsonArr).toJson());
|
||||
@@ -474,7 +474,7 @@ int Feed::updateArticles(const QList<QVariantHash> &loadedArticles)
|
||||
return (a1.first > a2.first);
|
||||
});
|
||||
|
||||
if (sortData.size() > m_session->maxArticlesPerFeed())
|
||||
if (sortData.size() > static_cast<uint>(m_session->maxArticlesPerFeed()))
|
||||
sortData.resize(m_session->maxArticlesPerFeed());
|
||||
|
||||
int newArticlesCount = 0;
|
||||
@@ -507,7 +507,7 @@ QJsonValue Feed::toJsonValue(bool withData) const
|
||||
jsonObj.insert(KEY_HASERROR, hasError());
|
||||
|
||||
QJsonArray jsonArr;
|
||||
for (Article *article : qAsConst(m_articles))
|
||||
for (Article *article : asConst(m_articles))
|
||||
jsonArr << article->toJsonObject();
|
||||
jsonObj.insert(KEY_ARTICLES, jsonArr);
|
||||
}
|
||||
|
||||
@@ -47,7 +47,7 @@ Folder::~Folder()
|
||||
{
|
||||
emit aboutToBeDestroyed(this);
|
||||
|
||||
foreach (auto item, items())
|
||||
for (auto item : asConst(items()))
|
||||
delete item;
|
||||
}
|
||||
|
||||
@@ -55,7 +55,7 @@ QList<Article *> Folder::articles() const
|
||||
{
|
||||
QList<Article *> news;
|
||||
|
||||
foreach (Item *item, items()) {
|
||||
for (Item *item : asConst(items())) {
|
||||
int n = news.size();
|
||||
news << item->articles();
|
||||
std::inplace_merge(news.begin(), news.begin() + n, news.end()
|
||||
@@ -70,20 +70,20 @@ QList<Article *> Folder::articles() const
|
||||
int Folder::unreadCount() const
|
||||
{
|
||||
int count = 0;
|
||||
foreach (Item *item, items())
|
||||
for (Item *item : asConst(items()))
|
||||
count += item->unreadCount();
|
||||
return count;
|
||||
}
|
||||
|
||||
void Folder::markAsRead()
|
||||
{
|
||||
foreach (Item *item, items())
|
||||
for (Item *item : asConst(items()))
|
||||
item->markAsRead();
|
||||
}
|
||||
|
||||
void Folder::refresh()
|
||||
{
|
||||
foreach (Item *item, items())
|
||||
for (Item *item : asConst(items()))
|
||||
item->refresh();
|
||||
}
|
||||
|
||||
@@ -95,7 +95,7 @@ QList<Item *> Folder::items() const
|
||||
QJsonValue Folder::toJsonValue(bool withData) const
|
||||
{
|
||||
QJsonObject jsonObj;
|
||||
foreach (Item *item, items())
|
||||
for (Item *item : asConst(items()))
|
||||
jsonObj.insert(item->name(), item->toJsonValue(withData));
|
||||
|
||||
return jsonObj;
|
||||
@@ -108,7 +108,7 @@ void Folder::handleItemUnreadCountChanged()
|
||||
|
||||
void Folder::cleanup()
|
||||
{
|
||||
foreach (Item *item, items())
|
||||
for (Item *item : asConst(items()))
|
||||
item->cleanup();
|
||||
}
|
||||
|
||||
@@ -123,7 +123,7 @@ void Folder::addItem(Item *item)
|
||||
connect(item, &Item::articleAboutToBeRemoved, this, &Item::articleAboutToBeRemoved);
|
||||
connect(item, &Item::unreadCountChanged, this, &Folder::handleItemUnreadCountChanged);
|
||||
|
||||
for (auto article: copyAsConst(item->articles()))
|
||||
for (auto article : asConst(item->articles()))
|
||||
emit newArticle(article);
|
||||
|
||||
if (item->unreadCount() > 0)
|
||||
@@ -134,7 +134,7 @@ void Folder::removeItem(Item *item)
|
||||
{
|
||||
Q_ASSERT(m_items.contains(item));
|
||||
|
||||
for (auto article: copyAsConst(item->articles()))
|
||||
for (auto article : asConst(item->articles()))
|
||||
emit articleAboutToBeRemoved(article);
|
||||
|
||||
item->disconnect(this);
|
||||
|
||||
@@ -41,6 +41,7 @@
|
||||
#include <QVariantHash>
|
||||
|
||||
#include "../asyncfilestorage.h"
|
||||
#include "../global.h"
|
||||
#include "../logger.h"
|
||||
#include "../profile.h"
|
||||
#include "../settingsstorage.h"
|
||||
@@ -283,7 +284,7 @@ void Session::load()
|
||||
void Session::loadFolder(const QJsonObject &jsonObj, Folder *folder)
|
||||
{
|
||||
bool updated = false;
|
||||
foreach (const QString &key, jsonObj.keys()) {
|
||||
for (const QString &key : asConst(jsonObj.keys())) {
|
||||
const QJsonValue val {jsonObj[key]};
|
||||
if (val.isString()) {
|
||||
// previous format (reduced form) doesn't contain UID
|
||||
@@ -355,7 +356,7 @@ void Session::loadLegacy()
|
||||
const QString parentFolderPath = Item::parentPath(legacyPath);
|
||||
const QString feedUrl = Item::relativeName(legacyPath);
|
||||
|
||||
foreach (const QString &folderPath, Item::expandPath(parentFolderPath))
|
||||
for (const QString &folderPath : asConst(Item::expandPath(parentFolderPath)))
|
||||
addFolder(folderPath);
|
||||
|
||||
const QString feedPath = feedAliases[i].isEmpty()
|
||||
|
||||
@@ -35,6 +35,7 @@
|
||||
|
||||
#include "bittorrent/session.h"
|
||||
#include "filesystemwatcher.h"
|
||||
#include "global.h"
|
||||
#include "preferences.h"
|
||||
#include "utils/fs.h"
|
||||
|
||||
@@ -254,7 +255,7 @@ void ScanFoldersModel::addToFSWatcher(const QStringList &watchPaths)
|
||||
if (!m_fsWatcher)
|
||||
return; // addPath() wasn't called before this
|
||||
|
||||
foreach (const QString &path, watchPaths) {
|
||||
for (const QString &path : watchPaths) {
|
||||
QDir watchDir(path);
|
||||
const QString canonicalWatchPath = watchDir.canonicalPath();
|
||||
m_fsWatcher->addPath(canonicalWatchPath);
|
||||
@@ -282,7 +283,7 @@ bool ScanFoldersModel::removePath(const QString &path, bool removeFromFSWatcher)
|
||||
|
||||
void ScanFoldersModel::removeFromFSWatcher(const QStringList &watchPaths)
|
||||
{
|
||||
foreach (const QString &path, watchPaths)
|
||||
for (const QString &path : watchPaths)
|
||||
m_fsWatcher->removePath(path);
|
||||
}
|
||||
|
||||
@@ -326,7 +327,7 @@ void ScanFoldersModel::makePersistent()
|
||||
{
|
||||
QVariantHash dirs;
|
||||
|
||||
foreach (const PathData *pathData, m_pathList) {
|
||||
for (const PathData *pathData : asConst(m_pathList)) {
|
||||
if (pathData->downloadType == CUSTOM_LOCATION)
|
||||
dirs.insert(Utils::Fs::fromNativePath(pathData->watchPath), Utils::Fs::fromNativePath(pathData->downloadPath));
|
||||
else
|
||||
@@ -350,7 +351,7 @@ void ScanFoldersModel::configure()
|
||||
|
||||
void ScanFoldersModel::addTorrentsToSession(const QStringList &pathList)
|
||||
{
|
||||
foreach (const QString &file, pathList) {
|
||||
for (const QString &file : pathList) {
|
||||
qDebug("File %s added", qUtf8Printable(file));
|
||||
|
||||
BitTorrent::AddTorrentParams params;
|
||||
|
||||
@@ -32,6 +32,7 @@
|
||||
#include <QProcess>
|
||||
#include <QTimer>
|
||||
|
||||
#include "../global.h"
|
||||
#include "../utils/foreignapps.h"
|
||||
#include "../utils/fs.h"
|
||||
#include "searchpluginmanager.h"
|
||||
@@ -138,7 +139,7 @@ void SearchHandler::readSearchOutput()
|
||||
m_searchResultLineTruncated = lines.takeLast().trimmed();
|
||||
|
||||
QList<SearchResult> searchResultList;
|
||||
foreach (const QByteArray &line, lines) {
|
||||
for (const QByteArray &line : asConst(lines)) {
|
||||
SearchResult searchResult;
|
||||
if (parseSearchResult(QString::fromUtf8(line), searchResult))
|
||||
searchResultList << searchResult;
|
||||
|
||||
@@ -65,7 +65,7 @@ namespace
|
||||
while (iter.hasNext())
|
||||
dirs += iter.next();
|
||||
|
||||
for (const QString &dir : qAsConst(dirs)) {
|
||||
for (const QString &dir : asConst(dirs)) {
|
||||
// python 3: remove "__pycache__" folders
|
||||
if (dir.endsWith("/__pycache__")) {
|
||||
Utils::Fs::removeDirRecursive(dir);
|
||||
@@ -101,9 +101,17 @@ SearchPluginManager::~SearchPluginManager()
|
||||
|
||||
SearchPluginManager *SearchPluginManager::instance()
|
||||
{
|
||||
if (!m_instance)
|
||||
m_instance = new SearchPluginManager;
|
||||
return m_instance;
|
||||
}
|
||||
|
||||
void SearchPluginManager::freeInstance()
|
||||
{
|
||||
if (m_instance)
|
||||
delete m_instance;
|
||||
}
|
||||
|
||||
QStringList SearchPluginManager::allPlugins() const
|
||||
{
|
||||
return m_plugins.keys();
|
||||
@@ -112,7 +120,7 @@ QStringList SearchPluginManager::allPlugins() const
|
||||
QStringList SearchPluginManager::enabledPlugins() const
|
||||
{
|
||||
QStringList plugins;
|
||||
for (const PluginInfo *plugin : qAsConst(m_plugins)) {
|
||||
for (const PluginInfo *plugin : asConst(m_plugins)) {
|
||||
if (plugin->enabled)
|
||||
plugins << plugin->name;
|
||||
}
|
||||
@@ -123,9 +131,9 @@ QStringList SearchPluginManager::enabledPlugins() const
|
||||
QStringList SearchPluginManager::supportedCategories() const
|
||||
{
|
||||
QStringList result;
|
||||
for (const PluginInfo *plugin : qAsConst(m_plugins)) {
|
||||
for (const PluginInfo *plugin : asConst(m_plugins)) {
|
||||
if (plugin->enabled) {
|
||||
foreach (QString cat, plugin->supportedCategories) {
|
||||
for (const QString &cat : plugin->supportedCategories) {
|
||||
if (!result.contains(cat))
|
||||
result << cat;
|
||||
}
|
||||
@@ -146,7 +154,7 @@ QStringList SearchPluginManager::getPluginCategories(const QString &pluginName)
|
||||
plugins << pluginName.trimmed();
|
||||
|
||||
QSet<QString> categories;
|
||||
for (const QString &name : qAsConst(plugins)) {
|
||||
for (const QString &name : asConst(plugins)) {
|
||||
const PluginInfo *plugin = pluginInfo(name);
|
||||
if (!plugin) continue; // plugin wasn't found
|
||||
for (const QString &category : plugin->supportedCategories)
|
||||
@@ -269,9 +277,8 @@ bool SearchPluginManager::uninstallPlugin(const QString &name)
|
||||
QDir pluginsFolder(pluginsLocation());
|
||||
QStringList filters;
|
||||
filters << name + ".*";
|
||||
QStringList files = pluginsFolder.entryList(filters, QDir::Files, QDir::Unsorted);
|
||||
QString file;
|
||||
foreach (file, files)
|
||||
const QStringList files = pluginsFolder.entryList(filters, QDir::Files, QDir::Unsorted);
|
||||
for (const QString &file : files)
|
||||
Utils::Fs::forceRemove(pluginsFolder.absoluteFilePath(file));
|
||||
// Remove it from supported engines
|
||||
delete m_plugins.take(name);
|
||||
|
||||
@@ -62,6 +62,7 @@ public:
|
||||
~SearchPluginManager() override;
|
||||
|
||||
static SearchPluginManager *instance();
|
||||
static void freeInstance();
|
||||
|
||||
QStringList allPlugins() const;
|
||||
QStringList enabledPlugins() const;
|
||||
|
||||
@@ -33,6 +33,7 @@
|
||||
#include <QFile>
|
||||
#include <QHash>
|
||||
|
||||
#include "global.h"
|
||||
#include "logger.h"
|
||||
#include "profile.h"
|
||||
#include "utils/fs.h"
|
||||
@@ -286,7 +287,7 @@ QString TransactionalSettings::deserialize(const QString &name, QVariantHash &da
|
||||
// Copy everything into memory. This means even keys inserted in the file manually
|
||||
// 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.
|
||||
foreach (const QString &key, settings->allKeys())
|
||||
for (const QString &key : asConst(settings->allKeys()))
|
||||
data.insert(key, settings->value(key));
|
||||
|
||||
return settings->fileName();
|
||||
|
||||
@@ -229,7 +229,7 @@ namespace
|
||||
|
||||
return QString();
|
||||
}
|
||||
#endif
|
||||
#endif // Q_OS_WIN
|
||||
}
|
||||
|
||||
bool Utils::ForeignApps::PythonInfo::isValid() const
|
||||
|
||||
@@ -133,7 +133,7 @@ bool Utils::Fs::smartRemoveEmptyFolderTree(const QString &path)
|
||||
std::sort(dirList.begin(), dirList.end()
|
||||
, [](const QString &l, const QString &r) { return l.count('/') > r.count('/'); });
|
||||
|
||||
for (const QString &p : qAsConst(dirList)) {
|
||||
for (const QString &p : asConst(dirList)) {
|
||||
// remove unwanted files
|
||||
for (const QString &f : deleteFilesList) {
|
||||
forceRemove(p + f);
|
||||
@@ -141,7 +141,7 @@ bool Utils::Fs::smartRemoveEmptyFolderTree(const QString &path)
|
||||
|
||||
// remove temp files on linux (file ends with '~'), e.g. `filename~`
|
||||
QDir dir(p);
|
||||
QStringList tmpFileList = dir.entryList(QDir::Files);
|
||||
const QStringList tmpFileList = dir.entryList(QDir::Files);
|
||||
for (const QString &f : tmpFileList) {
|
||||
if (f.endsWith('~'))
|
||||
forceRemove(p + f);
|
||||
@@ -329,7 +329,7 @@ bool Utils::Fs::isNetworkFileSystem(const QString &path)
|
||||
return ((strncmp(buf.f_fstypename, "cifs", sizeof(buf.f_fstypename)) == 0)
|
||||
|| (strncmp(buf.f_fstypename, "nfs", sizeof(buf.f_fstypename)) == 0)
|
||||
|| (strncmp(buf.f_fstypename, "smbfs", sizeof(buf.f_fstypename)) == 0));
|
||||
#else
|
||||
#else // Q_OS_WIN
|
||||
QString file = path;
|
||||
if (!file.endsWith('/'))
|
||||
file += '/';
|
||||
@@ -351,6 +351,6 @@ bool Utils::Fs::isNetworkFileSystem(const QString &path)
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
#endif // Q_OS_WIN
|
||||
}
|
||||
#endif
|
||||
#endif // Q_OS_HAIKU
|
||||
|
||||
@@ -66,7 +66,7 @@
|
||||
#if defined(Q_OS_UNIX) && !defined(Q_OS_MAC)
|
||||
#include "base/utils/version.h"
|
||||
#endif
|
||||
#endif
|
||||
#endif // DISABLE_GUI
|
||||
|
||||
#include "base/logger.h"
|
||||
#include "base/unicodestrings.h"
|
||||
@@ -391,7 +391,7 @@ QString Utils::Misc::getUserIDString()
|
||||
QStringList Utils::Misc::toStringList(const QList<bool> &l)
|
||||
{
|
||||
QStringList ret;
|
||||
foreach (const bool &b, l)
|
||||
for (const bool b : l)
|
||||
ret << (b ? "1" : "0");
|
||||
return ret;
|
||||
}
|
||||
@@ -399,7 +399,7 @@ QStringList Utils::Misc::toStringList(const QList<bool> &l)
|
||||
QList<int> Utils::Misc::intListfromStringList(const QStringList &l)
|
||||
{
|
||||
QList<int> ret;
|
||||
foreach (const QString &s, l)
|
||||
for (const QString &s : l)
|
||||
ret << s.toInt();
|
||||
return ret;
|
||||
}
|
||||
@@ -407,7 +407,7 @@ QList<int> Utils::Misc::intListfromStringList(const QStringList &l)
|
||||
QList<bool> Utils::Misc::boolListfromStringList(const QStringList &l)
|
||||
{
|
||||
QList<bool> ret;
|
||||
foreach (const QString &s, l)
|
||||
for (const QString &s : l)
|
||||
ret << (s == "1");
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -124,7 +124,7 @@ namespace Utils
|
||||
return reinterpret_cast<T>(
|
||||
::GetProcAddress(::LoadLibraryW(pathWchar.get()), funcName));
|
||||
}
|
||||
#endif
|
||||
#endif // Q_OS_WIN
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -60,7 +60,7 @@ namespace Utils
|
||||
{
|
||||
if (str.length() < 2) return str;
|
||||
|
||||
for (auto const quote : quotes) {
|
||||
for (const auto "e : quotes) {
|
||||
if (str.startsWith(quote) && str.endsWith(quote))
|
||||
return str.mid(1, str.length() - 2);
|
||||
}
|
||||
|
||||
@@ -36,6 +36,7 @@
|
||||
#include <QUrl>
|
||||
#include <QVector>
|
||||
|
||||
#include "base/bittorrent/filepriority.h"
|
||||
#include "base/bittorrent/magneturi.h"
|
||||
#include "base/bittorrent/session.h"
|
||||
#include "base/bittorrent/torrenthandle.h"
|
||||
@@ -143,7 +144,7 @@ AddNewTorrentDialog::AddNewTorrentDialog(const BitTorrent::AddTorrentParams &inP
|
||||
m_ui->categoryComboBox->addItem(defaultCategory);
|
||||
m_ui->categoryComboBox->addItem("");
|
||||
|
||||
foreach (const QString &category, categories)
|
||||
for (const QString &category : asConst(categories))
|
||||
if (category != defaultCategory && category != m_torrentParams.category)
|
||||
m_ui->categoryComboBox->addItem(category);
|
||||
|
||||
@@ -398,7 +399,7 @@ void AddNewTorrentDialog::saveSavePathHistory() const
|
||||
// Get current history
|
||||
QStringList history = settings()->loadValue(KEY_SAVEPATHHISTORY).toStringList();
|
||||
QVector<QDir> historyDirs;
|
||||
for (const QString &path : qAsConst(history))
|
||||
for (const QString &path : asConst(history))
|
||||
historyDirs << QDir {path};
|
||||
|
||||
const QDir selectedSavePath {m_ui->savePath->selectedPath()};
|
||||
@@ -622,18 +623,18 @@ void AddNewTorrentDialog::displayContentTreeMenu(const QPoint &)
|
||||
renameSelectedFile();
|
||||
}
|
||||
else {
|
||||
int prio = prio::NORMAL;
|
||||
BitTorrent::FilePriority prio = BitTorrent::FilePriority::Normal;
|
||||
if (act == m_ui->actionHigh)
|
||||
prio = prio::HIGH;
|
||||
prio = BitTorrent::FilePriority::High;
|
||||
else if (act == m_ui->actionMaximum)
|
||||
prio = prio::MAXIMUM;
|
||||
prio = BitTorrent::FilePriority::Maximum;
|
||||
else if (act == m_ui->actionNotDownloaded)
|
||||
prio = prio::IGNORED;
|
||||
prio = BitTorrent::FilePriority::Ignored;
|
||||
|
||||
qDebug("Setting files priority");
|
||||
foreach (const QModelIndex &index, selectedRows) {
|
||||
qDebug("Setting priority(%d) for file at row %d", prio, index.row());
|
||||
m_contentModel->setData(m_contentModel->index(index.row(), PRIORITY, index.parent()), prio);
|
||||
for (const QModelIndex &index : selectedRows) {
|
||||
qDebug("Setting priority(%d) for file at row %d", static_cast<int>(prio), index.row());
|
||||
m_contentModel->setData(m_contentModel->index(index.row(), PRIORITY, index.parent()), static_cast<int>(prio));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -36,6 +36,7 @@
|
||||
#include <QNetworkInterface>
|
||||
|
||||
#include "base/bittorrent/session.h"
|
||||
#include "base/global.h"
|
||||
#include "base/preferences.h"
|
||||
#include "base/unicodestrings.h"
|
||||
#include "app/application.h"
|
||||
@@ -83,6 +84,7 @@ enum AdvSettingsRows
|
||||
#if LIBTORRENT_VERSION_NUM >= 10100
|
||||
ASYNC_IO_THREADS,
|
||||
#endif
|
||||
CHECKING_MEM_USAGE,
|
||||
// cache
|
||||
DISK_CACHE,
|
||||
DISK_CACHE_TTL,
|
||||
@@ -152,6 +154,8 @@ void AdvancedSettings::saveAdvancedSettings()
|
||||
// Async IO threads
|
||||
session->setAsyncIOThreads(spinBoxAsyncIOThreads.value());
|
||||
#endif
|
||||
// Checking Memory Usage
|
||||
session->setCheckingMemUsage(spinBoxCheckingMemUsage.value());
|
||||
// Disk write cache
|
||||
session->setDiskCacheSize(spinBoxCache.value());
|
||||
session->setDiskCacheTTL(spinBoxCacheTTL.value());
|
||||
@@ -286,13 +290,13 @@ void AdvancedSettings::updateInterfaceAddressCombo()
|
||||
};
|
||||
|
||||
if (ifaceName.isEmpty()) {
|
||||
foreach (const QHostAddress &ip, QNetworkInterface::allAddresses())
|
||||
for (const QHostAddress &ip : asConst(QNetworkInterface::allAddresses()))
|
||||
populateCombo(ip.toString(), ip.protocol());
|
||||
}
|
||||
else {
|
||||
const QNetworkInterface iface = QNetworkInterface::interfaceFromName(ifaceName);
|
||||
const QList<QNetworkAddressEntry> addresses = iface.addressEntries();
|
||||
foreach (const QNetworkAddressEntry &entry, addresses) {
|
||||
for (const QNetworkAddressEntry &entry : addresses) {
|
||||
const QHostAddress ip = entry.ip();
|
||||
populateCombo(ip.toString(), ip.protocol());
|
||||
}
|
||||
@@ -325,6 +329,13 @@ void AdvancedSettings::loadAdvancedSettings()
|
||||
spinBoxAsyncIOThreads.setValue(session->asyncIOThreads());
|
||||
addRow(ASYNC_IO_THREADS, tr("Asynchronous I/O threads"), &spinBoxAsyncIOThreads);
|
||||
#endif
|
||||
|
||||
// Checking Memory Usage
|
||||
spinBoxCheckingMemUsage.setMinimum(1);
|
||||
spinBoxCheckingMemUsage.setValue(session->checkingMemUsage());
|
||||
spinBoxCheckingMemUsage.setSuffix(tr(" MiB"));
|
||||
addRow(CHECKING_MEM_USAGE, tr("Outstanding memory when checking torrents"), &spinBoxCheckingMemUsage);
|
||||
|
||||
// Disk write cache
|
||||
spinBoxCache.setMinimum(-1);
|
||||
// When build as 32bit binary, set the maximum at less than 2GB to prevent crashes.
|
||||
@@ -425,7 +436,7 @@ void AdvancedSettings::loadAdvancedSettings()
|
||||
const QString currentInterface = session->networkInterface();
|
||||
bool interfaceExists = currentInterface.isEmpty();
|
||||
int i = 1;
|
||||
foreach (const QNetworkInterface& iface, QNetworkInterface::allInterfaces()) {
|
||||
for (const QNetworkInterface &iface : asConst(QNetworkInterface::allInterfaces())) {
|
||||
// This line fixes a Qt bug => https://bugreports.qt.io/browse/QTBUG-52633
|
||||
// Tested in Qt 5.6.0. For more info see:
|
||||
// https://github.com/qbittorrent/qBittorrent/issues/5131
|
||||
|
||||
@@ -59,7 +59,7 @@ private:
|
||||
template <typename T> void addRow(int row, const QString &rowText, T *widget);
|
||||
|
||||
QLabel labelQbtLink, labelLibtorrentLink;
|
||||
QSpinBox spinBoxAsyncIOThreads, spinBoxCache, spinBoxSaveResumeDataInterval, spinBoxOutgoingPortsMin, spinBoxOutgoingPortsMax, spinBoxListRefresh, spinBoxMaxHalfOpen,
|
||||
QSpinBox spinBoxAsyncIOThreads, spinBoxCheckingMemUsage, spinBoxCache, spinBoxSaveResumeDataInterval, spinBoxOutgoingPortsMin, spinBoxOutgoingPortsMax, spinBoxListRefresh, spinBoxMaxHalfOpen,
|
||||
spinBoxTrackerPort, spinBoxCacheTTL, spinBoxSendBufferWatermark, spinBoxSendBufferLowWatermark,
|
||||
spinBoxSendBufferWatermarkFactor, spinBoxSavePathHistoryLength;
|
||||
QCheckBox checkBoxOsCache, checkBoxRecheckCompleted, checkBoxResolveCountries, checkBoxResolveHosts, checkBoxSuperSeeding,
|
||||
|
||||
@@ -107,8 +107,8 @@ void BanListOptionsDialog::on_buttonBanIP_clicked()
|
||||
|
||||
void BanListOptionsDialog::on_buttonDeleteIP_clicked()
|
||||
{
|
||||
QModelIndexList selection = m_ui->bannedIPList->selectionModel()->selectedIndexes();
|
||||
for (auto &i : selection)
|
||||
const QModelIndexList selection = m_ui->bannedIPList->selectionModel()->selectedIndexes();
|
||||
for (const auto &i : selection)
|
||||
m_sortFilter->removeRow(i.row());
|
||||
|
||||
m_modified = true;
|
||||
|
||||
@@ -33,6 +33,7 @@
|
||||
|
||||
#include "base/bittorrent/session.h"
|
||||
#include "base/bittorrent/torrenthandle.h"
|
||||
#include "base/global.h"
|
||||
#include "guiiconprovider.h"
|
||||
|
||||
class CategoryModelItem
|
||||
@@ -407,7 +408,7 @@ void CategoryFilterModel::populate()
|
||||
const QString &category = i.key();
|
||||
if (m_isSubcategoriesEnabled) {
|
||||
CategoryModelItem *parent = m_rootItem;
|
||||
foreach (const QString &subcat, session->expandCategory(category)) {
|
||||
for (const QString &subcat : asConst(session->expandCategory(category))) {
|
||||
const QString subcatName = shortName(subcat);
|
||||
if (!parent->hasChild(subcatName)) {
|
||||
new CategoryModelItem(
|
||||
@@ -436,7 +437,7 @@ CategoryModelItem *CategoryFilterModel::findItem(const QString &fullName) const
|
||||
return m_rootItem->child(fullName);
|
||||
|
||||
CategoryModelItem *item = m_rootItem;
|
||||
foreach (const QString &subcat, BitTorrent::Session::expandCategory(fullName)) {
|
||||
for (const QString &subcat : asConst(BitTorrent::Session::expandCategory(fullName))) {
|
||||
const QString subcatName = shortName(subcat);
|
||||
if (!item->hasChild(subcatName)) return nullptr;
|
||||
item = item->child(subcatName);
|
||||
|
||||
@@ -231,7 +231,7 @@ void CategoryFilterWidget::removeCategory()
|
||||
void CategoryFilterWidget::removeUnusedCategories()
|
||||
{
|
||||
auto session = BitTorrent::Session::instance();
|
||||
for (const QString &category : copyAsConst(session->categories().keys())) {
|
||||
for (const QString &category : asConst(session->categories().keys())) {
|
||||
if (model()->data(static_cast<CategoryFilterProxyModel *>(model())->index(category), Qt::UserRole) == 0)
|
||||
session->removeCategory(category);
|
||||
}
|
||||
|
||||
@@ -30,6 +30,7 @@
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#include "base/global.h"
|
||||
#include "base/net/downloadmanager.h"
|
||||
#include "base/settingsstorage.h"
|
||||
#include "cookiesmodel.h"
|
||||
@@ -100,6 +101,6 @@ void CookiesDialog::onButtonDeleteClicked()
|
||||
}
|
||||
);
|
||||
|
||||
for (const QModelIndex &idx : idxs)
|
||||
for (const QModelIndex &idx : asConst(idxs))
|
||||
m_cookiesModel->removeRow(idx.row());
|
||||
}
|
||||
|
||||
@@ -32,6 +32,7 @@
|
||||
#include <QDateTime>
|
||||
#include <QPalette>
|
||||
|
||||
#include "base/global.h"
|
||||
#include "guiiconprovider.h"
|
||||
#include "loglistwidget.h"
|
||||
#include "ui_executionlogwidget.h"
|
||||
@@ -52,9 +53,9 @@ ExecutionLogWidget::ExecutionLogWidget(QWidget *parent, const Log::MsgTypes &typ
|
||||
m_ui->tabBan->layout()->addWidget(m_peerList);
|
||||
|
||||
const Logger *const logger = Logger::instance();
|
||||
foreach (const Log::Msg &msg, logger->getMessages())
|
||||
for (const Log::Msg &msg : asConst(logger->getMessages()))
|
||||
addLogMessage(msg);
|
||||
foreach (const Log::Peer &peer, logger->getPeers())
|
||||
for (const Log::Peer &peer : asConst(logger->getPeers()))
|
||||
addPeerMessage(peer);
|
||||
connect(logger, &Logger::newLogMessage, this, &ExecutionLogWidget::addLogMessage);
|
||||
connect(logger, &Logger::newLogPeer, this, &ExecutionLogWidget::addPeerMessage);
|
||||
|
||||
@@ -350,7 +350,7 @@ void FileSystemPathComboEdit::addItem(const QString &text)
|
||||
editWidget<WidgetType>()->addItem(Utils::Fs::toNativePath(text));
|
||||
}
|
||||
|
||||
void FileSystemPathComboEdit::insertItem(int index, const QString& text)
|
||||
void FileSystemPathComboEdit::insertItem(int index, const QString &text)
|
||||
{
|
||||
editWidget<WidgetType>()->insertItem(index, Utils::Fs::toNativePath(text));
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Bittorrent Client using Qt and libtorrent.
|
||||
* Copyright (C) 2017 Thomas Piccirello <thomas@piccirello.com>
|
||||
* Copyright (C) 2017 Thomas Piccirello <thomas.piccirello@gmail.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
@@ -46,7 +46,7 @@ IPSubnetWhitelistOptionsDialog::IPSubnetWhitelistOptionsDialog(QWidget *parent)
|
||||
m_ui->setupUi(this);
|
||||
|
||||
QStringList authSubnetWhitelistStringList;
|
||||
for (const Utils::Net::Subnet &subnet : copyAsConst(Preferences::instance()->getWebUiAuthSubnetWhitelist()))
|
||||
for (const Utils::Net::Subnet &subnet : asConst(Preferences::instance()->getWebUiAuthSubnetWhitelist()))
|
||||
authSubnetWhitelistStringList << Utils::Net::subnetToString(subnet);
|
||||
m_model = new QStringListModel(authSubnetWhitelistStringList, this);
|
||||
|
||||
@@ -99,7 +99,7 @@ void IPSubnetWhitelistOptionsDialog::on_buttonWhitelistIPSubnet_clicked()
|
||||
|
||||
void IPSubnetWhitelistOptionsDialog::on_buttonDeleteIPSubnet_clicked()
|
||||
{
|
||||
for (const auto &i : copyAsConst(m_ui->whitelistedIPSubnetList->selectionModel()->selectedIndexes()))
|
||||
for (const auto &i : asConst(m_ui->whitelistedIPSubnetList->selectionModel()->selectedIndexes()))
|
||||
m_sortFilter->removeRow(i.row());
|
||||
|
||||
m_modified = true;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Bittorrent Client using Qt and libtorrent.
|
||||
* Copyright (C) 2017 Thomas Piccirello <thomas@piccirello.com>
|
||||
* Copyright (C) 2017 Thomas Piccirello <thomas.piccirello@gmail.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
|
||||
@@ -36,6 +36,7 @@
|
||||
#include <QListWidgetItem>
|
||||
#include <QRegularExpression>
|
||||
|
||||
#include "base/global.h"
|
||||
#include "guiiconprovider.h"
|
||||
|
||||
LogListWidget::LogListWidget(int maxLines, const Log::MsgTypes &types, QWidget *parent)
|
||||
@@ -97,7 +98,7 @@ void LogListWidget::copySelection()
|
||||
{
|
||||
static const QRegularExpression htmlTag("<[^>]+>");
|
||||
QStringList strings;
|
||||
foreach (QListWidgetItem* it, selectedItems())
|
||||
for (QListWidgetItem* it : asConst(selectedItems()))
|
||||
strings << static_cast<QLabel*>(itemWidget(it))->text().remove(htmlTag);
|
||||
|
||||
QApplication::clipboard()->setText(strings.join('\n'));
|
||||
|
||||
@@ -284,7 +284,7 @@ MainWindow::MainWindow(QWidget *parent)
|
||||
m_prioSeparatorMenu = m_ui->menuEdit->insertSeparator(m_ui->actionTopPriority);
|
||||
|
||||
#ifdef Q_OS_MAC
|
||||
foreach (QAction *action, m_ui->toolBar->actions()) {
|
||||
for (QAction *action : asConst(m_ui->toolBar->actions())) {
|
||||
if (action->isSeparator()) {
|
||||
QWidget *spacer = new QWidget(this);
|
||||
spacer->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
|
||||
@@ -305,7 +305,7 @@ MainWindow::MainWindow(QWidget *parent)
|
||||
spacer->setMinimumWidth(8);
|
||||
m_ui->toolBar->addWidget(spacer);
|
||||
}
|
||||
#endif
|
||||
#endif // Q_OS_MAC
|
||||
|
||||
// Transfer list slots
|
||||
connect(m_ui->actionStart, &QAction::triggered, m_transferListWidget, &TransferListWidget::startSelectedTorrents);
|
||||
@@ -1110,7 +1110,7 @@ void MainWindow::toggleVisibility(const QSystemTrayIcon::ActivationReason reason
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#endif // Q_OS_MAC
|
||||
|
||||
// Display About Dialog
|
||||
void MainWindow::on_actionAbout_triggered()
|
||||
@@ -1239,7 +1239,7 @@ bool MainWindow::event(QEvent *e)
|
||||
qDebug() << "Has active window:" << (qApp->activeWindow() != nullptr);
|
||||
// Check if there is a modal window
|
||||
bool hasModalWindow = false;
|
||||
foreach (QWidget *widget, QApplication::allWidgets()) {
|
||||
for (QWidget *widget : asConst(QApplication::allWidgets())) {
|
||||
if (widget->isModal()) {
|
||||
hasModalWindow = true;
|
||||
break;
|
||||
@@ -1272,7 +1272,7 @@ bool MainWindow::event(QEvent *e)
|
||||
default:
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
#endif // Q_OS_MAC
|
||||
|
||||
return QMainWindow::event(e);
|
||||
}
|
||||
@@ -1285,7 +1285,7 @@ void MainWindow::dropEvent(QDropEvent *event)
|
||||
// remove scheme
|
||||
QStringList files;
|
||||
if (event->mimeData()->hasUrls()) {
|
||||
foreach (const QUrl &url, event->mimeData()->urls()) {
|
||||
for (const QUrl &url : asConst(event->mimeData()->urls())) {
|
||||
if (url.isEmpty())
|
||||
continue;
|
||||
|
||||
@@ -1300,7 +1300,7 @@ void MainWindow::dropEvent(QDropEvent *event)
|
||||
|
||||
// differentiate ".torrent" files/links & magnet links from others
|
||||
QStringList torrentFiles, otherFiles;
|
||||
foreach (const QString &file, files) {
|
||||
for (const QString &file : asConst(files)) {
|
||||
const bool isTorrentLink = (file.startsWith("magnet:", Qt::CaseInsensitive)
|
||||
|| file.endsWith(C_TORRENT_FILE_EXTENSION, Qt::CaseInsensitive)
|
||||
|| Utils::Misc::isUrl(file));
|
||||
@@ -1312,7 +1312,7 @@ void MainWindow::dropEvent(QDropEvent *event)
|
||||
|
||||
// Download torrents
|
||||
const bool useTorrentAdditionDialog = AddNewTorrentDialog::isEnabled();
|
||||
foreach (const QString &file, torrentFiles) {
|
||||
for (const QString &file : asConst(torrentFiles)) {
|
||||
if (useTorrentAdditionDialog)
|
||||
AddNewTorrentDialog::show(file, this);
|
||||
else
|
||||
@@ -1321,7 +1321,7 @@ void MainWindow::dropEvent(QDropEvent *event)
|
||||
if (!torrentFiles.isEmpty()) return;
|
||||
|
||||
// Create torrent
|
||||
foreach (const QString &file, otherFiles) {
|
||||
for (const QString &file : asConst(otherFiles)) {
|
||||
createTorrentTriggered(file);
|
||||
|
||||
// currently only hande the first entry
|
||||
@@ -1333,7 +1333,7 @@ void MainWindow::dropEvent(QDropEvent *event)
|
||||
// Decode if we accept drag 'n drop or not
|
||||
void MainWindow::dragEnterEvent(QDragEnterEvent *event)
|
||||
{
|
||||
foreach (const QString &mime, event->mimeData()->formats())
|
||||
for (const QString &mime : asConst(event->mimeData()->formats()))
|
||||
qDebug("mimeData: %s", mime.toLocal8Bit().data());
|
||||
if (event->mimeData()->hasFormat("text/plain") || event->mimeData()->hasFormat("text/uri-list"))
|
||||
event->acceptProposedAction();
|
||||
@@ -1361,7 +1361,7 @@ void MainWindow::setupDockClickHandler()
|
||||
MacUtils::overrideDockClickHandler(dockClickHandler);
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif // Q_OS_MAC
|
||||
|
||||
/*****************************************************
|
||||
* *
|
||||
@@ -1382,7 +1382,7 @@ void MainWindow::on_actionOpen_triggered()
|
||||
|
||||
const bool useTorrentAdditionDialog = AddNewTorrentDialog::isEnabled();
|
||||
if (!pathsList.isEmpty()) {
|
||||
foreach (QString file, pathsList) {
|
||||
for (const QString &file : pathsList) {
|
||||
qDebug("Dropped file %s on download list", qUtf8Printable(file));
|
||||
if (useTorrentAdditionDialog)
|
||||
AddNewTorrentDialog::show(file, this);
|
||||
@@ -1635,7 +1635,7 @@ void MainWindow::showNotificationBaloon(QString title, QString msg) const
|
||||
void MainWindow::downloadFromURLList(const QStringList &urlList)
|
||||
{
|
||||
const bool useTorrentAdditionDialog = AddNewTorrentDialog::isEnabled();
|
||||
foreach (QString url, urlList) {
|
||||
for (QString url : urlList) {
|
||||
if (((url.size() == 40) && !url.contains(QRegularExpression("[^0-9A-Fa-f]")))
|
||||
|| ((url.size() == 32) && !url.contains(QRegularExpression("[^2-7A-Za-z]"))))
|
||||
url = "magnet:?xt=urn:btih:" + url;
|
||||
|
||||
@@ -71,6 +71,21 @@
|
||||
#include "ui_optionsdialog.h"
|
||||
#include "utils.h"
|
||||
|
||||
namespace
|
||||
{
|
||||
QStringList translatedWeekdayNames()
|
||||
{
|
||||
// return translated strings from Monday to Sunday in user selected locale
|
||||
|
||||
const QLocale locale {Preferences::instance()->getLocale()};
|
||||
const QDate date {2018, 11, 5}; // Monday
|
||||
QStringList ret;
|
||||
for (int i = 0; i < 7; ++i)
|
||||
ret.append(locale.toString(date.addDays(i), "dddd"));
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
class WheelEventEater : public QObject
|
||||
{
|
||||
public:
|
||||
@@ -145,10 +160,10 @@ OptionsDialog::OptionsDialog(QWidget *parent)
|
||||
m_ui->hsplitter->setCollapsible(0, false);
|
||||
m_ui->hsplitter->setCollapsible(1, false);
|
||||
// Get apply button in button box
|
||||
QList<QAbstractButton *> buttons = m_ui->buttonBox->buttons();
|
||||
foreach (QAbstractButton *button, buttons) {
|
||||
const QList<QAbstractButton *> buttons = m_ui->buttonBox->buttons();
|
||||
for (QAbstractButton *button : buttons) {
|
||||
if (m_ui->buttonBox->buttonRole(button) == QDialogButtonBox::ApplyRole) {
|
||||
applyButton = button;
|
||||
m_applyButton = button;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -164,8 +179,7 @@ OptionsDialog::OptionsDialog(QWidget *parent)
|
||||
initializeLanguageCombo();
|
||||
|
||||
// Load week days (scheduler)
|
||||
for (uint i = 1; i <= 7; ++i)
|
||||
m_ui->comboBoxScheduleDays->addItem(QDate::longDayName(i, QDate::StandaloneFormat));
|
||||
m_ui->comboBoxScheduleDays->addItems(translatedWeekdayNames());
|
||||
|
||||
// Load options
|
||||
loadOptions();
|
||||
@@ -390,6 +404,7 @@ OptionsDialog::OptionsDialog(QWidget *parent)
|
||||
connect(m_ui->checkBypassAuthSubnetWhitelist, &QAbstractButton::toggled, m_ui->IPSubnetWhitelistButton, &QPushButton::setEnabled);
|
||||
connect(m_ui->checkClickjacking, &QCheckBox::toggled, this, &ThisType::enableApplyButton);
|
||||
connect(m_ui->checkCSRFProtection, &QCheckBox::toggled, this, &ThisType::enableApplyButton);
|
||||
connect(m_ui->groupHostHeaderValidation, &QGroupBox::toggled, this, &ThisType::enableApplyButton);
|
||||
connect(m_ui->checkDynDNS, &QGroupBox::toggled, this, &ThisType::enableApplyButton);
|
||||
connect(m_ui->comboDNSService, qComboBoxCurrentIndexChanged, this, &ThisType::enableApplyButton);
|
||||
connect(m_ui->domainNameTxt, &QLineEdit::textChanged, this, &ThisType::enableApplyButton);
|
||||
@@ -409,13 +424,13 @@ OptionsDialog::OptionsDialog(QWidget *parent)
|
||||
connect(m_ui->btnEditRules, &QPushButton::clicked, this, [this]() { AutomatedRssDownloader(this).exec(); });
|
||||
|
||||
// Disable apply Button
|
||||
applyButton->setEnabled(false);
|
||||
m_applyButton->setEnabled(false);
|
||||
// Tab selection mechanism
|
||||
connect(m_ui->tabSelection, &QListWidget::currentItemChanged, this, &ThisType::changePage);
|
||||
// Load Advanced settings
|
||||
advancedSettings = new AdvancedSettings(m_ui->tabAdvancedPage);
|
||||
m_ui->advPageLayout->addWidget(advancedSettings);
|
||||
connect(advancedSettings, &AdvancedSettings::settingsChanged, this, &ThisType::enableApplyButton);
|
||||
m_advancedSettings = new AdvancedSettings(m_ui->tabAdvancedPage);
|
||||
m_ui->advPageLayout->addWidget(m_advancedSettings);
|
||||
connect(m_advancedSettings, &AdvancedSettings::settingsChanged, this, &ThisType::enableApplyButton);
|
||||
|
||||
m_ui->textFileLogPath->setDialogCaption(tr("Choose a save directory"));
|
||||
m_ui->textFileLogPath->setMode(FileSystemPathEdit::Mode::DirectorySave);
|
||||
@@ -438,9 +453,9 @@ OptionsDialog::OptionsDialog(QWidget *parent)
|
||||
|
||||
// disable mouse wheel event on widgets to avoid mis-selection
|
||||
WheelEventEater *wheelEventEater = new WheelEventEater(this);
|
||||
for (QComboBox *widget : copyAsConst(findChildren<QComboBox *>()))
|
||||
for (QComboBox *widget : asConst(findChildren<QComboBox *>()))
|
||||
widget->installEventFilter(wheelEventEater);
|
||||
for (QSpinBox *widget : copyAsConst(findChildren<QSpinBox *>()))
|
||||
for (QSpinBox *widget : asConst(findChildren<QSpinBox *>()))
|
||||
widget->installEventFilter(wheelEventEater);
|
||||
|
||||
loadWindowState();
|
||||
@@ -454,7 +469,7 @@ void OptionsDialog::initializeLanguageCombo()
|
||||
// List language files
|
||||
const QDir langDir(":/lang");
|
||||
const QStringList langFiles = langDir.entryList(QStringList("qbittorrent_*.qm"), QDir::Files);
|
||||
foreach (const QString langFile, langFiles) {
|
||||
for (const QString &langFile : langFiles) {
|
||||
QString localeStr = langFile.mid(12); // remove "qbittorrent_"
|
||||
localeStr.chop(3); // Remove ".qm"
|
||||
QString languageName;
|
||||
@@ -478,7 +493,7 @@ OptionsDialog::~OptionsDialog()
|
||||
|
||||
saveWindowState();
|
||||
|
||||
foreach (const QString &path, addedScanDirs)
|
||||
for (const QString &path : asConst(m_addedScanDirs))
|
||||
ScanFoldersModel::instance()->removePath(path);
|
||||
ScanFoldersModel::instance()->configure(); // reloads "removed" paths
|
||||
delete m_ui;
|
||||
@@ -526,7 +541,7 @@ void OptionsDialog::saveWindowState() const
|
||||
|
||||
void OptionsDialog::saveOptions()
|
||||
{
|
||||
applyButton->setEnabled(false);
|
||||
m_applyButton->setEnabled(false);
|
||||
Preferences *const pref = Preferences::instance();
|
||||
// Load the translation
|
||||
QString locale = getLocale();
|
||||
@@ -550,8 +565,8 @@ void OptionsDialog::saveOptions()
|
||||
pref->setTrayIconStyle(TrayIcon::Style(m_ui->comboTrayIcon->currentIndex()));
|
||||
pref->setCloseToTray(closeToTray());
|
||||
pref->setMinimizeToTray(minimizeToTray());
|
||||
pref->setStartMinimized(startMinimized());
|
||||
#endif
|
||||
pref->setStartMinimized(startMinimized());
|
||||
pref->setSplashScreenDisabled(isSplashScreenDisabled());
|
||||
pref->setConfirmOnExit(m_ui->checkProgramExitConfirm->isChecked());
|
||||
pref->setDontConfirmAutoExit(!m_ui->checkProgramAutoExitConfirm->isChecked());
|
||||
@@ -610,11 +625,11 @@ void OptionsDialog::saveOptions()
|
||||
AddNewTorrentDialog::setTopLevel(m_ui->checkAdditionDialogFront->isChecked());
|
||||
session->setAddTorrentPaused(addTorrentsInPause());
|
||||
session->setCreateTorrentSubfolder(m_ui->checkCreateSubfolder->isChecked());
|
||||
ScanFoldersModel::instance()->removeFromFSWatcher(removedScanDirs);
|
||||
ScanFoldersModel::instance()->addToFSWatcher(addedScanDirs);
|
||||
ScanFoldersModel::instance()->removeFromFSWatcher(m_removedScanDirs);
|
||||
ScanFoldersModel::instance()->addToFSWatcher(m_addedScanDirs);
|
||||
ScanFoldersModel::instance()->makePersistent();
|
||||
removedScanDirs.clear();
|
||||
addedScanDirs.clear();
|
||||
m_removedScanDirs.clear();
|
||||
m_addedScanDirs.clear();
|
||||
session->setTorrentExportDirectory(getTorrentExportDir());
|
||||
session->setFinishedTorrentExportDirectory(getFinishedTorrentExportDir());
|
||||
pref->setMailNotificationEnabled(m_ui->groupMailNotification->isChecked());
|
||||
@@ -719,6 +734,7 @@ void OptionsDialog::saveOptions()
|
||||
// Security
|
||||
pref->setWebUiClickjackingProtectionEnabled(m_ui->checkClickjacking->isChecked());
|
||||
pref->setWebUiCSRFProtectionEnabled(m_ui->checkCSRFProtection->isChecked());
|
||||
pref->setWebUIHostHeaderValidationEnabled(m_ui->groupHostHeaderValidation->isChecked());
|
||||
// DynDNS
|
||||
pref->setDynDNSEnabled(m_ui->checkDynDNS->isChecked());
|
||||
pref->setDynDNSService(m_ui->comboDNSService->currentIndex());
|
||||
@@ -732,7 +748,7 @@ void OptionsDialog::saveOptions()
|
||||
// End Web UI
|
||||
// End preferences
|
||||
// Save advanced settings
|
||||
advancedSettings->saveAdvancedSettings();
|
||||
m_advancedSettings->saveAdvancedSettings();
|
||||
// Assume that user changed multiple settings
|
||||
// so it's best to save immediately
|
||||
pref->apply();
|
||||
@@ -1082,6 +1098,7 @@ void OptionsDialog::loadOptions()
|
||||
// Security
|
||||
m_ui->checkClickjacking->setChecked(pref->isWebUiClickjackingProtectionEnabled());
|
||||
m_ui->checkCSRFProtection->setChecked(pref->isWebUiCSRFProtectionEnabled());
|
||||
m_ui->groupHostHeaderValidation->setChecked(pref->isWebUIHostHeaderValidationEnabled());
|
||||
|
||||
m_ui->checkDynDNS->setChecked(pref->isDynDNSEnabled());
|
||||
m_ui->comboDNSService->setCurrentIndex(static_cast<int>(pref->getDynDNSService()));
|
||||
@@ -1223,7 +1240,7 @@ int OptionsDialog::getMaxUploadsPerTorrent() const
|
||||
|
||||
void OptionsDialog::on_buttonBox_accepted()
|
||||
{
|
||||
if (applyButton->isEnabled()) {
|
||||
if (m_applyButton->isEnabled()) {
|
||||
if (!schedTimesOk()) {
|
||||
m_ui->tabSelection->setCurrentRow(TAB_SPEED);
|
||||
return;
|
||||
@@ -1232,7 +1249,11 @@ void OptionsDialog::on_buttonBox_accepted()
|
||||
m_ui->tabSelection->setCurrentRow(TAB_WEBUI);
|
||||
return;
|
||||
}
|
||||
applyButton->setEnabled(false);
|
||||
if (!isAlternativeWebUIPathValid()) {
|
||||
m_ui->tabSelection->setCurrentRow(TAB_WEBUI);
|
||||
return;
|
||||
}
|
||||
m_applyButton->setEnabled(false);
|
||||
this->hide();
|
||||
saveOptions();
|
||||
}
|
||||
@@ -1242,7 +1263,7 @@ void OptionsDialog::on_buttonBox_accepted()
|
||||
|
||||
void OptionsDialog::applySettings(QAbstractButton *button)
|
||||
{
|
||||
if (button == applyButton) {
|
||||
if (button == m_applyButton) {
|
||||
if (!schedTimesOk()) {
|
||||
m_ui->tabSelection->setCurrentRow(TAB_SPEED);
|
||||
return;
|
||||
@@ -1251,6 +1272,10 @@ void OptionsDialog::applySettings(QAbstractButton *button)
|
||||
m_ui->tabSelection->setCurrentRow(TAB_WEBUI);
|
||||
return;
|
||||
}
|
||||
if (!isAlternativeWebUIPathValid()) {
|
||||
m_ui->tabSelection->setCurrentRow(TAB_WEBUI);
|
||||
return;
|
||||
}
|
||||
saveOptions();
|
||||
}
|
||||
}
|
||||
@@ -1274,7 +1299,7 @@ bool OptionsDialog::useAdditionDialog() const
|
||||
|
||||
void OptionsDialog::enableApplyButton()
|
||||
{
|
||||
applyButton->setEnabled(true);
|
||||
m_applyButton->setEnabled(true);
|
||||
}
|
||||
|
||||
void OptionsDialog::toggleComboRatioLimitAct()
|
||||
@@ -1469,7 +1494,7 @@ void OptionsDialog::on_addScanFolderButton_clicked()
|
||||
break;
|
||||
default:
|
||||
pref->setScanDirsLastPath(dir);
|
||||
addedScanDirs << dir;
|
||||
m_addedScanDirs << dir;
|
||||
for (int i = 0; i < ScanFoldersModel::instance()->columnCount(); ++i)
|
||||
m_ui->scanFoldersView->resizeColumnToContents(i);
|
||||
enableApplyButton();
|
||||
@@ -1487,9 +1512,9 @@ void OptionsDialog::on_removeScanFolderButton_clicked()
|
||||
if (selected.isEmpty())
|
||||
return;
|
||||
Q_ASSERT(selected.count() == ScanFoldersModel::instance()->columnCount());
|
||||
foreach (const QModelIndex &index, selected) {
|
||||
for (const QModelIndex &index : selected) {
|
||||
if (index.column() == ScanFoldersModel::WATCH)
|
||||
removedScanDirs << index.data().toString();
|
||||
m_removedScanDirs << index.data().toString();
|
||||
}
|
||||
ScanFoldersModel::instance()->removePath(selected.first().row(), false);
|
||||
}
|
||||
@@ -1733,6 +1758,15 @@ bool OptionsDialog::webUIAuthenticationOk()
|
||||
return true;
|
||||
}
|
||||
|
||||
bool OptionsDialog::isAlternativeWebUIPathValid()
|
||||
{
|
||||
if (m_ui->groupAltWebUI->isChecked() && m_ui->textWebUIRootFolder->selectedPath().trimmed().isEmpty()) {
|
||||
QMessageBox::warning(this, tr("Location Error"), tr("The alternative Web UI files location cannot be blank."));
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void OptionsDialog::on_banListButton_clicked()
|
||||
{
|
||||
// call dialog window
|
||||
|
||||
@@ -172,15 +172,15 @@ private:
|
||||
bool setSslCertificate(const QByteArray &cert);
|
||||
bool schedTimesOk();
|
||||
bool webUIAuthenticationOk();
|
||||
bool isAlternativeWebUIPathValid();
|
||||
|
||||
QByteArray m_sslCert, m_sslKey;
|
||||
|
||||
Ui::OptionsDialog *m_ui;
|
||||
QButtonGroup choiceLanguage;
|
||||
QAbstractButton *applyButton;
|
||||
AdvancedSettings *advancedSettings;
|
||||
QList<QString> addedScanDirs;
|
||||
QList<QString> removedScanDirs;
|
||||
QAbstractButton *m_applyButton;
|
||||
AdvancedSettings *m_advancedSettings;
|
||||
QList<QString> m_addedScanDirs;
|
||||
QList<QString> m_removedScanDirs;
|
||||
};
|
||||
|
||||
#endif // OPTIONSDIALOG_H
|
||||
|
||||
@@ -941,7 +941,7 @@
|
||||
<item row="3" column="0">
|
||||
<widget class="QLabel" name="labelCategoryChanged">
|
||||
<property name="text">
|
||||
<string>When Category changed:</string>
|
||||
<string>When Category Save Path changed:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
@@ -2944,28 +2944,6 @@ Specify an IPv4 or IPv6 address. You can specify "0.0.0.0" for any IPv
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_10">
|
||||
<item>
|
||||
<widget class="QLabel" name="labelServerDomains">
|
||||
<property name="text">
|
||||
<string>Server domains:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLineEdit" name="textServerDomains">
|
||||
<property name="toolTip">
|
||||
<string>Whitelist for filtering HTTP Host header values.
|
||||
In order to defend against DNS rebinding attack,
|
||||
you should put in domain names used by WebUI server.
|
||||
|
||||
Use ';' to split multiple entries. Can use wildcard '*'.</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="checkWebUIUPnP">
|
||||
<property name="text">
|
||||
@@ -3177,17 +3155,60 @@ Use ';' to split multiple entries. Can use wildcard '*'.</string>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="checkClickjacking">
|
||||
<property name="text">
|
||||
<string>Enable clickjacking protection</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="checkCSRFProtection">
|
||||
<property name="text">
|
||||
<string>Enable Cross-Site Request Forgery (CSRF) protection</string>
|
||||
<widget class="QGroupBox" name="groupBox_3">
|
||||
<property name="title">
|
||||
<string>Security</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_33">
|
||||
<item>
|
||||
<widget class="QCheckBox" name="checkClickjacking">
|
||||
<property name="text">
|
||||
<string>Enable clickjacking protection</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="checkCSRFProtection">
|
||||
<property name="text">
|
||||
<string>Enable Cross-Site Request Forgery (CSRF) protection</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="groupHostHeaderValidation">
|
||||
<property name="title">
|
||||
<string>Enable Host header validation</string>
|
||||
</property>
|
||||
<property name="checkable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_32">
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_10">
|
||||
<item>
|
||||
<widget class="QLabel" name="labelServerDomains">
|
||||
<property name="text">
|
||||
<string>Server domains:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLineEdit" name="textServerDomains">
|
||||
<property name="toolTip">
|
||||
<string>Whitelist for filtering HTTP Host header values.
|
||||
In order to defend against DNS rebinding attack,
|
||||
you should put in domain names used by WebUI server.
|
||||
|
||||
Use ';' to split multiple entries. Can use wildcard '*'.</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
|
||||
@@ -141,7 +141,7 @@ bool ProgramUpdater::isVersionMoreRecent(const QString &remoteVersion) const
|
||||
qDebug() << Q_FUNC_INFO << "local version:" << localVersion << "/" << QBT_VERSION;
|
||||
QStringList remoteParts = remoteVersion.split('.');
|
||||
QStringList localParts = localVersion.split('.');
|
||||
for (int i = 0; i<qMin(remoteParts.size(), localParts.size()); ++i) {
|
||||
for (int i = 0; i < qMin(remoteParts.size(), localParts.size()); ++i) {
|
||||
if (remoteParts[i].toInt() > localParts[i].toInt())
|
||||
return true;
|
||||
if (remoteParts[i].toInt() < localParts[i].toInt())
|
||||
|
||||
@@ -103,7 +103,7 @@ PeerListWidget::PeerListWidget(PropertiesWidget *parent)
|
||||
hideColumn(PeerListDelegate::COUNTRY);
|
||||
// Ensure that at least one column is visible at all times
|
||||
bool atLeastOne = false;
|
||||
for (unsigned int i = 0; i < PeerListDelegate::IP_HIDDEN; ++i) {
|
||||
for (int i = 0; i < PeerListDelegate::IP_HIDDEN; ++i) {
|
||||
if (!isColumnHidden(i)) {
|
||||
atLeastOne = true;
|
||||
break;
|
||||
@@ -114,7 +114,7 @@ PeerListWidget::PeerListWidget(PropertiesWidget *parent)
|
||||
// To also mitigate the above issue, we have to resize each column when
|
||||
// its size is 0, because explicitly 'showing' the column isn't enough
|
||||
// in the above scenario.
|
||||
for (unsigned int i = 0; i < PeerListDelegate::IP_HIDDEN; ++i)
|
||||
for (int i = 0; i < PeerListDelegate::IP_HIDDEN; ++i)
|
||||
if ((columnWidth(i) <= 0) && !isColumnHidden(i))
|
||||
resizeColumnToContents(i);
|
||||
// Context menu
|
||||
@@ -169,7 +169,7 @@ void PeerListWidget::displayToggleColumnsMenu(const QPoint &)
|
||||
actions.append(myAct);
|
||||
}
|
||||
int visibleCols = 0;
|
||||
for (unsigned int i = 0; i < PeerListDelegate::IP_HIDDEN; ++i) {
|
||||
for (int i = 0; i < PeerListDelegate::IP_HIDDEN; ++i) {
|
||||
if (!isColumnHidden(i))
|
||||
++visibleCols;
|
||||
|
||||
@@ -248,9 +248,9 @@ void PeerListWidget::showPeerListMenu(const QPoint &)
|
||||
if (!act) return;
|
||||
|
||||
if (act == addPeerAct) {
|
||||
QList<BitTorrent::PeerAddress> peersList = PeersAdditionDialog::askForPeers(this);
|
||||
const QList<BitTorrent::PeerAddress> peersList = PeersAdditionDialog::askForPeers(this);
|
||||
int peerCount = 0;
|
||||
foreach (const BitTorrent::PeerAddress &addr, peersList) {
|
||||
for (const BitTorrent::PeerAddress &addr : peersList) {
|
||||
if (torrent->connectPeer(addr)) {
|
||||
qDebug("Adding peer %s...", qUtf8Printable(addr.ip.toString()));
|
||||
Logger::instance()->addMessage(tr("Manually adding peer '%1'...").arg(addr.ip.toString()));
|
||||
@@ -284,8 +284,8 @@ void PeerListWidget::banSelectedPeers()
|
||||
QString(), 0, 1);
|
||||
if (ret) return;
|
||||
|
||||
QModelIndexList selectedIndexes = selectionModel()->selectedRows();
|
||||
foreach (const QModelIndex &index, selectedIndexes) {
|
||||
const QModelIndexList selectedIndexes = selectionModel()->selectedRows();
|
||||
for (const QModelIndex &index : selectedIndexes) {
|
||||
int row = m_proxyModel->mapToSource(index).row();
|
||||
QString ip = m_listModel->data(m_listModel->index(row, PeerListDelegate::IP_HIDDEN)).toString();
|
||||
qDebug("Banning peer %s...", ip.toLocal8Bit().data());
|
||||
@@ -298,9 +298,9 @@ void PeerListWidget::banSelectedPeers()
|
||||
|
||||
void PeerListWidget::copySelectedPeers()
|
||||
{
|
||||
QModelIndexList selectedIndexes = selectionModel()->selectedRows();
|
||||
const QModelIndexList selectedIndexes = selectionModel()->selectedRows();
|
||||
QStringList selectedPeers;
|
||||
foreach (const QModelIndex &index, selectedIndexes) {
|
||||
for (const QModelIndex &index : selectedIndexes) {
|
||||
int row = m_proxyModel->mapToSource(index).row();
|
||||
QString ip = m_listModel->data(m_listModel->index(row, PeerListDelegate::IP_HIDDEN)).toString();
|
||||
QString myport = m_listModel->data(m_listModel->index(row, PeerListDelegate::PORT)).toString();
|
||||
@@ -321,7 +321,7 @@ void PeerListWidget::clear()
|
||||
int nbrows = m_listModel->rowCount();
|
||||
if (nbrows > 0) {
|
||||
qDebug("Cleared %d peers", nbrows);
|
||||
m_listModel->removeRows(0, nbrows);
|
||||
m_listModel->removeRows(0, nbrows);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -339,10 +339,10 @@ void PeerListWidget::loadPeers(BitTorrent::TorrentHandle *const torrent, bool fo
|
||||
{
|
||||
if (!torrent) return;
|
||||
|
||||
QList<BitTorrent::PeerInfo> peers = torrent->peers();
|
||||
const QList<BitTorrent::PeerInfo> peers = torrent->peers();
|
||||
QSet<QString> oldPeersSet = m_peerItems.keys().toSet();
|
||||
|
||||
foreach (const BitTorrent::PeerInfo &peer, peers) {
|
||||
for (const BitTorrent::PeerInfo &peer : peers) {
|
||||
BitTorrent::PeerAddress addr = peer.address();
|
||||
if (addr.ip.isNull()) continue;
|
||||
|
||||
|
||||
@@ -31,6 +31,7 @@
|
||||
#include <QHostAddress>
|
||||
#include <QMessageBox>
|
||||
|
||||
#include "base/global.h"
|
||||
#include "ui_peersadditiondialog.h"
|
||||
|
||||
PeersAdditionDialog::PeersAdditionDialog(QWidget *parent)
|
||||
@@ -61,7 +62,7 @@ void PeersAdditionDialog::validateInput()
|
||||
QMessageBox::Ok);
|
||||
return;
|
||||
}
|
||||
foreach (const QString &peer, m_ui->textEditPeers->toPlainText().trimmed().split('\n')) {
|
||||
for (const QString &peer : asConst(m_ui->textEditPeers->toPlainText().trimmed().split('\n'))) {
|
||||
BitTorrent::PeerAddress addr = parsePeer(peer);
|
||||
if (!addr.ip.isNull()) {
|
||||
m_peersList.append(addr);
|
||||
|
||||
@@ -259,7 +259,7 @@ void PiecesBar::showToolTip(const QHelpEvent *e)
|
||||
stream << "<html><body>";
|
||||
PieceIndexToImagePos transform {m_torrent->info(), m_image};
|
||||
int pieceIndex = transform.pieceIndex(imagePos);
|
||||
QVector<int> files {m_torrent->info().fileIndicesForPiece(pieceIndex)};
|
||||
const QVector<int> files {m_torrent->info().fileIndicesForPiece(pieceIndex)};
|
||||
|
||||
QString tooltipTitle;
|
||||
if (files.count() > 1) {
|
||||
@@ -275,7 +275,7 @@ void PiecesBar::showToolTip(const QHelpEvent *e)
|
||||
DetailedTooltipRenderer renderer(stream, tooltipTitle);
|
||||
|
||||
const bool isFileNameCorrectionNeeded = this->isFileNameCorrectionNeeded();
|
||||
for (int f: files) {
|
||||
for (int f : files) {
|
||||
QString filePath {m_torrent->info().filePath(f)};
|
||||
if (isFileNameCorrectionNeeded)
|
||||
filePath.replace(QLatin1String("/.unwanted"), QString());
|
||||
|
||||
@@ -38,6 +38,7 @@
|
||||
#include <QThread>
|
||||
#include <QTimer>
|
||||
|
||||
#include "base/bittorrent/filepriority.h"
|
||||
#include "base/bittorrent/session.h"
|
||||
#include "base/preferences.h"
|
||||
#include "base/unicodestrings.h"
|
||||
@@ -511,7 +512,7 @@ void PropertiesWidget::loadUrlSeeds()
|
||||
qDebug("Loading URL seeds");
|
||||
const QList<QUrl> hcSeeds = m_torrent->urlSeeds();
|
||||
// Add url seeds
|
||||
foreach (const QUrl &hcSeed, hcSeeds) {
|
||||
for (const QUrl &hcSeed : hcSeeds) {
|
||||
qDebug("Loading URL seed: %s", qUtf8Printable(hcSeed.toString()));
|
||||
new QListWidgetItem(hcSeed.toString(), m_ui->listWebSeeds);
|
||||
}
|
||||
@@ -582,7 +583,7 @@ void PropertiesWidget::displayFilesListMenu(const QPoint &)
|
||||
{
|
||||
if (!m_torrent) return;
|
||||
|
||||
QModelIndexList selectedRows = m_ui->filesList->selectionModel()->selectedRows(0);
|
||||
const QModelIndexList selectedRows = m_ui->filesList->selectionModel()->selectedRows(0);
|
||||
if (selectedRows.empty()) return;
|
||||
|
||||
QMenu myFilesLlistMenu;
|
||||
@@ -621,18 +622,18 @@ void PropertiesWidget::displayFilesListMenu(const QPoint &)
|
||||
renameSelectedFile();
|
||||
}
|
||||
else {
|
||||
int prio = prio::NORMAL;
|
||||
BitTorrent::FilePriority prio = BitTorrent::FilePriority::Normal;
|
||||
if (act == m_ui->actionHigh)
|
||||
prio = prio::HIGH;
|
||||
prio = BitTorrent::FilePriority::High;
|
||||
else if (act == m_ui->actionMaximum)
|
||||
prio = prio::MAXIMUM;
|
||||
prio = BitTorrent::FilePriority::Maximum;
|
||||
else if (act == m_ui->actionNotDownloaded)
|
||||
prio = prio::IGNORED;
|
||||
prio = BitTorrent::FilePriority::Ignored;
|
||||
|
||||
qDebug("Setting files priority");
|
||||
foreach (QModelIndex index, selectedRows) {
|
||||
qDebug("Setting priority(%d) for file at row %d", prio, index.row());
|
||||
m_propListModel->setData(m_propListModel->index(index.row(), PRIORITY, index.parent()), prio);
|
||||
for (const QModelIndex &index : selectedRows) {
|
||||
qDebug("Setting priority(%d) for file at row %d", static_cast<int>(prio), index.row());
|
||||
m_propListModel->setData(m_propListModel->index(index.row(), PRIORITY, index.parent()), static_cast<int>(prio));
|
||||
}
|
||||
// Save changes
|
||||
filteredFilesChanged();
|
||||
@@ -847,7 +848,7 @@ void PropertiesWidget::deleteSelectedUrlSeeds()
|
||||
if (selectedItems.isEmpty()) return;
|
||||
|
||||
QList<QUrl> urlSeeds;
|
||||
foreach (const QListWidgetItem *item, selectedItems)
|
||||
for (const QListWidgetItem *item : selectedItems)
|
||||
urlSeeds << item->text();
|
||||
|
||||
m_torrent->removeUrlSeeds(urlSeeds);
|
||||
@@ -861,7 +862,7 @@ void PropertiesWidget::copySelectedWebSeedsToClipboard() const
|
||||
if (selectedItems.isEmpty()) return;
|
||||
|
||||
QStringList urlsToCopy;
|
||||
foreach (QListWidgetItem *item, selectedItems)
|
||||
for (const QListWidgetItem *item : selectedItems)
|
||||
urlsToCopy << item->text();
|
||||
|
||||
QApplication::clipboard()->setText(urlsToCopy.join('\n'));
|
||||
|
||||
@@ -40,6 +40,7 @@
|
||||
#include <QProxyStyle>
|
||||
#endif
|
||||
|
||||
#include "base/bittorrent/filepriority.h"
|
||||
#include "base/unicodestrings.h"
|
||||
#include "base/utils/misc.h"
|
||||
#include "base/utils/string.h"
|
||||
@@ -92,7 +93,7 @@ void PropListDelegate::paint(QPainter *painter, const QStyleOptionViewItem &opti
|
||||
newopt.maximum = 100;
|
||||
newopt.minimum = 0;
|
||||
newopt.textVisible = true;
|
||||
if (index.sibling(index.row(), PRIORITY).data().toInt() == prio::IGNORED) {
|
||||
if (index.sibling(index.row(), PRIORITY).data().toInt() == static_cast<int>(BitTorrent::FilePriority::Ignored)) {
|
||||
newopt.state &= ~QStyle::State_Enabled;
|
||||
newopt.palette = progressBarDisabledPalette();
|
||||
}
|
||||
@@ -110,17 +111,17 @@ void PropListDelegate::paint(QPainter *painter, const QStyleOptionViewItem &opti
|
||||
break;
|
||||
case PRIORITY: {
|
||||
QString text = "";
|
||||
switch (index.data().toInt()) {
|
||||
case prio::MIXED:
|
||||
switch (static_cast<BitTorrent::FilePriority>(index.data().toInt())) {
|
||||
case BitTorrent::FilePriority::Mixed:
|
||||
text = tr("Mixed", "Mixed (priorities");
|
||||
break;
|
||||
case prio::IGNORED:
|
||||
case BitTorrent::FilePriority::Ignored:
|
||||
text = tr("Not downloaded");
|
||||
break;
|
||||
case prio::HIGH:
|
||||
case BitTorrent::FilePriority::High:
|
||||
text = tr("High", "High (priority)");
|
||||
break;
|
||||
case prio::MAXIMUM:
|
||||
case BitTorrent::FilePriority::Maximum:
|
||||
text = tr("Maximum", "Maximum (priority)");
|
||||
break;
|
||||
default:
|
||||
@@ -154,14 +155,14 @@ void PropListDelegate::setEditorData(QWidget *editor, const QModelIndex &index)
|
||||
{
|
||||
QComboBox *combobox = static_cast<QComboBox *>(editor);
|
||||
// Set combobox index
|
||||
switch (index.data().toInt()) {
|
||||
case prio::IGNORED:
|
||||
switch (static_cast<BitTorrent::FilePriority>(index.data().toInt())) {
|
||||
case BitTorrent::FilePriority::Ignored:
|
||||
combobox->setCurrentIndex(0);
|
||||
break;
|
||||
case prio::HIGH:
|
||||
case BitTorrent::FilePriority::High:
|
||||
combobox->setCurrentIndex(2);
|
||||
break;
|
||||
case prio::MAXIMUM:
|
||||
case BitTorrent::FilePriority::Maximum:
|
||||
combobox->setCurrentIndex(3);
|
||||
break;
|
||||
default:
|
||||
@@ -180,7 +181,7 @@ QWidget *PropListDelegate::createEditor(QWidget *parent, const QStyleOptionViewI
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (index.data().toInt() == prio::MIXED)
|
||||
if (index.data().toInt() == static_cast<int>(BitTorrent::FilePriority::Mixed))
|
||||
return nullptr;
|
||||
|
||||
QComboBox *editor = new QComboBox(parent);
|
||||
@@ -198,20 +199,20 @@ void PropListDelegate::setModelData(QWidget *editor, QAbstractItemModel *model,
|
||||
int value = combobox->currentIndex();
|
||||
qDebug("PropListDelegate: setModelData(%d)", value);
|
||||
|
||||
BitTorrent::FilePriority prio = BitTorrent::FilePriority::Normal; // NORMAL
|
||||
switch (value) {
|
||||
case 0:
|
||||
model->setData(index, prio::IGNORED); // IGNORED
|
||||
prio = BitTorrent::FilePriority::Ignored; // IGNORED
|
||||
break;
|
||||
case 2:
|
||||
model->setData(index, prio::HIGH); // HIGH
|
||||
prio = BitTorrent::FilePriority::High; // HIGH
|
||||
break;
|
||||
case 3:
|
||||
model->setData(index, prio::MAXIMUM); // MAX
|
||||
prio = BitTorrent::FilePriority::Maximum; // MAX
|
||||
break;
|
||||
default:
|
||||
model->setData(index, prio::NORMAL); // NORMAL
|
||||
}
|
||||
|
||||
model->setData(index, static_cast<int>(prio));
|
||||
emit filteredFilesChanged();
|
||||
}
|
||||
|
||||
|
||||
@@ -33,6 +33,7 @@
|
||||
#include <QPushButton>
|
||||
#include <QSpacerItem>
|
||||
|
||||
#include "base/global.h"
|
||||
#include "guiiconprovider.h"
|
||||
|
||||
PropTabBar::PropTabBar(QWidget *parent)
|
||||
@@ -102,7 +103,7 @@ PropTabBar::PropTabBar(QWidget *parent)
|
||||
connect(m_btnGroup, static_cast<void (QButtonGroup::*)(int)>(&QButtonGroup::buttonClicked)
|
||||
, this, &PropTabBar::setCurrentIndex);
|
||||
// Disable buttons focus
|
||||
foreach (QAbstractButton *btn, m_btnGroup->buttons())
|
||||
for (QAbstractButton *btn : asConst(m_btnGroup->buttons()))
|
||||
btn->setFocusPolicy(Qt::NoFocus);
|
||||
}
|
||||
|
||||
|
||||
@@ -274,7 +274,7 @@ void SpeedPlotView::paintEvent(QPaintEvent *)
|
||||
rect.adjust(0, fontMetrics.height(), 0, 0); // Add top padding for top speed text
|
||||
|
||||
// draw Y axis speed labels
|
||||
QVector<QString> speedLabels = {
|
||||
const QVector<QString> speedLabels = {
|
||||
formatLabel(niceScale.arg, niceScale.unit),
|
||||
formatLabel((0.75 * niceScale.arg), niceScale.unit),
|
||||
formatLabel((0.50 * niceScale.arg), niceScale.unit),
|
||||
@@ -348,7 +348,7 @@ void SpeedPlotView::paintEvent(QPaintEvent *)
|
||||
|
||||
double legendHeight = 0;
|
||||
int legendWidth = 0;
|
||||
for (const auto &property : qAsConst(m_properties)) {
|
||||
for (const auto &property : asConst(m_properties)) {
|
||||
if (!property.enable)
|
||||
continue;
|
||||
|
||||
@@ -363,7 +363,7 @@ void SpeedPlotView::paintEvent(QPaintEvent *)
|
||||
painter.fillRect(legendBackgroundRect, legendBackgroundColor);
|
||||
|
||||
i = 0;
|
||||
for (const auto &property : qAsConst(m_properties)) {
|
||||
for (const auto &property : asConst(m_properties)) {
|
||||
if (!property.enable)
|
||||
continue;
|
||||
|
||||
|
||||
@@ -45,6 +45,7 @@
|
||||
#include "base/bittorrent/session.h"
|
||||
#include "base/bittorrent/torrenthandle.h"
|
||||
#include "base/bittorrent/trackerentry.h"
|
||||
#include "base/global.h"
|
||||
#include "base/preferences.h"
|
||||
#include "base/utils/misc.h"
|
||||
#include "autoexpandabledialog.h"
|
||||
@@ -96,23 +97,23 @@ TrackerListWidget::TrackerListWidget(PropertiesWidget *properties)
|
||||
insertTopLevelItem(2, m_LSDItem);
|
||||
setRowColor(2, QColor("grey"));
|
||||
// Set static items alignment
|
||||
m_DHTItem->setTextAlignment(COL_RECEIVED, (Qt::AlignRight | Qt::AlignVCenter));
|
||||
m_PEXItem->setTextAlignment(COL_RECEIVED, (Qt::AlignRight | Qt::AlignVCenter));
|
||||
m_LSDItem->setTextAlignment(COL_RECEIVED, (Qt::AlignRight | Qt::AlignVCenter));
|
||||
m_DHTItem->setTextAlignment(COL_SEEDS, (Qt::AlignRight | Qt::AlignVCenter));
|
||||
m_PEXItem->setTextAlignment(COL_SEEDS, (Qt::AlignRight | Qt::AlignVCenter));
|
||||
m_LSDItem->setTextAlignment(COL_SEEDS, (Qt::AlignRight | Qt::AlignVCenter));
|
||||
m_DHTItem->setTextAlignment(COL_PEERS, (Qt::AlignRight | Qt::AlignVCenter));
|
||||
m_PEXItem->setTextAlignment(COL_PEERS, (Qt::AlignRight | Qt::AlignVCenter));
|
||||
m_LSDItem->setTextAlignment(COL_PEERS, (Qt::AlignRight | Qt::AlignVCenter));
|
||||
m_DHTItem->setTextAlignment(COL_SEEDS, (Qt::AlignRight | Qt::AlignVCenter));
|
||||
m_PEXItem->setTextAlignment(COL_SEEDS, (Qt::AlignRight | Qt::AlignVCenter));
|
||||
m_LSDItem->setTextAlignment(COL_SEEDS, (Qt::AlignRight | Qt::AlignVCenter));
|
||||
m_DHTItem->setTextAlignment(COL_LEECHES, (Qt::AlignRight | Qt::AlignVCenter));
|
||||
m_PEXItem->setTextAlignment(COL_LEECHES, (Qt::AlignRight | Qt::AlignVCenter));
|
||||
m_LSDItem->setTextAlignment(COL_LEECHES, (Qt::AlignRight | Qt::AlignVCenter));
|
||||
m_DHTItem->setTextAlignment(COL_DOWNLOADED, (Qt::AlignRight | Qt::AlignVCenter));
|
||||
m_PEXItem->setTextAlignment(COL_DOWNLOADED, (Qt::AlignRight | Qt::AlignVCenter));
|
||||
m_LSDItem->setTextAlignment(COL_DOWNLOADED, (Qt::AlignRight | Qt::AlignVCenter));
|
||||
// Set header alignment
|
||||
headerItem()->setTextAlignment(COL_TIER, (Qt::AlignRight | Qt::AlignVCenter));
|
||||
headerItem()->setTextAlignment(COL_RECEIVED, (Qt::AlignRight | Qt::AlignVCenter));
|
||||
headerItem()->setTextAlignment(COL_SEEDS, (Qt::AlignRight | Qt::AlignVCenter));
|
||||
headerItem()->setTextAlignment(COL_PEERS, (Qt::AlignRight | Qt::AlignVCenter));
|
||||
headerItem()->setTextAlignment(COL_SEEDS, (Qt::AlignRight | Qt::AlignVCenter));
|
||||
headerItem()->setTextAlignment(COL_LEECHES, (Qt::AlignRight | Qt::AlignVCenter));
|
||||
headerItem()->setTextAlignment(COL_DOWNLOADED, (Qt::AlignRight | Qt::AlignVCenter));
|
||||
// Set hotkeys
|
||||
m_editHotkey = new QShortcut(Qt::Key_F2, this, nullptr, nullptr, Qt::WidgetShortcut);
|
||||
@@ -140,7 +141,7 @@ QList<QTreeWidgetItem*> TrackerListWidget::getSelectedTrackerItems() const
|
||||
{
|
||||
const QList<QTreeWidgetItem *> selectedTrackerItems = selectedItems();
|
||||
QList<QTreeWidgetItem *> selectedTrackers;
|
||||
foreach (QTreeWidgetItem *item, selectedTrackerItems) {
|
||||
for (QTreeWidgetItem *item : selectedTrackerItems) {
|
||||
if (indexOfTopLevelItem(item) >= NB_STICKY_ITEM) // Ignore STICKY ITEMS
|
||||
selectedTrackers << item;
|
||||
}
|
||||
@@ -163,11 +164,11 @@ void TrackerListWidget::moveSelectionUp()
|
||||
clear();
|
||||
return;
|
||||
}
|
||||
QList<QTreeWidgetItem *> selectedTrackerItems = getSelectedTrackerItems();
|
||||
const QList<QTreeWidgetItem *> selectedTrackerItems = getSelectedTrackerItems();
|
||||
if (selectedTrackerItems.isEmpty()) return;
|
||||
|
||||
bool change = false;
|
||||
foreach (QTreeWidgetItem *item, selectedTrackerItems) {
|
||||
for (QTreeWidgetItem *item : selectedTrackerItems) {
|
||||
int index = indexOfTopLevelItem(item);
|
||||
if (index > NB_STICKY_ITEM) {
|
||||
insertTopLevelItem(index - 1, takeTopLevelItem(index));
|
||||
@@ -178,7 +179,7 @@ void TrackerListWidget::moveSelectionUp()
|
||||
|
||||
// Restore selection
|
||||
QItemSelectionModel *selection = selectionModel();
|
||||
foreach (QTreeWidgetItem *item, selectedTrackerItems)
|
||||
for (QTreeWidgetItem *item : selectedTrackerItems)
|
||||
selection->select(indexFromItem(item), (QItemSelectionModel::Rows | QItemSelectionModel::Select));
|
||||
|
||||
setSelectionModel(selection);
|
||||
@@ -204,7 +205,7 @@ void TrackerListWidget::moveSelectionDown()
|
||||
clear();
|
||||
return;
|
||||
}
|
||||
QList<QTreeWidgetItem *> selectedTrackerItems = getSelectedTrackerItems();
|
||||
const QList<QTreeWidgetItem *> selectedTrackerItems = getSelectedTrackerItems();
|
||||
if (selectedTrackerItems.isEmpty()) return;
|
||||
|
||||
bool change = false;
|
||||
@@ -219,7 +220,7 @@ void TrackerListWidget::moveSelectionDown()
|
||||
|
||||
// Restore selection
|
||||
QItemSelectionModel *selection = selectionModel();
|
||||
foreach (QTreeWidgetItem *item, selectedTrackerItems)
|
||||
for (QTreeWidgetItem *item : selectedTrackerItems)
|
||||
selection->select(indexFromItem(item), (QItemSelectionModel::Rows | QItemSelectionModel::Select));
|
||||
|
||||
setSelectionModel(selection);
|
||||
@@ -244,15 +245,15 @@ void TrackerListWidget::clear()
|
||||
m_trackerItems.clear();
|
||||
m_DHTItem->setText(COL_STATUS, "");
|
||||
m_DHTItem->setText(COL_SEEDS, "");
|
||||
m_DHTItem->setText(COL_PEERS, "");
|
||||
m_DHTItem->setText(COL_LEECHES, "");
|
||||
m_DHTItem->setText(COL_MSG, "");
|
||||
m_PEXItem->setText(COL_STATUS, "");
|
||||
m_PEXItem->setText(COL_SEEDS, "");
|
||||
m_PEXItem->setText(COL_PEERS, "");
|
||||
m_PEXItem->setText(COL_LEECHES, "");
|
||||
m_PEXItem->setText(COL_MSG, "");
|
||||
m_LSDItem->setText(COL_STATUS, "");
|
||||
m_LSDItem->setText(COL_SEEDS, "");
|
||||
m_LSDItem->setText(COL_PEERS, "");
|
||||
m_LSDItem->setText(COL_LEECHES, "");
|
||||
m_LSDItem->setText(COL_MSG, "");
|
||||
}
|
||||
|
||||
@@ -289,7 +290,7 @@ void TrackerListWidget::loadStickyItems(BitTorrent::TorrentHandle *const torrent
|
||||
// XXX: libtorrent should provide this info...
|
||||
// Count peers from DHT, PeX, LSD
|
||||
uint seedsDHT = 0, seedsPeX = 0, seedsLSD = 0, peersDHT = 0, peersPeX = 0, peersLSD = 0;
|
||||
foreach (const BitTorrent::PeerInfo &peer, torrent->peers()) {
|
||||
for (const BitTorrent::PeerInfo &peer : asConst(torrent->peers())) {
|
||||
if (peer.isConnecting()) continue;
|
||||
|
||||
if (peer.fromDHT()) {
|
||||
@@ -313,11 +314,11 @@ void TrackerListWidget::loadStickyItems(BitTorrent::TorrentHandle *const torrent
|
||||
}
|
||||
|
||||
m_DHTItem->setText(COL_SEEDS, QString::number(seedsDHT));
|
||||
m_DHTItem->setText(COL_PEERS, QString::number(peersDHT));
|
||||
m_DHTItem->setText(COL_LEECHES, QString::number(peersDHT));
|
||||
m_PEXItem->setText(COL_SEEDS, QString::number(seedsPeX));
|
||||
m_PEXItem->setText(COL_PEERS, QString::number(peersPeX));
|
||||
m_PEXItem->setText(COL_LEECHES, QString::number(peersPeX));
|
||||
m_LSDItem->setText(COL_SEEDS, QString::number(seedsLSD));
|
||||
m_LSDItem->setText(COL_PEERS, QString::number(peersLSD));
|
||||
m_LSDItem->setText(COL_LEECHES, QString::number(peersLSD));
|
||||
}
|
||||
|
||||
void TrackerListWidget::loadTrackers()
|
||||
@@ -331,7 +332,7 @@ void TrackerListWidget::loadTrackers()
|
||||
// Load actual trackers information
|
||||
QHash<QString, BitTorrent::TrackerInfo> trackerData = torrent->trackerInfos();
|
||||
QStringList oldTrackerURLs = m_trackerItems.keys();
|
||||
foreach (const BitTorrent::TrackerEntry &entry, torrent->trackers()) {
|
||||
for (const BitTorrent::TrackerEntry &entry : asConst(torrent->trackers())) {
|
||||
QString trackerURL = entry.url();
|
||||
QTreeWidgetItem *item = m_trackerItems.value(trackerURL, nullptr);
|
||||
if (!item) {
|
||||
@@ -365,25 +366,19 @@ void TrackerListWidget::loadTrackers()
|
||||
break;
|
||||
}
|
||||
|
||||
item->setText(COL_RECEIVED, QString::number(data.numPeers));
|
||||
#if LIBTORRENT_VERSION_NUM >= 10000
|
||||
item->setText(COL_PEERS, QString::number(data.numPeers));
|
||||
item->setText(COL_SEEDS, (entry.nativeEntry().scrape_complete > -1) ? QString::number(entry.nativeEntry().scrape_complete) : tr("N/A"));
|
||||
item->setText(COL_PEERS, (entry.nativeEntry().scrape_incomplete > -1) ? QString::number(entry.nativeEntry().scrape_incomplete) : tr("N/A"));
|
||||
item->setText(COL_LEECHES, (entry.nativeEntry().scrape_incomplete > -1) ? QString::number(entry.nativeEntry().scrape_incomplete) : tr("N/A"));
|
||||
item->setText(COL_DOWNLOADED, (entry.nativeEntry().scrape_downloaded > -1) ? QString::number(entry.nativeEntry().scrape_downloaded) : tr("N/A"));
|
||||
#else
|
||||
item->setText(COL_SEEDS, tr("N/A"));
|
||||
item->setText(COL_PEERS, tr("N/A"));
|
||||
item->setText(COL_DOWNLOADED, tr("N/A"));
|
||||
#endif
|
||||
|
||||
item->setTextAlignment(COL_TIER, (Qt::AlignRight | Qt::AlignVCenter));
|
||||
item->setTextAlignment(COL_RECEIVED, (Qt::AlignRight | Qt::AlignVCenter));
|
||||
item->setTextAlignment(COL_SEEDS, (Qt::AlignRight | Qt::AlignVCenter));
|
||||
item->setTextAlignment(COL_PEERS, (Qt::AlignRight | Qt::AlignVCenter));
|
||||
item->setTextAlignment(COL_SEEDS, (Qt::AlignRight | Qt::AlignVCenter));
|
||||
item->setTextAlignment(COL_LEECHES, (Qt::AlignRight | Qt::AlignVCenter));
|
||||
item->setTextAlignment(COL_DOWNLOADED, (Qt::AlignRight | Qt::AlignVCenter));
|
||||
}
|
||||
// Remove old trackers
|
||||
foreach (const QString &tracker, oldTrackerURLs)
|
||||
for (const QString &tracker : asConst(oldTrackerURLs))
|
||||
delete m_trackerItems.take(tracker);
|
||||
}
|
||||
|
||||
@@ -394,7 +389,7 @@ void TrackerListWidget::askForTrackers()
|
||||
if (!torrent) return;
|
||||
|
||||
QList<BitTorrent::TrackerEntry> trackers;
|
||||
foreach (const QString &tracker, TrackersAdditionDialog::askForTrackers(this, torrent))
|
||||
for (const QString &tracker : asConst(TrackersAdditionDialog::askForTrackers(this, torrent)))
|
||||
trackers << tracker;
|
||||
|
||||
torrent->addTrackers(trackers);
|
||||
@@ -402,11 +397,11 @@ void TrackerListWidget::askForTrackers()
|
||||
|
||||
void TrackerListWidget::copyTrackerUrl()
|
||||
{
|
||||
QList<QTreeWidgetItem *> selectedTrackerItems = getSelectedTrackerItems();
|
||||
const QList<QTreeWidgetItem *> selectedTrackerItems = getSelectedTrackerItems();
|
||||
if (selectedTrackerItems.isEmpty()) return;
|
||||
|
||||
QStringList urlsToCopy;
|
||||
foreach (QTreeWidgetItem *item, selectedTrackerItems) {
|
||||
for (const QTreeWidgetItem *item : selectedTrackerItems) {
|
||||
QString trackerURL = item->data(COL_URL, Qt::DisplayRole).toString();
|
||||
qDebug() << QString("Copy: ") + trackerURL;
|
||||
urlsToCopy << trackerURL;
|
||||
@@ -423,11 +418,11 @@ void TrackerListWidget::deleteSelectedTrackers()
|
||||
return;
|
||||
}
|
||||
|
||||
QList<QTreeWidgetItem *> selectedTrackerItems = getSelectedTrackerItems();
|
||||
const QList<QTreeWidgetItem *> selectedTrackerItems = getSelectedTrackerItems();
|
||||
if (selectedTrackerItems.isEmpty()) return;
|
||||
|
||||
QStringList urlsToRemove;
|
||||
foreach (QTreeWidgetItem *item, selectedTrackerItems) {
|
||||
for (const QTreeWidgetItem *item : selectedTrackerItems) {
|
||||
QString trackerURL = item->data(COL_URL, Qt::DisplayRole).toString();
|
||||
urlsToRemove << trackerURL;
|
||||
m_trackerItems.remove(trackerURL);
|
||||
@@ -436,8 +431,8 @@ void TrackerListWidget::deleteSelectedTrackers()
|
||||
|
||||
// Iterate over the trackers and remove the selected ones
|
||||
QList<BitTorrent::TrackerEntry> remainingTrackers;
|
||||
QList<BitTorrent::TrackerEntry> trackers = torrent->trackers();
|
||||
foreach (const BitTorrent::TrackerEntry &entry, trackers) {
|
||||
const QList<BitTorrent::TrackerEntry> trackers = torrent->trackers();
|
||||
for (const BitTorrent::TrackerEntry &entry : trackers) {
|
||||
if (!urlsToRemove.contains(entry.url()))
|
||||
remainingTrackers.push_back(entry);
|
||||
}
|
||||
@@ -493,7 +488,7 @@ void TrackerListWidget::editSelectedTracker()
|
||||
|
||||
void TrackerListWidget::reannounceSelected()
|
||||
{
|
||||
QList<QTreeWidgetItem *> selItems = selectedItems();
|
||||
const QList<QTreeWidgetItem *> selItems = selectedItems();
|
||||
if (selItems.isEmpty()) return;
|
||||
|
||||
BitTorrent::TorrentHandle *const torrent = m_properties->getCurrentTorrent();
|
||||
@@ -501,7 +496,7 @@ void TrackerListWidget::reannounceSelected()
|
||||
|
||||
QList<BitTorrent::TrackerEntry> trackers = torrent->trackers();
|
||||
|
||||
foreach (QTreeWidgetItem* item, selItems) {
|
||||
for (const QTreeWidgetItem *item : selItems) {
|
||||
// DHT case
|
||||
if (item == m_DHTItem) {
|
||||
torrent->forceDHTAnnounce();
|
||||
@@ -533,9 +528,9 @@ void TrackerListWidget::showTrackerListMenu(QPoint)
|
||||
QAction *delAct = nullptr;
|
||||
QAction *editAct = nullptr;
|
||||
if (!getSelectedTrackerItems().isEmpty()) {
|
||||
editAct = menu.addAction(GuiIconProvider::instance()->getIcon("edit-rename"),tr("Edit tracker URL..."));
|
||||
delAct = menu.addAction(GuiIconProvider::instance()->getIcon("list-remove"), tr("Remove tracker"));
|
||||
copyAct = menu.addAction(GuiIconProvider::instance()->getIcon("edit-copy"), tr("Copy tracker URL"));
|
||||
editAct = menu.addAction(GuiIconProvider::instance()->getIcon("edit-rename"),tr("Edit selected tracker URL"));
|
||||
}
|
||||
QAction *reannounceSelAct = nullptr;
|
||||
QAction *reannounceAllAct = nullptr;
|
||||
@@ -591,9 +586,9 @@ QStringList TrackerListWidget::headerLabels()
|
||||
"#"
|
||||
, tr("URL")
|
||||
, tr("Status")
|
||||
, tr("Received")
|
||||
, tr("Seeds")
|
||||
, tr("Peers")
|
||||
, tr("Seeds")
|
||||
, tr("Leeches")
|
||||
, tr("Downloaded")
|
||||
, tr("Message")
|
||||
};
|
||||
|
||||
@@ -54,9 +54,9 @@ public:
|
||||
COL_TIER,
|
||||
COL_URL,
|
||||
COL_STATUS,
|
||||
COL_RECEIVED,
|
||||
COL_SEEDS,
|
||||
COL_PEERS,
|
||||
COL_SEEDS,
|
||||
COL_LEECHES,
|
||||
COL_DOWNLOADED,
|
||||
COL_MSG,
|
||||
|
||||
|
||||
@@ -34,6 +34,7 @@
|
||||
|
||||
#include "base/bittorrent/torrenthandle.h"
|
||||
#include "base/bittorrent/trackerentry.h"
|
||||
#include "base/global.h"
|
||||
#include "base/net/downloadhandler.h"
|
||||
#include "base/net/downloadmanager.h"
|
||||
#include "base/utils/fs.h"
|
||||
@@ -59,7 +60,7 @@ TrackersAdditionDialog::~TrackersAdditionDialog()
|
||||
QStringList TrackersAdditionDialog::newTrackers() const
|
||||
{
|
||||
QStringList cleanTrackers;
|
||||
foreach (QString url, m_ui->textEditTrackersList->toPlainText().split('\n')) {
|
||||
for (QString url : asConst(m_ui->textEditTrackersList->toPlainText().split('\n'))) {
|
||||
url = url.trimmed();
|
||||
if (!url.isEmpty())
|
||||
cleanTrackers << url;
|
||||
@@ -83,8 +84,8 @@ void TrackersAdditionDialog::parseUTorrentList(const QString &, const QByteArray
|
||||
// Load from torrent handle
|
||||
QList<BitTorrent::TrackerEntry> existingTrackers = m_torrent->trackers();
|
||||
// Load from current user list
|
||||
QStringList tmp = m_ui->textEditTrackersList->toPlainText().split('\n');
|
||||
foreach (const QString &userURL, tmp) {
|
||||
const QStringList tmp = m_ui->textEditTrackersList->toPlainText().split('\n');
|
||||
for (const QString &userURL : tmp) {
|
||||
BitTorrent::TrackerEntry userTracker(userURL);
|
||||
if (!existingTrackers.contains(userTracker))
|
||||
existingTrackers << userTracker;
|
||||
|
||||
@@ -30,6 +30,7 @@
|
||||
|
||||
#include <QListWidgetItem>
|
||||
|
||||
#include "base/global.h"
|
||||
#include "base/rss/rss_article.h"
|
||||
#include "base/rss/rss_item.h"
|
||||
|
||||
@@ -68,7 +69,7 @@ void ArticleListWidget::setRSSItem(RSS::Item *rssItem, bool unreadOnly)
|
||||
connect(m_rssItem, &RSS::Item::articleRead, this, &ArticleListWidget::handleArticleRead);
|
||||
connect(m_rssItem, &RSS::Item::articleAboutToBeRemoved, this, &ArticleListWidget::handleArticleAboutToBeRemoved);
|
||||
|
||||
foreach (auto article, rssItem->articles()) {
|
||||
for (const auto article : asConst(rssItem->articles())) {
|
||||
if (!(m_unreadOnly && article->isRead())) {
|
||||
auto item = createItem(article);
|
||||
addItem(item);
|
||||
|
||||
@@ -41,6 +41,7 @@
|
||||
#include <QString>
|
||||
|
||||
#include "base/bittorrent/session.h"
|
||||
#include "base/global.h"
|
||||
#include "base/preferences.h"
|
||||
#include "base/rss/rss_article.h"
|
||||
#include "base/rss/rss_autodownloader.h"
|
||||
@@ -131,7 +132,7 @@ AutomatedRssDownloader::AutomatedRssDownloader(QWidget *parent)
|
||||
loadFeedList();
|
||||
|
||||
m_ui->listRules->blockSignals(true);
|
||||
foreach (const RSS::AutoDownloadRule &rule, RSS::AutoDownloader::instance()->rules())
|
||||
for (const RSS::AutoDownloadRule &rule : asConst(RSS::AutoDownloader::instance()->rules()))
|
||||
createRuleItem(rule);
|
||||
m_ui->listRules->blockSignals(false);
|
||||
|
||||
@@ -181,7 +182,7 @@ void AutomatedRssDownloader::loadFeedList()
|
||||
{
|
||||
const QSignalBlocker feedListSignalBlocker(m_ui->listFeeds);
|
||||
|
||||
foreach (auto feed, RSS::Session::instance()->feeds()) {
|
||||
for (const auto feed : asConst(RSS::Session::instance()->feeds())) {
|
||||
QListWidgetItem *item = new QListWidgetItem(feed->name(), m_ui->listFeeds);
|
||||
item->setData(Qt::UserRole, feed->url());
|
||||
item->setFlags(item->flags() | Qt::ItemIsUserCheckable | Qt::ItemIsTristate);
|
||||
@@ -211,7 +212,7 @@ void AutomatedRssDownloader::updateFeedList()
|
||||
bool allEnabled = true;
|
||||
bool anyEnabled = false;
|
||||
|
||||
foreach (const QListWidgetItem *ruleItem, selection) {
|
||||
for (const QListWidgetItem *ruleItem : asConst(selection)) {
|
||||
auto rule = RSS::AutoDownloader::instance()->ruleByName(ruleItem->text());
|
||||
if (rule.feedURLs().contains(feedURL))
|
||||
anyEnabled = true;
|
||||
@@ -384,7 +385,7 @@ void AutomatedRssDownloader::on_removeRuleBtn_clicked()
|
||||
if (QMessageBox::question(this, tr("Rule deletion confirmation"), confirmText, QMessageBox::Yes, QMessageBox::No) != QMessageBox::Yes)
|
||||
return;
|
||||
|
||||
foreach (QListWidgetItem *item, selection)
|
||||
for (const QListWidgetItem *item : selection)
|
||||
RSS::AutoDownloader::instance()->removeRule(item->text());
|
||||
}
|
||||
|
||||
@@ -548,7 +549,7 @@ void AutomatedRssDownloader::clearSelectedRuleDownloadedEpisodeList()
|
||||
void AutomatedRssDownloader::handleFeedCheckStateChange(QListWidgetItem *feedItem)
|
||||
{
|
||||
const QString feedURL = feedItem->data(Qt::UserRole).toString();
|
||||
foreach (QListWidgetItem *ruleItem, m_ui->listRules->selectedItems()) {
|
||||
for (QListWidgetItem *ruleItem : asConst(m_ui->listRules->selectedItems())) {
|
||||
RSS::AutoDownloadRule rule = (ruleItem == m_currentRuleItem
|
||||
? m_currentRule
|
||||
: RSS::AutoDownloader::instance()->ruleByName(ruleItem->text()));
|
||||
@@ -572,16 +573,16 @@ void AutomatedRssDownloader::updateMatchingArticles()
|
||||
{
|
||||
m_ui->treeMatchingArticles->clear();
|
||||
|
||||
foreach (const QListWidgetItem *ruleItem, m_ui->listRules->selectedItems()) {
|
||||
for (const QListWidgetItem *ruleItem : asConst(m_ui->listRules->selectedItems())) {
|
||||
RSS::AutoDownloadRule rule = (ruleItem == m_currentRuleItem
|
||||
? m_currentRule
|
||||
: RSS::AutoDownloader::instance()->ruleByName(ruleItem->text()));
|
||||
foreach (const QString &feedURL, rule.feedURLs()) {
|
||||
for (const QString &feedURL : asConst(rule.feedURLs())) {
|
||||
auto feed = RSS::Session::instance()->feedByURL(feedURL);
|
||||
if (!feed) continue; // feed doesn't exist
|
||||
|
||||
QStringList matchingArticles;
|
||||
foreach (auto article, feed->articles())
|
||||
for (const auto article : asConst(feed->articles()))
|
||||
if (rule.matches(article->data()))
|
||||
matchingArticles << article->title();
|
||||
if (!matchingArticles.isEmpty())
|
||||
@@ -620,7 +621,7 @@ void AutomatedRssDownloader::addFeedArticlesToTree(RSS::Feed *feed, const QStrin
|
||||
}
|
||||
|
||||
// Insert the articles
|
||||
foreach (const QString &article, articles) {
|
||||
for (const QString &article : articles) {
|
||||
QPair<QString, QString> key(feed->name(), article);
|
||||
|
||||
if (!m_treeListEntries.contains(key)) {
|
||||
@@ -675,10 +676,10 @@ void AutomatedRssDownloader::updateMustLineValidity()
|
||||
if (isRegex)
|
||||
tokens << text;
|
||||
else
|
||||
foreach (const QString &token, text.split('|'))
|
||||
for (const QString &token : asConst(text.split('|')))
|
||||
tokens << Utils::String::wildcardToRegex(token);
|
||||
|
||||
foreach (const QString &token, tokens) {
|
||||
for (const QString &token : asConst(tokens)) {
|
||||
QRegularExpression reg(token, QRegularExpression::CaseInsensitiveOption);
|
||||
if (!reg.isValid()) {
|
||||
if (isRegex)
|
||||
@@ -713,10 +714,10 @@ void AutomatedRssDownloader::updateMustNotLineValidity()
|
||||
if (isRegex)
|
||||
tokens << text;
|
||||
else
|
||||
foreach (const QString &token, text.split('|'))
|
||||
for (const QString &token : asConst(text.split('|')))
|
||||
tokens << Utils::String::wildcardToRegex(token);
|
||||
|
||||
foreach (const QString &token, tokens) {
|
||||
for (const QString &token : asConst(tokens)) {
|
||||
QRegularExpression reg(token, QRegularExpression::CaseInsensitiveOption);
|
||||
if (!reg.isValid()) {
|
||||
if (isRegex)
|
||||
|
||||
@@ -33,6 +33,7 @@
|
||||
#include <QDropEvent>
|
||||
#include <QTreeWidgetItem>
|
||||
|
||||
#include "base/global.h"
|
||||
#include "base/rss/rss_article.h"
|
||||
#include "base/rss/rss_feed.h"
|
||||
#include "base/rss/rss_folder.h"
|
||||
@@ -219,7 +220,7 @@ void FeedListWidget::dropEvent(QDropEvent *event)
|
||||
: RSS::Session::instance()->rootFolder());
|
||||
|
||||
// move as much items as possible
|
||||
foreach (QTreeWidgetItem *srcItem, selectedItems()) {
|
||||
for (QTreeWidgetItem *srcItem : asConst(selectedItems())) {
|
||||
auto rssItem = getRSSItem(srcItem);
|
||||
RSS::Session::instance()->moveItem(rssItem, RSS::Item::joinPath(destFolder->path(), rssItem->name()));
|
||||
}
|
||||
@@ -264,7 +265,7 @@ QTreeWidgetItem *FeedListWidget::createItem(RSS::Item *rssItem, QTreeWidgetItem
|
||||
|
||||
void FeedListWidget::fill(QTreeWidgetItem *parent, RSS::Folder *rssParent)
|
||||
{
|
||||
foreach (auto rssItem, rssParent->items()) {
|
||||
for (const auto rssItem : asConst(rssParent->items())) {
|
||||
QTreeWidgetItem *item = createItem(rssItem, parent);
|
||||
// Recursive call if this is a folder.
|
||||
if (auto folder = qobject_cast<RSS::Folder *>(rssItem))
|
||||
|
||||
@@ -41,6 +41,7 @@
|
||||
#include <QString>
|
||||
|
||||
#include "base/bittorrent/session.h"
|
||||
#include "base/global.h"
|
||||
#include "base/net/downloadmanager.h"
|
||||
#include "base/preferences.h"
|
||||
#include "base/rss/rss_article.h"
|
||||
@@ -186,7 +187,7 @@ void RSSWidget::displayItemsListMenu(const QPoint &)
|
||||
{
|
||||
bool hasTorrent = false;
|
||||
bool hasLink = false;
|
||||
foreach (const QListWidgetItem *item, m_articleListWidget->selectedItems()) {
|
||||
for (const QListWidgetItem *item : asConst(m_articleListWidget->selectedItems())) {
|
||||
auto article = reinterpret_cast<RSS::Article *>(item->data(Qt::UserRole).value<quintptr>());
|
||||
Q_ASSERT(article);
|
||||
|
||||
@@ -286,7 +287,7 @@ void RSSWidget::on_newFeedButton_clicked()
|
||||
|
||||
void RSSWidget::deleteSelectedItems()
|
||||
{
|
||||
QList<QTreeWidgetItem *> selectedItems = m_feedListWidget->selectedItems();
|
||||
const QList<QTreeWidgetItem *> selectedItems = m_feedListWidget->selectedItems();
|
||||
if (selectedItems.isEmpty())
|
||||
return;
|
||||
if ((selectedItems.size() == 1) && (selectedItems.first() == m_feedListWidget->stickyUnreadItem()))
|
||||
@@ -298,7 +299,7 @@ void RSSWidget::deleteSelectedItems()
|
||||
if (answer == QMessageBox::No)
|
||||
return;
|
||||
|
||||
foreach (QTreeWidgetItem *item, selectedItems)
|
||||
for (QTreeWidgetItem *item : selectedItems)
|
||||
if (item != m_feedListWidget->stickyUnreadItem())
|
||||
RSS::Session::instance()->removeItem(m_feedListWidget->itemPath(item));
|
||||
}
|
||||
@@ -306,9 +307,9 @@ void RSSWidget::deleteSelectedItems()
|
||||
void RSSWidget::loadFoldersOpenState()
|
||||
{
|
||||
const QStringList openedFolders = Preferences::instance()->getRssOpenFolders();
|
||||
foreach (const QString &varPath, openedFolders) {
|
||||
for (const QString &varPath : openedFolders) {
|
||||
QTreeWidgetItem *parent = nullptr;
|
||||
foreach (const QString &name, varPath.split('\\')) {
|
||||
for (const QString &name : asConst(varPath.split('\\'))) {
|
||||
int nbChildren = (parent ? parent->childCount() : m_feedListWidget->topLevelItemCount());
|
||||
for (int i = 0; i < nbChildren; ++i) {
|
||||
QTreeWidgetItem *child = (parent ? parent->child(i) : m_feedListWidget->topLevelItem(i));
|
||||
@@ -325,7 +326,7 @@ void RSSWidget::loadFoldersOpenState()
|
||||
void RSSWidget::saveFoldersOpenState()
|
||||
{
|
||||
QStringList openedFolders;
|
||||
foreach (QTreeWidgetItem *item, m_feedListWidget->getAllOpenedFolders())
|
||||
for (QTreeWidgetItem *item : asConst(m_feedListWidget->getAllOpenedFolders()))
|
||||
openedFolders << m_feedListWidget->itemPath(item);
|
||||
Preferences::instance()->setRssOpenFolders(openedFolders);
|
||||
}
|
||||
@@ -337,7 +338,7 @@ void RSSWidget::refreshAllFeeds()
|
||||
|
||||
void RSSWidget::downloadSelectedTorrents()
|
||||
{
|
||||
foreach (QListWidgetItem *item, m_articleListWidget->selectedItems()) {
|
||||
for (QListWidgetItem *item : asConst(m_articleListWidget->selectedItems())) {
|
||||
auto article = reinterpret_cast<RSS::Article *>(item->data(Qt::UserRole).value<quintptr>());
|
||||
Q_ASSERT(article);
|
||||
|
||||
@@ -356,7 +357,7 @@ void RSSWidget::downloadSelectedTorrents()
|
||||
// open the url of the selected RSS articles in the Web browser
|
||||
void RSSWidget::openSelectedArticlesUrls()
|
||||
{
|
||||
foreach (QListWidgetItem *item, m_articleListWidget->selectedItems()) {
|
||||
for (QListWidgetItem *item : asConst(m_articleListWidget->selectedItems())) {
|
||||
auto article = reinterpret_cast<RSS::Article *>(item->data(Qt::UserRole).value<quintptr>());
|
||||
Q_ASSERT(article);
|
||||
|
||||
@@ -397,7 +398,7 @@ void RSSWidget::renameSelectedRSSItem()
|
||||
|
||||
void RSSWidget::refreshSelectedItems()
|
||||
{
|
||||
foreach (QTreeWidgetItem *item, m_feedListWidget->selectedItems()) {
|
||||
for (QTreeWidgetItem *item : asConst(m_feedListWidget->selectedItems())) {
|
||||
if (item == m_feedListWidget->stickyUnreadItem()) {
|
||||
refreshAllFeeds();
|
||||
return;
|
||||
@@ -410,7 +411,7 @@ void RSSWidget::refreshSelectedItems()
|
||||
void RSSWidget::copySelectedFeedsURL()
|
||||
{
|
||||
QStringList URLs;
|
||||
foreach (QTreeWidgetItem *item, m_feedListWidget->selectedItems()) {
|
||||
for (QTreeWidgetItem *item : asConst(m_feedListWidget->selectedItems())) {
|
||||
if (auto feed = qobject_cast<RSS::Feed *>(m_feedListWidget->getRSSItem(item)))
|
||||
URLs << feed->url();
|
||||
}
|
||||
@@ -425,7 +426,7 @@ void RSSWidget::handleCurrentFeedItemChanged(QTreeWidgetItem *currentItem)
|
||||
|
||||
void RSSWidget::on_markReadButton_clicked()
|
||||
{
|
||||
foreach (QTreeWidgetItem *item, m_feedListWidget->selectedItems()) {
|
||||
for (QTreeWidgetItem *item : asConst(m_feedListWidget->selectedItems())) {
|
||||
m_feedListWidget->getRSSItem(item)->markAsRead();
|
||||
if (item == m_feedListWidget->stickyUnreadItem())
|
||||
break; // all items was read
|
||||
|
||||
@@ -39,6 +39,7 @@
|
||||
#include <QMimeData>
|
||||
#include <QTableView>
|
||||
|
||||
#include "base/global.h"
|
||||
#include "base/net/downloadhandler.h"
|
||||
#include "base/net/downloadmanager.h"
|
||||
#include "base/utils/fs.h"
|
||||
@@ -110,7 +111,7 @@ void PluginSelectDialog::dropEvent(QDropEvent *event)
|
||||
|
||||
QStringList files;
|
||||
if (event->mimeData()->hasUrls()) {
|
||||
foreach (const QUrl &url, event->mimeData()->urls()) {
|
||||
for (const QUrl &url : asConst(event->mimeData()->urls())) {
|
||||
if (!url.isEmpty()) {
|
||||
if (url.scheme().compare("file", Qt::CaseInsensitive) == 0)
|
||||
files << url.toLocalFile();
|
||||
@@ -125,7 +126,7 @@ void PluginSelectDialog::dropEvent(QDropEvent *event)
|
||||
|
||||
if (files.isEmpty()) return;
|
||||
|
||||
foreach (QString file, files) {
|
||||
for (const QString &file : asConst(files)) {
|
||||
qDebug("dropped %s", qUtf8Printable(file));
|
||||
startAsyncOp();
|
||||
m_pluginManager->installPlugin(file);
|
||||
@@ -135,8 +136,7 @@ void PluginSelectDialog::dropEvent(QDropEvent *event)
|
||||
// Decode if we accept drag 'n drop or not
|
||||
void PluginSelectDialog::dragEnterEvent(QDragEnterEvent *event)
|
||||
{
|
||||
QString mime;
|
||||
foreach (mime, event->mimeData()->formats()) {
|
||||
for (const QString &mime : asConst(event->mimeData()->formats())) {
|
||||
qDebug("mimeData: %s", qUtf8Printable(mime));
|
||||
}
|
||||
|
||||
@@ -188,7 +188,7 @@ void PluginSelectDialog::on_closeButton_clicked()
|
||||
void PluginSelectDialog::on_actionUninstall_triggered()
|
||||
{
|
||||
bool error = false;
|
||||
foreach (QTreeWidgetItem *item, m_ui->pluginsTree->selectedItems()) {
|
||||
for (QTreeWidgetItem *item : asConst(m_ui->pluginsTree->selectedItems())) {
|
||||
int index = m_ui->pluginsTree->indexOfTopLevelItem(item);
|
||||
Q_ASSERT(index != -1);
|
||||
QString id = item->text(PLUGIN_ID);
|
||||
@@ -212,7 +212,7 @@ void PluginSelectDialog::on_actionUninstall_triggered()
|
||||
|
||||
void PluginSelectDialog::enableSelection(bool enable)
|
||||
{
|
||||
foreach (QTreeWidgetItem *item, m_ui->pluginsTree->selectedItems()) {
|
||||
for (QTreeWidgetItem *item : asConst(m_ui->pluginsTree->selectedItems())) {
|
||||
int index = m_ui->pluginsTree->indexOfTopLevelItem(item);
|
||||
Q_ASSERT(index != -1);
|
||||
QString id = item->text(PLUGIN_ID);
|
||||
@@ -265,7 +265,7 @@ void PluginSelectDialog::loadSupportedSearchPlugins()
|
||||
{
|
||||
// Some clean up first
|
||||
m_ui->pluginsTree->clear();
|
||||
foreach (QString name, m_pluginManager->allPlugins())
|
||||
for (const QString &name : asConst(m_pluginManager->allPlugins()))
|
||||
addNewPlugin(name);
|
||||
}
|
||||
|
||||
@@ -360,11 +360,11 @@ void PluginSelectDialog::askForPluginUrl()
|
||||
|
||||
void PluginSelectDialog::askForLocalPlugin()
|
||||
{
|
||||
QStringList pathsList = QFileDialog::getOpenFileNames(
|
||||
const QStringList pathsList = QFileDialog::getOpenFileNames(
|
||||
nullptr, tr("Select search plugins"), QDir::homePath(),
|
||||
tr("qBittorrent search plugin") + QLatin1String(" (*.py)")
|
||||
);
|
||||
foreach (QString path, pathsList) {
|
||||
for (const QString &path : pathsList) {
|
||||
startAsyncOp();
|
||||
m_pluginManager->installPlugin(path);
|
||||
}
|
||||
@@ -380,7 +380,7 @@ void PluginSelectDialog::iconDownloaded(const QString &url, QString filePath)
|
||||
QList<QSize> sizes = icon.availableSizes();
|
||||
bool invalid = (sizes.isEmpty() || icon.pixmap(sizes.first()).isNull());
|
||||
if (!invalid) {
|
||||
foreach (QTreeWidgetItem *item, findItemsWithUrl(url)) {
|
||||
for (QTreeWidgetItem *item : asConst(findItemsWithUrl(url))) {
|
||||
QString id = item->text(PLUGIN_ID);
|
||||
PluginInfo *plugin = m_pluginManager->pluginInfo(id);
|
||||
if (!plugin) continue;
|
||||
|
||||
@@ -37,10 +37,6 @@
|
||||
#include "base/utils/misc.h"
|
||||
#include "searchsortmodel.h"
|
||||
|
||||
namespace
|
||||
{
|
||||
const char i18nContext[] = "SearchListDelegate";
|
||||
}
|
||||
|
||||
SearchListDelegate::SearchListDelegate(QObject *parent)
|
||||
: QItemDelegate(parent)
|
||||
@@ -63,7 +59,7 @@ void SearchListDelegate::paint(QPainter *painter, const QStyleOptionViewItem &op
|
||||
case SearchSortModel::LEECHES:
|
||||
opt.displayAlignment = Qt::AlignRight | Qt::AlignVCenter;
|
||||
QItemDelegate::drawDisplay(painter, opt, option.rect
|
||||
, (index.data().toLongLong() >= 0) ? index.data().toString() : QCoreApplication::translate(i18nContext, "Unknown"));
|
||||
, (index.data().toLongLong() >= 0) ? index.data().toString() : tr("Unknown"));
|
||||
break;
|
||||
default:
|
||||
QItemDelegate::paint(painter, option, index);
|
||||
|
||||
@@ -33,6 +33,8 @@
|
||||
|
||||
class SearchListDelegate : public QItemDelegate
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit SearchListDelegate(QObject *parent);
|
||||
|
||||
|
||||
@@ -28,6 +28,8 @@
|
||||
|
||||
#include "searchsortmodel.h"
|
||||
|
||||
#include "base/global.h"
|
||||
|
||||
SearchSortModel::SearchSortModel(QObject *parent)
|
||||
: base(parent)
|
||||
, m_isNameFilterEnabled(false)
|
||||
@@ -126,7 +128,7 @@ bool SearchSortModel::filterAcceptsRow(int sourceRow, const QModelIndex &sourceP
|
||||
const QAbstractItemModel *const sourceModel = this->sourceModel();
|
||||
if (m_isNameFilterEnabled && !m_searchTerm.isEmpty()) {
|
||||
QString name = sourceModel->data(sourceModel->index(sourceRow, NAME, sourceParent)).toString();
|
||||
for (const QString &word: m_searchTermWords) {
|
||||
for (const QString &word : asConst(m_searchTermWords)) {
|
||||
int i = name.indexOf(word, 0, Qt::CaseInsensitive);
|
||||
if (i == -1) {
|
||||
return false;
|
||||
|
||||
@@ -49,6 +49,7 @@
|
||||
#include <QTreeView>
|
||||
|
||||
#include "base/bittorrent/session.h"
|
||||
#include "base/global.h"
|
||||
#include "base/preferences.h"
|
||||
#include "base/search/searchpluginmanager.h"
|
||||
#include "base/search/searchhandler.h"
|
||||
@@ -166,11 +167,11 @@ void SearchWidget::fillCatCombobox()
|
||||
|
||||
using QStrPair = QPair<QString, QString>;
|
||||
QList<QStrPair> tmpList;
|
||||
foreach (const QString &cat, SearchPluginManager::instance()->getPluginCategories(selectedPlugin()))
|
||||
for (const QString &cat : asConst(SearchPluginManager::instance()->getPluginCategories(selectedPlugin())))
|
||||
tmpList << qMakePair(SearchPluginManager::categoryFullName(cat), cat);
|
||||
std::sort(tmpList.begin(), tmpList.end(), [](const QStrPair &l, const QStrPair &r) { return (QString::localeAwareCompare(l.first, r.first) < 0); });
|
||||
|
||||
foreach (const QStrPair &p, tmpList) {
|
||||
for (const QStrPair &p : asConst(tmpList)) {
|
||||
qDebug("Supported category: %s", qUtf8Printable(p.second));
|
||||
m_ui->comboCategory->addItem(p.first, QVariant(p.second));
|
||||
}
|
||||
@@ -188,11 +189,11 @@ void SearchWidget::fillPluginComboBox()
|
||||
|
||||
using QStrPair = QPair<QString, QString>;
|
||||
QList<QStrPair> tmpList;
|
||||
foreach (const QString &name, SearchPluginManager::instance()->enabledPlugins())
|
||||
for (const QString &name : asConst(SearchPluginManager::instance()->enabledPlugins()))
|
||||
tmpList << qMakePair(SearchPluginManager::instance()->pluginFullName(name), name);
|
||||
std::sort(tmpList.begin(), tmpList.end(), [](const QStrPair &l, const QStrPair &r) { return (l.first < r.first); } );
|
||||
|
||||
foreach (const QStrPair &p, tmpList)
|
||||
for (const QStrPair &p : asConst(tmpList))
|
||||
m_ui->selectPlugin->addItem(p.first, QVariant(p.second));
|
||||
|
||||
if (m_ui->selectPlugin->count() > 3)
|
||||
|
||||
@@ -32,6 +32,7 @@
|
||||
#include "base/bittorrent/session.h"
|
||||
#include "base/bittorrent/sessionstatus.h"
|
||||
#include "base/bittorrent/torrenthandle.h"
|
||||
#include "base/global.h"
|
||||
#include "base/utils/misc.h"
|
||||
#include "base/utils/string.h"
|
||||
#include "ui_statsdialog.h"
|
||||
@@ -89,7 +90,7 @@ void StatsDialog::update()
|
||||
|
||||
// num_peers is not reliable (adds up peers, which didn't even overcome tcp handshake)
|
||||
quint32 peers = 0;
|
||||
foreach (BitTorrent::TorrentHandle *const torrent, BitTorrent::Session::instance()->torrents())
|
||||
for (BitTorrent::TorrentHandle *const torrent : asConst(BitTorrent::Session::instance()->torrents()))
|
||||
peers += torrent->peersCount();
|
||||
|
||||
m_ui->labelWriteStarve->setText(QString("%1%")
|
||||
|
||||
@@ -33,6 +33,7 @@
|
||||
|
||||
#include "base/bittorrent/session.h"
|
||||
#include "base/bittorrent/torrenthandle.h"
|
||||
#include "base/global.h"
|
||||
#include "guiiconprovider.h"
|
||||
|
||||
namespace
|
||||
@@ -236,7 +237,7 @@ void TagFilterModel::torrentAdded(BitTorrent::TorrentHandle *const torrent)
|
||||
if (items.isEmpty())
|
||||
untaggedItem()->increaseTorrentsCount();
|
||||
|
||||
foreach (TagModelItem *item, items)
|
||||
for (TagModelItem *item : items)
|
||||
item->increaseTorrentsCount();
|
||||
}
|
||||
|
||||
@@ -247,7 +248,7 @@ void TagFilterModel::torrentAboutToBeRemoved(BitTorrent::TorrentHandle *const to
|
||||
if (torrent->tags().isEmpty())
|
||||
untaggedItem()->decreaseTorrentsCount();
|
||||
|
||||
foreach (TagModelItem *item, findItems(torrent->tags()))
|
||||
for (TagModelItem *item : asConst(findItems(torrent->tags())))
|
||||
item->decreaseTorrentsCount();
|
||||
}
|
||||
|
||||
@@ -274,7 +275,7 @@ void TagFilterModel::populate()
|
||||
[](Torrent *torrent) { return torrent->tags().isEmpty(); });
|
||||
addToModel(getSpecialUntaggedTag(), untaggedCount);
|
||||
|
||||
foreach (const QString &tag, session->tags()) {
|
||||
for (const QString &tag : asConst(session->tags())) {
|
||||
const int count = std::count_if(torrents.begin(), torrents.end(),
|
||||
[tag](Torrent *torrent) { return torrent->hasTag(tag); });
|
||||
addToModel(tag, count);
|
||||
@@ -313,7 +314,7 @@ QVector<TagModelItem *> TagFilterModel::findItems(const QSet<QString> &tags)
|
||||
{
|
||||
QVector<TagModelItem *> items;
|
||||
items.reserve(tags.size());
|
||||
foreach (const QString &tag, tags) {
|
||||
for (const QString &tag : tags) {
|
||||
TagModelItem *item = findItem(tag);
|
||||
if (item)
|
||||
items.push_back(item);
|
||||
|
||||
@@ -35,6 +35,7 @@
|
||||
#include <QMessageBox>
|
||||
|
||||
#include "base/bittorrent/session.h"
|
||||
#include "base/global.h"
|
||||
#include "autoexpandabledialog.h"
|
||||
#include "guiiconprovider.h"
|
||||
#include "tagfiltermodel.h"
|
||||
@@ -222,7 +223,7 @@ void TagFilterWidget::removeTag()
|
||||
void TagFilterWidget::removeUnusedTags()
|
||||
{
|
||||
auto session = BitTorrent::Session::instance();
|
||||
foreach (const QString &tag, session->tags())
|
||||
for (const QString &tag : asConst(session->tags()))
|
||||
if (model()->data(static_cast<TagFilterProxyModel *>(model())->index(tag), Qt::UserRole) == 0)
|
||||
session->removeTag(tag);
|
||||
updateGeometry();
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user