summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorVolker Hilsheimer <volker.hilsheimer@qt.io>2021-03-27 12:29:24 +0100
committerVolker Hilsheimer <volker.hilsheimer@qt.io>2021-03-30 08:11:27 +0200
commitccf1a1a9536be7b904494f5b3243202d71a33b06 (patch)
tree7fa14e4c2f0322f0d32a1fcecf00564afd00e82e /src
parentb050d4867f68c3d35493221d65d343749504c988 (diff)
Replace QTextDocumentResourceProvider with a std::function
376e3bd8ecf40881685714f6f19e12d68e92127e added the new class for Qt 6.1, but during header review we concluded that using a class introduces complexity wrt instance ownership and API design that can be avoided by using a std::function instead. The functionality is tied to QTextDocument, so the type definition and the default provider API is added there. Since std::function is not trivially copyable, the atomicity of the previous implementation is not maintained, and concurrent modifications of and access to the global default provider from multiple threads is not allowed. The relevant use case can be supported by implementing a resource provider that is thread safe. Task-number: QTBUG-90211 Fixes: QTBUG-92208 Pick-to: 6.1 Change-Id: I39215c5e51c7bd27f1dd29e1d9d908aecf754fb7 Reviewed-by: Kai Koehne <kai.koehne@qt.io>
Diffstat (limited to 'src')
-rw-r--r--src/gui/CMakeLists.txt1
-rw-r--r--src/gui/text/qtextdocument.cpp62
-rw-r--r--src/gui/text/qtextdocument.h11
-rw-r--r--src/gui/text/qtextdocument_p.cpp1
-rw-r--r--src/gui/text/qtextdocument_p.h2
-rw-r--r--src/gui/text/qtextdocumentresourceprovider.cpp100
-rw-r--r--src/gui/text/qtextdocumentresourceprovider.h63
-rw-r--r--src/widgets/widgets/qlabel.cpp4
-rw-r--r--src/widgets/widgets/qlabel.h6
-rw-r--r--src/widgets/widgets/qlabel_p.h2
10 files changed, 66 insertions, 186 deletions
diff --git a/src/gui/CMakeLists.txt b/src/gui/CMakeLists.txt
index 451187da17..89cefdc818 100644
--- a/src/gui/CMakeLists.txt
+++ b/src/gui/CMakeLists.txt
@@ -242,7 +242,6 @@ 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/qtextdocumentresourceprovider.cpp text/qtextdocumentresourceprovider.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 9234714f64..e302a1e170 100644
--- a/src/gui/text/qtextdocument.cpp
+++ b/src/gui/text/qtextdocument.cpp
@@ -46,7 +46,6 @@
#include "qtextdocumentfragment_p.h"
#include "qtexttable.h"
#include "qtextlist.h"
-#include "qtextdocumentresourceprovider.h"
#include <qdebug.h>
#if QT_CONFIG(regularexpression)
#include <qregularexpression.h>
@@ -81,6 +80,9 @@ QT_BEGIN_NAMESPACE
Q_CORE_EXPORT Q_DECL_CONST_FUNCTION unsigned int qt_int_sqrt(unsigned int n);
+namespace {
+ QTextDocument::ResourceProvider qt_defaultResourceProvider;
+};
/*!
Returns \c true if the string \a text is likely to be rich text;
@@ -2080,7 +2082,11 @@ void QTextDocument::print(QPagedPaintDevice *printer) const
the resource. loadResource should then use addResource to add the
resource to the cache.
- \sa QTextDocument::ResourceType
+ If loadResource does not load the resource, then the resourceProvider and
+ lastly the defaultResourceProvider will be called, if set. Note that the
+ result from the provider will not be added automatically to the cache.
+
+ \sa QTextDocument::ResourceType, resourceProvider()
*/
QVariant QTextDocument::resource(int type, const QUrl &name) const
{
@@ -2093,9 +2099,9 @@ QVariant QTextDocument::resource(int type, const QUrl &name) const
r = const_cast<QTextDocument *>(this)->loadResource(type, url);
if (!r.isValid()) {
if (d->resourceProvider)
- r = d->resourceProvider->resource(url);
- else if (auto defaultProvider = QTextDocumentResourceProvider::defaultProvider())
- r = defaultProvider->resource(url);
+ r = d->resourceProvider(url);
+ else if (auto defaultProvider = defaultResourceProvider())
+ r = defaultProvider(url);
}
}
}
@@ -2131,27 +2137,63 @@ void QTextDocument::addResource(int type, const QUrl &name, const QVariant &reso
\since 6.1
Returns the resource provider for this text document.
+
+ \sa setResourceProvider(), defaultResourceProvider(), loadResource()
*/
-QTextDocumentResourceProvider *QTextDocument::resourceProvider() const
+QTextDocument::ResourceProvider QTextDocument::resourceProvider() const
{
Q_D(const QTextDocument);
return d->resourceProvider;
}
/*!
+ \since 6.1
+ \typealias QTextDocument::ResourceProvider
+
+ Type alias for std::function\<QVariant(const QUrl&)\>.
+*/
+
+/*!
\since 6.1
- Sets the \a provider of resources for the text document.
+ Sets the provider of resources for the text document to \a provider.
- \note The text document \e{does not} take ownership of the \a provider.
+ \sa resourceProvider(), loadResource()
*/
-void QTextDocument::setResourceProvider(QTextDocumentResourceProvider *provider)
+void QTextDocument::setResourceProvider(const ResourceProvider &provider)
{
Q_D(QTextDocument);
d->resourceProvider = provider;
}
/*!
+ \since 6.1
+
+ Sets the default resource provider to \a provider.
+
+ The default provider will be used by all QTextDocuments that don't have an
+ explicit provider set.
+
+ \sa setResourceProvider(), loadResource()
+*/
+void QTextDocument::setDefaultResourceProvider(const ResourceProvider &provider)
+{
+ qt_defaultResourceProvider = provider;
+}
+
+/*!
+ \since 6.1
+
+ Returns the default resource provider.
+
+ \sa resourceProvider(), loadResource()
+*/
+QTextDocument::ResourceProvider QTextDocument::defaultResourceProvider()
+{
+ return qt_defaultResourceProvider;
+}
+
+/*!
Loads data of the specified \a type from the resource with the
given \a name.
@@ -2168,7 +2210,7 @@ void QTextDocument::setResourceProvider(QTextDocumentResourceProvider *provider)
or a QTextDocument itself then the default implementation tries
to retrieve the data from the parent.
- \sa QTextDocumentResourceProvider
+ \sa QTextDocument::ResourceProvider
*/
QVariant QTextDocument::loadResource(int type, const QUrl &name)
{
diff --git a/src/gui/text/qtextdocument.h b/src/gui/text/qtextdocument.h
index 286b1ed299..dc4d15f3a8 100644
--- a/src/gui/text/qtextdocument.h
+++ b/src/gui/text/qtextdocument.h
@@ -68,8 +68,6 @@ class QVariant;
class QRectF;
class QTextOption;
class QTextCursor;
-class QTextDocumentResourceProvider;
-
namespace Qt
{
@@ -240,8 +238,13 @@ public:
QVariant resource(int type, const QUrl &name) const;
void addResource(int type, const QUrl &name, const QVariant &resource);
- QTextDocumentResourceProvider *resourceProvider() const;
- void setResourceProvider(QTextDocumentResourceProvider *provider);
+ using ResourceProvider = std::function<QVariant(const QUrl&)>;
+
+ QTextDocument::ResourceProvider resourceProvider() const;
+ void setResourceProvider(const ResourceProvider &provider);
+
+ static QTextDocument::ResourceProvider defaultResourceProvider();
+ static void setDefaultResourceProvider(const ResourceProvider &provider);
QList<QTextFormat> allFormats() const;
diff --git a/src/gui/text/qtextdocument_p.cpp b/src/gui/text/qtextdocument_p.cpp
index eb62168a31..c902b878bf 100644
--- a/src/gui/text/qtextdocument_p.cpp
+++ b/src/gui/text/qtextdocument_p.cpp
@@ -52,7 +52,6 @@
#include "qtextdocumentlayout_p.h"
#include "qtexttable.h"
#include "qtextengine_p.h"
-#include "qtextdocumentresourceprovider.h"
#include <stdlib.h>
diff --git a/src/gui/text/qtextdocument_p.h b/src/gui/text/qtextdocument_p.h
index f68cd56d88..adebd0251f 100644
--- a/src/gui/text/qtextdocument_p.h
+++ b/src/gui/text/qtextdocument_p.h
@@ -366,7 +366,7 @@ private:
QMap<int, QTextObject *> objects;
QMap<QUrl, QVariant> resources;
QMap<QUrl, QVariant> cachedResources;
- QTextDocumentResourceProvider *resourceProvider;
+ QTextDocument::ResourceProvider resourceProvider;
QString defaultStyleSheet;
int lastBlockCount;
diff --git a/src/gui/text/qtextdocumentresourceprovider.cpp b/src/gui/text/qtextdocumentresourceprovider.cpp
deleted file mode 100644
index 1a03e1bb44..0000000000
--- a/src/gui/text/qtextdocumentresourceprovider.cpp
+++ /dev/null
@@ -1,100 +0,0 @@
-/****************************************************************************
-**
-** 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 "qtextdocumentresourceprovider.h"
-
-#include <QtCore/qatomic.h>
-
-QT_BEGIN_NAMESPACE
-
-/*!
- \class QTextDocumentResourceProvider
- \inmodule QtGui
- \since 6.1
- \brief The QTextDocumentResourceProvider is the base class of resource providers for QTextDocument.
-
- Override resource() in a subclass, and set a subclass instance on a text document via
- QTextDocument::setResourceProvider, or on a label via QLabel::setResourceProvider. This
- allows customizing how resources are loaded in rich text documents without having to subclass
- QTextDocument or QLabel, respectively.
-
- \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 QTextDocument lives
- outside the main thread.
-*/
-
-static QAtomicPointer<QTextDocumentResourceProvider> qt_provider;
-
-/*!
- Destroys the resource provider.
-*/
-QTextDocumentResourceProvider::~QTextDocumentResourceProvider()
-{
- qt_provider.testAndSetRelease(this, nullptr);
-}
-
-/*!
- \fn virtual QVariant QTextDocumentResourceProvider::resource(const QUrl &url) = 0;
-
- Returns data specified by the \a url.
-
- \sa QTextDocument::loadResource
-*/
-
-/*!
- Returns the default resource provider.
-
- \sa QTextDocument::loadResource
-*/
-QTextDocumentResourceProvider *QTextDocumentResourceProvider::defaultProvider()
-{
- return qt_provider.loadAcquire();
-}
-
-/*!
- Set the default resource provider to \a provider.
-
- \sa QTextDocument::loadResource
-*/
-void QTextDocumentResourceProvider::setDefaultProvider(QTextDocumentResourceProvider *provider)
-{
- qt_provider.storeRelease(provider);
-}
-
-QT_END_NAMESPACE
diff --git a/src/gui/text/qtextdocumentresourceprovider.h b/src/gui/text/qtextdocumentresourceprovider.h
deleted file mode 100644
index 5fd8699e7c..0000000000
--- a/src/gui/text/qtextdocumentresourceprovider.h
+++ /dev/null
@@ -1,63 +0,0 @@
-/****************************************************************************
-**
-** 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 QTEXTDOCUMENTRESOURCEPROVIDER_H
-#define QTEXTDOCUMENTRESOURCEPROVIDER_H
-
-#include <QtGui/qtguiglobal.h>
-#include <QtCore/qvariant.h>
-
-QT_BEGIN_NAMESPACE
-
-
-class Q_GUI_EXPORT QTextDocumentResourceProvider
-{
- Q_DISABLE_COPY(QTextDocumentResourceProvider)
-public:
- QTextDocumentResourceProvider() = default;
- virtual ~QTextDocumentResourceProvider();
- virtual QVariant resource(const QUrl &url) = 0;
-
- static QTextDocumentResourceProvider *defaultProvider();
- static void setDefaultProvider(QTextDocumentResourceProvider *provider);
-};
-
-QT_END_NAMESPACE
-
-#endif // QTEXTDOCUMENTRESOURCEPROVIDER_H
diff --git a/src/widgets/widgets/qlabel.cpp b/src/widgets/widgets/qlabel.cpp
index d2f176c67d..377f2967cf 100644
--- a/src/widgets/widgets/qlabel.cpp
+++ b/src/widgets/widgets/qlabel.cpp
@@ -1429,7 +1429,7 @@ void QLabel::setTextFormat(Qt::TextFormat format)
Returns the resource provider for rich text of this label.
*/
-QTextDocumentResourceProvider *QLabel::resourceProvider() const
+QTextDocument::ResourceProvider QLabel::resourceProvider() const
{
Q_D(const QLabel);
return d->control ? d->control->document()->resourceProvider() : d->resourceProvider;
@@ -1442,7 +1442,7 @@ QTextDocumentResourceProvider *QLabel::resourceProvider() const
\note The label \e{does not} take ownership of the \a provider.
*/
-void QLabel::setResourceProvider(QTextDocumentResourceProvider *provider)
+void QLabel::setResourceProvider(const QTextDocument::ResourceProvider &provider)
{
Q_D(QLabel);
d->resourceProvider = provider;
diff --git a/src/widgets/widgets/qlabel.h b/src/widgets/widgets/qlabel.h
index 1b6e946476..05fb39e0fa 100644
--- a/src/widgets/widgets/qlabel.h
+++ b/src/widgets/widgets/qlabel.h
@@ -43,13 +43,13 @@
#include <QtWidgets/qtwidgetsglobal.h>
#include <QtWidgets/qframe.h>
#include <QtGui/qpicture.h>
+#include <QtGui/qtextdocument.h>
QT_REQUIRE_CONFIG(label);
QT_BEGIN_NAMESPACE
-class QTextDocumentResourceProvider;
class QLabelPrivate;
class Q_WIDGETS_EXPORT QLabel : public QFrame
@@ -93,8 +93,8 @@ public:
Qt::TextFormat textFormat() const;
void setTextFormat(Qt::TextFormat);
- QTextDocumentResourceProvider *resourceProvider() const;
- void setResourceProvider(QTextDocumentResourceProvider *provider);
+ QTextDocument::ResourceProvider resourceProvider() const;
+ void setResourceProvider(const QTextDocument::ResourceProvider &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 635042a8cd..d26bbf6a7f 100644
--- a/src/widgets/widgets/qlabel_p.h
+++ b/src/widgets/widgets/qlabel_p.h
@@ -154,7 +154,7 @@ public:
#endif
uint openExternalLinks : 1;
// <-- space for more bit field values here
- QTextDocumentResourceProvider *resourceProvider;
+ QTextDocument::ResourceProvider resourceProvider;
friend class QMessageBoxPrivate;
};