diff --git a/.appveyor.yml b/.appveyor.yml index 075bb7f5d..744bb9eb7 100644 --- a/.appveyor.yml +++ b/.appveyor.yml @@ -43,7 +43,7 @@ install: before_build: # setup env - CALL "C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Auxiliary\Build\vcvars64.bat" - - SET PATH=%PATH%;c:\qbt\qt5_64\bin;%CACHE_DIR%\jom; + - SET PATH=%PATH%;C:\Qt\5.15.2\msvc2019_64\bin;%CACHE_DIR%\jom # setup project - COPY /Y "%CACHE_DIR%\conf.pri" "%REPO_DIR%" # workarounds diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 60574f109..b600d5052 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -42,12 +42,12 @@ jobs: libboost-dev libboost-chrono-dev libboost-random-dev libboost-system-dev # sudo apt install libqt5svg5-dev qtbase5-dev qttools5-dev # the Qt version in the standard repositories is too old... - # this will be installed under /opt/qt514. CMake will still find it automatically without additional hints - # to speed up the process, only the required components are installed rather than the full qt514-meta-full metapackage - - name: install Qt 5.14.2 from an external PPA + # this will be installed under /opt/qt515. CMake will still find it automatically without additional hints + # to speed up the process, only the required components are installed rather than the full qt515-meta-full metapackage + - name: install Qt 5.15.2 from an external PPA run: | - sudo add-apt-repository ppa:beineri/opt-qt-5.14.2-focal - sudo apt install qt514base qt514svg qt514tools + sudo add-apt-repository ppa:beineri/opt-qt-5.15.2-focal + sudo apt install qt515base qt515svg qt515tools - name: install libtorrent from source run: | diff --git a/CMakeLists.txt b/CMakeLists.txt index f390c33f4..aa9fdefcf 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -12,7 +12,7 @@ project(qBittorrent set(CMAKE_FIND_PACKAGE_PREFER_CONFIG ON) # version requirements - older vesions may work, but you are on your own set(minBoostVersion 1.65) -set(minQtVersion 5.14) +set(minQtVersion 5.15.2) set(minOpenSSLVersion 1.1.1) set(minLibtorrentVersion 1.2.14) set(minZlibVersion 1.2.11) diff --git a/INSTALL b/INSTALL index 6c6b7a3c1..79639b390 100644 --- a/INSTALL +++ b/INSTALL @@ -11,7 +11,7 @@ qBittorrent - A BitTorrent client in C++ / Qt - OpenSSL >= 1.1.1 - - Qt >= 5.14 + - Qt >= 5.15.2 - zlib >= 1.2.11 diff --git a/cmake/Modules/MacroQbtCommonConfig.cmake b/cmake/Modules/MacroQbtCommonConfig.cmake index ba442233f..391395bda 100644 --- a/cmake/Modules/MacroQbtCommonConfig.cmake +++ b/cmake/Modules/MacroQbtCommonConfig.cmake @@ -17,7 +17,7 @@ macro(qbt_common_config) ) target_compile_definitions(qbt_common_cfg INTERFACE - QT_DISABLE_DEPRECATED_BEFORE=0x050e00 + QT_DISABLE_DEPRECATED_BEFORE=0x050f02 QT_NO_CAST_TO_ASCII QT_NO_CAST_FROM_BYTEARRAY QT_USE_QSTRINGBUILDER diff --git a/configure b/configure index 2d4980fcd..91fa2a986 100755 --- a/configure +++ b/configure @@ -1450,7 +1450,7 @@ Some influential environment variables: directories to add to pkg-config's search path PKG_CONFIG_LIBDIR path overriding pkg-config's built-in search path - QT_QMAKE value of host_bins for Qt5Core >= 5.14, overriding pkg-config + QT_QMAKE value of host_bins for Qt5Core >= 5.15.2, overriding pkg-config Qt5Svg_CFLAGS C compiler flags for Qt5Svg, overriding pkg-config Qt5Svg_LIBS linker flags for Qt5Svg, overriding pkg-config @@ -5456,8 +5456,8 @@ printf "%s\n" "$enable_webui" >&6; } esac if test -n "$PKG_CONFIG" && \ - { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"Qt5Core >= 5.14\""; } >&5 - ($PKG_CONFIG --exists --print-errors "Qt5Core >= 5.14") 2>&5 + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"Qt5Core >= 5.15.2\""; } >&5 + ($PKG_CONFIG --exists --print-errors "Qt5Core >= 5.15.2") 2>&5 ac_status=$? printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then @@ -5466,12 +5466,12 @@ if test -n "$QT_QMAKE"; then pkg_cv_QT_QMAKE="$QT_QMAKE" elif test -n "$PKG_CONFIG"; then if test -n "$PKG_CONFIG" && \ - { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"Qt5Core >= 5.14\""; } >&5 - ($PKG_CONFIG --exists --print-errors "Qt5Core >= 5.14") 2>&5 + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"Qt5Core >= 5.15.2\""; } >&5 + ($PKG_CONFIG --exists --print-errors "Qt5Core >= 5.15.2") 2>&5 ac_status=$? printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then - pkg_cv_QT_QMAKE=`$PKG_CONFIG --variable="host_bins" "Qt5Core >= 5.14" 2>/dev/null` + pkg_cv_QT_QMAKE=`$PKG_CONFIG --variable="host_bins" "Qt5Core >= 5.15.2" 2>/dev/null` test "x$?" != "x0" && pkg_failed=yes else pkg_failed=yes @@ -5501,8 +5501,8 @@ fi fi -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for Qt5 qmake >= 5.14" >&5 -printf %s "checking for Qt5 qmake >= 5.14... " >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for Qt5 qmake >= 5.15.2" >&5 +printf %s "checking for Qt5 qmake >= 5.15.2... " >&6; } if test "x$QT_QMAKE" != "x" then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $QT_QMAKE" >&5 @@ -5529,12 +5529,12 @@ if test -n "$Qt5Svg_CFLAGS"; then pkg_cv_Qt5Svg_CFLAGS="$Qt5Svg_CFLAGS" elif test -n "$PKG_CONFIG"; then if test -n "$PKG_CONFIG" && \ - { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"Qt5Svg >= 5.14\""; } >&5 - ($PKG_CONFIG --exists --print-errors "Qt5Svg >= 5.14") 2>&5 + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"Qt5Svg >= 5.15.2\""; } >&5 + ($PKG_CONFIG --exists --print-errors "Qt5Svg >= 5.15.2") 2>&5 ac_status=$? printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then - pkg_cv_Qt5Svg_CFLAGS=`$PKG_CONFIG --cflags "Qt5Svg >= 5.14" 2>/dev/null` + pkg_cv_Qt5Svg_CFLAGS=`$PKG_CONFIG --cflags "Qt5Svg >= 5.15.2" 2>/dev/null` test "x$?" != "x0" && pkg_failed=yes else pkg_failed=yes @@ -5546,12 +5546,12 @@ if test -n "$Qt5Svg_LIBS"; then pkg_cv_Qt5Svg_LIBS="$Qt5Svg_LIBS" elif test -n "$PKG_CONFIG"; then if test -n "$PKG_CONFIG" && \ - { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"Qt5Svg >= 5.14\""; } >&5 - ($PKG_CONFIG --exists --print-errors "Qt5Svg >= 5.14") 2>&5 + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"Qt5Svg >= 5.15.2\""; } >&5 + ($PKG_CONFIG --exists --print-errors "Qt5Svg >= 5.15.2") 2>&5 ac_status=$? printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then - pkg_cv_Qt5Svg_LIBS=`$PKG_CONFIG --libs "Qt5Svg >= 5.14" 2>/dev/null` + pkg_cv_Qt5Svg_LIBS=`$PKG_CONFIG --libs "Qt5Svg >= 5.15.2" 2>/dev/null` test "x$?" != "x0" && pkg_failed=yes else pkg_failed=yes @@ -5572,14 +5572,14 @@ else _pkg_short_errors_supported=no fi if test $_pkg_short_errors_supported = yes; then - Qt5Svg_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "Qt5Svg >= 5.14" 2>&1` + Qt5Svg_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "Qt5Svg >= 5.15.2" 2>&1` else - Qt5Svg_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "Qt5Svg >= 5.14" 2>&1` + Qt5Svg_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "Qt5Svg >= 5.15.2" 2>&1` fi # Put the nasty error message in config.log where it belongs echo "$Qt5Svg_PKG_ERRORS" >&5 - as_fn_error $? "Package requirements (Qt5Svg >= 5.14) were not met: + as_fn_error $? "Package requirements (Qt5Svg >= 5.15.2) were not met: $Qt5Svg_PKG_ERRORS @@ -5619,11 +5619,11 @@ case "x$enable_qt_dbus" in #( "xyes") : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for Qt5DBus >= 5.14" >&5 -printf %s "checking for Qt5DBus >= 5.14... " >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for Qt5DBus >= 5.15.2" >&5 +printf %s "checking for Qt5DBus >= 5.15.2... " >&6; } if test -n "$PKG_CONFIG" && \ - { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"Qt5DBus >= 5.14\""; } >&5 - ($PKG_CONFIG --exists --print-errors "Qt5DBus >= 5.14") 2>&5 + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"Qt5DBus >= 5.15.2\""; } >&5 + ($PKG_CONFIG --exists --print-errors "Qt5DBus >= 5.15.2") 2>&5 ac_status=$? printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then diff --git a/configure.ac b/configure.ac index 8f2064243..5c63b1df0 100644 --- a/configure.ac +++ b/configure.ac @@ -1,3 +1,4 @@ + AC_INIT([qbittorrent], [v4.4.0alpha], [bugs.qbittorrent.org], [], [https://www.qbittorrent.org/]) AC_CONFIG_AUX_DIR([build-aux]) AC_CONFIG_MACRO_DIR([m4]) @@ -141,7 +142,7 @@ AS_IF([test "x$QT_QMAKE" = "x"], [AC_MSG_ERROR([Could not find qmake]) ]) AS_IF([test "x$enable_gui" = "xyes"], - [PKG_CHECK_MODULES(Qt5Svg, [Qt5Svg >= 5.14]) + [PKG_CHECK_MODULES(Qt5Svg, [Qt5Svg >= 5.15.2]) ]) AC_MSG_CHECKING([whether QtDBus should be enabled]) AS_CASE(["x$enable_qt_dbus"], diff --git a/m4/qbittorrent.m4 b/m4/qbittorrent.m4 index 56bdadaaa..e67f93544 100644 --- a/m4/qbittorrent.m4 +++ b/m4/qbittorrent.m4 @@ -5,9 +5,9 @@ # Sets the QT_QMAKE variable to the path of Qt5 qmake if found. # -------------------------------------- AC_DEFUN([FIND_QT5], -[PKG_CHECK_EXISTS([Qt5Core >= 5.14], +[PKG_CHECK_EXISTS([Qt5Core >= 5.15.2], [PKG_CHECK_VAR(QT_QMAKE, - [Qt5Core >= 5.14], + [Qt5Core >= 5.15.2], [host_bins]) ]) @@ -18,7 +18,7 @@ AS_IF([test -f "$QT_QMAKE/qmake"], [QT_QMAKE=""]) ]) -AC_MSG_CHECKING([for Qt5 qmake >= 5.14]) +AC_MSG_CHECKING([for Qt5 qmake >= 5.15.2]) AS_IF([test "x$QT_QMAKE" != "x"], [AC_MSG_RESULT([$QT_QMAKE])], [AC_MSG_RESULT([not found])] @@ -29,8 +29,8 @@ AS_IF([test "x$QT_QMAKE" != "x"], # Sets the HAVE_QTDBUS variable to true or false. # -------------------------------------- AC_DEFUN([FIND_QTDBUS], - [AC_MSG_CHECKING([for Qt5DBus >= 5.14]) - PKG_CHECK_EXISTS([Qt5DBus >= 5.14], + [AC_MSG_CHECKING([for Qt5DBus >= 5.15.2]) + PKG_CHECK_EXISTS([Qt5DBus >= 5.15.2], [AC_MSG_RESULT([found]) HAVE_QTDBUS=[true]], [AC_MSG_RESULT([not found]) diff --git a/src/app/application.cpp b/src/app/application.cpp index d89a51719..e87485751 100644 --- a/src/app/application.cpp +++ b/src/app/application.cpp @@ -435,16 +435,12 @@ void Application::runExternalProgram(const BitTorrent::Torrent *torrent) const // enable command injection via torrent name and other arguments // (especially when some automated download mechanism has been setup). // See: https://github.com/qbittorrent/qBittorrent/issues/10925 -#if (QT_VERSION >= QT_VERSION_CHECK(5, 15, 0)) QStringList args = QProcess::splitCommand(program); if (args.isEmpty()) return; const QString command = args.takeFirst(); QProcess::startDetached(command, args); -#else - QProcess::startDetached(program); -#endif #endif } @@ -565,7 +561,7 @@ void Application::processParams(const QStringList ¶ms) if (param.startsWith(QLatin1String("@addPaused="))) { - torrentParams.addPaused = (param.midRef(11).toInt() != 0); + torrentParams.addPaused = (QStringView(param).mid(11).toInt() != 0); continue; } @@ -595,7 +591,7 @@ void Application::processParams(const QStringList ¶ms) if (param.startsWith(QLatin1String("@skipDialog="))) { - skipTorrentDialog = (param.midRef(12).toInt() != 0); + skipTorrentDialog = (QStringView(param).mid(12).toInt() != 0); continue; } diff --git a/src/base/bittorrent/peeraddress.cpp b/src/base/bittorrent/peeraddress.cpp index 79ba90ee9..ebe73d637 100644 --- a/src/base/bittorrent/peeraddress.cpp +++ b/src/base/bittorrent/peeraddress.cpp @@ -32,18 +32,18 @@ using namespace BitTorrent; -PeerAddress PeerAddress::parse(const QString &address) +PeerAddress PeerAddress::parse(const QStringView address) { - QVector ipPort; + QList ipPort; - if (address.startsWith('[') && address.contains("]:")) + if (address.startsWith(u'[') && address.contains(QLatin1String("]:"))) { // IPv6 - ipPort = address.splitRef("]:"); + ipPort = address.split(QString::fromLatin1("]:")); ipPort[0] = ipPort[0].mid(1); // chop '[' } - else if (address.contains(':')) + else if (address.contains(u':')) { // IPv4 - ipPort = address.splitRef(':'); + ipPort = address.split(u':'); } else { diff --git a/src/base/bittorrent/peeraddress.h b/src/base/bittorrent/peeraddress.h index 142cf048f..3d7e5b391 100644 --- a/src/base/bittorrent/peeraddress.h +++ b/src/base/bittorrent/peeraddress.h @@ -39,7 +39,7 @@ namespace BitTorrent QHostAddress ip; ushort port = 0; - static PeerAddress parse(const QString &address); + static PeerAddress parse(QStringView address); QString toString() const; }; diff --git a/src/base/bittorrent/session.cpp b/src/base/bittorrent/session.cpp index f2a58f6db..aebb53d54 100644 --- a/src/base/bittorrent/session.cpp +++ b/src/base/bittorrent/session.cpp @@ -1590,7 +1590,7 @@ void Session::populateAdditionalTrackers() m_additionalTrackerList.clear(); const QString trackers = additionalTrackers(); - for (QStringRef tracker : asConst(trackers.splitRef('\n'))) + for (QStringView tracker : asConst(QStringView(trackers).split(u'\n'))) { tracker = tracker.trimmed(); if (!tracker.isEmpty()) diff --git a/src/base/bittorrent/torrentimpl.cpp b/src/base/bittorrent/torrentimpl.cpp index ed6d5ba9d..16670688b 100644 --- a/src/base/bittorrent/torrentimpl.cpp +++ b/src/base/bittorrent/torrentimpl.cpp @@ -1868,9 +1868,9 @@ void TorrentImpl::handleFileRenamedAlert(const lt::file_renamed_alert *p) if (m_oldPath[p->index].isEmpty()) m_oldPath.remove(p->index); - QVector oldPathParts = oldFilePath.splitRef('/', Qt::SkipEmptyParts); + QList oldPathParts = QStringView(oldFilePath).split('/', Qt::SkipEmptyParts); oldPathParts.removeLast(); // drop file name part - QVector newPathParts = newFilePath.splitRef('/', Qt::SkipEmptyParts); + QList newPathParts = QStringView(newFilePath).split('/', Qt::SkipEmptyParts); newPathParts.removeLast(); // drop file name part #if defined(Q_OS_WIN) @@ -1889,7 +1889,7 @@ void TorrentImpl::handleFileRenamedAlert(const lt::file_renamed_alert *p) for (int i = (oldPathParts.size() - 1); i >= pathIdx; --i) { - QDir().rmdir(savePath() + Utils::String::join(oldPathParts, QLatin1String("/"))); + QDir().rmdir(savePath() + Utils::String::join(oldPathParts, QString::fromLatin1("/"))); oldPathParts.removeLast(); } diff --git a/src/base/bittorrent/torrentinfo.cpp b/src/base/bittorrent/torrentinfo.cpp index 00e18de6c..e1805026f 100644 --- a/src/base/bittorrent/torrentinfo.cpp +++ b/src/base/bittorrent/torrentinfo.cpp @@ -61,7 +61,7 @@ namespace { if (QDir::isAbsolutePath(filePath)) continue; - const auto filePathElements = filePath.splitRef('/'); + const auto filePathElements = QStringView(filePath).split(u'/'); // if at least one file has no root folder, no common root folder exists if (filePathElements.count() <= 1) return {}; diff --git a/src/base/http/connection.cpp b/src/base/http/connection.cpp index a27b68a1f..0dc5a8b98 100644 --- a/src/base/http/connection.cpp +++ b/src/base/http/connection.cpp @@ -137,9 +137,9 @@ bool Connection::acceptsGzipEncoding(QString codings) { // [rfc7231] 5.3.4. Accept-Encoding - const auto isCodingAvailable = [](const QVector &list, const QString &encoding) -> bool + const auto isCodingAvailable = [](const QList &list, const QStringView encoding) -> bool { - for (const QStringRef &str : list) + for (const QStringView &str : list) { if (!str.startsWith(encoding)) continue; @@ -149,7 +149,7 @@ bool Connection::acceptsGzipEncoding(QString codings) return true; // [rfc7231] 5.3.1. Quality Values - const QStringRef substr = str.mid(encoding.size() + 3); // ex. skip over "gzip;q=" + const QStringView substr = str.mid(encoding.size() + 3); // ex. skip over "gzip;q=" bool ok = false; const double qvalue = substr.toDouble(&ok); @@ -161,15 +161,15 @@ bool Connection::acceptsGzipEncoding(QString codings) return false; }; - const QVector list = codings.remove(' ').remove('\t').splitRef(',', Qt::SkipEmptyParts); + const QList list = QStringView(codings.remove(' ').remove('\t')).split(u',', Qt::SkipEmptyParts); if (list.isEmpty()) return false; - const bool canGzip = isCodingAvailable(list, QLatin1String("gzip")); + const bool canGzip = isCodingAvailable(list, QString::fromLatin1("gzip")); if (canGzip) return true; - const bool canAny = isCodingAvailable(list, QLatin1String("*")); + const bool canAny = isCodingAvailable(list, QString::fromLatin1("*")); if (canAny) return true; diff --git a/src/base/http/requestparser.cpp b/src/base/http/requestparser.cpp index 284783c3f..7f8af9a66 100644 --- a/src/base/http/requestparser.cpp +++ b/src/base/http/requestparser.cpp @@ -57,7 +57,7 @@ namespace return in; } - bool parseHeaderLine(const QString &line, HeaderMap &out) + bool parseHeaderLine(const QStringView line, HeaderMap &out) { // [rfc7230] 3.2. Header Fields const int i = line.indexOf(':'); @@ -67,8 +67,8 @@ namespace return false; } - const QString name = line.leftRef(i).trimmed().toString().toLower(); - const QString value = line.midRef(i + 1).trimmed().toString(); + const QString name = line.left(i).trimmed().toString().toLower(); + const QString value = line.mid(i + 1).trimmed().toString(); out[name] = value; return true; @@ -145,10 +145,10 @@ RequestParser::ParseResult RequestParser::doParse(const QByteArray &data) return {ParseStatus::BadRequest, Request(), 0}; // TODO: SHOULD respond "501 Not Implemented" } -bool RequestParser::parseStartLines(const QString &data) +bool RequestParser::parseStartLines(const QStringView data) { // we don't handle malformed request which uses `LF` for newline - const QVector lines = data.splitRef(CRLF, Qt::SkipEmptyParts); + const QList lines = data.split(QString::fromLatin1(CRLF), Qt::SkipEmptyParts); // [rfc7230] 3.2.2. Field Order QStringList requestLines; @@ -267,7 +267,7 @@ bool RequestParser::parsePostMessage(const QByteArray &data) return false; } - const QByteArray delimiter = Utils::String::unquote(contentType.midRef(idx + boundaryFieldName.size())).toLatin1(); + const QByteArray delimiter = Utils::String::unquote(QStringView(contentType).mid(idx + boundaryFieldName.size())).toLatin1(); if (delimiter.isEmpty()) { qWarning() << Q_FUNC_INFO << "boundary delimiter field empty!"; @@ -311,13 +311,13 @@ bool RequestParser::parseFormData(const QByteArray &data) const QByteArray payload = viewWithoutEndingWith(list[1], CRLF); HeaderMap headersMap; - const QVector headerLines = headers.splitRef(CRLF, Qt::SkipEmptyParts); + const QList headerLines = QStringView(headers).split(QString::fromLatin1(CRLF), Qt::SkipEmptyParts); for (const auto &line : headerLines) { - if (line.trimmed().startsWith(HEADER_CONTENT_DISPOSITION, Qt::CaseInsensitive)) + if (line.trimmed().startsWith(QString::fromLatin1(HEADER_CONTENT_DISPOSITION), Qt::CaseInsensitive)) { // extract out filename & name - const QVector directives = line.split(';', Qt::SkipEmptyParts); + const QList directives = line.split(u';', Qt::SkipEmptyParts); for (const auto &directive : directives) { diff --git a/src/base/http/requestparser.h b/src/base/http/requestparser.h index cf510165e..b9eb7cdfa 100644 --- a/src/base/http/requestparser.h +++ b/src/base/http/requestparser.h @@ -60,7 +60,7 @@ namespace Http RequestParser(); ParseResult doParse(const QByteArray &data); - bool parseStartLines(const QString &data); + bool parseStartLines(QStringView data); bool parseRequestLine(const QString &line); bool parsePostMessage(const QByteArray &data); diff --git a/src/base/net/smtp.cpp b/src/base/net/smtp.cpp index df5f157f0..0c4ed4e69 100644 --- a/src/base/net/smtp.cpp +++ b/src/base/net/smtp.cpp @@ -122,12 +122,7 @@ Smtp::Smtp(QObject *parent) connect(m_socket, &QIODevice::readyRead, this, &Smtp::readyRead); connect(m_socket, &QAbstractSocket::disconnected, this, &QObject::deleteLater); -#if (QT_VERSION >= QT_VERSION_CHECK(5, 15, 0)) connect(m_socket, &QAbstractSocket::errorOccurred, this, &Smtp::error); -#else - connect(m_socket, qOverload(&QAbstractSocket::error) - , this, &Smtp::error); -#endif // Test hmacMD5 function (http://www.faqs.org/rfcs/rfc2202.html) Q_ASSERT(hmacMD5("Jefe", "what do ya want for nothing?").toHex() diff --git a/src/base/rss/rss_autodownloadrule.cpp b/src/base/rss/rss_autodownloadrule.cpp index 3c701ba91..ecc6b08fd 100644 --- a/src/base/rss/rss_autodownloadrule.cpp +++ b/src/base/rss/rss_autodownloadrule.cpp @@ -325,7 +325,7 @@ bool AutoDownloadRule::matchesEpisodeFilterExpression(const QString &articleTitl if (episode.endsWith('-')) { // Infinite range - const int episodeOurs {episode.leftRef(episode.size() - 1).toInt()}; + const int episodeOurs {QStringView(episode).left(episode.size() - 1).toInt()}; if (((seasonTheirs == seasonOurs) && (episodeTheirs >= episodeOurs)) || (seasonTheirs > seasonOurs)) return true; } diff --git a/src/base/search/searchdownloadhandler.cpp b/src/base/search/searchdownloadhandler.cpp index 8fd823c0d..2d781ff7a 100644 --- a/src/base/search/searchdownloadhandler.cpp +++ b/src/base/search/searchdownloadhandler.cpp @@ -59,7 +59,7 @@ void SearchDownloadHandler::downloadProcessFinished(int exitcode) if ((exitcode == 0) && (m_downloadProcess->exitStatus() == QProcess::NormalExit)) { const QString line = QString::fromUtf8(m_downloadProcess->readAllStandardOutput()).trimmed(); - const QVector parts = line.splitRef(' '); + const QList parts = QStringView(line).split(u' '); if (parts.size() == 2) path = parts[0].toString(); } diff --git a/src/base/search/searchhandler.cpp b/src/base/search/searchhandler.cpp index 6438f0cc9..7aec0d84d 100644 --- a/src/base/search/searchhandler.cpp +++ b/src/base/search/searchhandler.cpp @@ -163,9 +163,9 @@ void SearchHandler::processFailed() // Parse one line of search results list // Line is in the following form: // file url | file name | file size | nb seeds | nb leechers | Search engine url -bool SearchHandler::parseSearchResult(const QString &line, SearchResult &searchResult) +bool SearchHandler::parseSearchResult(const QStringView line, SearchResult &searchResult) { - const QVector parts = line.splitRef('|'); + const QList parts = line.split(u'|'); const int nbFields = parts.size(); if (nbFields < (NB_PLUGIN_COLUMNS - 1)) return false; // -1 because desc_link is optional diff --git a/src/base/search/searchhandler.h b/src/base/search/searchhandler.h index 981dae502..2f42b1bca 100644 --- a/src/base/search/searchhandler.h +++ b/src/base/search/searchhandler.h @@ -78,7 +78,7 @@ private: void readSearchOutput(); void processFailed(); void processFinished(int exitcode); - bool parseSearchResult(const QString &line, SearchResult &searchResult); + bool parseSearchResult(QStringView line, SearchResult &searchResult); const QString m_pattern; const QString m_category; diff --git a/src/base/utils/bytearray.h b/src/base/utils/bytearray.h index 2b49f2082..c3d959b4c 100644 --- a/src/base/utils/bytearray.h +++ b/src/base/utils/bytearray.h @@ -28,14 +28,14 @@ #pragma once -#include +#include #include class QByteArray; namespace Utils::ByteArray { - // Mimic QString::splitRef(sep, behavior) + // Mimic QStringView(in).split(sep, behavior) QVector splitToViews(const QByteArray &in, const QByteArray &sep, const Qt::SplitBehavior behavior = Qt::KeepEmptyParts); // Mimic QByteArray::mid(pos, len) but instead of returning a full-copy, diff --git a/src/base/utils/compare.cpp b/src/base/utils/compare.cpp index 343ff01f5..536dd147c 100644 --- a/src/base/utils/compare.cpp +++ b/src/base/utils/compare.cpp @@ -60,16 +60,16 @@ int Utils::Compare::naturalCompare(const QString &left, const QString &right, co { // Both are digits, compare the numbers - const auto numberView = [](const QString &str, int &pos) -> QStringRef + const auto numberView = [](const QStringView str, int &pos) -> QStringView { const int start = pos; while ((pos < str.size()) && str[pos].isDigit()) ++pos; - return str.midRef(start, (pos - start)); + return str.mid(start, (pos - start)); }; - const QStringRef numViewL = numberView(left, posL); - const QStringRef numViewR = numberView(right, posR); + const QStringView numViewL = numberView(left, posL); + const QStringView numViewR = numberView(right, posR); if (numViewL.length() != numViewR.length()) return (numViewL.length() - numViewR.length()); diff --git a/src/base/utils/misc.cpp b/src/base/utils/misc.cpp index e560f9e75..71c334d43 100644 --- a/src/base/utils/misc.cpp +++ b/src/base/utils/misc.cpp @@ -498,7 +498,7 @@ QString Utils::Misc::opensslVersionString() #else static const auto version {QString::fromLatin1(SSLeay_version(SSLEAY_VERSION))}; #endif - return version.splitRef(' ', Qt::SkipEmptyParts)[1].toString(); + return QStringView(version).split(u' ', Qt::SkipEmptyParts)[1].toString(); } QString Utils::Misc::zlibVersionString() diff --git a/src/base/utils/string.cpp b/src/base/utils/string.cpp index 46b2c4450..6efc1adb1 100644 --- a/src/base/utils/string.cpp +++ b/src/base/utils/string.cpp @@ -43,7 +43,7 @@ // to send numbers instead of strings with suffixes QString Utils::String::fromDouble(const double n, const int precision) { - /* HACK because QString rounds up. Eg QString::number(0.999*100.0, 'f' ,1) == 99.9 + /* HACK because QString rounds up. Eg QString::number(0.999*100.0, 'f', 1) == 99.9 ** but QString::number(0.9999*100.0, 'f' ,1) == 100.0 The problem manifests when ** the number has more digits after the decimal than we want AND the digit after ** our 'wanted' is >= 5. In this case our last digit gets rounded up. So for each @@ -99,7 +99,7 @@ std::optional Utils::String::parseDouble(const QString &string) return std::nullopt; } -QString Utils::String::join(const QVector &strings, const QString &separator) +QString Utils::String::join(const QList &strings, const QStringView separator) { if (strings.empty()) return {}; diff --git a/src/base/utils/string.h b/src/base/utils/string.h index e7ff9919b..e4f3c303b 100644 --- a/src/base/utils/string.h +++ b/src/base/utils/string.h @@ -37,8 +37,6 @@ #include #include -class QStringRef; - namespace Utils::String { QString wildcardToRegexPattern(const QString &pattern); @@ -61,7 +59,7 @@ namespace Utils::String std::optional parseInt(const QString &string); std::optional parseDouble(const QString &string); - QString join(const QVector &strings, const QString &separator); + QString join(const QList &strings, QStringView separator); QString fromDouble(double n, int precision); diff --git a/src/gui/downloadfromurldialog.cpp b/src/gui/downloadfromurldialog.cpp index e65c7664f..4e617a24e 100644 --- a/src/gui/downloadfromurldialog.cpp +++ b/src/gui/downloadfromurldialog.cpp @@ -75,10 +75,10 @@ DownloadFromURLDialog::DownloadFromURLDialog(QWidget *parent) // Paste clipboard if there is an URL in it const QString clipboardText = qApp->clipboard()->text(); - const QVector clipboardList = clipboardText.splitRef('\n'); + const QList clipboardList = QStringView(clipboardText).split(u'\n'); QSet uniqueURLs; - for (QStringRef strRef : clipboardList) + for (QStringView strRef : clipboardList) { strRef = strRef.trimmed(); if (strRef.isEmpty()) continue; @@ -107,10 +107,10 @@ DownloadFromURLDialog::~DownloadFromURLDialog() void DownloadFromURLDialog::downloadButtonClicked() { const QString plainText = m_ui->textUrls->toPlainText(); - const QVector urls = plainText.splitRef('\n'); + const QList urls = QStringView(plainText).split(u'\n'); QSet uniqueURLs; - for (QStringRef url : urls) + for (QStringView url : urls) { url = url.trimmed(); if (url.isEmpty()) continue; diff --git a/src/gui/fspathedit_p.cpp b/src/gui/fspathedit_p.cpp index 1cc63c384..f2c8c294a 100644 --- a/src/gui/fspathedit_p.cpp +++ b/src/gui/fspathedit_p.cpp @@ -107,30 +107,32 @@ QValidator::State Private::FileSystemPathValidator::validate(QString &input, int // we test path components from beginning to the one with cursor location in strict mode // and the one with cursor and beyond in non-strict mode - QVector components = input.splitRef(QDir::separator(), Qt::KeepEmptyParts); + QList components = QStringView(input).split(QDir::separator(), Qt::KeepEmptyParts); // find index of the component that contains pos int componentWithCursorIndex = 0; + int componentWithCursorPosition = 0; int pathLength = 0; // components.size() - 1 because when path ends with QDir::separator(), we will not see the last // character in the components array, yet everything past the one before the last delimiter // belongs to the last component - for (; (componentWithCursorIndex < components.size() - 1) && (pathLength < pos); ++componentWithCursorIndex) + for (; (componentWithCursorIndex < (components.size() - 1)) && (pathLength < pos); ++componentWithCursorIndex) { - pathLength = components[componentWithCursorIndex].position() + components[componentWithCursorIndex].size(); + pathLength = componentWithCursorPosition + components[componentWithCursorIndex].size(); + componentWithCursorPosition += components[componentWithCursorIndex].size() + 1; } Q_ASSERT(componentWithCursorIndex < components.size()); m_lastValidationState = QValidator::Acceptable; if (componentWithCursorIndex > 0) - m_lastValidationState = validate(input, components, m_strictMode, 0, componentWithCursorIndex - 1); + m_lastValidationState = validate(components, m_strictMode, 0, componentWithCursorIndex - 1); if ((m_lastValidationState == QValidator::Acceptable) && (componentWithCursorIndex < components.size())) - m_lastValidationState = validate(input, components, false, componentWithCursorIndex, components.size() - 1); + m_lastValidationState = validate(components, false, componentWithCursorIndex, components.size() - 1); return m_lastValidationState; } -QValidator::State Private::FileSystemPathValidator::validate(const QString &path, const QVector &pathComponents, bool strict, +QValidator::State Private::FileSystemPathValidator::validate(const QList &pathComponents, bool strict, int firstComponentToTest, int lastComponentToTest) const { Q_ASSERT(firstComponentToTest >= 0); @@ -141,12 +143,13 @@ QValidator::State Private::FileSystemPathValidator::validate(const QString &path if (pathComponents.empty()) return strict ? QValidator::Invalid : QValidator::Intermediate; - for (int i = firstComponentToTest; i < lastComponentToTest; ++i) + for (int i = firstComponentToTest; i <= lastComponentToTest; ++i) { - if (pathComponents[i].isEmpty()) continue; + const bool isFinalPath = (i == (pathComponents.size() - 1)); + const QStringView componentPath = pathComponents[i]; + if (componentPath.isEmpty()) continue; - QStringRef componentPath(&path, 0, pathComponents[i].position() + pathComponents[i].size()); - m_lastTestResult = testPath(componentPath, false); + m_lastTestResult = testPath(pathComponents[i], isFinalPath); if (m_lastTestResult != TestResult::OK) { m_lastTestedPath = componentPath.toString(); @@ -154,20 +157,11 @@ QValidator::State Private::FileSystemPathValidator::validate(const QString &path } } - const bool finalPath = (lastComponentToTest == (pathComponents.size() - 1)); - QStringRef componentPath(&path, 0, pathComponents[lastComponentToTest].position() - + pathComponents[lastComponentToTest].size()); - m_lastTestResult = testPath(componentPath, finalPath); - if (m_lastTestResult != TestResult::OK) - { - m_lastTestedPath = componentPath.toString(); - return strict ? QValidator::Invalid : QValidator::Intermediate; - } return QValidator::Acceptable; } Private::FileSystemPathValidator::TestResult -Private::FileSystemPathValidator::testPath(const QStringRef &path, bool pathIsComplete) const +Private::FileSystemPathValidator::testPath(const QStringView path, bool pathIsComplete) const { QFileInfo fi(path.toString()); if (m_existingOnly && !fi.exists()) diff --git a/src/gui/fspathedit_p.h b/src/gui/fspathedit_p.h index a99384fa9..8f443b4d2 100644 --- a/src/gui/fspathedit_p.h +++ b/src/gui/fspathedit_p.h @@ -39,7 +39,6 @@ class QCompleter; class QContextMenuEvent; class QFileSystemModel; class QKeyEvent; -class QStringRef; namespace Private { @@ -82,10 +81,10 @@ namespace Private QString lastTestedPath() const; private: - QValidator::State validate(const QString &path, const QVector &pathComponents, bool strict, + QValidator::State validate(const QList &pathComponents, bool strict, int firstComponentToTest, int lastComponentToTest) const; - TestResult testPath(const QStringRef &path, bool pathIsComplete) const; + TestResult testPath(QStringView path, bool pathIsComplete) const; bool m_strictMode; bool m_existingOnly; diff --git a/src/gui/mainwindow.cpp b/src/gui/mainwindow.cpp index 6210f3fb6..15a7ed5b6 100644 --- a/src/gui/mainwindow.cpp +++ b/src/gui/mainwindow.cpp @@ -2184,8 +2184,9 @@ void MainWindow::pythonDownloadFinished(const Net::DownloadResult &result) QProcess installer; qDebug("Launching Python installer in passive mode..."); - QFile::rename(result.filePath, result.filePath + ".exe"); - installer.start('"' + Utils::Fs::toNativePath(result.filePath) + ".exe\" /passive"); + const QString exePath = result.filePath + QLatin1String(".exe"); + QFile::rename(result.filePath, exePath); + installer.start(Utils::Fs::toNativePath(exePath), {"/passive"}); // Wait for setup to complete installer.waitForFinished(10 * 60 * 1000); @@ -2195,7 +2196,7 @@ void MainWindow::pythonDownloadFinished(const Net::DownloadResult &result) qDebug("Setup should be complete!"); // Delete temp file - Utils::Fs::forceRemove(result.filePath + ".exe"); + Utils::Fs::forceRemove(exePath); // Reload search engine if (Utils::ForeignApps::pythonInfo().isSupportedVersion()) diff --git a/src/gui/properties/proptabbar.cpp b/src/gui/properties/proptabbar.cpp index 1f6b53e42..de7079c96 100644 --- a/src/gui/properties/proptabbar.cpp +++ b/src/gui/properties/proptabbar.cpp @@ -100,13 +100,8 @@ PropTabBar::PropTabBar(QWidget *parent) addWidget(speedButton); m_btnGroup->addButton(speedButton, SpeedTab); // SIGNAL/SLOT -#if (QT_VERSION >= QT_VERSION_CHECK(5, 15, 0)) connect(m_btnGroup, &QButtonGroup::idClicked , this, &PropTabBar::setCurrentIndex); -#else - connect(m_btnGroup, qOverload(&QButtonGroup::buttonClicked) - , this, &PropTabBar::setCurrentIndex); -#endif // Disable buttons focus for (QAbstractButton *btn : asConst(m_btnGroup->buttons())) btn->setFocusPolicy(Qt::NoFocus); diff --git a/src/gui/properties/trackersadditiondialog.cpp b/src/gui/properties/trackersadditiondialog.cpp index f0f904e54..f9f4557b5 100644 --- a/src/gui/properties/trackersadditiondialog.cpp +++ b/src/gui/properties/trackersadditiondialog.cpp @@ -59,7 +59,7 @@ QStringList TrackersAdditionDialog::newTrackers() const const QString plainText = m_ui->textEditTrackersList->toPlainText(); QStringList cleanTrackers; - for (QStringRef url : asConst(plainText.splitRef('\n'))) + for (QStringView url : asConst(QStringView(plainText).split(u'\n'))) { url = url.trimmed(); if (!url.isEmpty()) diff --git a/src/gui/torrentcontentmodel.cpp b/src/gui/torrentcontentmodel.cpp index a37643de8..71a3374f7 100644 --- a/src/gui/torrentcontentmodel.cpp +++ b/src/gui/torrentcontentmodel.cpp @@ -504,16 +504,16 @@ void TorrentContentModel::setupModelData(const BitTorrent::TorrentInfo &info) const QString path = Utils::Fs::toUniformPath(info.filePath(i)); // Iterate of parts of the path to create necessary folders - QVector pathFolders = path.splitRef('/', Qt::SkipEmptyParts); + QList pathFolders = QStringView(path).split(u'/', Qt::SkipEmptyParts); pathFolders.removeLast(); - for (const QStringRef &pathPartRef : asConst(pathFolders)) + for (const QStringView pathPart : asConst(pathFolders)) { - const QString pathPart = pathPartRef.toString(); - TorrentContentModelFolder *newParent = currentParent->childFolderWithName(pathPart); + const QString folderPath = pathPart.toString(); + TorrentContentModelFolder *newParent = currentParent->childFolderWithName(folderPath); if (!newParent) { - newParent = new TorrentContentModelFolder(pathPart, currentParent); + newParent = new TorrentContentModelFolder(folderPath, currentParent); currentParent->appendChild(newParent); } currentParent = newParent; diff --git a/src/gui/torrentoptionsdialog.cpp b/src/gui/torrentoptionsdialog.cpp index 71326f71c..49ac52cf7 100644 --- a/src/gui/torrentoptionsdialog.cpp +++ b/src/gui/torrentoptionsdialog.cpp @@ -263,12 +263,7 @@ TorrentOptionsDialog::TorrentOptionsDialog(QWidget *parent, const QVectorcheckMaxRatio, &QCheckBox::toggled, m_ui->spinRatioLimit, &QDoubleSpinBox::setEnabled); connect(m_ui->checkMaxTime, &QCheckBox::toggled, m_ui->spinTimeLimit, &QSpinBox::setEnabled); -#if (QT_VERSION >= QT_VERSION_CHECK(5, 15, 0)) connect(m_ui->buttonGroup, &QButtonGroup::idClicked, this, &TorrentOptionsDialog::handleRatioTypeChanged); -#else - connect(m_ui->buttonGroup, qOverload(&QButtonGroup::buttonClicked) - , this, &TorrentOptionsDialog::handleRatioTypeChanged); -#endif Utils::Gui::resize(this, m_storeDialogSize); } diff --git a/src/gui/trackerentriesdialog.cpp b/src/gui/trackerentriesdialog.cpp index 46bb7fe37..a685449a4 100644 --- a/src/gui/trackerentriesdialog.cpp +++ b/src/gui/trackerentriesdialog.cpp @@ -81,13 +81,13 @@ void TrackerEntriesDialog::setTrackers(const QVector & QVector TrackerEntriesDialog::trackers() const { const QString plainText = m_ui->plainTextEdit->toPlainText(); - const QVector lines = plainText.splitRef('\n'); + const QList lines = QStringView(plainText).split(u'\n'); QVector entries; entries.reserve(lines.size()); int tier = 0; - for (QStringRef line : lines) + for (QStringView line : lines) { line = line.trimmed(); diff --git a/src/src.pro b/src/src.pro index 796c39521..8e87c56c9 100644 --- a/src/src.pro +++ b/src/src.pro @@ -56,7 +56,7 @@ CONFIG(release, debug|release) { include(../version.pri) # Qt defines -DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x050e00 +DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x050f02 DEFINES += QT_NO_CAST_TO_ASCII DEFINES += QT_NO_CAST_FROM_BYTEARRAY DEFINES += QT_USE_QSTRINGBUILDER diff --git a/src/webui/webapplication.cpp b/src/webui/webapplication.cpp index d71531ce4..f471da42e 100644 --- a/src/webui/webapplication.cpp +++ b/src/webui/webapplication.cpp @@ -72,11 +72,11 @@ const QString PRIVATE_FOLDER {QStringLiteral("/private")}; namespace { - QStringMap parseCookie(const QString &cookieStr) + QStringMap parseCookie(const QStringView cookieStr) { // [rfc6265] 4.2.1. Syntax QStringMap ret; - const QVector cookies = cookieStr.splitRef(';', Qt::SkipEmptyParts); + const QList cookies = cookieStr.split(u';', Qt::SkipEmptyParts); for (const auto &cookie : cookies) { @@ -386,10 +386,10 @@ void WebApplication::configure() if (pref->isWebUICustomHTTPHeadersEnabled()) { - const QString customHeaders = pref->getWebUICustomHTTPHeaders().trimmed(); - const QVector customHeaderLines = customHeaders.splitRef('\n', Qt::SkipEmptyParts); + const QString customHeaders = pref->getWebUICustomHTTPHeaders(); + const QList customHeaderLines = QStringView(customHeaders).trimmed().split(u'\n', Qt::SkipEmptyParts); - for (const QStringRef &line : customHeaderLines) + for (const QStringView line : customHeaderLines) { const int idx = line.indexOf(':'); if (idx < 0)