Qt::mightBeRichText: port to QAnyStringView

[ChangeLog][QtGui] Ported Qt::mightBeRichText() to QAnyStringView
(was: QString).

Change-Id: Ib5633ed45cba5f4f1211438397624574f7431908
Reviewed-by: Marc Mutz <marc.mutz@qt.io>
This commit is contained in:
Anton Kudryavtsev 2023-10-04 17:52:46 +03:00 committed by Marc Mutz
parent 2b7c2c3a71
commit ebf1538fa6
4 changed files with 45 additions and 12 deletions

View File

@ -19,6 +19,13 @@ QT_USE_NAMESPACE
#if QT_GUI_REMOVED_SINCE(6, 7) #if QT_GUI_REMOVED_SINCE(6, 7)
#include "qtextdocument.h"
bool Qt::mightBeRichText(const QString& text)
{
return Qt::mightBeRichText(qToStringViewIgnoringNull(text));
}
// #include "qotherheader.h" // #include "qotherheader.h"
// // implement removed functions from qotherheader.h // // implement removed functions from qotherheader.h
// order sections alphabetically // order sections alphabetically

View File

@ -51,6 +51,8 @@ namespace {
}; };
/*! /*!
\fn bool Qt::mightBeRichText(QAnyStringView text)
Returns \c true if the string \a text is likely to be rich text; Returns \c true if the string \a text is likely to be rich text;
otherwise returns \c false. otherwise returns \c false.
@ -60,18 +62,21 @@ namespace {
for common cases, there is no guarantee. for common cases, there is no guarantee.
This function is defined in the \c <QTextDocument> header file. This function is defined in the \c <QTextDocument> header file.
*/
bool Qt::mightBeRichText(const QString& text) \note In Qt versions prior to 6.7, this function took QString only.
*/
template <typename T>
static bool mightBeRichTextImpl(T text)
{ {
if (text.isEmpty()) if (text.isEmpty())
return false; return false;
qsizetype start = 0; qsizetype start = 0;
while (start < text.size() && text.at(start).isSpace()) while (start < text.size() && QChar(text.at(start)).isSpace())
++start; ++start;
// skip a leading <?xml ... ?> as for example with xhtml // skip a leading <?xml ... ?> as for example with xhtml
if (QStringView{text}.mid(start, 5).compare("<?xml"_L1) == 0) { if (text.mid(start, 5).compare("<?xml"_L1) == 0) {
while (start < text.size()) { while (start < text.size()) {
if (text.at(start) == u'?' if (text.at(start) == u'?'
&& start + 2 < text.size() && start + 2 < text.size()
@ -82,16 +87,16 @@ bool Qt::mightBeRichText(const QString& text)
++start; ++start;
} }
while (start < text.size() && text.at(start).isSpace()) while (start < text.size() && QChar(text.at(start)).isSpace())
++start; ++start;
} }
if (QStringView{text}.mid(start, 5).compare("<!doc"_L1, Qt::CaseInsensitive) == 0) if (text.mid(start, 5).compare("<!doc"_L1, Qt::CaseInsensitive) == 0)
return true; return true;
qsizetype open = start; qsizetype open = start;
while (open < text.size() && text.at(open) != u'<' while (open < text.size() && text.at(open) != u'<'
&& text.at(open) != u'\n') { && text.at(open) != u'\n') {
if (text.at(open) == u'&' && QStringView{text}.mid(open + 1, 3) == "lt;"_L1) if (text.at(open) == u'&' && text.mid(open + 1, 3) == "lt;"_L1)
return true; // support desperate attempt of user to see <...> return true; // support desperate attempt of user to see <...>
++open; ++open;
} }
@ -100,13 +105,14 @@ bool Qt::mightBeRichText(const QString& text)
if (close > -1) { if (close > -1) {
QVarLengthArray<char16_t> tag; QVarLengthArray<char16_t> tag;
for (qsizetype i = open + 1; i < close; ++i) { for (qsizetype i = open + 1; i < close; ++i) {
if (text[i].isDigit() || text[i].isLetter()) const auto current = QChar(text[i]);
tag.append(text[i].toLower().unicode()); if (current.isDigit() || current.isLetter())
else if (!tag.isEmpty() && text[i].isSpace()) tag.append(current.toLower().unicode());
else if (!tag.isEmpty() && current.isSpace())
break; break;
else if (!tag.isEmpty() && text[i] == u'/' && i + 1 == close) else if (!tag.isEmpty() && current == u'/' && i + 1 == close)
break; break;
else if (!text[i].isSpace() && (!tag.isEmpty() || text[i] != u'!')) else if (!current.isSpace() && (!tag.isEmpty() || current != u'!'))
return false; // that's not a tag return false; // that's not a tag
} }
#ifndef QT_NO_TEXTHTMLPARSER #ifndef QT_NO_TEXTHTMLPARSER
@ -119,6 +125,16 @@ bool Qt::mightBeRichText(const QString& text)
return false; return false;
} }
static bool mightBeRichTextImpl(QUtf8StringView text)
{
return mightBeRichTextImpl(QLatin1StringView(QByteArrayView(text)));
}
bool Qt::mightBeRichText(QAnyStringView text)
{
return text.visit([](auto text) { return mightBeRichTextImpl(text); });
}
/*! /*!
Converts the plain text string \a plain to an HTML-formatted Converts the plain text string \a plain to an HTML-formatted
paragraph while preserving most of its look. paragraph while preserving most of its look.

View File

@ -35,7 +35,10 @@ class QTextCursor;
namespace Qt namespace Qt
{ {
#if QT_GUI_REMOVED_SINCE(6, 7)
Q_GUI_EXPORT bool mightBeRichText(const QString&); Q_GUI_EXPORT bool mightBeRichText(const QString&);
#endif
Q_GUI_EXPORT bool mightBeRichText(QAnyStringView);
Q_GUI_EXPORT QString convertFromPlainText(const QString &plain, WhiteSpaceMode mode = WhiteSpacePre); Q_GUI_EXPORT QString convertFromPlainText(const QString &plain, WhiteSpaceMode mode = WhiteSpacePre);
} }

View File

@ -743,6 +743,9 @@ void tst_QTextDocument::mightBeRichText_data()
" PUBLIC ""-//W3C//DTD XHTML 1.0 Strict//EN\" \"DTD/xhtml1-strict.dtd\">\n" " PUBLIC ""-//W3C//DTD XHTML 1.0 Strict//EN\" \"DTD/xhtml1-strict.dtd\">\n"
"<html xmlns=\"http://www.w3.org/1999/xhtml\" xml:lang=\"en\" lang=\"en\">"; "<html xmlns=\"http://www.w3.org/1999/xhtml\" xml:lang=\"en\" lang=\"en\">";
QVERIFY(Qt::mightBeRichText(QString::fromLatin1(qtDocuHeader))); QVERIFY(Qt::mightBeRichText(QString::fromLatin1(qtDocuHeader)));
QVERIFY(Qt::mightBeRichText(QLatin1StringView(qtDocuHeader)));
QVERIFY(QUtf8StringView(qtDocuHeader).isValidUtf8());
QVERIFY(Qt::mightBeRichText(QUtf8StringView(qtDocuHeader)));
QTest::addColumn<QString>("input"); QTest::addColumn<QString>("input");
QTest::addColumn<bool>("result"); QTest::addColumn<bool>("result");
@ -762,6 +765,10 @@ void tst_QTextDocument::mightBeRichText()
QFETCH(QString, input); QFETCH(QString, input);
QFETCH(bool, result); QFETCH(bool, result);
QCOMPARE(result, Qt::mightBeRichText(input)); QCOMPARE(result, Qt::mightBeRichText(input));
QCOMPARE(result, Qt::mightBeRichText(QStringView(input)));
QCOMPARE(result, Qt::mightBeRichText(QUtf8StringView(input.toUtf8())));
QVERIFY(QtPrivate::isLatin1(input));
QCOMPARE(result, Qt::mightBeRichText(QLatin1StringView(input.toLatin1())));
} }
Q_DECLARE_METATYPE(QTextDocumentFragment) Q_DECLARE_METATYPE(QTextDocumentFragment)