diff options
Diffstat (limited to 'src/widgets/widgets/qtextbrowser.cpp')
-rw-r--r-- | src/widgets/widgets/qtextbrowser.cpp | 148 |
1 files changed, 66 insertions, 82 deletions
diff --git a/src/widgets/widgets/qtextbrowser.cpp b/src/widgets/widgets/qtextbrowser.cpp index 99ebaa93bf..2c01ed2b26 100644 --- a/src/widgets/widgets/qtextbrowser.cpp +++ b/src/widgets/widgets/qtextbrowser.cpp @@ -1,41 +1,5 @@ -/**************************************************************************** -** -** Copyright (C) 2019 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtWidgets module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ +// Copyright (C) 2019 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only #include "qtextbrowser.h" #include "qtextedit_p.h" @@ -54,9 +18,21 @@ #endif #include <qtextobject.h> #include <qdesktopservices.h> +#include <qstringconverter.h> QT_BEGIN_NAMESPACE +using namespace Qt::StringLiterals; + +static inline bool shouldEnableInputMethod(QTextBrowser *texbrowser) +{ +#if defined (Q_OS_ANDROID) + return !texbrowser->isReadOnly() || (texbrowser->textInteractionFlags() & Qt::TextSelectableByMouse); +#else + return !texbrowser->isReadOnly(); +#endif +} + Q_LOGGING_CATEGORY(lcBrowser, "qt.text.browser") class QTextBrowserPrivate : public QTextEditPrivate @@ -70,6 +46,11 @@ public: , lastKeypadScrollValue(-1) #endif {} + ~QTextBrowserPrivate() + { + for (const QMetaObject::Connection &connection : connections) + QObject::disconnect(connection); + } void init(); @@ -88,13 +69,13 @@ public: HistoryEntry history(int i) const { if (i <= 0) - if (-i < stack.count()) - return stack[stack.count()+i-1]; + if (-i < stack.size()) + return stack[stack.size()+i-1]; else return HistoryEntry(); else - if (i <= forwardStack.count()) - return forwardStack[forwardStack.count()-i]; + if (i <= forwardStack.size()) + return forwardStack[forwardStack.size()-i]; else return HistoryEntry(); } @@ -127,14 +108,14 @@ public: QString findFile(const QUrl &name) const; - inline void _q_documentModified() + inline void documentModified() { textOrSourceChanged = true; forceLoadOnSourceChange = !currentURL.path().isEmpty(); } - void _q_activateAnchor(const QString &href); - void _q_highlightLink(const QString &href); + void activateAnchor(const QString &href); + void highlightLink(const QString &href); void setSource(const QUrl &url, QTextDocument::ResourceType type); @@ -153,20 +134,21 @@ public: Q_Q(QTextBrowser); emit q->highlighted(url); } + std::array<QMetaObject::Connection, 3> connections; }; Q_DECLARE_TYPEINFO(QTextBrowserPrivate::HistoryEntry, Q_RELOCATABLE_TYPE); QString QTextBrowserPrivate::findFile(const QUrl &name) const { QString fileName; - if (name.scheme() == QLatin1String("qrc")) { - fileName = QLatin1String(":/") + name.path(); + if (name.scheme() == "qrc"_L1) { + fileName = ":/"_L1 + name.path(); } else if (name.scheme().isEmpty()) { fileName = name.path(); } else { #if defined(Q_OS_ANDROID) - if (name.scheme() == QLatin1String("assets")) - fileName = QLatin1String("assets:") + name.path(); + if (name.scheme() == "assets"_L1) + fileName = "assets:"_L1 + name.path(); else #endif fileName = name.toLocalFile(); @@ -178,9 +160,9 @@ QString QTextBrowserPrivate::findFile(const QUrl &name) const if (QFileInfo(fileName).isAbsolute()) return fileName; - for (QString path : qAsConst(searchPaths)) { - if (!path.endsWith(QLatin1Char('/'))) - path.append(QLatin1Char('/')); + for (QString path : std::as_const(searchPaths)) { + if (!path.endsWith(u'/')) + path.append(u'/'); path.append(fileName); if (QFileInfo(path).isReadable()) return path; @@ -197,7 +179,7 @@ QUrl QTextBrowserPrivate::resolveUrl(const QUrl &url) const // For the second case QUrl can merge "#someanchor" with "foo.html" // correctly to "foo.html#someanchor" if (!(currentURL.isRelative() - || (currentURL.scheme() == QLatin1String("file") + || (currentURL.scheme() == "file"_L1 && !QFileInfo(currentURL.toLocalFile()).isAbsolute())) || (url.hasFragment() && url.path().isEmpty())) { return currentURL.resolved(url); @@ -214,7 +196,7 @@ QUrl QTextBrowserPrivate::resolveUrl(const QUrl &url) const return url; } -void QTextBrowserPrivate::_q_activateAnchor(const QString &href) +void QTextBrowserPrivate::activateAnchor(const QString &href) { if (href.isEmpty()) return; @@ -235,11 +217,11 @@ void QTextBrowserPrivate::_q_activateAnchor(const QString &href) #ifndef QT_NO_DESKTOPSERVICES bool isFileScheme = - url.scheme() == QLatin1String("file") + url.scheme() == "file"_L1 #if defined(Q_OS_ANDROID) - || url.scheme() == QLatin1String("assets") + || url.scheme() == "assets"_L1 #endif - || url.scheme() == QLatin1String("qrc"); + || url.scheme() == "qrc"_L1; if ((openExternalLinks && !isFileScheme && !url.isRelative()) || (url.isRelative() && !currentURL.isRelative() && !isFileScheme)) { QDesktopServices::openUrl(url); @@ -255,7 +237,7 @@ void QTextBrowserPrivate::_q_activateAnchor(const QString &href) q->setSource(url); } -void QTextBrowserPrivate::_q_highlightLink(const QString &anchor) +void QTextBrowserPrivate::highlightLink(const QString &anchor) { if (anchor.isEmpty()) { #ifndef QT_NO_CURSOR @@ -294,9 +276,9 @@ void QTextBrowserPrivate::setSource(const QUrl &url, QTextDocument::ResourceType QString fileName = url.fileName(); if (type == QTextDocument::UnknownResource) { #if QT_CONFIG(textmarkdownreader) - if (fileName.endsWith(QLatin1String(".md")) || - fileName.endsWith(QLatin1String(".mkd")) || - fileName.endsWith(QLatin1String(".markdown"))) + if (fileName.endsWith(".md"_L1) || + fileName.endsWith(".mkd"_L1) || + fileName.endsWith(".markdown"_L1)) type = QTextDocument::MarkdownResource; else #endif @@ -312,12 +294,11 @@ void QTextBrowserPrivate::setSource(const QUrl &url, QTextDocument::ResourceType } else if (data.userType() == QMetaType::QByteArray) { QByteArray ba = data.toByteArray(); if (type == QTextDocument::HtmlResource) { - auto encoding = QStringConverter::encodingForHtml(ba); - if (!encoding) + auto decoder = QStringDecoder::decoderForHtml(ba); + if (!decoder.isValid()) // fall back to utf8 - encoding = QStringDecoder::Utf8; - QStringDecoder toUtf16(*encoding); - txt = toUtf16(ba); + decoder = QStringDecoder(QStringDecoder::Utf8); + txt = decoder(ba); } else { txt = QString::fromUtf8(ba); } @@ -326,8 +307,8 @@ void QTextBrowserPrivate::setSource(const QUrl &url, QTextDocument::ResourceType qWarning("QTextBrowser: No document for %s", url.toString().toLatin1().constData()); if (q->isVisible()) { - const QStringView firstTag = QStringView{txt}.left(txt.indexOf(QLatin1Char('>')) + 1); - if (firstTag.startsWith(QLatin1String("<qt")) && firstTag.contains(QLatin1String("type")) && firstTag.contains(QLatin1String("detail"))) { + const QStringView firstTag = QStringView{txt}.left(txt.indexOf(u'>') + 1); + if (firstTag.startsWith("<qt"_L1) && firstTag.contains("type"_L1) && firstTag.contains("detail"_L1)) { #ifndef QT_NO_CURSOR QGuiApplication::restoreOverrideCursor(); #endif @@ -692,14 +673,17 @@ void QTextBrowserPrivate::init() #ifndef QT_NO_CURSOR viewport->setCursor(oldCursor); #endif - q->setAttribute(Qt::WA_InputMethodEnabled, !q->isReadOnly()); + q->setAttribute(Qt::WA_InputMethodEnabled, shouldEnableInputMethod(q)); q->setUndoRedoEnabled(false); viewport->setMouseTracking(true); - QObject::connect(q->document(), SIGNAL(contentsChanged()), q, SLOT(_q_documentModified())); - QObject::connect(control, SIGNAL(linkActivated(QString)), - q, SLOT(_q_activateAnchor(QString))); - QObject::connect(control, SIGNAL(linkHovered(QString)), - q, SLOT(_q_highlightLink(QString))); + connections = { + QObjectPrivate::connect(q->document(), &QTextDocument::contentsChanged, + this, &QTextBrowserPrivate::documentModified), + QObjectPrivate::connect(control, &QWidgetTextControl::linkActivated, + this, &QTextBrowserPrivate::activateAnchor), + QObjectPrivate::connect(control, &QWidgetTextControl::linkHovered, + this, &QTextBrowserPrivate::highlightLink), + }; } /*! @@ -853,11 +837,11 @@ void QTextBrowser::doSetSource(const QUrl &url, QTextDocument::ResourceType type entry.vpos = 0; d->stack.push(entry); - emit backwardAvailable(d->stack.count() > 1); + emit backwardAvailable(d->stack.size() > 1); if (!d->forwardStack.isEmpty() && d->forwardStack.top().url == url) { d->forwardStack.pop(); - emit forwardAvailable(d->forwardStack.count() > 0); + emit forwardAvailable(d->forwardStack.size() > 0); } else { d->forwardStack.clear(); emit forwardAvailable(false); @@ -898,7 +882,7 @@ void QTextBrowser::doSetSource(const QUrl &url, QTextDocument::ResourceType type being the new source. Source changes happen both programmatically when calling - setSource(), forward(), backword() or home() or when the user + setSource(), forward(), backward() or home() or when the user clicks on links or presses the equivalent key sequences. */ @@ -931,14 +915,14 @@ void QTextBrowser::doSetSource(const QUrl &url, QTextDocument::ResourceType type void QTextBrowser::backward() { Q_D(QTextBrowser); - if (d->stack.count() <= 1) + if (d->stack.size() <= 1) return; // Update the history entry d->forwardStack.push(d->createHistoryEntry()); d->stack.pop(); // throw away the old version of the current entry d->restoreHistoryEntry(d->stack.top()); // previous entry - emit backwardAvailable(d->stack.count() > 1); + emit backwardAvailable(d->stack.size() > 1); emit forwardAvailable(true); emit historyChanged(); } @@ -1181,7 +1165,7 @@ QVariant QTextBrowser::loadResource(int /*type*/, const QUrl &name) bool QTextBrowser::isBackwardAvailable() const { Q_D(const QTextBrowser); - return d->stack.count() > 1; + return d->stack.size() > 1; } /*! @@ -1268,7 +1252,7 @@ QString QTextBrowser::historyTitle(int i) const int QTextBrowser::forwardHistoryCount() const { Q_D(const QTextBrowser); - return d->forwardStack.count(); + return d->forwardStack.size(); } /*! @@ -1279,7 +1263,7 @@ int QTextBrowser::forwardHistoryCount() const int QTextBrowser::backwardHistoryCount() const { Q_D(const QTextBrowser); - return d->stack.count()-1; + return d->stack.size()-1; } /*! |