Compare commits

..

67 Commits

Author SHA1 Message Date
sledgehammer999
d2f3d1ec2c Bump to 4.0.4 2018-02-16 00:46:34 +02:00
sledgehammer999
bc6e3ae40d Sync translations from Transifex and run lupdate. 2018-02-09 21:14:58 +02:00
sledgehammer999
b02e239f7c Set default file log size to 65 KiB and delete backup logs older than 1 month. 2018-02-09 20:50:43 +02:00
Luís Pereira
397cd4bf60 Don't set application name twice
It's an artifact introduced by commit b3c73b7868.
2018-02-09 20:50:43 +02:00
Thomas Piccirello
409f972ad3 Add missing units 2018-02-09 20:50:42 +02:00
Thomas Piccirello
267961ffca Right-align stat values 2018-02-09 20:50:41 +02:00
Thomas Piccirello
dff753c452 Remove invalid subnets directly from list 2018-02-09 20:50:41 +02:00
Thomas Piccirello
ce3bafd30d Perform ip string validation inside setWebUiAuthSubnetWhitelist 2018-02-09 20:50:40 +02:00
Thomas Piccirello
e5538d9f25 Separate subnet whitelist options into two lines 2018-02-09 20:50:39 +02:00
Tom Piccirello
7a8a32b1c3 Remove default case, fix #8302 2018-02-09 20:50:39 +02:00
Vladimir Golovnev (Glassez)
cac5e0391b Remove legacy and corrupted RSS settings 2018-02-09 20:50:38 +02:00
Vladimir Golovnev (Glassez)
726790fa93 Require '#pragma once' in new code 2018-02-09 20:50:37 +02:00
Thomas Piccirello
c9c7a5be53 Add default case 2018-02-09 20:50:36 +02:00
sledgehammer999
1495513cfc Revert "Remove examples from gpl.html. Closes #7749."
The GPL folks are a bit overzealous. See https://www.gnu.org/licenses/gpl-faq.html#GPLOmitPreamble

This reverts commit 5cf4f00824.
2018-02-09 20:50:36 +02:00
sledgehammer999
085afaac14 Sync translations from Transifex and run lupdate. 2018-02-09 20:50:34 +02:00
Thomas Piccirello
d58a54c758 Use switch statement 2018-02-09 20:50:33 +02:00
Thomas Piccirello
78d9bcb6a1 Match webui statuses to gui, closes #7516 2018-02-09 20:50:33 +02:00
Tom Piccirello
1a43cd329d Only add search separators as needed 2018-02-09 20:50:32 +02:00
Jesse Bryan
2fe687eeca transferlist: added a force reannounce option. closes #6448. 2018-02-09 20:50:31 +02:00
Chocobo1
107bd8a54f Torrent creator: raise maximum piece size to 32 MiB 2018-02-09 20:50:31 +02:00
Chocobo1
865df3fcf1 Fix translation context.
Partially addresses #8220.

Also sort include headers
2018-02-09 20:50:30 +02:00
sledgehammer999
cbf9c52462 Update copyright year. 2018-02-09 20:50:29 +02:00
Chocobo1
171e25e962 Fix translation context. Closes #8211. 2018-02-09 20:50:11 +02:00
sledgehammer999
239d14fd10 Update configure version info. 2018-01-03 23:29:59 +02:00
sledgehammer999
0b7a175156 Update libtorrent bottle for Travis. 2018-01-03 23:28:24 +02:00
Chocobo1
b37dbb60b5 Sort filename lists in .pri files 2018-01-03 23:28:18 +02:00
sledgehammer999
d5acd1f210 configure: Parse all compiler related flags together. 2018-01-03 03:18:15 +02:00
sledgehammer999
65eda4a68e Fix splitting of compiler flags in configure.
Autoconf removes a set of [] during script translation, resulting in a wrong sed command.
2018-01-03 03:18:14 +02:00
sledgehammer999
7209881025 Fix constant status of '[F] Downloading'. Closes #7628. 2018-01-03 03:18:13 +02:00
Chocobo1
a5d0a4b619 Fix column size too narrow on resize
Instead of giving a value, just resize to the content size
2018-01-03 03:18:13 +02:00
Chocobo1
79276a8786 Resize dialog size on high DPI monitors 2018-01-03 03:18:12 +02:00
Chocobo1
fa2b645a64 Fix gui issues on high DPI monitor
Fix LineEdit widget size issues
Up-scale the icons on statusbar
Up-scale the icons in options dialog. Closes #7729.
Fix small icons in cookie manager
Fix progress bar height
Fix small icons in confirm delete dialog
Fix small icons in options dialog
Fix small images in about dialog
2018-01-03 03:18:11 +02:00
Chocobo1
4d5d6df734 Tweak spacing 2018-01-03 03:18:10 +02:00
Chocobo1
2c39b69c18 Cleanup
Use Qt5 connect syntax
Reorder include headers
2018-01-03 03:18:10 +02:00
Chocobo1
13c0077e95 Revert "Run external program" function
This revert df95efe33e partially
2018-01-03 03:18:09 +02:00
Vladimir Golovnev (Glassez)
9299e3f371 Don't process new/updated RSS rules when disabled 2018-01-03 03:18:08 +02:00
Thomas Piccirello
b9ddc6ee86 Use https for www.qbittorrent.org 2018-01-03 03:18:07 +02:00
Thomas Piccirello
276856a614 Add Time Active column 2018-01-03 03:18:07 +02:00
Thomas Piccirello
fbd6a8a0da Add Tags columns 2018-01-03 03:18:06 +02:00
Thomas Piccirello
6fc18b4af6 Reposition Total Size column to match gui 2018-01-03 03:18:05 +02:00
Thomas Piccirello
44d633fb68 Make value formatting consistent with GUI 2017-12-24 03:01:17 +02:00
Thomas Piccirello
eb4bf6cc68 Add "Remaining" and "Availability" columns to webui Content tab 2017-12-24 03:01:15 +02:00
jan.karberg
6db6c850eb search only when category is supported by plugin Closes #8053 2017-12-24 03:01:14 +02:00
thalieht
02ae1e3734 Make peer information flags in peerlist more readable 2017-12-24 03:01:13 +02:00
sledgehammer999
eb887139fd Fix application of speed limits on LAN and μTP connections. Closes #7745. 2017-12-24 03:01:12 +02:00
sledgehammer999
84805f7fb8 Fix natural sorting when the common part of 2 strings ends partially in a number which continues in the uncommon part.
Closes #8080 #6732.
2017-12-24 03:01:11 +02:00
sledgehammer999
2719131ed2 Simplify sorting code. 2017-12-24 03:01:10 +02:00
sledgehammer999
52401bd2b0 Fix sorting of country flags column in Peers tab. 2017-12-24 03:01:09 +02:00
Vladimir Golovnev (Glassez)
4834703bc4 Fix RSS rule updated when deleting
Closes #8094
2017-12-24 03:01:08 +02:00
Chocobo1
3ed73244b1 Use standard folder icon for open file behavior on Windows. Closes #7880. 2017-12-24 03:01:07 +02:00
vit9696
97cd430125 Fix cmd+w not closing the main window on macOS 2017-12-24 03:01:06 +02:00
vit9696
d202b85d51 Fix Finder reveal in preview and torrent contents 2017-12-24 03:01:05 +02:00
vit9696
c51b79e9fc Put macOS specific functions to MacUtils namespace 2017-12-24 03:01:04 +02:00
vit9696
4449018207 Fix torrent file selection in Finder on mac 2017-12-24 03:01:03 +02:00
Chocobo1
ced8e41473 Add source field in Torrent creator. Closes #7965.
This field is often used for cross-seeding between (private) trackers.
2017-12-24 03:01:02 +02:00
Chocobo1
2c66ed6708 Add struct TorrentCreatorParams for passing parameters
Filter out continuous newlines in Trackers field
Avoid adding empty url seed entries

Cleanup:
  Replace boost::bind
  Add const
  Use nullptr
  Use QString::SkipEmptyParts
  Rename variables
  Throw proper exception type
2017-12-24 03:01:01 +02:00
Chocobo1
c7d3d6ac90 WebUI: Only prepend scheme when it is not present. Closes #8057. 2017-12-24 03:00:55 +02:00
sledgehammer999
13210b3e9f Bump to 4.0.3 2017-12-17 23:31:59 +02:00
sledgehammer999
6e622fc23b Sync translations from Transifex and run lupdate. 2017-12-17 23:19:17 +02:00
Vladimir Golovnev (Glassez)
ae35111b59 Fix WebUI is not reachable via IPv6 2017-12-17 23:07:59 +02:00
Chocobo1
e1c3d419a7 Disable the "?" help button in all dialogs on Windows. Closes #7365. 2017-12-17 23:07:58 +02:00
Chocobo1
7396b8adba Partial revert eac8838dc2. Fixes #7952.
mapFromSource() didn't work as expected, when used in lessThan(), it sometimes
returns an invalid QModelIndex.
A crash is observed when filtering source model via filterAcceptsRow() in #7952,
the crash is due to endless recursive of filterAcceptsRow() & lessThan() calling
each other and mapFromSource() is the culprit of it.
2017-12-17 23:07:57 +02:00
Chocobo1
c09001545d Allow to drag-n-drop URLs into mainwindow to initiate download
Fix issue: https://github.com/qbittorrent/qBittorrent/issues/7785#issuecomment-347092418
Minor refactor
2017-12-17 23:07:55 +02:00
Chocobo1
f8d4315f7e [WebUI] Use POST for logout command
This is to avoid browser being smart to prefetch the link then logging
out the user.
2017-12-17 23:07:54 +02:00
Chocobo1
1fa2957d27 [WebUI] Add check to avoid type error after logout 2017-12-17 23:07:53 +02:00
Chocobo1
ade50d2b53 Fix missing qbt logo on login page in webUI. Closes #7953. 2017-12-17 23:07:52 +02:00
sledgehammer999
0fa1d35b87 Add height padding to the transfer list icons. Closes #7951. 2017-12-17 23:07:29 +02:00
189 changed files with 41783 additions and 42541 deletions

View File

@@ -76,10 +76,13 @@ before_install:
- shopt -s expand_aliases
- alias make="colormake -j3" # Using nprocs/2 sometimes may fail (gcc is killed by system)
#- libt_path="$HOME/libt_install"
#- ltconf="$ltconf --prefix="$libt_path" --disable-geoip"
- qbt_path="$HOME/qbt_install"
- qbtconf="$qbtconf --prefix="$qbt_path" PKG_CONFIG_PATH="$libt_path/lib/pkgconfig":/opt/qt55/lib/pkgconfig:$PKG_CONFIG_PATH"
- |
if [ "$TRAVIS_OS_NAME" = "linux" ]; then
qbtconf="$qbtconf --prefix="$qbt_path" PKG_CONFIG_PATH=/opt/qt55/lib/pkgconfig:$PKG_CONFIG_PATH"
else
qbtconf="$qbtconf --prefix="$qbt_path""
fi
# options for specific branches
- if [ "$gui" = false ]; then qbtconf="$qbtconf --disable-gui" ; fi
@@ -131,13 +134,13 @@ install:
cp "version" $HOME/hombebrew_cache
cd "$HOME/hombebrew_cache"
wget https://builds.shiki.hu/homebrew/libtorrent-rasterbar.rb
wget https://builds.shiki.hu/homebrew/libtorrent-rasterbar-1.0.11+git20170910.6d5625e0ea.el_capitan.bottle.tar.gz
wget https://builds.shiki.hu/homebrew/libtorrent-rasterbar-1.1.6+git20180101.b45acf28a5+patched-configure.el_capitan.bottle.tar.gz
fi
# Copy custom libtorrent bottle to homebrew's cache so it can find and install it
# Also install our custom libtorrent formula by passing the local path to it
# These 2 files are restored from Travis' cache.
cp "$HOME/hombebrew_cache/libtorrent-rasterbar-1.0.11+git20170910.6d5625e0ea.el_capitan.bottle.tar.gz" "$(brew --cache)"
cp "$HOME/hombebrew_cache/libtorrent-rasterbar-1.1.6+git20180101.b45acf28a5+patched-configure.el_capitan.bottle.tar.gz" "$(brew --cache)"
brew install "$HOME/hombebrew_cache/libtorrent-rasterbar.rb"
if [ "$build_system" = "cmake" ]; then
@@ -168,11 +171,15 @@ script:
BUILD_TOOL="ninja"
fi
if [ "$build_system" = "qmake" ]; then
./bootstrap.sh && ./configure $qbtconf
if [ "$TRAVIS_OS_NAME" = "osx" ]; then
# For some reason for RC_1_1 we need to also specify the OpenSSL compiler/linker flags
# Homebrew doesn't symlink OpenSSL for security reasons
./bootstrap.sh && ./configure $qbtconf CXXFLAGS="$(PKG_CONFIG_PATH="/usr/local/opt/openssl/lib/pkgconfig:$PKG_CONFIG_PATH" pkg-config --cflags openssl)" LDFLAGS="$(PKG_CONFIG_PATH="/usr/local/opt/openssl/lib/pkgconfig:$PKG_CONFIG_PATH" pkg-config --libs openssl)"
sed -i "" -e "s/^\(CC.*&&\).*$/\1 $CC/" src/Makefile # workaround for Qt & ccache: https://bugreports.qt.io/browse/QTBUG-31034
sed -i "" -e "s/^\(CXX.*&&\).*$/\1 $CXX/" src/Makefile
sed -i "" -e 's/^\(CXXFLAGS.*\)$/\1 -Wno-unused-local-typedefs -Wno-inconsistent-missing-override/' src/Makefile
else
./bootstrap.sh && ./configure $qbtconf
fi
BUILD_TOOL="make"
fi

View File

@@ -240,7 +240,23 @@ Example:
```
### 9. Misc. ###
### 9. Include guard. ###
`#pragma once` should be used instead of "include guard" in new code:
```c++
// examplewidget.h
#pragma once
#include <QWidget>
class ExampleWidget : public QWidget
{
// (some code omitted)
};
```
### 10. Misc. ###
* Line breaks for long lines with operation:

View File

@@ -1,3 +1,52 @@
* Fri Feb 16 2018 - sledgehammer999 <sledgehammer999@qbittorrent.org> - v4.0.4
- FEATURE: Add source field in Torrent creator. Closes #7965. (Chocobo1)
- FEATURE: Torrent creator: raise maximum piece size to 32 MiB (Chocobo1)
- FEATURE: Add a force reannounce option in the transfer list context menu. Closes #6448. (Jesse Bryan)
- BUGFIX: Fix sorting of country flags column in Peers tab. (sledgehammer999)
- BUGFIX: Fix natural sorting when the common part of 2 strings ends partially in a number which continues in the uncommon part. Closes #8080 #6732. (sledgehammer999)
- BUGFIX: Fix application of speed limits on LAN and μTP connections. Closes #7745. (sledgehammer999)
- BUGFIX: Make peer information flags in peerlist more readable. (thalieht)
- BUGFIX: Fix gui issues on high DPI monitor. (Chocobo1)
- BUGFIX: Fix dialog and column size on high DPI monitors. (Chocobo1)
- BUGFIX: Fix constant status of '[F] Downloading'. Closes #7628. (sledgehammer999)
- BUGFIX: Fix translation context. Closes #8211. (sledgehammer999)
- BUGFIX: Separate subnet whitelist options into two lines. (Thomas Piccirello)
- BUGFIX: Don't set application name twice. (Luís Pereira)
- BUGFIX: Set default file log size to 65 KiB and delete backup logs older than 1 month. (sledgehammer999)
- WEBUI: Only prepend scheme when it is not present. Closes #8057. (Chocobo1)
- WEBUI: Add "Remaining" and "Availability" columns to webui Content tab. (Thomas Piccirello)
- WEBUI: Make value formatting consistent with GUI (Thomas Piccirello)
- WEBUI: Reposition Total Size column to match gui (Thomas Piccirello)
- WEBUI: Add Tags and Time Active columns (Thomas Piccirello)
- WEBUI: Use https for www.qbittorrent.org (Thomas Piccirello)
- WEBUI: Match webui statuses to gui, closes #7516 (Thomas Piccirello)
- WEBUI: Right-align stat values (Thomas Piccirello)
- WEBUI: Add missing units. (Thomas Piccirello)
- RSS: Fix crash when deleting rule because it tries to update. Closes #8094 (glassez)
- RSS: Don't process new/updated RSS rules when disabled (glassez)
- RSS: Remove legacy and corrupted RSS settings (glassez)
- SEARCH: Search only when category is supported by plugin. Closes #8053. (jan.karberg)
- SEARCH: Only add search separators as needed. (Thomas Piccirello)
- COSMETIC: Tweak spacing in torrent properties widget and speed widget. (Chocobo1)
- WINDOWS: Use standard folder icon for open file behavior on Windows. Closes #7880. (Chocobo1)
- WINDOWS: Revert "Run external program" function. Now you will not be able to directly run batch scripts. (Chocobo1)
- MACOS: Fix torrent file selection in Finder on mac (vit9696)
- MACOS: Fix Finder reveal in preview and torrent contents (vit9696)
- MACOS: Fix cmd+w not closing the main window on macOS (vit9696)
- OTHER: Fix splitting of compiler flags in configure. Autoconf removes a set of [] during script translation, resulting in a wrong sed command. (sledgehammer999)
- OTHER: configure: Parse all compiler related flags together. (sledgehammer999)
- OTHER: Update copyright year. (sledgehammer999)
* Sun Dec 17 2017 - sledgehammer999 <sledgehammer999@qbittorrent.org> - v4.0.3
- BUGFIX: Add height padding to the transfer list icons. Closes #7951. (sledgehammer999)
- BUGFIX: Allow to drag-n-drop URLs into mainwindow to initiate download. (Chocobo1)
- BUGFIX: Fix crash when fitlering search results. Stable sorting is removed. Closes #7952.(Chocobo1)
- WEBUI: Fix missing qbt logo on login page in webUI. Closes #7953. (Chocobo1)
- WEBUI: Add check to avoid type error after logout. (Chocobo1)
- WEBUI: Use POST for logout command. This is to avoid browser being smart to prefetch the link then logging out the user. (Chocobo1)
- WEBUI: Fix WebUI is not reachable via IPv6. (glassez)
- WINDOWS: Disable the "?" help button in all dialogs on Windows. Closes #7365. Requires Qt 5.10. (Chocobo1)
* Fri Dec 01 2017 - sledgehammer999 <sledgehammer999@qbittorrent.org> - v4.0.2
- BUGFIX: Fix crash on some systems when creating address object for 255.255.255.255. Closes #7735. (sledgehammer999)
- PERFORMANCE: Change MixedModeAlgorithm default to TCP. This was the v3_3_x default and should sustain higher speeds. Closes #7779. (Chocobo1)

View File

