Compare commits

...

108 Commits

Author SHA1 Message Date
sledgehammer999
da0b276d5f Bump to 4.3.3 2021-01-19 00:47:04 +02:00
sledgehammer999
2d73bc9e7d Update Changelog 2021-01-19 00:46:29 +02:00
Chocobo1
fdd54fe568 Simplify code for checking free disk space
`QStorageInfo::bytesAvailable()` is guaranteed to return `-1` for an
invalid path.
https://doc.qt.io/qt-5/qstorageinfo.html#bytesAvailable
2021-01-19 00:45:13 +02:00
Chocobo1
e5ce24e55e Improve detection of file extension string 2021-01-19 00:45:06 +02:00
sledgehammer999
d90349709b Sync translations from Transifex and run lupdate 2021-01-17 23:24:02 +02:00
Vladimir Golovnev (Glassez)
adb0fe6582 WebUI: Correctly represent torrent content structure 2021-01-17 22:50:40 +02:00
Chocobo1
5ed81580c9 Add README.md to searchengine folder 2021-01-17 22:50:39 +02:00
Chocobo1
86d6fb86d7 Unify "github actions" artifacts naming scheme 2021-01-17 22:50:38 +02:00
Chocobo1
ddec247d4f Migrate away from deprecated Qt functions
`QString QDateTime::toString(Qt::DateFormat format = Qt::TextDate)` will
be removed in Qt6.
2021-01-17 22:50:37 +02:00
Chocobo1
d431ecbe00 Disable clang "range loop analysis" compiler warning
See: https://github.com/qbittorrent/qBittorrent/pull/13915#issuecomment-739449084
2021-01-17 22:50:36 +02:00
Chocobo1
be929ed88c Set source character sets to UTF-8
This suppress warning C4819.
https://docs.microsoft.com/en-us/cpp/build/reference/utf-8-set-source-and-executable-character-sets-to-utf-8?view=msvc-160
2021-01-17 22:50:35 +02:00
Chocobo1
2e1f9bf8be Add script for generating project tarball 2021-01-17 22:50:20 +02:00
lbilli
7fff393b0e On Linux use legacy 'data' directory only as a fallback 2021-01-17 22:47:13 +02:00
sledgehammer999
a669ec49ad Correct copyright attribution
These files were created and edited in their entirety in commit 8db4bde15d
As far as I can tell they were almost entirety rewritten from their original state.
The old copyright attribution is restored and the new author is added too.
2021-01-17 22:47:11 +02:00
Vladimir Golovnev (Glassez)
1880082017 Remove redundant suffix from TorrentHandle class
Originally, it was just a wrapper for libtorrent::torrent_handle class, so it mimicked its name.
It was then transformed into a more complex aggregate, but the name was retained (just by inertia).
Unlike libtorrent::torrent_handle class in whose name "handle" means the pattern used,
it does not matter for qBittorrent classes and just eats up space in the source code.
2021-01-17 22:47:00 +02:00
sledgehammer999
0cbd15890a Merge pull request #14170 from sledgehammer999/use_cxx1z
Use c++1z to enable c++17
2021-01-07 13:40:05 +02:00
sledgehammer999
7fe7c6c277 Use c++1z to enable c++17
It increases compatibility with older qt versions.
2021-01-06 21:54:46 +02:00
jagannatharjun
e4c177fec7 Correctly set items flags in TorrentContentModel
Only set editable flag on item's where editing is handled in the delegate

closes #13515
2021-01-06 21:36:40 +02:00
Chocobo1
77f4e6c2cf Generate version header when configuring project
The basic idea is we create a version header template at
"src/base/version.h.in" and the build systems are expected to replace
strings that are enclosed with @ symbols and generate
"src/base/version.h" for other source files to consume/include.
2021-01-06 21:36:39 +02:00
sledgehammer999
4563b11a2e Bump copyright year 2021-01-06 21:36:37 +02:00
Vladimir Golovnev (Glassez)
cb477f9a29 QMake: Raise minimal macOS target version 2021-01-06 21:36:35 +02:00
Vladimir Golovnev (Glassez)
58ac07667e Use single parameter to accept torrent source 2021-01-06 21:36:34 +02:00
Vladimir Golovnev (Glassez)
74bf3af41c Use std::optional<bool> instead of custom TriStateBool 2021-01-06 21:36:33 +02:00
Vladimir Golovnev (Glassez)
9317071122 Change parseBool() to return optional bool value 2021-01-06 21:36:31 +02:00
Vladimir Golovnev (Glassez)
dab32f2090 Use std::optional instead of boost::optional 2021-01-06 21:36:29 +02:00
Vladimir Golovnev (Glassez)
dc464d4d41 Use nested namespaces definition syntax 2021-01-06 21:36:28 +02:00
Chocobo1
e7e3f6a9db Don't use deprecated locale name 2021-01-06 21:36:27 +02:00
Chocobo1
5a1c4e79b3 Revise store/load state operations of Options Dialog 2021-01-06 21:36:26 +02:00
Chocobo1
c6d9ab6810 Remember dialog sizes
This applies to "About Dialog", "Ban List Options Dialog", "Download From URL Dialog", "IP Subnet
Whitelist Options Dialog", "Search Plugin Select Dialog", "Search Plugin Source Dialog",
"Statistics Dialog", "Speed Limit Dialog" and "Torrent Options Dialog".

Also unifies storing the dialog size under the key "Size".
2021-01-06 21:36:24 +02:00
Chocobo1
d7afad835e Revise SettingsStorage store/load value interface 2021-01-06 21:36:22 +02:00
Chocobo1
8608d7b9da Improve load data behavior of SettingsStorage class
Previously it only handle the case of failed lookup, now it discard
invalid values when deserializing the database from disk.
Also checks whether the data is convertible to the intended type.
2021-01-06 21:36:22 +02:00
Vladimir Golovnev (Glassez)
72970602af Reload "missing files" torrent instead of re-checking 2021-01-06 21:36:20 +02:00
Vladimir Golovnev (Glassez)
86579ca87d Extract torrent reloading logic into separate method 2021-01-06 21:36:19 +02:00
Vladimir Golovnev (Glassez)
e55582124c Drop notification about move storage failed 2021-01-06 21:36:17 +02:00
Vladimir Golovnev (Glassez)
bd8b06c607 Drop notification about move storage finished 2021-01-06 21:36:16 +02:00
Chocobo1
230fedf069 Move parsing of TriStateBool to a static class function 2021-01-06 21:36:14 +02:00
thalieht
7bea10f507 Update "Keep top-level folder" in WebUI options 2021-01-06 21:36:13 +02:00
Chocobo1
7cde969b90 Exclude configure script for "trailing newlines" checking 2021-01-06 21:36:12 +02:00
Chocobo1
a3b8f6880b Migrate away from deprecated AC_OUTPUT macro
The `AC_OUTPUT` has two versions, the deprecated one takes arguments and the other not. Check the
following link for equivalent replacement:
https://www.gnu.org/savannah-checkouts/gnu/autoconf/manual/autoconf-2.70/html_node/Obsolete-Macros.html#Obsolete-Macros

Also regenerate the configure script with the latest Autoconf 2.70.
2021-01-06 21:35:33 +02:00
Chocobo1
ad79fc8d43 Migrate away from deprecated std::iterator class 2021-01-06 21:31:51 +02:00
Chocobo1
fb4bf94a56 Use function-pointer based signal-slot connection 2021-01-06 21:31:50 +02:00
Chocobo1
1c184944fd Remove unused define 2021-01-06 21:31:49 +02:00
Chocobo1
ec420f6617 Bump project requirement to C++17 2021-01-06 21:31:47 +02:00
Chocobo1
d908227619 Add a thin layer around SettingsStorage class
This new layer would be handy for saving GUI widget states as they don't
need the value cached and they store/load rarely.
2021-01-06 21:31:45 +02:00
sledgehammer999
ac8167410b Add new languages
* Azerbaijani
* Estonian
2021-01-06 21:31:44 +02:00
Vladimir Golovnev (Glassez)
26ce187b30 Don't call non-existent elements
Fixed a regression where the script tries to access elements that no longer
exist on the page, because they were replaced with others by a previous change.
2021-01-06 21:31:43 +02:00
Vladimir Golovnev (Glassez)
2c4e04e537 Don't call non-existent elements
Fixed a regression where the script tries to access elements that no longer
exist on the page, because they were replaced with others by a previous change.
2021-01-06 21:31:42 +02:00
Vladimir Golovnev (Glassez)
b418f65c2f Improve content file/folder names handling
Move files/folders renaming functions to core classes.
Query file/folder for renaming by its current path.
Add ability to rename content folders from WebAPI/WebUI.
2021-01-06 21:31:41 +02:00
Vladimir Golovnev (Glassez)
dd3a8d5d56 Fix folder name extraction functions
It should return empty string if there is no parent folder.
2021-01-06 21:31:39 +02:00
Chocobo1
49e54a55df Capitalize locale names 2021-01-06 21:31:38 +02:00
thalieht
8cd0a7ae85 Group several torrent options into one dialog
Speed limits, share limits and the new options to disable DHT, PeX, LSD per torrent
2021-01-06 21:31:36 +02:00
thalieht
442f0df613 Save fastresume when setting torrent speed limits 2021-01-06 21:31:35 +02:00
thalieht
f9ee5bdb59 Increase maximum global speed limits from ~1 GiB/s to ~2 GiB/s
Closer to the INT_MAX limit of ~2 Billion when multiplied by 1024 for libtorrent
2021-01-06 21:31:33 +02:00
thalieht
b9602cc6ab Convert existing speed dialog to global + alt global limits only 2021-01-06 21:31:25 +02:00
sledgehammer999
abb854a1e6 Bump to 4.3.2 2020-12-27 13:42:41 +02:00
sledgehammer999
4ee17a73d0 Update Changelog 2020-12-27 13:42:40 +02:00
sledgehammer999
faf6e82274 Sync translations from Transifex and run lupdate 2020-12-26 21:18:40 +02:00
Vladimir Golovnev (Glassez)
c08ec1ac5e Allow to add root folder to torrent content 2020-12-26 20:27:34 +02:00
Vladimir Golovnev (Glassez)
cd0b6d9a43 Extract enum serialization/parsing functions 2020-12-26 20:27:33 +02:00
Vladimir Golovnev (Glassez)
b8f1142abe Improve torrent name handling 2020-12-26 20:27:31 +02:00
Chocobo1
78859415d6 Use a helper function to look up stat indexes 2020-12-26 20:27:29 +02:00
Chocobo1
ef92c17192 Don't use removed stat metric in libtorrent 2.0
For now, the metric is not entirely removed due to WebAPI still needs to
access it.
2020-12-26 20:27:28 +02:00
Chocobo1
22f3abc4b5 Initialize stat indices to -1
When the index is initialized it will be set to a number >= 0, so we use
-1 to denote its uninitialized status.
2020-12-26 20:27:27 +02:00
Chocobo1
a56e6294c1 Fix wrong JSON type returned
Fix up 78638a15be.
Closes #14041.
2020-12-26 20:27:26 +02:00
Chocobo1
77909e0093 Don't use default CFLAGS, CXXFLAGS from autotools
Before this commit, autotools will inject `-g -O2` to debug build
(`--enable-debug=yes`) and rendering the result binary useless. This
commit fixes it.
https://www.gnu.org/savannah-checkouts/gnu/autoconf/manual/autoconf-2.70/html_node/C_002b_002b-Compiler.html

Closes #14032.
2020-12-26 20:27:25 +02:00
Vladimir Golovnev (Glassez)
2c2bb14b2a Fix bug of "move storage job" can be performed multiple times 2020-12-26 20:27:16 +02:00
Chocobo1
73c8b77464 Migrate away from deprecated QVariant comparison operators
Fortunately, serializing to JSON limits the data types to a very small
subset and thus we are able to implement the comparison without much
hassle.

