Introduce QTextDocument::baseUrl
Required for QQuickText & friends to implement image resource handling in a clean way - to get rid of QQuickTextDocumentWithImageResources and eventually make QQuickTextEdit's document interchangeable. Change-Id: I97314a6c3e2d5726539d5722795a472631388cb0 Reviewed-by: Konstantin Ritt <ritt.ks@gmail.com>
This commit is contained in:
parent
2ced0cb08d
commit
1f22c1d981
@ -550,6 +550,39 @@ void QTextDocument::setDefaultTextOption(const QTextOption &option)
|
|||||||
d->lout->documentChanged(0, 0, d->length());
|
d->lout->documentChanged(0, 0, d->length());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\property QTextDocument::baseUrl
|
||||||
|
\since 5.3
|
||||||
|
\brief the base URL used to resolve relative resource URLs within the document.
|
||||||
|
|
||||||
|
Resource URLs are resolved to be within the same directory as the target of the base
|
||||||
|
URL meaning any portion of the path after the last '/' will be ignored.
|
||||||
|
|
||||||
|
\table
|
||||||
|
\header \li Base URL \li Relative URL \li Resolved URL
|
||||||
|
\row \li file:///path/to/content \li images/logo.png \li file:///path/to/images/logo.png
|
||||||
|
\row \li file:///path/to/content/ \li images/logo.png \li file:///path/to/content/images/logo.png
|
||||||
|
\row \li file:///path/to/content/index.html \li images/logo.png \li file:///path/to/content/images/logo.png
|
||||||
|
\row \li file:///path/to/content/images/ \li ../images/logo.png \li file:///path/to/content/images/logo.png
|
||||||
|
\endtable
|
||||||
|
*/
|
||||||
|
QUrl QTextDocument::baseUrl() const
|
||||||
|
{
|
||||||
|
Q_D(const QTextDocument);
|
||||||
|
return d->baseUrl;
|
||||||
|
}
|
||||||
|
|
||||||
|
void QTextDocument::setBaseUrl(const QUrl &url)
|
||||||
|
{
|
||||||
|
Q_D(QTextDocument);
|
||||||
|
if (d->baseUrl != url) {
|
||||||
|
d->baseUrl = url;
|
||||||
|
if (d->lout)
|
||||||
|
d->lout->documentChanged(0, 0, d->length());
|
||||||
|
emit baseUrlChanged(url);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\since 4.8
|
\since 4.8
|
||||||
|
|
||||||
@ -1849,11 +1882,12 @@ void QTextDocument::print(QPagedPaintDevice *printer) const
|
|||||||
QVariant QTextDocument::resource(int type, const QUrl &name) const
|
QVariant QTextDocument::resource(int type, const QUrl &name) const
|
||||||
{
|
{
|
||||||
Q_D(const QTextDocument);
|
Q_D(const QTextDocument);
|
||||||
QVariant r = d->resources.value(name);
|
const QUrl url = d->baseUrl.resolved(name);
|
||||||
|
QVariant r = d->resources.value(url);
|
||||||
if (!r.isValid()) {
|
if (!r.isValid()) {
|
||||||
r = d->cachedResources.value(name);
|
r = d->cachedResources.value(url);
|
||||||
if (!r.isValid())
|
if (!r.isValid())
|
||||||
r = const_cast<QTextDocument *>(this)->loadResource(type, name);
|
r = const_cast<QTextDocument *>(this)->loadResource(type, url);
|
||||||
}
|
}
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
@ -1924,27 +1958,29 @@ QVariant QTextDocument::loadResource(int type, const QUrl &name)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// if resource was not loaded try to load it here
|
// if resource was not loaded try to load it here
|
||||||
if (!qobject_cast<QTextDocument *>(p) && r.isNull() && name.isRelative()) {
|
if (!qobject_cast<QTextDocument *>(p) && r.isNull()) {
|
||||||
QUrl currentURL = d->url;
|
|
||||||
QUrl resourceUrl = name;
|
QUrl resourceUrl = name;
|
||||||
|
|
||||||
// For the second case QUrl can merge "#someanchor" with "foo.html"
|
if (name.isRelative()) {
|
||||||
// correctly to "foo.html#someanchor"
|
QUrl currentURL = d->url;
|
||||||
if (!(currentURL.isRelative()
|
// For the second case QUrl can merge "#someanchor" with "foo.html"
|
||||||
|| (currentURL.scheme() == QLatin1String("file")
|
// correctly to "foo.html#someanchor"
|
||||||
&& !QFileInfo(currentURL.toLocalFile()).isAbsolute()))
|
if (!(currentURL.isRelative()
|
||||||
|| (name.hasFragment() && name.path().isEmpty())) {
|
|| (currentURL.scheme() == QLatin1String("file")
|
||||||
resourceUrl = currentURL.resolved(name);
|
&& !QFileInfo(currentURL.toLocalFile()).isAbsolute()))
|
||||||
} else {
|
|| (name.hasFragment() && name.path().isEmpty())) {
|
||||||
// this is our last resort when current url and new url are both relative
|
resourceUrl = currentURL.resolved(name);
|
||||||
// we try to resolve against the current working directory in the local
|
} else {
|
||||||
// file system.
|
// this is our last resort when current url and new url are both relative
|
||||||
QFileInfo fi(currentURL.toLocalFile());
|
// we try to resolve against the current working directory in the local
|
||||||
if (fi.exists()) {
|
// file system.
|
||||||
resourceUrl =
|
QFileInfo fi(currentURL.toLocalFile());
|
||||||
QUrl::fromLocalFile(fi.absolutePath() + QDir::separator()).resolved(name);
|
if (fi.exists()) {
|
||||||
} else if (currentURL.isEmpty()) {
|
resourceUrl =
|
||||||
resourceUrl.setScheme(QLatin1String("file"));
|
QUrl::fromLocalFile(fi.absolutePath() + QDir::separator()).resolved(name);
|
||||||
|
} else if (currentURL.isEmpty()) {
|
||||||
|
resourceUrl.setScheme(QLatin1String("file"));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -47,6 +47,7 @@
|
|||||||
#include <QtCore/qrect.h>
|
#include <QtCore/qrect.h>
|
||||||
#include <QtCore/qvariant.h>
|
#include <QtCore/qvariant.h>
|
||||||
#include <QtGui/qfont.h>
|
#include <QtGui/qfont.h>
|
||||||
|
#include <QtCore/qurl.h>
|
||||||
|
|
||||||
QT_BEGIN_NAMESPACE
|
QT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
@ -63,7 +64,6 @@ class QTextFormat;
|
|||||||
class QTextFrame;
|
class QTextFrame;
|
||||||
class QTextBlock;
|
class QTextBlock;
|
||||||
class QTextCodec;
|
class QTextCodec;
|
||||||
class QUrl;
|
|
||||||
class QVariant;
|
class QVariant;
|
||||||
class QRectF;
|
class QRectF;
|
||||||
class QTextOption;
|
class QTextOption;
|
||||||
@ -114,6 +114,7 @@ class Q_GUI_EXPORT QTextDocument : public QObject
|
|||||||
Q_PROPERTY(int maximumBlockCount READ maximumBlockCount WRITE setMaximumBlockCount)
|
Q_PROPERTY(int maximumBlockCount READ maximumBlockCount WRITE setMaximumBlockCount)
|
||||||
Q_PROPERTY(qreal documentMargin READ documentMargin WRITE setDocumentMargin)
|
Q_PROPERTY(qreal documentMargin READ documentMargin WRITE setDocumentMargin)
|
||||||
QDOC_PROPERTY(QTextOption defaultTextOption READ defaultTextOption WRITE setDefaultTextOption)
|
QDOC_PROPERTY(QTextOption defaultTextOption READ defaultTextOption WRITE setDefaultTextOption)
|
||||||
|
Q_PROPERTY(QUrl baseUrl READ baseUrl WRITE setBaseUrl NOTIFY baseUrlChanged)
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit QTextDocument(QObject *parent = 0);
|
explicit QTextDocument(QObject *parent = 0);
|
||||||
@ -256,6 +257,9 @@ public:
|
|||||||
QTextOption defaultTextOption() const;
|
QTextOption defaultTextOption() const;
|
||||||
void setDefaultTextOption(const QTextOption &option);
|
void setDefaultTextOption(const QTextOption &option);
|
||||||
|
|
||||||
|
QUrl baseUrl() const;
|
||||||
|
void setBaseUrl(const QUrl &url);
|
||||||
|
|
||||||
Qt::CursorMoveStyle defaultCursorMoveStyle() const;
|
Qt::CursorMoveStyle defaultCursorMoveStyle() const;
|
||||||
void setDefaultCursorMoveStyle(Qt::CursorMoveStyle style);
|
void setDefaultCursorMoveStyle(Qt::CursorMoveStyle style);
|
||||||
|
|
||||||
@ -268,7 +272,7 @@ Q_SIGNALS:
|
|||||||
void modificationChanged(bool m);
|
void modificationChanged(bool m);
|
||||||
void cursorPositionChanged(const QTextCursor &cursor);
|
void cursorPositionChanged(const QTextCursor &cursor);
|
||||||
void blockCountChanged(int newBlockCount);
|
void blockCountChanged(int newBlockCount);
|
||||||
|
void baseUrlChanged(const QUrl &url);
|
||||||
void documentLayoutChanged();
|
void documentLayoutChanged();
|
||||||
|
|
||||||
public Q_SLOTS:
|
public Q_SLOTS:
|
||||||
|
@ -355,6 +355,7 @@ public:
|
|||||||
QString url;
|
QString url;
|
||||||
qreal indentWidth;
|
qreal indentWidth;
|
||||||
qreal documentMargin;
|
qreal documentMargin;
|
||||||
|
QUrl baseUrl;
|
||||||
|
|
||||||
void mergeCachedResources(const QTextDocumentPrivate *priv);
|
void mergeCachedResources(const QTextDocumentPrivate *priv);
|
||||||
|
|
||||||
|
@ -189,6 +189,9 @@ private slots:
|
|||||||
void QTBUG27354_spaceAndSoftSpace();
|
void QTBUG27354_spaceAndSoftSpace();
|
||||||
void cssInheritance();
|
void cssInheritance();
|
||||||
|
|
||||||
|
void baseUrl_data();
|
||||||
|
void baseUrl();
|
||||||
|
|
||||||
void QTBUG28998_linkColor();
|
void QTBUG28998_linkColor();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@ -2978,6 +2981,53 @@ void tst_QTextDocument::cssInheritance()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class BaseDocument : public QTextDocument
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
QUrl loadedResource() const { return resourceUrl; }
|
||||||
|
|
||||||
|
QVariant loadResource(int type, const QUrl &name)
|
||||||
|
{
|
||||||
|
resourceUrl = name;
|
||||||
|
return QTextDocument::loadResource(type, name);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
QUrl resourceUrl;
|
||||||
|
};
|
||||||
|
|
||||||
|
void tst_QTextDocument::baseUrl_data()
|
||||||
|
{
|
||||||
|
QTest::addColumn<QUrl>("base");
|
||||||
|
QTest::addColumn<QUrl>("resource");
|
||||||
|
QTest::addColumn<QUrl>("loaded");
|
||||||
|
|
||||||
|
QTest::newRow("1") << QUrl() << QUrl("images/logo.png") << QUrl("images/logo.png");
|
||||||
|
QTest::newRow("2") << QUrl("file:///path/to/content") << QUrl("images/logo.png") << QUrl("file:///path/to/images/logo.png");
|
||||||
|
QTest::newRow("3") << QUrl("file:///path/to/content/") << QUrl("images/logo.png") << QUrl("file:///path/to/content/images/logo.png");
|
||||||
|
QTest::newRow("4") << QUrl("file:///path/to/content/images") << QUrl("images/logo.png") << QUrl("file:///path/to/content/images/logo.png");
|
||||||
|
QTest::newRow("5") << QUrl("file:///path/to/content/images/") << QUrl("images/logo.png") << QUrl("file:///path/to/content/images/images/logo.png");
|
||||||
|
QTest::newRow("6") << QUrl("file:///path/to/content/images") << QUrl("../images/logo.png") << QUrl("file:///path/to/images/logo.png");
|
||||||
|
QTest::newRow("7") << QUrl("file:///path/to/content/images/") << QUrl("../images/logo.png") << QUrl("file:///path/to/content/images/logo.png");
|
||||||
|
QTest::newRow("8") << QUrl("file:///path/to/content/index.html") << QUrl("images/logo.png") << QUrl("file:///path/to/content/images/logo.png");
|
||||||
|
}
|
||||||
|
|
||||||
|
void tst_QTextDocument::baseUrl()
|
||||||
|
{
|
||||||
|
QFETCH(QUrl, base);
|
||||||
|
QFETCH(QUrl, resource);
|
||||||
|
QFETCH(QUrl, loaded);
|
||||||
|
|
||||||
|
BaseDocument document;
|
||||||
|
QVERIFY(!document.baseUrl().isValid());
|
||||||
|
document.setBaseUrl(base);
|
||||||
|
QCOMPARE(document.baseUrl(), base);
|
||||||
|
|
||||||
|
document.setHtml(QString("<img src='%1'/>").arg(resource.toString()));
|
||||||
|
document.resource(QTextDocument::ImageResource, resource);
|
||||||
|
QCOMPARE(document.loadedResource(), loaded);
|
||||||
|
}
|
||||||
|
|
||||||
void tst_QTextDocument::QTBUG28998_linkColor()
|
void tst_QTextDocument::QTBUG28998_linkColor()
|
||||||
{
|
{
|
||||||
QPalette pal;
|
QPalette pal;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user