diff options
author | Alexander Volkov <avolkov@astralinux.ru> | 2018-09-25 18:09:28 +0300 |
---|---|---|
committer | Alexander Volkov <avolkov@astralinux.ru> | 2021-01-12 15:33:10 +0300 |
commit | 376e3bd8ecf40881685714f6f19e12d68e92127e (patch) | |
tree | 8a137b8cea51115b405202ef6c0cffdf6fe78192 /src | |
parent | 9e09677c1dd4da92735736a0fbcb703416bf4d6d (diff) |
Introduce QUrlResourceProvider to load resources for HTML
QTextDocument and the text editor classes suggest to override
their loadResource() methods to provide data associated with
a text document. This approach has the following drawbacks:
- it requires subclassing
- there is no way to set a global resource provider
- QLabel is missing virtual loadResource() method and
it can't be added without breaking ABI
QUrlResourceProvider is designed to solve these issues.
One should create a derived class that implements
QUrlResourceProvider::resource(). The objects of the derived
class then can be set for any text document.
The default resource provider can be set with
QUrlResourceProvider::setDefaultProvider().
This change also adds QLabel::setResourceProvider(),
which doesn't break ABI.
[ChangeLog][QtGui][Text] Introduced QUrlResourceProvider that allows to
load resources for HTML. It is intended to replace the use of
QTextDocument::loadResource().
Change-Id: Iaf19b229f522a73508f20715257450fe58f68daf
Reviewed-by: Konstantin Ritt <ritt.ks@gmail.com>
Reviewed-by: Lars Knoll <lars.knoll@qt.io>
Diffstat (limited to 'src')
-rw-r--r-- | src/gui/CMakeLists.txt | 1 | ||||
-rw-r--r-- | src/gui/text/qtextdocument.cpp | 35 | ||||
-rw-r--r-- | src/gui/text/qtextdocument.h | 4 | ||||
-rw-r--r-- | src/gui/text/qtextdocument_p.cpp | 4 | ||||
-rw-r--r-- | src/gui/text/qtextdocument_p.h | 1 | ||||
-rw-r--r-- | src/gui/text/qurlresourceprovider.cpp | 88 | ||||
-rw-r--r-- | src/gui/text/qurlresourceprovider.h | 61 | ||||
-rw-r--r-- | src/widgets/widgets/qlabel.cpp | 31 | ||||
-rw-r--r-- | src/widgets/widgets/qlabel.h | 4 | ||||
-rw-r--r-- | src/widgets/widgets/qlabel_p.h | 1 | ||||
-rw-r--r-- | src/widgets/widgets/qwidgettextcontrol.cpp | 1 |
11 files changed, 228 insertions, 3 deletions
diff --git a/src/gui/CMakeLists.txt b/src/gui/CMakeLists.txt index 802c0a2ecd..30e28cfd0e 100644 --- a/src/gui/CMakeLists.txt +++ b/src/gui/CMakeLists.txt @@ -242,6 +242,7 @@ qt_internal_add_module(Gui text/qtextobject.cpp text/qtextobject.h text/qtextobject_p.h text/qtextoption.cpp text/qtextoption.h text/qtexttable.cpp text/qtexttable.h text/qtexttable_p.h + text/qurlresourceprovider.cpp text/qurlresourceprovider.h util/qabstractlayoutstyleinfo.cpp util/qabstractlayoutstyleinfo_p.h util/qastchandler.cpp util/qastchandler_p.h util/qdesktopservices.cpp util/qdesktopservices.h diff --git a/src/gui/text/qtextdocument.cpp b/src/gui/text/qtextdocument.cpp index 0fae775bae..2e9293eb99 100644 --- a/src/gui/text/qtextdocument.cpp +++ b/src/gui/text/qtextdocument.cpp @@ -46,6 +46,7 @@ #include "qtextdocumentfragment_p.h" #include "qtexttable.h" #include "qtextlist.h" +#include "qurlresourceprovider.h" #include <qdebug.h> #if QT_CONFIG(regularexpression) #include <qregularexpression.h> @@ -354,6 +355,7 @@ QTextDocument *QTextDocument::clone(QObject *parent) const priv->setDefaultFont(d->defaultFont()); priv->resources = d->resources; priv->cachedResources.clear(); + priv->resourceProvider = d->resourceProvider; #ifndef QT_NO_CSSPARSER priv->defaultStyleSheet = d->defaultStyleSheet; priv->parsedDefaultStyleSheet = d->parsedDefaultStyleSheet; @@ -2087,8 +2089,15 @@ QVariant QTextDocument::resource(int type, const QUrl &name) const QVariant r = d->resources.value(url); if (!r.isValid()) { r = d->cachedResources.value(url); - if (!r.isValid()) + if (!r.isValid()) { r = const_cast<QTextDocument *>(this)->loadResource(type, url); + if (!r.isValid()) { + if (d->resourceProvider) + r = d->resourceProvider->resource(url); + else if (auto defaultProvider = QUrlResourceProvider::defaultProvider()) + r = defaultProvider->resource(url); + } + } } return r; } @@ -2119,6 +2128,30 @@ void QTextDocument::addResource(int type, const QUrl &name, const QVariant &reso } /*! + \since 6.1 + + Returns the resource provider for this text document. +*/ +QUrlResourceProvider *QTextDocument::resourceProvider() const +{ + Q_D(const QTextDocument); + return d->resourceProvider; +} + +/*! + \since 6.1 + + Sets the \a provider of resources for the text document. + + \note The text document \e{does not} take ownership of the \a provider. +*/ +void QTextDocument::setResourceProvider(QUrlResourceProvider *provider) +{ + Q_D(QTextDocument); + d->resourceProvider = provider; +} + +/*! Loads data of the specified \a type from the resource with the given \a name. diff --git a/src/gui/text/qtextdocument.h b/src/gui/text/qtextdocument.h index 23fffc4771..ea57b697a8 100644 --- a/src/gui/text/qtextdocument.h +++ b/src/gui/text/qtextdocument.h @@ -68,6 +68,7 @@ class QVariant; class QRectF; class QTextOption; class QTextCursor; +class QUrlResourceProvider; namespace Qt @@ -239,6 +240,9 @@ public: QVariant resource(int type, const QUrl &name) const; void addResource(int type, const QUrl &name, const QVariant &resource); + QUrlResourceProvider *resourceProvider() const; + void setResourceProvider(QUrlResourceProvider *provider); + QList<QTextFormat> allFormats() const; void markContentsDirty(int from, int length); diff --git a/src/gui/text/qtextdocument_p.cpp b/src/gui/text/qtextdocument_p.cpp index d6da0f38d2..1f2e8d2da2 100644 --- a/src/gui/text/qtextdocument_p.cpp +++ b/src/gui/text/qtextdocument_p.cpp @@ -52,6 +52,7 @@ #include "qtextdocumentlayout_p.h" #include "qtexttable.h" #include "qtextengine_p.h" +#include "qurlresourceprovider.h" #include <stdlib.h> @@ -186,7 +187,8 @@ QTextDocumentPrivate::QTextDocumentPrivate() docChangeLength(0), framesDirty(true), rtFrame(nullptr), - initialBlockCharFormatIndex(-1) // set correctly later in init() + initialBlockCharFormatIndex(-1), // set correctly later in init() + resourceProvider(nullptr) { editBlock = 0; editBlockCursorPosition = -1; diff --git a/src/gui/text/qtextdocument_p.h b/src/gui/text/qtextdocument_p.h index b4e0f526d0..d04113b320 100644 --- a/src/gui/text/qtextdocument_p.h +++ b/src/gui/text/qtextdocument_p.h @@ -366,6 +366,7 @@ private: QMap<int, QTextObject *> objects; QMap<QUrl, QVariant> resources; QMap<QUrl, QVariant> cachedResources; + QUrlResourceProvider *resourceProvider; QString defaultStyleSheet; int lastBlockCount; diff --git a/src/gui/text/qurlresourceprovider.cpp b/src/gui/text/qurlresourceprovider.cpp new file mode 100644 index 0000000000..6a50504471 --- /dev/null +++ b/src/gui/text/qurlresourceprovider.cpp @@ -0,0 +1,88 @@ +/**************************************************************************** +** +** Copyright (C) 2020 Alexander Volkov <avolkov@astralinux.ru> +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtGui 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$ +** +****************************************************************************/ + +#include "qurlresourceprovider.h" + +#include <QtCore/qatomic.h> + +QT_BEGIN_NAMESPACE + +/*! + \class QUrlResourceProvider + \inmodule QtGui + \since 6.1 + \brief The QUrlResourceProvider is the base class of resource providers for QTextDocument. + \note An implementation should be thread-safe if it can be accessed from different threads, + e.g. when the default resource provider lives in the main thread and a QTexDocument lives + outside the main thread. +*/ + +static QAtomicPointer<QUrlResourceProvider> qt_provider; + +/*! + Destroys the resource provider. +*/ +QUrlResourceProvider::~QUrlResourceProvider() +{ + qt_provider.testAndSetRelease(this, nullptr); +} + +/*! + \fn virtual QVariant QUrlResourceProvider::resource(const QUrl &url) = 0; + + Returns data specified by the \a url. +*/ + +/*! + Returns the default resource provider. +*/ +QUrlResourceProvider *QUrlResourceProvider::defaultProvider() +{ + return qt_provider.loadAcquire(); +} + +/*! + Set the default resource provider to \a provider. +*/ +void QUrlResourceProvider::setDefaultProvider(QUrlResourceProvider *provider) +{ + qt_provider.storeRelease(provider); +} + +QT_END_NAMESPACE diff --git a/src/gui/text/qurlresourceprovider.h b/src/gui/text/qurlresourceprovider.h new file mode 100644 index 0000000000..587a371a83 --- /dev/null +++ b/src/gui/text/qurlresourceprovider.h @@ -0,0 +1,61 @@ +/**************************************************************************** +** +** Copyright (C) 2020 Alexander Volkov <avolkov@astralinux.ru> +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtGui 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$ +** +****************************************************************************/ + +#ifndef QURLRESOURCEPROVIDER_H +#define QURLRESOURCEPROVIDER_H + +#include <QtGui/qtguiglobal.h> +#include <QtCore/qvariant.h> + +QT_BEGIN_NAMESPACE + + +class Q_GUI_EXPORT QUrlResourceProvider +{ +public: + virtual ~QUrlResourceProvider(); + virtual QVariant resource(const QUrl &url) = 0; + + static QUrlResourceProvider *defaultProvider(); + static void setDefaultProvider(QUrlResourceProvider *provider); +}; + +QT_END_NAMESPACE + +#endif // QURLRESOURCEPROVIDER_H diff --git a/src/widgets/widgets/qlabel.cpp b/src/widgets/widgets/qlabel.cpp index e124022e52..2d7b7f79b1 100644 --- a/src/widgets/widgets/qlabel.cpp +++ b/src/widgets/widgets/qlabel.cpp @@ -100,7 +100,8 @@ QLabelPrivate::QLabelPrivate() validCursor(false), onAnchor(false), #endif - openExternalLinks(false) + openExternalLinks(false), + resourceProvider(nullptr) { } @@ -1424,6 +1425,32 @@ void QLabel::setTextFormat(Qt::TextFormat format) } /*! + \since 6.1 + + Returns the resource provider for rich text of this label. +*/ +QUrlResourceProvider *QLabel::resourceProvider() const +{ + Q_D(const QLabel); + return d->control ? d->control->document()->resourceProvider() : d->resourceProvider; +} + +/*! + \since 6.1 + + Sets the \a provider of resources for rich text of this label. + + \note The label \e{does not} take ownership of the \a provider. +*/ +void QLabel::setResourceProvider(QUrlResourceProvider *provider) +{ + Q_D(QLabel); + d->resourceProvider = provider; + if (d->control != nullptr) + d->control->document()->setResourceProvider(provider); +} + +/*! \reimp */ void QLabel::changeEvent(QEvent *ev) @@ -1589,6 +1616,8 @@ void QLabelPrivate::ensureTextControl() const control = new QWidgetTextControl(const_cast<QLabel *>(q)); control->document()->setUndoRedoEnabled(false); control->document()->setDefaultFont(q->font()); + if (resourceProvider != nullptr) + control->document()->setResourceProvider(resourceProvider); control->setTextInteractionFlags(textInteractionFlags); control->setOpenExternalLinks(openExternalLinks); control->setPalette(q->palette()); diff --git a/src/widgets/widgets/qlabel.h b/src/widgets/widgets/qlabel.h index 8cc86b421e..69aea6d57a 100644 --- a/src/widgets/widgets/qlabel.h +++ b/src/widgets/widgets/qlabel.h @@ -49,6 +49,7 @@ QT_REQUIRE_CONFIG(label); QT_BEGIN_NAMESPACE +class QUrlResourceProvider; class QLabelPrivate; class Q_WIDGETS_EXPORT QLabel : public QFrame @@ -92,6 +93,9 @@ public: Qt::TextFormat textFormat() const; void setTextFormat(Qt::TextFormat); + QUrlResourceProvider *resourceProvider() const; + void setResourceProvider(QUrlResourceProvider *provider); + Qt::Alignment alignment() const; void setAlignment(Qt::Alignment); diff --git a/src/widgets/widgets/qlabel_p.h b/src/widgets/widgets/qlabel_p.h index 4458df3b3e..80243239d2 100644 --- a/src/widgets/widgets/qlabel_p.h +++ b/src/widgets/widgets/qlabel_p.h @@ -154,6 +154,7 @@ public: #endif uint openExternalLinks : 1; // <-- space for more bit field values here + QUrlResourceProvider *resourceProvider; friend class QMessageBoxPrivate; }; diff --git a/src/widgets/widgets/qwidgettextcontrol.cpp b/src/widgets/widgets/qwidgettextcontrol.cpp index 9fe6e3e1e3..ef1be67975 100644 --- a/src/widgets/widgets/qwidgettextcontrol.cpp +++ b/src/widgets/widgets/qwidgettextcontrol.cpp @@ -2677,6 +2677,7 @@ void QWidgetTextControl::print(QPagedPaintDevice *printer) const if (!d->cursor.hasSelection()) return; tempDoc = new QTextDocument(const_cast<QTextDocument *>(doc)); + tempDoc->setResourceProvider(doc->resourceProvider()); tempDoc->setMetaInformation(QTextDocument::DocumentTitle, doc->metaInformation(QTextDocument::DocumentTitle)); tempDoc->setPageSize(doc->pageSize()); tempDoc->setDefaultFont(doc->defaultFont()); |