remove dependency on deprecated qt5 libraries for qt6 (#4692)

* remove dependency on deprecated qt5 libraries for qt6

removes the use of qt6-5compat for builds
replaces use of QRegExp with QRegularExpression
fixes incorrect usage of QRegExp
removes use of QTextCodec
fixes incorrect usage of QTextCodec
sets qtlinguist as a required component for qt6

* fix anchoredPattern not existing in qt 5.11
This commit is contained in:
ebbit1q 2022-10-31 23:24:11 +01:00 committed by GitHub
parent f619ef23fd
commit dec2a252fa
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
18 changed files with 65 additions and 75 deletions

View file

@ -7,7 +7,7 @@ RUN dnf install -y \
git \ git \
mariadb-devel \ mariadb-devel \
protobuf-devel \ protobuf-devel \
qt6-{qttools,qtsvg,qtmultimedia,qtwebsockets,qt5compat}-devel \ qt6-{qttools,qtsvg,qtmultimedia,qtwebsockets}-devel \
rpm-build \ rpm-build \
xz-devel \ xz-devel \
zlib-devel \ zlib-devel \

View file

@ -13,7 +13,6 @@ RUN apt-get update && \
liblzma-dev \ liblzma-dev \
libmariadb-dev-compat \ libmariadb-dev-compat \
libprotobuf-dev \ libprotobuf-dev \
libqt6core5compat6-dev \
libqt6multimedia6 \ libqt6multimedia6 \
libqt6sql6-mysql \ libqt6sql6-mysql \
libqt6svg6-dev \ libqt6svg6-dev \

View file

@ -310,7 +310,7 @@ jobs:
qt_version: 6.3.* qt_version: 6.3.*
qt_arch: msvc2019_64 qt_arch: msvc2019_64
qt_tools: "tools_openssl_x64" qt_tools: "tools_openssl_x64"
qt_modules: "qt5compat qtmultimedia qtwebsockets" qt_modules: "qtmultimedia qtwebsockets"
name: ${{matrix.target}} name: ${{matrix.target}}
needs: configure needs: configure

View file

@ -21,8 +21,8 @@ if(WITH_CLIENT)
Network Network
PrintSupport PrintSupport
Svg Svg
Widgets
WebSockets WebSockets
Widgets
) )
endif() endif()
if(WITH_ORACLE) if(WITH_ORACLE)
@ -41,27 +41,24 @@ set(REQUIRED_QT_COMPONENTS ${REQUIRED_QT_COMPONENTS} ${_SERVATRICE_NEEDED} ${_CO
list(REMOVE_DUPLICATES REQUIRED_QT_COMPONENTS) list(REMOVE_DUPLICATES REQUIRED_QT_COMPONENTS)
if(NOT FORCE_USE_QT5) if(NOT FORCE_USE_QT5)
# Core5Compat is Qt6 Only, Linguist is now a component in Qt6 instead of an external package # Linguist is now a component in Qt6 instead of an external package
find_package( find_package(
Qt6 6.2.3 Qt6 6.2.3
COMPONENTS Core5Compat ${REQUIRED_QT_COMPONENTS} COMPONENTS ${REQUIRED_QT_COMPONENTS} Linguist
OPTIONAL_COMPONENTS Linguist
QUIET HINTS ${Qt6_DIR} QUIET HINTS ${Qt6_DIR}
) )
endif() endif()
if(Qt6_FOUND) if(Qt6_FOUND)
set(COCKATRICE_QT_VERSION_NAME Qt6) set(COCKATRICE_QT_VERSION_NAME Qt6)
if(Qt6LinguistTools_FOUND) list(FIND Qt6LinguistTools_TARGETS Qt6::lrelease QT6_LRELEASE_INDEX)
list(FIND Qt6LinguistTools_TARGETS Qt6::lrelease QT6_LRELEASE_INDEX) if(QT6_LRELEASE_INDEX EQUAL -1)
if(QT6_LRELEASE_INDEX EQUAL -1) message(WARNING "Qt6 lrelease not found.")
message(WARNING "Qt6 lrelease not found.") endif()
endif()
list(FIND Qt6LinguistTools_TARGETS Qt6::lupdate QT6_LUPDATE_INDEX) list(FIND Qt6LinguistTools_TARGETS Qt6::lupdate QT6_LUPDATE_INDEX)
if(QT6_LUPDATE_INDEX EQUAL -1) if(QT6_LUPDATE_INDEX EQUAL -1)
message(WARNING "Qt6 lupdate not found.") message(WARNING "Qt6 lupdate not found.")
endif()
endif() endif()
else() else()
find_package( find_package(
@ -116,10 +113,5 @@ string(REGEX REPLACE "([^;]+)" "${COCKATRICE_QT_VERSION_NAME}::\\1" COCKATRICE_Q
string(REGEX REPLACE "([^;]+)" "${COCKATRICE_QT_VERSION_NAME}::\\1" ORACLE_QT_MODULES "${_ORACLE_NEEDED}") string(REGEX REPLACE "([^;]+)" "${COCKATRICE_QT_VERSION_NAME}::\\1" ORACLE_QT_MODULES "${_ORACLE_NEEDED}")
string(REGEX REPLACE "([^;]+)" "${COCKATRICE_QT_VERSION_NAME}::\\1" DB_CONVERTER_QT_MODULES "${_DBCONVERTER_NEEDED}") string(REGEX REPLACE "([^;]+)" "${COCKATRICE_QT_VERSION_NAME}::\\1" DB_CONVERTER_QT_MODULES "${_DBCONVERTER_NEEDED}")
string(REGEX REPLACE "([^;]+)" "${COCKATRICE_QT_VERSION_NAME}::\\1" TEST_QT_MODULES "${_TEST_NEEDED}") string(REGEX REPLACE "([^;]+)" "${COCKATRICE_QT_VERSION_NAME}::\\1" TEST_QT_MODULES "${_TEST_NEEDED}")
if(Qt6_FOUND)
list(APPEND SERVATRICE_QT_MODULES ${COCKATRICE_QT_VERSION_NAME}::Core5Compat)
list(APPEND COCKATRICE_QT_MODULES ${COCKATRICE_QT_VERSION_NAME}::Core5Compat)
list(APPEND ORACLE_QT_MODULES ${COCKATRICE_QT_VERSION_NAME}::Core5Compat)
endif()
message(STATUS "Found Qt ${${COCKATRICE_QT_VERSION_NAME}_VERSION} at: ${${COCKATRICE_QT_VERSION_NAME}_DIR}") message(STATUS "Found Qt ${${COCKATRICE_QT_VERSION_NAME}_VERSION} at: ${${COCKATRICE_QT_VERSION_NAME}_DIR}")

View file

@ -360,7 +360,7 @@ Data = Resources\")
endif() endif()
endif() endif()
if(Qt6LinguistTools_FOUND) if(Qt6_FOUND AND Qt6LinguistTools_FOUND)
#Qt6 Translations happen after the executable is built up #Qt6 Translations happen after the executable is built up
if(UPDATE_TRANSLATIONS) if(UPDATE_TRANSLATIONS)
qt6_add_translations( qt6_add_translations(

View file

@ -7,7 +7,7 @@
#include <QNetworkAccessManager> #include <QNetworkAccessManager>
#include <QNetworkReply> #include <QNetworkReply>
#include <QNetworkRequest> #include <QNetworkRequest>
#include <QRegExp> #include <QRegularExpression>
#include <QUrlQuery> #include <QUrlQuery>
DeckStatsInterface::DeckStatsInterface(CardDatabase &_cardDatabase, QObject *parent) DeckStatsInterface::DeckStatsInterface(CardDatabase &_cardDatabase, QObject *parent)
@ -20,7 +20,7 @@ DeckStatsInterface::DeckStatsInterface(CardDatabase &_cardDatabase, QObject *par
void DeckStatsInterface::queryFinished(QNetworkReply *reply) void DeckStatsInterface::queryFinished(QNetworkReply *reply)
{ {
if (reply->error() != QNetworkReply::NoError) { if (reply->error() != QNetworkReply::NoError) {
QMessageBox::critical(0, tr("Error"), reply->errorString()); QMessageBox::critical(nullptr, tr("Error"), reply->errorString());
reply->deleteLater(); reply->deleteLater();
deleteLater(); deleteLater();
return; return;
@ -29,14 +29,15 @@ void DeckStatsInterface::queryFinished(QNetworkReply *reply)
QString data(reply->readAll()); QString data(reply->readAll());
reply->deleteLater(); reply->deleteLater();
QRegExp rx("<meta property=\"og:url\" content=\"([^\"]+)\""); static const QRegularExpression rx("<meta property=\"og:url\" content=\"([^\"]+)\"");
if (-1 == rx.indexIn(data)) { auto match = rx.match(data);
QMessageBox::critical(0, tr("Error"), tr("The reply from the server could not be parsed.")); if (!match.hasMatch()) {
QMessageBox::critical(nullptr, tr("Error"), tr("The reply from the server could not be parsed."));
deleteLater(); deleteLater();
return; return;
} }
QString deckUrl = rx.cap(1); QString deckUrl = match.captured(1);
QDesktopServices::openUrl(deckUrl); QDesktopServices::openUrl(deckUrl);
deleteLater(); deleteLater();

View file

@ -43,7 +43,6 @@
#include <QLibraryInfo> #include <QLibraryInfo>
#include <QLocale> #include <QLocale>
#include <QSystemTrayIcon> #include <QSystemTrayIcon>
#include <QTextCodec>
#include <QTextStream> #include <QTextStream>
#include <QTranslator> #include <QTranslator>
#include <QtPlugin> #include <QtPlugin>

View file

@ -7,7 +7,6 @@
#include <QNetworkAccessManager> #include <QNetworkAccessManager>
#include <QNetworkReply> #include <QNetworkReply>
#include <QNetworkRequest> #include <QNetworkRequest>
#include <QRegExp>
#include <QRegularExpression> #include <QRegularExpression>
#include <QUrlQuery> #include <QUrlQuery>
@ -21,7 +20,7 @@ TappedOutInterface::TappedOutInterface(CardDatabase &_cardDatabase, QObject *par
void TappedOutInterface::queryFinished(QNetworkReply *reply) void TappedOutInterface::queryFinished(QNetworkReply *reply)
{ {
if (reply->error() != QNetworkReply::NoError) { if (reply->error() != QNetworkReply::NoError) {
QMessageBox::critical(0, tr("Error"), reply->errorString()); QMessageBox::critical(nullptr, tr("Error"), reply->errorString());
reply->deleteLater(); reply->deleteLater();
deleteLater(); deleteLater();
return; return;
@ -42,26 +41,26 @@ void TappedOutInterface::queryFinished(QNetworkReply *reply)
* from the html. Css pseudo selector for errors: $("div.alert-danger > ul > li") * from the html. Css pseudo selector for errors: $("div.alert-danger > ul > li")
*/ */
QString data(reply->readAll()); QString data(reply->readAll());
QString errorMessage = tr("Unable to analyze the deck."); QStringList errorMessageList = {tr("Unable to analyze the deck.")};
QRegExp rx("<div class=\"alert alert-danger.*<ul>(.*)</ul>"); static const QRegularExpression rx("<div class=\"alert alert-danger.*?<ul>(.*?)</ul>");
rx.setMinimal(true); auto match = rx.match(data);
int found = rx.indexIn(data); if (match.hasMatch()) {
if (found >= 0) { QString errors = match.captured(1);
QString errors = rx.cap(1); static const QRegularExpression rx2("<li>(.*?)</li>");
QRegExp rx2("<li>(.*)</li>"); static const QRegularExpression rxremove("<[^>]*>");
rx2.setMinimal(true); auto matchIterator = rx2.globalMatch(errors);
while (matchIterator.hasNext()) {
int captures = rx2.captureCount(); auto match2 = matchIterator.next();
for (int i = 1; i <= captures; i++) { errorMessageList.append(match2.captured(1).remove(rxremove).simplified());
errorMessage += QString("\n") + rx2.cap(i).remove(QRegularExpression("<[^>]*>")).simplified();
} }
} }
QString errorMessage = errorMessageList.join("\n");
qDebug() << "Tappedout: bad reply, http status" << httpStatus << "size" << data.size() << "message" qDebug() << "Tappedout: bad reply, http status" << httpStatus << "size" << data.size() << "message"
<< errorMessage; << errorMessage;
QMessageBox::critical(0, tr("Error"), errorMessage); QMessageBox::critical(nullptr, tr("Error"), errorMessage);
} }
reply->deleteLater(); reply->deleteLater();

View file

@ -252,7 +252,7 @@ Translations = Resources/translations\")
) )
endif() endif()
if(Qt6LinguistTools_FOUND) if(Qt6_FOUND AND Qt6LinguistTools_FOUND)
#Qt6 Translations happen after the executable is built up #Qt6 Translations happen after the executable is built up
if(UPDATE_TRANSLATIONS) if(UPDATE_TRANSLATIONS)
qt6_add_translations( qt6_add_translations(

View file

@ -8,7 +8,6 @@
#include <QCommandLineParser> #include <QCommandLineParser>
#include <QIcon> #include <QIcon>
#include <QLibraryInfo> #include <QLibraryInfo>
#include <QTextCodec>
#include <QTranslator> #include <QTranslator>
QTranslator *translator, *qtTranslator; QTranslator *translator, *qtTranslator;

View file

@ -465,7 +465,7 @@ UnZip::ErrorCode UnzipPrivate::seekToCentralDirectory()
quint16 commentLength = getUShort((const unsigned char*)buffer1, UNZIP_EOCD_OFF_COMMLEN + 4); quint16 commentLength = getUShort((const unsigned char*)buffer1, UNZIP_EOCD_OFF_COMMLEN + 4);
if (commentLength != 0) { if (commentLength != 0) {
QByteArray c = device->read(commentLength); QByteArray c = device->read(commentLength);
if (c.count() != commentLength) if (c.size() != commentLength)
return UnZip::ReadFailed; return UnZip::ReadFailed;
comment = c; comment = c;

View file

@ -32,7 +32,6 @@
#include <QDateTime> #include <QDateTime>
#include <QFile> #include <QFile>
#include <QMetaType> #include <QMetaType>
#include <QTextCodec>
#include <QtGlobal> #include <QtGlobal>
#include <iostream> #include <iostream>

View file

@ -177,23 +177,23 @@ bool Servatrice_DatabaseInterface::usernameIsValid(const QString &user, QString
return false; return false;
} }
for (const QRegExp &regExp : settingsCache->disallowedRegExp) { for (const QRegularExpression &regExp : settingsCache->disallowedRegExp) {
if (regExp.exactMatch(user)) if (regExp.match(user).hasMatch())
return false; return false;
} }
QString regEx("["); QString regEx("\\A[");
if (allowLowercase) if (allowLowercase)
regEx.append("a-z"); regEx.append("a-z");
if (allowUppercase) if (allowUppercase)
regEx.append("A-Z"); regEx.append("A-Z");
if (allowNumerics) if (allowNumerics)
regEx.append("0-9"); regEx.append("0-9");
regEx.append(QRegExp::escape(allowedPunctuation)); regEx.append(QRegularExpression::escape(allowedPunctuation));
regEx.append("]+"); regEx.append("]+\\z");
static QRegExp re = QRegExp(regEx); QRegularExpression re = QRegularExpression(regEx);
return re.exactMatch(user); return re.match(user).hasMatch();
} }
bool Servatrice_DatabaseInterface::registerUser(const QString &userName, bool Servatrice_DatabaseInterface::registerUser(const QString &userName,

View file

@ -19,7 +19,7 @@ SettingsCache::SettingsCache(const QString &fileName, QSettings::Format format,
#endif #endif
disallowedRegExpStr.removeDuplicates(); disallowedRegExpStr.removeDuplicates();
for (const QString &regExpStr : disallowedRegExpStr) { for (const QString &regExpStr : disallowedRegExpStr) {
disallowedRegExp.append(QRegExp(regExpStr)); disallowedRegExp.append(QRegularExpression(QString("\\A%1\\z").arg(regExpStr)));
} }
} }

View file

@ -2,7 +2,7 @@
#define SERVATRICE_SETTINGSCACHE_H #define SERVATRICE_SETTINGSCACHE_H
#include <QList> #include <QList>
#include <QRegExp> #include <QRegularExpression>
#include <QSettings> #include <QSettings>
#include <QString> #include <QString>
@ -17,7 +17,7 @@ public:
QSettings::Format format = QSettings::IniFormat, QSettings::Format format = QSettings::IniFormat,
QObject *parent = 0); QObject *parent = 0);
static QString guessConfigurationPath(); static QString guessConfigurationPath();
QList<QRegExp> disallowedRegExp; QList<QRegularExpression> disallowedRegExp;
bool getIsPortableBuild() const bool getIsPortableBuild() const
{ {
return isPortableBuild; return isPortableBuild;

View file

@ -26,12 +26,10 @@
#define QXTMAIL_P_H #define QXTMAIL_P_H
#include <QByteArray> #include <QByteArray>
#include <QTextCodec>
#define QXT_MUST_QP(x) (x < char(32) || x > char(126) || x == '=' || x == '?') #define QXT_MUST_QP(x) (x < char(32) || x > char(126) || x == '=' || x == '?')
QByteArray qxt_fold_mime_header(const QString &key, QByteArray qxt_fold_mime_header(const QString &key,
const QString &value, const QString &value,
QTextCodec *latin1,
const QByteArray &prefix = QByteArray()); const QByteArray &prefix = QByteArray());
#endif // QXTMAIL_P_H #endif // QXTMAIL_P_H

View file

@ -34,7 +34,6 @@
#include "qxtmailattachment.h" #include "qxtmailattachment.h"
#include "qxtmail_p.h" #include "qxtmail_p.h"
#include <QTextCodec>
#include <QBuffer> #include <QBuffer>
#include <QPointer> #include <QPointer>
#include <QFile> #include <QFile>
@ -187,11 +186,10 @@ QByteArray QxtMailAttachment::mimeData()
return QByteArray(); return QByteArray();
} }
QTextCodec* latin1 = QTextCodec::codecForName("latin1");
QByteArray rv = "Content-Type: " + qxt_d->contentType.toLatin1() + "\r\nContent-Transfer-Encoding: base64\r\n"; QByteArray rv = "Content-Type: " + qxt_d->contentType.toLatin1() + "\r\nContent-Transfer-Encoding: base64\r\n";
foreach(const QString& r, qxt_d->extraHeaders.keys()) foreach(const QString& r, qxt_d->extraHeaders.keys())
{ {
rv += qxt_fold_mime_header(r.toLatin1(), extraHeader(r), latin1); rv += qxt_fold_mime_header(r.toLatin1(), extraHeader(r));
} }
rv += "\r\n"; rv += "\r\n";

View file

@ -35,10 +35,17 @@
#include "qxtmail_p.h" #include "qxtmail_p.h"
#include <QDir> #include <QDir>
#include <QTextCodec>
#include <QUuid> #include <QUuid>
#include <QtDebug> #include <QtDebug>
static bool isASCII(const QString &string) {
for(const QChar &chr : string){
if(chr.unicode() > 0x7f)
return false;
}
return true;
}
struct QxtMailMessagePrivate : public QSharedData struct QxtMailMessagePrivate : public QSharedData
{ {
QxtMailMessagePrivate() QxtMailMessagePrivate()
@ -204,13 +211,13 @@ void QxtMailMessage::removeAttachment(const QString &filename)
qxt_d->attachments.remove(filename); qxt_d->attachments.remove(filename);
} }
QByteArray qxt_fold_mime_header(const QString &key, const QString &value, QTextCodec *latin1, const QByteArray &prefix) QByteArray qxt_fold_mime_header(const QString &key, const QString &value, const QByteArray &prefix)
{ {
QByteArray rv = ""; QByteArray rv = "";
QByteArray line = key.toLatin1() + ": "; QByteArray line = key.toLatin1() + ": ";
if (!prefix.isEmpty()) if (!prefix.isEmpty())
line += prefix; line += prefix;
if (!value.contains("=?") && latin1->canEncode(value)) { if (!value.contains("=?") && isASCII(value)) {
bool firstWord = true; bool firstWord = true;
foreach (const QByteArray &word, value.toLatin1().split(' ')) { foreach (const QByteArray &word, value.toLatin1().split(' ')) {
if (line.size() > 78) { if (line.size() > 78) {
@ -274,26 +281,25 @@ QByteArray QxtMailMessage::rfc2822() const
// Use base64 if requested // Use base64 if requested
bool useBase64 = (extraHeader("Content-Transfer-Encoding").toLower() == "base64"); bool useBase64 = (extraHeader("Content-Transfer-Encoding").toLower() == "base64");
// Check to see if plain text is ASCII-clean; assume it isn't if QP or base64 was requested // Check to see if plain text is ASCII-clean; assume it isn't if QP or base64 was requested
QTextCodec *latin1 = QTextCodec::codecForName("latin1"); bool bodyIsAscii = !useQuotedPrintable && !useBase64 && isASCII(body());
bool bodyIsAscii = latin1->canEncode(body()) && !useQuotedPrintable && !useBase64;
QHash<QString, QxtMailAttachment> attach = attachments(); QHash<QString, QxtMailAttachment> attach = attachments();
QByteArray rv; QByteArray rv;
if (!sender().isEmpty() && !hasExtraHeader("From")) { if (!sender().isEmpty() && !hasExtraHeader("From")) {
rv += qxt_fold_mime_header("From", sender(), latin1); rv += qxt_fold_mime_header("From", sender());
} }
if (!qxt_d->rcptTo.isEmpty()) { if (!qxt_d->rcptTo.isEmpty()) {
rv += qxt_fold_mime_header("To", qxt_d->rcptTo.join(", "), latin1); rv += qxt_fold_mime_header("To", qxt_d->rcptTo.join(", "));
} }
if (!qxt_d->rcptCc.isEmpty()) { if (!qxt_d->rcptCc.isEmpty()) {
rv += qxt_fold_mime_header("Cc", qxt_d->rcptCc.join(", "), latin1); rv += qxt_fold_mime_header("Cc", qxt_d->rcptCc.join(", "));
} }
if (!subject().isEmpty()) { if (!subject().isEmpty()) {
rv += qxt_fold_mime_header("Subject", subject(), latin1); rv += qxt_fold_mime_header("Subject", subject());
} }
if (!bodyIsAscii) { if (!bodyIsAscii) {
@ -338,7 +344,7 @@ QByteArray QxtMailMessage::rfc2822() const
// Since we're in multipart mode, we'll be outputting this later // Since we're in multipart mode, we'll be outputting this later
continue; continue;
} }
rv += qxt_fold_mime_header(r.toLatin1(), extraHeader(r), latin1); rv += qxt_fold_mime_header(r.toLatin1(), extraHeader(r));
} }
rv += "\r\n"; rv += "\r\n";
@ -366,7 +372,7 @@ QByteArray QxtMailMessage::rfc2822() const
} }
if (bodyIsAscii) { if (bodyIsAscii) {
QByteArray b = latin1->fromUnicode(body()); QByteArray b = body().toLatin1();
int len = b.length(); int len = b.length();
QByteArray line = ""; QByteArray line = "";
QByteArray word = ""; QByteArray word = "";
@ -460,7 +466,7 @@ QByteArray QxtMailMessage::rfc2822() const
foreach (const QString &filename, attach.keys()) { foreach (const QString &filename, attach.keys()) {
rv += "--" + qxt_d->boundary + "\r\n"; rv += "--" + qxt_d->boundary + "\r\n";
rv += rv +=
qxt_fold_mime_header("Content-Disposition", QDir(filename).dirName(), latin1, "attachment; filename="); qxt_fold_mime_header("Content-Disposition", QDir(filename).dirName(), "attachment; filename=");
rv += attach[filename].mimeData(); rv += attach[filename].mimeData();
} }
rv += "--" + qxt_d->boundary + "--\r\n"; rv += "--" + qxt_d->boundary + "--\r\n";