Fix up cba8d83b21.
2020-12-26 20:27:14 +02:00
Alessandro Simonelli
042238db87 NSIS: Fixed italian.nsi after 4.3.0.1 update
Merged my previous fixes (discussed in #13607) with the suggestions by @glassez (#13615).
2020-12-26 20:27:13 +02:00
FranciscoPombal
6e267f8e81 Update coding guidelines policy for include guards 2020-12-26 20:27:11 +02:00
FranciscoPombal
fdc64d9b38 Use #pragma once instead of include guards 2020-12-26 20:27:10 +02:00
Chocobo1
0b42425db5 Add support for allow_idna option
Upstream PR: https://github.com/arvidn/libtorrent/pull/5316
2020-12-26 20:27:08 +02:00
Chocobo1
e5d7738127 Update "HTTPS tracker validation" enablement conditional
https://github.com/arvidn/libtorrent/pull/5313
2020-12-26 20:27:06 +02:00
Chocobo1
422489e2a1 Revise Utils::Version comparison operators 2020-12-26 20:27:04 +02:00
Chocobo1
7de983b4e5 Add operator< for InfoHash class 2020-12-26 20:27:03 +02:00
Chocobo1
e4e55d2a80 Migrate away from deprecated QVariant comparison operators
Another idea would be manually define a custom comparison function for
QVariant. However, having the function would be excessive due to its
limited usage count, also note that we are already casting
various QVariant to its underlying type in existing code.
2020-12-26 20:27:01 +02:00
Vladimir Golovnev (Glassez)
926012ce71 Fix bug of torrents don't save "stopped" state 2020-12-26 20:27:00 +02:00
Chocobo1
487eb554c9 Fix coding style 2020-12-26 20:26:59 +02:00
Chocobo1
5a96e1fc7a Use Qt provided forward declaration header 2020-12-26 20:26:58 +02:00
FranciscoPombal
2fe698ee60 CMake: detect required header for STACKTRACE feature
musl does not provide execinfo.h, so our current stacktrace-related
code cannot be used with it.
2020-12-26 20:26:57 +02:00
Chocobo1
177ac32a5e Use the correct type when referring to info hash 2020-12-26 20:26:55 +02:00
Vladimir Golovnev (Glassez)
5f34d1555b Fix received metadata handling 2020-12-26 20:26:54 +02:00
FranciscoPombal
7cfe68f46c Bump dependency versions in CI
- Bump vcpkg version in GitHub Actions CI
- Bump libtorrent version in Travis CI

Co-authored-by: Vladimir Golovnev <glassez@yandex.ru>
2020-12-26 20:26:53 +02:00
Vladimir Golovnev
f94f4d2391 Drop support for building with libtorrent < 1.2.11
Co-authored-by: Vladimir Golovnev <glassez@yandex.ru>
2020-12-26 20:26:52 +02:00
FranciscoPombal
73b18d7ef3 Update minimum depedency versions 2020-12-26 20:26:51 +02:00
FranciscoPombal
817e9c4747 Fix method invocation on Qt < 5.10
Fixup 0c3fe54b0b
2020-12-26 20:26:48 +02:00
Vladimir Golovnev (Glassez)
28844eff44 Search for existing files in separate thread 2020-12-26 20:26:47 +02:00
Vladimir Golovnev (Glassez)
389664213b Don't rewrite TorrentInfo instance if it's valid 2020-12-26 20:26:46 +02:00
Vladimir Golovnev (Glassez)
953b6fd6f8 Properly handle "Append extension" option changing 2020-12-26 20:26:45 +02:00
Vladimir Golovnev (Glassez)
9b4f3fcbf8 Clean up metadata downloading code 2020-12-26 20:26:43 +02:00
Chocobo1
80743180be Remove unnecessary restriction on input length
Closes #13884.
2020-12-26 20:26:42 +02:00
Chocobo1
b2847b2381 Update URL to libtorrent settings 2020-12-26 20:26:41 +02:00
Chocobo1
eb657ec032 Move "embedded tracker" options to qbt section 2020-12-26 20:26:39 +02:00
Chocobo1
fc2be601df Add links to libtorrent documentation 2020-12-26 20:26:38 +02:00
Chocobo1
5786c7ff11 Lift upper limit of "Max concurrent HTTP announces" option
Closes #13800.
2020-12-26 20:26:37 +02:00
Jesse Chan
4a183dd968 WebAPI: bump version to 2.6.2 2020-12-26 20:26:36 +02:00
Jesse Chan
7c10dba10c WebAPI: allow to attach tags while adding torrents 2020-12-26 20:26:35 +02:00
sledgehammer999
894446d308 Don't try to remove folders for a torrent without metadata 2020-12-26 20:26:34 +02:00
sledgehammer999
47e9c5ac08 Fix status of torrents without metadata 2020-12-26 20:26:33 +02:00
Chocobo1
7f47ac11f1 Add libtorrent 2.0 to TravisCI script
Also bumping to ubuntu focal as libtorrent requires boost >= 1.66.
2020-12-26 20:26:32 +02:00
Chocobo1
67b17891fa Simplify the calculation of speed graph scale 2020-12-26 20:26:31 +02:00
Chocobo1
dd5b7ba05b Avoid potential rounding to integer issues 2020-12-26 20:26:30 +02:00
Chocobo1
61aa4d9f1c Fix coding style 2020-12-26 20:26:29 +02:00
Chocobo1
6e924b668e Fix availability value
Closes #13869.
Fix up 02f19bfbee.
2020-12-26 20:26:27 +02:00
FranciscoPombal
618ce33fa0 Detect .ts file issues with file health workflow
Also adjust newlines to improve output
2020-12-26 20:26:26 +02:00
Chocobo1
ac413c76b9 Update to use latest macOS image for TravisCI
The default version is so outdated that it needs to rebuild many
dependencies. Now we bump it to the latest version so that it can use
prebuilt packages.
2020-12-26 20:26:25 +02:00
Chocobo1
f266184514 Add ability to use 'shift+delete' to delete torrents in WebUI
Closes #13827.
2020-12-26 20:26:24 +02:00
Chocobo1
8c48bf4a70 Fix wrong data used for comparison
In torrent transfer list we should use underlying data for sorting, not
displayed values.

Closes #13818.
2020-12-26 20:26:23 +02:00
Andrei Stepanov
8bee69c9fc NSIS: Update Russian translation 2020-12-26 20:26:14 +02:00
407 changed files with 112698 additions and 79046 deletions

View File

@@ -12,12 +12,12 @@ on:
branches: [ master ]
env:
# Qt: 5.15.0
# libtorrent: RC_1_2 HEAD, 1.2.10
VCPKG_COMMIT: 32eccc18191fbb57b159784a1724d2d00613ae82
# Qt: 5.15.1
# libtorrent: RC_1_2 HEAD, 1.2.11
VCPKG_COMMIT: 133051b793486ef14e67e9d1f48c9cfe64dc127e
VCPKG_DEST_MACOS: /Users/runner/qbt_tools/vcpkg
VCPKG_DEST_WIN: C:\qbt_tools\vcpkg
LIBTORRENT_VERSION_TAG: libtorrent-1.2.10
LIBTORRENT_VERSION_TAG: v1.2.11
jobs:
@@ -72,7 +72,7 @@ jobs:
- name: upload artifact as zip
uses: actions/upload-artifact@v2
with:
name: qBittorrent-CI-Ubuntu_${{ matrix.os }}-${{ matrix.qbt_gui }}
name: qBittorrent-CI_${{ matrix.os }}-x64_${{ matrix.qbt_gui }}
path: |
build/compile_commands.json
build/target_graph.dot
@@ -151,7 +151,7 @@ jobs:
- name: upload artifact as zip
uses: actions/upload-artifact@v2
with:
name: qBittorrent-CI-Windows_x64-static-release
name: qBittorrent-CI_Windows-x64
path: |
build/compile_commands.json
build/target_graph.dot
@@ -178,11 +178,11 @@ jobs:
uses: actions/checkout@v2
# - ninja is needed for building qBittorrent (because it's preferrable, not a hard requirement)
# - pkg-config is needed for some vcpkg installations
# - automake is needed for the installation the vcpkg installation of fontconfig, a dependency of qt5-base
- name: install additional required packages with homebrew
shell: bash
run: |
brew install ninja pkg-config
brew install automake ninja
- name: setup vcpkg (cached, if possible)
uses: lukka/run-vcpkg@v4
@@ -197,13 +197,13 @@ jobs:
Copy-Item ${{ env.RUNVCPKG_VCPKG_ROOT }}/triplets/x64-osx.cmake `
${{ github.workspace }}/triplets_overlay/x64-osx-release.cmake
Add-Content ${{ github.workspace }}/triplets_overlay/x64-osx-release.cmake `
-Value "set(VCPKG_BUILD_TYPE release)"
-Value "set(VCPKG_BUILD_TYPE release)","set(VCPKG_OSX_DEPLOYMENT_TARGET 10.15)"
# NOTE: Avoids a libtorrent ABI issue. See https://github.com/arvidn/libtorrent/issues/4965
- name: force AppleClang to compile libtorrent with C++14
- name: force AppleClang to compile libtorrent with C++17
run: |
(Get-Content -path ${{ env.RUNVCPKG_VCPKG_ROOT }}/ports/libtorrent/portfile.cmake).Replace( `
'${FEATURE_OPTIONS}', '${FEATURE_OPTIONS} -DCMAKE_CXX_STANDARD=14') `
'${FEATURE_OPTIONS}', '${FEATURE_OPTIONS} -DCMAKE_CXX_STANDARD=17') `
| Set-Content -Path ${{ env.RUNVCPKG_VCPKG_ROOT }}/ports/libtorrent/portfile.cmake
- name: install dependencies via vcpkg
@@ -236,7 +236,7 @@ jobs:
- name: upload artifact as zip
uses: actions/upload-artifact@v2
with:
name: qBittorrent-CI-macOS_x64-static-release_${{ matrix.qbt_gui }}
name: qBittorrent-CI_macOS_${{ matrix.qbt_gui }}
path: |
build/compile_commands.json
build/target_graph.dot

View File

@@ -12,62 +12,72 @@ regressions=0
exclusions_nonutf8='(.*(7z|gif|ic(ns|o)|png|qm|zip))'
exclusions_bom='src/base/unicodestrings.h'
exclusions_tw='(*.ts)|src/webui/www/private/scripts/lib/mootools-1.2-more.js'
exclusions_trailing_newline='configure'
exclusions_no_lf='(*.ts)|(.*svg)|compile_commands.json|src/webui/www/private/scripts/lib/mootools-1.2-(core-yc.js|more.js)'
echo -e "*** Detect files not encoded in UTF-8 ***\n"
echo -e "\n*** Detect files not encoded in UTF-8 ***\n"
find . -path ./build -prune -false -o -path ./.git -prune -false -o -type f -exec file --mime {} \; | sort \
| grep -v -e "charset=us-ascii" -e "charset=utf-8" | cut -d ":" -f 1 \
| grep -E -v -e "${exclusions_nonutf8}" \
| tee >(echo -e "\n--> Files not encoded in UTF-8: found" "$(wc -l < /dev/stdin)" "regression(s)") \
| tee >(echo -e "--> Files not encoded in UTF-8: found" "$(wc -l < /dev/stdin)" "regression(s)\n") \
| xargs -I my_input -0 bash -c 'echo "my_input"; test "$(echo -n "my_input" | wc -l)" -eq 0'
regressions=$((regressions+$?))
echo -e "*** Detect files encoded in UTF-8 with BOM ***\n"
echo -e "\n*** Detect files encoded in UTF-8 with BOM ***\n"
grep --exclude-dir={.git,build} -rIl $'\xEF\xBB\xBF' | sort \
| grep -E -v -e "${exclusions_bom}" \
| tee >(echo -e "\n--> Files encoded in UTF-8 with BOM: found" "$(wc -l < /dev/stdin)" "regression(s)") \
| tee >(echo -e "--> Files encoded in UTF-8 with BOM: found" "$(wc -l < /dev/stdin)" "regression(s)\n") \
| xargs -I my_input -0 bash -c 'echo "my_input"; test "$(echo -n "my_input" | wc -l)" -eq 0'
regressions=$((regressions+$?))
echo -e "*** Detect usage of CR byte ***\n"
echo -e "\n*** Detect usage of CR byte ***\n"
grep --exclude-dir={.git,build} -rIlU $'\x0D' | sort \
| tee >(echo -e "\n--> Usage of CR byte: found" "$(wc -l < /dev/stdin)" "regression(s)") \
| tee >(echo -e "--> Usage of CR byte: found" "$(wc -l < /dev/stdin)" "regression(s)\n") \
| xargs -I my_input -0 bash -c 'echo "my_input"; test "$(echo -n "my_input" | wc -l)" -eq 0'
regressions=$((regressions+$?))
echo -e "*** Detect trailing whitespace in lines ***\n"
echo -e "\n*** Detect trailing whitespace in lines ***\n"
grep --exclude-dir={.git,build} -rIl "[[:blank:]]$" | sort \
| grep -E -v -e "${exclusions_tw}" \
| tee >(echo -e "\n--> Trailing whitespace in lines: found" "$(wc -l < /dev/stdin)" "regression(s)") \
| tee >(echo -e "--> Trailing whitespace in lines: found" "$(wc -l < /dev/stdin)" "regression(s)\n") \
| xargs -I my_input -0 bash -c 'echo "my_input"; test "$(echo -n "my_input" | wc -l)" -eq 0';
regressions=$((regressions+$?))
echo -e "*** Detect too many trailing newlines ***\n"
echo -e "\n*** Detect too many trailing newlines ***\n"
find . -path ./build -prune -false -o -path ./.git -prune -false -o -type f -exec file --mime {} \; | sort \
| grep -e "charset=us-ascii" -e "charset=utf-8" | cut -d ":" -f 1 \
| grep -E -v -e "${exclusions_trailing_newline}" \
| xargs -L1 -I my_input bash -c 'test "$(tail -q -c2 "my_input" | hexdump -C | grep "0a 0a")" && echo "my_input"' \
| tee >(echo -e "\n--> Too many trailing newlines: found" "$(wc -l < /dev/stdin)" "regression(s)") \
| tee >(echo -e "--> Too many trailing newlines: found" "$(wc -l < /dev/stdin)" "regression(s)\n") \
| xargs -I my_input -0 bash -c 'echo "my_input"; test "$(echo -n "my_input" | wc -l)" -eq 0'
regressions=$((regressions+$?))
echo -e "*** Detect no trailing newline ***\n"
echo -e "\n*** Detect no trailing newline ***\n"
find . -path ./build -prune -false -o -path ./.git -prune -false -o -type f -exec file --mime {} \; | sort \
| grep -e "charset=us-ascii" -e "charset=utf-8" | cut -d ":" -f 1 \
| grep -E -v -e "${exclusions_no_lf}" \
| xargs -L1 -I my_input bash -c 'test "$(tail -q -c1 "my_input" | hexdump -C | grep "0a")" || echo "my_input"' \
| tee >(echo -e "\n--> No trailing newline: found" "$(wc -l < /dev/stdin)" "regression(s)") \
| tee >(echo -e "--> No trailing newline: found" "$(wc -l < /dev/stdin)" "regression(s)\n") \
| xargs -I my_input -0 bash -c 'echo "my_input"; test "$(echo -n "my_input" | wc -l)" -eq 0'
regressions=$((regressions+$?))
echo -e "\n*** Detect translation closing tag in new line ***\n"
grep --exclude-dir={.git,build} -nri "^</translation>" | sort \
| cut -d ":" -f 1,2 \
| tee >(echo -e "--> Translation closing tag in new line: found" "$(wc -l < /dev/stdin)" "regression(s)\n") \
| xargs -I my_input -0 bash -c 'echo "my_input"; test "$(echo -n "my_input" | wc -l)" -eq 0'
regressions=$((regressions+$?))
if [ "$regressions" -ne 0 ]; then
regressions=1
echo "File health regressions found. Please fix them (or add them as exclusions)."
echo "\nFile health regressions found. Please fix them (or add them as exclusions)."
else
echo "All OK, no file health regressions found."
fi

View File

@@ -11,7 +11,7 @@ jobs:
check_file_health:
name: Check file health
runs-on: ubuntu-latest
runs-on: ubuntu-20.04
steps:
- name: checkout repository

1
.gitignore vendored
View File

@@ -4,6 +4,7 @@ src/qbittorrent
src/qbittorrent-nox
src/release
src/debug
src/base/version.h
CMakeLists.txt.user*
qbittorrent.pro.user*
conf.pri

View File

@@ -4,7 +4,8 @@ os:
- linux
- osx
dist: bionic
dist: focal
osx_image: xcode12.2
env:
matrix:
@@ -16,6 +17,11 @@ env:
- secure: "OI9CUjj4lTb0HwwIZU5PbECU3hLlAL6KC8KsbwohG8/O3j5fLcnmDsK4Ad9us5cC39sS11Jcd1kDP2qRcCuST/glVNhLkcjKkiQerOfd5nQ/qL4JYfz/1mfP5mdpz9jHKzpLUIG+TXkbSTjP6VVmsb5KPT+3pKEdRFZB+Pu9+J8="
- coverity_branch: coverity_scan
jobs:
include:
- env: libt_branch=RC_2_0 gui=true build_system=qmake
os: linux
notifications:
email:
on_success: change
@@ -39,8 +45,7 @@ addons:
apt:
sources:
# sources list: https://github.com/travis-ci/apt-source-safelist/blob/master/ubuntu.json
- sourceline: 'ppa:qbittorrent-team/qbt-libtorrent-travisci'
- sourceline: 'deb https://apt.kitware.com/ubuntu/ bionic main'
- sourceline: 'deb https://apt.kitware.com/ubuntu/ focal main'
key_url: 'https://apt.kitware.com/keys/kitware-archive-latest.asc'
packages:
# packages list: https://github.com/travis-ci/apt-package-safelist/blob/master/ubuntu-trusty
@@ -69,6 +74,8 @@ before_install:
# TravisCI installs its own cmake to another location which ovverides other installations
# if they don't call the new binary directly
alias cmake="/usr/bin/cmake"
export LD_LIBRARY_PATH="$LD_LIBRARY_PATH:/usr/local/lib"
fi
- |
if [ "$TRAVIS_OS_NAME" = "osx" ]; then
@@ -114,20 +121,34 @@ install:
ccache -V && ccache --show-stats && ccache --zero-stats
fi
- |
if [ "$libt_branch" = "RC_1_2" ] && [ "$TRAVIS_OS_NAME" = "linux" ]; then
# Will install latest 1.2.x daily build from the PPA
sudo apt-get -y install libtorrent-rasterbar-dev
fi
- |
if [ "$libt_branch" = "RC_1_2" ] && [ "$TRAVIS_OS_NAME" = "osx" ]; then
# building libtorrent manually should be faster than using the official bottle
# because the bottle will also pull in a lot of updated dependencies and prolong the overall time
if [ "$libt_branch" = "RC_1_2" ]; then
pushd "$HOME"
git clone --single-branch --branch RC_1_2 https://github.com/arvidn/libtorrent.git
cd libtorrent
git checkout tags/v1.2.10
git checkout tags/v1.2.11
cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_CXX_STANDARD=14 -Ddeprecated-functions=OFF -DOPENSSL_ROOT_DIR="$openssl_root_path" ./
cmake \
-DCMAKE_BUILD_TYPE=Release \
-DCMAKE_CXX_STANDARD=17 \
-Ddeprecated-functions=OFF \
-DOPENSSL_ROOT_DIR="$openssl_root_path" \
./
make
sudo make install
popd
elif [ "$libt_branch" = "RC_2_0" ]; then
pushd "$HOME"
git clone --single-branch --branch RC_2_0 https://github.com/arvidn/libtorrent.git
cd libtorrent
git checkout tags/v2.0.1
git submodule update --init --recursive
cmake \
-DCMAKE_BUILD_TYPE=Release \
-DCMAKE_CXX_STANDARD=17 \
-Ddeprecated-functions=ON \
-DOPENSSL_ROOT_DIR="$openssl_root_path" \
./
make
sudo make install
popd

View File

@@ -3,7 +3,6 @@ cmake_minimum_required(VERSION 3.16 FATAL_ERROR) # Policies <= CMP0097 default t
list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake/Modules)
project(qBittorrent
VERSION 4.3.1.0
DESCRIPTION "The qBittorrent BitTorrent client"
HOMEPAGE_URL "https://www.qbittorrent.org/"
LANGUAGES CXX
@@ -11,14 +10,15 @@ project(qBittorrent
# use CONFIG mode first in find_package
set(CMAKE_FIND_PACKAGE_PREFER_CONFIG ON)
# version requirements
set(requiredBoostVersion 1.40)
set(requiredQtVersion 5.9.0)
set(requiredOpenSSLVersion 1.0)
set(requiredLibtorrentVersion 1.2.0)
set(requiredZlibVersion 1.2.5.2)
# version requirements - older vesions may work, but you are on your own
set(minBoostVersion 1.65)
set(minQtVersion 5.9.5)
set(minOpenSSLVersion 1.1.1)
set(minLibtorrentVersion 1.2.11)
set(minZlibVersion 1.2.11)
# features (some are platform-specific)
include(CheckCXXSourceCompiles) # TODO: migrate to CheckSourceCompiles in CMake >= 3.19
include(FeatureSummary)
include(FeatureOptionsSetup)
feature_option(STACKTRACE "Enable stacktraces" ON)
@@ -34,12 +34,22 @@ if (CMAKE_SYSTEM_NAME STREQUAL "Linux")
"Install systemd service file to a directory manually overridable with Systemd_SERVICES_INSTALL_DIR"
OFF "NOT GUI" OFF
)
if (STACKTRACE)
check_cxx_source_compiles(
"#include <execinfo.h>
int main(){return 0;}"
QBITTORRENT_HAS_EXECINFO_H
)
if (NOT QBITTORRENT_HAS_EXECINFO_H)
message(FATAL_ERROR "execinfo.h header file not found.\n"
"Please either disable the STACKTRACE feature or use a libc that has this header file, such as glibc (GNU libc)."
)
endif()
endif()
elseif (MSVC)
feature_option(MSVC_RUNTIME_DYNAMIC "Use MSVC dynamic runtime library (-MD) instead of static (-MT)" ON)
endif()
set(QBT_VER_STATUS "alpha1" CACHE STRING "Project status version. Should be empty for release builds.")
include(GNUInstallDirs)
add_subdirectory(src)
add_subdirectory(dist)
@@ -49,3 +59,7 @@ if (VERBOSE_CONFIGURE)
else()
feature_summary(WHAT ENABLED_FEATURES DISABLED_FEATURES)
endif()
# Generate version header
file(READ "src/base/version.h.in" versionHeader)
file(WRITE "src/base/version.h" "${versionHeader}")

View File

@@ -372,7 +372,7 @@ Example:
## 8. Include guard
`#pragma once` should be used instead of "include guard" in new code:
`#pragma once` must be used instead of a "classic include guard":
```c++
// examplewidget.h

View File

@@ -1,3 +1,43 @@
Tue Jan 19 2021 - sledgehammer999 <sledgehammer999@qbittorrent.org> - v4.3.3
- FEATURE: New languages: Azerbaijani, Estonian
- BUGFIX: Unify global speed dialogs for normal/alternative speeds (thalieht)
- BUGFIX: Increase maximum global speed limits ~2 GiB/s (thalieht)
- BUGFIX: Save fastresume when setting torrent speed limits (thalieht)
- BUGFIX: Group several torrent options into one dialog (thalieht)
- BUGFIX: Capitalize locale names (Chocobo1)
- BUGFIX: Improve content file/folder names handling (glassez)
- BUGFIX: Drop notification about move storage finished or failed (glassez)
- BUGFIX: Reload "missing files" torrent instead of re-checking (glassez)
- BUGFIX: Remember dialog sizes (Chocobo1)
- BUGFIX: Improve detection of file extension string (Chocobo1)
- WEBUI: Don't call non-existent elements (glassez)
- WEBUI: Update "Keep top-level folder" in WebUI options (thalieht)
- MACOS: QMake: Raise minimal macOS target version to 10.14 (glassez)
- LINUX: Use legacy 'data' directory only as a fallback (lbilli)
- OTHER: Bump project requirement to C++17 (Chocobo1)
Sun Dec 27 2020 - sledgehammer999 <sledgehammer999@qbittorrent.org> - v4.3.2
- FEATURE: Allow to add root folder to torrent content (glassez)
- FEATURE: "HTTPS tracker validation" option is available on all platforms with latest libtorrent (Chocobo1)
- FEATURE: Option for supporting internationalized domain names (IDNs) (Chocobo1)
- BUGFIX: Fix broken sorting on some columns (Chocobo1)
- BUGFIX: Fix availability per file value (Chocobo1)
- BUGFIX: Fix status of torrents without metadata (sledgehammer999)
- BUGFIX: Don't try to remove folders for a torrent without metadata (sledgehammer999)
- BUGFIX: Lift upper limit of "Max concurrent HTTP announces" option (Chocobo1)
- BUGFIX: Add links to libtorrent documentation (Chocobo1)
- BUGFIX: Move "embedded tracker" options to qbt section (Chocobo1)
- BUGFIX: Properly handle "Append extension" option changing (glassez)
- BUGFIX: Correctly save paused torrent state (glassez)
- BUGFIX: Fix bug of "move storage job" can be performed multiple times (glassez)
- WEBUI: Add ability to use 'shift+delete' to delete torrents (Chocobo1)
- WEBUI: Allow to attach tags while adding torrents (Jesse Chan)
- WEBUI: Bump version to 2.6.2 (Jesse Chan)
- WEBUI: Remove unnecessary restriction on input length (Chocobo1)
- WINDOWS: NSIS: Update Russian translation (Andrei Stepanov)
- WINDOWS: NSIS: Update Italian translation (Alessandro Simonelli)
- OTHER: Drop support for building with libtorrent < 1.2.11 (Vladimir Golovnev)
Wed Nov 25 2020 - sledgehammer999 <sledgehammer999@qbittorrent.org> - v4.3.1
- FEATURE: Allow progress bar styling from custom themes (jagannatharjun)
- FEATURE: Allow adding torrents using "Paste" key sequence (Chocobo1)

16
INSTALL
View File

@@ -3,23 +3,27 @@ qBittorrent - A BitTorrent client in C++ / Qt
1) Install these dependencies:
- Boost >= 1.40
- Boost >= 1.65
- libtorrent-rasterbar >= 1.2 (by Arvid Norberg)
- libtorrent-rasterbar >= 1.2.11 (by Arvid Norberg)
* https://www.libtorrent.org/
* Be careful: another library (the one used by rTorrent) uses a similar name
- OpenSSL >= 1.0
- OpenSSL >= 1.1.1
- Qt >= 5.9.0
- Qt >= 5.9.5
- zlib >= 1.2.5.2
- zlib >= 1.2.11
- pkg-config (compile-time only)
- pkg-config (compile-time only on *nix systems)
- Python >= 3.5.0 (optional, runtime only)
* Required by the internal search engine
Dependency version numbers are bumped every once in a while to keep the range of properly tested configurations manageable, even if not strictly required to build.
You may be able to build with older versions of (some of) the dependencies other than the minimum versions specified in the build scripts, but support for such builds is not provided - you are on your own.
Please ensure you are building with an officially supported configuration when reporting bugs.
2a) Compile and install qBittorrent with Qt graphical interface
$ ./configure

19
build_dist.sh Executable file
View File

@@ -0,0 +1,19 @@
#!/bin/sh
# get version numbers
versionSrc="src/base/version.h.in"
versionMajor="$(grep -Po '(?<=QBT_VERSION_MAJOR )\d+' "$versionSrc")"
versionMinor="$(grep -Po '(?<=QBT_VERSION_MINOR )\d+' "$versionSrc")"
versionBugfix="$(grep -Po '(?<=QBT_VERSION_BUGFIX )\d+' "$versionSrc")"
versionBuild="$(grep -Po '(?<=QBT_VERSION_BUILD )\d+' "$versionSrc")"
versionStatus="$(grep -Po '(?<=QBT_VERSION_STATUS ")\w+' "$versionSrc")"
if [ "$versionBuild" != "0" ]; then
projectVersion="$versionMajor.$versionMinor.$versionBugfix.$versionBuild$versionStatus"
else
projectVersion="$versionMajor.$versionMinor.$versionBugfix$versionStatus"
fi
# pack archives
git archive --format=tar --prefix="qbittorrent-$projectVersion/" HEAD | gzip -9 > "qbittorrent-$projectVersion.tar.gz"
git archive --format=tar --prefix="qbittorrent-$projectVersion/" HEAD | xz -9 > "qbittorrent-$projectVersion.tar.xz"

View File

@@ -7,47 +7,16 @@ macro(qbt_common_config)
# treat value specified by the CXX_STANDARD target property as a requirement by default
set(CMAKE_CXX_STANDARD_REQUIRED ON)
# these definitions are only needed for calls to
# lt::generate_fingerprint and for the qbittorrent.rc file on Windows
add_library(qbt_version_definitions INTERFACE)
target_compile_definitions(qbt_version_definitions INTERFACE
QBT_VERSION_MAJOR=${qBittorrent_VERSION_MAJOR}
QBT_VERSION_MINOR=${qBittorrent_VERSION_MINOR}
QBT_VERSION_BUGFIX=${qBittorrent_VERSION_PATCH}
QBT_VERSION_BUILD=${qBittorrent_VERSION_TWEAK}
)
add_library(qbt_common_cfg INTERFACE)
# Full C++ 14 support is required
# Full C++ 17 support is required
# See also https://cmake.org/cmake/help/latest/prop_gbl/CMAKE_CXX_KNOWN_FEATURES.html
# for a breakdown of the features that CMake recognizes for each C++ standard
target_compile_features(qbt_common_cfg INTERFACE
cxx_std_14
cxx_aggregate_default_initializers
cxx_attribute_deprecated
cxx_binary_literals
cxx_contextual_conversions
cxx_decltype_auto
cxx_digit_separators
cxx_generic_lambdas
cxx_lambda_init_captures
cxx_relaxed_constexpr
cxx_return_type_deduction
cxx_variable_templates
cxx_std_17
)
set(QBT_PROJECT_VERSION "${qBittorrent_VERSION_MAJOR}.${qBittorrent_VERSION_MINOR}.${qBittorrent_VERSION_PATCH}")
if (NOT ${qBittorrent_VERSION_TWEAK} EQUAL 0)
set(QBT_PROJECT_VERSION "${QBT_PROJECT_VERSION}.${qBittorrent_VERSION_TWEAK}")
endif()
set(QBT_FULL_VERSION "${QBT_PROJECT_VERSION}${QBT_VER_STATUS}")
target_compile_definitions(qbt_common_cfg INTERFACE
QBT_VERSION="v${QBT_FULL_VERSION}"
QBT_VERSION_2="${QBT_FULL_VERSION}"
QT_DEPRECATED_WARNINGS
QT_NO_CAST_TO_ASCII
QT_NO_CAST_FROM_BYTEARRAY
@@ -90,6 +59,12 @@ macro(qbt_common_config)
endif()
endif()
if ((CXX_COMPILER_ID STREQUAL "Clang") OR (CXX_COMPILER_ID STREQUAL "AppleClang"))
target_compile_options(qbt_common_cfg INTERFACE
-Wno-range-loop-analysis
)
endif()
if (MINGW)
target_link_options(qbt_common_cfg INTERFACE $<$<OR:$<CONFIG:Debug>,$<CONFIG:RelWithDebInfo>>:LINKER:--dynamicbase>)
endif()
@@ -101,8 +76,12 @@ macro(qbt_common_config)
endif()
if (MSVC)
target_compile_options(qbt_common_cfg INTERFACE /guard:cf)
target_link_options(qbt_common_cfg INTERFACE /guard:cf
target_compile_options(qbt_common_cfg INTERFACE
/guard:cf
/utf-8
)
target_link_options(qbt_common_cfg INTERFACE
/guard:cf
$<$<NOT:$<CONFIG:Debug>>:/OPT:REF /OPT:ICF>
# suppress linking warning due to /INCREMENTAL and /OPT:ICF being both ON
$<$<CONFIG:RelWithDebInfo>:/INCREMENTAL:NO>

4958
configure vendored

File diff suppressed because it is too large Load Diff

View File

@@ -1,6 +1,8 @@
AC_INIT([qbittorrent], [v4.3.1], [bugs.qbittorrent.org], [], [https://www.qbittorrent.org/])
AC_INIT([qbittorrent], [v4.3.3], [bugs.qbittorrent.org], [], [https://www.qbittorrent.org/])
AC_CONFIG_AUX_DIR([build-aux])
AC_CONFIG_MACRO_DIR([m4])
: ${CFLAGS=""}
: ${CXXFLAGS=""}
AC_PROG_CC
AC_PROG_CXX
AC_PROG_SED
@@ -157,7 +159,7 @@ AS_CASE(["x$enable_qt_dbus"],
AC_MSG_ERROR([Unknown option "$enable_qt_dbus". Use either "yes" or "no".])])
AX_BOOST_BASE([1.40],
AX_BOOST_BASE([1.65],
[AC_MSG_NOTICE([Boost CXXFLAGS: "$BOOST_CPPFLAGS"])
AC_MSG_NOTICE([Boost LDFLAGS: "$BOOST_LDFLAGS"])],
[AC_MSG_ERROR([Could not find Boost])])
@@ -178,48 +180,48 @@ AC_MSG_NOTICE([Boost.System LIB: "$BOOST_SYSTEM_LIB"])
LIBS="$BOOST_SYSTEM_LIB $LIBS"
PKG_CHECK_MODULES(libtorrent,
[libtorrent-rasterbar >= 1.2],
[libtorrent-rasterbar >= 1.2.11],
[CXXFLAGS="$libtorrent_CFLAGS $CXXFLAGS"
LIBS="$libtorrent_LIBS $LIBS"])
PKG_CHECK_MODULES(openssl,
[openssl >= 1.0],
[openssl >= 1.1.1],
[CXXFLAGS="$openssl_CFLAGS $CXXFLAGS"
LIBS="$openssl_LIBS $LIBS"])
PKG_CHECK_MODULES(zlib,
[zlib >= 1.2.5.2],
[zlib >= 1.2.11],
[CXXFLAGS="$zlib_CFLAGS $CXXFLAGS"
LIBS="$zlib_LIBS $LIBS"])
# Check if already in >= C++14 mode because of the flags returned by one of the above packages
# Check if already in >= C++17 mode because of the flags returned by one of the above packages
TMP_CXXFLAGS="$CXXFLAGS"
CXXFLAGS=""
AC_MSG_CHECKING([if compiler defaults to C++14 or later mode])
AC_COMPILE_IFELSE([DETECT_CPP14_PROGRAM()],
AC_MSG_CHECKING([if compiler defaults to C++17 or later mode])
AC_COMPILE_IFELSE([DETECT_CPP17_PROGRAM()],
[AC_MSG_RESULT([yes])
QBT_CXX14_FOUND="yes"],
QBT_CXX17_FOUND="yes"],
[AC_MSG_RESULT([no])
QBT_CXX14_FOUND="no"])
QBT_CXX17_FOUND="no"])
# In case of no, check if the compiler can support at least C++14
# In case of no, check if the compiler can support at least C++17
# and if yes, enable it leaving a warning to the user
AS_IF([test "x$QBT_CXX14_FOUND" = "xno"],
[AC_MSG_CHECKING([if compiler supports C++14])
CXXFLAGS="-std=c++14"
AC_COMPILE_IFELSE([DETECT_CPP14_PROGRAM()],
AS_IF([test "x$QBT_CXX17_FOUND" = "xno"],
[AC_MSG_CHECKING([if compiler supports C++17])
CXXFLAGS="-std=c++17"
AC_COMPILE_IFELSE([DETECT_CPP17_PROGRAM()],
[AC_MSG_RESULT([yes])
AC_MSG_CHECKING([if C++14 is disabled by the set compiler flags])
AC_MSG_CHECKING([if C++17 is disabled by the set compiler flags])
# prepend the flag so it won't override conflicting user defined flags
CXXFLAGS="-std=c++14 $TMP_CXXFLAGS"
AC_COMPILE_IFELSE([DETECT_CPP14_PROGRAM()],
CXXFLAGS="-std=c++17 $TMP_CXXFLAGS"
AC_COMPILE_IFELSE([DETECT_CPP17_PROGRAM()],
[AC_MSG_RESULT([no])
QBT_ADD_CONFIG="$QBT_ADD_CONFIG c++14"
AC_MSG_WARN([C++14 mode is now force enabled. The C++ mode should match the mode that other libraries were built with, otherwise you'll likely get linking errors.])],
QBT_ADD_CONFIG="$QBT_ADD_CONFIG c++1z"
AC_MSG_WARN([C++17 mode is now force enabled. The C++ mode should match the mode that other libraries were built with, otherwise you'll likely get linking errors.])],
[AC_MSG_RESULT([yes])
AC_MSG_ERROR([The compiler supports C++14 but the user or a dependency has explicitly enabled a lower mode.])])],
AC_MSG_ERROR([The compiler supports C++17 but the user or a dependency has explicitly enabled a lower mode.])])],
[AC_MSG_RESULT([no])
AC_MSG_ERROR([A compiler supporting C++14 is required.])])
AC_MSG_ERROR([A compiler supporting C++17 is required.])])
])
CXXFLAGS="$TMP_CXXFLAGS"
@@ -270,9 +272,13 @@ AC_SUBST(QBT_REMOVE_CONFIG)
AC_SUBST(QBT_ADD_DEFINES)
AC_SUBST(QBT_REMOVE_DEFINES)
AC_OUTPUT(conf.pri)
QBT_CONFIG_FILES="conf.pri"
AS_IF([test "x$enable_systemd" = "xyes"],
[AC_OUTPUT(dist/unix/systemd/qbittorrent-nox@.service)])
[QBT_CONFIG_FILES="$QBT_CONFIG_FILES dist/unix/systemd/qbittorrent-nox@.service"])
AC_CONFIG_FILES(["$QBT_CONFIG_FILES"])
AC_OUTPUT
AC_MSG_NOTICE([Running qmake to generate the makefile...])
TOPDIR="$(cd "$(dirname "$0")" && pwd)"

4
dist/mac/Info.plist vendored
View File

@@ -55,7 +55,7 @@
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>4.3.0</string>
<string>4.3.3</string>
<key>CFBundleExecutable</key>
<string>@EXECUTABLE@</string>
<key>CFBundleIdentifier</key>
@@ -67,7 +67,7 @@
<key>NSAppleScriptEnabled</key>
<string>YES</string>
<key>NSHumanReadableCopyright</key>
<string>Copyright © 2006-2020 The qBittorrent project</string>
<string>Copyright © 2006-2021 The qBittorrent project</string>
<key>UTExportedTypeDeclarations</key>
<array>
<dict>

View File

@@ -74,6 +74,6 @@
<url type="translate">https://github.com/qbittorrent/qBittorrent/wiki/How-to-translate-qBittorrent</url>
<content_rating type="oars-1.1"/>
<releases>
<release version="4.3.1" date="2020-11-25"/>
<release version="4.3.3" date="2021-01-19"/>
</releases>
</component>

View File

@@ -11,6 +11,11 @@ Type=Application
StartupNotify=false
StartupWMClass=qbittorrent
Keywords=bittorrent;torrent;magnet;download;p2p;
# Translations
# Translations
Comment[oc]=Telecargar e partejar de fichièrs amb BitTorrent
GenericName[oc]=Client BitTorrent
Name[oc]=qBittorrent
@@ -53,6 +58,9 @@ Name[en_GB]=qBittorrent
Comment[es]=Descargue y comparta archivos por BitTorrent
GenericName[es]=Cliente BitTorrent
Name[es]=qBittorrent
Comment[et]=Lae alla ja jaga faile üle BitTorrenti
GenericName[et]=BitTorrent klient
Name[et]=qBittorrent
Comment[eu]=Jeitsi eta elkarbanatu agiriak BitTorrent bidez
GenericName[eu]=BitTorrent bezeroa
Name[eu]=qBittorrent
@@ -80,13 +88,16 @@ Name[hr]=qBittorrent
Comment[hu]=Fájlok letöltése és megosztása a BitTorrent hálózaton keresztül
GenericName[hu]=BitTorrent kliens
Name[hu]=qBittorrent
Comment[hy]=Նիշքերի փոխանցում BitTorrent-ի միջոցով
GenericName[hy]=BitTorrent սպասառու
Name[hy]=qBittorrent
Comment[id]=Unduh dan berbagi berkas melalui BitTorrent
GenericName[id]=Klien BitTorrent
Name[id]=qBittorrent
Comment[is]=Sækja og deila skrám yfir BitTorrent
GenericName[is]=BitTorrent biðlarar
Name[is]=qBittorrent
Comment[it]=Client BitTorrent per il download di file via internet
Comment[it]=Scarica e condividi file tramite BitTorrent
GenericName[it]=Client BitTorrent
Name[it]=qBittorrent
Comment[ja]=BitTorrent でファイルをダウンロードおよび共有します
@@ -95,8 +106,8 @@ Name[ja]=qBittorrent
Comment[ka]=ჩამოტვირთე და გააზიარე ფაილები Bittorrent-ის საშუალებით
GenericName[ka]=BitTorrent კლიენტი
Name[ka]=qBittorrent
Comment[ko]=비트토트를 통해 파일을 받고 공유합니다
GenericName[ko]=비트토트 클라이언트
Comment[ko]=비트토트를 통해 파일을 받고 공유합니다
GenericName[ko]=비트토트 클라이언트
Name[ko]=qBittorrent
Comment[zh]=通过 BitTorrent 下载和分享文件
GenericName[zh]=BitTorrent 客户端
@@ -137,6 +148,7 @@ Name[sk]=qBittorrent
Comment[sl]=Prenesite in delite datoteke preko BitTorrenta
GenericName[sl]=BitTorrent odjemalec
Name[sl]=qBittorrent
Comment[sr]=Преузимајте и делите фајлове преко BitTorrent протокола
GenericName[sr]=BitTorrent-клијент
Comment[sr@latin]=Preuzimanje i deljenje fajlova preko BitTorrent-a
GenericName[sr@latin]=BitTorrent klijent
@@ -150,8 +162,8 @@ Name[uz@Latn]=qBittorrent
Comment[ltg]=Atsasyuteit i daleit failus ar BitTorrent
GenericName[ltg]=BitTorrent klients
Name[ltg]=qBittorrent
Comment[hi_IN]= अपनी फाइलें BitTorrent के माध्यम से डाउनलोड आैर साॅझा करें
GenericName[hi_IN]=BitTorrent उपभोक्ता
Comment[hi_IN]=BitTorrent द्वारा फाइल डाउनलोड व सहभाजन
GenericName[hi_IN]=BitTorrent साधन
Name[hi_IN]=qBittorrent
Comment[tr]=Dosyaları BitTorrent üzerinden indirin ve paylaşın
GenericName[tr]=BitTorrent istemcisi
@@ -165,6 +177,9 @@ Name[uk]=qBittorrent
Comment[vi]=Tải về và chia sẻ các tập tin thông qua BitTorrent
GenericName[vi]=Máy trạm dạng BitTorrent
Name[vi]=qBittorrent
Comment[az@latin]=Faylları BitTorrent vasitəsilə göndərin və paylaşın
GenericName[az@latin]=BitTorrent client
Name[az@latin]=qBittorrent
Comment[zh_HK]=經由BitTorrent下載並分享檔案
GenericName[zh_HK]=BitTorrent用戶端
Name[zh_HK]=qBittorrent
@@ -180,8 +195,8 @@ Name[ms_MY]=qBittorrent
Comment[eo]=Elŝutu kaj kunhavigu dosierojn per BitTorrent
GenericName[eo]=BitTorrent-kliento
Name[eo]=qBittorrent
Comment[mn_MN]=BitTorrent ашиглан файлуудыг татаж түгээх
GenericName[mn_MN]=BitTorrent үйлчлүүлэгч
Comment[mn_MN]=BitTorrent-оор файлуудаа тат, түгээ
GenericName[mn_MN]=BitTorrent татагч
Name[mn_MN]=qBittorrent
Comment[ta]=BitTorrent வழியாக கோப்புகளை பதிவிறக்க மற்றும் பகிர
GenericName[ta]=BitTorrent வாடிக்கையாளர்
@@ -195,6 +210,6 @@ Name[te]=క్యు బిట్ టొరెంట్
Comment[en_AU]=Download and share files over BitTorrent
GenericName[en_AU]=BitTorrent client
Name[en_AU]=qBittorrent
Comment[th]=ดาวนโหลดและแชร์ไฟล์ด้วยบิททอเร้น
Comment[th]=ดาวนโหลดและแชร์ไฟล์ด้วยบิททอเร้น
GenericName[th]=โปรแกรมบิททอเร้น
Name[th]=qBittorrent

View File

@@ -3,9 +3,9 @@
;LangString inst_qbt_req ${LANG_ENGLISH} "qBittorrent (required)"
LangString inst_qbt_req ${LANG_ITALIAN} "qBittorrent (necessario)"
;LangString inst_dekstop ${LANG_ENGLISH} "Create Desktop Shortcut"
LangString inst_dekstop ${LANG_ITALIAN} "Crea icone sul desktop"
LangString inst_dekstop ${LANG_ITALIAN} "Crea collegamento sul Desktop"
;LangString inst_startmenu ${LANG_ENGLISH} "Create Start Menu Shortcut"
LangString inst_startmenu ${LANG_ITALIAN} "Crea gruppo programmi"
LangString inst_startmenu ${LANG_ITALIAN} "Aggiungi al menu Start"
;LangString inst_startup ${LANG_ENGLISH} "Start qBittorrent on Windows start up"
LangString inst_startup ${LANG_ITALIAN} "Esegui qBittorrent all'avvio di Windows"
;LangString inst_torrent ${LANG_ENGLISH} "Open .torrent files with qBittorrent"
@@ -15,19 +15,19 @@ LangString inst_magnet ${LANG_ITALIAN} "Apri collegamenti magnet con qBittorrent
;LangString inst_firewall ${LANG_ENGLISH} "Add Windows Firewall rule"
LangString inst_firewall ${LANG_ITALIAN} "Aggiungi regola al firewall di Windows"
;LangString inst_pathlimit ${LANG_ENGLISH} "Disable Windows path length limit (260 character MAX_PATH limitation, requires Windows 10 1607 or later)"
LangString inst_pathlimit ${LANG_ITALIAN} "Disabilita limite percorso Windows (limite MAX_PATH max 260 caratterin, richiede Windows 10 versione 1607 o successive)"
LangString inst_pathlimit ${LANG_ITALIAN} "Disabilita limite lunghezza percorsi Windows (limite MAX_PATH di 260 caratteri, richiede Windows 10 versione 1607 o successive)"
;LangString inst_firewallinfo ${LANG_ENGLISH} "Adding Windows Firewall rule"
LangString inst_firewallinfo ${LANG_ITALIAN} "Aggiunta regola al firewall di Windows"
;LangString inst_warning ${LANG_ENGLISH} "qBittorrent is running. Please close the application before installing."
LangString inst_warning ${LANG_ITALIAN} "qBittorrent è in esecuzione.%n%nChiudi l'applicazione qBittorrent prima della nuova installazione."
LangString inst_warning ${LANG_ITALIAN} "qBittorrent è in esecuzione. Chiudilo prima di procedere con l'installazione."
;LangString inst_uninstall_question ${LANG_ENGLISH} "Current version will be uninstalled. User settings and torrents will remain intact."
LangString inst_uninstall_question ${LANG_ITALIAN} "L'attuale versione di qBittorrent verrà disinstallata.%n%nLe impostazioni utente e i torrent rimanno invariati."
LangString inst_uninstall_question ${LANG_ITALIAN} "La versione attuale verrà disinstallata. Le impostazioni utente e i torrent rimarranno invariati."
;LangString inst_unist ${LANG_ENGLISH} "Uninstalling previous version."
LangString inst_unist ${LANG_ITALIAN} "Disinstallazione versione precedente di qBittorrent."
LangString inst_unist ${LANG_ITALIAN} "Disinstallazione versione precedente."
;LangString launch_qbt ${LANG_ENGLISH} "Launch qBittorrent."
LangString launch_qbt ${LANG_ITALIAN} "Esegui qBittorrent"
LangString launch_qbt ${LANG_ITALIAN} "Esegui qBittorrent."
;LangString inst_requires_64bit ${LANG_ENGLISH} "This installer works only in 64-bit Windows versions."
LangString inst_requires_64bit ${LANG_ITALIAN} "Questo installer di qBittorrent funziona solo con Windows a 64bit."
LangString inst_requires_64bit ${LANG_ITALIAN} "Questo installer funziona solo con versioni di Windows a 64bit."
;LangString inst_requires_win7 ${LANG_ENGLISH} "This qBittorrent version requires at least Windows 7."
LangString inst_requires_win7 ${LANG_ITALIAN} "Questa versione di qBittorrent richiede Windows 7 o versioni successive."
@@ -42,7 +42,7 @@ LangString remove_shortcuts ${LANG_ITALIAN} "Rimuovi collegamenti"
;LangString remove_associations ${LANG_ENGLISH} "Remove file associations"
LangString remove_associations ${LANG_ITALIAN} "Rimuovi associazione file"
;LangString remove_registry ${LANG_ENGLISH} "Remove registry keys"
LangString remove_registry ${LANG_ITALIAN} "Rimuovi chiavi registro"
LangString remove_registry ${LANG_ITALIAN} "Rimuovi chiavi di registro"
;LangString remove_conf ${LANG_ENGLISH} "Remove configuration files"
LangString remove_conf ${LANG_ITALIAN} "Rimuovi file di configurazione"
;LangString remove_firewall ${LANG_ENGLISH} "Remove Windows Firewall rule"
@@ -52,7 +52,7 @@ LangString remove_firewallinfo ${LANG_ITALIAN} "Rimozione regola dal firewall di
;LangString remove_cache ${LANG_ENGLISH} "Remove torrents and cached data"
LangString remove_cache ${LANG_ITALIAN} "Rimuovi torrent e dati nella cache"
;LangString uninst_warning ${LANG_ENGLISH} "qBittorrent is running. Please close the application before uninstalling."
LangString uninst_warning ${LANG_ITALIAN} "qBittorrent è in esecuzione.%n%nChiudi qBittorrent prima della disinstallazione."
LangString uninst_warning ${LANG_ITALIAN} "qBittorrent è in esecuzione. Chiudilo prima di procedere con la disinstallazione."
;LangString uninst_tor_warn ${LANG_ENGLISH} "Not removing .torrent association. It is associated with:"
LangString uninst_tor_warn ${LANG_ITALIAN} "Associazione file .torrent non rimossa. File associati con:"
;LangString uninst_mag_warn ${LANG_ENGLISH} "Not removing magnet association. It is associated with:"

View File

@@ -21,7 +21,7 @@ LangString inst_firewallinfo ${LANG_RUSSIAN} "Добавление в списо
;LangString inst_warning ${LANG_ENGLISH} "qBittorrent is running. Please close the application before installing."
LangString inst_warning ${LANG_RUSSIAN} "qBittorrent запущен. Пожалуйста, закройте qBittorrent и перезапустите программу установки."
;LangString inst_uninstall_question ${LANG_ENGLISH} "Current version will be uninstalled. User settings and torrents will remain intact."
LangString inst_uninstall_question ${LANG_RUSSIAN} "Обнаружена предыдущая установка. Она будет деинсталлирована без удаления пользовательских настроек."
LangString inst_uninstall_question ${LANG_RUSSIAN} "Текущая версия будет деинсталлирована. Пользовательские настройки и торренты останутся нетронутыми."
;LangString inst_unist ${LANG_ENGLISH} "Uninstalling previous version."
LangString inst_unist ${LANG_RUSSIAN} "Деинсталлируется старая версия."
;LangString launch_qbt ${LANG_ENGLISH} "Launch qBittorrent."

View File

@@ -28,7 +28,7 @@ XPStyle on
!define CSIDL_LOCALAPPDATA '0x1C' ;Local Application Data path
; Program specific
!define PROG_VERSION "4.3.1"
!define PROG_VERSION "4.3.3"
!define MUI_FINISHPAGE_RUN
!define MUI_FINISHPAGE_RUN_FUNCTION PageFinishRun
@@ -51,7 +51,7 @@ XPStyle on
;Installer Version Information
VIAddVersionKey "ProductName" "qBittorrent"
VIAddVersionKey "CompanyName" "The qBittorrent project"
VIAddVersionKey "LegalCopyright" "Copyright ©2006-2020 The qBittorrent project"
VIAddVersionKey "LegalCopyright" "Copyright ©2006-2021 The qBittorrent project"
VIAddVersionKey "FileDescription" "qBittorrent - A Bittorrent Client"
VIAddVersionKey "FileVersion" "${PROG_VERSION}"

View File

@@ -5,9 +5,9 @@
# Sets the QT_QMAKE variable to the path of Qt5 qmake if found.
# --------------------------------------
AC_DEFUN([FIND_QT5],
[PKG_CHECK_EXISTS([Qt5Core >= 5.9.0],
[PKG_CHECK_EXISTS([Qt5Core >= 5.9.5],
[PKG_CHECK_VAR(QT_QMAKE,
[Qt5Core >= 5.9.0],
[Qt5Core >= 5.9.5],
[host_bins])
])
@@ -18,7 +18,7 @@ AS_IF([test -f "$QT_QMAKE/qmake"],
[QT_QMAKE=""])
])
AC_MSG_CHECKING([for Qt5 qmake >= 5.9.0])
AC_MSG_CHECKING([for Qt5 qmake >= 5.9.5])
AS_IF([test "x$QT_QMAKE" != "x"],
[AC_MSG_RESULT([$QT_QMAKE])],
[AC_MSG_RESULT([not found])]
@@ -29,23 +29,23 @@ AS_IF([test "x$QT_QMAKE" != "x"],
# Sets the HAVE_QTDBUS variable to true or false.
# --------------------------------------
AC_DEFUN([FIND_QTDBUS],
[AC_MSG_CHECKING([for Qt5DBus >= 5.9.0])
PKG_CHECK_EXISTS([Qt5DBus >= 5.9.0],
[AC_MSG_CHECKING([for Qt5DBus >= 5.9.5])
PKG_CHECK_EXISTS([Qt5DBus >= 5.9.5],
[AC_MSG_RESULT([found])
HAVE_QTDBUS=[true]],
[AC_MSG_RESULT([not found])
HAVE_QTDBUS=[false]])
])
# DETECT_CPP14_PROGRAM()
# Detects if at least C++14 mode is enabled.
# DETECT_CPP17_PROGRAM()
# Detects if at least C++17 mode is enabled.
# --------------------------------------
AC_DEFUN([DETECT_CPP14_PROGRAM],
AC_DEFUN([DETECT_CPP17_PROGRAM],
[AC_LANG_PROGRAM([[
#ifndef __cplusplus
#error "This is not a C++ compiler"
#elif __cplusplus < 201402L
#error "This is not a C++14 compiler"
#elif __cplusplus < 201703L
#error "This is not a C++17 compiler"
#endif]],
[[]])
])

View File

@@ -7,6 +7,8 @@ else {
include(conf.pri)
}
QMAKE_MACOSX_DEPLOYMENT_TARGET = 10.14
LIBS += -framework Carbon -framework IOKit -framework AppKit
QT_LANG_PATH = ../dist/qt-translations

View File

@@ -4,19 +4,6 @@ SUBDIRS += src
include(version.pri)
# Make target to create release tarball. Use 'make tarball'
tarball.commands += rm -fR ../$${PROJECT_NAME}-$${PROJECT_VERSION}/ &&
tarball.commands += git clone . ../$${PROJECT_NAME}-$${PROJECT_VERSION} &&
tarball.commands += rm -fR ../$${PROJECT_NAME}-$${PROJECT_VERSION}/.git &&
tarball.commands += rm -f ../$${PROJECT_NAME}-$${PROJECT_VERSION}/.gitignore &&
tarball.commands += cd .. &&
tarball.commands += tar czf $${PROJECT_NAME}-$${PROJECT_VERSION}.tar.gz $${PROJECT_NAME}-$${PROJECT_VERSION} &&
tarball.commands += tar cf $${PROJECT_NAME}-$${PROJECT_VERSION}.tar $${PROJECT_NAME}-$${PROJECT_VERSION} &&
tarball.commands += xz -f $${PROJECT_NAME}-$${PROJECT_VERSION}.tar &&
tarball.commands += rm -fR $${PROJECT_NAME}-$${PROJECT_VERSION}
QMAKE_EXTRA_TARGETS += tarball
# For Qt Creator beautifier
DISTFILES += \
uncrustify.cfg

View File

@@ -1,12 +1,12 @@
if (UNIX AND (NOT APPLE) AND (NOT CYGWIN))
find_package(LibtorrentRasterbar QUIET ${requiredLibtorrentVersion} COMPONENTS torrent-rasterbar)
find_package(LibtorrentRasterbar QUIET ${minLibtorrentVersion} COMPONENTS torrent-rasterbar)
if (NOT LibtorrentRasterbar_FOUND)
include(FindPkgConfig)
pkg_check_modules(LIBTORRENT_RASTERBAR IMPORTED_TARGET GLOBAL "libtorrent-rasterbar>=${requiredLibtorrentVersion}")
pkg_check_modules(LIBTORRENT_RASTERBAR IMPORTED_TARGET GLOBAL "libtorrent-rasterbar>=${minLibtorrentVersion}")
if (NOT LIBTORRENT_RASTERBAR_FOUND)
message(
FATAL_ERROR
"Package LibtorrentRasterbar >= ${requiredLibtorrentVersion} not found"
"Package LibtorrentRasterbar >= ${minLibtorrentVersion} not found"
" with CMake or pkg-config.\n- Set LibtorrentRasterbar_DIR to a directory containing"
" a LibtorrentRasterbarConfig.cmake file or add the installation prefix of LibtorrentRasterbar"
" to CMAKE_PREFIX_PATH.\n- Alternatively, make sure there is a valid libtorrent-rasterbar.pc"
@@ -18,9 +18,9 @@ if (UNIX AND (NOT APPLE) AND (NOT CYGWIN))
# force a fake package to show up in the feature summary
set_property(GLOBAL APPEND PROPERTY
PACKAGES_FOUND
"LibtorrentRasterbar via pkg-config (required version >= ${requiredLibtorrentVersion})"
"LibtorrentRasterbar via pkg-config (version >= ${minLibtorrentVersion})"
)
set_package_properties("LibtorrentRasterbar via pkg-config (required version >= ${requiredLibtorrentVersion})"
set_package_properties("LibtorrentRasterbar via pkg-config (version >= ${minLibtorrentVersion})"
PROPERTIES
TYPE REQUIRED
)
@@ -28,16 +28,16 @@ if (UNIX AND (NOT APPLE) AND (NOT CYGWIN))
set_package_properties(LibtorrentRasterbar PROPERTIES TYPE REQUIRED)
endif()
else()
find_package(LibtorrentRasterbar ${requiredLibtorrentVersion} REQUIRED COMPONENTS torrent-rasterbar)
find_package(LibtorrentRasterbar ${minLibtorrentVersion} REQUIRED COMPONENTS torrent-rasterbar)
endif()
# force variable type so that it always shows up in ccmake/cmake-gui frontends
set_property(CACHE LibtorrentRasterbar_DIR PROPERTY TYPE PATH)
find_package(Boost ${requiredBoostVersion} REQUIRED)
find_package(OpenSSL ${requiredOpenSSLVersion} REQUIRED)
find_package(ZLIB ${requiredZlibVersion} REQUIRED)
find_package(Qt5 ${requiredQtVersion} REQUIRED COMPONENTS Core Network Xml LinguistTools)
find_package(Boost ${minBoostVersion} REQUIRED)
find_package(OpenSSL ${minOpenSSLVersion} REQUIRED)
find_package(ZLIB ${minZlibVersion} REQUIRED)
find_package(Qt5 ${minQtVersion} REQUIRED COMPONENTS Core Network Xml LinguistTools)
if (DBUS)
find_package(Qt5 ${requiredQtVersion} REQUIRED COMPONENTS DBus)
find_package(Qt5 ${minQtVersion} REQUIRED COMPONENTS DBus)
set_package_properties(Qt5DBus PROPERTIES
DESCRIPTION "Qt5 module for inter-process communication over the D-Bus protocol"
PURPOSE "Required by the DBUS feature"
@@ -60,11 +60,11 @@ include_directories(${CMAKE_CURRENT_SOURCE_DIR})
add_subdirectory(base)
if (GUI)
find_package(Qt5 ${requiredQtVersion} REQUIRED COMPONENTS Widgets Svg)
find_package(Qt5 ${minQtVersion} REQUIRED COMPONENTS Widgets Svg)
if (CMAKE_SYSTEM_NAME STREQUAL "Darwin")
find_package(Qt5 ${requiredQtVersion} REQUIRED COMPONENTS MacExtras)
find_package(Qt5 ${minQtVersion} REQUIRED COMPONENTS MacExtras)
elseif (CMAKE_SYSTEM_NAME STREQUAL "Windows")
find_package(Qt5 ${requiredQtVersion} REQUIRED COMPONENTS WinExtras)
find_package(Qt5 ${minQtVersion} REQUIRED COMPONENTS WinExtras)
endif()
add_subdirectory(gui)
endif()

View File

@@ -61,7 +61,6 @@ target_sources(qbt_app PRIVATE
target_link_libraries(qbt_app PRIVATE
qbt_base
qbt_version_definitions
)
set_target_properties(qbt_app PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}")

View File

@@ -63,7 +63,7 @@
#include "base/bittorrent/infohash.h"
#include "base/bittorrent/session.h"
#include "base/bittorrent/torrenthandle.h"
#include "base/bittorrent/torrent.h"
#include "base/exceptions.h"
#include "base/iconprovider.h"
#include "base/logger.h"
@@ -81,6 +81,7 @@
#include "base/utils/fs.h"
#include "base/utils/misc.h"
#include "base/utils/string.h"
#include "base/version.h"
#include "applicationinstancemanager.h"
#include "filelogger.h"
@@ -214,7 +215,7 @@ const QBtCommandLineParameters &Application::commandLineArgs() const
bool Application::isFileLoggerEnabled() const
{
return settings()->loadValue(KEY_FILELOGGER_ENABLED, true).toBool();
return settings()->loadValue(KEY_FILELOGGER_ENABLED, true);
}
void Application::setFileLoggerEnabled(const bool value)
@@ -228,8 +229,8 @@ void Application::setFileLoggerEnabled(const bool value)
QString Application::fileLoggerPath() const
{
return settings()->loadValue(KEY_FILELOGGER_PATH,
{specialFolderLocation(SpecialFolder::Data) + LOG_FOLDER}).toString();
return settings()->loadValue(KEY_FILELOGGER_PATH
, QString {specialFolderLocation(SpecialFolder::Data) + LOG_FOLDER});
}
void Application::setFileLoggerPath(const QString &path)
@@ -241,7 +242,7 @@ void Application::setFileLoggerPath(const QString &path)
bool Application::isFileLoggerBackup() const
{
return settings()->loadValue(KEY_FILELOGGER_BACKUP, true).toBool();
return settings()->loadValue(KEY_FILELOGGER_BACKUP, true);
}
void Application::setFileLoggerBackup(const bool value)
@@ -253,7 +254,7 @@ void Application::setFileLoggerBackup(const bool value)
bool Application::isFileLoggerDeleteOld() const
{
return settings()->loadValue(KEY_FILELOGGER_DELETEOLD, true).toBool();
return settings()->loadValue(KEY_FILELOGGER_DELETEOLD, true);
}
void Application::setFileLoggerDeleteOld(const bool value)
@@ -265,7 +266,7 @@ void Application::setFileLoggerDeleteOld(const bool value)
int Application::fileLoggerMaxSize() const
{
const int val = settings()->loadValue(KEY_FILELOGGER_MAXSIZEBYTES, DEFAULT_FILELOG_SIZE).toInt();
const int val = settings()->loadValue(KEY_FILELOGGER_MAXSIZEBYTES, DEFAULT_FILELOG_SIZE);
return std::min(std::max(val, MIN_FILELOG_SIZE), MAX_FILELOG_SIZE);
}
@@ -279,7 +280,7 @@ void Application::setFileLoggerMaxSize(const int bytes)
int Application::fileLoggerAge() const
{
const int val = settings()->loadValue(KEY_FILELOGGER_AGE, 1).toInt();
const int val = settings()->loadValue(KEY_FILELOGGER_AGE, 1);
return std::min(std::max(val, 1), 365);
}
@@ -290,7 +291,7 @@ void Application::setFileLoggerAge(const int value)
int Application::fileLoggerAgeType() const
{
const int val = settings()->loadValue(KEY_FILELOGGER_AGETYPE, 1).toInt();
const int val = settings()->loadValue(KEY_FILELOGGER_AGETYPE, 1);
return ((val < 0) || (val > 2)) ? 1 : val;
}
@@ -310,7 +311,7 @@ void Application::processMessage(const QString &message)
m_paramsQueue.append(params);
}
void Application::runExternalProgram(const BitTorrent::TorrentHandle *torrent) const
void Application::runExternalProgram(const BitTorrent::Torrent *torrent) const
{
QString program = Preferences::instance()->getAutoRunProgram().trimmed();
program.replace("%N", torrent->name());
@@ -404,7 +405,7 @@ void Application::runExternalProgram(const BitTorrent::TorrentHandle *torrent) c
#endif
}
void Application::sendNotificationEmail(const BitTorrent::TorrentHandle *torrent)
void Application::sendNotificationEmail(const BitTorrent::Torrent *torrent)
{
// Prepare mail content
const QString content = tr("Torrent name: %1").arg(torrent->name()) + '\n'
@@ -423,7 +424,7 @@ void Application::sendNotificationEmail(const BitTorrent::TorrentHandle *torrent
content);
}
void Application::torrentFinished(BitTorrent::TorrentHandle *const torrent)
void Application::torrentFinished(BitTorrent::Torrent *const torrent)
{
Preferences *const pref = Preferences::instance();
@@ -505,7 +506,7 @@ void Application::processParams(const QStringList &params)
}
#endif
BitTorrent::AddTorrentParams torrentParams;
TriStateBool skipTorrentDialog;
std::optional<bool> skipTorrentDialog;
for (QString param : params)
{
@@ -521,7 +522,7 @@ void Application::processParams(const QStringList &params)
if (param.startsWith(QLatin1String("@addPaused=")))
{
torrentParams.addPaused = param.midRef(11).toInt() ? TriStateBool::True : TriStateBool::False;
torrentParams.addPaused = (param.midRef(11).toInt() != 0);
continue;
}
@@ -551,7 +552,7 @@ void Application::processParams(const QStringList &params)
if (param.startsWith(QLatin1String("@skipDialog=")))
{
skipTorrentDialog = param.midRef(12).toInt() ? TriStateBool::True : TriStateBool::False;
skipTorrentDialog = (param.midRef(12).toInt() != 0);
continue;
}
@@ -561,9 +562,7 @@ void Application::processParams(const QStringList &params)
// be shown and skipTorrentDialog is undefined. The other is when
// skipTorrentDialog is false, meaning that the application setting
// should be overridden.
const bool showDialogForThisTorrent =
((AddNewTorrentDialog::isEnabled() && skipTorrentDialog == TriStateBool::Undefined)
|| skipTorrentDialog == TriStateBool::False);
const bool showDialogForThisTorrent = !skipTorrentDialog.value_or(!AddNewTorrentDialog::isEnabled());
if (showDialogForThisTorrent)
AddNewTorrentDialog::show(param, torrentParams, m_window);
else

View File

@@ -59,7 +59,7 @@ class FileLogger;
namespace BitTorrent
{
class TorrentHandle;
class Torrent;
}
namespace RSS
@@ -112,7 +112,7 @@ protected:
private slots:
void processMessage(const QString &message);
void torrentFinished(BitTorrent::TorrentHandle *const torrent);
void torrentFinished(BitTorrent::Torrent *const torrent);
void allTorrentsFinished();
void cleanup();
#if (!defined(DISABLE_GUI) && defined(Q_OS_WIN))
@@ -142,6 +142,6 @@ private:
void initializeTranslation();
void processParams(const QStringList &params);
void runExternalProgram(const BitTorrent::TorrentHandle *torrent) const;
void sendNotificationEmail(const BitTorrent::TorrentHandle *torrent);
void runExternalProgram(const BitTorrent::Torrent *torrent) const;
void sendNotificationEmail(const BitTorrent::Torrent *torrent);
};

View File

@@ -254,13 +254,13 @@ namespace
return padUsageText(fullParameter() + QLatin1String("=<true|false>"));
}
TriStateBool value(const QString &arg) const
std::optional<bool> value(const QString &arg) const
{
QStringList parts = arg.split(QLatin1Char('='));
if (parts.size() == 1)
{
return TriStateBool(m_defaultValue);
return m_defaultValue;
}
if (parts.size() == 2)
{
@@ -268,11 +268,11 @@ namespace
if ((val.toUpper() == QLatin1String("TRUE")) || (val == QLatin1String("1")))
{
return TriStateBool::True;
return true;
}
if ((val.toUpper() == QLatin1String("FALSE")) || (val == QLatin1String("0")))
{
return TriStateBool::False;
return false;
}
}
@@ -282,30 +282,30 @@ namespace
.arg(fullParameter(), QLatin1String("<true|false>")));
}
TriStateBool value(const QProcessEnvironment &env) const
std::optional<bool> value(const QProcessEnvironment &env) const
{
const QString val = env.value(envVarName(), "-1");
if (val.isEmpty())
{
return TriStateBool(m_defaultValue);
return m_defaultValue;
}
if (val == QLatin1String("-1"))
{
return TriStateBool::Undefined;
return std::nullopt;
}
if ((val.toUpper() == QLatin1String("TRUE")) || (val == QLatin1String("1")))
{
return TriStateBool::True;
return true;
}
if ((val.toUpper() == QLatin1String("FALSE")) || (val == QLatin1String("0")))
{
return TriStateBool::False;
return false;
}
qDebug() << QObject::tr("Expected %1 in environment variable '%2', but got '%3'")
.arg(QLatin1String("true|false"), envVarName(), val);
return TriStateBool::Undefined;
return std::nullopt;
}
bool m_defaultValue;
@@ -374,14 +374,8 @@ QStringList QBtCommandLineParameters::paramList() const
if (!savePath.isEmpty())
result.append(QLatin1String("@savePath=") + savePath);
if (addPaused == TriStateBool::True)
{
result.append(QLatin1String("@addPaused=1"));
}
else if (addPaused == TriStateBool::False)
{
result.append(QLatin1String("@addPaused=0"));
}
if (addPaused.has_value())
result.append(*addPaused ? QLatin1String {"@addPaused=1"} : QLatin1String {"@addPaused=0"});
if (skipChecking)
result.append(QLatin1String("@skipChecking"));
@@ -395,14 +389,8 @@ QStringList QBtCommandLineParameters::paramList() const
if (firstLastPiecePriority)
result.append(QLatin1String("@firstLastPiecePriority"));
if (skipDialog == TriStateBool::True)
{
result.append(QLatin1String("@skipDialog=1"));
}
else if (skipDialog == TriStateBool::False)
{
result.append(QLatin1String("@skipDialog=0"));
}
if (skipDialog.has_value())
result.append(*skipDialog ? QLatin1String {"@skipDialog=1"} : QLatin1String {"@skipDialog=0"});
result += torrents;
return result;

View File

@@ -28,16 +28,14 @@
* exception statement from your version.
*/
#ifndef APP_OPTIONS_H
#define APP_OPTIONS_H
#pragma once
#include <optional>
#include <stdexcept>
#include <QString>
#include <QStringList>
#include "base/tristatebool.h"
class QProcessEnvironment;
struct QBtCommandLineParameters
@@ -56,8 +54,8 @@ struct QBtCommandLineParameters
bool shouldDaemonize;
#endif
int webUiPort;
TriStateBool addPaused;
TriStateBool skipDialog;
std::optional<bool> addPaused;
std::optional<bool> skipDialog;
QStringList torrents;
QString profileDir;
QString configurationName;
@@ -81,5 +79,3 @@ private:
QBtCommandLineParameters parseCommandLine(const QStringList &args);
void displayUsage(const QString &prgName);
#endif // APP_OPTIONS_H

View File

@@ -33,6 +33,7 @@
#include <QDateTime>
#include <QDir>
#include <QTextStream>
#include <QVector>
#include "base/global.h"
#include "base/logger.h"

View File

@@ -26,8 +26,7 @@
* exception statement from your version.
*/
#ifndef FILELOGGER_H
#define FILELOGGER_H
#pragma once
#include <QFile>
#include <QObject>
@@ -73,5 +72,3 @@ private:
QFile m_logFile;
QTimer m_flusher;
};
#endif // FILELOGGER_H

View File

@@ -78,6 +78,7 @@ Q_IMPORT_PLUGIN(QICOPlugin)
#include "base/preferences.h"
#include "base/profile.h"
#include "base/version.h"
#include "application.h"
#include "cmdoptions.h"
#include "upgrade.h"

View File

@@ -152,7 +152,7 @@ bool QtLocalPeer::isClient()
#endif
if (!res)
qWarning("QtSingleCoreApplication: listen on local socket failed, %s", qPrintable(server->errorString()));
QObject::connect(server, SIGNAL(newConnection()), SLOT(receiveConnection()));
connect(server, &QLocalServer::newConnection, this, &QtLocalPeer::receiveConnection);
return false;
}

View File

@@ -66,8 +66,7 @@
****************************************************************************
*/
#ifndef QTLOCALPEER_H
#define QTLOCALPEER_H
#pragma once
#include "qtlockedfile.h"
@@ -99,5 +98,3 @@ protected:
private:
static const char* ack;
};
#endif // QTLOCALPEER_H

View File

@@ -66,8 +66,7 @@
****************************************************************************
*/
#ifndef QTLOCKEDFILE_H
#define QTLOCKEDFILE_H
#pragma once
#include <QFile>
@@ -112,5 +111,3 @@ namespace QtLP_Private
LockMode m_lock_mode;
};
}
#endif

View File

@@ -18,8 +18,7 @@
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/
#ifndef STACKTRACE_WIN_H
#define STACKTRACE_WIN_H
#pragma once
#include <windows.h>
#include <dbghelp.h>
@@ -355,5 +354,3 @@ const QString straceWin::getBacktrace()
#pragma warning(pop)
#pragma optimize("g", on)
#endif
#endif // STACKTRACE_WIN_H

View File

@@ -32,6 +32,7 @@
#include <QString>
#include "base/utils/misc.h"
#include "base/version.h"
#include "ui_stacktracedialog.h"
StacktraceDialog::StacktraceDialog(QWidget *parent)

View File

@@ -27,8 +27,7 @@
*
*/
#ifndef STACKTRACEDIALOG_H
#define STACKTRACEDIALOG_H
#pragma once
#include <QDialog>
@@ -51,5 +50,3 @@ public:
private:
Ui::StacktraceDialog *m_ui;
};
#endif // STACKTRACEDIALOG_H

View File

@@ -29,11 +29,15 @@
#include "upgrade.h"
#include <QFile>
#include <QMetaEnum>
#include <QVector>
#include "base/bittorrent/torrentcontentlayout.h"
#include "base/logger.h"
#include "base/profile.h"
#include "base/settingsstorage.h"
#include "base/utils/fs.h"
#include "base/utils/string.h"
namespace
{
@@ -42,8 +46,8 @@ namespace
const auto migrate = [](const QString &oldKey, const QString &newKey, const QString &savePath)
{
SettingsStorage *settingsStorage {SettingsStorage::instance()};
const QByteArray oldData {settingsStorage->loadValue(oldKey).toByteArray()};
const QString newData {settingsStorage->loadValue(newKey).toString()};
const auto oldData {settingsStorage->loadValue<QByteArray>(oldKey)};
const auto newData {settingsStorage->loadValue<QString>(newKey)};
const QString errorMsgFormat {QObject::tr("Migrate preferences failed: WebUI https, file: \"%1\", error: \"%2\"")};
if (!newData.isEmpty() || oldData.isEmpty())
@@ -78,11 +82,32 @@ namespace
, QLatin1String("Preferences/WebUI/HTTPS/KeyPath")
, Utils::Fs::toNativePath(configPath + QLatin1String("WebUIPrivateKey.pem")));
}
void upgradeTorrentContentLayout()
{
const QString oldKey {QLatin1String {"BitTorrent/Session/CreateTorrentSubfolder"}};
const QString newKey {QLatin1String {"BitTorrent/Session/TorrentContentLayout"}};
SettingsStorage *settingsStorage {SettingsStorage::instance()};
const auto oldData {settingsStorage->loadValue<QVariant>(oldKey)};
const auto newData {settingsStorage->loadValue<QString>(newKey)};
if (!newData.isEmpty() || !oldData.isValid())
return;
const bool createSubfolder = oldData.toBool();
const BitTorrent::TorrentContentLayout torrentContentLayout =
(createSubfolder ? BitTorrent::TorrentContentLayout::Original : BitTorrent::TorrentContentLayout::NoSubfolder);
settingsStorage->storeValue(newKey, Utils::String::fromEnum(torrentContentLayout));
settingsStorage->removeValue(oldKey);
}
}
bool upgrade(const bool /*ask*/)
{
exportWebUIHttpsFiles();
upgradeTorrentContentLayout();
return true;
}
@@ -103,7 +128,7 @@ void handleChangedDefaults(const DefaultPreferencesMode mode)
SettingsStorage *settingsStorage {SettingsStorage::instance()};
for (auto it = changedDefaults.cbegin(); it != changedDefaults.cend(); ++it)
{
if (settingsStorage->loadValue(it->name).isNull())
if (settingsStorage->loadValue<QVariant>(it->name).isNull())
settingsStorage->storeValue(it->name, (mode == DefaultPreferencesMode::Legacy ? it->legacy : it->current));
}
}

View File

@@ -2,12 +2,14 @@ add_library(qbt_base STATIC
# headers
algorithm.h
asyncfilestorage.h
bittorrent/abstractfilestorage.h
bittorrent/addtorrentparams.h
bittorrent/bandwidthscheduler.h
bittorrent/cachestatus.h
bittorrent/common.h
bittorrent/customstorage.h
bittorrent/downloadpriority.h
bittorrent/filesearcher.h
bittorrent/filterparserthread.h
bittorrent/infohash.h
bittorrent/ltqhash.h
@@ -23,9 +25,10 @@ add_library(qbt_base STATIC
bittorrent/sessionstatus.h
bittorrent/speedmonitor.h
bittorrent/statistics.h
bittorrent/torrent.h
bittorrent/torrentcontentlayout.h
bittorrent/torrentcreatorthread.h
bittorrent/torrenthandle.h
bittorrent/torrenthandleimpl.h
bittorrent/torrentimpl.h
bittorrent/torrentinfo.h
bittorrent/tracker.h
bittorrent/trackerentry.h
@@ -70,7 +73,6 @@ add_library(qbt_base STATIC
settingsstorage.h
torrentfileguard.h
torrentfilter.h
tristatebool.h
types.h
unicodestrings.h
utils/bytearray.h
@@ -84,12 +86,15 @@ add_library(qbt_base STATIC
utils/random.h
utils/string.h
utils/version.h
version.h
# sources
asyncfilestorage.cpp
bittorrent/abstractfilestorage.cpp
bittorrent/bandwidthscheduler.cpp
bittorrent/customstorage.cpp
bittorrent/downloadpriority.cpp
bittorrent/filesearcher.cpp
bittorrent/filterparserthread.cpp
bittorrent/infohash.cpp
bittorrent/magneturi.cpp
@@ -102,9 +107,9 @@ add_library(qbt_base STATIC
bittorrent/session.cpp
bittorrent/speedmonitor.cpp
bittorrent/statistics.cpp
bittorrent/torrent.cpp
bittorrent/torrentcreatorthread.cpp
bittorrent/torrenthandle.cpp
bittorrent/torrenthandleimpl.cpp
bittorrent/torrentimpl.cpp
bittorrent/torrentinfo.cpp
bittorrent/tracker.cpp
bittorrent/trackerentry.cpp
@@ -145,7 +150,6 @@ add_library(qbt_base STATIC
settingsstorage.cpp
torrentfileguard.cpp
torrentfilter.cpp
tristatebool.cpp
utils/bytearray.cpp
utils/foreignapps.cpp
utils/fs.cpp
@@ -162,7 +166,6 @@ target_link_libraries(qbt_base
PRIVATE
OpenSSL::Crypto OpenSSL::SSL
ZLIB::ZLIB
qbt_version_definitions
PUBLIC
LibtorrentRasterbar::torrent-rasterbar
Qt5::Core Qt5::Network Qt5::Xml

View File

@@ -32,9 +32,6 @@
namespace Algorithm
{
template <typename ...>
using void_t = void; // replace this with std::void_t in C++17
template <typename T, typename = void>
struct HasMappedType
: std::false_type
@@ -42,7 +39,7 @@ namespace Algorithm
};
template <typename T>
struct HasMappedType<T, void_t<typename T::mapped_type>>
struct HasMappedType<T, std::void_t<typename T::mapped_type>>
: std::true_type
{
};

View File

@@ -1,12 +1,14 @@
HEADERS += \
$$PWD/algorithm.h \
$$PWD/asyncfilestorage.h \
$$PWD/bittorrent/abstractfilestorage.h \
$$PWD/bittorrent/addtorrentparams.h \
$$PWD/bittorrent/bandwidthscheduler.h \
$$PWD/bittorrent/cachestatus.h \
$$PWD/bittorrent/common.h \
$$PWD/bittorrent/customstorage.h \
$$PWD/bittorrent/downloadpriority.h \
$$PWD/bittorrent/filesearcher.h \
$$PWD/bittorrent/filterparserthread.h \
$$PWD/bittorrent/infohash.h \
$$PWD/bittorrent/ltqhash.h \
@@ -22,9 +24,10 @@ HEADERS += \
$$PWD/bittorrent/sessionstatus.h \
$$PWD/bittorrent/speedmonitor.h \
$$PWD/bittorrent/statistics.h \
$$PWD/bittorrent/torrent.h \
$$PWD/bittorrent/torrentcontentlayout.h \
$$PWD/bittorrent/torrentcreatorthread.h \
$$PWD/bittorrent/torrenthandle.h \
$$PWD/bittorrent/torrenthandleimpl.h \
$$PWD/bittorrent/torrentimpl.h \
$$PWD/bittorrent/torrentinfo.h \
$$PWD/bittorrent/tracker.h \
$$PWD/bittorrent/trackerentry.h \
@@ -70,7 +73,6 @@ HEADERS += \
$$PWD/settingvalue.h \
$$PWD/torrentfileguard.h \
$$PWD/torrentfilter.h \
$$PWD/tristatebool.h \
$$PWD/types.h \
$$PWD/unicodestrings.h \
$$PWD/utils/bytearray.h \
@@ -83,13 +85,16 @@ HEADERS += \
$$PWD/utils/password.h \
$$PWD/utils/random.h \
$$PWD/utils/string.h \
$$PWD/utils/version.h
$$PWD/utils/version.h \
$$PWD/version.h
SOURCES += \
$$PWD/asyncfilestorage.cpp \
$$PWD/bittorrent/abstractfilestorage.cpp \
$$PWD/bittorrent/bandwidthscheduler.cpp \
$$PWD/bittorrent/customstorage.cpp \
$$PWD/bittorrent/downloadpriority.cpp \
$$PWD/bittorrent/filesearcher.cpp \
$$PWD/bittorrent/filterparserthread.cpp \
$$PWD/bittorrent/infohash.cpp \
$$PWD/bittorrent/magneturi.cpp \
@@ -102,9 +107,9 @@ SOURCES += \
$$PWD/bittorrent/session.cpp \
$$PWD/bittorrent/speedmonitor.cpp \
$$PWD/bittorrent/statistics.cpp \
$$PWD/bittorrent/torrent.cpp \
$$PWD/bittorrent/torrentcreatorthread.cpp \
$$PWD/bittorrent/torrenthandle.cpp \
$$PWD/bittorrent/torrenthandleimpl.cpp \
$$PWD/bittorrent/torrentimpl.cpp \
$$PWD/bittorrent/torrentinfo.cpp \
$$PWD/bittorrent/tracker.cpp \
$$PWD/bittorrent/trackerentry.cpp \
@@ -145,7 +150,6 @@ SOURCES += \
$$PWD/settingsstorage.cpp \
$$PWD/torrentfileguard.cpp \
$$PWD/torrentfilter.cpp \
$$PWD/tristatebool.cpp \
$$PWD/utils/bytearray.cpp \
$$PWD/utils/foreignapps.cpp \
$$PWD/utils/fs.cpp \

View File

@@ -0,0 +1,140 @@
/*
* Bittorrent Client using Qt and libtorrent.
* Copyright (C) 2020 Vladimir Golovnev <glassez@yandex.ru>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* In addition, as a special exception, the copyright holders give permission to
* link this program with the OpenSSL project's "OpenSSL" library (or with
* modified versions of it that use the same license as the "OpenSSL" library),
* and distribute the linked executables. You must obey the GNU General Public
* License in all respects for all of the code used other than "OpenSSL". If you
* modify file(s), you may extend this exception to your version of the file(s),
* but you are not obligated to do so. If you do not wish to do so, delete this
* exception statement from your version.
*/
#include "abstractfilestorage.h"
#include <QDir>
#include <QHash>
#include <QVector>
#include "base/bittorrent/common.h"
#include "base/exceptions.h"
#include "base/utils/fs.h"
#if defined(Q_OS_WIN)
const Qt::CaseSensitivity CASE_SENSITIVITY {Qt::CaseInsensitive};
#else
const Qt::CaseSensitivity CASE_SENSITIVITY {Qt::CaseSensitive};
#endif
namespace
{
bool areSameFileNames(QString first, QString second)
{
if (first.endsWith(QB_EXT, Qt::CaseInsensitive))
first.chop(QB_EXT.size());
if (second.endsWith(QB_EXT, Qt::CaseInsensitive))
second.chop(QB_EXT.size());
return QString::compare(first, second, CASE_SENSITIVITY) == 0;
}
}
void BitTorrent::AbstractFileStorage::renameFile(const QString &oldPath, const QString &newPath)
{
if (!Utils::Fs::isValidFileSystemName(oldPath, true))
throw RuntimeError {tr("The old path is invalid: '%1'.").arg(oldPath)};
if (!Utils::Fs::isValidFileSystemName(newPath, true))
throw RuntimeError {tr("The new path is invalid: '%1'.").arg(newPath)};
const QString oldFilePath = Utils::Fs::toUniformPath(oldPath);
if (oldFilePath.endsWith(QLatin1Char {'/'}))
throw RuntimeError {tr("Invalid file path: '%1'.").arg(oldFilePath)};
const QString newFilePath = Utils::Fs::toUniformPath(newPath);
if (newFilePath.endsWith(QLatin1Char {'/'}))
throw RuntimeError {tr("Invalid file path: '%1'.").arg(newFilePath)};
if (QDir().isAbsolutePath(newFilePath))
throw RuntimeError {tr("Absolute path isn't allowed: '%1'.").arg(newFilePath)};
int renamingFileIndex = -1;
for (int i = 0; i < filesCount(); ++i)
{
const QString path = filePath(i);
if ((renamingFileIndex < 0) && areSameFileNames(path, oldFilePath))
renamingFileIndex = i;
if (areSameFileNames(path, newFilePath))
throw RuntimeError {tr("The file already exists: '%1'.").arg(newFilePath)};
}
if (renamingFileIndex < 0)
throw RuntimeError {tr("No such file: '%1'.").arg(oldFilePath)};
const auto extAdjusted = [](const QString &path, const bool needExt) -> QString
{
if (path.endsWith(QB_EXT, Qt::CaseInsensitive) == needExt)
return path;
return (needExt ? (path + QB_EXT) : (path.left(path.size() - QB_EXT.size())));
};
renameFile(renamingFileIndex, extAdjusted(newFilePath, filePath(renamingFileIndex).endsWith(QB_EXT, Qt::CaseInsensitive)));
}
void BitTorrent::AbstractFileStorage::renameFolder(const QString &oldPath, const QString &newPath)
{
if (!Utils::Fs::isValidFileSystemName(oldPath, true))
throw RuntimeError {tr("The old path is invalid: '%1'.").arg(oldPath)};
if (!Utils::Fs::isValidFileSystemName(newPath, true))
throw RuntimeError {tr("The new path is invalid: '%1'.").arg(newPath)};
const auto cleanFolderPath = [](const QString &path) -> QString
{
const QString uniformPath = Utils::Fs::toUniformPath(path);
return (uniformPath.endsWith(QLatin1Char {'/'}) ? uniformPath : uniformPath + QLatin1Char {'/'});
};
const QString oldFolderPath = cleanFolderPath(oldPath);
const QString newFolderPath = cleanFolderPath(newPath);
if (QDir().isAbsolutePath(newFolderPath))
throw RuntimeError {tr("Absolute path isn't allowed: '%1'.").arg(newFolderPath)};
QVector<int> renamingFileIndexes;
renamingFileIndexes.reserve(filesCount());
for (int i = 0; i < filesCount(); ++i)
{
const QString path = filePath(i);
if (path.startsWith(oldFolderPath, CASE_SENSITIVITY))
renamingFileIndexes.append(i);
if (path.startsWith(newFolderPath, CASE_SENSITIVITY))
throw RuntimeError {tr("The folder already exists: '%1'.").arg(newFolderPath)};
}
if (renamingFileIndexes.isEmpty())
throw RuntimeError {tr("No such folder: '%1'.").arg(oldFolderPath)};
for (const int index : renamingFileIndexes)
{
const QString newFilePath = newFolderPath + filePath(index).mid(oldFolderPath.size());
renameFile(index, newFilePath);
}
}

View File

@@ -0,0 +1,53 @@
/*
* Bittorrent Client using Qt and libtorrent.
* Copyright (C) 2020 Vladimir Golovnev <glassez@yandex.ru>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* In addition, as a special exception, the copyright holders give permission to
* link this program with the OpenSSL project's "OpenSSL" library (or with
* modified versions of it that use the same license as the "OpenSSL" library),
* and distribute the linked executables. You must obey the GNU General Public
* License in all respects for all of the code used other than "OpenSSL". If you
* modify file(s), you may extend this exception to your version of the file(s),
* but you are not obligated to do so. If you do not wish to do so, delete this
* exception statement from your version.
*/
#pragma once
#include <QtGlobal>
#include <QCoreApplication>
class QString;
namespace BitTorrent
{
class AbstractFileStorage
{
Q_DECLARE_TR_FUNCTIONS(AbstractFileStorage)
public:
virtual int filesCount() const = 0;
virtual QString filePath(int index) const = 0;
virtual QString fileName(int index) const = 0;
virtual qlonglong fileSize(int index) const = 0;
virtual void renameFile(int index, const QString &name) = 0;
void renameFile(const QString &oldPath, const QString &newPath);
void renameFolder(const QString &oldPath, const QString &newPath);
};
}

View File

@@ -28,12 +28,14 @@
#pragma once
#include <optional>
#include <QSet>
#include <QString>
#include <QVector>
#include "base/tristatebool.h"
#include "torrenthandle.h"
#include "torrent.h"
#include "torrentcontentlayout.h"
namespace BitTorrent
{
@@ -48,15 +50,15 @@ namespace BitTorrent
bool disableTempPath = false; // e.g. for imported torrents
bool sequential = false;
bool firstLastPiecePriority = false;
TriStateBool addForced;
TriStateBool addPaused;
bool addForced = false;
std::optional<bool> addPaused;
QVector<DownloadPriority> filePriorities; // used if TorrentInfo is set
bool skipChecking = false;
TriStateBool createSubfolder;
TriStateBool useAutoTMM;
std::optional<BitTorrent::TorrentContentLayout> contentLayout;
std::optional<bool> useAutoTMM;
int uploadLimit = -1;
int downloadLimit = -1;
int seedingTimeLimit = TorrentHandle::USE_GLOBAL_SEEDING_TIME;
qreal ratioLimit = TorrentHandle::USE_GLOBAL_RATIO;
int seedingTimeLimit = Torrent::USE_GLOBAL_SEEDING_TIME;
qreal ratioLimit = Torrent::USE_GLOBAL_RATIO;
};
}

View File

@@ -27,8 +27,7 @@
* exception statement from your version.
*/
#ifndef BANDWIDTHSCHEDULER_H
#define BANDWIDTHSCHEDULER_H
#pragma once
#include <QObject>
#include <QTimer>
@@ -52,5 +51,3 @@ private:
QTimer m_timer;
bool m_lastAlternative;
};
#endif // BANDWIDTHSCHEDULER_H

View File

@@ -26,8 +26,7 @@
* exception statement from your version.
*/
#ifndef BITTORRENT_CACHESTATUS_H
#define BITTORRENT_CACHESTATUS_H
#pragma once
#include <QtGlobal>
@@ -39,8 +38,6 @@ namespace BitTorrent
quint64 jobQueueLength = 0;
quint64 averageJobTime = 0;
quint64 queuedBytes = 0;
qreal readRatio = 0.0;
qreal readRatio = 0; // TODO: remove when LIBTORRENT_VERSION_NUM >= 20000
};
}
#endif // BITTORRENT_CACHESTATUS_H

View File

@@ -30,5 +30,4 @@
#include <QString>
// TODO: Make it inline in C++17
extern const QString QB_EXT;
inline const QString QB_EXT {QStringLiteral(".!qB")};

View File

@@ -0,0 +1,69 @@
/*
* Bittorrent Client using Qt and libtorrent.
* Copyright (C) 2020 Vladimir Golovnev <glassez@yandex.ru>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* In addition, as a special exception, the copyright holders give permission to
* link this program with the OpenSSL project's "OpenSSL" library (or with
* modified versions of it that use the same license as the "OpenSSL" library),
* and distribute the linked executables. You must obey the GNU General Public
* License in all respects for all of the code used other than "OpenSSL". If you
* modify file(s), you may extend this exception to your version of the file(s),
* but you are not obligated to do so. If you do not wish to do so, delete this
* exception statement from your version.
*/
#include "filesearcher.h"
#include <QDir>
#include "base/bittorrent/common.h"
#include "base/bittorrent/infohash.h"
void FileSearcher::search(const BitTorrent::InfoHash &id, const QStringList &originalFileNames
, const QString &completeSavePath, const QString &incompleteSavePath)
{
const auto findInDir = [](const QString &dirPath, QStringList &fileNames) -> bool
{
const QDir dir {dirPath};
bool found = false;
for (QString &fileName : fileNames)
{
if (dir.exists(fileName))
{
found = true;
}
else if (dir.exists(fileName + QB_EXT))
{
found = true;
fileName += QB_EXT;
}
}
return found;
};
QString savePath = completeSavePath;
QStringList adjustedFileNames = originalFileNames;
const bool found = findInDir(savePath, adjustedFileNames);
if (!found && !incompleteSavePath.isEmpty())
{
savePath = incompleteSavePath;
findInDir(savePath, adjustedFileNames);
}
emit searchFinished(id, savePath, adjustedFileNames);
}

View File

@@ -1,6 +1,6 @@
/*
* Bittorrent Client using Qt and libtorrent.
* Copyright (C) 2015 Vladimir Golovnev <glassez@yandex.ru>
* Copyright (C) 2020 Vladimir Golovnev <glassez@yandex.ru>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -26,8 +26,27 @@
* exception statement from your version.
*/
#include "tristatebool.h"
#pragma once
const TriStateBool TriStateBool::Undefined(-1);
const TriStateBool TriStateBool::False(0);
const TriStateBool TriStateBool::True(1);
#include <QObject>
namespace BitTorrent
{
class InfoHash;
}
class FileSearcher final : public QObject
{
Q_OBJECT
Q_DISABLE_COPY(FileSearcher)
public:
FileSearcher() = default;
public slots:
void search(const BitTorrent::InfoHash &id, const QStringList &originalFileNames
, const QString &completeSavePath, const QString &incompleteSavePath);
signals:
void searchFinished(const BitTorrent::InfoHash &id, const QString &savePath, const QStringList &fileNames);
};

View File

@@ -26,8 +26,7 @@
* exception statement from your version.
*/
#ifndef FILTERPARSERTHREAD_H
#define FILTERPARSERTHREAD_H
#pragma once
#include <libtorrent/ip_filter.hpp>
@@ -64,5 +63,3 @@ private:
QString m_filePath;
lt::ip_filter m_filter;
};
#endif // BITTORRENT_FILTERPARSERTHREAD_H

View File

@@ -33,10 +33,7 @@
using namespace BitTorrent;
InfoHash::InfoHash()
: m_valid(false)
{
}
const int InfoHashTypeId = qRegisterMetaType<InfoHash>();
InfoHash::InfoHash(const lt::sha1_hash &nativeHash)
: m_valid(true)
@@ -87,6 +84,11 @@ bool BitTorrent::operator!=(const InfoHash &left, const InfoHash &right)
return !(left == right);
}
bool BitTorrent::operator<(const InfoHash &left, const InfoHash &right)
{
return static_cast<lt::sha1_hash>(left) < static_cast<lt::sha1_hash>(right);
}
uint BitTorrent::qHash(const InfoHash &key, const uint seed)
{
return ::qHash((std::hash<lt::sha1_hash> {})(key), seed);

View File

@@ -26,11 +26,11 @@
* exception statement from your version.
*/
#ifndef BITTORRENT_INFOHASH_H
#define BITTORRENT_INFOHASH_H
#pragma once
#include <libtorrent/sha1_hash.hpp>
#include <QMetaType>
#include <QString>
namespace BitTorrent
@@ -38,7 +38,7 @@ namespace BitTorrent
class InfoHash
{
public:
InfoHash();
InfoHash() = default;
InfoHash(const lt::sha1_hash &nativeHash);
InfoHash(const QString &hashString);
InfoHash(const InfoHash &other) = default;
@@ -54,14 +54,15 @@ namespace BitTorrent
operator QString() const;
private:
bool m_valid;
bool m_valid = false;
lt::sha1_hash m_nativeHash;
QString m_hashString;
};
bool operator==(const InfoHash &left, const InfoHash &right);
bool operator!=(const InfoHash &left, const InfoHash &right);
bool operator<(const InfoHash &left, const InfoHash &right);
uint qHash(const InfoHash &key, uint seed);
}
#endif // BITTORRENT_INFOHASH_H
Q_DECLARE_METATYPE(BitTorrent::InfoHash)

View File

@@ -30,9 +30,6 @@
#include <type_traits>
template <typename ...>
using void_t = void; // replace this with std::void_t in C++17
template <typename T, typename = void>
struct HasUnderlyingType
: std::false_type
@@ -40,7 +37,7 @@ struct HasUnderlyingType
};
template <typename T>
struct HasUnderlyingType<T, void_t<typename T::underlying_type>>
struct HasUnderlyingType<T, std::void_t<typename T::underlying_type>>
: std::true_type
{
};

View File

@@ -26,8 +26,7 @@
* exception statement from your version.
*/
#ifndef BITTORRENT_MAGNETURI_H
#define BITTORRENT_MAGNETURI_H
#pragma once
#include <libtorrent/add_torrent_params.hpp>
@@ -65,5 +64,3 @@ namespace BitTorrent
lt::add_torrent_params m_addTorrentParams;
};
}
#endif // BITTORRENT_MAGNETURI_H

View File

@@ -52,3 +52,11 @@ bool NativeTorrentExtension::on_pause()
// and other extensions to be also invoked.
return false;
}
void NativeTorrentExtension::on_state(const lt::torrent_status::state_t state)
{
if (m_state == lt::torrent_status::downloading_metadata)
m_torrentHandle.set_flags(lt::torrent_flags::stop_when_ready);
m_state = state;
}

View File

@@ -38,6 +38,8 @@ public:
private:
bool on_pause() override;
void on_state(lt::torrent_status::state_t state) override;
lt::torrent_handle m_torrentHandle;
lt::torrent_status::state_t m_state = lt::torrent_status::checking_resume_data;
};

View File

@@ -30,14 +30,14 @@
#include <QBitArray>
#include "base/bittorrent/torrenthandle.h"
#include "base/bittorrent/torrent.h"
#include "base/net/geoipmanager.h"
#include "base/unicodestrings.h"
#include "peeraddress.h"
using namespace BitTorrent;
PeerInfo::PeerInfo(const TorrentHandle *torrent, const lt::peer_info &nativeInfo)
PeerInfo::PeerInfo(const Torrent *torrent, const lt::peer_info &nativeInfo)
: m_nativeInfo(nativeInfo)
{
calcRelevance(torrent);
@@ -226,7 +226,7 @@ QString PeerInfo::connectionType() const
: QLatin1String {"Web"};
}
void PeerInfo::calcRelevance(const TorrentHandle *torrent)
void PeerInfo::calcRelevance(const Torrent *torrent)
{
const QBitArray allPieces = torrent->pieces();
const QBitArray peerPieces = pieces();

View File

@@ -26,8 +26,7 @@
* exception statement from your version.
*/
#ifndef BITTORRENT_PEERINFO_H
#define BITTORRENT_PEERINFO_H
#pragma once
#include <libtorrent/peer_info.hpp>
@@ -37,7 +36,7 @@ class QBitArray;
namespace BitTorrent
{
class TorrentHandle;
class Torrent;
struct PeerAddress;
class PeerInfo
@@ -46,7 +45,7 @@ namespace BitTorrent
public:
PeerInfo() = default;
PeerInfo(const TorrentHandle *torrent, const lt::peer_info &nativeInfo);
PeerInfo(const Torrent *torrent, const lt::peer_info &nativeInfo);
bool fromDHT() const;
bool fromPeX() const;
@@ -93,7 +92,7 @@ namespace BitTorrent
int downloadingPieceIndex() const;
private:
void calcRelevance(const TorrentHandle *torrent);
void calcRelevance(const Torrent *torrent);
void determineFlags();
lt::peer_info m_nativeInfo = {};
@@ -104,5 +103,3 @@ namespace BitTorrent
mutable QString m_country;
};
}
#endif // BITTORRENT_PEERINFO_H

View File

@@ -39,7 +39,7 @@ const QString KEY_ENABLED = QStringLiteral("Network/PortForwardingEnabled");
PortForwarderImpl::PortForwarderImpl(lt::session *provider, QObject *parent)
: Net::PortForwarder {parent}
, m_active {SettingsStorage::instance()->loadValue(KEY_ENABLED, true).toBool()}
, m_active {SettingsStorage::instance()->loadValue(KEY_ENABLED, true)}
, m_provider {provider}
{
if (m_active)

File diff suppressed because it is too large Load Diff

View File

@@ -27,10 +27,10 @@
* exception statement from your version.
*/
#ifndef BITTORRENT_SESSION_H
#define BITTORRENT_SESSION_H
#pragma once
#include <memory>
#include <variant>
#include <vector>
#include <libtorrent/add_torrent_params.hpp>
@@ -41,6 +41,7 @@
#include <QHash>
#include <QPointer>
#include <QSet>
#include <QtContainerFwd>
#include <QVector>
#include "base/settingvalue.h"
@@ -50,20 +51,24 @@
#include "sessionstatus.h"
#include "torrentinfo.h"
#if ((LIBTORRENT_VERSION_NUM >= 10206) && !defined(Q_OS_WIN))
#if !defined(Q_OS_WIN) || (LIBTORRENT_VERSION_NUM >= 10212)
#define HAS_HTTPS_TRACKER_VALIDATION
#endif
#if ((LIBTORRENT_VERSION_NUM >= 10212) && (LIBTORRENT_VERSION_NUM < 20000)) || (LIBTORRENT_VERSION_NUM >= 20002)
#define HAS_IDN_SUPPORT
#endif
class QFile;
class QNetworkConfiguration;
class QNetworkConfigurationManager;
class QString;
class QStringList;
class QThread;
class QTimer;
class QUrl;
class BandwidthScheduler;
class FileSearcher;
class FilterParserThread;
class ResumeDataSavingManager;
class Statistics;
@@ -80,8 +85,8 @@ enum MaxRatioAction
enum DeleteOption
{
Torrent,
TorrentAndFiles
DeleteTorrent,
DeleteTorrentAndFiles
};
enum TorrentExportFolder
@@ -99,8 +104,8 @@ namespace BitTorrent
{
class InfoHash;
class MagnetUri;
class TorrentHandle;
class TorrentHandleImpl;
class Torrent;
class TorrentImpl;
class Tracker;
class TrackerEntry;
struct LoadTorrentParams;
@@ -110,7 +115,7 @@ namespace BitTorrent
// Using `Q_ENUM_NS()` without a wrapper namespace in our case is not advised
// since `Q_NAMESPACE` cannot be used when the same namespace resides at different files.
// https://www.kdab.com/new-qt-5-8-meta-object-support-namespaces/#comment-143779
namespace SessionSettingsEnums
inline namespace SessionSettingsEnums
{
Q_NAMESPACE
@@ -156,49 +161,50 @@ namespace BitTorrent
Q_ENUM_NS(OSMemoryPriority)
#endif
}
using namespace SessionSettingsEnums;
struct SessionMetricIndices
{
struct
{
int hasIncomingConnections = 0;
int sentPayloadBytes = 0;
int recvPayloadBytes = 0;
int sentBytes = 0;
int recvBytes = 0;
int sentIPOverheadBytes = 0;
int recvIPOverheadBytes = 0;
int sentTrackerBytes = 0;
int recvTrackerBytes = 0;
int recvRedundantBytes = 0;
int recvFailedBytes = 0;
int hasIncomingConnections = -1;
int sentPayloadBytes = -1;
int recvPayloadBytes = -1;
int sentBytes = -1;
int recvBytes = -1;
int sentIPOverheadBytes = -1;
int recvIPOverheadBytes = -1;
int sentTrackerBytes = -1;
int recvTrackerBytes = -1;
int recvRedundantBytes = -1;
int recvFailedBytes = -1;
} net;
struct
{
int numPeersConnected = 0;
int numPeersUpDisk = 0;
int numPeersDownDisk = 0;
int numPeersConnected = -1;
int numPeersUpDisk = -1;
int numPeersDownDisk = -1;
} peer;
struct
{
int dhtBytesIn = 0;
int dhtBytesOut = 0;
int dhtNodes = 0;
int dhtBytesIn = -1;
int dhtBytesOut = -1;
int dhtNodes = -1;
} dht;
struct
{
int diskBlocksInUse = 0;
int numBlocksRead = 0;
int numBlocksCacheHits = 0;
int writeJobs = 0;
int readJobs = 0;
int hashJobs = 0;
int queuedDiskJobs = 0;
int diskJobTime = 0;
int diskBlocksInUse = -1;
int numBlocksRead = -1;
#if (LIBTORRENT_VERSION_NUM < 20000)
int numBlocksCacheHits = -1;
#endif
int writeJobs = -1;
int readJobs = -1;
int hashJobs = -1;
int queuedDiskJobs = -1;
int diskJobTime = -1;
} disk;
};
@@ -270,8 +276,8 @@ namespace BitTorrent
void setPeXEnabled(bool enabled);
bool isAddTorrentPaused() const;
void setAddTorrentPaused(bool value);
bool isKeepTorrentTopLevelFolder() const;
void setKeepTorrentTopLevelFolder(bool value);
TorrentContentLayout torrentContentLayout() const;
void setTorrentContentLayout(TorrentContentLayout value);
bool isTrackerEnabled() const;
void setTrackerEnabled(bool enabled);
bool isAppendExtensionEnabled() const;
@@ -416,6 +422,8 @@ namespace BitTorrent
void setUTPRateLimited(bool limited);
MixedModeAlgorithm utpMixedMode() const;
void setUtpMixedMode(MixedModeAlgorithm mode);
bool isIDNSupportEnabled() const;
void setIDNSupportEnabled(bool enabled);
bool multiConnectionsPerIpEnabled() const;
void setMultiConnectionsPerIpEnabled(bool enabled);
bool validateHTTPSTrackerCertificate() const;
@@ -432,8 +440,8 @@ namespace BitTorrent
#endif
void startUpTorrents();
TorrentHandle *findTorrent(const InfoHash &hash) const;
QVector<TorrentHandle *> torrents() const;
Torrent *findTorrent(const InfoHash &hash) const;
QVector<Torrent *> torrents() const;
bool hasActiveTorrents() const;
bool hasUnfinishedTorrents() const;
bool hasRunningSeed() const;
@@ -452,9 +460,9 @@ namespace BitTorrent
bool addTorrent(const QString &source, const AddTorrentParams &params = AddTorrentParams());
bool addTorrent(const MagnetUri &magnetUri, const AddTorrentParams &params = AddTorrentParams());
bool addTorrent(const TorrentInfo &torrentInfo, const AddTorrentParams &params = AddTorrentParams());
bool deleteTorrent(const InfoHash &hash, DeleteOption deleteOption = Torrent);
bool loadMetadata(const MagnetUri &magnetUri);
bool cancelLoadMetadata(const InfoHash &hash);
bool deleteTorrent(const InfoHash &hash, DeleteOption deleteOption = DeleteTorrent);
bool downloadMetadata(const MagnetUri &magnetUri);
bool cancelDownloadMetadata(const InfoHash &hash);
void recursiveTorrentDownload(const InfoHash &hash);
void increaseTorrentsQueuePos(const QVector<InfoHash> &hashes);
@@ -462,31 +470,33 @@ namespace BitTorrent
void topTorrentsQueuePos(const QVector<InfoHash> &hashes);
void bottomTorrentsQueuePos(const QVector<InfoHash> &hashes);
// TorrentHandle interface
void handleTorrentSaveResumeDataRequested(const TorrentHandleImpl *torrent);
void handleTorrentShareLimitChanged(TorrentHandleImpl *const torrent);
void handleTorrentNameChanged(TorrentHandleImpl *const torrent);
void handleTorrentSavePathChanged(TorrentHandleImpl *const torrent);
void handleTorrentCategoryChanged(TorrentHandleImpl *const torrent, const QString &oldCategory);
void handleTorrentTagAdded(TorrentHandleImpl *const torrent, const QString &tag);
void handleTorrentTagRemoved(TorrentHandleImpl *const torrent, const QString &tag);
void handleTorrentSavingModeChanged(TorrentHandleImpl *const torrent);
void handleTorrentMetadataReceived(TorrentHandleImpl *const torrent);
void handleTorrentPaused(TorrentHandleImpl *const torrent);
void handleTorrentResumed(TorrentHandleImpl *const torrent);
void handleTorrentChecked(TorrentHandleImpl *const torrent);
void handleTorrentFinished(TorrentHandleImpl *const torrent);
void handleTorrentTrackersAdded(TorrentHandleImpl *const torrent, const QVector<TrackerEntry> &newTrackers);
void handleTorrentTrackersRemoved(TorrentHandleImpl *const torrent, const QVector<TrackerEntry> &deletedTrackers);
void handleTorrentTrackersChanged(TorrentHandleImpl *const torrent);
void handleTorrentUrlSeedsAdded(TorrentHandleImpl *const torrent, const QVector<QUrl> &newUrlSeeds);
void handleTorrentUrlSeedsRemoved(TorrentHandleImpl *const torrent, const QVector<QUrl> &urlSeeds);
void handleTorrentResumeDataReady(TorrentHandleImpl *const torrent, const std::shared_ptr<lt::entry> &data);
void handleTorrentTrackerReply(TorrentHandleImpl *const torrent, const QString &trackerUrl);
void handleTorrentTrackerWarning(TorrentHandleImpl *const torrent, const QString &trackerUrl);
void handleTorrentTrackerError(TorrentHandleImpl *const torrent, const QString &trackerUrl);
// Torrent interface
void handleTorrentSaveResumeDataRequested(const TorrentImpl *torrent);
void handleTorrentShareLimitChanged(TorrentImpl *const torrent);
void handleTorrentNameChanged(TorrentImpl *const torrent);
void handleTorrentSavePathChanged(TorrentImpl *const torrent);
void handleTorrentCategoryChanged(TorrentImpl *const torrent, const QString &oldCategory);
void handleTorrentTagAdded(TorrentImpl *const torrent, const QString &tag);
void handleTorrentTagRemoved(TorrentImpl *const torrent, const QString &tag);
void handleTorrentSavingModeChanged(TorrentImpl *const torrent);
void handleTorrentMetadataReceived(TorrentImpl *const torrent);
void handleTorrentPaused(TorrentImpl *const torrent);
void handleTorrentResumed(TorrentImpl *const torrent);
void handleTorrentChecked(TorrentImpl *const torrent);
void handleTorrentFinished(TorrentImpl *const torrent);
void handleTorrentTrackersAdded(TorrentImpl *const torrent, const QVector<TrackerEntry> &newTrackers);
void handleTorrentTrackersRemoved(TorrentImpl *const torrent, const QVector<TrackerEntry> &deletedTrackers);
void handleTorrentTrackersChanged(TorrentImpl *const torrent);
void handleTorrentUrlSeedsAdded(TorrentImpl *const torrent, const QVector<QUrl> &newUrlSeeds);
void handleTorrentUrlSeedsRemoved(TorrentImpl *const torrent, const QVector<QUrl> &urlSeeds);
void handleTorrentResumeDataReady(TorrentImpl *const torrent, const std::shared_ptr<lt::entry> &data);
void handleTorrentTrackerReply(TorrentImpl *const torrent, const QString &trackerUrl);
void handleTorrentTrackerWarning(TorrentImpl *const torrent, const QString &trackerUrl);
void handleTorrentTrackerError(TorrentImpl *const torrent, const QString &trackerUrl);
bool addMoveTorrentStorageJob(TorrentHandleImpl *torrent, const QString &newPath, MoveStorageMode mode);
bool addMoveTorrentStorageJob(TorrentImpl *torrent, const QString &newPath, MoveStorageMode mode);
void findIncompleteFiles(const TorrentInfo &torrentInfo, const QString &savePath) const;
signals:
void allTorrentsFinished();
@@ -494,39 +504,37 @@ namespace BitTorrent
void categoryRemoved(const QString &categoryName);
void downloadFromUrlFailed(const QString &url, const QString &reason);
void downloadFromUrlFinished(const QString &url);
void fullDiskError(TorrentHandle *torrent, const QString &msg);
void fullDiskError(Torrent *torrent, const QString &msg);
void IPFilterParsed(bool error, int ruleCount);
void loadTorrentFailed(const QString &error);
void metadataLoaded(const TorrentInfo &info);
void recursiveTorrentDownloadPossible(TorrentHandle *torrent);
void metadataDownloaded(const TorrentInfo &info);
void recursiveTorrentDownloadPossible(Torrent *torrent);
void speedLimitModeChanged(bool alternative);
void statsUpdated();
void subcategoriesSupportChanged();
void tagAdded(const QString &tag);
void tagRemoved(const QString &tag);
void torrentAboutToBeRemoved(TorrentHandle *torrent);
void torrentAdded(TorrentHandle *torrent);
void torrentCategoryChanged(TorrentHandle *torrent, const QString &oldCategory);
void torrentFinished(TorrentHandle *torrent);
void torrentFinishedChecking(TorrentHandle *torrent);
void torrentLoaded(TorrentHandle *torrent);
void torrentMetadataLoaded(TorrentHandle *torrent);
void torrentPaused(TorrentHandle *torrent);
void torrentResumed(TorrentHandle *torrent);
void torrentSavePathChanged(TorrentHandle *torrent);
void torrentSavingModeChanged(TorrentHandle *torrent);
void torrentStorageMoveFailed(TorrentHandle *torrent, const QString &targetPath, const QString &error);
void torrentStorageMoveFinished(TorrentHandle *torrent, const QString &newPath);
void torrentsUpdated(const QVector<TorrentHandle *> &torrents);
void torrentTagAdded(TorrentHandle *torrent, const QString &tag);
void torrentTagRemoved(TorrentHandle *torrent, const QString &tag);
void trackerError(TorrentHandle *torrent, const QString &tracker);
void trackerlessStateChanged(TorrentHandle *torrent, bool trackerless);
void trackersAdded(TorrentHandle *torrent, const QVector<TrackerEntry> &trackers);
void trackersChanged(TorrentHandle *torrent);
void trackersRemoved(TorrentHandle *torrent, const QVector<TrackerEntry> &trackers);
void trackerSuccess(TorrentHandle *torrent, const QString &tracker);
void trackerWarning(TorrentHandle *torrent, const QString &tracker);
void torrentAboutToBeRemoved(Torrent *torrent);
void torrentAdded(Torrent *torrent);
void torrentCategoryChanged(Torrent *torrent, const QString &oldCategory);
void torrentFinished(Torrent *torrent);
void torrentFinishedChecking(Torrent *torrent);
void torrentLoaded(Torrent *torrent);
void torrentMetadataReceived(Torrent *torrent);
void torrentPaused(Torrent *torrent);
void torrentResumed(Torrent *torrent);
void torrentSavePathChanged(Torrent *torrent);
void torrentSavingModeChanged(Torrent *torrent);
void torrentsUpdated(const QVector<Torrent *> &torrents);
void torrentTagAdded(Torrent *torrent, const QString &tag);
void torrentTagRemoved(Torrent *torrent, const QString &tag);
void trackerError(Torrent *torrent, const QString &tracker);
void trackerlessStateChanged(Torrent *torrent, bool trackerless);
void trackersAdded(Torrent *torrent, const QVector<TrackerEntry> &trackers);
void trackersChanged(Torrent *torrent);
void trackersRemoved(Torrent *torrent, const QVector<TrackerEntry> &trackers);
void trackerSuccess(Torrent *torrent, const QString &tracker);
void trackerWarning(Torrent *torrent, const QString &tracker);
private slots:
void configureDeferred();
@@ -537,6 +545,7 @@ namespace BitTorrent
void handleIPFilterParsed(int ruleCount);
void handleIPFilterError();
void handleDownloadFinished(const Net::DownloadResult &result);
void fileSearchFinished(const InfoHash &id, const QString &savePath, const QStringList &fileNames);
// Session reconfiguration triggers
void networkOnlineStateChanged(bool online);
@@ -592,11 +601,10 @@ namespace BitTorrent
bool loadTorrentResumeData(const QByteArray &data, const TorrentInfo &metadata, LoadTorrentParams &torrentParams);
bool loadTorrent(LoadTorrentParams params);
LoadTorrentParams initLoadTorrentParams(const AddTorrentParams &addTorrentParams);
bool addTorrent_impl(const AddTorrentParams &addTorrentParams, const MagnetUri &magnetUri, TorrentInfo torrentInfo = TorrentInfo());
bool findIncompleteFiles(TorrentInfo &torrentInfo, QString &savePath) const;
bool addTorrent_impl(const std::variant<MagnetUri, TorrentInfo> &source, const AddTorrentParams &addTorrentParams);
void updateSeedingLimitTimer();
void exportTorrentFile(const TorrentHandle *torrent, TorrentExportFolder folder = TorrentExportFolder::Regular);
void exportTorrentFile(const Torrent *torrent, TorrentExportFolder folder = TorrentExportFolder::Regular);
void handleAlert(const lt::alert *a);
void dispatchTorrentAlert(const lt::alert *a);
@@ -604,9 +612,6 @@ namespace BitTorrent
void handleStateUpdateAlert(const lt::state_update_alert *p);
void handleMetadataReceivedAlert(const lt::metadata_received_alert *p);
void handleFileErrorAlert(const lt::file_error_alert *p);
#if (LIBTORRENT_VERSION_NUM < 10208)
void handleReadPieceAlert(const lt::read_piece_alert *p) const;
#endif
void handleTorrentRemovedAlert(const lt::torrent_removed_alert *p);
void handleTorrentDeletedAlert(const lt::torrent_deleted_alert *p);
void handleTorrentDeleteFailedAlert(const lt::torrent_delete_failed_alert *p);
@@ -622,11 +627,9 @@ namespace BitTorrent
void handleAlertsDroppedAlert(const lt::alerts_dropped_alert *p) const;
void handleStorageMovedAlert(const lt::storage_moved_alert *p);
void handleStorageMovedFailedAlert(const lt::storage_moved_failed_alert *p);
#if (LIBTORRENT_VERSION_NUM >= 10204)
void handleSocks5Alert(const lt::socks5_alert *p) const;
#endif
void createTorrentHandle(const lt::torrent_handle &nativeHandle);
void createTorrent(const lt::torrent_handle &nativeHandle);
void saveResumeData();
void saveTorrentsQueue();
@@ -690,6 +693,7 @@ namespace BitTorrent
CachedSettingValue<BTProtocol> m_btProtocol;
CachedSettingValue<bool> m_isUTPRateLimited;
CachedSettingValue<MixedModeAlgorithm> m_utpMixedMode;
CachedSettingValue<bool> m_IDNSupportEnabled;
CachedSettingValue<bool> m_multiConnectionsPerIpEnabled;
CachedSettingValue<bool> m_validateHTTPSTrackerCertificate;
CachedSettingValue<bool> m_blockPeersOnPrivilegedPorts;
@@ -698,7 +702,7 @@ namespace BitTorrent
CachedSettingValue<qreal> m_globalMaxRatio;
CachedSettingValue<int> m_globalMaxSeedingMinutes;
CachedSettingValue<bool> m_isAddTorrentPaused;
CachedSettingValue<bool> m_isKeepTorrentTopLevelFolder;
CachedSettingValue<TorrentContentLayout> m_torrentContentLayout;
CachedSettingValue<bool> m_isAppendExtensionEnabled;
CachedSettingValue<int> m_refreshInterval;
CachedSettingValue<bool> m_isPreallocationEnabled;
@@ -763,10 +767,11 @@ namespace BitTorrent
// fastresume data writing thread
QThread *m_ioThread = nullptr;
ResumeDataSavingManager *m_resumeDataSavingManager = nullptr;
FileSearcher *m_fileSearcher = nullptr;
QSet<InfoHash> m_loadedMetadata;
QSet<InfoHash> m_downloadedMetadata;
QHash<InfoHash, TorrentHandleImpl *> m_torrents;
QHash<InfoHash, TorrentImpl *> m_torrents;
QHash<InfoHash, LoadTorrentParams> m_loadingTorrents;
QHash<QString, AddTorrentParams> m_downloadedTorrents;
QHash<InfoHash, RemovingTorrentData> m_removingTorrents;
@@ -795,5 +800,3 @@ namespace BitTorrent
Q_DECLARE_METATYPE(std::shared_ptr<lt::entry>)
const int sharedPtrLtEntryTypeID = qRegisterMetaType<std::shared_ptr<lt::entry>>();
#endif
#endif // BITTORRENT_SESSION_H

View File

@@ -26,8 +26,7 @@
* exception statement from your version.
*/
#ifndef BITTORRENT_SESSIONSTATUS_H
#define BITTORRENT_SESSIONSTATUS_H
#pragma once
#include <QtGlobal>
@@ -74,5 +73,3 @@ namespace BitTorrent
quint64 peersCount = 0;
};
}
#endif // BITTORRENT_SESSIONSTATUS_H

View File

@@ -27,8 +27,7 @@
* exception statement from your version.
*/
#ifndef SPEEDMONITOR_H
#define SPEEDMONITOR_H
#pragma once
#ifndef Q_MOC_RUN
#include <boost/circular_buffer.hpp>
@@ -86,5 +85,3 @@ private:
boost::circular_buffer<SpeedSample> m_speedSamples;
SpeedSample m_sum;
};
#endif // SPEEDMONITOR_H

View File

@@ -26,8 +26,7 @@
* exception statement from your version.
*/
#ifndef STATISTICS_H
#define STATISTICS_H
#pragma once
#include <QObject>
#include <QTimer>
@@ -67,5 +66,3 @@ private:
QTimer m_timer;
};
#endif // STATISTICS_H

View File

@@ -27,10 +27,12 @@
* exception statement from your version.
*/
#include "torrenthandle.h"
#include "torrent.h"
#include <type_traits>
#include <QHash>
namespace BitTorrent
{
uint qHash(const TorrentState key, const uint seed)
@@ -38,33 +40,33 @@ namespace BitTorrent
return ::qHash(static_cast<std::underlying_type_t<TorrentState>>(key), seed);
}
// TorrentHandle
// Torrent
const qreal TorrentHandle::USE_GLOBAL_RATIO = -2.;
const qreal TorrentHandle::NO_RATIO_LIMIT = -1.;
const qreal Torrent::USE_GLOBAL_RATIO = -2.;
const qreal Torrent::NO_RATIO_LIMIT = -1.;
const int TorrentHandle::USE_GLOBAL_SEEDING_TIME = -2;
const int TorrentHandle::NO_SEEDING_TIME_LIMIT = -1;
const int Torrent::USE_GLOBAL_SEEDING_TIME = -2;
const int Torrent::NO_SEEDING_TIME_LIMIT = -1;
const qreal TorrentHandle::MAX_RATIO = 9999.;
const int TorrentHandle::MAX_SEEDING_TIME = 525600;
const qreal Torrent::MAX_RATIO = 9999.;
const int Torrent::MAX_SEEDING_TIME = 525600;
bool TorrentHandle::isResumed() const
bool Torrent::isResumed() const
{
return !isPaused();
}
qlonglong TorrentHandle::remainingSize() const
qlonglong Torrent::remainingSize() const
{
return wantedSize() - completedSize();
}
void TorrentHandle::toggleSequentialDownload()
void Torrent::toggleSequentialDownload()
{
setSequentialDownload(!isSequentialDownload());
}
void TorrentHandle::toggleFirstLastPiecePriority()
void Torrent::toggleFirstLastPiecePriority()
{
setFirstLastPiecePriority(!hasFirstLastPiecePriority());
}

View File

@@ -29,15 +29,14 @@
#pragma once
#include <QHash>
#include <QMetaType>
#include <QSet>
#include <QString>
#include <QVector>
#include <QtContainerFwd>
#include "abstractfilestorage.h"
class QBitArray;
class QDateTime;
class QStringList;
class QUrl;
namespace BitTorrent
@@ -92,7 +91,7 @@ namespace BitTorrent
uint qHash(TorrentState key, uint seed);
class TorrentHandle
class Torrent : public AbstractFileStorage
{
public:
static const qreal USE_GLOBAL_RATIO;
@@ -104,7 +103,7 @@ namespace BitTorrent
static const qreal MAX_RATIO;
static const int MAX_SEEDING_TIME;
virtual ~TorrentHandle() = default;
virtual ~Torrent() = default;
virtual InfoHash hash() const = 0;
virtual QString name() const = 0;
@@ -180,9 +179,6 @@ namespace BitTorrent
virtual bool removeTag(const QString &tag) = 0;
virtual void removeAllTags() = 0;
virtual bool hasRootFolder() const = 0;
virtual int filesCount() const = 0;
virtual int piecesCount() const = 0;
virtual int piecesHave() const = 0;
virtual qreal progress() const = 0;
@@ -190,9 +186,6 @@ namespace BitTorrent
virtual qreal ratioLimit() const = 0;
virtual int seedingTimeLimit() const = 0;
virtual QString filePath(int index) const = 0;
virtual QString fileName(int index) const = 0;
virtual qlonglong fileSize(int index) const = 0;
virtual QStringList absoluteFilePaths() const = 0;
virtual QVector<DownloadPriority> filePriorities() const = 0;
@@ -243,6 +236,9 @@ namespace BitTorrent
virtual int downloadLimit() const = 0;
virtual int uploadLimit() const = 0;
virtual bool superSeeding() const = 0;
virtual bool isDHTDisabled() const = 0;
virtual bool isPEXDisabled() const = 0;
virtual bool isLSDDisabled() const = 0;
virtual QVector<PeerInfo> peers() const = 0;
virtual QBitArray pieces() const = 0;
virtual QBitArray downloadingPieces() const = 0;
@@ -275,13 +271,15 @@ namespace BitTorrent
virtual void forceReannounce(int index = -1) = 0;
virtual void forceDHTAnnounce() = 0;
virtual void forceRecheck() = 0;
virtual void renameFile(int index, const QString &name) = 0;
virtual void prioritizeFiles(const QVector<DownloadPriority> &priorities) = 0;
virtual void setRatioLimit(qreal limit) = 0;
virtual void setSeedingTimeLimit(int limit) = 0;
virtual void setUploadLimit(int limit) = 0;
virtual void setDownloadLimit(int limit) = 0;
virtual void setSuperSeeding(bool enable) = 0;
virtual void setDHTDisabled(bool disable) = 0;
virtual void setPEXDisabled(bool disable) = 0;
virtual void setLSDDisabled(bool disable) = 0;
virtual void flushCache() const = 0;
virtual void addTrackers(const QVector<TrackerEntry> &trackers) = 0;
virtual void replaceTrackers(const QVector<TrackerEntry> &trackers) = 0;

View File

@@ -1,6 +1,6 @@
/*
* Bittorrent Client using Qt and libtorrent.
* Copyright (C) 2015 Vladimir Golovnev <glassez@yandex.ru>
* Copyright (C) 2020 Vladimir Golovnev <glassez@yandex.ru>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -26,47 +26,26 @@
* exception statement from your version.
*/
#ifndef TRISTATEBOOL_H
#define TRISTATEBOOL_H
#pragma once
class TriStateBool
#include <QMetaEnum>
namespace BitTorrent
{
public:
static const TriStateBool Undefined;
static const TriStateBool False;
static const TriStateBool True;
constexpr TriStateBool() = default;
constexpr TriStateBool(const TriStateBool &other) = default;
explicit constexpr TriStateBool(const bool boolean)
// Using `Q_ENUM_NS()` without a wrapper namespace in our case is not advised
// since `Q_NAMESPACE` cannot be used when the same namespace resides at different files.
// https://www.kdab.com/new-qt-5-8-meta-object-support-namespaces/#comment-143779
inline namespace TorrentContentLayoutNS
{
*this = boolean ? True : False;
Q_NAMESPACE
enum class TorrentContentLayout
{
Original,
Subfolder,
NoSubfolder
};
Q_ENUM_NS(TorrentContentLayout)
}
TriStateBool &operator=(const TriStateBool &other) = default; // TODO: add constexpr when using C++17
explicit constexpr operator signed char() const
{
return m_value;
}
constexpr friend bool operator==(const TriStateBool &left, const TriStateBool &right)
{
return (left.m_value == right.m_value);
}
private:
explicit constexpr TriStateBool(const int value)
: m_value((value < 0) ? -1 : ((value > 0) ? 1 : 0))
{
}
signed char m_value = -1; // Undefined by default
};
constexpr bool operator!=(const TriStateBool &left, const TriStateBool &right)
{
return !(left == right);
}
#endif // TRISTATEBOOL_H

View File

@@ -45,6 +45,7 @@
#include "base/utils/fs.h"
#include "base/utils/io.h"
#include "base/utils/string.h"
#include "base/version.h"
#include "ltunderlyingtype.h"
namespace

View File

@@ -26,8 +26,7 @@
* exception statement from your version.
*/
#ifndef BITTORRENT_TORRENTCREATORTHREAD_H
#define BITTORRENT_TORRENTCREATORTHREAD_H
#pragma once
#include <libtorrent/version.hpp>
@@ -94,5 +93,3 @@ namespace BitTorrent
TorrentCreatorParams m_params;
};
}
#endif // BITTORRENT_TORRENTCREATORTHREAD_H

View File

@@ -46,7 +46,7 @@
#include "infohash.h"
#include "speedmonitor.h"
#include "torrenthandle.h"
#include "torrent.h"
#include "torrentinfo.h"
namespace BitTorrent
@@ -62,14 +62,15 @@ namespace BitTorrent
QString category;
QSet<QString> tags;
QString savePath;
TorrentContentLayout contentLayout = TorrentContentLayout::Original;
bool firstLastPiecePriority = false;
bool hasSeedStatus = false;
bool hasRootFolder = true;
bool forced = false;
bool paused = false;
qreal ratioLimit = TorrentHandle::USE_GLOBAL_RATIO;
int seedingTimeLimit = TorrentHandle::USE_GLOBAL_SEEDING_TIME;
qreal ratioLimit = Torrent::USE_GLOBAL_RATIO;
int seedingTimeLimit = Torrent::USE_GLOBAL_SEEDING_TIME;
bool restored = false; // is existing torrent job?
};
@@ -80,15 +81,21 @@ namespace BitTorrent
Overwrite
};
class TorrentHandleImpl final : public QObject, public TorrentHandle
enum class MaintenanceJob
{
Q_DISABLE_COPY(TorrentHandleImpl)
Q_DECLARE_TR_FUNCTIONS(BitTorrent::TorrentHandleImpl)
None,
HandleMetadata
};
class TorrentImpl final : public QObject, public Torrent
{
Q_DISABLE_COPY(TorrentImpl)
Q_DECLARE_TR_FUNCTIONS(BitTorrent::TorrentImpl)
public:
TorrentHandleImpl(Session *session, const lt::torrent_handle &nativeHandle,
const LoadTorrentParams &params);
~TorrentHandleImpl() override;
TorrentImpl(Session *session, lt::session *nativeSession
, const lt::torrent_handle &nativeHandle, const LoadTorrentParams &params);
~TorrentImpl() override;
bool isValid() const;
@@ -123,8 +130,6 @@ namespace BitTorrent
bool removeTag(const QString &tag) override;
void removeAllTags() override;
bool hasRootFolder() const override;
int filesCount() const override;
int piecesCount() const override;
int piecesHave() const override;
@@ -186,6 +191,9 @@ namespace BitTorrent
int downloadLimit() const override;
int uploadLimit() const override;
bool superSeeding() const override;
bool isDHTDisabled() const override;
bool isPEXDisabled() const override;
bool isLSDDisabled() const override;
QVector<PeerInfo> peers() const override;
QBitArray pieces() const override;
QBitArray downloadingPieces() const override;
@@ -212,13 +220,16 @@ namespace BitTorrent
void forceReannounce(int index = -1) override;
void forceDHTAnnounce() override;
void forceRecheck() override;
void renameFile(int index, const QString &name) override;
void renameFile(int index, const QString &path) override;
void prioritizeFiles(const QVector<DownloadPriority> &priorities) override;
void setRatioLimit(qreal limit) override;
void setSeedingTimeLimit(int limit) override;
void setUploadLimit(int limit) override;
void setDownloadLimit(int limit) override;
void setSuperSeeding(bool enable) override;
void setDHTDisabled(bool disable) override;
void setPEXDisabled(bool disable) override;
void setLSDDisabled(bool disable) override;
void flushCache() const override;
void addTrackers(const QVector<TrackerEntry> &trackers) override;
void replaceTrackers(const QVector<TrackerEntry> &trackers) override;
@@ -241,6 +252,7 @@ namespace BitTorrent
void handleAppendExtensionToggled();
void saveResumeData();
void handleMoveStorageJobFinished(bool hasOutstandingJob);
void fileSearchFinished(const QString &savePath, const QStringList &fileNames);
QString actualStorageLocation() const;
@@ -250,7 +262,6 @@ namespace BitTorrent
void updateStatus();
void updateStatus(const lt::torrent_status &nativeStatus);
void updateState();
void updateTorrentInfo();
void handleFastResumeRejectedAlert(const lt::fastresume_rejected_alert *p);
void handleFileCompletedAlert(const lt::file_completed_alert *p);
@@ -279,7 +290,11 @@ namespace BitTorrent
void manageIncompleteFiles();
void applyFirstLastPiecePriority(bool enabled, const QVector<DownloadPriority> &updatedFilePrio = {});
void endReceivedMetadataHandling(const QString &savePath, const QStringList &fileNames);
void reload();
Session *const m_session;
lt::session *m_nativeSession;
lt::torrent_handle m_nativeHandle;
lt::torrent_status m_nativeStatus;
TorrentState m_state = TorrentState::Unknown;
@@ -294,6 +309,8 @@ namespace BitTorrent
int m_renameCount = 0;
bool m_storageIsMoving = false;
MaintenanceJob m_maintenanceJob = MaintenanceJob::None;
// Until libtorrent provide an "old_name" field in `file_renamed_alert`
// we will rely on this workaround to remove empty leftover folders
QHash<lt::file_index_t, QVector<QString>> m_oldPath;
@@ -308,10 +325,10 @@ namespace BitTorrent
qreal m_ratioLimit;
int m_seedingTimeLimit;
TorrentOperatingMode m_operatingMode;
TorrentContentLayout m_contentLayout;
bool m_hasSeedStatus;
bool m_fastresumeDataRejected = false;
bool m_hasMissingFiles = false;
bool m_hasRootFolder;
bool m_hasFirstLastPiecePriority = false;
bool m_useAutoTMM;
bool m_isStopped;

View File

@@ -40,6 +40,7 @@
#include <QString>
#include <QStringList>
#include <QUrl>
#include <QVector>
#include "base/exceptions.h"
#include "base/global.h"
@@ -51,6 +52,29 @@
using namespace BitTorrent;
namespace
{
QString getRootFolder(const QStringList &filePaths)
{
QString rootFolder;
for (const QString &filePath : filePaths)
{
if (QDir::isAbsolutePath(filePath)) continue;
const auto filePathElements = filePath.splitRef('/');
// if at least one file has no root folder, no common root folder exists
if (filePathElements.count() <= 1) return {};
if (rootFolder.isEmpty())
rootFolder = filePathElements.at(0).toString();
else if (rootFolder != filePathElements.at(0))
return {};
}
return rootFolder;
}
}
TorrentInfo::TorrentInfo(std::shared_ptr<const lt::torrent_info> nativeInfo)
{
m_nativeInfo = std::const_pointer_cast<lt::torrent_info>(nativeInfo);
@@ -169,7 +193,7 @@ InfoHash TorrentInfo::hash() const
QString TorrentInfo::name() const
{
if (!isValid()) return {};
return QString::fromStdString(m_nativeInfo->name());
return QString::fromStdString(m_nativeInfo->orig_files().name());
}
QDateTime TorrentInfo::creationDate() const
@@ -411,23 +435,7 @@ int TorrentInfo::fileIndex(const QString &fileName) const
QString TorrentInfo::rootFolder() const
{
QString rootFolder;
for (int i = 0; i < filesCount(); ++i)
{
const QString filePath = this->filePath(i);
if (QDir::isAbsolutePath(filePath)) continue;
const auto filePathElements = filePath.splitRef('/');
// if at least one file has no root folder, no common root folder exists
if (filePathElements.count() <= 1) return "";
if (rootFolder.isEmpty())
rootFolder = filePathElements.at(0).toString();
else if (rootFolder != filePathElements.at(0))
return "";
}
return rootFolder;
return getRootFolder(filePaths());
}
bool TorrentInfo::hasRootFolder() const
@@ -435,10 +443,26 @@ bool TorrentInfo::hasRootFolder() const
return !rootFolder().isEmpty();
}
void TorrentInfo::setContentLayout(const TorrentContentLayout layout)
{
switch (layout)
{
case TorrentContentLayout::Original:
setContentLayout(defaultContentLayout());
break;
case TorrentContentLayout::Subfolder:
if (rootFolder().isEmpty())
addRootFolder();
break;
case TorrentContentLayout::NoSubfolder:
if (!rootFolder().isEmpty())
stripRootFolder();
break;
}
}
void TorrentInfo::stripRootFolder()
{
if (!hasRootFolder()) return;
lt::file_storage files = m_nativeInfo->files();
// Solution for case of renamed root folder
@@ -455,6 +479,32 @@ void TorrentInfo::stripRootFolder()
m_nativeInfo->remap_files(files);
}
void TorrentInfo::addRootFolder()
{
const QString rootFolder = name();
Q_ASSERT(!rootFolder.isEmpty());
const std::string rootPrefix = Utils::Fs::toNativePath(rootFolder + QLatin1Char {'/'}).toStdString();
lt::file_storage files = m_nativeInfo->files();
files.set_name(rootFolder.toStdString());
for (int i = 0; i < files.num_files(); ++i)
files.rename_file(lt::file_index_t {i}, rootPrefix + files.file_path(lt::file_index_t {i}));
m_nativeInfo->remap_files(files);
}
TorrentContentLayout TorrentInfo::defaultContentLayout() const
{
QStringList origFilePaths;
origFilePaths.reserve(filesCount());
for (int i = 0; i < filesCount(); ++i)
origFilePaths << origFilePath(i);
const QString origRootFolder = getRootFolder(origFilePaths);
return (origRootFolder.isEmpty()
? TorrentContentLayout::NoSubfolder
: TorrentContentLayout::Subfolder);
}
std::shared_ptr<lt::torrent_info> TorrentInfo::nativeInfo() const
{
return m_nativeInfo;

View File

@@ -26,20 +26,20 @@
* exception statement from your version.
*/
#ifndef BITTORRENT_TORRENTINFO_H
#define BITTORRENT_TORRENTINFO_H
#pragma once
#include <libtorrent/torrent_info.hpp>
#include <QCoreApplication>
#include <QVector>
#include <QtContainerFwd>
#include "base/indexrange.h"
#include "abstractfilestorage.h"
#include "torrentcontentlayout.h"
class QByteArray;
class QDateTime;
class QString;
class QStringList;
class QUrl;
namespace BitTorrent
@@ -47,7 +47,7 @@ namespace BitTorrent
class InfoHash;
class TrackerEntry;
class TorrentInfo
class TorrentInfo final : public AbstractFileStorage
{
Q_DECLARE_TR_FUNCTIONS(TorrentInfo)
@@ -69,15 +69,15 @@ namespace BitTorrent
QString comment() const;
bool isPrivate() const;
qlonglong totalSize() const;
int filesCount() const;
int filesCount() const override;
int pieceLength() const;
int pieceLength(int index) const;
int piecesCount() const;
QString filePath(int index) const;
QString filePath(int index) const override;
QStringList filePaths() const;
QString fileName(int index) const;
QString fileName(int index) const override;
QString origFilePath(int index) const;
qlonglong fileSize(int index) const;
qlonglong fileSize(int index) const override;
qlonglong fileOffset(int index) const;
QVector<TrackerEntry> trackers() const;
QVector<QUrl> urlSeeds() const;
@@ -92,19 +92,21 @@ namespace BitTorrent
PieceRange filePieces(const QString &file) const;
PieceRange filePieces(int fileIndex) const;
void renameFile(int index, const QString &newPath);
void renameFile(int index, const QString &newPath) override;
QString rootFolder() const;
bool hasRootFolder() const;
void stripRootFolder();
void setContentLayout(TorrentContentLayout layout);
std::shared_ptr<lt::torrent_info> nativeInfo() const;
private:
// returns file index or -1 if fileName is not found
int fileIndex(const QString &fileName) const;
void stripRootFolder();
void addRootFolder();
TorrentContentLayout defaultContentLayout() const;
std::shared_ptr<lt::torrent_info> m_nativeInfo;
};
}
#endif // BITTORRENT_TORRENTINFO_H

View File

@@ -28,8 +28,7 @@
* exception statement from your version.
*/
#ifndef BITTORRENT_TRACKER_H
#define BITTORRENT_TRACKER_H
#pragma once
#include <string>
@@ -106,5 +105,3 @@ namespace BitTorrent
QHash<InfoHash, TorrentStats> m_torrents;
};
}
#endif // BITTORRENT_TRACKER_H

View File

@@ -26,8 +26,7 @@
* exception statement from your version.
*/
#ifndef BITTORRENT_TRACKERENTRY_H
#define BITTORRENT_TRACKERENTRY_H
#pragma once
#include <libtorrent/announce_entry.hpp>
@@ -73,5 +72,3 @@ namespace BitTorrent
bool operator==(const TrackerEntry &left, const TrackerEntry &right);
uint qHash(const TrackerEntry &key, uint seed);
}
#endif // BITTORRENT_TRACKERENTRY_H

View File

@@ -26,17 +26,15 @@
* exception statement from your version.
*/
#ifndef FILESYSTEMWATCHER_H
#define FILESYSTEMWATCHER_H
#pragma once
#include <QDir>
#include <QFileSystemWatcher>
#include <QHash>
#include <QtContainerFwd>
#include <QTimer>
#include <QVector>
class QStringList;
/*
* Subclassing QFileSystemWatcher in order to support Network File
* System watching (NFS, CIFS) on Linux and Mac OS.
@@ -70,5 +68,3 @@ private:
QVector<QDir> m_watchedFolders;
QTimer m_watchTimer;
};
#endif // FILESYSTEMWATCHER_H

View File

@@ -28,8 +28,7 @@
*/
#ifndef HTTP_CONNECTION_H
#define HTTP_CONNECTION_H
#pragma once
#include <QElapsedTimer>
#include <QObject>
@@ -66,5 +65,3 @@ namespace Http
QElapsedTimer m_idleTimer;
};
}
#endif // HTTP_CONNECTION_H

View File

@@ -26,8 +26,7 @@
* exception statement from your version.
*/
#ifndef HTTP_IREQUESTHANDLER_H
#define HTTP_IREQUESTHANDLER_H
#pragma once
namespace Http
{
@@ -42,5 +41,3 @@ namespace Http
virtual Response processRequest(const Request &request, const Environment &env) = 0;
};
}
#endif // HTTP_IREQUESTHANDLER_H

View File

@@ -28,8 +28,7 @@
* exception statement from your version.
*/
#ifndef HTTP_REQUESTPARSER_H
#define HTTP_REQUESTPARSER_H
#pragma once
#include "types.h"
@@ -70,5 +69,3 @@ namespace Http
Request m_request;
};
}
#endif // HTTP_REQUESTPARSER_H

View File

@@ -26,8 +26,7 @@
* exception statement from your version.
*/
#ifndef HTTP_RESPONSEBUILDER_H
#define HTTP_RESPONSEBUILDER_H
#pragma once
#include "types.h"
@@ -50,5 +49,3 @@ namespace Http
Response m_response;
};
}
#endif // HTTP_RESPONSEBUILDER_H

View File

@@ -28,8 +28,7 @@
*/
#ifndef HTTP_RESPONSEGENERATOR_H
#define HTTP_RESPONSEGENERATOR_H
#pragma once
class QByteArray;
class QString;
@@ -42,5 +41,3 @@ namespace Http
QString httpDate();
void compressContent(Response &response);
}
#endif // HTTP_RESPONSEGENERATOR_H

View File

@@ -28,8 +28,7 @@
*/
#ifndef HTTP_SERVER_H
#define HTTP_SERVER_H
#pragma once
#include <QSet>
#include <QSslCertificate>
@@ -67,5 +66,3 @@ namespace Http
QSslKey m_key;
};
}
#endif // HTTP_SERVER_H

View File

@@ -27,8 +27,7 @@
* exception statement from your version.
*/
#ifndef HTTP_TYPES_H
#define HTTP_TYPES_H
#pragma once
#include <QHostAddress>
#include <QString>
@@ -127,5 +126,3 @@ namespace Http
}
};
}
#endif // HTTP_TYPES_H

View File

@@ -27,8 +27,7 @@
* exception statement from your version.
*/
#ifndef ICONPROVIDER_H
#define ICONPROVIDER_H
#pragma once
#include <QObject>
@@ -51,5 +50,3 @@ protected:
static IconProvider *m_instance;
};
#endif // ICONPROVIDER_H

View File

@@ -26,8 +26,7 @@
* exception statement from your version.
*/
#ifndef QBT_INDEXRANGE_H
#define QBT_INDEXRANGE_H
#pragma once
#include <QtGlobal>
@@ -38,8 +37,7 @@ class IndexInterval
public:
using IndexType = Index;
// TODO: add constexpr when using C++17
IndexInterval(const IndexType first, const IndexType last)
constexpr IndexInterval(const IndexType first, const IndexType last)
: m_first {first}
, m_last {last}
{
@@ -169,5 +167,3 @@ private:
IndexType m_first;
IndexDiffType m_size;
};
#endif // QBT_INDEXRANGE_H

View File

@@ -31,6 +31,7 @@
#include <algorithm>
#include <QDateTime>
#include <QVector>
namespace
{

View File

@@ -26,15 +26,14 @@
* exception statement from your version.
*/
#ifndef LOGGER_H
#define LOGGER_H
#pragma once
#include <boost/circular_buffer.hpp>
#include <QObject>
#include <QReadWriteLock>
#include <QString>
#include <QVector>
#include <QtContainerFwd>
const int MAX_LOG_MESSAGES = 20000;
@@ -103,5 +102,3 @@ private:
// Helper function
void LogMsg(const QString &message, const Log::MsgType &type = Log::NORMAL);
#endif // LOGGER_H

View File

@@ -34,6 +34,7 @@
#include "base/logger.h"
#include "base/net/downloadmanager.h"
#include "base/version.h"
using namespace Net;

View File

@@ -26,8 +26,7 @@
* exception statement from your version.
*/
#ifndef DNSUPDATER_H
#define DNSUPDATER_H
#pragma once
#include <QDateTime>
#include <QHostAddress>
@@ -84,5 +83,3 @@ namespace Net
QString m_password;
};
}
#endif // DNSUPDATER_H

View File

@@ -27,8 +27,7 @@
* exception statement from your version.
*/
#ifndef NET_DOWNLOADMANAGER_H
#define NET_DOWNLOADMANAGER_H
#pragma once
#include <QHash>
#include <QNetworkAccessManager>
@@ -159,5 +158,3 @@ namespace Net
connect(handler, &DownloadHandler::finished, context, slot);
}
}
#endif // NET_DOWNLOADMANAGER_H

View File

@@ -26,8 +26,7 @@
* exception statement from your version.
*/
#ifndef GEOIPDATABASE_H
#define GEOIPDATABASE_H
#pragma once
#include <QCoreApplication>
#include <QtGlobal>
@@ -100,5 +99,3 @@ private:
quint32 m_size;
uchar *m_data;
};
#endif // GEOIPDATABASE_H

View File

@@ -27,8 +27,7 @@
* exception statement from your version.
*/
#ifndef NET_GEOIPMANAGER_H
#define NET_GEOIPMANAGER_H
#pragma once
#include <QObject>
@@ -73,5 +72,3 @@ namespace Net
static GeoIPManager *m_instance;
};
}
#endif // NET_GEOIPMANAGER_H

View File

@@ -26,8 +26,7 @@
* exception statement from your version.
*/
#ifndef NET_PORTFORWARDER_H
#define NET_PORTFORWARDER_H
#pragma once
#include <QObject>
@@ -53,5 +52,3 @@ namespace Net
static PortForwarder *m_instance;
};
}
#endif // NET_PORTFORWARDER_H

View File

@@ -64,15 +64,15 @@ ProxyConfigurationManager *ProxyConfigurationManager::m_instance = nullptr;
ProxyConfigurationManager::ProxyConfigurationManager(QObject *parent)
: QObject(parent)
{
m_isProxyOnlyForTorrents = settings()->loadValue(KEY_ONLY_FOR_TORRENTS, false).toBool();
m_isProxyOnlyForTorrents = settings()->loadValue(KEY_ONLY_FOR_TORRENTS, false);
m_config.type = static_cast<ProxyType>(
settings()->loadValue(KEY_TYPE, static_cast<int>(ProxyType::None)).toInt());
settings()->loadValue(KEY_TYPE, static_cast<int>(ProxyType::None)));
if ((m_config.type < ProxyType::None) || (m_config.type > ProxyType::SOCKS4))
m_config.type = ProxyType::None;
m_config.ip = settings()->loadValue(KEY_IP, "0.0.0.0").toString();
m_config.port = static_cast<ushort>(settings()->loadValue(KEY_PORT, 8080).toUInt());
m_config.username = settings()->loadValue(KEY_USERNAME).toString();
m_config.password = settings()->loadValue(KEY_PASSWORD).toString();
m_config.ip = settings()->loadValue<QString>(KEY_IP, "0.0.0.0");
m_config.port = settings()->loadValue<ushort>(KEY_PORT, 8080);
m_config.username = settings()->loadValue<QString>(KEY_USERNAME);
m_config.password = settings()->loadValue<QString>(KEY_PASSWORD);
configureProxy();
}

View File

@@ -26,8 +26,7 @@
* exception statement from your version.
*/
#ifndef NET_PROXYCONFIGURATIONMANAGER_H
#define NET_PROXYCONFIGURATIONMANAGER_H
#pragma once
#include <QObject>
@@ -85,5 +84,3 @@ namespace Net
bool m_isProxyOnlyForTorrents;
};
}
#endif // NET_PROXYCONFIGURATIONMANAGER_H

View File

@@ -26,8 +26,7 @@
* exception statement from your version.
*/
#ifndef NET_REVERSERESOLUTION_H
#define NET_REVERSERESOLUTION_H
#pragma once
#include <QCache>
#include <QObject>
@@ -60,5 +59,3 @@ namespace Net
QCache<QHostAddress, QString> m_cache; // <IP, HostName>
};
}
#endif // NET_REVERSERESOLUTION_H

View File

@@ -30,8 +30,7 @@
* This code is based on QxtSmtp from libqxt (http://libqxt.org)
*/
#ifndef SMTP_H
#define SMTP_H
#pragma once
#include <QAbstractSocket>
#include <QByteArray>
@@ -119,5 +118,3 @@ namespace Net
QString m_password;
};
}
#endif // SMTP_H

View File

@@ -41,6 +41,7 @@
#include <QCoreApplication>
#include <QDateTime>
#include <QDir>
#include <QList>
#include <QLocale>
#include <QNetworkCookie>
#include <QSettings>
@@ -1240,26 +1241,6 @@ void Preferences::setMainLastDir(const QString &path)
setValue("MainWindowLastDir", path);
}
QSize Preferences::getPrefSize() const
{
return value("Preferences/State/size").toSize();
}
void Preferences::setPrefSize(const QSize &size)
{
setValue("Preferences/State/size", size);
}
QStringList Preferences::getPrefHSplitterSizes() const
{
return value("Preferences/State/hSplitterSizes").toStringList();
}
void Preferences::setPrefHSplitterSizes(const QStringList &sizes)
{
setValue("Preferences/State/hSplitterSizes", sizes);
}
QByteArray Preferences::getPeerListState() const
{
return value("TorrentProperties/Peers/qt5/PeerListState").toByteArray();

View File

@@ -27,19 +27,17 @@
* exception statement from your version.
*/
#ifndef PREFERENCES_H
#define PREFERENCES_H
#pragma once
#include <QList>
#include <QtContainerFwd>
#include <QVariant>
#include "base/utils/net.h"
class QDateTime;
class QNetworkCookie;
class QSize;
class QStringList;
class QTime;
class QVariant;
enum SchedulerDays
{
@@ -331,10 +329,6 @@ public:
void setMainVSplitterState(const QByteArray &state);
QString getMainLastDir() const;
void setMainLastDir(const QString &path);
QSize getPrefSize() const;
void setPrefSize(const QSize &size);
QStringList getPrefHSplitterSizes() const;
void setPrefHSplitterSizes(const QStringList &sizes);
QByteArray getPeerListState() const;
void setPeerListState(const QByteArray &state);
QString getPropSplitterSizes() const;
@@ -404,5 +398,3 @@ public slots:
void apply();
};
#endif // PREFERENCES_H

View File

@@ -27,8 +27,7 @@
* exception statement from your version.
*/
#ifndef QBT_PROFILE_H
#define QBT_PROFILE_H
#pragma once
#include <memory>
@@ -82,5 +81,3 @@ private:
};
QString specialFolderLocation(SpecialFolder folder);
#endif // QBT_PROFILE_H

Some files were not shown because too many files have changed in this diff Show More