Compare commits
41 Commits
release-4.
...
release-4.
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a574c4a70a | ||
|
|
1e367f818d | ||
|
|
00599c8f02 | ||
|
|
332a836746 | ||
|
|
a1992acc16 | ||
|
|
c3f002a544 | ||
|
|
c28cbe0a74 | ||
|
|
435daaceed | ||
|
|
e29ab0087b | ||
|
|
aadd5a3312 | ||
|
|
7e354ffad3 | ||
|
|
ee6a071fb6 | ||
|
|
bc8b838953 | ||
|
|
5251d93b3d | ||
|
|
84f0dbecfe | ||
|
|
bba0c8b2cc | ||
|
|
2f90be8bd2 | ||
|
|
cb6b6296aa | ||
|
|
9d25fdce2a | ||
|
|
12b2732f1a | ||
|
|
8c9ece73ee | ||
|
|
a7db786387 | ||
|
|
e5bf65c9bd | ||
|
|
900e7d3a14 | ||
|
|
f1ff74a926 | ||
|
|
30bc4b837e | ||
|
|
050a4f8b23 | ||
|
|
487103d58f | ||
|
|
eeea69d4c1 | ||
|
|
00360ad418 | ||
|
|
a733253ae5 | ||
|
|
9788ee042b | ||
|
|
e9c9ea3bba | ||
|
|
312dfb989d | ||
|
|
75deafe5b1 | ||
|
|
4ca257a389 | ||
|
|
03375a78f2 | ||
|
|
423c7066d7 | ||
|
|
5cd5cc71a8 | ||
|
|
45d4d22055 | ||
|
|
916a92aa0d |
12
.travis.yml
@@ -134,14 +134,20 @@ 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.1.7+git20180422.3ede0b9c20+patched-configure.el_capitan.bottle.tar.gz
|
||||
wget https://builds.shiki.hu/homebrew/5146d2df7e48f321511273fb9829ebdc3a6dc519f9ef36a344a343ae524c3ae6--libtorrent-rasterbar-1.1.9+git20180812.0bcf6cef23+patched-configure.el_capitan.bottle.tar.gz
|
||||
fi
|
||||
|
||||
# Copy custom libtorrent bottle to homebrew's cache so it can find and install it
|
||||
# Copy custom libtorrent bottle to homebrew's download 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.1.7+git20180422.3ede0b9c20+patched-configure.el_capitan.bottle.tar.gz" "$(brew --cache)"
|
||||
cp "$HOME/hombebrew_cache/5146d2df7e48f321511273fb9829ebdc3a6dc519f9ef36a344a343ae524c3ae6--libtorrent-rasterbar-1.1.9+git20180812.0bcf6cef23+patched-configure.el_capitan.bottle.tar.gz" "$(brew --cache)/downloads"
|
||||
brew install "$HOME/hombebrew_cache/libtorrent-rasterbar.rb"
|
||||
|
||||
# NOTE about the bottle name
|
||||
# The part before the "--" characters is a sha256 hash of the string
|
||||
# of the URL homebrew itself would use to download the bottle.
|
||||
# In this case the URL is the following:
|
||||
# http://127.0.0.1/libtorrent-rasterbar-1.1.9+git20180812.0bcf6cef23+patched-configure.el_capitan.bottle.tar.gz
|
||||
|
||||
if [ "$build_system" = "cmake" ]; then
|
||||
brew outdated cmake || brew upgrade cmake
|
||||
|
||||
26
Changelog
@@ -1,3 +1,29 @@
|
||||
* Tue Sep 18 2018 - sledgehammer999 <sledgehammer999@qbittorrent.org> - v4.1.3
|
||||
- FEATURE: Preselect name without extension when renaming files (thalieht)
|
||||
- FEATURE: Allow setting seq & first/last from context menu without metadata (thalieht)
|
||||
- BUGFIX: Show "N/A" if there is no scrape (thalieht)
|
||||
- BUGFIX: Save option about tracker favicons under correct key (sledgehammer999)
|
||||
- BUGFIX: When file data are unreachable pause torrent and show "Missing Files" status (temporary fix) (sledgehammer999)
|
||||
- BUGFIX: Don't disable DHT when using force proxy (Thomas Piccirello)
|
||||
- BUGFIX: Correctly save torrent queue position/state/priority changes in fastresume (glassez, thalieht, sledgehammer999)
|
||||
- BUGFIX: Fix icon height/width ratio (Chocobo1)
|
||||
- BUGFIX: Fix values sorted wrong in "Last Activity" column (Chocobo1)
|
||||
- BUGFIX: Replace png icons with svg (Chocobo1)
|
||||
- WEBUI: Allow WebUI sidebar filters to be hidden (Thomas Piccirello)
|
||||
- WEBUI: Increase WebUI Options initial height (Thomas Piccirello)
|
||||
- WEBUI: Adjust WebUI Options form alignment (Thomas Piccirello)
|
||||
- WEBUI: Fix WebUI unreachable issue (Chocobo1)
|
||||
- WEBUI: Require torrent category creation to be explicit (Thomas Piccirello)
|
||||
- WEBUI: Include category save path in web api sync data (Thomas Piccirello)
|
||||
- WEBUI: Add save path and editing to WebUI new category dialog (Thomas Piccirello)
|
||||
- WEBUI: Bump Web API version
|
||||
- SEARCH: Refactor in searchjob to always color visited entries (thalieht)
|
||||
- SEARCH: Set "enter" as shortcut to download the selected torrents in search job (thalieht)
|
||||
- SEARCH: Add regex option in the search filter's context menu (thalieht)
|
||||
- LINUX: Fix GUI scaling issue on Linux (Chocobo1)
|
||||
- LINUX: Fix regression that broke installing desktop file (Eli Schwartz)
|
||||
- OPENBSD: Better filesystem support for filewatcher (Elias M. Mariani)
|
||||
|
||||
* Sun Aug 12 2018 - sledgehammer999 <sledgehammer999@qbittorrent.org> - v4.1.2
|
||||
- FEATURE: New options for "inhibit sleep" (Lukas Greib)
|
||||
- FEATURE: Add option for regexps in the transferlist search filter's context menu (thalieht)
|
||||
|
||||
49
INSTALL
@@ -1,54 +1,49 @@
|
||||
qBittorrent - A BitTorrent client in C++ / Qt4
|
||||
qBittorrent - A BitTorrent client in C++ / Qt
|
||||
------------------------------------------
|
||||
|
||||
1) Compile and install qBittorrent with Qt4 Graphical Interface
|
||||
1) Compile and install qBittorrent with Qt graphical interface
|
||||
|
||||
$ ./configure
|
||||
$ make && make install
|
||||
$ qbittorrent
|
||||
|
||||
will install and execute qBittorrent hopefully without any problems.
|
||||
will install and execute qBittorrent.
|
||||
|
||||
Dependencies:
|
||||
- Qt >= 4.6.0 (libqtgui, libqtcore, libqtnetwork, libqtxml, libqtdbus/optional)
|
||||
- Qt >= 5.5.1
|
||||
|
||||
- pkg-config executable
|
||||
- pkg-config
|
||||
|
||||
- libtorrent-rasterbar by Arvid Norberg (>= 1.0.6)
|
||||
-> http://www.libtorrent.net
|
||||
Be careful: another library (the one used by rTorrent) uses a similar name.
|
||||
- libtorrent-rasterbar >= 1.0.6 (by Arvid Norberg)
|
||||
* https://www.libtorrent.org/
|
||||
* Be careful: another library (the one used by rTorrent) uses a similar name
|
||||
|
||||
- libboost >= 1.35.x (libboost-system)
|
||||
- Boost >= 1.35
|
||||
|
||||
- python >= 2.3 (needed by search engine)
|
||||
* Run time only dependency
|
||||
- Python >= 2.7.9 / 3.3.0 (optional, runtime only)
|
||||
* Required by the internal search engine
|
||||
|
||||
- geoip-database (optional)
|
||||
* If qBittorrent cannot find this database, it will try to resolve countries using the Internet but it will be a lot slower.
|
||||
* Run time only dependency
|
||||
|
||||
2) Compile and install qBittorrent without Qt4 Graphical interface
|
||||
2) Compile and install qBittorrent without Qt graphical interface
|
||||
|
||||
$ ./configure --disable-gui
|
||||
$ make && make install
|
||||
$ qbittorrent
|
||||
$ qbittorrent-nox
|
||||
|
||||
will install and execute qBittorrent hopefully without any problems.
|
||||
will install and execute qBittorrent.
|
||||
|
||||
Dependencies:
|
||||
- Qt >= 4.4.0 (libqt-devel, libqtcore, libqtnetwork)
|
||||
- Qt >= 5.5.1
|
||||
|
||||
- pkg-config executable
|
||||
- pkg-config
|
||||
|
||||
- libtorrent-rasterbar by Arvid Norberg (>= v1.0.6)
|
||||
-> http://www.libtorrent.net
|
||||
Be careful: another library (the one used by rTorrent) uses a similar name.
|
||||
|
||||
- libboost: libboost-filesystem, libboost-date-time, libboost-thread, libboost-serialization
|
||||
- libtorrent-rasterbar >= 1.0.6 (by Arvid Norberg)
|
||||
* https://www.libtorrent.org/
|
||||
* Be careful: another library (the one used by rTorrent) uses a similar name
|
||||
|
||||
- Boost >= 1.35
|
||||
|
||||
DOCUMENTATION:
|
||||
Please note that there is a documentation with a "compiling howto" at http://wiki.qbittorrent.org.
|
||||
Please note that there is a "Compilation" section at http://wiki.qbittorrent.org.
|
||||
|
||||
------------------------------------------
|
||||
Christophe Dumez <chris@qbittorrent.org>
|
||||
sledgehammer999 <sledgehammer999@qbittorrent.org>
|
||||
|
||||
24
configure
vendored
@@ -1,6 +1,6 @@
|
||||
#! /bin/sh
|
||||
# Guess values for system-dependent variables and create Makefiles.
|
||||
# Generated by GNU Autoconf 2.69 for qbittorrent v4.1.2.
|
||||
# Generated by GNU Autoconf 2.69 for qbittorrent v4.1.3.
|
||||
#
|
||||
# Report bugs to <bugs.qbittorrent.org>.
|
||||
#
|
||||
@@ -580,8 +580,8 @@ MAKEFLAGS=
|
||||
# Identity of this package.
|
||||
PACKAGE_NAME='qbittorrent'
|
||||
PACKAGE_TARNAME='qbittorrent'
|
||||
PACKAGE_VERSION='v4.1.2'
|
||||
PACKAGE_STRING='qbittorrent v4.1.2'
|
||||
PACKAGE_VERSION='v4.1.3'
|
||||
PACKAGE_STRING='qbittorrent v4.1.3'
|
||||
PACKAGE_BUGREPORT='bugs.qbittorrent.org'
|
||||
PACKAGE_URL='https://www.qbittorrent.org/'
|
||||
|
||||
@@ -1297,7 +1297,7 @@ if test "$ac_init_help" = "long"; then
|
||||
# Omit some internal or obsolete options to make the list less imposing.
|
||||
# This message is too long to be a string in the A/UX 3.1 sh.
|
||||
cat <<_ACEOF
|
||||
\`configure' configures qbittorrent v4.1.2 to adapt to many kinds of systems.
|
||||
\`configure' configures qbittorrent v4.1.3 to adapt to many kinds of systems.
|
||||
|
||||
Usage: $0 [OPTION]... [VAR=VALUE]...
|
||||
|
||||
@@ -1368,7 +1368,7 @@ fi
|
||||
|
||||
if test -n "$ac_init_help"; then
|
||||
case $ac_init_help in
|
||||
short | recursive ) echo "Configuration of qbittorrent v4.1.2:";;
|
||||
short | recursive ) echo "Configuration of qbittorrent v4.1.3:";;
|
||||
esac
|
||||
cat <<\_ACEOF
|
||||
|
||||
@@ -1503,7 +1503,7 @@ fi
|
||||
test -n "$ac_init_help" && exit $ac_status
|
||||
if $ac_init_version; then
|
||||
cat <<\_ACEOF
|
||||
qbittorrent configure v4.1.2
|
||||
qbittorrent configure v4.1.3
|
||||
generated by GNU Autoconf 2.69
|
||||
|
||||
Copyright (C) 2012 Free Software Foundation, Inc.
|
||||
@@ -1642,7 +1642,7 @@ cat >config.log <<_ACEOF
|
||||
This file contains any messages produced by compilers while
|
||||
running configure, to aid debugging if configure makes a mistake.
|
||||
|
||||
It was created by qbittorrent $as_me v4.1.2, which was
|
||||
It was created by qbittorrent $as_me v4.1.3, which was
|
||||
generated by GNU Autoconf 2.69. Invocation command line was
|
||||
|
||||
$ $0 $@
|
||||
@@ -3820,7 +3820,7 @@ fi
|
||||
|
||||
# Define the identity of the package.
|
||||
PACKAGE='qbittorrent'
|
||||
VERSION='v4.1.2'
|
||||
VERSION='v4.1.3'
|
||||
|
||||
|
||||
cat >>confdefs.h <<_ACEOF
|
||||
@@ -6174,7 +6174,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
|
||||
# report actual input values of CONFIG_FILES etc. instead of their
|
||||
# values after options handling.
|
||||
ac_log="
|
||||
This file was extended by qbittorrent $as_me v4.1.2, which was
|
||||
This file was extended by qbittorrent $as_me v4.1.3, which was
|
||||
generated by GNU Autoconf 2.69. Invocation command line was
|
||||
|
||||
CONFIG_FILES = $CONFIG_FILES
|
||||
@@ -6232,7 +6232,7 @@ _ACEOF
|
||||
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
|
||||
ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
|
||||
ac_cs_version="\\
|
||||
qbittorrent config.status v4.1.2
|
||||
qbittorrent config.status v4.1.3
|
||||
configured by $0, generated by GNU Autoconf 2.69,
|
||||
with options \\"\$ac_cs_config\\"
|
||||
|
||||
@@ -7489,7 +7489,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
|
||||
# report actual input values of CONFIG_FILES etc. instead of their
|
||||
# values after options handling.
|
||||
ac_log="
|
||||
This file was extended by qbittorrent $as_me v4.1.2, which was
|
||||
This file was extended by qbittorrent $as_me v4.1.3, which was
|
||||
generated by GNU Autoconf 2.69. Invocation command line was
|
||||
|
||||
CONFIG_FILES = $CONFIG_FILES
|
||||
@@ -7547,7 +7547,7 @@ _ACEOF
|
||||
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
|
||||
ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
|
||||
ac_cs_version="\\
|
||||
qbittorrent config.status v4.1.2
|
||||
qbittorrent config.status v4.1.3
|
||||
configured by $0, generated by GNU Autoconf 2.69,
|
||||
with options \\"\$ac_cs_config\\"
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
AC_INIT([qbittorrent], [v4.1.2], [bugs.qbittorrent.org], [], [https://www.qbittorrent.org/])
|
||||
AC_INIT([qbittorrent], [v4.1.3], [bugs.qbittorrent.org], [], [https://www.qbittorrent.org/])
|
||||
AC_CONFIG_AUX_DIR([build-aux])
|
||||
AC_CONFIG_MACRO_DIR([m4])
|
||||
AC_PROG_CC
|
||||
|
||||
2
dist/mac/Info.plist
vendored
@@ -45,7 +45,7 @@
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>APPL</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>4.1.2</string>
|
||||
<string>4.1.3</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>qBit</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
|
||||
2
dist/windows/options.nsi
vendored
@@ -27,7 +27,7 @@ XPStyle on
|
||||
!define CSIDL_LOCALAPPDATA '0x1C' ;Local Application Data path
|
||||
|
||||
; Program specific
|
||||
!define PROG_VERSION "4.1.2"
|
||||
!define PROG_VERSION "4.1.3"
|
||||
|
||||
!define MUI_FINISHPAGE_RUN
|
||||
!define MUI_FINISHPAGE_RUN_FUNCTION PageFinishRun
|
||||
|
||||
@@ -102,10 +102,6 @@ void displayBadArgMessage(const QString &message);
|
||||
|
||||
#if !defined(DISABLE_GUI)
|
||||
void showSplashScreen();
|
||||
|
||||
#if defined(Q_OS_UNIX)
|
||||
void setupDpi();
|
||||
#endif // Q_OS_UNIX
|
||||
#endif // DISABLE_GUI
|
||||
|
||||
// Main
|
||||
@@ -120,10 +116,6 @@ int main(int argc, char *argv[])
|
||||
macMigratePlists();
|
||||
#endif
|
||||
|
||||
#if !defined(DISABLE_GUI) && defined(Q_OS_UNIX)
|
||||
setupDpi();
|
||||
#endif
|
||||
|
||||
try {
|
||||
// Create Application
|
||||
QString appId = QLatin1String("qBittorrent-") + Utils::Misc::getUserIDString();
|
||||
@@ -330,14 +322,6 @@ void showSplashScreen()
|
||||
QTimer::singleShot(1500, splash, &QObject::deleteLater);
|
||||
qApp->processEvents();
|
||||
}
|
||||
|
||||
#if defined(Q_OS_UNIX)
|
||||
void setupDpi()
|
||||
{
|
||||
if (qEnvironmentVariableIsEmpty("QT_AUTO_SCREEN_SCALE_FACTOR"))
|
||||
qputenv("QT_AUTO_SCREEN_SCALE_FACTOR", "1");
|
||||
}
|
||||
#endif // Q_OS_UNIX
|
||||
#endif // DISABLE_GUI
|
||||
|
||||
void displayVersion()
|
||||
|
||||
@@ -1354,11 +1354,7 @@ void Session::configure(libtorrent::settings_pack &settingsPack)
|
||||
settingsPack.set_int(libt::settings_pack::active_tracker_limit, -1);
|
||||
settingsPack.set_int(libt::settings_pack::active_dht_limit, -1);
|
||||
settingsPack.set_int(libt::settings_pack::active_lsd_limit, -1);
|
||||
// 1 active torrent force 2 connections. If you have more active torrents * 2 than connection limit,
|
||||
// connection limit will get extended. Multiply max connections or active torrents by 10 for queue.
|
||||
// Ignore -1 values because we don't want to set a max int message queue
|
||||
settingsPack.set_int(libt::settings_pack::alert_queue_size, std::max(1000,
|
||||
10 * std::max(maxActiveTorrents() * 2, maxConnections())));
|
||||
settingsPack.set_int(libt::settings_pack::alert_queue_size, std::numeric_limits<int>::max() / 2);
|
||||
|
||||
// Outgoing ports
|
||||
settingsPack.set_int(libt::settings_pack::outgoing_port, outgoingPortsMin());
|
||||
@@ -1633,11 +1629,7 @@ void Session::configure(libtorrent::session_settings &sessionSettings)
|
||||
sessionSettings.active_tracker_limit = -1;
|
||||
sessionSettings.active_dht_limit = -1;
|
||||
sessionSettings.active_lsd_limit = -1;
|
||||
// 1 active torrent force 2 connections. If you have more active torrents * 2 than connection limit,
|
||||
// connection limit will get extended. Multiply max connections or active torrents by 10 for queue.
|
||||
// Ignore -1 values because we don't want to set a max int message queue
|
||||
sessionSettings.alert_queue_size = std::max(1000,
|
||||
10 * std::max(maxActiveTorrents() * 2, maxConnections()));
|
||||
sessionSettings.alert_queue_size = std::numeric_limits<int>::max() / 2;
|
||||
|
||||
// Outgoing ports
|
||||
sessionSettings.outgoing_ports = std::make_pair(outgoingPortsMin(), outgoingPortsMax());
|
||||
@@ -1998,6 +1990,8 @@ void Session::increaseTorrentsPriority(const QStringList &hashes)
|
||||
torrentQueuePositionUp(torrent->nativeHandle());
|
||||
torrentQueue.pop();
|
||||
}
|
||||
|
||||
handleTorrentsPrioritiesChanged();
|
||||
}
|
||||
|
||||
void Session::decreaseTorrentsPriority(const QStringList &hashes)
|
||||
@@ -2022,6 +2016,8 @@ void Session::decreaseTorrentsPriority(const QStringList &hashes)
|
||||
|
||||
for (auto i = m_loadedMetadata.cbegin(); i != m_loadedMetadata.cend(); ++i)
|
||||
torrentQueuePositionBottom(m_nativeSession->find_torrent(i.key()));
|
||||
|
||||
handleTorrentsPrioritiesChanged();
|
||||
}
|
||||
|
||||
void Session::topTorrentsPriority(const QStringList &hashes)
|
||||
@@ -2043,6 +2039,8 @@ void Session::topTorrentsPriority(const QStringList &hashes)
|
||||
torrentQueuePositionTop(torrent->nativeHandle());
|
||||
torrentQueue.pop();
|
||||
}
|
||||
|
||||
handleTorrentsPrioritiesChanged();
|
||||
}
|
||||
|
||||
void Session::bottomTorrentsPriority(const QStringList &hashes)
|
||||
@@ -2067,6 +2065,8 @@ void Session::bottomTorrentsPriority(const QStringList &hashes)
|
||||
|
||||
for (auto i = m_loadedMetadata.cbegin(); i != m_loadedMetadata.cend(); ++i)
|
||||
torrentQueuePositionBottom(m_nativeSession->find_torrent(i.key()));
|
||||
|
||||
handleTorrentsPrioritiesChanged();
|
||||
}
|
||||
|
||||
QHash<InfoHash, TorrentHandle *> Session::torrents() const
|
||||
@@ -2360,7 +2360,7 @@ void Session::generateResumeData(bool final)
|
||||
if (!final && !torrent->needSaveResumeData()) continue;
|
||||
if (torrent->hasMissingFiles() || torrent->hasError()) continue;
|
||||
|
||||
saveTorrentResumeData(torrent, final);
|
||||
saveTorrentResumeData(torrent);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3531,10 +3531,22 @@ void Session::handleTorrentShareLimitChanged(TorrentHandle *const torrent)
|
||||
updateSeedingLimitTimer();
|
||||
}
|
||||
|
||||
void Session::saveTorrentResumeData(TorrentHandle *const torrent, bool finalSave)
|
||||
void Session::handleTorrentsPrioritiesChanged()
|
||||
{
|
||||
// Save fastresume for the torrents that changed queue position
|
||||
for (TorrentHandle *const torrent : torrents()) {
|
||||
if (!torrent->isSeed()) {
|
||||
// cached vs actual queue position, qBt starts queue at 1
|
||||
if (torrent->queuePosition() != (torrent->nativeHandle().queue_position() + 1))
|
||||
saveTorrentResumeData(torrent);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Session::saveTorrentResumeData(TorrentHandle *const torrent)
|
||||
{
|
||||
qDebug("Saving fastresume data for %s", qUtf8Printable(torrent->name()));
|
||||
torrent->saveResumeData(finalSave);
|
||||
torrent->saveResumeData();
|
||||
++m_numResumeData;
|
||||
}
|
||||
|
||||
@@ -3653,8 +3665,11 @@ void Session::handleTorrentChecked(TorrentHandle *const torrent)
|
||||
|
||||
void Session::handleTorrentFinished(TorrentHandle *const torrent)
|
||||
{
|
||||
if (!torrent->hasError() && !torrent->hasMissingFiles())
|
||||
if (!torrent->hasError() && !torrent->hasMissingFiles()) {
|
||||
saveTorrentResumeData(torrent);
|
||||
if (isQueueingSystemEnabled())
|
||||
handleTorrentsPrioritiesChanged();
|
||||
}
|
||||
emit torrentFinished(torrent);
|
||||
|
||||
qDebug("Checking if the torrent contains torrent files to download");
|
||||
|
||||
@@ -481,6 +481,7 @@ namespace BitTorrent
|
||||
|
||||
// TorrentHandle interface
|
||||
void handleTorrentShareLimitChanged(TorrentHandle *const torrent);
|
||||
void handleTorrentsPrioritiesChanged();
|
||||
void handleTorrentNameChanged(TorrentHandle *const torrent);
|
||||
void handleTorrentSavePathChanged(TorrentHandle *const torrent);
|
||||
void handleTorrentCategoryChanged(TorrentHandle *const torrent, const QString &oldCategory);
|
||||
@@ -606,7 +607,7 @@ namespace BitTorrent
|
||||
|
||||
void updateSeedingLimitTimer();
|
||||
void exportTorrentFile(TorrentHandle *const torrent, TorrentExportFolder folder = TorrentExportFolder::Regular);
|
||||
void saveTorrentResumeData(TorrentHandle *const torrent, bool finalSave = false);
|
||||
void saveTorrentResumeData(TorrentHandle *const torrent);
|
||||
|
||||
void handleAlert(libtorrent::alert *a);
|
||||
void dispatchTorrentAlert(libtorrent::alert *a);
|
||||
|
||||
@@ -504,11 +504,8 @@ bool TorrentHandle::needSaveResumeData() const
|
||||
return m_nativeHandle.need_save_resume_data();
|
||||
}
|
||||
|
||||
void TorrentHandle::saveResumeData(bool updateStatus)
|
||||
void TorrentHandle::saveResumeData()
|
||||
{
|
||||
if (updateStatus) // to update queue_position, see discussion in PR #6154
|
||||
this->updateStatus();
|
||||
|
||||
m_nativeHandle.save_resume_data();
|
||||
}
|
||||
|
||||
@@ -1213,12 +1210,8 @@ void TorrentHandle::setName(const QString &name)
|
||||
bool TorrentHandle::setCategory(const QString &category)
|
||||
{
|
||||
if (m_category != category) {
|
||||
if (!category.isEmpty()) {
|
||||
if (!Session::isValidCategoryName(category)) return false;
|
||||
if (!m_session->categories().contains(category))
|
||||
if (!m_session->addCategory(category))
|
||||
return false;
|
||||
}
|
||||
if (!category.isEmpty() && !m_session->categories().contains(category))
|
||||
return false;
|
||||
|
||||
QString oldCategory = m_category;
|
||||
m_category = category;
|
||||
@@ -1350,6 +1343,12 @@ void TorrentHandle::pause()
|
||||
|
||||
m_nativeHandle.auto_managed(false);
|
||||
m_nativeHandle.pause();
|
||||
|
||||
// Libtorrent doesn't emit a torrent_paused_alert when the
|
||||
// torrent is queued (no I/O)
|
||||
// We test on the cached m_nativeStatus
|
||||
if (isQueued())
|
||||
m_session->handleTorrentPaused(this);
|
||||
}
|
||||
|
||||
void TorrentHandle::resume(bool forced)
|
||||
@@ -1646,7 +1645,7 @@ void TorrentHandle::handleSaveResumeDataAlert(const libtorrent::save_resume_data
|
||||
resumeData["qBt-name"] = m_name.toStdString();
|
||||
resumeData["qBt-seedStatus"] = m_hasSeedStatus;
|
||||
resumeData["qBt-tempPathDisabled"] = m_tempPathDisabled;
|
||||
resumeData["qBt-queuePosition"] = queuePosition();
|
||||
resumeData["qBt-queuePosition"] = (nativeHandle().queue_position() + 1); // qBt starts queue at 1
|
||||
resumeData["qBt-hasRootFolder"] = m_hasRootFolder;
|
||||
|
||||
m_session->handleTorrentResumeDataReady(this, resumeData);
|
||||
@@ -1664,15 +1663,11 @@ void TorrentHandle::handleSaveResumeDataFailedAlert(const libtorrent::save_resum
|
||||
|
||||
void TorrentHandle::handleFastResumeRejectedAlert(const libtorrent::fastresume_rejected_alert *p)
|
||||
{
|
||||
qDebug("/!\\ Fast resume failed for %s, reason: %s", qUtf8Printable(name()), p->message().c_str());
|
||||
|
||||
updateStatus();
|
||||
if (p->error.value() == libt::errors::mismatching_file_size) {
|
||||
// Mismatching file size (files were probably moved)
|
||||
LogMsg(tr("File sizes mismatch for torrent '%1', pausing it.").arg(name()), Log::CRITICAL);
|
||||
pause();
|
||||
m_hasMissingFiles = true;
|
||||
if (!isPaused())
|
||||
pause();
|
||||
LogMsg(tr("File sizes mismatch for torrent '%1', pausing it.").arg(name()), Log::CRITICAL);
|
||||
}
|
||||
else {
|
||||
LogMsg(tr("Fast resume data was rejected for torrent '%1'. Reason: %2. Checking again...")
|
||||
|
||||
@@ -372,7 +372,7 @@ namespace BitTorrent
|
||||
void handleTempPathChanged();
|
||||
void handleCategorySavePathChanged();
|
||||
void handleAppendExtensionToggled();
|
||||
void saveResumeData(bool updateStatus = false);
|
||||
void saveResumeData();
|
||||
|
||||
/**
|
||||
* @brief fraction of file pieces that are available at least from one peer
|
||||
|
||||
@@ -339,12 +339,12 @@ TorrentInfo::PieceRange TorrentInfo::filePieces(int fileIndex) const
|
||||
|
||||
const libt::file_storage &files = nativeInfo()->files();
|
||||
const auto fileSize = files.file_size(fileIndex);
|
||||
const auto firstOffset = files.file_offset(fileIndex);
|
||||
return makeInterval(static_cast<int>(firstOffset / pieceLength()),
|
||||
static_cast<int>((firstOffset + fileSize - 1) / pieceLength()));
|
||||
const auto fileOffset = files.file_offset(fileIndex);
|
||||
return makeInterval(static_cast<int>(fileOffset / pieceLength()),
|
||||
static_cast<int>((fileOffset + fileSize - 1) / pieceLength()));
|
||||
}
|
||||
|
||||
void TorrentInfo::renameFile(uint index, const QString &newPath)
|
||||
void TorrentInfo::renameFile(const int index, const QString &newPath)
|
||||
{
|
||||
if (!isValid()) return;
|
||||
nativeInfo()->rename_file(index, Utils::Fs::toNativePath(newPath).toStdString());
|
||||
|
||||
@@ -102,7 +102,7 @@ namespace BitTorrent
|
||||
PieceRange filePieces(const QString &file) const;
|
||||
PieceRange filePieces(int fileIndex) const;
|
||||
|
||||
void renameFile(uint index, const QString &newPath);
|
||||
void renameFile(int index, const QString &newPath);
|
||||
|
||||
QString rootFolder() const;
|
||||
bool hasRootFolder() const;
|
||||
|
||||
@@ -30,7 +30,7 @@
|
||||
|
||||
#include <QtGlobal>
|
||||
|
||||
#if defined(Q_OS_MAC) || defined(Q_OS_FREEBSD)
|
||||
#if defined(Q_OS_MAC) || defined(Q_OS_FREEBSD) || defined(Q_OS_OPENBSD)
|
||||
#include <cstring>
|
||||
#include <sys/mount.h>
|
||||
#include <sys/param.h>
|
||||
|
||||
@@ -29,6 +29,8 @@
|
||||
|
||||
#include "iconprovider.h"
|
||||
|
||||
#include <QFileInfo>
|
||||
|
||||
IconProvider::IconProvider(QObject *parent)
|
||||
: QObject(parent)
|
||||
{
|
||||
@@ -57,7 +59,13 @@ IconProvider *IconProvider::instance()
|
||||
|
||||
QString IconProvider::getIconPath(const QString &iconId) const
|
||||
{
|
||||
return ":/icons/qbt-theme/" + iconId + ".png";
|
||||
// there are a few icons not available in svg
|
||||
const QString pathSvg = ":/icons/qbt-theme/" + iconId + ".svg";
|
||||
if (QFileInfo::exists(pathSvg))
|
||||
return pathSvg;
|
||||
|
||||
const QString pathPng = ":/icons/qbt-theme/" + iconId + ".png";
|
||||
return pathPng;
|
||||
}
|
||||
|
||||
IconProvider *IconProvider::m_instance = nullptr;
|
||||
|
||||
@@ -64,7 +64,7 @@ namespace
|
||||
setAllCookies(cookies);
|
||||
}
|
||||
|
||||
~NetworkCookieJar()
|
||||
~NetworkCookieJar() override
|
||||
{
|
||||
QDateTime now = QDateTime::currentDateTime();
|
||||
QList<QNetworkCookie> cookies = allCookies();
|
||||
|
||||
@@ -92,12 +92,12 @@ GeoIPDatabase *GeoIPDatabase::load(const QString &filename, QString &error)
|
||||
QFile file(filename);
|
||||
if (file.size() > MAX_FILE_SIZE) {
|
||||
error = tr("Unsupported database file size.");
|
||||
return 0;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (!file.open(QFile::ReadOnly)) {
|
||||
error = file.errorString();
|
||||
return 0;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
db = new GeoIPDatabase(file.size());
|
||||
@@ -105,13 +105,13 @@ GeoIPDatabase *GeoIPDatabase::load(const QString &filename, QString &error)
|
||||
if (file.read(reinterpret_cast<char *>(db->m_data), db->m_size) != db->m_size) {
|
||||
error = file.errorString();
|
||||
delete db;
|
||||
return 0;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
||||
if (!db->parseMetadata(db->readMetadata(), error) || !db->loadDB(error)) {
|
||||
delete db;
|
||||
return 0;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return db;
|
||||
@@ -122,7 +122,7 @@ GeoIPDatabase *GeoIPDatabase::load(const QByteArray &data, QString &error)
|
||||
GeoIPDatabase *db = nullptr;
|
||||
if (data.size() > MAX_FILE_SIZE) {
|
||||
error = tr("Unsupported database file size.");
|
||||
return 0;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
db = new GeoIPDatabase(data.size());
|
||||
@@ -131,7 +131,7 @@ GeoIPDatabase *GeoIPDatabase::load(const QByteArray &data, QString &error)
|
||||
|
||||
if (!db->parseMetadata(db->readMetadata(), error) || !db->loadDB(error)) {
|
||||
delete db;
|
||||
return 0;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return db;
|
||||
|
||||
@@ -530,7 +530,7 @@ void Preferences::setWebUiAuthSubnetWhitelist(QStringList subnets)
|
||||
|
||||
QString Preferences::getServerDomains() const
|
||||
{
|
||||
return value("Preferences/WebUI/ServerDomains", '*').toString();
|
||||
return value("Preferences/WebUI/ServerDomains", QChar('*')).toString();
|
||||
}
|
||||
|
||||
void Preferences::setServerDomains(const QString &str)
|
||||
@@ -540,7 +540,7 @@ void Preferences::setServerDomains(const QString &str)
|
||||
|
||||
QString Preferences::getWebUiAddress() const
|
||||
{
|
||||
return value("Preferences/WebUI/Address", '*').toString().trimmed();
|
||||
return value("Preferences/WebUI/Address", QChar('*')).toString().trimmed();
|
||||
}
|
||||
|
||||
void Preferences::setWebUiAddress(const QString &addr)
|
||||
@@ -1429,6 +1429,16 @@ void Preferences::setSearchTabHeaderState(const QByteArray &state)
|
||||
setValue("SearchTab/qt5/HeaderState", state);
|
||||
}
|
||||
|
||||
bool Preferences::getRegexAsFilteringPatternForSearchJob() const
|
||||
{
|
||||
return value("SearchTab/UseRegexAsFilteringPattern", false).toBool();
|
||||
}
|
||||
|
||||
void Preferences::setRegexAsFilteringPatternForSearchJob(const bool checked)
|
||||
{
|
||||
setValue("SearchTab/UseRegexAsFilteringPattern", checked);
|
||||
}
|
||||
|
||||
QStringList Preferences::getSearchEngDisabled() const
|
||||
{
|
||||
return value("SearchEngines/disabledEngines").toStringList();
|
||||
@@ -1519,12 +1529,12 @@ void Preferences::setTransHeaderState(const QByteArray &state)
|
||||
setValue("TransferList/qt5/HeaderState", state);
|
||||
}
|
||||
|
||||
bool Preferences::getRegexAsFilteringPattern() const
|
||||
bool Preferences::getRegexAsFilteringPatternForTransferList() const
|
||||
{
|
||||
return value("TransferList/UseRegexAsFilteringPattern", false).toBool();
|
||||
}
|
||||
|
||||
void Preferences::setRegexAsFilteringPattern(const bool checked)
|
||||
void Preferences::setRegexAsFilteringPatternForTransferList(const bool checked)
|
||||
{
|
||||
setValue("TransferList/UseRegexAsFilteringPattern", checked);
|
||||
}
|
||||
|
||||
@@ -342,6 +342,8 @@ public:
|
||||
void setRssMainSplitterState(const QByteArray &state);
|
||||
QByteArray getSearchTabHeaderState() const;
|
||||
void setSearchTabHeaderState(const QByteArray &state);
|
||||
bool getRegexAsFilteringPatternForSearchJob() const;
|
||||
void setRegexAsFilteringPatternForSearchJob(bool checked);
|
||||
QStringList getSearchEngDisabled() const;
|
||||
void setSearchEngDisabled(const QStringList &engines);
|
||||
QString getTorImportLastContentDir() const;
|
||||
@@ -356,8 +358,8 @@ public:
|
||||
void setTransSelFilter(const int &index);
|
||||
QByteArray getTransHeaderState() const;
|
||||
void setTransHeaderState(const QByteArray &state);
|
||||
bool getRegexAsFilteringPattern() const;
|
||||
void setRegexAsFilteringPattern(bool checked);
|
||||
bool getRegexAsFilteringPatternForTransferList() const;
|
||||
void setRegexAsFilteringPatternForTransferList(bool checked);
|
||||
int getToolbarTextPosition() const;
|
||||
void setToolbarTextPosition(const int position);
|
||||
|
||||
|
||||
@@ -73,7 +73,7 @@ namespace
|
||||
|
||||
// python 2: remove "*.pyc" files
|
||||
const QStringList files = QDir(dir).entryList(QDir::Files);
|
||||
for (const QString file : files) {
|
||||
for (const QString &file : files) {
|
||||
if (file.endsWith(".pyc"))
|
||||
Utils::Fs::forceRemove(file);
|
||||
}
|
||||
|
||||
@@ -44,7 +44,7 @@
|
||||
|
||||
#if defined(Q_OS_WIN)
|
||||
#include <Windows.h>
|
||||
#elif defined(Q_OS_MAC) || defined(Q_OS_FREEBSD)
|
||||
#elif defined(Q_OS_MAC) || defined(Q_OS_FREEBSD) || defined(Q_OS_OPENBSD)
|
||||
#include <sys/param.h>
|
||||
#include <sys/mount.h>
|
||||
#elif defined(Q_OS_HAIKU)
|
||||
@@ -313,7 +313,7 @@ bool Utils::Fs::isNetworkFileSystem(const QString &path)
|
||||
if (statfs(file.toLocal8Bit().constData(), &buf) != 0)
|
||||
return false;
|
||||
|
||||
#ifdef Q_OS_MAC
|
||||
#if defined(Q_OS_MAC) || defined(Q_OS_OPENBSD)
|
||||
// XXX: should we make sure HAVE_STRUCT_FSSTAT_F_FSTYPENAME is defined?
|
||||
return ((strncmp(buf.f_fstypename, "nfs", sizeof(buf.f_fstypename)) == 0)
|
||||
|| (strncmp(buf.f_fstypename, "cifs", sizeof(buf.f_fstypename)) == 0)
|
||||
|
||||
@@ -426,7 +426,7 @@ int AddNewTorrentDialog::indexOfSavePath(const QString &savePath)
|
||||
void AddNewTorrentDialog::updateDiskSpaceLabel()
|
||||
{
|
||||
// Determine torrent size
|
||||
qulonglong torrentSize = 0;
|
||||
qlonglong torrentSize = 0;
|
||||
|
||||
if (m_hasMetadata) {
|
||||
if (m_contentModel) {
|
||||
@@ -489,8 +489,9 @@ void AddNewTorrentDialog::renameSelectedFile()
|
||||
|
||||
// Ask for new name
|
||||
bool ok = false;
|
||||
QString newName = AutoExpandableDialog::getText(this, tr("Renaming"), tr("New name:"), QLineEdit::Normal, modelIndex.data().toString(), &ok)
|
||||
.trimmed();
|
||||
const bool isFile = (m_contentModel->itemType(modelIndex) == TorrentContentModelItem::FileType);
|
||||
QString newName = AutoExpandableDialog::getText(this, tr("Renaming"), tr("New name:"), QLineEdit::Normal
|
||||
, modelIndex.data().toString(), &ok, isFile).trimmed();
|
||||
if (!ok) return;
|
||||
|
||||
if (newName.isEmpty() || !Utils::Fs::isValidFileSystemName(newName)) {
|
||||
@@ -500,8 +501,7 @@ void AddNewTorrentDialog::renameSelectedFile()
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_contentModel->itemType(modelIndex) == TorrentContentModelItem::FileType) {
|
||||
// renaming a file
|
||||
if (isFile) {
|
||||
const int fileIndex = m_contentModel->getFileIndex(modelIndex);
|
||||
|
||||
if (newName.endsWith(QB_EXT))
|
||||
|
||||
@@ -48,7 +48,7 @@ AutoExpandableDialog::~AutoExpandableDialog()
|
||||
|
||||
QString AutoExpandableDialog::getText(QWidget *parent, const QString &title, const QString &label,
|
||||
QLineEdit::EchoMode mode, const QString &text,
|
||||
bool *ok, Qt::InputMethodHints inputMethodHints)
|
||||
bool *ok, const bool excludeExtension, Qt::InputMethodHints inputMethodHints)
|
||||
{
|
||||
AutoExpandableDialog d(parent);
|
||||
d.setWindowTitle(title);
|
||||
@@ -57,6 +57,16 @@ QString AutoExpandableDialog::getText(QWidget *parent, const QString &title, con
|
||||
d.m_ui->textEdit->setEchoMode(mode);
|
||||
d.m_ui->textEdit->setInputMethodHints(inputMethodHints);
|
||||
|
||||
d.m_ui->textEdit->selectAll();
|
||||
if (excludeExtension) {
|
||||
int lastDotIndex = text.lastIndexOf('.');
|
||||
if ((lastDotIndex > 3) && (text.mid(lastDotIndex - 4, 4).toLower() == ".tar"))
|
||||
lastDotIndex -= 4;
|
||||
// Select file name without extension, except dot files like .gitignore
|
||||
if (lastDotIndex > 0)
|
||||
d.m_ui->textEdit->setSelection(0, lastDotIndex);
|
||||
}
|
||||
|
||||
bool res = d.exec();
|
||||
if (ok)
|
||||
*ok = res;
|
||||
|
||||
@@ -48,7 +48,7 @@ public:
|
||||
|
||||
static QString getText(QWidget *parent, const QString &title, const QString &label,
|
||||
QLineEdit::EchoMode mode = QLineEdit::Normal, const QString &text = QString(),
|
||||
bool *ok = nullptr, Qt::InputMethodHints inputMethodHints = Qt::ImhNone);
|
||||
bool *ok = nullptr, bool excludeExtension = false, Qt::InputMethodHints inputMethodHints = Qt::ImhNone);
|
||||
|
||||
protected:
|
||||
void showEvent(QShowEvent *e) override;
|
||||
|
||||
@@ -228,7 +228,7 @@ QVariant CategoryFilterModel::data(const QModelIndex &index, int role) const
|
||||
|
||||
Qt::ItemFlags CategoryFilterModel::flags(const QModelIndex &index) const
|
||||
{
|
||||
if (!index.isValid()) return 0;
|
||||
if (!index.isValid()) return Qt::NoItemFlags;
|
||||
|
||||
return Qt::ItemIsEnabled | Qt::ItemIsSelectable;
|
||||
}
|
||||
|
||||
@@ -45,11 +45,7 @@
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QToolButton" name="buttonAdd">
|
||||
<property name="text">
|
||||
<string notr="true"/>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QToolButton" name="buttonAdd"/>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="verticalSpacer">
|
||||
@@ -68,11 +64,7 @@
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QToolButton" name="buttonDelete">
|
||||
<property name="text">
|
||||
<string notr="true"/>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QToolButton" name="buttonDelete"/>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="verticalSpacer_3">
|
||||
|
||||
@@ -172,7 +172,7 @@ bool CookiesModel::removeRows(int row, int count, const QModelIndex &parent)
|
||||
|
||||
Qt::ItemFlags CookiesModel::flags(const QModelIndex &index) const
|
||||
{
|
||||
if (!index.isValid()) return 0;
|
||||
if (!index.isValid()) return Qt::NoItemFlags;
|
||||
|
||||
return Qt::ItemIsEditable | QAbstractItemModel::flags(index);
|
||||
}
|
||||
|
||||
@@ -66,9 +66,6 @@
|
||||
<property name="toolTip">
|
||||
<string>Remember choice</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string notr="true"/>
|
||||
</property>
|
||||
<property name="iconSize">
|
||||
<size>
|
||||
<width>24</width>
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
|
||||
#include "guiiconprovider.h"
|
||||
|
||||
#include <QHash>
|
||||
#include <QIcon>
|
||||
#include <QVector>
|
||||
#if (defined(Q_OS_UNIX) && !defined(Q_OS_MAC))
|
||||
@@ -71,13 +72,20 @@ QIcon GuiIconProvider::getIcon(const QString &iconId, const QString &fallback) c
|
||||
QIcon icon = QIcon::fromTheme(iconId);
|
||||
if (icon.name() != iconId)
|
||||
icon = QIcon::fromTheme(fallback, QIcon(IconProvider::getIconPath(iconId)));
|
||||
icon = generateDifferentSizes(icon);
|
||||
return icon;
|
||||
}
|
||||
#else
|
||||
Q_UNUSED(fallback)
|
||||
#endif
|
||||
return QIcon(IconProvider::getIconPath(iconId));
|
||||
// cache to avoid rescaling svg icons
|
||||
static QHash<QString, QIcon> iconCache;
|
||||
const auto iter = iconCache.find(iconId);
|
||||
if (iter != iconCache.end())
|
||||
return *iter;
|
||||
|
||||
const QIcon icon {IconProvider::getIconPath(iconId)};
|
||||
iconCache[iconId] = icon;
|
||||
return icon;
|
||||
}
|
||||
|
||||
QIcon GuiIconProvider::getFlagIcon(const QString &countryIsoCode) const
|
||||
@@ -86,41 +94,6 @@ QIcon GuiIconProvider::getFlagIcon(const QString &countryIsoCode) const
|
||||
return QIcon(":/icons/flags/" + countryIsoCode.toLower() + ".svg");
|
||||
}
|
||||
|
||||
// Makes sure the icon is at least available in 16px and 24px size
|
||||
// It scales the icon from the theme if necessary
|
||||
// Otherwise, the UI looks broken if the icon is not available
|
||||
// in the correct size.
|
||||
#if (defined(Q_OS_UNIX) && !defined(Q_OS_MAC))
|
||||
QIcon GuiIconProvider::generateDifferentSizes(const QIcon &icon) const
|
||||
{
|
||||
// if icon is loaded from SVG format, it already contains all the required sizes and we shall not resize it
|
||||
// In that case it will be available in the following sizes:
|
||||
// (QSize(16, 16), QSize(22, 22), QSize(32, 32), QSize(48, 48), QSize(64, 64), QSize(128, 128), QSize(256, 256))
|
||||
|
||||
if (icon.availableSizes(QIcon::Normal, QIcon::On).size() > 6)
|
||||
return icon;
|
||||
|
||||
QIcon newIcon;
|
||||
const QVector<QSize> requiredSizes {{16, 16}, {24, 24}, {32, 32}};
|
||||
const QVector<QIcon::Mode> modes {QIcon::Normal, QIcon::Active, QIcon::Selected, QIcon::Disabled};
|
||||
for (const QSize &size : requiredSizes) {
|
||||
for (const QIcon::Mode mode : modes) {
|
||||
QPixmap pixoff = icon.pixmap(size, mode, QIcon::Off);
|
||||
if (pixoff.height() > size.height())
|
||||
pixoff = pixoff.scaled(size, Qt::KeepAspectRatio, Qt::SmoothTransformation);
|
||||
newIcon.addPixmap(pixoff, mode, QIcon::Off);
|
||||
|
||||
QPixmap pixon = icon.pixmap(size, mode, QIcon::On);
|
||||
if (pixon.height() > size.height())
|
||||
pixon = pixoff.scaled(size, Qt::KeepAspectRatio, Qt::SmoothTransformation);
|
||||
newIcon.addPixmap(pixon, mode, QIcon::On);
|
||||
}
|
||||
}
|
||||
|
||||
return newIcon;
|
||||
}
|
||||
#endif
|
||||
|
||||
QString GuiIconProvider::getIconPath(const QString &iconId) const
|
||||
{
|
||||
#if (defined(Q_OS_UNIX) && !defined(Q_OS_MAC))
|
||||
|
||||
@@ -53,10 +53,9 @@ private slots:
|
||||
|
||||
private:
|
||||
explicit GuiIconProvider(QObject *parent = nullptr);
|
||||
~GuiIconProvider();
|
||||
#if (defined(Q_OS_UNIX) && !defined(Q_OS_MAC))
|
||||
QIcon generateDifferentSizes(const QIcon &icon) const;
|
||||
~GuiIconProvider() override;
|
||||
|
||||
#if (defined(Q_OS_UNIX) && !defined(Q_OS_MAC))
|
||||
bool m_useSystemTheme;
|
||||
#endif
|
||||
};
|
||||
|
||||
@@ -132,7 +132,7 @@ namespace
|
||||
const QString KEY_NOTIFICATIONS_TORRENTADDED = NOTIFICATIONS_SETTINGS_KEY("TorrentAdded");
|
||||
|
||||
// Misc
|
||||
const QString KEY_DOWNLOAD_TRACKER_FAVICON = NOTIFICATIONS_SETTINGS_KEY("DownloadTrackerFavicon");
|
||||
const QString KEY_DOWNLOAD_TRACKER_FAVICON = QStringLiteral(SETTINGS_KEY("DownloadTrackerFavicon"));
|
||||
|
||||
// just a shortcut
|
||||
inline SettingsStorage *settings()
|
||||
@@ -710,10 +710,10 @@ void MainWindow::showFilterContextMenu(const QPoint &)
|
||||
menu->addSeparator();
|
||||
QAction *useRegexAct = new QAction(tr("Use regular expressions"), menu);
|
||||
useRegexAct->setCheckable(true);
|
||||
useRegexAct->setChecked(pref->getRegexAsFilteringPattern());
|
||||
useRegexAct->setChecked(pref->getRegexAsFilteringPatternForTransferList());
|
||||
menu->addAction(useRegexAct);
|
||||
|
||||
connect(useRegexAct, &QAction::toggled, pref, &Preferences::setRegexAsFilteringPattern);
|
||||
connect(useRegexAct, &QAction::toggled, pref, &Preferences::setRegexAsFilteringPatternForTransferList);
|
||||
connect(useRegexAct, &QAction::toggled, this, [this]() { m_transferListWidget->applyNameFilter(m_searchFilter->text()); });
|
||||
|
||||
menu->exec(QCursor::pos());
|
||||
@@ -1036,7 +1036,7 @@ void MainWindow::on_actionCloseWindow_triggered()
|
||||
QWidget *MainWindow::currentTabWidget() const
|
||||
{
|
||||
if (isMinimized() || !isVisible())
|
||||
return 0;
|
||||
return nullptr;
|
||||
if (m_tabs->currentIndex() == 0)
|
||||
return m_transferListWidget;
|
||||
return m_tabs->currentWidget();
|
||||
@@ -1437,7 +1437,7 @@ void MainWindow::loadPreferences(bool configureSession)
|
||||
#else
|
||||
const bool newSystrayIntegration = pref->systrayIntegration();
|
||||
m_ui->actionLock->setVisible(newSystrayIntegration);
|
||||
if (newSystrayIntegration != (m_systrayIcon != 0)) {
|
||||
if (newSystrayIntegration != (m_systrayIcon != nullptr)) {
|
||||
if (newSystrayIntegration) {
|
||||
// create the trayicon
|
||||
if (!QSystemTrayIcon::isSystemTrayAvailable()) {
|
||||
@@ -1568,10 +1568,10 @@ void MainWindow::updateGUI()
|
||||
html += "qBittorrent";
|
||||
html += "</div>";
|
||||
html += "<div style='vertical-align: baseline; height: 18px;'>";
|
||||
html += "<img src=':/icons/skin/download.png' height='14'/> " + tr("DL speed: %1", "e.g: Download speed: 10 KiB/s").arg(Utils::Misc::friendlyUnit(status.payloadDownloadRate, true));
|
||||
html += "<img src=':/icons/skin/download.svg' height='14'/> " + tr("DL speed: %1", "e.g: Download speed: 10 KiB/s").arg(Utils::Misc::friendlyUnit(status.payloadDownloadRate, true));
|
||||
html += "</div>";
|
||||
html += "<div style='vertical-align: baseline; height: 18px;'>";
|
||||
html += "<img src=':/icons/skin/seeding.png' height='14'/> " + tr("UP speed: %1", "e.g: Upload speed: 10 KiB/s").arg(Utils::Misc::friendlyUnit(status.payloadUploadRate, true));
|
||||
html += "<img src=':/icons/skin/seeding.svg' height='14'/> " + tr("UP speed: %1", "e.g: Upload speed: 10 KiB/s").arg(Utils::Misc::friendlyUnit(status.payloadUploadRate, true));
|
||||
html += "</div>";
|
||||
#else
|
||||
// OSes such as Windows do not support html here
|
||||
|
||||
@@ -1358,7 +1358,6 @@ void OptionsDialog::toggleComboRatioLimitAct()
|
||||
void OptionsDialog::enableForceProxy(bool enable)
|
||||
{
|
||||
m_ui->checkUPnP->setEnabled(!enable);
|
||||
m_ui->checkDHT->setEnabled(!enable);
|
||||
m_ui->checkLSD->setEnabled(!enable);
|
||||
}
|
||||
|
||||
@@ -1751,11 +1750,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(Utils::Gui::scaledPixmap(":/icons/qbt-theme/security-high.png", this, 24));
|
||||
m_ui->lblSslKeyStatus->setPixmap(Utils::Gui::scaledPixmapSvg(":/icons/qbt-theme/security-high.svg", this, 24));
|
||||
m_sslKey = key;
|
||||
}
|
||||
else {
|
||||
m_ui->lblSslKeyStatus->setPixmap(Utils::Gui::scaledPixmap(":/icons/qbt-theme/security-low.png", this, 24));
|
||||
m_ui->lblSslKeyStatus->setPixmap(Utils::Gui::scaledPixmapSvg(":/icons/qbt-theme/security-low.svg", this, 24));
|
||||
m_sslKey.clear();
|
||||
}
|
||||
return isKeyValid;
|
||||
@@ -1770,11 +1769,11 @@ bool OptionsDialog::setSslCertificate(const QByteArray &cert)
|
||||
#ifndef QT_NO_OPENSSL
|
||||
const bool isCertValid = !QSslCertificate(cert).isNull();
|
||||
if (isCertValid) {
|
||||
m_ui->lblSslCertStatus->setPixmap(Utils::Gui::scaledPixmap(":/icons/qbt-theme/security-high.png", this, 24));
|
||||
m_ui->lblSslCertStatus->setPixmap(Utils::Gui::scaledPixmapSvg(":/icons/qbt-theme/security-high.svg", this, 24));
|
||||
m_sslCert = cert;
|
||||
}
|
||||
else {
|
||||
m_ui->lblSslCertStatus->setPixmap(Utils::Gui::scaledPixmap(":/icons/qbt-theme/security-low.png", this, 24));
|
||||
m_ui->lblSslCertStatus->setPixmap(Utils::Gui::scaledPixmapSvg(":/icons/qbt-theme/security-low.svg", this, 24));
|
||||
m_sslCert.clear();
|
||||
}
|
||||
return isCertValid;
|
||||
|
||||
@@ -2987,11 +2987,7 @@ Use ';' to split multiple entries. Can use wildcard '*'.</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_11">
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="lblSslCertStatus">
|
||||
<property name="text">
|
||||
<string notr="true"/>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QLabel" name="lblSslCertStatus"/>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QLabel" name="lblWebUiCrt">
|
||||
@@ -3028,11 +3024,7 @@ Use ';' to split multiple entries. Can use wildcard '*'.</string>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="lblSslKeyStatus">
|
||||
<property name="text">
|
||||
<string notr="true"/>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QLabel" name="lblSslKeyStatus"/>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QLabel" name="lblWebUiKey">
|
||||
|
||||
@@ -63,7 +63,7 @@ public:
|
||||
|
||||
PeerListDelegate(QObject *parent) : QItemDelegate(parent) {}
|
||||
|
||||
~PeerListDelegate() {}
|
||||
~PeerListDelegate() override {}
|
||||
|
||||
void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const override
|
||||
{
|
||||
|
||||
@@ -441,7 +441,7 @@ void PeerListWidget::updatePeer(const QString &ip, BitTorrent::TorrentHandle *co
|
||||
|
||||
void PeerListWidget::handleResolved(const QString &ip, const QString &hostname)
|
||||
{
|
||||
QStandardItem *item = m_peerItems.value(ip, 0);
|
||||
QStandardItem *item = m_peerItems.value(ip, nullptr);
|
||||
if (item) {
|
||||
qDebug("Resolved %s -> %s", qUtf8Printable(ip), qUtf8Printable(hostname));
|
||||
item->setData(hostname, Qt::DisplayRole);
|
||||
|
||||
@@ -61,7 +61,7 @@ class PeerListWidget : public QTreeView
|
||||
|
||||
public:
|
||||
explicit PeerListWidget(PropertiesWidget *parent);
|
||||
~PeerListWidget();
|
||||
~PeerListWidget() override;
|
||||
|
||||
void loadPeers(BitTorrent::TorrentHandle *const torrent, bool forceHostnameResolution = false);
|
||||
QStandardItem *addPeer(const QString &ip, BitTorrent::TorrentHandle *const torrent, const BitTorrent::PeerInfo &peer);
|
||||
|
||||
@@ -685,8 +685,9 @@ void PropertiesWidget::renameSelectedFile()
|
||||
|
||||
// Ask for new name
|
||||
bool ok = false;
|
||||
QString newName = AutoExpandableDialog::getText(this, tr("Renaming"), tr("New name:"), QLineEdit::Normal, modelIndex.data().toString(), &ok)
|
||||
.trimmed();
|
||||
const bool isFile = (m_propListModel->itemType(modelIndex) == TorrentContentModelItem::FileType);
|
||||
QString newName = AutoExpandableDialog::getText(this, tr("Renaming"), tr("New name:"), QLineEdit::Normal
|
||||
, modelIndex.data().toString(), &ok, isFile).trimmed();
|
||||
if (!ok) return;
|
||||
|
||||
if (newName.isEmpty() || !Utils::Fs::isValidFileSystemName(newName)) {
|
||||
@@ -696,8 +697,7 @@ void PropertiesWidget::renameSelectedFile()
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_propListModel->itemType(modelIndex) == TorrentContentModelItem::FileType) {
|
||||
// renaming a file
|
||||
if (isFile) {
|
||||
const int fileIndex = m_propListModel->getFileIndex(modelIndex);
|
||||
|
||||
if (newName.endsWith(QB_EXT))
|
||||
|
||||
@@ -73,7 +73,7 @@ TrackerListWidget::TrackerListWidget(PropertiesWidget *properties)
|
||||
// To also mitigate the above issue, we have to resize each column when
|
||||
// its size is 0, because explicitly 'showing' the column isn't enough
|
||||
// in the above scenario.
|
||||
for (unsigned int i = 0; i < COL_COUNT; ++i)
|
||||
for (int i = 0; i < COL_COUNT; ++i)
|
||||
if ((columnWidth(i) <= 0) && !isColumnHidden(i))
|
||||
resizeColumnToContents(i);
|
||||
// Context menu
|
||||
@@ -150,9 +150,9 @@ QList<QTreeWidgetItem*> TrackerListWidget::getSelectedTrackerItems() const
|
||||
|
||||
void TrackerListWidget::setRowColor(int row, QColor color)
|
||||
{
|
||||
unsigned int nbColumns = columnCount();
|
||||
const int nbColumns = columnCount();
|
||||
QTreeWidgetItem *item = topLevelItem(row);
|
||||
for (unsigned int i = 0; i < nbColumns; ++i)
|
||||
for (int i = 0; i < nbColumns; ++i)
|
||||
item->setData(i, Qt::ForegroundRole, color);
|
||||
}
|
||||
|
||||
@@ -333,7 +333,7 @@ void TrackerListWidget::loadTrackers()
|
||||
QStringList oldTrackerURLs = m_trackerItems.keys();
|
||||
foreach (const BitTorrent::TrackerEntry &entry, torrent->trackers()) {
|
||||
QString trackerURL = entry.url();
|
||||
QTreeWidgetItem *item = m_trackerItems.value(trackerURL, 0);
|
||||
QTreeWidgetItem *item = m_trackerItems.value(trackerURL, nullptr);
|
||||
if (!item) {
|
||||
item = new QTreeWidgetItem();
|
||||
item->setText(COL_URL, trackerURL);
|
||||
@@ -367,13 +367,13 @@ void TrackerListWidget::loadTrackers()
|
||||
|
||||
item->setText(COL_RECEIVED, QString::number(data.numPeers));
|
||||
#if LIBTORRENT_VERSION_NUM >= 10000
|
||||
item->setText(COL_SEEDS, QString::number(entry.nativeEntry().scrape_complete > 0 ? entry.nativeEntry().scrape_complete : 0));
|
||||
item->setText(COL_PEERS, QString::number(entry.nativeEntry().scrape_incomplete > 0 ? entry.nativeEntry().scrape_incomplete : 0));
|
||||
item->setText(COL_DOWNLOADED, QString::number(entry.nativeEntry().scrape_downloaded > 0 ? entry.nativeEntry().scrape_downloaded : 0));
|
||||
item->setText(COL_SEEDS, (entry.nativeEntry().scrape_complete > -1) ? QString::number(entry.nativeEntry().scrape_complete) : tr("N/A"));
|
||||
item->setText(COL_PEERS, (entry.nativeEntry().scrape_incomplete > -1) ? QString::number(entry.nativeEntry().scrape_incomplete) : tr("N/A"));
|
||||
item->setText(COL_DOWNLOADED, (entry.nativeEntry().scrape_downloaded > -1) ? QString::number(entry.nativeEntry().scrape_downloaded) : tr("N/A"));
|
||||
#else
|
||||
item->setText(COL_SEEDS, '0');
|
||||
item->setText(COL_PEERS, '0');
|
||||
item->setText(COL_DOWNLOADED, '0');
|
||||
item->setText(COL_SEEDS, tr("N/A"));
|
||||
item->setText(COL_PEERS, tr("N/A"));
|
||||
item->setText(COL_DOWNLOADED, tr("N/A"));
|
||||
#endif
|
||||
|
||||
item->setTextAlignment(COL_TIER, (Qt::AlignRight | Qt::AlignVCenter));
|
||||
@@ -604,7 +604,7 @@ QStringList TrackerListWidget::headerLabels()
|
||||
int TrackerListWidget::visibleColumnsCount() const
|
||||
{
|
||||
int visibleCols = 0;
|
||||
for (unsigned int i = 0; i < COL_COUNT; ++i) {
|
||||
for (int i = 0; i < COL_COUNT; ++i) {
|
||||
if (!isColumnHidden(i))
|
||||
++visibleCols;
|
||||
}
|
||||
|
||||
@@ -54,7 +54,7 @@ void ScanFoldersDelegate::setEditorData(QWidget *editor, const QModelIndex &inde
|
||||
|
||||
QWidget *ScanFoldersDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &, const QModelIndex &index) const
|
||||
{
|
||||
if (index.column() != ScanFoldersModel::DOWNLOAD) return 0;
|
||||
if (index.column() != ScanFoldersModel::DOWNLOAD) return nullptr;
|
||||
|
||||
QComboBox *editor = new QComboBox(parent);
|
||||
|
||||
@@ -96,7 +96,7 @@ void ScanFoldersDelegate::setModelData(QWidget *editor, QAbstractItemModel *mode
|
||||
model->setData(
|
||||
index,
|
||||
QFileDialog::getExistingDirectory(
|
||||
0, tr("Select save location"),
|
||||
nullptr, tr("Select save location"),
|
||||
index.data(Qt::UserRole).toInt() == ScanFoldersModel::CUSTOM_LOCATION ?
|
||||
index.data().toString() :
|
||||
BitTorrent::Session::instance()->defaultSavePath()),
|
||||
|
||||
@@ -258,7 +258,7 @@ QTreeWidgetItem *PluginSelectDialog::findItemWithID(QString id)
|
||||
return item;
|
||||
}
|
||||
|
||||
return 0;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void PluginSelectDialog::loadSupportedSearchPlugins()
|
||||
@@ -361,7 +361,7 @@ void PluginSelectDialog::askForPluginUrl()
|
||||
void PluginSelectDialog::askForLocalPlugin()
|
||||
{
|
||||
QStringList pathsList = QFileDialog::getOpenFileNames(
|
||||
0, tr("Select search plugins"), QDir::homePath(),
|
||||
nullptr, tr("Select search plugins"), QDir::homePath(),
|
||||
tr("qBittorrent search plugin") + QLatin1String(" (*.py)")
|
||||
);
|
||||
foreach (QString path, pathsList) {
|
||||
|
||||
@@ -103,7 +103,7 @@ SearchJobWidget::SearchJobWidget(SearchHandler *searchHandler, QWidget *parent)
|
||||
|
||||
// Ensure that at least one column is visible at all times
|
||||
bool atLeastOne = false;
|
||||
for (unsigned int i = 0; i < SearchSortModel::DL_LINK; ++i) {
|
||||
for (int i = 0; i < SearchSortModel::DL_LINK; ++i) {
|
||||
if (!m_ui->resultsBrowser->isColumnHidden(i)) {
|
||||
atLeastOne = true;
|
||||
break;
|
||||
@@ -114,7 +114,7 @@ SearchJobWidget::SearchJobWidget(SearchHandler *searchHandler, QWidget *parent)
|
||||
// To also mitigate the above issue, we have to resize each column when
|
||||
// its size is 0, because explicitly 'showing' the column isn't enough
|
||||
// in the above scenario.
|
||||
for (unsigned int i = 0; i < SearchSortModel::DL_LINK; ++i)
|
||||
for (int i = 0; i < SearchSortModel::DL_LINK; ++i)
|
||||
if ((m_ui->resultsBrowser->columnWidth(i) <= 0) && !m_ui->resultsBrowser->isColumnHidden(i))
|
||||
m_ui->resultsBrowser->resizeColumnToContents(i);
|
||||
|
||||
@@ -131,6 +131,8 @@ SearchJobWidget::SearchJobWidget(SearchHandler *searchHandler, QWidget *parent)
|
||||
m_lineEditSearchResultsFilter = new LineEdit(this);
|
||||
m_lineEditSearchResultsFilter->setFixedWidth(Utils::Gui::scaledSize(this, 170));
|
||||
m_lineEditSearchResultsFilter->setPlaceholderText(tr("Filter search results..."));
|
||||
m_lineEditSearchResultsFilter->setContextMenuPolicy(Qt::CustomContextMenu);
|
||||
connect(m_lineEditSearchResultsFilter, &QWidget::customContextMenuRequested, this, &SearchJobWidget::showFilterContextMenu);
|
||||
m_ui->horizontalLayout->insertWidget(0, m_lineEditSearchResultsFilter);
|
||||
|
||||
connect(m_lineEditSearchResultsFilter, &LineEdit::textChanged, this, &SearchJobWidget::filterSearchResults);
|
||||
@@ -159,6 +161,9 @@ SearchJobWidget::SearchJobWidget(SearchHandler *searchHandler, QWidget *parent)
|
||||
connect(searchHandler, &SearchHandler::searchFinished, this, &SearchJobWidget::searchFinished);
|
||||
connect(searchHandler, &SearchHandler::searchFailed, this, &SearchJobWidget::searchFailed);
|
||||
connect(this, &QObject::destroyed, searchHandler, &QObject::deleteLater);
|
||||
|
||||
QShortcut *enterHotkey = new QShortcut(Qt::Key_Return, m_ui->resultsBrowser, nullptr, nullptr, Qt::WidgetShortcut);
|
||||
connect(enterHotkey, &QShortcut::activated, this, &SearchJobWidget::downloadTorrents);
|
||||
}
|
||||
|
||||
SearchJobWidget::~SearchJobWidget()
|
||||
@@ -169,7 +174,6 @@ SearchJobWidget::~SearchJobWidget()
|
||||
|
||||
void SearchJobWidget::onItemDoubleClicked(const QModelIndex &index)
|
||||
{
|
||||
setRowColor(index.row(), QApplication::palette().color(QPalette::LinkVisited));
|
||||
downloadTorrent(index);
|
||||
}
|
||||
|
||||
@@ -267,6 +271,7 @@ void SearchJobWidget::downloadTorrent(const QModelIndex &rowIndex)
|
||||
connect(downloadHandler, &SearchDownloadHandler::downloadFinished, this, &SearchJobWidget::addTorrentToSession);
|
||||
connect(downloadHandler, &SearchDownloadHandler::downloadFinished, downloadHandler, &SearchDownloadHandler::deleteLater);
|
||||
}
|
||||
setRowColor(rowIndex.row(), QApplication::palette().color(QPalette::LinkVisited));
|
||||
}
|
||||
|
||||
void SearchJobWidget::addTorrentToSession(const QString &source)
|
||||
@@ -342,10 +347,29 @@ void SearchJobWidget::fillFilterComboBoxes()
|
||||
|
||||
void SearchJobWidget::filterSearchResults(const QString &name)
|
||||
{
|
||||
m_proxyModel->setFilterRegExp(QRegExp(name, Qt::CaseInsensitive));
|
||||
const QRegExp::PatternSyntax patternSyntax = Preferences::instance()->getRegexAsFilteringPatternForSearchJob()
|
||||
? QRegExp::RegExp : QRegExp::WildcardUnix;
|
||||
m_proxyModel->setFilterRegExp(QRegExp(name, Qt::CaseInsensitive, patternSyntax));
|
||||
updateResultsCount();
|
||||
}
|
||||
|
||||
void SearchJobWidget::showFilterContextMenu(const QPoint &)
|
||||
{
|
||||
const Preferences *pref = Preferences::instance();
|
||||
|
||||
QMenu *menu = m_lineEditSearchResultsFilter->createStandardContextMenu();
|
||||
menu->addSeparator();
|
||||
QAction *useRegexAct = new QAction(tr("Use regular expressions"), menu);
|
||||
useRegexAct->setCheckable(true);
|
||||
useRegexAct->setChecked(pref->getRegexAsFilteringPatternForSearchJob());
|
||||
menu->addAction(useRegexAct);
|
||||
|
||||
connect(useRegexAct, &QAction::toggled, pref, &Preferences::setRegexAsFilteringPatternForSearchJob);
|
||||
connect(useRegexAct, &QAction::toggled, this, [this]() { filterSearchResults(m_lineEditSearchResultsFilter->text()); });
|
||||
|
||||
menu->exec(QCursor::pos());
|
||||
}
|
||||
|
||||
QString SearchJobWidget::statusText(SearchJobWidget::Status st)
|
||||
{
|
||||
switch (st) {
|
||||
@@ -391,7 +415,7 @@ void SearchJobWidget::displayToggleColumnsMenu(const QPoint&)
|
||||
actions.append(myAct);
|
||||
}
|
||||
int visibleCols = 0;
|
||||
for (unsigned int i = 0; i < SearchSortModel::DL_LINK; ++i) {
|
||||
for (int i = 0; i < SearchSortModel::DL_LINK; ++i) {
|
||||
if (!m_ui->resultsBrowser->isColumnHidden(i))
|
||||
++visibleCols;
|
||||
|
||||
|
||||
@@ -96,6 +96,7 @@ private:
|
||||
void saveSettings() const;
|
||||
void updateFilter();
|
||||
void filterSearchResults(const QString &name);
|
||||
void showFilterContextMenu(const QPoint &);
|
||||
void displayToggleColumnsMenu(const QPoint&);
|
||||
void onItemDoubleClicked(const QModelIndex &index);
|
||||
void searchFinished(bool cancelled);
|
||||
|
||||
@@ -63,14 +63,14 @@ StatusBar::StatusBar(QWidget *parent)
|
||||
m_connecStatusLblIcon->setFlat(true);
|
||||
m_connecStatusLblIcon->setFocusPolicy(Qt::NoFocus);
|
||||
m_connecStatusLblIcon->setCursor(Qt::PointingHandCursor);
|
||||
m_connecStatusLblIcon->setIcon(QIcon(":/icons/skin/firewalled.png"));
|
||||
m_connecStatusLblIcon->setIcon(QIcon(":/icons/skin/firewalled.svg"));
|
||||
m_connecStatusLblIcon->setToolTip(
|
||||
QString(QLatin1String("<b>%1</b><br><i>%2</i>")).arg(tr("Connection status:")
|
||||
, tr("No direct connections. This may indicate network configuration problems.")));
|
||||
connect(m_connecStatusLblIcon, &QAbstractButton::clicked, this, &StatusBar::connectionButtonClicked);
|
||||
|
||||
m_dlSpeedLbl = new QPushButton(this);
|
||||
m_dlSpeedLbl->setIcon(QIcon(":/icons/skin/download.png"));
|
||||
m_dlSpeedLbl->setIcon(QIcon(":/icons/skin/download.svg"));
|
||||
connect(m_dlSpeedLbl, &QAbstractButton::clicked, this, &StatusBar::capDownloadSpeed);
|
||||
m_dlSpeedLbl->setFlat(true);
|
||||
m_dlSpeedLbl->setFocusPolicy(Qt::NoFocus);
|
||||
@@ -79,7 +79,7 @@ StatusBar::StatusBar(QWidget *parent)
|
||||
m_dlSpeedLbl->setMinimumWidth(200);
|
||||
|
||||
m_upSpeedLbl = new QPushButton(this);
|
||||
m_upSpeedLbl->setIcon(QIcon(":/icons/skin/seeding.png"));
|
||||
m_upSpeedLbl->setIcon(QIcon(":/icons/skin/seeding.svg"));
|
||||
connect(m_upSpeedLbl, &QAbstractButton::clicked, this, &StatusBar::capUploadSpeed);
|
||||
m_upSpeedLbl->setFlat(true);
|
||||
m_upSpeedLbl->setFocusPolicy(Qt::NoFocus);
|
||||
@@ -174,17 +174,17 @@ void StatusBar::updateConnectionStatus()
|
||||
const BitTorrent::SessionStatus &sessionStatus = BitTorrent::Session::instance()->status();
|
||||
|
||||
if (!BitTorrent::Session::instance()->isListening()) {
|
||||
m_connecStatusLblIcon->setIcon(QIcon(QLatin1String(":/icons/skin/disconnected.png")));
|
||||
m_connecStatusLblIcon->setIcon(QIcon(QLatin1String(":/icons/skin/disconnected.svg")));
|
||||
m_connecStatusLblIcon->setToolTip(QLatin1String("<b>") + tr("Connection Status:") + QLatin1String("</b><br>") + tr("Offline. This usually means that qBittorrent failed to listen on the selected port for incoming connections."));
|
||||
}
|
||||
else {
|
||||
if (sessionStatus.hasIncomingConnections) {
|
||||
// Connection OK
|
||||
m_connecStatusLblIcon->setIcon(QIcon(QLatin1String(":/icons/skin/connected.png")));
|
||||
m_connecStatusLblIcon->setIcon(QIcon(QLatin1String(":/icons/skin/connected.svg")));
|
||||
m_connecStatusLblIcon->setToolTip(QLatin1String("<b>") + tr("Connection Status:") + QLatin1String("</b><br>") + tr("Online"));
|
||||
}
|
||||
else {
|
||||
m_connecStatusLblIcon->setIcon(QIcon(QLatin1String(":/icons/skin/firewalled.png")));
|
||||
m_connecStatusLblIcon->setIcon(QIcon(QLatin1String(":/icons/skin/firewalled.svg")));
|
||||
m_connecStatusLblIcon->setToolTip(QLatin1String("<b>") + tr("Connection status:") + QLatin1String("</b><br>") + QLatin1String("<i>") + tr("No direct connections. This may indicate network configuration problems.") + QLatin1String("</i>"));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -135,7 +135,7 @@ QVariant TagFilterModel::data(const QModelIndex &index, int role) const
|
||||
Qt::ItemFlags TagFilterModel::flags(const QModelIndex &index) const
|
||||
{
|
||||
if (!index.isValid())
|
||||
return 0;
|
||||
return Qt::NoItemFlags;
|
||||
return Qt::ItemIsEnabled | Qt::ItemIsSelectable;
|
||||
}
|
||||
|
||||
|
||||
@@ -47,7 +47,7 @@ class TagFilterModel : public QAbstractListModel
|
||||
|
||||
public:
|
||||
explicit TagFilterModel(QObject *parent = nullptr);
|
||||
~TagFilterModel();
|
||||
~TagFilterModel() override;
|
||||
|
||||
static bool isSpecialItem(const QModelIndex &index);
|
||||
|
||||
|
||||
@@ -41,7 +41,7 @@ class TorrentContentFilterModel : public QSortFilterProxyModel
|
||||
|
||||
public:
|
||||
TorrentContentFilterModel(QObject *parent = nullptr);
|
||||
virtual ~TorrentContentFilterModel();
|
||||
~TorrentContentFilterModel() override;
|
||||
|
||||
TorrentContentModel *model() const;
|
||||
TorrentContentModelItem::ItemType itemType(const QModelIndex &index) const;
|
||||
|
||||
@@ -377,7 +377,7 @@ QVariant TorrentContentModel::data(const QModelIndex& index, int role) const
|
||||
Qt::ItemFlags TorrentContentModel::flags(const QModelIndex &index) const
|
||||
{
|
||||
if (!index.isValid())
|
||||
return 0;
|
||||
return Qt::NoItemFlags;
|
||||
|
||||
if (itemType(index) == TorrentContentModelItem::FolderType)
|
||||
return Qt::ItemIsEditable | Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsUserCheckable | Qt::ItemIsTristate;
|
||||
|
||||
@@ -46,7 +46,7 @@ class TorrentContentModel : public QAbstractItemModel
|
||||
|
||||
public:
|
||||
TorrentContentModel(QObject *parent = nullptr);
|
||||
~TorrentContentModel();
|
||||
~TorrentContentModel() override;
|
||||
|
||||
void updateFilesProgress(const QVector<qreal> &fp);
|
||||
void updateFilesPriorities(const QVector<int> &fprio);
|
||||
|
||||
@@ -80,7 +80,7 @@ void TorrentContentModelFolder::appendChild(TorrentContentModelItem *item)
|
||||
|
||||
TorrentContentModelItem *TorrentContentModelFolder::child(int row) const
|
||||
{
|
||||
return m_childItems.value(row, 0);
|
||||
return m_childItems.value(row, nullptr);
|
||||
}
|
||||
|
||||
TorrentContentModelFolder *TorrentContentModelFolder::childFolderWithName(const QString &name) const
|
||||
@@ -88,7 +88,7 @@ TorrentContentModelFolder *TorrentContentModelFolder::childFolderWithName(const
|
||||
foreach (TorrentContentModelItem *child, m_childItems)
|
||||
if ((child->itemType() == FolderType) && (child->name() == name))
|
||||
return static_cast<TorrentContentModelFolder *>(child);
|
||||
return 0;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
int TorrentContentModelFolder::childCount() const
|
||||
|
||||
@@ -40,7 +40,7 @@ public:
|
||||
// Invisible root item constructor
|
||||
TorrentContentModelFolder(const QList<QVariant> &data);
|
||||
|
||||
~TorrentContentModelFolder();
|
||||
~TorrentContentModelFolder() override;
|
||||
|
||||
ItemType itemType() const override;
|
||||
|
||||
|
||||
@@ -50,7 +50,7 @@ class TorrentCreatorDialog : public QDialog
|
||||
|
||||
public:
|
||||
TorrentCreatorDialog(QWidget *parent = nullptr, const QString &defaultPath = QString());
|
||||
~TorrentCreatorDialog();
|
||||
~TorrentCreatorDialog() override;
|
||||
void updateInputPath(const QString &path);
|
||||
|
||||
private slots:
|
||||
|
||||
@@ -33,6 +33,7 @@
|
||||
#include <QPushButton>
|
||||
|
||||
#include "base/bittorrent/torrenthandle.h"
|
||||
#include "guiiconprovider.h"
|
||||
#include "utils.h"
|
||||
|
||||
TrackerLoginDialog::TrackerLoginDialog(QWidget *parent, BitTorrent::TorrentHandle *const torrent)
|
||||
@@ -44,7 +45,7 @@ TrackerLoginDialog::TrackerLoginDialog(QWidget *parent, BitTorrent::TorrentHandl
|
||||
|
||||
buttonBox->button(QDialogButtonBox::Ok)->setText(tr("Log in"));
|
||||
|
||||
labelLoginLogo->setPixmap(QPixmap(QLatin1String(":/icons/qbt-theme/encrypted.png")));
|
||||
labelLoginLogo->setPixmap(Utils::Gui::scaledPixmap(GuiIconProvider::instance()->getIcon("document-encrypt"), this, 32));
|
||||
|
||||
labelTrackerURL->setText(torrent->currentTracker());
|
||||
|
||||
|
||||
@@ -104,7 +104,7 @@ void TransferListDelegate::paint(QPainter *painter, const QStyleOptionViewItem &
|
||||
break;
|
||||
case TransferListModel::TR_UPSPEED:
|
||||
case TransferListModel::TR_DLSPEED: {
|
||||
const qulonglong speed = index.data().toULongLong();
|
||||
const int speed = index.data().toInt();
|
||||
if (hideValues && !speed)
|
||||
break;
|
||||
opt.displayAlignment = Qt::AlignRight | Qt::AlignVCenter;
|
||||
|
||||
@@ -132,31 +132,31 @@ StatusFilterWidget::StatusFilterWidget(QWidget *parent, TransferListWidget *tran
|
||||
// Add status filters
|
||||
QListWidgetItem *all = new QListWidgetItem(this);
|
||||
all->setData(Qt::DisplayRole, QVariant(tr("All (0)", "this is for the status filter")));
|
||||
all->setData(Qt::DecorationRole, QIcon(":/icons/skin/filterall.png"));
|
||||
all->setData(Qt::DecorationRole, QIcon(":/icons/skin/filterall.svg"));
|
||||
QListWidgetItem *downloading = new QListWidgetItem(this);
|
||||
downloading->setData(Qt::DisplayRole, QVariant(tr("Downloading (0)")));
|
||||
downloading->setData(Qt::DecorationRole, QIcon(":/icons/skin/downloading.png"));
|
||||
downloading->setData(Qt::DecorationRole, QIcon(":/icons/skin/downloading.svg"));
|
||||
QListWidgetItem *seeding = new QListWidgetItem(this);
|
||||
seeding->setData(Qt::DisplayRole, QVariant(tr("Seeding (0)")));
|
||||
seeding->setData(Qt::DecorationRole, QIcon(":/icons/skin/uploading.png"));
|
||||
seeding->setData(Qt::DecorationRole, QIcon(":/icons/skin/uploading.svg"));
|
||||
QListWidgetItem *completed = new QListWidgetItem(this);
|
||||
completed->setData(Qt::DisplayRole, QVariant(tr("Completed (0)")));
|
||||
completed->setData(Qt::DecorationRole, QIcon(":/icons/skin/completed.png"));
|
||||
completed->setData(Qt::DecorationRole, QIcon(":/icons/skin/completed.svg"));
|
||||
QListWidgetItem *resumed = new QListWidgetItem(this);
|
||||
resumed->setData(Qt::DisplayRole, QVariant(tr("Resumed (0)")));
|
||||
resumed->setData(Qt::DecorationRole, QIcon(":/icons/skin/resumed.png"));
|
||||
resumed->setData(Qt::DecorationRole, QIcon(":/icons/skin/resumed.svg"));
|
||||
QListWidgetItem *paused = new QListWidgetItem(this);
|
||||
paused->setData(Qt::DisplayRole, QVariant(tr("Paused (0)")));
|
||||
paused->setData(Qt::DecorationRole, QIcon(":/icons/skin/paused.png"));
|
||||
paused->setData(Qt::DecorationRole, QIcon(":/icons/skin/paused.svg"));
|
||||
QListWidgetItem *active = new QListWidgetItem(this);
|
||||
active->setData(Qt::DisplayRole, QVariant(tr("Active (0)")));
|
||||
active->setData(Qt::DecorationRole, QIcon(":/icons/skin/filteractive.png"));
|
||||
active->setData(Qt::DecorationRole, QIcon(":/icons/skin/filteractive.svg"));
|
||||
QListWidgetItem *inactive = new QListWidgetItem(this);
|
||||
inactive->setData(Qt::DisplayRole, QVariant(tr("Inactive (0)")));
|
||||
inactive->setData(Qt::DecorationRole, QIcon(":/icons/skin/filterinactive.png"));
|
||||
inactive->setData(Qt::DecorationRole, QIcon(":/icons/skin/filterinactive.svg"));
|
||||
QListWidgetItem *errored = new QListWidgetItem(this);
|
||||
errored->setData(Qt::DisplayRole, QVariant(tr("Errored (0)")));
|
||||
errored->setData(Qt::DecorationRole, QIcon(":/icons/skin/error.png"));
|
||||
errored->setData(Qt::DecorationRole, QIcon(":/icons/skin/error.svg"));
|
||||
|
||||
const Preferences *const pref = Preferences::instance();
|
||||
setCurrentRow(pref->getTransSelFilter(), QItemSelectionModel::SelectCurrent);
|
||||
|
||||
@@ -71,7 +71,7 @@ class StatusFilterWidget : public BaseFilterWidget
|
||||
|
||||
public:
|
||||
StatusFilterWidget(QWidget *parent, TransferListWidget *transferList);
|
||||
~StatusFilterWidget();
|
||||
~StatusFilterWidget() override;
|
||||
|
||||
private slots:
|
||||
void updateTorrentNumbers();
|
||||
@@ -91,7 +91,7 @@ class TrackerFiltersList : public BaseFilterWidget
|
||||
|
||||
public:
|
||||
TrackerFiltersList(QWidget *parent, TransferListWidget *transferList);
|
||||
~TrackerFiltersList();
|
||||
~TrackerFiltersList() override;
|
||||
|
||||
// Redefine addItem() to make sure the list stays sorted
|
||||
void addItem(const QString &tracker, const QString &hash);
|
||||
|
||||
@@ -240,8 +240,6 @@ QVariant TransferListModel::data(const QModelIndex &index, int role) const
|
||||
return torrent->timeSinceActivity();
|
||||
case TR_TOTAL_SIZE:
|
||||
return torrent->totalSize();
|
||||
default:
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
return QVariant();
|
||||
@@ -283,7 +281,7 @@ void TransferListModel::addTorrent(BitTorrent::TorrentHandle *const torrent)
|
||||
|
||||
Qt::ItemFlags TransferListModel::flags(const QModelIndex &index) const
|
||||
{
|
||||
if (!index.isValid()) return 0;
|
||||
if (!index.isValid()) return Qt::NoItemFlags;
|
||||
|
||||
// Explicitly mark as editable
|
||||
return QAbstractListModel::flags(index) | Qt::ItemIsEditable;
|
||||
@@ -291,7 +289,7 @@ Qt::ItemFlags TransferListModel::flags(const QModelIndex &index) const
|
||||
|
||||
BitTorrent::TorrentHandle *TransferListModel::torrentHandle(const QModelIndex &index) const
|
||||
{
|
||||
if (!index.isValid()) return 0;
|
||||
if (!index.isValid()) return nullptr;
|
||||
|
||||
return m_torrents.value(index.row());
|
||||
}
|
||||
@@ -419,55 +417,55 @@ QColor getColorByState(BitTorrent::TorrentState state)
|
||||
|
||||
QIcon getPausedIcon()
|
||||
{
|
||||
static QIcon cached = QIcon(":/icons/skin/paused.png");
|
||||
static QIcon cached = QIcon(":/icons/skin/paused.svg");
|
||||
return cached;
|
||||
}
|
||||
|
||||
QIcon getQueuedIcon()
|
||||
{
|
||||
static QIcon cached = QIcon(":/icons/skin/queued.png");
|
||||
static QIcon cached = QIcon(":/icons/skin/queued.svg");
|
||||
return cached;
|
||||
}
|
||||
|
||||
QIcon getDownloadingIcon()
|
||||
{
|
||||
static QIcon cached = QIcon(":/icons/skin/downloading.png");
|
||||
static QIcon cached = QIcon(":/icons/skin/downloading.svg");
|
||||
return cached;
|
||||
}
|
||||
|
||||
QIcon getStalledDownloadingIcon()
|
||||
{
|
||||
static QIcon cached = QIcon(":/icons/skin/stalledDL.png");
|
||||
static QIcon cached = QIcon(":/icons/skin/stalledDL.svg");
|
||||
return cached;
|
||||
}
|
||||
|
||||
QIcon getUploadingIcon()
|
||||
{
|
||||
static QIcon cached = QIcon(":/icons/skin/uploading.png");
|
||||
static QIcon cached = QIcon(":/icons/skin/uploading.svg");
|
||||
return cached;
|
||||
}
|
||||
|
||||
QIcon getStalledUploadingIcon()
|
||||
{
|
||||
static QIcon cached = QIcon(":/icons/skin/stalledUP.png");
|
||||
static QIcon cached = QIcon(":/icons/skin/stalledUP.svg");
|
||||
return cached;
|
||||
}
|
||||
|
||||
QIcon getCompletedIcon()
|
||||
{
|
||||
static QIcon cached = QIcon(":/icons/skin/completed.png");
|
||||
static QIcon cached = QIcon(":/icons/skin/completed.svg");
|
||||
return cached;
|
||||
}
|
||||
|
||||
QIcon getCheckingIcon()
|
||||
{
|
||||
static QIcon cached = QIcon(":/icons/skin/checking.png");
|
||||
static QIcon cached = QIcon(":/icons/skin/checking.svg");
|
||||
return cached;
|
||||
}
|
||||
|
||||
QIcon getErrorIcon()
|
||||
{
|
||||
static QIcon cached = QIcon(":/icons/skin/error.png");
|
||||
static QIcon cached = QIcon(":/icons/skin/error.svg");
|
||||
return cached;
|
||||
}
|
||||
|
||||
|
||||
@@ -183,23 +183,23 @@ bool TransferListSortModel::lessThan(const QModelIndex &left, const QModelIndex
|
||||
}
|
||||
|
||||
case TransferListModel::TR_LAST_ACTIVITY: {
|
||||
const qlonglong vL = left.data().toLongLong();
|
||||
const qlonglong vR = right.data().toLongLong();
|
||||
const int vL = left.data().toInt();
|
||||
const int vR = right.data().toInt();
|
||||
|
||||
if (vL == -1) return false;
|
||||
if (vR == -1) return true;
|
||||
if (vL < 0) return false;
|
||||
if (vR < 0) return true;
|
||||
|
||||
return vL < vR;
|
||||
return (vL < vR);
|
||||
}
|
||||
|
||||
case TransferListModel::TR_RATIO_LIMIT: {
|
||||
const qreal vL = left.data().toDouble();
|
||||
const qreal vR = right.data().toDouble();
|
||||
const qreal vL = left.data().toReal();
|
||||
const qreal vR = right.data().toReal();
|
||||
|
||||
if (vL == -1) return false;
|
||||
if (vR == -1) return true;
|
||||
if (vL < 0) return false;
|
||||
if (vR < 0) return true;
|
||||
|
||||
return vL < vR;
|
||||
return (vL < vR);
|
||||
}
|
||||
|
||||
default: {
|
||||
|
||||
@@ -260,7 +260,7 @@ TransferListWidget::TransferListWidget(QWidget *parent, MainWindow *mainWindow)
|
||||
|
||||
//Ensure that at least one column is visible at all times
|
||||
bool atLeastOne = false;
|
||||
for (unsigned int i = 0; i < TransferListModel::NB_COLUMNS; ++i) {
|
||||
for (int i = 0; i < TransferListModel::NB_COLUMNS; ++i) {
|
||||
if (!isColumnHidden(i)) {
|
||||
atLeastOne = true;
|
||||
break;
|
||||
@@ -272,7 +272,7 @@ TransferListWidget::TransferListWidget(QWidget *parent, MainWindow *mainWindow)
|
||||
//When adding/removing columns between versions some may
|
||||
//end up being size 0 when the new version is launched with
|
||||
//a conf file from the previous version.
|
||||
for (unsigned int i = 0; i < TransferListModel::NB_COLUMNS; ++i)
|
||||
for (int i = 0; i < TransferListModel::NB_COLUMNS; ++i)
|
||||
if ((columnWidth(i) <= 0) && (!isColumnHidden(i)))
|
||||
resizeColumnToContents(i);
|
||||
|
||||
@@ -713,7 +713,7 @@ void TransferListWidget::displayDLHoSMenu(const QPoint&)
|
||||
actions.append(myAct);
|
||||
}
|
||||
int visibleCols = 0;
|
||||
for (unsigned int i = 0; i < TransferListModel::NB_COLUMNS; ++i) {
|
||||
for (int i = 0; i < TransferListModel::NB_COLUMNS; ++i) {
|
||||
if (!isColumnHidden(i))
|
||||
++visibleCols;
|
||||
|
||||
@@ -874,7 +874,7 @@ void TransferListWidget::displayListMenu(const QPoint&)
|
||||
connect(&actionDelete, &QAction::triggered, this, &TransferListWidget::softDeleteSelectedTorrents);
|
||||
QAction actionPreviewFile(GuiIconProvider::instance()->getIcon("view-preview"), tr("Preview file..."), nullptr);
|
||||
connect(&actionPreviewFile, &QAction::triggered, this, &TransferListWidget::previewSelectedTorrents);
|
||||
QAction actionSetMaxRatio(QIcon(QLatin1String(":/icons/skin/ratio.png")), tr("Limit share ratio..."), nullptr);
|
||||
QAction actionSetMaxRatio(QIcon(QLatin1String(":/icons/skin/ratio.svg")), tr("Limit share ratio..."), nullptr);
|
||||
connect(&actionSetMaxRatio, &QAction::triggered, this, &TransferListWidget::setMaxRatioSelectedTorrents);
|
||||
QAction actionSetUploadLimit(GuiIconProvider::instance()->getIcon("kt-set-max-upload-speed"), tr("Limit upload rate..."), nullptr);
|
||||
connect(&actionSetUploadLimit, &QAction::triggered, this, &TransferListWidget::setUpLimitSelectedTorrents);
|
||||
@@ -963,27 +963,23 @@ void TransferListWidget::displayListMenu(const QPoint&)
|
||||
oneHasMetadata = true;
|
||||
if (!torrent->isSeed()) {
|
||||
oneNotSeed = true;
|
||||
if (torrent->hasMetadata()) {
|
||||
if (first) {
|
||||
sequentialDownloadMode = torrent->isSequentialDownload();
|
||||
prioritizeFirstLast = torrent->hasFirstLastPiecePriority();
|
||||
}
|
||||
else {
|
||||
if (sequentialDownloadMode != torrent->isSequentialDownload())
|
||||
allSameSequentialDownloadMode = false;
|
||||
if (prioritizeFirstLast != torrent->hasFirstLastPiecePriority())
|
||||
allSamePrioFirstlast = false;
|
||||
}
|
||||
if (first) {
|
||||
sequentialDownloadMode = torrent->isSequentialDownload();
|
||||
prioritizeFirstLast = torrent->hasFirstLastPiecePriority();
|
||||
}
|
||||
else {
|
||||
if (sequentialDownloadMode != torrent->isSequentialDownload())
|
||||
allSameSequentialDownloadMode = false;
|
||||
if (prioritizeFirstLast != torrent->hasFirstLastPiecePriority())
|
||||
allSamePrioFirstlast = false;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (!oneNotSeed && allSameSuperSeeding && torrent->hasMetadata()) {
|
||||
if (first) {
|
||||
if (first)
|
||||
superSeedingMode = torrent->superSeeding();
|
||||
}
|
||||
else if (superSeedingMode != torrent->superSeeding())
|
||||
allSameSuperSeeding = false;
|
||||
|
||||
}
|
||||
}
|
||||
if (!torrent->isForced())
|
||||
@@ -1082,7 +1078,7 @@ void TransferListWidget::displayListMenu(const QPoint&)
|
||||
listMenu.addAction(&actionPreviewFile);
|
||||
addedPreviewAction = true;
|
||||
}
|
||||
if (oneNotSeed && oneHasMetadata) {
|
||||
if (oneNotSeed) {
|
||||
if (allSameSequentialDownloadMode) {
|
||||
actionSequentialDownload.setChecked(sequentialDownloadMode);
|
||||
listMenu.addAction(&actionSequentialDownload);
|
||||
@@ -1188,7 +1184,7 @@ void TransferListWidget::applyTrackerFilter(const QStringList &hashes)
|
||||
|
||||
void TransferListWidget::applyNameFilter(const QString &name)
|
||||
{
|
||||
const QRegExp::PatternSyntax patternSyntax = Preferences::instance()->getRegexAsFilteringPattern()
|
||||
const QRegExp::PatternSyntax patternSyntax = Preferences::instance()->getRegexAsFilteringPatternForTransferList()
|
||||
? QRegExp::RegExp : QRegExp::WildcardUnix;
|
||||
m_sortFilterModel->setFilterRegExp(QRegExp(name, Qt::CaseInsensitive, patternSyntax));
|
||||
}
|
||||
|
||||
@@ -52,7 +52,7 @@ class TransferListWidget : public QTreeView
|
||||
|
||||
public:
|
||||
TransferListWidget(QWidget *parent, MainWindow *mainWindow);
|
||||
~TransferListWidget();
|
||||
~TransferListWidget() override;
|
||||
TransferListModel *getSourceModel() const;
|
||||
|
||||
public slots:
|
||||
|
||||
@@ -63,6 +63,13 @@ qreal Utils::Gui::screenScalingFactor(const QWidget *widget)
|
||||
#endif // Q_OS_WIN
|
||||
}
|
||||
|
||||
QPixmap Utils::Gui::scaledPixmap(const QIcon &icon, const QWidget *widget, const int height)
|
||||
{
|
||||
Q_ASSERT(height > 0);
|
||||
const int scaledHeight = height * Utils::Gui::screenScalingFactor(widget);
|
||||
return icon.pixmap(scaledHeight);
|
||||
}
|
||||
|
||||
QPixmap Utils::Gui::scaledPixmap(const QString &path, const QWidget *widget, const int height)
|
||||
{
|
||||
const QPixmap pixmap(path);
|
||||
|
||||
@@ -33,6 +33,7 @@
|
||||
#include <QPixmap>
|
||||
#include <QSize>
|
||||
|
||||
class QIcon;
|
||||
class QWidget;
|
||||
|
||||
namespace Utils
|
||||
@@ -48,6 +49,7 @@ namespace Utils
|
||||
return (size * screenScalingFactor(widget));
|
||||
}
|
||||
|
||||
QPixmap scaledPixmap(const QIcon &icon, const QWidget *widget, const int height);
|
||||
QPixmap scaledPixmap(const QString &path, const QWidget *widget, const int height = 0);
|
||||
QPixmap scaledPixmapSvg(const QString &path, const QWidget *widget, const int baseHeight);
|
||||
QSize smallIconSize(const QWidget *widget = nullptr);
|
||||
|
||||
8
src/icons/.svgo.yml
Normal file
@@ -0,0 +1,8 @@
|
||||
# config file for [SVGO](https://github.com/svg/svgo)
|
||||
# SVGO: Node.js tool for optimizing SVG files
|
||||
# svgo --config=<this file> <svg file>
|
||||
|
||||
multipass: true
|
||||
js2svg:
|
||||
pretty: true
|
||||
indent: ' '
|
||||
@@ -251,105 +251,105 @@
|
||||
<file>flags/zw.svg</file>
|
||||
<file>L.gif</file>
|
||||
<file>loading.png</file>
|
||||
<file>qbt-theme/application-exit.png</file>
|
||||
<file>qbt-theme/application-rss+xml.png</file>
|
||||
<file>qbt-theme/application-x-mswinurl.png</file>
|
||||
<file>qbt-theme/checked.png</file>
|
||||
<file>qbt-theme/configure.png</file>
|
||||
<file>qbt-theme/dialog-cancel.png</file>
|
||||
<file>qbt-theme/dialog-information.png</file>
|
||||
<file>qbt-theme/dialog-warning.png</file>
|
||||
<file>qbt-theme/document-edit-verify.png</file>
|
||||
<file>qbt-theme/document-edit.png</file>
|
||||
<file>qbt-theme/document-encrypt.png</file>
|
||||
<file>qbt-theme/document-import.png</file>
|
||||
<file>qbt-theme/document-new.png</file>
|
||||
<file>qbt-theme/document-properties.png</file>
|
||||
<file>qbt-theme/document-save.png</file>
|
||||
<file>qbt-theme/download.png</file>
|
||||
<file>qbt-theme/edit-clear-history.png</file>
|
||||
<file>qbt-theme/edit-clear.png</file>
|
||||
<file>qbt-theme/edit-copy.png</file>
|
||||
<file>qbt-theme/edit-cut.png</file>
|
||||
<file>qbt-theme/edit-delete.png</file>
|
||||
<file>qbt-theme/edit-find-user.png</file>
|
||||
<file>qbt-theme/edit-find.png</file>
|
||||
<file>qbt-theme/edit-paste.png</file>
|
||||
<file>qbt-theme/edit-rename.png</file>
|
||||
<file>qbt-theme/folder-documents.png</file>
|
||||
<file>qbt-theme/folder-download.png</file>
|
||||
<file>qbt-theme/folder-new.png</file>
|
||||
<file>qbt-theme/folder-remote.png</file>
|
||||
<file>qbt-theme/gear.png</file>
|
||||
<file>qbt-theme/gear32.png</file>
|
||||
<file>qbt-theme/go-bottom.png</file>
|
||||
<file>qbt-theme/go-down.png</file>
|
||||
<file>qbt-theme/go-top.png</file>
|
||||
<file>qbt-theme/go-up.png</file>
|
||||
<file>qbt-theme/help-about.png</file>
|
||||
<file>qbt-theme/help-contents.png</file>
|
||||
<file>qbt-theme/inode-directory.png</file>
|
||||
<file>qbt-theme/insert-link.png</file>
|
||||
<file>qbt-theme/application-exit.svg</file>
|
||||
<file>qbt-theme/application-rss+xml.svg</file>
|
||||
<file>qbt-theme/application-x-mswinurl.svg</file>
|
||||
<file>qbt-theme/checked.svg</file>
|
||||
<file>qbt-theme/configure.svg</file>
|
||||
<file>qbt-theme/dialog-cancel.svg</file>
|
||||
<file>qbt-theme/dialog-information.svg</file>
|
||||
<file>qbt-theme/dialog-warning.svg</file>
|
||||
<file>qbt-theme/document-edit-verify.svg</file>
|
||||
<file>qbt-theme/document-edit.svg</file>
|
||||
<file>qbt-theme/document-encrypt.svg</file>
|
||||
<file>qbt-theme/document-import.svg</file>
|
||||
<file>qbt-theme/document-new.svg</file>
|
||||
<file>qbt-theme/document-properties.svg</file>
|
||||
<file>qbt-theme/document-save.svg</file>
|
||||
<file>qbt-theme/download.svg</file>
|
||||
<file>qbt-theme/edit-clear-history.svg</file>
|
||||
<file>qbt-theme/edit-clear.svg</file>
|
||||
<file>qbt-theme/edit-copy.svg</file>
|
||||
<file>qbt-theme/edit-cut.svg</file>
|
||||
<file>qbt-theme/edit-delete.svg</file>
|
||||
<file>qbt-theme/edit-find-user.svg</file>
|
||||
<file>qbt-theme/edit-find.svg</file>
|
||||
<file>qbt-theme/edit-paste.svg</file>
|
||||
<file>qbt-theme/edit-rename.svg</file>
|
||||
<file>qbt-theme/folder-documents.svg</file>
|
||||
<file>qbt-theme/folder-download.svg</file>
|
||||
<file>qbt-theme/folder-new.svg</file>
|
||||
<file>qbt-theme/folder-remote.svg</file>
|
||||
<file>qbt-theme/gear.svg</file>
|
||||
<file>qbt-theme/gear32.svg</file>
|
||||
<file>qbt-theme/go-bottom.svg</file>
|
||||
<file>qbt-theme/go-down.svg</file>
|
||||
<file>qbt-theme/go-top.svg</file>
|
||||
<file>qbt-theme/go-up.svg</file>
|
||||
<file>qbt-theme/help-about.svg</file>
|
||||
<file>qbt-theme/help-contents.svg</file>
|
||||
<file>qbt-theme/inode-directory.svg</file>
|
||||
<file>qbt-theme/insert-link.svg</file>
|
||||
<file>qbt-theme/kt-magnet.png</file>
|
||||
<file>qbt-theme/kt-set-max-download-speed.png</file>
|
||||
<file>qbt-theme/kt-set-max-upload-speed.png</file>
|
||||
<file>qbt-theme/list-add.png</file>
|
||||
<file>qbt-theme/list-remove.png</file>
|
||||
<file>qbt-theme/mail-folder-inbox.png</file>
|
||||
<file>qbt-theme/mail-mark-read.png</file>
|
||||
<file>qbt-theme/media-playback-pause.png</file>
|
||||
<file>qbt-theme/media-playback-start.png</file>
|
||||
<file>qbt-theme/media-seek-forward.png</file>
|
||||
<file>qbt-theme/network-server.png</file>
|
||||
<file>qbt-theme/network-wired.png</file>
|
||||
<file>qbt-theme/object-locked.png</file>
|
||||
<file>qbt-theme/office-chart-line.png</file>
|
||||
<file>qbt-theme/preferences-desktop.png</file>
|
||||
<file>qbt-theme/preferences-other.png</file>
|
||||
<file>qbt-theme/preferences-system-network.png</file>
|
||||
<file>qbt-theme/preferences-web-browser-cookies.png</file>
|
||||
<file>qbt-theme/list-add.svg</file>
|
||||
<file>qbt-theme/list-remove.svg</file>
|
||||
<file>qbt-theme/mail-folder-inbox.svg</file>
|
||||
<file>qbt-theme/mail-mark-read.svg</file>
|
||||
<file>qbt-theme/media-playback-pause.svg</file>
|
||||
<file>qbt-theme/media-playback-start.svg</file>
|
||||
<file>qbt-theme/media-seek-forward.svg</file>
|
||||
<file>qbt-theme/network-server.svg</file>
|
||||
<file>qbt-theme/network-wired.svg</file>
|
||||
<file>qbt-theme/object-locked.svg</file>
|
||||
<file>qbt-theme/office-chart-line.svg</file>
|
||||
<file>qbt-theme/preferences-desktop.svg</file>
|
||||
<file>qbt-theme/preferences-other.svg</file>
|
||||
<file>qbt-theme/preferences-system-network.svg</file>
|
||||
<file>qbt-theme/preferences-web-browser-cookies.svg</file>
|
||||
<file>qbt-theme/rss-config.png</file>
|
||||
<file>qbt-theme/security-high.png</file>
|
||||
<file>qbt-theme/security-low.png</file>
|
||||
<file>qbt-theme/services.png</file>
|
||||
<file>qbt-theme/speedometer.png</file>
|
||||
<file>qbt-theme/system-log-out.png</file>
|
||||
<file>qbt-theme/tab-close.png</file>
|
||||
<file>qbt-theme/task-attention.png</file>
|
||||
<file>qbt-theme/security-high.svg</file>
|
||||
<file>qbt-theme/security-low.svg</file>
|
||||
<file>qbt-theme/services.svg</file>
|
||||
<file>qbt-theme/speedometer.svg</file>
|
||||
<file>qbt-theme/system-log-out.svg</file>
|
||||
<file>qbt-theme/tab-close.svg</file>
|
||||
<file>qbt-theme/task-attention.svg</file>
|
||||
<file>qbt-theme/task-complete.png</file>
|
||||
<file>qbt-theme/task-ongoing.png</file>
|
||||
<file>qbt-theme/task-reject.png</file>
|
||||
<file>qbt-theme/text-plain.png</file>
|
||||
<file>qbt-theme/tools-report-bug.png</file>
|
||||
<file>qbt-theme/unavailable.png</file>
|
||||
<file>qbt-theme/user-group-delete.png</file>
|
||||
<file>qbt-theme/user-group-new.png</file>
|
||||
<file>qbt-theme/view-calendar-journal.png</file>
|
||||
<file>qbt-theme/view-categories.png</file>
|
||||
<file>qbt-theme/view-filter.png</file>
|
||||
<file>qbt-theme/view-preview.png</file>
|
||||
<file>qbt-theme/view-refresh.png</file>
|
||||
<file>qbt-theme/view-statistics.png</file>
|
||||
<file>qbt-theme/wallet-open.png</file>
|
||||
<file>qbt-theme/webui.png</file>
|
||||
<file>qbt-theme/text-plain.svg</file>
|
||||
<file>qbt-theme/tools-report-bug.svg</file>
|
||||
<file>qbt-theme/unavailable.svg</file>
|
||||
<file>qbt-theme/user-group-delete.svg</file>
|
||||
<file>qbt-theme/user-group-new.svg</file>
|
||||
<file>qbt-theme/view-calendar-journal.svg</file>
|
||||
<file>qbt-theme/view-categories.svg</file>
|
||||
<file>qbt-theme/view-filter.svg</file>
|
||||
<file>qbt-theme/view-preview.svg</file>
|
||||
<file>qbt-theme/view-refresh.svg</file>
|
||||
<file>qbt-theme/view-statistics.svg</file>
|
||||
<file>qbt-theme/wallet-open.svg</file>
|
||||
<file>qbt-theme/webui.svg</file>
|
||||
<file>skin/arrow-right.gif</file>
|
||||
<file>skin/bg-dropdown.gif</file>
|
||||
<file>skin/bg-handle-horizontal.gif</file>
|
||||
<file>skin/bg-header.gif</file>
|
||||
<file>skin/bg-panel-header.gif</file>
|
||||
<file>skin/checking.png</file>
|
||||
<file>skin/checking.svg</file>
|
||||
<file>skin/collapse-expand.gif</file>
|
||||
<file>skin/completed.png</file>
|
||||
<file>skin/connected.png</file>
|
||||
<file>skin/disconnected.png</file>
|
||||
<file>skin/completed.svg</file>
|
||||
<file>skin/connected.svg</file>
|
||||
<file>skin/disconnected.svg</file>
|
||||
<file>skin/dock-tabs.gif</file>
|
||||
<file>skin/download.png</file>
|
||||
<file>skin/downloading.png</file>
|
||||
<file>skin/error.png</file>
|
||||
<file>skin/filteractive.png</file>
|
||||
<file>skin/filterall.png</file>
|
||||
<file>skin/filterinactive.png</file>
|
||||
<file>skin/firewalled.png</file>
|
||||
<file>skin/download.svg</file>
|
||||
<file>skin/downloading.svg</file>
|
||||
<file>skin/error.svg</file>
|
||||
<file>skin/filteractive.svg</file>
|
||||
<file>skin/filterall.svg</file>
|
||||
<file>skin/filterinactive.svg</file>
|
||||
<file>skin/firewalled.svg</file>
|
||||
<file>skin/handle-icon-horizontal.gif</file>
|
||||
<file>skin/handle-icon.gif</file>
|
||||
<file>skin/knob.gif</file>
|
||||
@@ -357,26 +357,26 @@
|
||||
<file>skin/logo.gif</file>
|
||||
<file>skin/logo2.gif</file>
|
||||
<file>skin/mascot.png</file>
|
||||
<file>skin/paused.png</file>
|
||||
<file>skin/paused.svg</file>
|
||||
<file>skin/qbittorrent-tray.svg</file>
|
||||
<file>skin/qbittorrent-tray-dark.svg</file>
|
||||
<file>skin/qbittorrent-tray-light.svg</file>
|
||||
<file>skin/qbittorrent32.png</file>
|
||||
<file>skin/queued.png</file>
|
||||
<file>skin/ratio.png</file>
|
||||
<file>skin/resumed.png</file>
|
||||
<file>skin/seeding.png</file>
|
||||
<file>skin/queued.svg</file>
|
||||
<file>skin/ratio.svg</file>
|
||||
<file>skin/resumed.svg</file>
|
||||
<file>skin/seeding.svg</file>
|
||||
<file>skin/slider-area.gif</file>
|
||||
<file>skin/spacer.gif</file>
|
||||
<file>skin/spinner-placeholder.gif</file>
|
||||
<file>skin/spinner.gif</file>
|
||||
<file>skin/splash.png</file>
|
||||
<file>skin/stalledDL.png</file>
|
||||
<file>skin/stalledUP.png</file>
|
||||
<file>skin/stalledDL.svg</file>
|
||||
<file>skin/stalledUP.svg</file>
|
||||
<file>skin/tabs.gif</file>
|
||||
<file>skin/toolbox-divider.gif</file>
|
||||
<file>skin/toolbox-divider2.gif</file>
|
||||
<file>skin/uploading.png</file>
|
||||
<file>skin/uploading.svg</file>
|
||||
<file>slow.png</file>
|
||||
<file>slow_off.png</file>
|
||||
<file>sphere.png</file>
|
||||
|
||||
|
Before Width: | Height: | Size: 2.7 KiB |
|
Before Width: | Height: | Size: 478 B After Width: | Height: | Size: 478 B |
|
Before Width: | Height: | Size: 3.5 KiB |
|
Before Width: | Height: | Size: 878 B After Width: | Height: | Size: 878 B |
|
Before Width: | Height: | Size: 4.9 KiB |
|
Before Width: | Height: | Size: 4.2 KiB After Width: | Height: | Size: 4.2 KiB |
|
Before Width: | Height: | Size: 1.4 KiB |
|
Before Width: | Height: | Size: 338 B After Width: | Height: | Size: 338 B |
|
Before Width: | Height: | Size: 3.0 KiB |
|
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 1.3 KiB |
|
Before Width: | Height: | Size: 4.0 KiB |
|
Before Width: | Height: | Size: 663 B After Width: | Height: | Size: 663 B |
|
Before Width: | Height: | Size: 3.2 KiB |
|
Before Width: | Height: | Size: 796 B After Width: | Height: | Size: 796 B |
|
Before Width: | Height: | Size: 2.8 KiB |
|
Before Width: | Height: | Size: 585 B After Width: | Height: | Size: 585 B |
|
Before Width: | Height: | Size: 3.0 KiB |
|
Before Width: | Height: | Size: 1013 B After Width: | Height: | Size: 1013 B |
|
Before Width: | Height: | Size: 2.0 KiB |
|
Before Width: | Height: | Size: 801 B After Width: | Height: | Size: 801 B |
|
Before Width: | Height: | Size: 2.3 KiB |
|
Before Width: | Height: | Size: 453 B After Width: | Height: | Size: 453 B |
|
Before Width: | Height: | Size: 2.0 KiB |
|
Before Width: | Height: | Size: 817 B After Width: | Height: | Size: 817 B |
|
Before Width: | Height: | Size: 1.8 KiB |
|
Before Width: | Height: | Size: 824 B After Width: | Height: | Size: 824 B |
|
Before Width: | Height: | Size: 2.9 KiB |
|
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 1.4 KiB |
|
Before Width: | Height: | Size: 1.8 KiB |
|
Before Width: | Height: | Size: 732 B After Width: | Height: | Size: 732 B |
|
Before Width: | Height: | Size: 2.0 KiB |
|
Before Width: | Height: | Size: 711 B After Width: | Height: | Size: 711 B |
|
Before Width: | Height: | Size: 3.9 KiB |
|
Before Width: | Height: | Size: 1.6 KiB After Width: | Height: | Size: 1.6 KiB |
|
Before Width: | Height: | Size: 3.6 KiB |
|
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 1.4 KiB |