@@ -35,7 +35,7 @@ You can also download it from [here](https://github.com/qbittorrent/qBittorrent/
### Misc:
For more information please visit:
http://www.qbittorrent.org
https://www.qbittorrent.org
or our wiki here:
http://wiki.qbittorrent.org

51
configure vendored
View File

@@ -1,6 +1,6 @@
#! /bin/sh
# Guess values for system-dependent variables and create Makefiles.
# Generated by GNU Autoconf 2.69 for qbittorrent v3.2.0alpha.
# Generated by GNU Autoconf 2.69 for qbittorrent v4.0.4.
#
# Report bugs to <bugs.qbittorrent.org>.
#
@@ -580,10 +580,10 @@ MAKEFLAGS=
# Identity of this package.
PACKAGE_NAME='qbittorrent'
PACKAGE_TARNAME='qbittorrent'
PACKAGE_VERSION='v3.2.0alpha'
PACKAGE_STRING='qbittorrent v3.2.0alpha'
PACKAGE_VERSION='v4.0.4'
PACKAGE_STRING='qbittorrent v4.0.4'
PACKAGE_BUGREPORT='bugs.qbittorrent.org'
PACKAGE_URL='http://www.qbittorrent.org/'
PACKAGE_URL='https://www.qbittorrent.org/'
ac_subst_vars='am__EXEEXT_FALSE
am__EXEEXT_TRUE
@@ -690,6 +690,7 @@ infodir
docdir
oldincludedir
includedir
runstatedir
localstatedir
sharedstatedir
sysconfdir
@@ -783,6 +784,7 @@ datadir='${datarootdir}'
sysconfdir='${prefix}/etc'
sharedstatedir='${prefix}/com'
localstatedir='${prefix}/var'
runstatedir='${localstatedir}/run'
includedir='${prefix}/include'
oldincludedir='/usr/include'
docdir='${datarootdir}/doc/${PACKAGE_TARNAME}'
@@ -1035,6 +1037,15 @@ do
| -silent | --silent | --silen | --sile | --sil)
silent=yes ;;
-runstatedir | --runstatedir | --runstatedi | --runstated \
| --runstate | --runstat | --runsta | --runst | --runs \
| --run | --ru | --r)
ac_prev=runstatedir ;;
-runstatedir=* | --runstatedir=* | --runstatedi=* | --runstated=* \
| --runstate=* | --runstat=* | --runsta=* | --runst=* | --runs=* \
| --run=* | --ru=* | --r=*)
runstatedir=$ac_optarg ;;
-sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
ac_prev=sbindir ;;
-sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
@@ -1172,7 +1183,7 @@ fi
for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \
datadir sysconfdir sharedstatedir localstatedir includedir \
oldincludedir docdir infodir htmldir dvidir pdfdir psdir \
libdir localedir mandir
libdir localedir mandir runstatedir
do
eval ac_val=\$$ac_var
# Remove trailing slashes.
@@ -1285,7 +1296,7 @@ if test "$ac_init_help" = "long"; then
# Omit some internal or obsolete options to make the list less imposing.
# This message is too long to be a string in the A/UX 3.1 sh.
cat <<_ACEOF
\`configure' configures qbittorrent v3.2.0alpha to adapt to many kinds of systems.
\`configure' configures qbittorrent v4.0.4 to adapt to many kinds of systems.
Usage: $0 [OPTION]... [VAR=VALUE]...
@@ -1325,6 +1336,7 @@ Fine tuning of the installation directories:
--sysconfdir=DIR read-only single-machine data [PREFIX/etc]
--sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com]
--localstatedir=DIR modifiable single-machine data [PREFIX/var]
--runstatedir=DIR modifiable per-process data [LOCALSTATEDIR/run]
--libdir=DIR object code libraries [EPREFIX/lib]
--includedir=DIR C header files [PREFIX/include]
--oldincludedir=DIR C header files for non-gcc [/usr/include]
@@ -1355,7 +1367,7 @@ fi
if test -n "$ac_init_help"; then
case $ac_init_help in
short | recursive ) echo "Configuration of qbittorrent v3.2.0alpha:";;
short | recursive ) echo "Configuration of qbittorrent v4.0.4:";;
esac
cat <<\_ACEOF
@@ -1426,7 +1438,7 @@ Use these variables to override the choices made by `configure' or to help
it to find libraries and programs with nonstandard names/locations.
Report bugs to <bugs.qbittorrent.org>.
qbittorrent home page: <http://www.qbittorrent.org/>.
qbittorrent home page: <https://www.qbittorrent.org/>.
_ACEOF
ac_status=$?
fi
@@ -1489,7 +1501,7 @@ fi
test -n "$ac_init_help" && exit $ac_status
if $ac_init_version; then
cat <<\_ACEOF
qbittorrent configure v3.2.0alpha
qbittorrent configure v4.0.4
generated by GNU Autoconf 2.69
Copyright (C) 2012 Free Software Foundation, Inc.
@@ -1628,7 +1640,7 @@ cat >config.log <<_ACEOF
This file contains any messages produced by compilers while
running configure, to aid debugging if configure makes a mistake.
It was created by qbittorrent $as_me v3.2.0alpha, which was
It was created by qbittorrent $as_me v4.0.4, which was
generated by GNU Autoconf 2.69. Invocation command line was
$ $0 $@
@@ -3806,7 +3818,7 @@ fi
# Define the identity of the package.
PACKAGE='qbittorrent'
VERSION='v3.2.0alpha'
VERSION='v4.0.4'
cat >>confdefs.h <<_ACEOF
@@ -5489,7 +5501,7 @@ extract() {
new_line='
'
# Convert " -" to "\n" if not between quotes and remove possible leading white spaces
string=$(echo " $*" | $SED -e "s: -:\\${new_line}:g" -e 's:"\(.*\)\n\(.*\)":\"\1 -\2":g' -e "s:'\(.*\)\n\(.*\)':\'\1 -\2':g" -e 's/^[:space:]*//')
string=$(echo " $*" | $SED -e "s: -:\\${new_line}:g" -e 's:"\(.*\)\n\(.*\)":\"\1 -\2":g' -e "s:'\(.*\)\n\(.*\)':\'\1 -\2':g" -e 's/^[[:space:]]*//')
SAVEIFS=$IFS
IFS=$(printf "\n\b")
for i in $string; do
@@ -5503,9 +5515,8 @@ extract() {
IFS=$SAVEIFS
}
extract $CPPFLAGS
extract "$CFLAGS $CPPFLAGS $CXXFLAGS"
QBT_ADD_DEFINES="$QBT_ADD_DEFINES $QBT_CONF_DEFINES"
QBT_CONF_EXTRA_CFLAGS="$QBT_CONF_EXTRA_CFLAGS $CXXFLAGS"
# Substitute the values of these vars in conf.pri.in
@@ -6087,7 +6098,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
# report actual input values of CONFIG_FILES etc. instead of their
# values after options handling.
ac_log="
This file was extended by qbittorrent $as_me v3.2.0alpha, which was
This file was extended by qbittorrent $as_me v4.0.4, which was
generated by GNU Autoconf 2.69. Invocation command line was
CONFIG_FILES = $CONFIG_FILES
@@ -6139,13 +6150,13 @@ Configuration commands:
$config_commands
Report bugs to <bugs.qbittorrent.org>.
qbittorrent home page: <http://www.qbittorrent.org/>."
qbittorrent home page: <https://www.qbittorrent.org/>."
_ACEOF
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
ac_cs_version="\\
qbittorrent config.status v3.2.0alpha
qbittorrent config.status v4.0.4
configured by $0, generated by GNU Autoconf 2.69,
with options \\"\$ac_cs_config\\"
@@ -7402,7 +7413,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
# report actual input values of CONFIG_FILES etc. instead of their
# values after options handling.
ac_log="
This file was extended by qbittorrent $as_me v3.2.0alpha, which was
This file was extended by qbittorrent $as_me v4.0.4, which was
generated by GNU Autoconf 2.69. Invocation command line was
CONFIG_FILES = $CONFIG_FILES
@@ -7454,13 +7465,13 @@ Configuration commands:
$config_commands
Report bugs to <bugs.qbittorrent.org>.
qbittorrent home page: <http://www.qbittorrent.org/>."
qbittorrent home page: <https://www.qbittorrent.org/>."
_ACEOF
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
ac_cs_version="\\
qbittorrent config.status v3.2.0alpha
qbittorrent config.status v4.0.4
configured by $0, generated by GNU Autoconf 2.69,
with options \\"\$ac_cs_config\\"

View File

@@ -1,4 +1,4 @@
AC_INIT([qbittorrent], [v3.2.0alpha], [bugs.qbittorrent.org], [], [http://www.qbittorrent.org/])
AC_INIT([qbittorrent], [v4.0.4], [bugs.qbittorrent.org], [], [https://www.qbittorrent.org/])
AC_CONFIG_AUX_DIR([build-aux])
AC_CONFIG_MACRO_DIR([m4])
AC_PROG_CC
@@ -190,7 +190,7 @@ extract() {
new_line='
'
# Convert " -" to "\n" if not between quotes and remove possible leading white spaces
string=$(echo " $*" | $SED -e "s: -:\\${new_line}:g" -e 's:"\(.*\)\n\(.*\)":\"\1 -\2":g' -e "s:'\(.*\)\n\(.*\)':\'\1 -\2':g" -e 's/^[[:space:]]*//')
string=$(echo " $*" | $SED -e "s: -:\\${new_line}:g" -e 's:"\(.*\)\n\(.*\)":\"\1 -\2":g' -e "s:'\(.*\)\n\(.*\)':\'\1 -\2':g" -e 's/^[[[:space:]]]*//')
SAVEIFS=$IFS
IFS=$(printf "\n\b")
for i in $string; do
@@ -204,9 +204,8 @@ extract() {
IFS=$SAVEIFS
}
extract $CPPFLAGS
extract "$CFLAGS $CPPFLAGS $CXXFLAGS"
QBT_ADD_DEFINES="$QBT_ADD_DEFINES $QBT_CONF_DEFINES"
QBT_CONF_EXTRA_CFLAGS="$QBT_CONF_EXTRA_CFLAGS $CXXFLAGS"
# Substitute the values of these vars in conf.pri.in
AC_SUBST(QBT_CONF_INCLUDES)

4
dist/mac/Info.plist vendored
View File

@@ -45,7 +45,7 @@
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>4.0.2</string>
<string>4.0.4</string>
<key>CFBundleSignature</key>
<string>qBit</string>
<key>CFBundleExecutable</key>
@@ -59,7 +59,7 @@
<key>NSAppleScriptEnabled</key>
<string>YES</string>
<key>NSHumanReadableCopyright</key>
<string>Copyright © 2006-2017 The qBittorrent project</string>
<string>Copyright © 2006-2018 The qBittorrent project</string>
<key>UTExportedTypeDeclarations</key>
<array>
<dict>

View File

@@ -56,7 +56,7 @@
</image>
</screenshot>
</screenshots>
<url type="homepage">http://www.qbittorrent.org/</url>
<url type="homepage">https://www.qbittorrent.org/</url>
<update_contact>sledgehammer999@qbittorrent.org</update_contact>
<developer_name>The qBittorrent Project</developer_name>
<url type="bugtracker">http://bugs.qbittorrent.org/</url>

View File

@@ -86,7 +86,7 @@ Section $(inst_qbt_req) ;"qBittorrent (required)"
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\qBittorrent" "UninstallString" '"$INSTDIR\uninst.exe"'
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\qBittorrent" "DisplayIcon" '"$INSTDIR\qbittorrent.exe",0'
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\qBittorrent" "Publisher" "The qBittorrent project"
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\qBittorrent" "URLInfoAbout" "http://www.qbittorrent.org"
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\qBittorrent" "URLInfoAbout" "https://www.qbittorrent.org"
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\qBittorrent" "DisplayVersion" "${PROG_VERSION}"
WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\qBittorrent" "NoModify" 1
WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\qBittorrent" "NoRepair" 1

View File

@@ -27,7 +27,7 @@ XPStyle on
!define CSIDL_LOCALAPPDATA '0x1C' ;Local Application Data path
; Program specific
!define PROG_VERSION "4.0.2"
!define PROG_VERSION "4.0.4"
!define MUI_FINISHPAGE_RUN
!define MUI_FINISHPAGE_RUN_FUNCTION PageFinishRun
@@ -50,7 +50,7 @@ XPStyle on
;Installer Version Information
VIAddVersionKey "ProductName" "qBittorrent"
VIAddVersionKey "CompanyName" "The qBittorrent project"
VIAddVersionKey "LegalCopyright" "Copyright ©2006-2017 The qBittorrent project"
VIAddVersionKey "LegalCopyright" "Copyright ©2006-2018 The qBittorrent project"
VIAddVersionKey "FileDescription" "qBittorrent - A Bittorrent Client"
VIAddVersionKey "FileVersion" "${PROG_VERSION}"

View File

@@ -87,7 +87,7 @@ namespace
const QString KEY_FILELOGGER_PATH = FILELOGGER_SETTINGS_KEY("Path");
const QString KEY_FILELOGGER_BACKUP = FILELOGGER_SETTINGS_KEY("Backup");
const QString KEY_FILELOGGER_DELETEOLD = FILELOGGER_SETTINGS_KEY("DeleteOld");
const QString KEY_FILELOGGER_MAXSIZE = FILELOGGER_SETTINGS_KEY("MaxSize");
const QString KEY_FILELOGGER_MAXSIZEBYTES = FILELOGGER_SETTINGS_KEY("MaxSizeBytes");
const QString KEY_FILELOGGER_AGE = FILELOGGER_SETTINGS_KEY("Age");
const QString KEY_FILELOGGER_AGETYPE = FILELOGGER_SETTINGS_KEY("AgeType");
@@ -98,6 +98,10 @@ namespace
const char PARAMS_SEPARATOR[] = "|";
const QString DEFAULT_PORTABLE_MODE_PROFILE_DIR = QLatin1String("profile");
const int MIN_FILELOG_SIZE = 1024; // 1KiB
const int MAX_FILELOG_SIZE = 1000 * 1024 * 1024; // 1000MiB
const int DEFAULT_FILELOG_SIZE = 65 * 1024; // 65KiB
}
Application::Application(const QString &id, int &argc, char **argv)
@@ -128,7 +132,6 @@ Application::Application(const QString &id, int &argc, char **argv)
if (m_commandLineArgs.webUiPort > 0) // it will be -1 when user did not set any value
Preferences::instance()->setWebUiPort(m_commandLineArgs.webUiPort);
setApplicationName("qBittorrent");
initializeTranslation();
#if !defined(DISABLE_GUI)
@@ -221,29 +224,22 @@ void Application::setFileLoggerDeleteOld(bool value)
int Application::fileLoggerMaxSize() const
{
int val = settings()->loadValue(KEY_FILELOGGER_MAXSIZE, 10).toInt();
if (val < 1)
return 1;
if (val > 1000)
return 1000;
return val;
int val = settings()->loadValue(KEY_FILELOGGER_MAXSIZEBYTES, DEFAULT_FILELOG_SIZE).toInt();
return std::min(std::max(val, MIN_FILELOG_SIZE), MAX_FILELOG_SIZE);
}
void Application::setFileLoggerMaxSize(const int value)
void Application::setFileLoggerMaxSize(const int bytes)
{
int clampedValue = std::min(std::max(bytes, MIN_FILELOG_SIZE), MAX_FILELOG_SIZE);
if (m_fileLogger)
m_fileLogger->setMaxSize(value);
settings()->storeValue(KEY_FILELOGGER_MAXSIZE, std::min(std::max(value, 1), 1000));
m_fileLogger->setMaxSize(clampedValue);
settings()->storeValue(KEY_FILELOGGER_MAXSIZEBYTES, clampedValue);
}
int Application::fileLoggerAge() const
{
int val = settings()->loadValue(KEY_FILELOGGER_AGE, 6).toInt();
if (val < 1)
return 1;
if (val > 365)
return 365;
return val;
int val = settings()->loadValue(KEY_FILELOGGER_AGE, 1).toInt();
return std::min(std::max(val, 1), 365);
}
void Application::setFileLoggerAge(const int value)
@@ -291,27 +287,6 @@ void Application::runExternalProgram(BitTorrent::TorrentHandle *const torrent) c
#if defined(Q_OS_UNIX)
QProcess::startDetached(QLatin1String("/bin/sh"), {QLatin1String("-c"), program});
#elif defined(Q_OS_WIN) // test cmd: `echo "%F" > "c:\ab ba.txt"`
program.prepend(QLatin1String("\"")).append(QLatin1String("\""));
program.prepend(Utils::Misc::windowsSystemPath() + QLatin1String("\\cmd.exe /C "));
const int cmdMaxLength = 32768; // max length (incl. terminate char) for `lpCommandLine` in `CreateProcessW()`
if ((program.size() + 1) > cmdMaxLength) {
logger->addMessage(tr("Torrent: %1, run external program command too long (length > %2), execution failed.").arg(torrent->name()).arg(cmdMaxLength), Log::CRITICAL);
return;
}
STARTUPINFOW si = {0};
si.cb = sizeof(si);
PROCESS_INFORMATION pi = {0};
WCHAR *arg = new WCHAR[program.size() + 1];
program.toWCharArray(arg);
arg[program.size()] = L'\0';
if (CreateProcessW(NULL, arg, NULL, NULL, FALSE, CREATE_NO_WINDOW, NULL, NULL, &si, &pi)) {
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
}
delete[] arg;
#else
QProcess::startDetached(program);
#endif

View File

@@ -101,7 +101,7 @@ public:
bool isFileLoggerDeleteOld() const;
void setFileLoggerDeleteOld(bool value);
int fileLoggerMaxSize() const;
void setFileLoggerMaxSize(const int value);
void setFileLoggerMaxSize(const int bytes);
int fileLoggerAge() const;
void setFileLoggerAge(const int value);
int fileLoggerAgeType() const;

View File

@@ -135,7 +135,7 @@ void FileLogger::addLogMessage(const Log::Msg &msg)
str << QDateTime::fromMSecsSinceEpoch(msg.timestamp).toString(Qt::ISODate) << " - " << msg.message << endl;
if (m_backup && (m_logFile->size() >= (m_maxSize * 1024 * 1024))) {
if (m_backup && (m_logFile->size() >= m_maxSize)) {
closeLogFile();
int counter = 0;
QString backupLogFilename = m_path + ".bak";

View File

@@ -212,6 +212,10 @@ int main(int argc, char *argv[])
// 3. https://bugreports.qt.io/browse/QTBUG-46015
qputenv("QT_BEARER_POLL_TIMEOUT", QByteArray::number(-1));
#if (QT_VERSION >= QT_VERSION_CHECK(5, 10, 0))
// this is the default in Qt6
app->setAttribute(Qt::AA_DisableWindowContextHelpButton);
#endif
#endif
#if defined(Q_OS_MAC)

View File

@@ -1,124 +1,124 @@
HEADERS += \
$$PWD/asyncfilestorage.h \
$$PWD/types.h \
$$PWD/tristatebool.h \
$$PWD/bittorrent/addtorrentparams.h \
$$PWD/bittorrent/cachestatus.h \
$$PWD/bittorrent/infohash.h \
$$PWD/bittorrent/magneturi.h \
$$PWD/bittorrent/peerinfo.h \
$$PWD/bittorrent/private/bandwidthscheduler.h \
$$PWD/bittorrent/private/filterparserthread.h \
$$PWD/bittorrent/private/resumedatasavingmanager.h \
$$PWD/bittorrent/private/speedmonitor.h \
$$PWD/bittorrent/private/statistics.h \
$$PWD/bittorrent/session.h \
$$PWD/bittorrent/sessionstatus.h \
$$PWD/bittorrent/torrentcreatorthread.h \
$$PWD/bittorrent/torrenthandle.h \
$$PWD/bittorrent/torrentinfo.h \
$$PWD/bittorrent/tracker.h \
$$PWD/bittorrent/trackerentry.h \
$$PWD/filesystemwatcher.h \
$$PWD/logger.h \
$$PWD/settingsstorage.h \
$$PWD/settingvalue.h \
$$PWD/preferences.h \
$$PWD/indexrange.h \
$$PWD/iconprovider.h \
$$PWD/http/irequesthandler.h \
$$PWD/global.h \
$$PWD/http/connection.h \
$$PWD/http/irequesthandler.h \
$$PWD/http/requestparser.h \
$$PWD/http/responsebuilder.h \
$$PWD/http/responsegenerator.h \
$$PWD/http/server.h \
$$PWD/http/types.h \
$$PWD/http/responsebuilder.h \
$$PWD/iconprovider.h \
$$PWD/indexrange.h \
$$PWD/logger.h \
$$PWD/net/dnsupdater.h \
$$PWD/net/downloadmanager.h \
$$PWD/net/downloadhandler.h \
$$PWD/net/downloadmanager.h \
$$PWD/net/geoipmanager.h \
$$PWD/net/portforwarder.h \
$$PWD/net/private/geoipdatabase.h \
$$PWD/net/proxyconfigurationmanager.h \
$$PWD/net/reverseresolution.h \
$$PWD/net/smtp.h \
$$PWD/net/private/geoipdatabase.h \
$$PWD/bittorrent/addtorrentparams.h \
$$PWD/bittorrent/infohash.h \
$$PWD/bittorrent/session.h \
$$PWD/bittorrent/sessionstatus.h \
$$PWD/bittorrent/cachestatus.h \
$$PWD/bittorrent/magneturi.h \
$$PWD/bittorrent/torrentinfo.h \
$$PWD/bittorrent/torrenthandle.h \
$$PWD/bittorrent/peerinfo.h \
$$PWD/bittorrent/trackerentry.h \
$$PWD/bittorrent/tracker.h \
$$PWD/bittorrent/torrentcreatorthread.h \
$$PWD/bittorrent/private/speedmonitor.h \
$$PWD/bittorrent/private/bandwidthscheduler.h \
$$PWD/bittorrent/private/filterparserthread.h \
$$PWD/bittorrent/private/statistics.h \
$$PWD/bittorrent/private/resumedatasavingmanager.h \
$$PWD/preferences.h \
$$PWD/private/profile_p.h \
$$PWD/profile.h \
$$PWD/rss/private/rss_parser.h \
$$PWD/rss/rss_article.h \
$$PWD/rss/rss_item.h \
$$PWD/rss/rss_feed.h \
$$PWD/rss/rss_folder.h \
$$PWD/rss/rss_session.h \
$$PWD/rss/rss_autodownloader.h \
$$PWD/rss/rss_autodownloadrule.h \
$$PWD/rss/private/rss_parser.h \
$$PWD/rss/rss_feed.h \
$$PWD/rss/rss_folder.h \
$$PWD/rss/rss_item.h \
$$PWD/rss/rss_session.h \
$$PWD/scanfoldersmodel.h \
$$PWD/searchengine.h \
$$PWD/settingsstorage.h \
$$PWD/settingvalue.h \
$$PWD/torrentfileguard.h \
$$PWD/torrentfilter.h \
$$PWD/tristatebool.h \
$$PWD/types.h \
$$PWD/unicodestrings.h \
$$PWD/utils/fs.h \
$$PWD/utils/gzip.h \
$$PWD/utils/misc.h \
$$PWD/utils/net.h \
$$PWD/utils/random.h \
$$PWD/utils/string.h \
$$PWD/utils/version.h \
$$PWD/profile.h \
$$PWD/private/profile_p.h \
$$PWD/unicodestrings.h \
$$PWD/torrentfileguard.h \
$$PWD/torrentfilter.h \
$$PWD/scanfoldersmodel.h \
$$PWD/searchengine.h \
$$PWD/global.h
$$PWD/utils/version.h
SOURCES += \
$$PWD/asyncfilestorage.cpp \
$$PWD/tristatebool.cpp \
$$PWD/bittorrent/infohash.cpp \
$$PWD/bittorrent/magneturi.cpp \
$$PWD/bittorrent/peerinfo.cpp \
$$PWD/bittorrent/private/bandwidthscheduler.cpp \
$$PWD/bittorrent/private/filterparserthread.cpp \
$$PWD/bittorrent/private/resumedatasavingmanager.cpp \
$$PWD/bittorrent/private/speedmonitor.cpp \
$$PWD/bittorrent/private/statistics.cpp \
$$PWD/bittorrent/session.cpp \
$$PWD/bittorrent/torrentcreatorthread.cpp \
$$PWD/bittorrent/torrenthandle.cpp \
$$PWD/bittorrent/torrentinfo.cpp \
$$PWD/bittorrent/tracker.cpp \
$$PWD/bittorrent/trackerentry.cpp \
$$PWD/filesystemwatcher.cpp \
$$PWD/logger.cpp \
$$PWD/settingsstorage.cpp \
$$PWD/preferences.cpp \
$$PWD/iconprovider.cpp \
$$PWD/http/connection.cpp \
$$PWD/http/requestparser.cpp \
$$PWD/http/responsebuilder.cpp \
$$PWD/http/responsegenerator.cpp \
$$PWD/http/server.cpp \
$$PWD/http/responsebuilder.cpp \
$$PWD/iconprovider.cpp \
$$PWD/logger.cpp \
$$PWD/net/dnsupdater.cpp \
$$PWD/net/downloadmanager.cpp \
$$PWD/net/downloadhandler.cpp \
$$PWD/net/downloadmanager.cpp \
$$PWD/net/geoipmanager.cpp \
$$PWD/net/portforwarder.cpp \
$$PWD/net/private/geoipdatabase.cpp \
$$PWD/net/proxyconfigurationmanager.cpp \
$$PWD/net/reverseresolution.cpp \
$$PWD/net/smtp.cpp \
$$PWD/net/private/geoipdatabase.cpp \
$$PWD/bittorrent/infohash.cpp \
$$PWD/bittorrent/session.cpp \
$$PWD/bittorrent/magneturi.cpp \
$$PWD/bittorrent/torrentinfo.cpp \
$$PWD/bittorrent/torrenthandle.cpp \
$$PWD/bittorrent/peerinfo.cpp \
$$PWD/bittorrent/trackerentry.cpp \
$$PWD/bittorrent/tracker.cpp \
$$PWD/bittorrent/torrentcreatorthread.cpp \
$$PWD/bittorrent/private/speedmonitor.cpp \
$$PWD/bittorrent/private/bandwidthscheduler.cpp \
$$PWD/bittorrent/private/filterparserthread.cpp \
$$PWD/bittorrent/private/statistics.cpp \
$$PWD/bittorrent/private/resumedatasavingmanager.cpp \
$$PWD/preferences.cpp \
$$PWD/private/profile_p.cpp \
$$PWD/profile.cpp \
$$PWD/rss/private/rss_parser.cpp \
$$PWD/rss/rss_article.cpp \
$$PWD/rss/rss_item.cpp \
$$PWD/rss/rss_feed.cpp \
$$PWD/rss/rss_folder.cpp \
$$PWD/rss/rss_session.cpp \
$$PWD/rss/rss_autodownloader.cpp \
$$PWD/rss/rss_autodownloadrule.cpp \
$$PWD/rss/private/rss_parser.cpp \
$$PWD/rss/rss_feed.cpp \
$$PWD/rss/rss_folder.cpp \
$$PWD/rss/rss_item.cpp \
$$PWD/rss/rss_session.cpp \
$$PWD/scanfoldersmodel.cpp \
$$PWD/searchengine.cpp \
$$PWD/settingsstorage.cpp \
$$PWD/torrentfileguard.cpp \
$$PWD/torrentfilter.cpp \
$$PWD/tristatebool.cpp \
$$PWD/utils/fs.cpp \
$$PWD/utils/gzip.cpp \
$$PWD/utils/misc.cpp \
$$PWD/utils/net.cpp \
$$PWD/utils/random.cpp \
$$PWD/utils/string.cpp \
$$PWD/profile.cpp \
$$PWD/private/profile_p.cpp \
$$PWD/torrentfileguard.cpp \
$$PWD/torrentfilter.cpp \
$$PWD/scanfoldersmodel.cpp \
$$PWD/searchengine.cpp
$$PWD/utils/string.cpp

View File

@@ -273,18 +273,20 @@ qreal PeerInfo::relevance() const
void PeerInfo::determineFlags()
{
QStringList flagsDescriptionList;
if (isInteresting()) {
// d = Your client wants to download, but peer doesn't want to send (interested and choked)
if (isRemoteChocked()) {
m_flags += "d ";
m_flagsDescription += tr("interested(local) and choked(peer)");
m_flagsDescription += ", ";
flagsDescriptionList += "d = "
+ tr("Interested(local) and Choked(peer)");
}
else {
// D = Currently downloading (interested and not choked)
m_flags += "D ";
m_flagsDescription += tr("interested(local) and unchoked(peer)");
m_flagsDescription += ", ";
flagsDescriptionList += "D = "
+ tr("interested(local) and unchoked(peer)");
}
}
@@ -292,97 +294,95 @@ void PeerInfo::determineFlags()
// u = Peer wants your client to upload, but your client doesn't want to (interested and choked)
if (isChocked()) {
m_flags += "u ";
m_flagsDescription += tr("interested(peer) and choked(local)");
m_flagsDescription += ", ";
flagsDescriptionList += "u = "
+ tr("interested(peer) and choked(local)");
}
else {
// U = Currently uploading (interested and not choked)
m_flags += "U ";
m_flagsDescription += tr("interested(peer) and unchoked(local)");
m_flagsDescription += ", ";
flagsDescriptionList += "U = "
+ tr("interested(peer) and unchoked(local)");
}
}
// O = Optimistic unchoke
if (optimisticUnchoke()) {
m_flags += "O ";
m_flagsDescription += tr("optimistic unchoke");
m_flagsDescription += ", ";
flagsDescriptionList += "O = "
+ tr("optimistic unchoke");
}
// S = Peer is snubbed
if (isSnubbed()) {
m_flags += "S ";
m_flagsDescription += tr("peer snubbed");
m_flagsDescription += ", ";
flagsDescriptionList += "S = "
+ tr("peer snubbed");
}
// I = Peer is an incoming connection
if (!isLocalConnection()) {
m_flags += "I ";
m_flagsDescription += tr("incoming connection");
m_flagsDescription += ", ";
flagsDescriptionList += "I = "
+ tr("incoming connection");
}
// K = Peer is unchoking your client, but your client is not interested
if (!isRemoteChocked() && !isInteresting()) {
m_flags += "K ";
m_flagsDescription += tr("not interested(local) and unchoked(peer)");
m_flagsDescription += ", ";
flagsDescriptionList += "K = "
+ tr("not interested(local) and unchoked(peer)");
}
// ? = Your client unchoked the peer but the peer is not interested
if (!isChocked() && !isRemoteInterested()) {
m_flags += "? ";
m_flagsDescription += tr("not interested(peer) and unchoked(local)");
m_flagsDescription += ", ";
flagsDescriptionList += "? = "
+ tr("not interested(peer) and unchoked(local)");
}
// X = Peer was included in peerlists obtained through Peer Exchange (PEX)
if (fromPeX()) {
m_flags += "X ";
m_flagsDescription += tr("peer from PEX");
m_flagsDescription += ", ";
flagsDescriptionList += "X = "
+ tr("peer from PEX");
}
// H = Peer was obtained through DHT
if (fromDHT()) {
m_flags += "H ";
m_flagsDescription += tr("peer from DHT");
m_flagsDescription += ", ";
flagsDescriptionList += "H = "
+ tr("peer from DHT");
}
// E = Peer is using Protocol Encryption (all traffic)
if (isRC4Encrypted()) {
m_flags += "E ";
m_flagsDescription += tr("encrypted traffic");
m_flagsDescription += ", ";
flagsDescriptionList += "E = "
+ tr("encrypted traffic");
}
// e = Peer is using Protocol Encryption (handshake)
if (isPlaintextEncrypted()) {
m_flags += "e ";
m_flagsDescription += tr("encrypted handshake");
m_flagsDescription += ", ";
flagsDescriptionList += "e = "
+ tr("encrypted handshake");
}
// P = Peer is using uTorrent uTP
if (useUTPSocket()) {
m_flags += "P ";
m_flagsDescription += QString::fromUtf8(C_UTP);
m_flagsDescription += ", ";
flagsDescriptionList += "P = "
+ QString::fromUtf8(C_UTP);
}
// L = Peer is local
if (fromLSD()) {
m_flags += "L";
m_flagsDescription += tr("peer from LSD");
flagsDescriptionList += "L = "
+ tr("peer from LSD");
}
m_flags = m_flags.trimmed();
m_flagsDescription = m_flagsDescription.trimmed();
if (m_flagsDescription.endsWith(',', Qt::CaseInsensitive))
m_flagsDescription.chop(1);
m_flagsDescription = flagsDescriptionList.join('\n');
}
QString PeerInfo::flags() const

View File

@@ -1481,14 +1481,10 @@ void Session::configurePeerClasses()
peerClassTypeFilter.add(libt::peer_class_type_filter::tcp_socket, libt::session::tcp_peer_class_id);
peerClassTypeFilter.add(libt::peer_class_type_filter::ssl_tcp_socket, libt::session::tcp_peer_class_id);
peerClassTypeFilter.add(libt::peer_class_type_filter::i2p_socket, libt::session::tcp_peer_class_id);
if (isUTPRateLimited()) {
peerClassTypeFilter.add(libt::peer_class_type_filter::utp_socket
, libt::session::local_peer_class_id);
peerClassTypeFilter.add(libt::peer_class_type_filter::utp_socket
if (!isUTPRateLimited()) {
peerClassTypeFilter.disallow(libt::peer_class_type_filter::utp_socket
, libt::session::global_peer_class_id);
peerClassTypeFilter.add(libt::peer_class_type_filter::ssl_utp_socket
, libt::session::local_peer_class_id);
peerClassTypeFilter.add(libt::peer_class_type_filter::ssl_utp_socket
peerClassTypeFilter.disallow(libt::peer_class_type_filter::ssl_utp_socket
, libt::session::global_peer_class_id);
}
m_nativeSession->set_peer_class_type_filter(peerClassTypeFilter);

View File

@@ -59,8 +59,6 @@ using namespace BitTorrent;
TorrentCreatorThread::TorrentCreatorThread(QObject *parent)
: QThread(parent)
, m_private(false)
, m_pieceSize(0)
{
}
@@ -70,97 +68,91 @@ TorrentCreatorThread::~TorrentCreatorThread()
wait();
}
void TorrentCreatorThread::create(const QString &inputPath, const QString &savePath, const QStringList &trackers,
const QStringList &urlSeeds, const QString &comment, bool isPrivate, int pieceSize)
void TorrentCreatorThread::create(const TorrentCreatorParams &params)
{
m_inputPath = Utils::Fs::fromNativePath(inputPath);
m_savePath = Utils::Fs::fromNativePath(savePath);
if (QFile(m_savePath).exists())
Utils::Fs::forceRemove(m_savePath);
m_trackers = trackers;
m_urlSeeds = urlSeeds;
m_comment = comment;
m_private = isPrivate;
m_pieceSize = pieceSize;
m_params = params;
start();
}
void TorrentCreatorThread::sendProgressSignal(int numHashes, int numPieces)
void TorrentCreatorThread::sendProgressSignal(int currentPieceIdx, int totalPieces)
{
emit updateProgress(static_cast<int>((numHashes * 100.) / numPieces));
emit updateProgress(static_cast<int>((currentPieceIdx * 100.) / totalPieces));
}
void TorrentCreatorThread::run()
{
const QString creatorStr("qBittorrent " QBT_VERSION);
emit updateProgress(0);
QString creator_str("qBittorrent " QBT_VERSION);
try {
libt::file_storage fs;
// Adding files to the torrent
libt::add_files(fs, Utils::Fs::toNativePath(m_inputPath).toStdString(), fileFilter);
libt::add_files(fs, Utils::Fs::toNativePath(m_params.inputPath).toStdString(), fileFilter);
if (isInterruptionRequested()) return;
libt::create_torrent t(fs, m_pieceSize);
libt::create_torrent newTorrent(fs, m_params.pieceSize);
// Add url seeds
foreach (const QString &seed, m_urlSeeds)
t.add_url_seed(seed.trimmed().toStdString());
foreach (QString seed, m_params.urlSeeds) {
seed = seed.trimmed();
if (!seed.isEmpty())
newTorrent.add_url_seed(seed.toStdString());
}
int tier = 0;
bool newline = false;
foreach (const QString &tracker, m_trackers) {
if (tracker.isEmpty()) {
if (newline)
continue;
foreach (const QString &tracker, m_params.trackers) {
if (tracker.isEmpty())
++tier;
newline = true;
continue;
}
t.add_tracker(tracker.trimmed().toStdString(), tier);
newline = false;
else
newTorrent.add_tracker(tracker.trimmed().toStdString(), tier);
}
if (isInterruptionRequested()) return;
// calculate the hash for all pieces
const QString parentPath = Utils::Fs::branchPath(m_inputPath) + "/";
libt::set_piece_hashes(t, Utils::Fs::toNativePath(parentPath).toStdString(), boost::bind(&TorrentCreatorThread::sendProgressSignal, this, _1, t.num_pieces()));
const QString parentPath = Utils::Fs::branchPath(m_params.inputPath) + "/";
libt::set_piece_hashes(newTorrent, Utils::Fs::toNativePath(parentPath).toStdString()
, [this, &newTorrent](const int n) { sendProgressSignal(n, newTorrent.num_pieces()); });
// Set qBittorrent as creator and add user comment to
// torrent_info structure
t.set_creator(creator_str.toUtf8().constData());
t.set_comment(m_comment.toUtf8().constData());
newTorrent.set_creator(creatorStr.toUtf8().constData());
newTorrent.set_comment(m_params.comment.toUtf8().constData());
// Is private ?
t.set_priv(m_private);
newTorrent.set_priv(m_params.isPrivate);
if (isInterruptionRequested()) return;
// create the torrent and print it to out
qDebug("Saving to %s", qUtf8Printable(m_savePath));
libt::entry entry = newTorrent.generate();
// add source field
if (!m_params.source.isEmpty())
entry["info"]["source"] = m_params.source.toStdString();
if (isInterruptionRequested()) return;
// create the torrent
std::ofstream outfile(
#ifdef _MSC_VER
wchar_t *savePathW = new wchar_t[m_savePath.length() + 1];
int len = Utils::Fs::toNativePath(m_savePath).toWCharArray(savePathW);
savePathW[len] = L'\0';
std::ofstream outfile(savePathW, std::ios_base::out | std::ios_base::binary);
delete[] savePathW;
Utils::Fs::toNativePath(m_params.savePath).toStdWString().c_str()
#else
std::ofstream outfile(Utils::Fs::toNativePath(m_savePath).toLocal8Bit().constData(), std::ios_base::out | std::ios_base::binary);
Utils::Fs::toNativePath(m_params.savePath).toUtf8().constData()
#endif
, (std::ios_base::out | std::ios_base::binary | std::ios_base::trunc));
if (outfile.fail())
throw std::exception();
throw std::runtime_error(tr("create new torrent file failed").toStdString());
if (isInterruptionRequested()) return;
libt::bencode(std::ostream_iterator<char>(outfile), t.generate());
libt::bencode(std::ostream_iterator<char>(outfile), entry);
outfile.close();
emit updateProgress(100);
emit creationSuccess(m_savePath, parentPath);
emit creationSuccess(m_params.savePath, parentPath);
}
catch (std::exception& e) {
emit creationFailure(QString::fromStdString(e.what()));
catch (const std::exception &e) {
emit creationFailure(e.what());
}
}

View File

@@ -36,16 +36,27 @@
namespace BitTorrent
{
struct TorrentCreatorParams
{
bool isPrivate;
int pieceSize;
QString inputPath;
QString savePath;
QString comment;
QString source;
QStringList trackers;
QStringList urlSeeds;
};
class TorrentCreatorThread : public QThread
{
Q_OBJECT
public:
TorrentCreatorThread(QObject *parent = 0);
TorrentCreatorThread(QObject *parent = nullptr);
~TorrentCreatorThread();
void create(const QString &inputPath, const QString &savePath, const QStringList &trackers,
const QStringList &urlSeeds, const QString &comment, bool isPrivate, int pieceSize);
void create(const TorrentCreatorParams &params);
static int calculateTotalPieces(const QString &inputPath, const int pieceSize);
@@ -58,15 +69,9 @@ namespace BitTorrent
void updateProgress(int progress);
private:
void sendProgressSignal(int numHashes, int numPieces);
void sendProgressSignal(int currentPieceIdx, int totalPieces);
QString m_inputPath;
QString m_savePath;
QStringList m_trackers;
QStringList m_urlSeeds;
QString m_comment;
bool m_private;
int m_pieceSize;
TorrentCreatorParams m_params;
};
}

View File

@@ -156,6 +156,8 @@ const int TorrentHandle::MAX_SEEDING_TIME = 525600;
// The following can be removed after one or two libtorrent releases on each branch.
namespace
{
const char i18nContext[] = "TorrentHandle";
// new constructor is available
template<typename T, typename std::enable_if<std::is_constructible<T, libt::torrent_info, bool>::value, int>::type = 0>
T makeTorrentCreator(const libtorrent::torrent_info & ti)
@@ -1469,7 +1471,7 @@ void TorrentHandle::handleStorageMovedFailedAlert(libtorrent::storage_moved_fail
return;
}
Logger::instance()->addMessage(tr("Could not move torrent: '%1'. Reason: %2")
LogMsg(QCoreApplication::translate(i18nContext, "Could not move torrent: '%1'. Reason: %2")
.arg(name()).arg(QString::fromStdString(p->message())), Log::CRITICAL);
m_moveStorageInfo.newPath.clear();
@@ -1647,13 +1649,13 @@ void TorrentHandle::handleFastResumeRejectedAlert(libtorrent::fastresume_rejecte
updateStatus();
if (p->error.value() == libt::errors::mismatching_file_size) {
// Mismatching file size (files were probably moved)
logger->addMessage(tr("File sizes mismatch for torrent '%1', pausing it.").arg(name()), Log::CRITICAL);
logger->addMessage(QCoreApplication::translate(i18nContext, "File sizes mismatch for torrent '%1', pausing it.").arg(name()), Log::CRITICAL);
m_hasMissingFiles = true;
if (!isPaused())
pause();
}
else {
logger->addMessage(tr("Fast resume data was rejected for torrent '%1'. Reason: %2. Checking again...")
logger->addMessage(QCoreApplication::translate(i18nContext, "Fast resume data was rejected for torrent '%1'. Reason: %2. Checking again...")
.arg(name()).arg(QString::fromStdString(p->message())), Log::CRITICAL);
}
}

View File

@@ -59,6 +59,7 @@ namespace Http
const char CONTENT_TYPE_JSON[] = "application/json";
const char CONTENT_TYPE_PNG[] = "image/png";
const char CONTENT_TYPE_TXT[] = "text/plain; charset=UTF-8";
const char CONTENT_TYPE_SVG[] = "image/svg+xml";
// portability: "\r\n" doesn't guarantee mapping to the correct value
const char CRLF[] = {0x0D, 0x0A, '\0'};

View File

@@ -35,6 +35,7 @@
#include <QCryptographicHash>
#include <QDir>
#include <QLocale>
#include <QMutableListIterator>
#include <QPair>
#include <QSettings>
@@ -487,13 +488,17 @@ QList<Utils::Net::Subnet> Preferences::getWebUiAuthSubnetWhitelist() const
return subnets;
}
void Preferences::setWebUiAuthSubnetWhitelist(const QList<Utils::Net::Subnet> &subnets)
void Preferences::setWebUiAuthSubnetWhitelist(QStringList subnets)
{
QStringList subnetsStringList;
for (const Utils::Net::Subnet &subnet : subnets)
subnetsStringList.append(Utils::Net::subnetToString(subnet));
QMutableListIterator<QString> i(subnets);
while (i.hasNext()) {
bool ok = false;
const Utils::Net::Subnet subnet = Utils::Net::parseSubnet(i.next().trimmed(), &ok);
if (!ok)
i.remove();
}
setValue("Preferences/WebUI/AuthSubnetWhitelist", subnetsStringList);
setValue("Preferences/WebUI/AuthSubnetWhitelist", subnets);
}
QString Preferences::getServerDomains() const
@@ -1216,9 +1221,9 @@ void Preferences::setMainLastDir(const QString &path)
setValue("MainWindowLastDir", path);
}
QSize Preferences::getPrefSize(const QSize &defaultSize) const
QSize Preferences::getPrefSize() const
{
return value("Preferences/State/size", defaultSize).toSize();
return value("Preferences/State/size").toSize();
}
void Preferences::setPrefSize(const QSize &size)
@@ -1296,9 +1301,9 @@ void Preferences::setPropTrackerListState(const QByteArray &state)
setValue("TorrentProperties/Trackers/qt5/TrackerListState", state);
}
QSize Preferences::getRssGeometrySize(const QSize &defaultSize) const
QSize Preferences::getRssGeometrySize() const
{
return value("RssFeedDownloader/geometrySize", defaultSize).toSize();
return value("RssFeedDownloader/geometrySize").toSize();
}
void Preferences::setRssGeometrySize(const QSize &geometry)

View File

@@ -191,7 +191,7 @@ public:
bool isWebUiAuthSubnetWhitelistEnabled() const;
void setWebUiAuthSubnetWhitelistEnabled(bool enabled);
QList<Utils::Net::Subnet> getWebUiAuthSubnetWhitelist() const;
void setWebUiAuthSubnetWhitelist(const QList<Utils::Net::Subnet> &subnets);
void setWebUiAuthSubnetWhitelist(QStringList subnets);
QString getWebUiUsername() const;
void setWebUiUsername(const QString &username);
QString getWebUiPassword() const;
@@ -301,7 +301,7 @@ public:
void setMainVSplitterState(const QByteArray &state);
QString getMainLastDir() const;
void setMainLastDir(const QString &path);
QSize getPrefSize(const QSize &defaultSize) const;
QSize getPrefSize() const;
void setPrefSize(const QSize &size);
QStringList getPrefHSplitterSizes() const;
void setPrefHSplitterSizes(const QStringList &sizes);
@@ -317,7 +317,7 @@ public:
void setPropVisible(const bool visible);
QByteArray getPropTrackerListState() const;
void setPropTrackerListState(const QByteArray &state);
QSize getRssGeometrySize(const QSize &defaultSize) const;
QSize getRssGeometrySize() const;
void setRssGeometrySize(const QSize &geometry);
QByteArray getRssHSplitterSizes() const;
void setRssHSplitterSizes(const QByteArray &sizes);

View File

@@ -424,6 +424,8 @@ bool AutoDownloader::isProcessingEnabled() const
void AutoDownloader::resetProcessingQueue()
{
m_processingQueue.clear();
if (!m_processingEnabled) return;
foreach (Article *article, Session::instance()->rootFolder()->articles()) {
if (!article->isRead() && !article->torrentUrl().isEmpty())
addJobForArticle(article);

View File

@@ -102,6 +102,27 @@ Session::Session()
m_refreshTimer.start(m_refreshInterval * MsecsPerMin);
refresh();
}
// Remove legacy/corrupted settings
// (at least on Windows, QSettings is case-insensitive and it can get
// confused when asked about settings that differ only in their case)
auto settingsStorage = SettingsStorage::instance();
settingsStorage->removeValue("Rss/streamList");
settingsStorage->removeValue("Rss/streamAlias");
settingsStorage->removeValue("Rss/open_folders");
settingsStorage->removeValue("Rss/qt5/splitter_h");
settingsStorage->removeValue("Rss/qt5/splitterMain");
settingsStorage->removeValue("Rss/hosts_cookies");
settingsStorage->removeValue("RSS/streamList");
settingsStorage->removeValue("RSS/streamAlias");
settingsStorage->removeValue("RSS/open_folders");
settingsStorage->removeValue("RSS/qt5/splitter_h");
settingsStorage->removeValue("RSS/qt5/splitterMain");
settingsStorage->removeValue("RSS/hosts_cookies");
settingsStorage->removeValue("Rss/Session/EnableProcessing");
settingsStorage->removeValue("Rss/Session/RefreshInterval");
settingsStorage->removeValue("Rss/Session/MaxArticlesPerFeed");
settingsStorage->removeValue("Rss/AutoDownloader/EnableProcessing");
}
Session::~Session()
@@ -295,20 +316,6 @@ void Session::loadFolder(const QJsonObject &jsonObj, Folder *folder)
void Session::loadLegacy()
{
struct LegacySettingsDeleter
{
~LegacySettingsDeleter()
{
auto settingsStorage = SettingsStorage::instance();
settingsStorage->removeValue("Rss/streamList");
settingsStorage->removeValue("Rss/streamAlias");
settingsStorage->removeValue("Rss/open_folders");
settingsStorage->removeValue("Rss/qt5/splitter_h");
settingsStorage->removeValue("Rss/qt5/splitterMain");
settingsStorage->removeValue("Rss/hosts_cookies");
}
} legacySettingsDeleter;
const QStringList legacyFeedPaths = SettingsStorage::instance()->loadValue("Rss/streamList").toStringList();
const QStringList feedAliases = SettingsStorage::instance()->loadValue("Rss/streamAlias").toStringList();
if (legacyFeedPaths.size() != feedAliases.size()) {

View File

@@ -632,19 +632,6 @@ void Utils::Misc::openFolderSelect(const QString &absolutePath)
#endif
}
QSize Utils::Misc::smallIconSize()
{
// Get DPI scaled icon size (device-dependent), see QT source
int s = QApplication::style()->pixelMetric(QStyle::PM_SmallIconSize);
return QSize(s, s);
}
QSize Utils::Misc::largeIconSize()
{
// Get DPI scaled icon size (device-dependent), see QT source
int s = QApplication::style()->pixelMetric(QStyle::PM_LargeIconSize);
return QSize(s, s);
}
#endif // DISABLE_GUI
QString Utils::Misc::osName()

View File

@@ -103,8 +103,6 @@ namespace Utils
void openFolderSelect(const QString& absolutePath);
QPoint screenCenter(const QWidget *w);
QSize smallIconSize();
QSize largeIconSize();
#endif
#ifdef Q_OS_WIN

View File

@@ -85,7 +85,10 @@ namespace
const QChar leftChar = (m_caseSensitivity == Qt::CaseSensitive) ? left[posL] : left[posL].toLower();
const QChar rightChar = (m_caseSensitivity == Qt::CaseSensitive) ? right[posR] : right[posR].toLower();
if (leftChar == rightChar) {
// Compare only non-digits.
// Numbers should be compared as a whole
// otherwise the string->int conversion can yield a wrong value
if ((leftChar == rightChar) && !leftChar.isDigit()) {
// compare next character
++posL;
++posR;

View File

@@ -74,6 +74,7 @@ transferlistfilterswidget.h
transferlistsortmodel.h
transferlistwidget.h
updownratiodlg.h
utils.h
)
set(QBT_GUI_SOURCES
@@ -119,6 +120,7 @@ transferlistfilterswidget.cpp
transferlistsortmodel.cpp
transferlistwidget.cpp
updownratiodlg.cpp
utils.cpp
)
if (APPLE)

View File

@@ -18,11 +18,7 @@
<item>
<layout class="QHBoxLayout" name="titleHBoxLayout">
<item>
<widget class="QLabel" name="logo">
<property name="pixmap">
<pixmap resource="../icons.qrc">:/icons/skin/qbittorrent32.png</pixmap>
</property>
</widget>
<widget class="QLabel" name="logo"/>
</item>
<item>
<widget class="QLabel" name="lb_name">
@@ -57,11 +53,7 @@
</attribute>
<layout class="QGridLayout" name="aboutTabLayout">
<item row="0" column="0">
<widget class="QLabel" name="mascot_lbl">
<property name="pixmap">
<pixmap resource="../icons.qrc">:/icons/skin/mascot.png</pixmap>
</property>
</widget>
<widget class="QLabel" name="labelMascot"/>
</item>
<item row="0" column="1">
<widget class="QLabel" name="lb_about">

View File

@@ -31,10 +31,12 @@
#ifndef ABOUT_H
#define ABOUT_H
#include "ui_about.h"
#include <QFile>
#include "base/utils/misc.h"
#include "base/unicodestrings.h"
#include "ui_about.h"
#include "utils.h"
class about: public QDialog, private Ui::AboutDlg
{
@@ -53,24 +55,28 @@ public:
lb_name->setText("<b><h2>qBittorrent " QBT_VERSION " (32-bit)</h2></b>");
#endif
logo->setPixmap(Utils::Gui::scaledPixmap(":/icons/skin/qbittorrent32.png", this));
// About
QString aboutText = QString(
"<p style=\"white-space: pre-wrap;\">"
"%1\n\n"
"%2\n\n"
"<table>"
"<tr><td>%3</td><td><a href=\"http://www.qbittorrent.org\">http://www.qbittorrent.org</a></td></tr>"
"<tr><td>%3</td><td><a href=\"https://www.qbittorrent.org\">https://www.qbittorrent.org</a></td></tr>"
"<tr><td>%4</td><td><a href=\"http://forum.qbittorrent.org\">http://forum.qbittorrent.org</a></td></tr>"
"<tr><td>%5</td><td><a href=\"http://bugs.qbittorrent.org\">http://bugs.qbittorrent.org</a></td></tr>"
"</table>"
"</p>")
.arg(tr("An advanced BitTorrent client programmed in C++, based on Qt toolkit and libtorrent-rasterbar."))
.arg(tr("Copyright %1 2006-2017 The qBittorrent project").arg(QString::fromUtf8(C_COPYRIGHT)))
.arg(tr("Copyright %1 2006-2018 The qBittorrent project").arg(QString::fromUtf8(C_COPYRIGHT)))
.arg(tr("Home Page:"))
.arg(tr("Forum:"))
.arg(tr("Bug Tracker:"));
lb_about->setText(aboutText);
labelMascot->setPixmap(Utils::Gui::scaledPixmap(":/icons/skin/mascot.png", this));
// Thanks
QFile thanksfile(":/thanks.html");
if (thanksfile.open(QIODevice::ReadOnly | QIODevice::Text)) {
@@ -97,6 +103,7 @@ public:
label_12->setText(Utils::Misc::libtorrentVersionString());
label_13->setText(Utils::Misc::boostVersionString());
Utils::Gui::resize(this);
show();
}
};

View File

@@ -28,36 +28,38 @@
* Contact : chris@qbittorrent.org
*/
#include <QDebug>
#include <QString>
#include <QFile>
#include <QUrl>
#include <QMenu>
#include <QFileDialog>
#include <QPushButton>
#include "addnewtorrentdialog.h"
#include <QDebug>
#include <QFile>
#include <QFileDialog>
#include <QMenu>
#include <QPushButton>
#include <QString>
#include <QUrl>
#include "autoexpandabledialog.h"
#include "base/bittorrent/magneturi.h"
#include "base/bittorrent/session.h"
#include "base/bittorrent/torrenthandle.h"
#include "base/bittorrent/torrentinfo.h"
#include "base/net/downloadhandler.h"
#include "base/net/downloadmanager.h"
#include "base/preferences.h"
#include "base/settingsstorage.h"
#include "base/settingvalue.h"
#include "base/net/downloadmanager.h"
#include "base/net/downloadhandler.h"
#include "base/bittorrent/session.h"
#include "base/bittorrent/magneturi.h"
#include "base/bittorrent/torrentinfo.h"
#include "base/bittorrent/torrenthandle.h"
#include "base/torrentfileguard.h"
#include "base/unicodestrings.h"
#include "base/utils/fs.h"
#include "base/utils/misc.h"
#include "base/utils/string.h"
#include "base/torrentfileguard.h"
#include "base/unicodestrings.h"
#include "guiiconprovider.h"
#include "autoexpandabledialog.h"
#include "messageboxraised.h"
#include "proplistdelegate.h"
#include "torrentcontentmodel.h"
#include "torrentcontentfiltermodel.h"
#include "torrentcontentmodel.h"
#include "ui_addnewtorrentdialog.h"
#include "addnewtorrentdialog.h"
#include "utils.h"
namespace
{
@@ -212,10 +214,11 @@ CachedSettingValue<int> &AddNewTorrentDialog::savePathHistoryLengthSetting()
void AddNewTorrentDialog::loadState()
{
m_headerState = settings()->loadValue(KEY_TREEHEADERSTATE).toByteArray();
int width = settings()->loadValue(KEY_WIDTH, -1).toInt();
QSize geo = size();
geo.setWidth(width);
resize(geo);
const QSize newSize = Utils::Gui::scaledSize(this, size());
const int width = settings()->loadValue(KEY_WIDTH, newSize.width()).toInt();
const int height = newSize.height();
resize(width, height);
ui->adv_button->setChecked(settings()->loadValue(KEY_EXPANDED).toBool());
}

View File

@@ -32,6 +32,7 @@
#include "mainwindow.h"
#include "ui_autoexpandabledialog.h"
#include "utils.h"
AutoExpandableDialog::AutoExpandableDialog(QWidget *parent)
: QDialog(parent)
@@ -68,30 +69,29 @@ QString AutoExpandableDialog::getText(QWidget *parent, const QString &title, con
void AutoExpandableDialog::showEvent(QShowEvent *e)
{
// Overriding showEvent is required for consistent UI with fixed size under custom DPI
// Show dialog
QDialog::showEvent(e);
// and resize textbox to fit the text
// NOTE: For some strange reason QFontMetrics gets more accurate
// when called from showEvent. Only 6 symbols off instead of 11 symbols off.
int textW = m_ui->textEdit->fontMetrics().width(m_ui->textEdit->text()) + 4;
int wd = textW;
// Show dialog and resize textbox to fit the text
// NOTE: For unknown reason QFontMetrics gets more accurate when called from showEvent.
int wd = m_ui->textEdit->fontMetrics().width(m_ui->textEdit->text()) + 4;
if (!windowTitle().isEmpty()) {
int w = fontMetrics().width(windowTitle());
if (w > wd)
wd = w;
// not really the font metrics in window title, so we enlarge it a bit,
// including the small icon and close button width
int w = fontMetrics().width(windowTitle()) * 1.8;
wd = std::max(wd, w);
}
if (!m_ui->textLabel->text().isEmpty()) {
int w = m_ui->textLabel->fontMetrics().width(m_ui->textLabel->text());
if (w > wd)
wd = w;
wd = std::max(wd, w);
}
// Now resize the dialog to fit the contents
// max width of text from either of: label, title, textedit
// If the value is less than dialog default size, default size is used
if (wd > width())
resize(width() - m_ui->verticalLayout->sizeHint().width() + wd, height());
if (wd > width()) {
QSize size = {width() - m_ui->verticalLayout->sizeHint().width() + wd, height()};
Utils::Gui::resize(this, size);
}
}

View File

@@ -36,6 +36,7 @@
#include "base/bittorrent/session.h"
#include "base/utils/net.h"
#include "ui_banlistoptions.h"
#include "utils.h"
BanListOptions::BanListOptions(QWidget *parent)
: QDialog(parent)
@@ -52,6 +53,8 @@ BanListOptions::BanListOptions(QWidget *parent)
m_ui->bannedIPList->setModel(m_sortFilter);
m_ui->bannedIPList->sortByColumn(0, Qt::AscendingOrder);
m_ui->buttonBanIP->setEnabled(false);
Utils::Gui::resize(this);
}
BanListOptions::~BanListOptions()

View File

@@ -54,8 +54,6 @@ bool CategoryFilterProxyModel::lessThan(const QModelIndex &left, const QModelInd
int result = Utils::String::naturalCompare(left.data().toString(), right.data().toString()
, Qt::CaseInsensitive);
if (result != 0)
return (result < 0);
return (mapFromSource(left) < mapFromSource(right));
return (result < 0);
}

View File

@@ -35,11 +35,11 @@
#include <QMessageBox>
#include "base/bittorrent/session.h"
#include "base/utils/misc.h"
#include "categoryfiltermodel.h"
#include "categoryfilterproxymodel.h"
#include "guiiconprovider.h"
#include "torrentcategorydialog.h"
#include "utils.h"
namespace
{
@@ -70,7 +70,7 @@ CategoryFilterWidget::CategoryFilterWidget(QWidget *parent)
setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
setUniformRowHeights(true);
setHeaderHidden(true);
setIconSize(Utils::Misc::smallIconSize());
setIconSize(Utils::Gui::smallIconSize());
#ifdef Q_OS_MAC
setAttribute(Qt::WA_MacShowFocusRect, false);
#endif

View File

@@ -35,6 +35,7 @@
#include "cookiesmodel.h"
#include "guiiconprovider.h"
#include "ui_cookiesdialog.h"
#include "utils.h"
#define SETTINGS_KEY(name) "CookiesDialog/" name
const QString KEY_SIZE = SETTINGS_KEY("Size");
@@ -50,6 +51,8 @@ CookiesDialog::CookiesDialog(QWidget *parent)
setWindowIcon(GuiIconProvider::instance()->getIcon("preferences-web-browser-cookies"));
m_ui->buttonAdd->setIcon(GuiIconProvider::instance()->getIcon("list-add"));
m_ui->buttonDelete->setIcon(GuiIconProvider::instance()->getIcon("list-remove"));
m_ui->buttonAdd->setIconSize(Utils::Gui::mediumIconSize());
m_ui->buttonDelete->setIconSize(Utils::Gui::mediumIconSize());
m_ui->treeView->setModel(m_cookiesModel);
if (m_cookiesModel->rowCount() > 0)
@@ -57,7 +60,7 @@ CookiesDialog::CookiesDialog(QWidget *parent)
m_cookiesModel->index(0, 0),
QItemSelectionModel::ClearAndSelect | QItemSelectionModel::Rows);
resize(SettingsStorage::instance()->loadValue(KEY_SIZE, size()).toSize());
Utils::Gui::resize(this, SettingsStorage::instance()->loadValue(KEY_SIZE).toSize());
m_ui->treeView->header()->restoreState(
SettingsStorage::instance()->loadValue(KEY_COOKIESVIEWSTATE).toByteArray());
}

View File

@@ -49,12 +49,6 @@
<property name="text">
<string notr="true"/>
</property>
<property name="iconSize">
<size>
<width>20</width>
<height>20</height>
</size>
</property>
</widget>
</item>
<item>
@@ -78,12 +72,6 @@
<property name="text">
<string notr="true"/>
</property>
<property name="iconSize">
<size>
<width>20</width>
<height>20</height>
</size>
</property>
</widget>
</item>
<item>

View File

@@ -33,11 +33,13 @@
#include <QDialog>
#include <QPushButton>
#include "ui_confirmdeletiondlg.h"
#include "base/preferences.h"
#include "base/utils/misc.h"
#include "base/utils/string.h"
#include "guiiconprovider.h"
#include "ui_confirmdeletiondlg.h"
#include "utils.h"
class DeletionConfirmationDlg : public QDialog, private Ui::confirmDeletionDlg {
Q_OBJECT
@@ -50,13 +52,17 @@ class DeletionConfirmationDlg : public QDialog, private Ui::confirmDeletionDlg {
else
label->setText(tr("Are you sure you want to delete these %1 torrents from the transfer list?", "Are you sure you want to delete these 5 torrents from the transfer list?").arg(QString::number(size)));
// Icons
lbl_warn->setPixmap(GuiIconProvider::instance()->getIcon("dialog-warning").pixmap(lbl_warn->height()));
lbl_warn->setFixedWidth(lbl_warn->height());
const QSize iconSize = Utils::Gui::largeIconSize();
lbl_warn->setPixmap(GuiIconProvider::instance()->getIcon("dialog-warning").pixmap(iconSize));
lbl_warn->setFixedWidth(iconSize.width());
rememberBtn->setIcon(GuiIconProvider::instance()->getIcon("object-locked"));
rememberBtn->setIconSize(Utils::Gui::mediumIconSize());
checkPermDelete->setChecked(defaultDeleteFiles || Preferences::instance()->deleteTorrentFilesAsDefault());
connect(checkPermDelete, SIGNAL(clicked()), this, SLOT(updateRememberButtonState()));
buttonBox->button(QDialogButtonBox::Cancel)->setFocus();
Utils::Gui::resize(this);
}
bool shouldDeleteLocalFiles() const {

View File

@@ -40,6 +40,7 @@
#include <QStringList>
#include "ui_downloadfromurldlg.h"
#include "utils.h"
class downloadFromURL : public QDialog, private Ui::downloadFromURL
{
@@ -82,6 +83,7 @@ class downloadFromURL : public QDialog, private Ui::downloadFromURL
if (clip_txt_list_cleaned.size() > 0)
textUrls->setText(clip_txt_list_cleaned.join("\n"));
Utils::Gui::resize(this);
show();
}

View File

@@ -30,6 +30,7 @@
#include <QAction>
#include <QApplication>
#include <QCoreApplication>
#include <QFileDialog>
#include <QHBoxLayout>
#include <QStyle>
@@ -40,6 +41,7 @@
namespace
{
const char i18nContext[] = "FileSystemPathEdit";
struct TrStringWithComment
{
const char *source;
@@ -47,18 +49,18 @@ namespace
QString tr() const
{
return QObject::tr(source, comment);
return QCoreApplication::translate(i18nContext, source, comment);
}
};
constexpr TrStringWithComment browseButtonBriefText =
QT_TRANSLATE_NOOP3("FileSystemPathEdit", "...", "Launch file dialog button text (brief)");
QT_TRANSLATE_NOOP3(i18nContext, "...", "Launch file dialog button text (brief)");
constexpr TrStringWithComment browseButtonFullText =
QT_TRANSLATE_NOOP3("FileSystemPathEdit", "&Browse...", "Launch file dialog button text (full)");
QT_TRANSLATE_NOOP3(i18nContext, "&Browse...", "Launch file dialog button text (full)");
constexpr TrStringWithComment defaultDialogCaptionForFile =
QT_TRANSLATE_NOOP3("FileSystemPathEdit", "Choose a file", "Caption for file open/save dialog");
QT_TRANSLATE_NOOP3(i18nContext, "Choose a file", "Caption for file open/save dialog");
constexpr TrStringWithComment defaultDialogCaptionForDirectory =
QT_TRANSLATE_NOOP3("FileSystemPathEdit", "Choose a folder", "Caption for directory open dialog");
QT_TRANSLATE_NOOP3(i18nContext, "Choose a folder", "Caption for directory open dialog");
}
class FileSystemPathEdit::FileSystemPathEditPrivate
@@ -154,7 +156,9 @@ void FileSystemPathEdit::FileSystemPathEditPrivate::modeChanged()
switch (m_mode) {
case FileSystemPathEdit::Mode::FileOpen:
case FileSystemPathEdit::Mode::FileSave:
pixmap = QStyle::SP_DialogOpenButton;
#ifdef Q_OS_WIN
pixmap = QStyle::SP_DirOpenIcon;
#endif
showDirsOnly = false;
break;
case FileSystemPathEdit::Mode::DirectoryOpen:

View File

@@ -426,6 +426,92 @@ PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.
</p>
<h3>END OF TERMS AND CONDITIONS</h3>
<h3>END OF TERMS AND CONDITIONS</h3>
<h3><a name="howto"></a><a name="SEC4" href="#TOC4">How to Apply These Terms to Your New Programs</a></h3>
<p>
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
</p>
<p>
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
</p>
<pre>
<var>one line to give the program's name and an idea of what it does.</var>
Copyright (C) <var>yyyy</var> <var>name of author</var>
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.
</pre>
<p>
Also add information on how to contact you by electronic and paper mail.
</p>
<p>
If the program is interactive, make it output a short notice like this
when it starts in an interactive mode:
</p>
<pre>
Gnomovision version 69, Copyright (C) <var>year</var> <var>name of author</var>
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details
type `show w'. This is free software, and you are welcome
to redistribute it under certain conditions; type `show c'
for details.
</pre>
<p>
The hypothetical commands <samp>`show w'</samp> and <samp>`show c'</samp> should show
the appropriate parts of the General Public License. Of course, the
commands you use may be called something other than <samp>`show w'</samp> and
<samp>`show c'</samp>; they could even be mouse-clicks or menu items--whatever
suits your program.
</p>
<p>
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the program, if
necessary. Here is a sample; alter the names:
</p>
<pre>
Yoyodyne, Inc., hereby disclaims all copyright
interest in the program `Gnomovision'
(which makes passes at compilers) written
by James Hacker.
<var>signature of Ty Coon</var>, 1 April 1989
Ty Coon, President of Vice
</pre>
<p>
This General Public License does not permit incorporating your program into
proprietary programs. If your program is a subroutine library, you may
consider it more useful to permit linking proprietary applications with the
library. If this is what you want to do, use the
<a href="https://www.gnu.org/licenses/lgpl.html">GNU Lesser General Public License</a>
instead of this License.
</p>
</body>
</html>

View File

@@ -1,124 +1,126 @@
INCLUDEPATH += $$PWD
include(lineedit/lineedit.pri)
include(properties/properties.pri)
include(powermanagement/powermanagement.pri)
include(properties/properties.pri)
unix:!macx:dbus: include(qtnotify/qtnotify.pri)
HEADERS += \
$$PWD/mainwindow.h \
$$PWD/transferlistwidget.h \
$$PWD/transferlistdelegate.h \
$$PWD/transferlistfilterswidget.h \
$$PWD/transferlistsortmodel.h \
$$PWD/torrentcategorydialog.h \
$$PWD/torrentcontentmodel.h \
$$PWD/torrentcontentmodelitem.h \
$$PWD/torrentcontentmodelfolder.h \
$$PWD/torrentcontentmodelfile.h \
$$PWD/torrentcontentfiltermodel.h \
$$PWD/torrentcontenttreeview.h \
$$PWD/deletionconfirmationdlg.h \
$$PWD/statusbar.h \
$$PWD/speedlimitdlg.h \
$$PWD/about_imp.h \
$$PWD/previewlistdelegate.h \
$$PWD/downloadfromurldlg.h \
$$PWD/trackerlogin.h \
$$PWD/hidabletabwidget.h \
$$PWD/executionlog.h \
$$PWD/guiiconprovider.h \
$$PWD/updownratiodlg.h \
$$PWD/loglistwidget.h \
$$PWD/addnewtorrentdialog.h \
$$PWD/advancedsettings.h \
$$PWD/autoexpandabledialog.h \
$$PWD/statsdialog.h \
$$PWD/banlistoptions.h \
$$PWD/categoryfiltermodel.h \
$$PWD/categoryfilterproxymodel.h \
$$PWD/categoryfilterwidget.h \
$$PWD/cookiesdialog.h \
$$PWD/cookiesmodel.h \
$$PWD/deletionconfirmationdlg.h \
$$PWD/downloadfromurldlg.h \
$$PWD/executionlog.h \
$$PWD/fspathedit.h \
$$PWD/fspathedit_p.h \
$$PWD/guiiconprovider.h \
$$PWD/hidabletabwidget.h \
$$PWD/ipsubnetwhitelistoptionsdialog.h \
$$PWD/loglistwidget.h \
$$PWD/mainwindow.h \
$$PWD/messageboxraised.h \
$$PWD/optionsdlg.h \
$$PWD/advancedsettings.h \
$$PWD/shutdownconfirmdlg.h \
$$PWD/torrentmodel.h \
$$PWD/torrentcreatordlg.h \
$$PWD/previewlistdelegate.h \
$$PWD/previewselectdialog.h \
$$PWD/rss/articlelistwidget.h \
$$PWD/rss/automatedrssdownloader.h \
$$PWD/rss/feedlistwidget.h \
$$PWD/rss/htmlbrowser.h \
$$PWD/rss/rsswidget.h \
$$PWD/scanfoldersdelegate.h \
$$PWD/search/searchwidget.h \
$$PWD/search/searchtab.h \
$$PWD/search/pluginselectdlg.h \
$$PWD/search/pluginsourcedlg.h \
$$PWD/search/searchlistdelegate.h \
$$PWD/search/searchsortmodel.h \
$$PWD/cookiesmodel.h \
$$PWD/cookiesdialog.h \
$$PWD/categoryfiltermodel.h \
$$PWD/categoryfilterproxymodel.h \
$$PWD/categoryfilterwidget.h \
$$PWD/search/searchtab.h \
$$PWD/search/searchwidget.h \
$$PWD/shutdownconfirmdlg.h \
$$PWD/speedlimitdlg.h \
$$PWD/statsdialog.h \
$$PWD/statusbar.h \
$$PWD/tagfiltermodel.h \
$$PWD/tagfilterproxymodel.h \
$$PWD/tagfilterwidget.h \
$$PWD/banlistoptions.h \
$$PWD/ipsubnetwhitelistoptionsdialog.h \
$$PWD/rss/rsswidget.h \
$$PWD/rss/articlelistwidget.h \
$$PWD/rss/feedlistwidget.h \
$$PWD/rss/automatedrssdownloader.h \
$$PWD/rss/htmlbrowser.h \
$$PWD/fspathedit.h \
$$PWD/fspathedit_p.h \
$$PWD/previewselectdialog.h \
$$PWD/torrentcategorydialog.h \
$$PWD/torrentcontentfiltermodel.h \
$$PWD/torrentcontentmodel.h \
$$PWD/torrentcontentmodelfile.h \
$$PWD/torrentcontentmodelfolder.h \
$$PWD/torrentcontentmodelitem.h \
$$PWD/torrentcontenttreeview.h \
$$PWD/torrentcreatordlg.h \
$$PWD/torrentmodel.h \
$$PWD/trackerlogin.h \
$$PWD/transferlistdelegate.h \
$$PWD/transferlistfilterswidget.h \
$$PWD/transferlistsortmodel.h \
$$PWD/transferlistwidget.h \
$$PWD/updownratiodlg.h \
$$PWD/utils.h
SOURCES += \
$$PWD/mainwindow.cpp \
$$PWD/transferlistwidget.cpp \
$$PWD/transferlistsortmodel.cpp \
$$PWD/transferlistdelegate.cpp \
$$PWD/transferlistfilterswidget.cpp \
$$PWD/torrentcategorydialog.cpp \
$$PWD/torrentcontentmodel.cpp \
$$PWD/torrentcontentmodelitem.cpp \
$$PWD/torrentcontentmodelfolder.cpp \
$$PWD/torrentcontentmodelfile.cpp \
$$PWD/torrentcontentfiltermodel.cpp \
$$PWD/torrentcontenttreeview.cpp \
$$PWD/executionlog.cpp \
$$PWD/speedlimitdlg.cpp \
$$PWD/guiiconprovider.cpp \
$$PWD/updownratiodlg.cpp \
$$PWD/loglistwidget.cpp \
$$PWD/addnewtorrentdialog.cpp \
$$PWD/autoexpandabledialog.cpp \
$$PWD/statsdialog.cpp \
$$PWD/messageboxraised.cpp \
$$PWD/statusbar.cpp \
$$PWD/advancedsettings.cpp \
$$PWD/trackerlogin.cpp \
$$PWD/autoexpandabledialog.cpp \
$$PWD/banlistoptions.cpp \
$$PWD/categoryfiltermodel.cpp \
$$PWD/categoryfilterproxymodel.cpp \
$$PWD/categoryfilterwidget.cpp \
$$PWD/cookiesdialog.cpp \
$$PWD/cookiesmodel.cpp \
$$PWD/executionlog.cpp \
$$PWD/fspathedit.cpp \
$$PWD/fspathedit_p.cpp \
$$PWD/guiiconprovider.cpp \
$$PWD/ipsubnetwhitelistoptionsdialog.cpp \
$$PWD/loglistwidget.cpp \
$$PWD/mainwindow.cpp \
$$PWD/messageboxraised.cpp \
$$PWD/optionsdlg.cpp \
$$PWD/shutdownconfirmdlg.cpp \
$$PWD/torrentmodel.cpp \
$$PWD/torrentcreatordlg.cpp \
$$PWD/previewselectdialog.cpp \
$$PWD/rss/articlelistwidget.cpp \
$$PWD/rss/automatedrssdownloader.cpp \
$$PWD/rss/feedlistwidget.cpp \
$$PWD/rss/htmlbrowser.cpp \
$$PWD/rss/rsswidget.cpp \
$$PWD/scanfoldersdelegate.cpp \
$$PWD/search/searchwidget.cpp \
$$PWD/search/searchtab.cpp \
$$PWD/search/pluginselectdlg.cpp \
$$PWD/search/pluginsourcedlg.cpp \
$$PWD/search/searchlistdelegate.cpp \
$$PWD/search/searchsortmodel.cpp \
$$PWD/cookiesmodel.cpp \
$$PWD/cookiesdialog.cpp \
$$PWD/categoryfiltermodel.cpp \
$$PWD/categoryfilterproxymodel.cpp \
$$PWD/categoryfilterwidget.cpp \
$$PWD/search/searchtab.cpp \
$$PWD/search/searchwidget.cpp \
$$PWD/shutdownconfirmdlg.cpp \
$$PWD/speedlimitdlg.cpp \
$$PWD/statsdialog.cpp \
$$PWD/statusbar.cpp \
$$PWD/tagfiltermodel.cpp \
$$PWD/tagfilterproxymodel.cpp \
$$PWD/tagfilterwidget.cpp \
$$PWD/banlistoptions.cpp \
$$PWD/ipsubnetwhitelistoptionsdialog.cpp \
$$PWD/rss/rsswidget.cpp \
$$PWD/rss/articlelistwidget.cpp \
$$PWD/rss/feedlistwidget.cpp \
$$PWD/rss/automatedrssdownloader.cpp \
$$PWD/rss/htmlbrowser.cpp \
$$PWD/fspathedit.cpp \
$$PWD/fspathedit_p.cpp \
$$PWD/previewselectdialog.cpp \
$$PWD/torrentcategorydialog.cpp \
$$PWD/torrentcontentfiltermodel.cpp \
$$PWD/torrentcontentmodel.cpp \
$$PWD/torrentcontentmodelfile.cpp \
$$PWD/torrentcontentmodelfolder.cpp \
$$PWD/torrentcontentmodelitem.cpp \
$$PWD/torrentcontenttreeview.cpp \
$$PWD/torrentcreatordlg.cpp \
$$PWD/torrentmodel.cpp \
$$PWD/trackerlogin.cpp \
$$PWD/transferlistdelegate.cpp \
$$PWD/transferlistfilterswidget.cpp \
$$PWD/transferlistsortmodel.cpp \
$$PWD/transferlistwidget.cpp \
$$PWD/updownratiodlg.cpp \
$$PWD/utils.cpp
win32|macx {
HEADERS += $$PWD/programupdater.h
@@ -131,30 +133,30 @@ macx {
}
FORMS += \
$$PWD/mainwindow.ui \
$$PWD/about.ui \
$$PWD/previewselectdialog.ui \
$$PWD/login.ui \
$$PWD/downloadfromurldlg.ui \
$$PWD/bandwidth_limit.ui \
$$PWD/updownratiodlg.ui \
$$PWD/confirmdeletiondlg.ui \
$$PWD/shutdownconfirmdlg.ui \
$$PWD/executionlog.ui \
$$PWD/addnewtorrentdialog.ui \
$$PWD/autoexpandabledialog.ui \
$$PWD/statsdialog.ui \
$$PWD/bandwidth_limit.ui \
$$PWD/banlistoptions.ui \
$$PWD/confirmdeletiondlg.ui \
$$PWD/cookiesdialog.ui \
$$PWD/downloadfromurldlg.ui \
$$PWD/executionlog.ui \
$$PWD/ipsubnetwhitelistoptionsdialog.ui \
$$PWD/login.ui \
$$PWD/mainwindow.ui \
$$PWD/optionsdlg.ui \
$$PWD/torrentcreatordlg.ui \
$$PWD/search/searchwidget.ui \
$$PWD/previewselectdialog.ui \
$$PWD/rss/automatedrssdownloader.ui \
$$PWD/rss/rsswidget.ui \
$$PWD/search/pluginselectdlg.ui \
$$PWD/search/pluginsourcedlg.ui \
$$PWD/search/searchtab.ui \
$$PWD/cookiesdialog.ui \
$$PWD/banlistoptions.ui \
$$PWD/ipsubnetwhitelistoptionsdialog.ui \
$$PWD/rss/rsswidget.ui \
$$PWD/rss/automatedrssdownloader.ui \
$$PWD/torrentcategorydialog.ui
$$PWD/search/searchwidget.ui \
$$PWD/shutdownconfirmdlg.ui \
$$PWD/statsdialog.ui \
$$PWD/torrentcategorydialog.ui \
$$PWD/torrentcreatordlg.ui \
$$PWD/updownratiodlg.ui
RESOURCES += $$PWD/about.qrc

View File

@@ -37,6 +37,7 @@
#include "base/preferences.h"
#include "base/utils/net.h"
#include "ui_ipsubnetwhitelistoptionsdialog.h"
#include "utils.h"
IPSubnetWhitelistOptionsDialog::IPSubnetWhitelistOptionsDialog(QWidget *parent)
: QDialog(parent)
@@ -57,6 +58,8 @@ IPSubnetWhitelistOptionsDialog::IPSubnetWhitelistOptionsDialog(QWidget *parent)
m_ui->whitelistedIPSubnetList->setModel(m_sortFilter);
m_ui->whitelistedIPSubnetList->sortByColumn(0, Qt::AscendingOrder);
m_ui->buttonWhitelistIPSubnet->setEnabled(false);
Utils::Gui::resize(this);
}
IPSubnetWhitelistOptionsDialog::~IPSubnetWhitelistOptionsDialog()
@@ -68,12 +71,10 @@ void IPSubnetWhitelistOptionsDialog::on_buttonBox_accepted()
{
if (m_modified) {
// save to session
QList<Utils::Net::Subnet> subnets;
QStringList subnets;
// Operate on the m_sortFilter to grab the strings in sorted order
for (int i = 0; i < m_sortFilter->rowCount(); ++i) {
const QString subnet = m_sortFilter->index(i, 0).data().toString();
subnets.append(QHostAddress::parseSubnet(subnet));
}
for (int i = 0; i < m_sortFilter->rowCount(); ++i)
subnets.append(m_sortFilter->index(i, 0).data().toString());
Preferences::instance()->setWebUiAuthSubnetWhitelist(subnets);
QDialog::accept();
}

View File

@@ -25,7 +25,7 @@
<property name="frameShadow">
<enum>QFrame::Raised</enum>
</property>
<layout class="QVBoxLayout" name="verticalLayout_21">
<layout class="QVBoxLayout" name="verticalLayout_31">
<item>
<widget class="QTreeView" name="whitelistedIPSubnetList">
<property name="rootIsDecorated">
@@ -46,7 +46,7 @@
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_18">
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QLineEdit" name="txtIPSubnet">
<property name="placeholderText">
@@ -54,6 +54,10 @@
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_12">
<item>
<widget class="QPushButton" name="buttonWhitelistIPSubnet">
<property name="text">

View File

@@ -6,11 +6,5 @@ set(QBT_LINEEDIT_HEADERS
src/lineedit.h
)
set(QBT_LINEEDIT_RESOURCES
resources/lineeditimages.qrc
)
add_library(qbt_lineedit STATIC ${QBT_LINEEDIT_SOURCES} ${QBT_LINEEDIT_HEADERS})
target_link_libraries(qbt_lineedit Qt5::Widgets)
qbt_target_sources(${QBT_LINEEDIT_RESOURCES})

View File

@@ -1,4 +1,3 @@
INCLUDEPATH += $$PWD/src
HEADERS += $$PWD/src/lineedit.h
SOURCES += $$PWD/src/lineedit.cpp
RESOURCES += $$PWD/resources/lineeditimages.qrc

View File

@@ -1,5 +0,0 @@
<!DOCTYPE RCC><RCC version="1.0">
<qresource>
<file>lineeditimages/search.png</file>
</qresource>
</RCC>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 292 B

View File

@@ -8,37 +8,35 @@
****************************************************************************/
#include "lineedit.h"
#include <algorithm>
#include <QResizeEvent>
#include <QStyle>
#include <QToolButton>
#include <QResizeEvent>
#include "guiiconprovider.h"
LineEdit::LineEdit(QWidget *parent)
: QLineEdit(parent)
{
QPixmap pixmap1(":/lineeditimages/search.png");
searchButton = new QToolButton(this);
searchButton->setIcon(QIcon(pixmap1));
searchButton->setIconSize(pixmap1.size());
searchButton->setCursor(Qt::ArrowCursor);
searchButton->setStyleSheet("QToolButton { border: none; padding: 2px; }");
QSize searchButtonHint = searchButton->sizeHint();
m_searchButton = new QToolButton(this);
m_searchButton->setIcon(GuiIconProvider::instance()->getIcon("edit-find"));
m_searchButton->setCursor(Qt::ArrowCursor);
m_searchButton->setStyleSheet("QToolButton {border: none; padding: 2px;}");
// padding between text and widget borders
setStyleSheet(QString("QLineEdit {padding-left: %1px;}").arg(m_searchButton->sizeHint().width()));
QSize clearButtonHint(0, 0);
setClearButtonEnabled(true);
setStyleSheet(QString("QLineEdit { padding-left: %1px; }").arg(searchButtonHint.width())); // padding between text and widget borders
QSize widgetHint = sizeHint();
int frameWidth = style()->pixelMetric(QStyle::PM_DefaultFrameWidth);
setMaximumHeight(std::max({ widgetHint.height(), searchButtonHint.height(), clearButtonHint.height() }) + frameWidth * 2);
const int frameWidth = style()->pixelMetric(QStyle::PM_DefaultFrameWidth);
setMaximumHeight(std::max(sizeHint().height(), m_searchButton->sizeHint().height()) + frameWidth * 2);
setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);
}
void LineEdit::resizeEvent(QResizeEvent *e)
{
int frameWidth = style()->pixelMetric(QStyle::PM_DefaultFrameWidth);
QSize sz = searchButton->sizeHint();
searchButton->move(frameWidth, (e->size().height() - sz.height()) / 2);
const int frameWidth = style()->pixelMetric(QStyle::PM_DefaultFrameWidth);
m_searchButton->move(frameWidth, (e->size().height() - m_searchButton->sizeHint().height()) / 2);
}

View File

@@ -22,10 +22,10 @@ public:
LineEdit(QWidget *parent);
protected:
void resizeEvent(QResizeEvent *e);
void resizeEvent(QResizeEvent *e) override;
private:
QToolButton *searchButton;
QToolButton *m_searchButton;
};
#endif // LIENEDIT_H

View File

@@ -33,8 +33,12 @@
#include <QSize>
#include <objc/objc.h>
QPixmap pixmapForExtension(const QString &ext, const QSize &size);
void overrideDockClickHandler(bool (*dockClickHandler)(id, SEL, ...));
void displayNotification(const QString &title, const QString &message);
namespace MacUtils
{
QPixmap pixmapForExtension(const QString &ext, const QSize &size);
void overrideDockClickHandler(bool (*dockClickHandler)(id, SEL, ...));
void displayNotification(const QString &title, const QString &message);
void openFiles(const QSet<QString> &pathsList);
}
#endif // MACUTILITIES_H

View File

@@ -28,56 +28,72 @@
#include "macutilities.h"
#include <QSet>
#include <QtMac>
#include <objc/message.h>
#import <Cocoa/Cocoa.h>
QPixmap pixmapForExtension(const QString &ext, const QSize &size)
namespace MacUtils
{
@autoreleasepool {
NSImage *image = [[NSWorkspace sharedWorkspace] iconForFileType:ext.toNSString()];
if (image) {
NSRect rect = NSMakeRect(0, 0, size.width(), size.height());
CGImageRef cgImage = [image CGImageForProposedRect:&rect context:nil hints:nil];
return QtMac::fromCGImageRef(cgImage);
QPixmap pixmapForExtension(const QString &ext, const QSize &size)
{
@autoreleasepool {
NSImage *image = [[NSWorkspace sharedWorkspace] iconForFileType:ext.toNSString()];
if (image) {
NSRect rect = NSMakeRect(0, 0, size.width(), size.height());
CGImageRef cgImage = [image CGImageForProposedRect:&rect context:nil hints:nil];
return QtMac::fromCGImageRef(cgImage);
}
return QPixmap();
}
}
void overrideDockClickHandler(bool (*dockClickHandler)(id, SEL, ...))
{
NSApplication *appInst = [NSApplication sharedApplication];
if (!appInst)
return;
Class delClass = [[appInst delegate] class];
SEL shouldHandle = sel_registerName("applicationShouldHandleReopen:hasVisibleWindows:");
if (class_getInstanceMethod(delClass, shouldHandle)) {
if (class_replaceMethod(delClass, shouldHandle, (IMP)dockClickHandler, "B@:"))
qDebug("Registered dock click handler (replaced original method)");
else
qWarning("Failed to replace method for dock click handler");
}
else {
if (class_addMethod(delClass, shouldHandle, (IMP)dockClickHandler, "B@:"))
qDebug("Registered dock click handler");
else
qWarning("Failed to register dock click handler");
}
}
void displayNotification(const QString &title, const QString &message)
{
@autoreleasepool {
NSUserNotification *notification = [[NSUserNotification alloc] init];
notification.title = title.toNSString();
notification.informativeText = message.toNSString();
notification.soundName = NSUserNotificationDefaultSoundName;
[[NSUserNotificationCenter defaultUserNotificationCenter] deliverNotification:notification];
}
}
void openFiles(const QSet<QString> &pathsList)
{
@autoreleasepool {
NSMutableArray *pathURLs = [NSMutableArray arrayWithCapacity:pathsList.size()];
for (const auto &path : pathsList)
[pathURLs addObject:[NSURL fileURLWithPath:path.toNSString()]];
[[NSWorkspace sharedWorkspace] activateFileViewerSelectingURLs:pathURLs];
}
return QPixmap();
}
}
void overrideDockClickHandler(bool (*dockClickHandler)(id, SEL, ...))
{
NSApplication *appInst = [NSApplication sharedApplication];
if (!appInst)
return;
Class delClass = [[appInst delegate] class];
SEL shouldHandle = sel_registerName("applicationShouldHandleReopen:hasVisibleWindows:");
if (class_getInstanceMethod(delClass, shouldHandle)) {
if (class_replaceMethod(delClass, shouldHandle, (IMP)dockClickHandler, "B@:"))
qDebug("Registered dock click handler (replaced original method)");
else
qWarning("Failed to replace method for dock click handler");
}
else {
if (class_addMethod(delClass, shouldHandle, (IMP)dockClickHandler, "B@:"))
qDebug("Registered dock click handler");
else
qWarning("Failed to register dock click handler");
}
}
void displayNotification(const QString &title, const QString &message)
{
@autoreleasepool {
NSUserNotification *notification = [[NSUserNotification alloc] init];
notification.title = title.toNSString();
notification.informativeText = message.toNSString();
notification.soundName = NSUserNotificationDefaultSoundName;
[[NSUserNotificationCenter defaultUserNotificationCenter] deliverNotification:notification];
}
}

View File

@@ -30,84 +30,84 @@
#include "mainwindow.h"
#ifdef Q_OS_MAC
#include <QtMacExtras>
#include <QtMac>
#endif
#include <QClipboard>
#include <QCloseEvent>
#include <QCryptographicHash>
#include <QDebug>
#include <QDesktopServices>
#include <QFileDialog>
#include <QFileSystemWatcher>
#include <QMessageBox>
#include <QMimeData>
#include <QProcess>
#include <QScrollBar>
#include <QShortcut>
#include <QSplitter>
#include <QStatusBar>
#include <QSysInfo>
#include <QtGlobal>
#include <QTimer>
#ifdef Q_OS_MAC
#include <QtMac>
#include <QtMacExtras>
#endif
#if (defined(Q_OS_UNIX) && !defined(Q_OS_MAC)) && defined(QT_DBUS_LIB)
#include <QDBusConnection>
#include "notifications.h"
#endif
#include <QDebug>
#include <QFileDialog>
#include <QFileSystemWatcher>
#include <QMessageBox>
#include <QTimer>
#include <QDesktopServices>
#include <QStatusBar>
#include <QClipboard>
#include <QCloseEvent>
#include <QShortcut>
#include <QScrollBar>
#include <QSplitter>
#include <QSysInfo>
#include <QMimeData>
#include <QCryptographicHash>
#include <QProcess>
#include "base/preferences.h"
#include "base/settingsstorage.h"
#include "base/logger.h"
#include "base/utils/misc.h"
#include "base/utils/fs.h"
#ifdef Q_OS_WIN
#include "base/net/downloadmanager.h"
#include "base/net/downloadhandler.h"
#endif
#include "about_imp.h"
#include "addnewtorrentdialog.h"
#include "application.h"
#include "autoexpandabledialog.h"
#include "base/bittorrent/session.h"
#include "base/bittorrent/sessionstatus.h"
#include "base/bittorrent/torrenthandle.h"
#include "base/global.h"
#include "base/logger.h"
#include "base/preferences.h"
#include "base/rss/rss_folder.h"
#include "base/rss/rss_session.h"
#include "base/settingsstorage.h"
#include "base/utils/fs.h"
#include "base/utils/misc.h"
#include "cookiesdialog.h"
#include "downloadfromurldlg.h"
#include "executionlog.h"
#include "guiiconprovider.h"
#include "hidabletabwidget.h"
#include "lineedit.h"
#include "optionsdlg.h"
#include "peerlistwidget.h"
#include "powermanagement.h"
#include "propertieswidget.h"
#include "rss/rsswidget.h"
#include "search/searchwidget.h"
#include "speedlimitdlg.h"
#include "statsdialog.h"
#include "statusbar.h"
#include "torrentcreatordlg.h"
#include "torrentmodel.h"
#include "trackerlist.h"
#include "transferlistfilterswidget.h"
#include "transferlistwidget.h"
#include "ui_mainwindow.h"
#include "utils.h"
#include "application.h"
#ifdef Q_OS_WIN
#include "base/net/downloadhandler.h"
#include "base/net/downloadmanager.h"
#endif
#ifdef Q_OS_MAC
#include "macutilities.h"
#endif
#if defined(Q_OS_WIN) || defined(Q_OS_MAC)
#include "programupdater.h"
#endif
#include "powermanagement.h"
#include "guiiconprovider.h"
#include "torrentmodel.h"
#include "autoexpandabledialog.h"
#include "torrentcreatordlg.h"
#include "downloadfromurldlg.h"
#include "addnewtorrentdialog.h"
#include "statsdialog.h"
#include "cookiesdialog.h"
#include "speedlimitdlg.h"
#include "transferlistwidget.h"
#include "search/searchwidget.h"
#include "trackerlist.h"
#include "peerlistwidget.h"
#include "transferlistfilterswidget.h"
#include "propertieswidget.h"
#include "statusbar.h"
#include "rss/rsswidget.h"
#include "about_imp.h"
#include "optionsdlg.h"
#if LIBTORRENT_VERSION_NUM < 10100
#include "trackerlogin.h"
#endif
#include "lineedit.h"
#include "executionlog.h"
#include "hidabletabwidget.h"
#include "ui_mainwindow.h"
#ifdef Q_OS_MAC
#include "macutilities.h"
#endif
#ifdef Q_OS_MAC
void qt_mac_set_dock_menu(QMenu *menu);
@@ -231,7 +231,7 @@ MainWindow::MainWindow(QWidget *parent)
m_searchFilter = new LineEdit(this);
m_searchFilterAction = m_ui->toolBar->insertWidget(m_ui->actionLock, m_searchFilter);
m_searchFilter->setPlaceholderText(tr("Filter torrent list..."));
m_searchFilter->setFixedWidth(200);
m_searchFilter->setFixedWidth(Utils::Gui::scaledSize(this, 200));
QWidget *spacer = new QWidget(this);
spacer->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
@@ -843,6 +843,11 @@ void MainWindow::createKeyboardShortcuts()
m_ui->actionDelete->setShortcutContext(Qt::WidgetShortcut); // nullify its effect: delete key event is handled by respective widgets, not here
m_ui->actionDownloadFromURL->setShortcut(Qt::CTRL + Qt::SHIFT + Qt::Key_O);
m_ui->actionExit->setShortcut(Qt::CTRL + Qt::Key_Q);
#ifdef Q_OS_MAC
m_ui->actionCloseWindow->setShortcut(QKeySequence::Close);
#else
m_ui->actionCloseWindow->setVisible(false);
#endif
QShortcut *switchTransferShortcut = new QShortcut(Qt::ALT + Qt::Key_1, this);
connect(switchTransferShortcut, &QShortcut::activated, this, &MainWindow::displayTransferTab);
@@ -978,6 +983,16 @@ void MainWindow::on_actionExit_triggered()
close();
}
#ifdef Q_OS_MAC
void MainWindow::on_actionCloseWindow_triggered()
{
// On macOS window close is basically equivalent to window hide.
// If you decide to implement this functionality for other OS,
// then you will also need ui lock checks like in actionExit.
close();
}
#endif
QWidget *MainWindow::currentTabWidget() const
{
if (isMinimized() || !isVisible())
@@ -1225,25 +1240,26 @@ void MainWindow::dropEvent(QDropEvent *event)
// remove scheme
QStringList files;
if (event->mimeData()->hasUrls()) {
const QList<QUrl> urls = event->mimeData()->urls();
foreach (const QUrl &url, urls) {
if (!url.isEmpty()) {
if (url.scheme().compare("file", Qt::CaseInsensitive) == 0)
files << url.toLocalFile();
else
files << url.toString();
}
foreach (const QUrl &url, event->mimeData()->urls()) {
if (url.isEmpty())
continue;
files << ((url.scheme().compare("file", Qt::CaseInsensitive) == 0)
? url.toLocalFile()
: url.toString());
}
}
else {
files = event->mimeData()->text().split('\n');
}
// differentiate ".torrent" files and others
// differentiate ".torrent" files/links & magnet links from others
QStringList torrentFiles, otherFiles;
foreach (const QString &file, files) {
if (file.startsWith("magnet:", Qt::CaseInsensitive)
|| file.endsWith(C_TORRENT_FILE_EXTENSION, Qt::CaseInsensitive))
const bool isTorrentLink = (file.startsWith("magnet:", Qt::CaseInsensitive)
|| file.endsWith(C_TORRENT_FILE_EXTENSION, Qt::CaseInsensitive)
|| Utils::Misc::isUrl(file));
if (isTorrentLink)
torrentFiles << file;
else
otherFiles << file;
@@ -1297,7 +1313,7 @@ static bool dockClickHandler(id self, SEL cmd, ...)
void MainWindow::setupDockClickHandler()
{
dockMainWindowHandle = this;
overrideDockClickHandler(dockClickHandler);
MacUtils::overrideDockClickHandler(dockClickHandler);
}
#endif
@@ -1556,7 +1572,7 @@ void MainWindow::showNotificationBaloon(QString title, QString msg) const
if (!reply.isError())
return;
#elif defined(Q_OS_MAC)
displayNotification(title, msg);
MacUtils::displayNotification(title, msg);
#else
if (m_systrayIcon && QSystemTrayIcon::supportsMessages())
m_systrayIcon->showMessage(title, msg, QSystemTrayIcon::Information, TIME_TRAY_BALLOON);
@@ -1838,7 +1854,7 @@ void MainWindow::toggleAlternativeSpeeds()
void MainWindow::on_actionDonateMoney_triggered()
{
QDesktopServices::openUrl(QUrl("http://www.qbittorrent.org/donate"));
QDesktopServices::openUrl(QUrl("https://www.qbittorrent.org/donate"));
}
void MainWindow::showConnectionSettings()

View File

@@ -187,7 +187,9 @@ private slots:
void toolbarTextBeside();
void toolbarTextUnder();
void toolbarFollowSystem();
#ifndef Q_OS_MAC
#ifdef Q_OS_MAC
void on_actionCloseWindow_triggered();
#else
void toggleVisibility(const QSystemTrayIcon::ActivationReason reason = QSystemTrayIcon::Trigger);
void createSystrayDelayed();
void updateTrayIconMenu();

View File

@@ -90,6 +90,7 @@
</property>
<addaction name="actionOpen"/>
<addaction name="actionDownloadFromURL"/>
<addaction name="actionCloseWindow"/>
<addaction name="separator"/>
<addaction name="actionExit"/>
</widget>
@@ -466,6 +467,11 @@
<string>Critical Messages</string>
</property>
</action>
<action name="actionCloseWindow">
<property name="text">
<string>Close Window</string>
</property>
</action>
</widget>
<resources/>
<connections/>

View File

@@ -68,6 +68,7 @@
#include "ipsubnetwhitelistoptionsdialog.h"
#include "guiiconprovider.h"
#include "scanfoldersdelegate.h"
#include "utils.h"
#include "ui_optionsdlg.h"
@@ -99,13 +100,21 @@ OptionsDialog::OptionsDialog(QWidget *parent)
m_ui->tabSelection->item(TAB_WEBUI)->setHidden(true);
#endif
m_ui->tabSelection->item(TAB_ADVANCED)->setIcon(GuiIconProvider::instance()->getIcon("preferences-other"));
// set uniform size for all icons
int maxHeight = -1;
for (int i = 0; i < m_ui->tabSelection->count(); ++i)
maxHeight = std::max(maxHeight, m_ui->tabSelection->visualItemRect(m_ui->tabSelection->item(i)).size().height());
for (int i = 0; i < m_ui->tabSelection->count(); ++i) {
// uniform size for all icons
m_ui->tabSelection->item(i)->setSizeHint(QSize(std::numeric_limits<int>::max(), 62));
const QSize size(std::numeric_limits<int>::max(), static_cast<int>(maxHeight * 1.2));
m_ui->tabSelection->item(i)->setSizeHint(size);
}
m_ui->IpFilterRefreshBtn->setIcon(GuiIconProvider::instance()->getIcon("view-refresh"));
m_ui->labelGlobalRate->setPixmap(Utils::Gui::scaledPixmap(":/icons/slow_off.png", this, 16));
m_ui->labelAltRate->setPixmap(Utils::Gui::scaledPixmap(":/icons/slow.png", this, 16));
m_ui->deleteTorrentWarningIcon->setPixmap(QApplication::style()->standardIcon(QStyle::SP_MessageBoxCritical).pixmap(16, 16));
m_ui->deleteTorrentWarningIcon->hide();
m_ui->deleteTorrentWarningLabel->hide();
@@ -139,7 +148,7 @@ OptionsDialog::OptionsDialog(QWidget *parent)
connect(ScanFoldersModel::instance(), &QAbstractListModel::dataChanged, this, &ThisType::enableApplyButton);
connect(m_ui->scanFoldersView->selectionModel(), &QItemSelectionModel::selectionChanged, this, &ThisType::handleScanFolderViewSelectionChanged);
connect(m_ui->buttonBox, SIGNAL(clicked(QAbstractButton*)), this, SLOT(applySettings(QAbstractButton*)));
connect(m_ui->buttonBox, &QDialogButtonBox::clicked, this, &OptionsDialog::applySettings);
// Languages supported
initializeLanguageCombo();
@@ -445,25 +454,19 @@ void OptionsDialog::changePage(QListWidgetItem *current, QListWidgetItem *previo
void OptionsDialog::loadWindowState()
{
const Preferences* const pref = Preferences::instance();
resize(pref->getPrefSize(this->size()));
Utils::Gui::resize(this, Preferences::instance()->getPrefSize());
}
void OptionsDialog::loadSplitterState()
{
const Preferences* const pref = Preferences::instance();
const QStringList sizesStr = Preferences::instance()->getPrefHSplitterSizes();
const QStringList sizes_str = pref->getPrefHSplitterSizes();
QList<int> sizes;
if (sizes_str.size() == 2) {
sizes << sizes_str.first().toInt();
sizes << sizes_str.last().toInt();
}
else {
sizes << 116;
sizes << m_ui->hsplitter->width() - 116;
}
// width has been modified, use height as width reference instead
const int width = Utils::Gui::scaledSize(this
, (m_ui->tabSelection->item(TAB_UI)->sizeHint().height() * 2));
QList<int> sizes {width, (m_ui->hsplitter->width() - width)};
if (sizesStr.size() == 2)
sizes = {sizesStr.first().toInt(), sizesStr.last().toInt()};
m_ui->hsplitter->setSizes(sizes);
}
@@ -534,7 +537,7 @@ void OptionsDialog::saveOptions()
Application * const app = static_cast<Application*>(QCoreApplication::instance());
app->setFileLoggerPath(m_ui->textFileLogPath->selectedPath());
app->setFileLoggerBackup(m_ui->checkFileLogBackup->isChecked());
app->setFileLoggerMaxSize(m_ui->spinFileLogSize->value());
app->setFileLoggerMaxSize(m_ui->spinFileLogSize->value() * 1024);
app->setFileLoggerAge(m_ui->spinFileLogAge->value());
app->setFileLoggerAgeType(m_ui->comboFileLogAgeType->currentIndex());
app->setFileLoggerDeleteOld(m_ui->checkFileLogDelete->isChecked());
@@ -762,7 +765,7 @@ void OptionsDialog::loadOptions()
m_ui->checkFileLogDelete->setChecked(fileLogDelete);
m_ui->spinFileLogAge->setEnabled(fileLogDelete);
m_ui->comboFileLogAgeType->setEnabled(fileLogDelete);
m_ui->spinFileLogSize->setValue(app->fileLoggerMaxSize());
m_ui->spinFileLogSize->setValue(app->fileLoggerMaxSize() / 1024);
m_ui->spinFileLogAge->setValue(app->fileLoggerAge());
m_ui->comboFileLogAgeType->setCurrentIndex(app->fileLoggerAgeType());
// End General preferences
@@ -1578,7 +1581,7 @@ void OptionsDialog::on_IpFilterRefreshBtn_clicked()
session->setIPFilteringEnabled(true);
session->setIPFilterFile(""); // forcing Session reload filter file
session->setIPFilterFile(getFilter());
connect(session, SIGNAL(IPFilterParsed(bool, int)), SLOT(handleIPFilterParsed(bool, int)));
connect(session, &BitTorrent::Session::IPFilterParsed, this, &OptionsDialog::handleIPFilterParsed);
setCursor(QCursor(Qt::WaitCursor));
}
@@ -1590,7 +1593,7 @@ void OptionsDialog::handleIPFilterParsed(bool error, int ruleCount)
else
QMessageBox::information(this, tr("Successfully refreshed"), tr("Successfully parsed the provided IP filter: %1 rules were applied.", "%1 is a number").arg(ruleCount));
m_refreshingIpFilter = false;
disconnect(BitTorrent::Session::instance(), SIGNAL(IPFilterParsed(bool, int)), this, SLOT(handleIPFilterParsed(bool, int)));
disconnect(BitTorrent::Session::instance(), &BitTorrent::Session::IPFilterParsed, this, &OptionsDialog::handleIPFilterParsed);
}
QString OptionsDialog::languageToLocalizedString(const QLocale &locale)
@@ -1675,11 +1678,11 @@ bool OptionsDialog::setSslKey(const QByteArray &key)
// try different formats
const bool isKeyValid = (!QSslKey(key, QSsl::Rsa).isNull() || !QSslKey(key, QSsl::Ec).isNull());
if (isKeyValid) {
m_ui->lblSslKeyStatus->setPixmap(QPixmap(":/icons/qbt-theme/security-high.png").scaledToHeight(20, Qt::SmoothTransformation));
m_ui->lblSslKeyStatus->setPixmap(Utils::Gui::scaledPixmap(":/icons/qbt-theme/security-high.png", this, 24));
m_sslKey = key;
}
else {
m_ui->lblSslKeyStatus->setPixmap(QPixmap(":/icons/qbt-theme/security-low.png").scaledToHeight(20, Qt::SmoothTransformation));
m_ui->lblSslKeyStatus->setPixmap(Utils::Gui::scaledPixmap(":/icons/qbt-theme/security-low.png", this, 24));
m_sslKey.clear();
}
return isKeyValid;
@@ -1694,11 +1697,11 @@ bool OptionsDialog::setSslCertificate(const QByteArray &cert)
#ifndef QT_NO_OPENSSL
const bool isCertValid = !QSslCertificate(cert).isNull();
if (isCertValid) {
m_ui->lblSslCertStatus->setPixmap(QPixmap(":/icons/qbt-theme/security-high.png").scaledToHeight(20, Qt::SmoothTransformation));
m_ui->lblSslCertStatus->setPixmap(Utils::Gui::scaledPixmap(":/icons/qbt-theme/security-high.png", this, 24));
m_sslCert = cert;
}
else {
m_ui->lblSslCertStatus->setPixmap(QPixmap(":/icons/qbt-theme/security-low.png").scaledToHeight(20, Qt::SmoothTransformation));
m_ui->lblSslCertStatus->setPixmap(Utils::Gui::scaledPixmap(":/icons/qbt-theme/security-low.png", this, 24));
m_sslCert.clear();
}
return isCertValid;

View File

@@ -535,16 +535,16 @@
<item>
<widget class="QSpinBox" name="spinFileLogSize">
<property name="suffix">
<string> MB</string>
<string> KiB</string>
</property>
<property name="minimum">
<number>1</number>
</property>
<property name="maximum">
<number>1000</number>
<number>1024000</number>
</property>
<property name="value">
<number>10</number>
<number>65</number>
</property>
</widget>
</item>
@@ -1823,11 +1823,7 @@
</widget>
</item>
<item row="0" column="0" rowspan="2">
<widget class="QLabel" name="label_5">
<property name="pixmap">
<pixmap resource="../icons.qrc">:/icons/slow_off.png</pixmap>
</property>
</widget>
<widget class="QLabel" name="labelGlobalRate"/>
</item>
<item row="1" column="1">
<widget class="QCheckBox" name="checkDownloadLimit">
@@ -1970,11 +1966,7 @@
</widget>
</item>
<item row="0" column="0" rowspan="2">
<widget class="QLabel" name="label_16">
<property name="pixmap">
<pixmap resource="../icons.qrc">:/icons/slow.png</pixmap>
</property>
</widget>
<widget class="QLabel" name="labelAltRate"/>
</item>
<item row="0" column="1">
<widget class="QCheckBox" name="checkUploadLimitAlt">
@@ -2853,20 +2845,8 @@ Use ';' to split multiple entries. Can use wildcard '*'.</string>
<layout class="QGridLayout" name="gridLayout_11">
<item row="0" column="0">
<widget class="QLabel" name="lblSslCertStatus">
<property name="minimumSize">
<size>
<width>22</width>
<height>22</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>22</width>
<height>22</height>
</size>
</property>
<property name="text">
<string/>
<string notr="true"/>
</property>
</widget>
</item>
@@ -2906,20 +2886,8 @@ Use ';' to split multiple entries. Can use wildcard '*'.</string>
</item>
<item row="1" column="0">
<widget class="QLabel" name="lblSslKeyStatus">
<property name="minimumSize">
<size>
<width>22</width>
<height>22</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>22</width>
<height>22</height>
</size>
</property>
<property name="text">
<string/>
<string notr="true"/>
</property>
</widget>
</item>

View File

@@ -39,6 +39,7 @@
#include "base/utils/fs.h"
#include "base/utils/misc.h"
#include "previewlistdelegate.h"
#include "utils.h"
#define SETTINGS_KEY(name) "PreviewSelectDialog/" name
@@ -146,7 +147,7 @@ void PreviewSelectDialog::previewButtonClicked()
void PreviewSelectDialog::saveWindowState()
{
// Persist dialog size
m_storeDialogSize = this->size();
m_storeDialogSize = size();
// Persist TreeView Header state
m_storeTreeHeaderState = previewList->header()->saveState();
}
@@ -154,9 +155,8 @@ void PreviewSelectDialog::saveWindowState()
void PreviewSelectDialog::loadWindowState()
{
// Restore dialog size
if (m_storeDialogSize.value().isValid()) {
resize(m_storeDialogSize);
}
Utils::Gui::resize(this, m_storeDialogSize);
// Restore TreeView Header state
if (!m_storeTreeHeaderState.value().isEmpty()) {
m_headerStateInitialized = previewList->header()->restoreState(m_storeTreeHeaderState);

View File

@@ -53,17 +53,11 @@ protected:
const QString strL = left.data().toString();
const QString strR = right.data().toString();
const int result = Utils::String::naturalCompare(strL, strR, Qt::CaseInsensitive);
if (result != 0)
return (result < 0);
return (mapFromSource(left) < mapFromSource(right));
}
return (result < 0);
}
break;
default:
if (left.data() != right.data())
return QSortFilterProxyModel::lessThan(left, right);
return (mapFromSource(left) < mapFromSource(right));
return QSortFilterProxyModel::lessThan(left, right);
};
}
};

View File

@@ -180,10 +180,9 @@ void PeerListWidget::displayToggleColumnsMenu(const QPoint &)
Q_ASSERT(visibleCols > 0);
if (!isColumnHidden(col) && (visibleCols == 1))
return;
qDebug("Toggling column %d visibility", col);
setColumnHidden(col, !isColumnHidden(col));
if (!isColumnHidden(col) && (columnWidth(col) <= 5))
setColumnWidth(col, 100);
resizeColumnToContents(col);
saveSettings();
}
}

View File

@@ -1,33 +1,36 @@
INCLUDEPATH += $$PWD
FORMS += $$PWD/propertieswidget.ui \
$$PWD/trackersadditiondlg.ui \
$$PWD/peersadditiondlg.ui
FORMS += \
$$PWD/peersadditiondlg.ui \
$$PWD/propertieswidget.ui \
$$PWD/trackersadditiondlg.ui
HEADERS += $$PWD/propertieswidget.h \
$$PWD/peerlistwidget.h \
$$PWD/proplistdelegate.h \
$$PWD/trackerlist.h \
$$PWD/downloadedpiecesbar.h \
$$PWD/peerlistdelegate.h \
$$PWD/peerlistsortmodel.h \
$$PWD/peersadditiondlg.h \
$$PWD/trackersadditiondlg.h \
$$PWD/pieceavailabilitybar.h \
$$PWD/proptabbar.h \
$$PWD/speedwidget.h \
$$PWD/speedplotview.h \
$$PWD/piecesbar.h
HEADERS += \
$$PWD/downloadedpiecesbar.h \
$$PWD/peerlistdelegate.h \
$$PWD/peerlistsortmodel.h \
$$PWD/peerlistwidget.h \
$$PWD/peersadditiondlg.h \
$$PWD/pieceavailabilitybar.h \
$$PWD/piecesbar.h \
$$PWD/propertieswidget.h \
$$PWD/proplistdelegate.h \
$$PWD/proptabbar.h \
$$PWD/speedplotview.h \
$$PWD/speedwidget.h \
$$PWD/trackerlist.h \
$$PWD/trackersadditiondlg.h
SOURCES += $$PWD/propertieswidget.cpp \
$$PWD/proplistdelegate.cpp \
$$PWD/peerlistwidget.cpp \
$$PWD/trackerlist.cpp \
$$PWD/peersadditiondlg.cpp \
$$PWD/downloadedpiecesbar.cpp \
$$PWD/trackersadditiondlg.cpp \
$$PWD/pieceavailabilitybar.cpp \
$$PWD/proptabbar.cpp \
$$PWD/speedwidget.cpp \
$$PWD/speedplotview.cpp \
$$PWD/piecesbar.cpp
SOURCES += \
$$PWD/downloadedpiecesbar.cpp \
$$PWD/peerlistwidget.cpp \
$$PWD/peersadditiondlg.cpp \
$$PWD/pieceavailabilitybar.cpp \
$$PWD/piecesbar.cpp \
$$PWD/propertieswidget.cpp \
$$PWD/proplistdelegate.cpp \
$$PWD/proptabbar.cpp \
$$PWD/speedplotview.cpp \
$$PWD/speedwidget.cpp \
$$PWD/trackerlist.cpp \
$$PWD/trackersadditiondlg.cpp

View File

@@ -62,9 +62,14 @@
#include "torrentcontentmodel.h"
#include "trackerlist.h"
#include "transferlistwidget.h"
#include "utils.h"
#include "ui_propertieswidget.h"
#ifdef Q_OS_MAC
#include "macutilities.h"
#endif
PropertiesWidget::PropertiesWidget(QWidget *parent, MainWindow *mainWindow, TransferListWidget *transferList)
: QWidget(parent)
, m_ui(new Ui::PropertiesWidget())
@@ -83,10 +88,11 @@ PropertiesWidget::PropertiesWidget(QWidget *parent, MainWindow *mainWindow, Tran
m_propListDelegate = new PropListDelegate(this);
m_ui->filesList->setItemDelegate(m_propListDelegate);
m_ui->filesList->setSortingEnabled(true);
// Torrent content filtering
m_contentFilterLine = new LineEdit(this);
m_contentFilterLine->setPlaceholderText(tr("Filter files..."));
m_contentFilterLine->setMaximumSize(300, m_contentFilterLine->size().height());
m_contentFilterLine->setFixedWidth(Utils::Gui::scaledSize(this, 300));
connect(m_contentFilterLine, SIGNAL(textChanged(QString)), this, SLOT(filterText(QString)));
m_ui->contentFilterLayout->insertWidget(3, m_contentFilterLine);
@@ -108,7 +114,7 @@ PropertiesWidget::PropertiesWidget(QWidget *parent, MainWindow *mainWindow, Tran
connect(m_ui->filesList->header(), SIGNAL(sortIndicatorChanged(int,Qt::SortOrder)), this, SLOT(saveSettings()));
// set bar height relative to screen dpi
int barHeight = devicePixelRatio() * 18;
const int barHeight = Utils::Gui::scaledSize(this, 18);
// Downloaded pieces progress bar
m_ui->tempProgressBarArea->setVisible(false);
@@ -127,9 +133,9 @@ PropertiesWidget::PropertiesWidget(QWidget *parent, MainWindow *mainWindow, Tran
// Tracker list
m_trackerList = new TrackerList(this);
m_ui->trackerUpButton->setIcon(GuiIconProvider::instance()->getIcon("go-up"));
m_ui->trackerUpButton->setIconSize(Utils::Misc::smallIconSize());
m_ui->trackerUpButton->setIconSize(Utils::Gui::smallIconSize());
m_ui->trackerDownButton->setIcon(GuiIconProvider::instance()->getIcon("go-down"));
m_ui->trackerDownButton->setIconSize(Utils::Misc::smallIconSize());
m_ui->trackerDownButton->setIconSize(Utils::Gui::smallIconSize());
connect(m_ui->trackerUpButton, SIGNAL(clicked()), m_trackerList, SLOT(moveSelectionUp()));
connect(m_ui->trackerDownButton, SIGNAL(clicked()), m_trackerList, SLOT(moveSelectionDown()));
m_ui->horizontalLayout_trackers->insertWidget(0, m_trackerList);
@@ -365,9 +371,7 @@ void PropertiesWidget::readSettings()
}
const int current_tab = pref->getPropCurTab();
const bool visible = pref->getPropVisible();
// the following will call saveSettings but shouldn't change any state
if (!m_ui->filesList->header()->restoreState(pref->getPropFileListState()))
m_ui->filesList->header()->resizeSection(0, 400); // Default
m_ui->filesList->header()->restoreState(pref->getPropFileListState());
m_tabBar->setCurrentIndex(current_tab);
if (!visible)
setVisibility(false);
@@ -574,10 +578,14 @@ void PropertiesWidget::openFolder(const QModelIndex &index, bool containingFolde
// Flush data
m_torrent->flushCache();
#ifdef Q_OS_MAC
MacUtils::openFiles(QSet<QString>{absolutePath});
#else
if (containingFolder)
Utils::Misc::openFolderSelect(absolutePath);
else
Utils::Misc::openPath(absolutePath);
#endif
}
void PropertiesWidget::displayFilesListMenu(const QPoint &)

View File

@@ -1000,6 +1000,9 @@
</widget>
<widget class="QWidget" name="pageContents">
<layout class="QVBoxLayout" name="verticalLayout_3">
<property name="spacing">
<number>3</number>
</property>
<property name="leftMargin">
<number>0</number>
</property>

View File

@@ -61,6 +61,7 @@ SpeedWidget::SpeedWidget(PropertiesWidget *parent)
{
m_layout = new QVBoxLayout(this);
m_layout->setContentsMargins(0, 0, 0, 0);
m_layout->setSpacing(3);
m_hlayout = new QHBoxLayout();
m_hlayout->setContentsMargins(0, 0, 0, 0);

View File

@@ -627,9 +627,8 @@ void TrackerList::displayToggleColumnsMenu(const QPoint &)
Q_ASSERT(visibleColumnsCount() > 0);
if (!isColumnHidden(col) && (visibleColumnsCount() == 1))
return;
qDebug("Toggling column %d visibility", col);
setColumnHidden(col, !isColumnHidden(col));
if (!isColumnHidden(col) && (columnWidth(col) <= 5))
setColumnWidth(col, 100);
resizeColumnToContents(col);
saveSettings();
}

View File

@@ -53,6 +53,7 @@
#include "guiiconprovider.h"
#include "autoexpandabledialog.h"
#include "ui_automatedrssdownloader.h"
#include "utils.h"
const QString EXT_JSON {QStringLiteral(".json")};
const QString EXT_LEGACY {QStringLiteral(".rssrules")};
@@ -155,14 +156,14 @@ AutomatedRssDownloader::~AutomatedRssDownloader()
void AutomatedRssDownloader::loadSettings()
{
const Preferences *const pref = Preferences::instance();
resize(pref->getRssGeometrySize(this->size()));
Utils::Gui::resize(this, pref->getRssGeometrySize());
m_ui->hsplitter->restoreState(pref->getRssHSplitterSizes());
}
void AutomatedRssDownloader::saveSettings()
{
Preferences *const pref = Preferences::instance();
pref->setRssGeometrySize(this->size());
pref->setRssGeometrySize(size());
pref->setRssHSplitterSizes(m_ui->hsplitter->saveState());
}
@@ -755,6 +756,7 @@ void AutomatedRssDownloader::handleRuleChanged(const QString &ruleName)
void AutomatedRssDownloader::handleRuleAboutToBeRemoved(const QString &ruleName)
{
m_currentRuleItem = nullptr;
delete m_itemsByRuleName.take(ruleName);
}

View File

@@ -31,25 +31,26 @@
#include "pluginselectdlg.h"
#include <QClipboard>
#include <QDropEvent>
#include <QFileDialog>
#include <QHeaderView>
#include <QImageReader>
#include <QMenu>
#include <QMessageBox>
#include <QFileDialog>
#include <QDropEvent>
#include <QMimeData>
#include <QClipboard>
#include <QTableView>
#include <QImageReader>
#include "autoexpandabledialog.h"
#include "base/net/downloadhandler.h"
#include "base/net/downloadmanager.h"
#include "base/utils/fs.h"
#include "base/utils/misc.h"
#include "base/net/downloadmanager.h"
#include "base/net/downloadhandler.h"
#include "searchwidget.h"
#include "pluginsourcedlg.h"
#include "guiiconprovider.h"
#include "autoexpandabledialog.h"
#include "pluginsourcedlg.h"
#include "searchwidget.h"
#include "ui_pluginselectdlg.h"
#include "utils.h"
enum PluginColumns
{
@@ -78,9 +79,6 @@ PluginSelectDlg::PluginSelectDlg(SearchEngine *pluginManager, QWidget *parent)
unused.setVerticalHeader(new QHeaderView(Qt::Horizontal));
m_ui->pluginsTree->setRootIsDecorated(false);
m_ui->pluginsTree->header()->resizeSection(0, 160);
m_ui->pluginsTree->header()->resizeSection(1, 80);
m_ui->pluginsTree->header()->resizeSection(2, 200);
m_ui->pluginsTree->hideColumn(PLUGIN_ID);
m_ui->pluginsTree->header()->setSortIndicator(0, Qt::AscendingOrder);
@@ -99,6 +97,7 @@ PluginSelectDlg::PluginSelectDlg(SearchEngine *pluginManager, QWidget *parent)
connect(m_pluginManager, &SearchEngine::checkForUpdatesFinished, this, &PluginSelectDlg::checkForUpdatesFinished);
connect(m_pluginManager, &SearchEngine::checkForUpdatesFailed, this, &PluginSelectDlg::checkForUpdatesFailed);
Utils::Gui::resize(this);
show();
}

View File

@@ -31,6 +31,7 @@
#include "pluginsourcedlg.h"
#include "ui_pluginsourcedlg.h"
#include "utils.h"
PluginSourceDlg::PluginSourceDlg(QWidget *parent)
: QDialog(parent)
@@ -38,6 +39,8 @@ PluginSourceDlg::PluginSourceDlg(QWidget *parent)
{
m_ui->setupUi(this);
setAttribute(Qt::WA_DeleteOnClose);
Utils::Gui::resize(this);
show();
}

View File

@@ -28,14 +28,20 @@
* Contact : chris@qbittorrent.org
*/
#include <QStyleOptionViewItem>
#include <QCoreApplication>
#include <QModelIndex>
#include <QPainter>
#include <QProgressBar>
#include <QStyleOptionViewItem>
#include "base/utils/misc.h"
#include "searchsortmodel.h"
#include "searchlistdelegate.h"
#include "searchsortmodel.h"
namespace
{
const char i18nContext[] = "SearchListDelegate";
}
SearchListDelegate::SearchListDelegate(QObject *parent)
: QItemDelegate(parent)
@@ -57,7 +63,8 @@ void SearchListDelegate::paint(QPainter *painter, const QStyleOptionViewItem &op
case SearchSortModel::SEEDS:
case SearchSortModel::LEECHES:
opt.displayAlignment = Qt::AlignRight | Qt::AlignVCenter;
QItemDelegate::drawDisplay(painter, opt, option.rect, (index.data().toLongLong() >= 0) ? index.data().toString() : tr("Unknown"));
QItemDelegate::drawDisplay(painter, opt, option.rect
, (index.data().toLongLong() >= 0) ? index.data().toString() : QCoreApplication::translate(i18nContext, "Unknown"));
break;
default:
QItemDelegate::paint(painter, option, index);

View File

@@ -113,17 +113,11 @@ bool SearchSortModel::lessThan(const QModelIndex &left, const QModelIndex &right
const QString strL = left.data().toString();
const QString strR = right.data().toString();
const int result = Utils::String::naturalCompare(strL, strR, Qt::CaseInsensitive);
if (result != 0)
return (result < 0);
return (mapFromSource(left) < mapFromSource(right));
}
return (result < 0);
}
break;
default:
if (left.data() != right.data())
return base::lessThan(left, right);
return (mapFromSource(left) < mapFromSource(right));
return base::lessThan(left, right);
};
}

View File

@@ -334,10 +334,9 @@ void SearchTab::displayToggleColumnsMenu(const QPoint&)
Q_ASSERT(visibleCols > 0);
if ((!m_ui->resultsBrowser->isColumnHidden(col)) && (visibleCols == 1))
return;
qDebug("Toggling column %d visibility", col);
m_ui->resultsBrowser->setColumnHidden(col, !m_ui->resultsBrowser->isColumnHidden(col));
if ((!m_ui->resultsBrowser->isColumnHidden(col)) && (m_ui->resultsBrowser->columnWidth(col) <= 5))
m_ui->resultsBrowser->setColumnWidth(col, 100);
m_ui->resultsBrowser->resizeColumnToContents(col);
saveSettings();
}
}

View File

@@ -144,7 +144,6 @@ void SearchWidget::fillCatCombobox()
{
m_ui->comboCategory->clear();
m_ui->comboCategory->addItem(SearchEngine::categoryFullName("all"), QVariant("all"));
m_ui->comboCategory->insertSeparator(1);
using QStrPair = QPair<QString, QString>;
QList<QStrPair> tmpList;
@@ -156,6 +155,9 @@ void SearchWidget::fillCatCombobox()
qDebug("Supported category: %s", qUtf8Printable(p.second));
m_ui->comboCategory->addItem(p.first, QVariant(p.second));
}
if (m_ui->comboCategory->count() > 1)
m_ui->comboCategory->insertSeparator(1);
}
void SearchWidget::fillPluginComboBox()
@@ -164,7 +166,6 @@ void SearchWidget::fillPluginComboBox()
m_ui->selectPlugin->addItem(tr("Only enabled"), QVariant("enabled"));
m_ui->selectPlugin->addItem(tr("All plugins"), QVariant("all"));
m_ui->selectPlugin->addItem(tr("Select..."), QVariant("multi"));
m_ui->selectPlugin->insertSeparator(3);
using QStrPair = QPair<QString, QString>;
QList<QStrPair> tmpList;
@@ -174,6 +175,9 @@ void SearchWidget::fillPluginComboBox()
foreach (const QStrPair &p, tmpList)
m_ui->selectPlugin->addItem(p.first, QVariant(p.second));
if (m_ui->selectPlugin->count() > 3)
m_ui->selectPlugin->insertSeparator(3);
}
QString SearchWidget::selectedCategory() const

View File

@@ -37,6 +37,7 @@
#include "base/preferences.h"
#include "base/utils/misc.h"
#include "ui_shutdownconfirmdlg.h"
#include "utils.h"
ShutdownConfirmDlg::ShutdownConfirmDlg(QWidget *parent, const ShutdownDialogAction &action)
: QDialog(parent)
@@ -66,6 +67,8 @@ ShutdownConfirmDlg::ShutdownConfirmDlg(QWidget *parent, const ShutdownDialogActi
m_timer.setInterval(1000); // 1sec
connect(&m_timer, SIGNAL(timeout()), this, SLOT(updateSeconds()));
Utils::Gui::resize(this);
}
ShutdownConfirmDlg::~ShutdownConfirmDlg()

View File

@@ -30,6 +30,7 @@
#include "base/unicodestrings.h"
#include "ui_bandwidth_limit.h"
#include "utils.h"
SpeedLimitDialog::SpeedLimitDialog(QWidget *parent)
: QDialog(parent)
@@ -41,6 +42,8 @@ SpeedLimitDialog::SpeedLimitDialog(QWidget *parent)
// Connect to slots
connect(m_ui->bandwidthSlider, SIGNAL(valueChanged(int)), this, SLOT(updateSpinValue(int)));
connect(m_ui->spinBandwidth, SIGNAL(valueChanged(int)), this, SLOT(updateSliderValue(int)));
Utils::Gui::resize(this);
}
SpeedLimitDialog::~SpeedLimitDialog()

View File

@@ -35,6 +35,7 @@
#include "base/utils/misc.h"
#include "base/utils/string.h"
#include "ui_statsdialog.h"
#include "utils.h"
StatsDialog::StatsDialog(QWidget *parent)
: QDialog(parent)
@@ -48,6 +49,7 @@ StatsDialog::StatsDialog(QWidget *parent)
connect(BitTorrent::Session::instance(), &BitTorrent::Session::statsUpdated
, this, &StatsDialog::update);
Utils::Gui::resize(this);
show();
}

View File

@@ -41,6 +41,7 @@
#include "base/utils/misc.h"
#include "guiiconprovider.h"
#include "speedlimitdlg.h"
#include "utils.h"
StatusBar::StatusBar(QWidget *parent)
: QStatusBar(parent)
@@ -100,15 +101,15 @@ StatusBar::StatusBar(QWidget *parent)
// Because on some platforms the default icon size is bigger
// and it will result in taller/fatter statusbar, even if the
// icons are actually 16x16
m_connecStatusLblIcon->setIconSize(QSize(16, 16));
m_dlSpeedLbl->setIconSize(QSize(16, 16));
m_upSpeedLbl->setIconSize(QSize(16, 16));
m_altSpeedsBtn->setIconSize(QSize(28, 16));
m_connecStatusLblIcon->setIconSize(Utils::Gui::smallIconSize());
m_dlSpeedLbl->setIconSize(Utils::Gui::smallIconSize());
m_upSpeedLbl->setIconSize(Utils::Gui::smallIconSize());
m_altSpeedsBtn->setIconSize(QSize(Utils::Gui::mediumIconSize().width(), Utils::Gui::smallIconSize().height()));
// Set to the known maximum width(plus some padding)
// so the speed widgets will take the rest of the space
m_connecStatusLblIcon->setMaximumWidth(16 + 6);
m_altSpeedsBtn->setMaximumWidth(28 + 6);
m_connecStatusLblIcon->setMaximumWidth(Utils::Gui::largeIconSize().width());
m_altSpeedsBtn->setMaximumWidth(Utils::Gui::largeIconSize().width());
QFrame *statusSep1 = new QFrame(this);
statusSep1->setFrameStyle(QFrame::VLine);

View File

@@ -54,8 +54,5 @@ bool TagFilterProxyModel::lessThan(const QModelIndex &left, const QModelIndex &r
int result = Utils::String::naturalCompare(left.data().toString(), right.data().toString()
, Qt::CaseInsensitive);
if (result != 0)
return (result < 0);
return (mapFromSource(left) < mapFromSource(right));
return (result < 0);
}

View File

@@ -36,11 +36,11 @@
#include <QMessageBox>
#include "base/bittorrent/session.h"
#include "base/utils/misc.h"
#include "autoexpandabledialog.h"
#include "guiiconprovider.h"
#include "tagfiltermodel.h"
#include "tagfilterproxymodel.h"
#include "utils.h"
namespace
{
@@ -70,7 +70,7 @@ TagFilterWidget::TagFilterWidget(QWidget *parent)
setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
setUniformRowHeights(true);
setHeaderHidden(true);
setIconSize(Utils::Misc::smallIconSize());
setIconSize(Utils::Gui::smallIconSize());
#if defined(Q_OS_MAC)
setAttribute(Qt::WA_MacShowFocusRect, false);
#endif

View File

@@ -150,7 +150,7 @@ namespace
{
QPixmap pixmapForExtension(const QString &ext) const override
{
return ::pixmapForExtension(ext, QSize(32, 32));
return MacUtils::pixmapForExtension(ext, QSize(32, 32));
}
};
#else

View File

@@ -41,8 +41,8 @@
#include "base/bittorrent/torrentinfo.h"
#include "base/global.h"
#include "base/utils/fs.h"
#include "ui_torrentcreatordlg.h"
#include "utils.h"
#define SETTINGS_KEY(name) "TorrentCreator/" name
@@ -60,6 +60,7 @@ TorrentCreatorDlg::TorrentCreatorDlg(QWidget *parent, const QString &defaultPath
, m_storeWebSeedList(SETTINGS_KEY("WebSeedList"))
, m_storeComments(SETTINGS_KEY("Comments"))
, m_storeLastSavePath(SETTINGS_KEY("LastSavePath"), QDir::homePath())
, m_storeSource(SETTINGS_KEY("Source"))
{
m_ui->setupUi(this);
setAttribute(Qt::WA_DeleteOnClose);
@@ -112,7 +113,7 @@ void TorrentCreatorDlg::onAddFileButtonClicked()
int TorrentCreatorDlg::getPieceSize() const
{
const int pieceSizes[] = {0, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192, 16384}; // base unit in KiB
const int pieceSizes[] = {0, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192, 16384, 32768}; // base unit in KiB
return pieceSizes[m_ui->comboPieceSize->currentIndex()] * 1024;
}
@@ -161,12 +162,15 @@ void TorrentCreatorDlg::onCreateButtonClicked()
setInteractionEnabled(false);
setCursor(QCursor(Qt::WaitCursor));
QStringList trackers = m_ui->trackersList->toPlainText().split("\n");
QStringList urlSeeds = m_ui->URLSeedsList->toPlainText().split("\n");
QString comment = m_ui->txtComment->toPlainText();
const QStringList trackers = m_ui->trackersList->toPlainText().trimmed()
.replace(QRegularExpression("\n\n[\n]+"), "\n\n").split('\n');
const QStringList urlSeeds = m_ui->URLSeedsList->toPlainText().split('\n', QString::SkipEmptyParts);
const QString comment = m_ui->txtComment->toPlainText();
const QString source = m_ui->lineEditSource->text();
// run the creator thread
m_creatorThread->create(input, destination, trackers, urlSeeds, comment, m_ui->checkPrivate->isChecked(), getPieceSize());
m_creatorThread->create({ m_ui->checkPrivate->isChecked(), getPieceSize()
, input, destination, comment, source, trackers, urlSeeds });
}
void TorrentCreatorDlg::handleCreationFailure(const QString &msg)
@@ -240,6 +244,7 @@ void TorrentCreatorDlg::saveSettings()
m_storeTrackerList = m_ui->trackersList->toPlainText();
m_storeWebSeedList = m_ui->URLSeedsList->toPlainText();
m_storeComments = m_ui->txtComment->toPlainText();
m_storeSource = m_ui->lineEditSource->text();
m_storeDialogSize = size();
}
@@ -257,7 +262,7 @@ void TorrentCreatorDlg::loadSettings()
m_ui->trackersList->setPlainText(m_storeTrackerList);
m_ui->URLSeedsList->setPlainText(m_storeWebSeedList);
m_ui->txtComment->setPlainText(m_storeComments);
m_ui->lineEditSource->setText(m_storeSource);
if (m_storeDialogSize.value().isValid())
resize(m_storeDialogSize);
Utils::Gui::resize(this, m_storeDialogSize);
}

View File

@@ -85,6 +85,7 @@ private:
CachedSettingValue<QString> m_storeWebSeedList;
CachedSettingValue<QString> m_storeComments;
CachedSettingValue<QString> m_storeLastSavePath;
CachedSettingValue<QString> m_storeSource;
};
#endif

View File

@@ -164,6 +164,11 @@
<string>16 MiB</string>
</property>
</item>
<item>
<property name="text">
<string>32 MiB</string>
</property>
</item>
</widget>
</item>
<item>
@@ -273,6 +278,16 @@
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QLabel" name="labelSource">
<property name="text">
<string>Source:</string>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QLineEdit" name="lineEditSource"/>
</item>
</layout>
</widget>
</item>

View File

@@ -184,7 +184,7 @@ QVariant TorrentModel::data(const QModelIndex &index, int role) const
case TR_PROGRESS:
return torrent->progress();
case TR_STATUS:
return static_cast<int>(torrent->state());
return QVariant::fromValue(torrent->state());
case TR_SEEDS:
return (role == Qt::DisplayRole) ? torrent->seedsCount() : torrent->totalSeedsCount();
case TR_PEERS:

View File

@@ -30,9 +30,12 @@
#include "trackerlogin.h"
#include <QPushButton>
#include <libtorrent/version.hpp>
#include <QPushButton>
#include "base/bittorrent/torrenthandle.h"
#include "utils.h"
trackerLogin::trackerLogin(QWidget *parent, BitTorrent::TorrentHandle *const torrent)
: QDialog(parent)
@@ -53,6 +56,7 @@ trackerLogin::trackerLogin(QWidget *parent, BitTorrent::TorrentHandle *const tor
connect(this, SIGNAL(trackerLoginCancelled(QPair<BitTorrent::TorrentHandle*, QString>)), // TODO: use Qt5 connect syntax
parent, SLOT(addUnauthenticatedTracker(QPair<BitTorrent::TorrentHandle*, QString>)));
Utils::Gui::resize(this);
show();
}

View File

@@ -38,6 +38,7 @@
#include <QMessageBox>
#include <QScrollArea>
#include <QVBoxLayout>
#include <QUrl>
#include "base/bittorrent/session.h"
#include "base/bittorrent/torrenthandle.h"
@@ -48,7 +49,6 @@
#include "base/preferences.h"
#include "base/torrentfilter.h"
#include "base/utils/fs.h"
#include "base/utils/misc.h"
#include "base/utils/string.h"
#include "autoexpandabledialog.h"
#include "categoryfilterwidget.h"
@@ -57,6 +57,7 @@
#include "torrentmodel.h"
#include "transferlistdelegate.h"
#include "transferlistwidget.h"
#include "utils.h"
const QLatin1String GOOGLE_FAVICON_URL("https://www.google.com/s2/favicons?domain=");
@@ -71,7 +72,7 @@ FiltersBase::FiltersBase(QWidget *parent, TransferListWidget *transferList)
setUniformItemSizes(true);
setSpacing(0);
setIconSize(Utils::Misc::smallIconSize());
setIconSize(Utils::Gui::smallIconSize());
#if defined(Q_OS_MAC)
setAttribute(Qt::WA_MacShowFocusRect, false);

View File

@@ -95,10 +95,21 @@ bool TransferListSortModel::lessThan(const QModelIndex &left, const QModelIndex
return lowerPositionThan(left, right);
const int result = Utils::String::naturalCompare(vL.toString(), vR.toString(), Qt::CaseInsensitive);
if (result != 0)
return (result < 0);
return (result < 0);
}
return (mapFromSource(left) < mapFromSource(right));
case TorrentModel::TR_STATUS: {
// QSortFilterProxyModel::lessThan() uses the < operator only for specific QVariant types
// so our custom type is outside that list.
// In this case QSortFilterProxyModel::lessThan() converts other types to QString and
// sorts them.
// Thus we can't use the code in the default label.
const BitTorrent::TorrentState leftValue = left.data().value<BitTorrent::TorrentState>();
const BitTorrent::TorrentState rightValue = right.data().value<BitTorrent::TorrentState>();
if (leftValue != rightValue)
return leftValue < rightValue;
return lowerPositionThan(left, right);
}
case TorrentModel::TR_ADD_DATE:

View File

@@ -62,6 +62,10 @@
#include "transferlistsortmodel.h"
#include "updownratiodlg.h"
#ifdef Q_OS_MAC
#include "macutilities.h"
#endif
namespace
{
using ToggleFn = std::function<void (Qt::CheckState)>;
@@ -358,10 +362,14 @@ void TransferListWidget::torrentDoubleClicked()
torrent->pause();
break;
case OPEN_DEST:
#ifdef Q_OS_MAC
MacUtils::openFiles(QSet<QString>{torrent->contentPath(true)});
#else
if (torrent->filesCount() == 1)
Utils::Misc::openFolderSelect(torrent->contentPath(true));
else
Utils::Misc::openPath(torrent->contentPath(true));
#endif
break;
}
}
@@ -548,6 +556,15 @@ void TransferListWidget::hidePriorityColumn(bool hide)
void TransferListWidget::openSelectedTorrentsFolder() const
{
QSet<QString> pathsList;
#ifdef Q_OS_MAC
// On macOS you expect both the files and folders to be opened in their parent
// folders prehilighted for opening, so we use a custom method.
foreach (BitTorrent::TorrentHandle *const torrent, getSelectedTorrents()) {
QString path = torrent->contentPath(true);
pathsList.insert(path);
}
MacUtils::openFiles(pathsList);
#else
foreach (BitTorrent::TorrentHandle *const torrent, getSelectedTorrents()) {
QString path = torrent->contentPath(true);
if (!pathsList.contains(path)) {
@@ -558,6 +575,7 @@ void TransferListWidget::openSelectedTorrentsFolder() const
}
pathsList.insert(path);
}
#endif
}
void TransferListWidget::previewSelectedTorrents()
@@ -665,6 +683,12 @@ void TransferListWidget::recheckSelectedTorrents()
torrent->forceRecheck();
}
void TransferListWidget::reannounceSelectedTorrents()
{
foreach (BitTorrent::TorrentHandle *const torrent, getSelectedTorrents())
torrent->forceReannounce();
}
// hide/show columns menu
void TransferListWidget::displayDLHoSMenu(const QPoint&)
{
@@ -698,10 +722,9 @@ void TransferListWidget::displayDLHoSMenu(const QPoint&)
Q_ASSERT(visibleCols > 0);
if (!isColumnHidden(col) && visibleCols == 1)
return;
qDebug("Toggling column %d visibility", col);
setColumnHidden(col, !isColumnHidden(col));
if (!isColumnHidden(col) && columnWidth(col) <= 5)
setColumnWidth(col, 100);
resizeColumnToContents(col);
saveSettings();
}
}
@@ -864,6 +887,8 @@ void TransferListWidget::displayListMenu(const QPoint&)
connect(&actionSetTorrentPath, SIGNAL(triggered()), this, SLOT(setSelectedTorrentsLocation()));
QAction actionForce_recheck(GuiIconProvider::instance()->getIcon("document-edit-verify"), tr("Force recheck"), 0);
connect(&actionForce_recheck, SIGNAL(triggered()), this, SLOT(recheckSelectedTorrents()));
QAction actionForce_reannounce(GuiIconProvider::instance()->getIcon("document-edit-verify"), tr("Force reannounce"), 0);
connect(&actionForce_reannounce, SIGNAL(triggered()), this, SLOT(reannounceSelectedTorrents()));
QAction actionCopy_magnet_link(GuiIconProvider::instance()->getIcon("kt-magnet"), tr("Copy magnet link"), 0);
connect(&actionCopy_magnet_link, SIGNAL(triggered()), this, SLOT(copySelectedMagnetURIs()));
QAction actionCopy_name(GuiIconProvider::instance()->getIcon("edit-copy"), tr("Copy name"), 0);
@@ -1067,6 +1092,7 @@ void TransferListWidget::displayListMenu(const QPoint&)
listMenu.addSeparator();
if (one_has_metadata) {
listMenu.addAction(&actionForce_recheck);
listMenu.addAction(&actionForce_reannounce);
listMenu.addSeparator();
}
listMenu.addAction(&actionOpen_destination_folder);
@@ -1175,10 +1201,7 @@ void TransferListWidget::saveSettings()
bool TransferListWidget::loadSettings()
{
bool ok = header()->restoreState(Preferences::instance()->getTransHeaderState());
if (!ok)
header()->resizeSection(0, 200); // Default
return ok;
return header()->restoreState(Preferences::instance()->getTransHeaderState());
}
void TransferListWidget::wheelEvent(QWheelEvent *event)

View File

@@ -85,6 +85,7 @@ public slots:
void copySelectedHashes() const;
void openSelectedTorrentsFolder() const;
void recheckSelectedTorrents();
void reannounceSelectedTorrents();
void setDlLimitSelectedTorrents();
void setUpLimitSelectedTorrents();
void setMaxRatioSelectedTorrents();

View File

@@ -33,6 +33,7 @@
#include "base/bittorrent/session.h"
#include "ui_updownratiodlg.h"
#include "utils.h"
UpDownRatioDlg::UpDownRatioDlg(bool useDefault, qreal initialRatioValue,
qreal maxRatioValue, int initialTimeValue,
@@ -73,6 +74,8 @@ UpDownRatioDlg::UpDownRatioDlg(bool useDefault, qreal initialRatioValue,
connect(m_ui->checkMaxTime, SIGNAL(toggled(bool)), this, SLOT(enableTimeSpin()));
handleRatioTypeChanged();
Utils::Gui::resize(this);
}
void UpDownRatioDlg::accept()

87
src/gui/utils.cpp Normal file
View File

@@ -0,0 +1,87 @@
/*
* Bittorrent Client using Qt and libtorrent.
* Copyright (C) 2017 Mike Tzou
*
* 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 "utils.h"
#include <QApplication>
#include <QDesktopWidget>
#include <QScreen>
#include <QStyle>
#include <QWidget>
#include <QWindow>
void Utils::Gui::resize(QWidget *widget, const QSize &newSize)
{
if (newSize.isValid())
widget->resize(newSize);
else // depends on screen DPI
widget->resize(widget->size() * screenScalingFactor(widget));
}
qreal Utils::Gui::screenScalingFactor(const QWidget *widget)
{
#ifdef Q_OS_WIN
const int screen = qApp->desktop()->screenNumber(widget);
return (QApplication::screens()[screen]->logicalDotsPerInch() / 96);
#else
#if (QT_VERSION >= QT_VERSION_CHECK(5, 6, 0))
return widget->devicePixelRatioF();
#else
return widget->devicePixelRatio();
#endif
#endif // Q_OS_WIN
}
QPixmap Utils::Gui::scaledPixmap(const QString &path, const QWidget *widget, const int height)
{
const QPixmap pixmap(path);
const int scaledHeight = ((height > 0) ? height : pixmap.height()) * Utils::Gui::screenScalingFactor(widget);
return pixmap.scaledToHeight(scaledHeight, Qt::SmoothTransformation);
}
QSize Utils::Gui::smallIconSize(const QWidget *widget)
{
// Get DPI scaled icon size (device-dependent), see QT source
// under a 1080p screen is usually 16x16
const int s = QApplication::style()->pixelMetric(QStyle::PM_SmallIconSize, nullptr, widget);
return QSize(s, s);
}
QSize Utils::Gui::mediumIconSize(const QWidget *widget)
{
// under a 1080p screen is usually 24x24
return ((smallIconSize(widget) + largeIconSize(widget)) / 2);
}
QSize Utils::Gui::largeIconSize(const QWidget *widget)
{
// Get DPI scaled icon size (device-dependent), see QT source
// under a 1080p screen is usually 32x32
const int s = QApplication::style()->pixelMetric(QStyle::PM_LargeIconSize, nullptr, widget);
return QSize(s, s);
}

58
src/gui/utils.h Normal file
View File

@@ -0,0 +1,58 @@
/*
* Bittorrent Client using Qt and libtorrent.
* Copyright (C) 2017 Mike Tzou
*
* 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.
*/
#ifndef UTILS_GUI_H
#define UTILS_GUI_H
#include <QtGlobal>
#include <QPixmap>
#include <QSize>
class QWidget;
namespace Utils
{
namespace Gui
{
void resize(QWidget *widget, const QSize &newSize = {});
qreal screenScalingFactor(const QWidget *widget);
template <typename T>
T scaledSize(const QWidget *widget, const T &size)
{
return (size * screenScalingFactor(widget));
}
QPixmap scaledPixmap(const QString &path, const QWidget *widget, const int height = 0);
QSize smallIconSize(const QWidget *widget = nullptr);
QSize mediumIconSize(const QWidget *widget = nullptr);
QSize largeIconSize(const QWidget *widget = nullptr);
}
}
#endif // UTILS_GUI_H

View File

@@ -1,3 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 21.4 21.4">
<path d="M10.7 7.2c-1 0-1.8.3-2.5 1s-1 1.5-1 2.5.3 1.8 1 2.5 1.5 1 2.5 1 1.8-.3 2.5-1 1-1.5 1-2.5-.3-1.8-1-2.5-1.5-1-2.5-1zm10.7 2v3.1c0 .1 0 .2-.1.3-.1.1-.2.2-.3.2l-2.6.4c-.2.5-.4.9-.5 1.3.3.5.8 1.1 1.5 1.9.1.1.1.2.1.3 0 .1 0 .2-.1.3-.3.3-.7.8-1.4 1.5s-1.1 1-1.3 1c-.1 0-.2 0-.4-.1l-1.9-1.5c-.4.2-.8.4-1.3.5-.1 1.3-.3 2.1-.4 2.6-.1.3-.2.4-.5.4H9.1c-.1 0-.2 0-.3-.1-.1-.1-.2-.2-.2-.3l-.4-2.6c-.5-.1-.9-.3-1.3-.5l-2 1.5c-.1.1-.2.1-.3.1-.1 0-.2-.1-.3-.2C3.1 18.2 2.4 17.5 2 17c-.1-.1-.1-.2-.1-.3 0-.1 0-.2.1-.3.1-.2.4-.5.7-.9.3-.4.6-.8.8-1-.3-.5-.4-.9-.6-1.4l-2.5-.4c-.1 0-.2-.1-.3-.2-.1-.1-.1-.2-.1-.3V9.1c0-.1 0-.2.1-.3.1-.1.2-.2.3-.2L3 8.2c.1-.4.3-.9.5-1.3C3.1 6.4 2.6 5.7 2 5c-.1-.1-.1-.2-.1-.3 0-.1 0-.2.1-.3.2-.4.7-.9 1.4-1.5.7-.7 1.1-1 1.3-1 .1 0 .2 0 .4.1L7 3.5c.4-.2.8-.4 1.3-.5.1-1.3.3-2.1.4-2.6.1-.3.2-.4.5-.4h3.1c.1 0 .2 0 .3.1.1.1.1.2.2.3l.4 2.6c.5.1.9.3 1.3.5l2-1.5c.1-.1.2-.1.3-.1.1 0 .2 0 .3.1 1.2 1.1 2 1.9 2.3 2.4.1.1.1.2.1.3 0 .1 0 .2-.1.3-.1.2-.4.5-.7.9-.3.4-.6.8-.8 1 .2.5.4.9.6 1.4l2.6.4c.1 0 .2.1.3.2z" fill="teal"/>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 21.4 25.4" width="21.4" height="25.4">
<path d="M10.7 9.2c-1 0-1.8.3-2.5 1s-1 1.5-1 2.5.3 1.8 1 2.5 1.5 1 2.5 1 1.8-.3 2.5-1 1-1.5 1-2.5-.3-1.8-1-2.5-1.5-1-2.5-1zm10.7 2v3.1c0 .1 0 .2-.1.3-.1.1-.2.2-.3.2l-2.6.4c-.2.5-.4.9-.5 1.3.3.5.8 1.1 1.5 1.9.1.1.1.2.1.3 0 .1 0 .2-.1.3-.3.3-.7.8-1.4 1.5s-1.1 1-1.3 1c-.1 0-.2 0-.4-.1l-1.9-1.5c-.4.2-.8.4-1.3.5-.1 1.3-.3 2.1-.4 2.6-.1.3-.2.4-.5.4H9.1c-.1 0-.2 0-.3-.1-.1-.1-.2-.2-.2-.3l-.4-2.6c-.5-.1-.9-.3-1.3-.5l-2 1.5c-.1.1-.2.1-.3.1-.1 0-.2-.1-.3-.2C3.1 20.2 2.4 19.5 2 19c-.1-.1-.1-.2-.1-.3 0-.1 0-.2.1-.3.1-.2.4-.5.7-.9.3-.4.6-.8.8-1-.3-.5-.4-.9-.6-1.4l-2.5-.4c-.1 0-.2-.1-.3-.2-.1-.1-.1-.2-.1-.3v-3.1c0-.1 0-.2.1-.3.1-.1.2-.2.3-.2l2.6-.4c.1-.4.3-.9.5-1.3C3.1 8.4 2.6 7.7 2 7c-.1-.1-.1-.2-.1-.3 0-.1 0-.2.1-.3.2-.4.7-.9 1.4-1.5.7-.7 1.1-1 1.3-1 .1 0 .2 0 .4.1L7 5.5c.4-.2.8-.4 1.3-.5.1-1.3.3-2.1.4-2.6.1-.3.2-.4.5-.4h3.1c.1 0 .2 0 .3.1.1.1.1.2.2.3l.4 2.6c.5.1.9.3 1.3.5l2-1.5c.1-.1.2-.1.3-.1.1 0 .2 0 .3.1 1.2 1.1 2 1.9 2.3 2.4.1.1.1.2.1.3 0 .1 0 .2-.1.3-.1.2-.4.5-.7.9-.3.4-.6.8-.8 1 .2.5.4.9.6 1.4l2.6.4c.1 0 .2.1.3.2z" fill="teal"/>
</svg>

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@@ -1,3 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 23.200001 17.6">
<path d="M22.7 4.4L11.9 15.2l-2 2c-.2.2-.7.4-1 .4-.4 0-.7-.2-1-.4l-2-2L.5 9.8C.2 9.5 0 9.1 0 8.7c0-.4.2-.7.4-1l2-2c.2-.2.7-.4 1-.4.4 0 .7.2 1 .4l4.4 4.4L18.6.4c.2-.2.7-.4 1-.4.4 0 .7.2 1 .4l2 2c.4.2.6.6.6 1-.1.4-.2.7-.5 1z" fill="#000081"/>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 23.200001 21.6" width="23.2" height="21.6">
<path d="M22.7 6.4L11.9 17.2l-2 2c-.2.2-.7.4-1 .4-.4 0-.7-.2-1-.4l-2-2-5.4-5.4c-.3-.3-.5-.7-.5-1.1 0-.4.2-.7.4-1l2-2c.2-.2.7-.4 1-.4.4 0 .7.2 1 .4l4.4 4.4 9.8-9.7c.2-.2.7-.4 1-.4.4 0 .7.2 1 .4l2 2c.4.2.6.6.6 1-.1.4-.2.7-.5 1z" fill="#000081"/>
</svg>

Before

Width:  |  Height:  |  Size: 320 B

After

Width:  |  Height:  |  Size: 350 B

View File

@@ -1,3 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20.678461 21.799999">
<path d="M20.2 12.4l-9 9c-.3.3-.5.4-.9.4s-.7-.1-.9-.4l-9-9c-.4-.4-.5-.8-.3-1.5.3-.5.7-.8 1.2-.8h5.2V1.3c0-.4.1-.7.4-.9.3-.3.5-.4.9-.4H13c.4 0 .7.1.9.4.2.2.4.5.4.9v9h5.2c.5-.1.9.1 1.1.7.2.5 0 1-.4 1.4z" fill="#228b22"/>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20.678459 25.799999" width="20.678" height="25.8">
<path d="M20.2 14.4l-9 9c-.3.3-.5.4-.9.4s-.7-.1-.9-.4l-9-9c-.4-.4-.5-.8-.3-1.5.3-.5.7-.8 1.2-.8h5.2V3.3c0-.4.1-.7.4-.9.3-.3.5-.4.9-.4H13c.4 0 .7.1.9.4.2.2.4.5.4.9v9h5.2c.5-.1.9.1 1.1.7.2.5 0 1-.4 1.4z" fill="#228b22"/>
</svg>

Before

Width:  |  Height:  |  Size: 303 B

After

Width:  |  Height:  |  Size: 332 B

View File

@@ -1,3 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 6.0392303 19.6">
<path d="M5.8 18.7c0 .2-.1.4-.3.6-.2.2-.4.3-.6.3H1.4c-.2 0-.4-.1-.6-.3-.2-.2-.3-.4-.3-.6v-3.1c0-.2.1-.4.3-.6.2-.2.4-.3.6-.3h3.5c.2 0 .4.1.6.3.2.2.3.4.3.6zm0-7.1c0 .2-.1.4-.3.6-.2.2-.4.3-.6.3H1.4c-.2 0-.5-.1-.6-.3-.2-.2-.3-.4-.3-.6L0 .9C0 .7.1.5.2.3.4.1.6 0 .8 0h4.4c.2 0 .4.1.6.3.2.2.3.4.2.6z" fill="red"/>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 6.0392298 23.6" width="6.039" height="23.6">
<path d="M5.8 20.7c0 .2-.1.4-.3.6-.2.2-.4.3-.6.3H1.4c-.2 0-.4-.1-.6-.3-.2-.2-.3-.4-.3-.6v-3.1c0-.2.1-.4.3-.6.2-.2.4-.3.6-.3h3.5c.2 0 .4.1.6.3.2.2.3.4.3.6zm0-7.1c0 .2-.1.4-.3.6-.2.2-.4.3-.6.3H1.4c-.2 0-.5-.1-.6-.3-.2-.2-.3-.4-.3-.6L0 2.9c0-.2.1-.4.2-.6.2-.2.4-.3.6-.3h4.4c.2 0 .4.1.6.3.2.2.3.4.2.6z" fill="red"/>
</svg>

Before

Width:  |  Height:  |  Size: 386 B

After

Width:  |  Height:  |  Size: 419 B

View File

@@ -1,3 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 21.781139 21.6">
<path d="M21.5 1.7l-7.6 7.5v11.4c0 .5-.2.7-.6.9-.1.1-.3.1-.4.1-.3 0-.6-.1-.7-.3l-4-4c-.2-.2-.3-.5-.3-.7V9.1L.4 1.7C0 1.3-.1.9.1.6.3.2.6 0 1 0h19.7c.5 0 .7.3.9.6.3.4.2.7-.1 1.1z" fill="#427337"/>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 21.781139 25.6" width="21.781" height="25.6">
<path d="M21.5 3.7l-7.6 7.5v11.4c0 .5-.2.7-.6.9-.1.1-.3.1-.4.1-.3 0-.6-.1-.7-.3l-4-4c-.2-.2-.3-.5-.3-.7v-7.5L.4 3.7C0 3.3-.1 2.9.1 2.6.3 2.2.6 2 1 2h19.7c.5 0 .7.3.9.6.3.4.2.7-.1 1.1z" fill="#427337"/>
</svg>

Before

Width:  |  Height:  |  Size: 274 B

After

Width:  |  Height:  |  Size: 310 B

View File

@@ -1,3 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 21.781139 21.6">
<path d="M21.5 1.7l-7.6 7.5v11.4c0 .5-.2.7-.6.9-.1.1-.3.1-.4.1-.3 0-.6-.1-.7-.3l-4-4c-.2-.2-.3-.5-.3-.7V9.1L.4 1.7C0 1.3-.1.9.1.6.3.2.6 0 1 0h19.7c.5 0 .7.3.9.6.3.4.2.7-.1 1.1z" fill="#d1954e"/>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 21.781139 25.6" width="21.781" height="25.6">
<path d="M21.5 3.7l-7.6 7.5v11.4c0 .5-.2.7-.6.9-.1.1-.3.1-.4.1-.3 0-.6-.1-.7-.3l-4-4c-.2-.2-.3-.5-.3-.7v-7.5L.4 3.7C0 3.3-.1 2.9.1 2.6.3 2.2.6 2 1 2h19.7c.5 0 .7.3.9.6.3.4.2.7-.1 1.1z" fill="#d1954e"/>
</svg>

Before

Width:  |  Height:  |  Size: 274 B

After

Width:  |  Height:  |  Size: 310 B

View File

@@ -1,3 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 21.781139 21.6">
<path d="M21.5 1.7l-7.6 7.5v11.4c0 .5-.2.7-.6.9-.1.1-.3.1-.4.1-.3 0-.6-.1-.7-.3l-4-4c-.2-.2-.3-.5-.3-.7V9.1L.4 1.7C0 1.3-.1.9.1.6.3.2.6 0 1 0h19.7c.5 0 .7.3.9.6.3.4.2.7-.1 1.1z" fill="#733737"/>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 21.781139 25.6" width="21.781" height="25.6">
<path d="M21.5 3.7l-7.6 7.5v11.4c0 .5-.2.7-.6.9-.1.1-.3.1-.4.1-.3 0-.6-.1-.7-.3l-4-4c-.2-.2-.3-.5-.3-.7v-7.5L.4 3.7C0 3.3-.1 2.9.1 2.6.3 2.2.6 2 1 2h19.7c.5 0 .7.3.9.6.3.4.2.7-.1 1.1z" fill="#733737"/>
</svg>

Before

Width:  |  Height:  |  Size: 274 B

After

Width:  |  Height:  |  Size: 310 B

View File

@@ -1,3 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20.9 20.6">
<path d="M8.4 19.8c0 .2 0 .4-.2.6-.2.2-.4.2-.6.2H.8c-.2 0-.4 0-.6-.2-.2-.2-.2-.4-.2-.6V.8C0 .6 0 .4.2.2.4 0 .6 0 .8 0h6.8c.2 0 .4 0 .6.2.2.2.2.4.2.6zm12.5 0c0 .2 0 .4-.2.6-.2.2-.4.2-.6.2h-6.8c-.2 0-.4 0-.6-.2-.2-.2-.2-.4-.2-.6V.8c0-.2 0-.4.2-.6.2-.2.4-.2.6-.2h6.8c.2 0 .4 0 .6.2.2.2.2.4.2.6z" fill="salmon"/>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20.9 24.6" width="20.9" height="24.6">
<path d="M8.4 21.8c0 .2 0 .4-.2.6-.2.2-.4.2-.6.2H.8c-.2 0-.4 0-.6-.2-.2-.2-.2-.4-.2-.6v-19c0-.2 0-.4.2-.6.2-.2.4-.2.6-.2h6.8c.2 0 .4 0 .6.2.2.2.2.4.2.6zm12.5 0c0 .2 0 .4-.2.6-.2.2-.4.2-.6.2h-6.8c-.2 0-.4 0-.6-.2-.2-.2-.2-.4-.2-.6v-19c0-.2 0-.4.2-.6.2-.2.4-.2.6-.2h6.8c.2 0 .4 0 .6.2.2.2.2.4.2.6z" fill="salmon"/>
</svg>

Before

Width:  |  Height:  |  Size: 383 B

After

Width:  |  Height:  |  Size: 414 B

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