From bab2eaf3da299c471dd898c89cf356984b077412 Mon Sep 17 00:00:00 2001
From: Andrew den Exter <andrew.den-exter@nokia.com>
Date: Mon, 16 Jan 2012 16:40:13 +1000
Subject: [PATCH] Don't load embedded images from the current working
 directory.

Override QTextImageHandler's image loading as it will attempt to resolve
relative paths and load the image itself if the document returns an
invalid image from loadResource, which we don't want as it bypasses the
pixmap cache and resolves against the application and current working
directory instead of the Text items context.

Change-Id: Ia1d3633036f96d902e1ac03dae5d5b203fba7ff1
Reviewed-by: Martin Jones <martin.jones@nokia.com>
---
 src/quick/items/qquicktext.cpp                | 120 ++++++++++++++----
 src/quick/items/qquicktext_p.h                |   3 +
 src/quick/items/qquicktext_p_p.h              |  16 ++-
 src/quick/items/qquicktextedit.cpp            |   1 +
 src/quick/items/qquicktextedit_p.h            |   6 +-
 src/quick/items/qquicktextedit_p_p.h          |   3 +
 src/quick/items/qquicktextnode.cpp            |  12 +-
 .../qtquick2/qquicktext/tst_qquicktext.cpp    |   1 +
 .../data/embeddedImagesLocal.qml              |   6 +
 .../data/embeddedImagesLocalError.qml         |   6 +
 .../data/embeddedImagesRemote.qml             |   6 +
 .../data/embeddedImagesRemoteError.qml        |   6 +
 .../qquicktextedit/data/http/exists.png       | Bin 0 -> 2738 bytes
 .../qquicktextedit/tst_qquicktextedit.cpp     |  46 +++++++
 14 files changed, 203 insertions(+), 29 deletions(-)
 create mode 100644 tests/auto/qtquick2/qquicktextedit/data/embeddedImagesLocal.qml
 create mode 100644 tests/auto/qtquick2/qquicktextedit/data/embeddedImagesLocalError.qml
 create mode 100644 tests/auto/qtquick2/qquicktextedit/data/embeddedImagesRemote.qml
 create mode 100644 tests/auto/qtquick2/qquicktextedit/data/embeddedImagesRemoteError.qml
 create mode 100644 tests/auto/qtquick2/qquicktextedit/data/http/exists.png

diff --git a/src/quick/items/qquicktext.cpp b/src/quick/items/qquicktext.cpp
index e8eb555dde..fb9022072a 100644
--- a/src/quick/items/qquicktext.cpp
+++ b/src/quick/items/qquicktext.cpp
@@ -107,6 +107,7 @@ QQuickTextDocumentWithImageResources::QQuickTextDocumentWithImageResources(QQuic
 : QTextDocument(parent), outstanding(0)
 {
     setUndoRedoEnabled(false);
+    documentLayout()->registerHandler(QTextFormat::ImageObject, this);
 }
 
 QQuickTextDocumentWithImageResources::~QQuickTextDocumentWithImageResources()
@@ -121,27 +122,8 @@ QVariant QQuickTextDocumentWithImageResources::loadResource(int type, const QUrl
     QUrl url = context->resolvedUrl(name);
 
     if (type == QTextDocument::ImageResource) {
-        QHash<QUrl, QDeclarativePixmap *>::Iterator iter = m_resources.find(url);
-
-        if (iter == m_resources.end()) {
-            QDeclarativePixmap *p = new QDeclarativePixmap(context->engine(), url);
-            iter = m_resources.insert(url, p);
-
-            if (p->isLoading()) {
-                p->connectFinished(this, SLOT(requestFinished()));
-                outstanding++;
-            }
-        }
-
-        QDeclarativePixmap *p = *iter;
-        if (p->isReady()) {
-            return p->image();
-        } else if (p->isError()) {
-            if (!errors.contains(url)) {
-                errors.insert(url);
-                qmlInfo(parent()) << p->error();
-            }
-        }
+        QDeclarativePixmap *p = loadPixmap(context, url);
+        return p->image();
     }
 
     return QTextDocument::loadResource(type,url); // The *resolved* URL
@@ -152,9 +134,7 @@ void QQuickTextDocumentWithImageResources::requestFinished()
     outstanding--;
     if (outstanding == 0) {
         markContentsDirty(0, characterCount());
-
-        if (QQuickText *item = qobject_cast<QQuickText *>(parent()))
-            QQuickTextPrivate::get(item)->updateLayout();
+        emit imagesLoaded();
     }
 }
 
@@ -165,6 +145,91 @@ void QQuickTextDocumentWithImageResources::clear()
     QTextDocument::clear();
 }
 
+
+QSizeF QQuickTextDocumentWithImageResources::intrinsicSize(
+        QTextDocument *, int, const QTextFormat &format)
+{
+    if (format.isImageFormat()) {
+        QTextImageFormat imageFormat = format.toImageFormat();
+
+        const bool hasWidth = imageFormat.hasProperty(QTextFormat::ImageWidth);
+        const int width = qRound(imageFormat.width());
+        const bool hasHeight = imageFormat.hasProperty(QTextFormat::ImageHeight);
+        const int height = qRound(imageFormat.height());
+
+        QSizeF size(width, height);
+        if (!hasWidth || !hasHeight) {
+            QDeclarativeContext *context = qmlContext(parent());
+            QUrl url = context->resolvedUrl(QUrl(imageFormat.name()));
+
+            QDeclarativePixmap *p = loadPixmap(context, url);
+            if (!p->isReady()) {
+                if (!hasWidth)
+                    size.setWidth(16);
+                if (!hasHeight)
+                    size.setHeight(16);
+                return size;
+            }
+            QSize implicitSize = p->implicitSize();
+
+            if (!hasWidth) {
+                if (!hasHeight)
+                    size.setWidth(implicitSize.width());
+                else
+                    size.setWidth(qRound(height * (implicitSize.width() / (qreal) implicitSize.height())));
+            }
+            if (!hasHeight) {
+                if (!hasWidth)
+                    size.setHeight(implicitSize.height());
+                else
+                    size.setHeight(qRound(width * (implicitSize.height() / (qreal) implicitSize.width())));
+            }
+        }
+        return size;
+    }
+    return QSizeF();
+}
+
+void QQuickTextDocumentWithImageResources::drawObject(
+        QPainter *, const QRectF &, QTextDocument *, int, const QTextFormat &)
+{
+}
+
+QImage QQuickTextDocumentWithImageResources::image(const QTextImageFormat &format)
+{
+    QDeclarativeContext *context = qmlContext(parent());
+    QUrl url = context->resolvedUrl(QUrl(format.name()));
+
+    QDeclarativePixmap *p = loadPixmap(context, url);
+    return p->image();
+}
+
+QDeclarativePixmap *QQuickTextDocumentWithImageResources::loadPixmap(
+        QDeclarativeContext *context, const QUrl &url)
+{
+
+    QHash<QUrl, QDeclarativePixmap *>::Iterator iter = m_resources.find(url);
+
+    if (iter == m_resources.end()) {
+        QDeclarativePixmap *p = new QDeclarativePixmap(context->engine(), url);
+        iter = m_resources.insert(url, p);
+
+        if (p->isLoading()) {
+            p->connectFinished(this, SLOT(requestFinished()));
+            outstanding++;
+        }
+    }
+
+    QDeclarativePixmap *p = *iter;
+    if (p->isError()) {
+        if (!errors.contains(url)) {
+            errors.insert(url);
+            qmlInfo(parent()) << p->error();
+        }
+    }
+    return p;
+}
+
 void QQuickTextDocumentWithImageResources::clearResources()
 {
     foreach (QDeclarativePixmap *pixmap, m_resources)
@@ -206,6 +271,12 @@ qreal QQuickTextPrivate::getImplicitWidth() const
     return implicitWidth;
 }
 
+void QQuickText::q_imagesLoaded()
+{
+    Q_D(QQuickText);
+    d->updateLayout();
+}
+
 void QQuickTextPrivate::updateLayout()
 {
     Q_Q(QQuickText);
@@ -830,6 +901,7 @@ void QQuickTextPrivate::ensureDoc()
         Q_Q(QQuickText);
         doc = new QQuickTextDocumentWithImageResources(q);
         doc->setDocumentMargin(0);
+        FAST_CONNECT(doc, SIGNAL(imagesLoaded()), q, SLOT(q_imagesLoaded()));
     }
 }
 
diff --git a/src/quick/items/qquicktext_p.h b/src/quick/items/qquicktext_p.h
index 2292ea5f4d..ad3895358c 100644
--- a/src/quick/items/qquicktext_p.h
+++ b/src/quick/items/qquicktext_p.h
@@ -203,6 +203,9 @@ protected:
     virtual QSGNode *updatePaintNode(QSGNode *, UpdatePaintNodeData *);
     virtual bool event(QEvent *);
 
+private Q_SLOTS:
+    void q_imagesLoaded();
+
 private:
     Q_DISABLE_COPY(QQuickText)
     Q_DECLARE_PRIVATE(QQuickText)
diff --git a/src/quick/items/qquicktext_p_p.h b/src/quick/items/qquicktext_p_p.h
index fe25a02759..cf95fc6153 100644
--- a/src/quick/items/qquicktext_p_p.h
+++ b/src/quick/items/qquicktext_p_p.h
@@ -58,6 +58,7 @@
 #include "qquickimplicitsizeitem_p_p.h"
 
 #include <QtDeclarative/qdeclarative.h>
+#include <QtGui/qabstracttextdocumentlayout.h>
 #include <QtGui/qtextlayout.h>
 
 QT_BEGIN_NAMESPACE
@@ -167,9 +168,10 @@ public:
 };
 
 class QDeclarativePixmap;
-class QQuickTextDocumentWithImageResources : public QTextDocument {
+class QQuickTextDocumentWithImageResources : public QTextDocument, public QTextObjectInterface
+{
     Q_OBJECT
-
+    Q_INTERFACES(QTextObjectInterface)
 public:
     QQuickTextDocumentWithImageResources(QQuickItem *parent);
     virtual ~QQuickTextDocumentWithImageResources();
@@ -181,9 +183,19 @@ public:
 
     void clear();
 
+    QSizeF intrinsicSize(QTextDocument *doc, int posInDocument, const QTextFormat &format);
+    void drawObject(QPainter *p, const QRectF &rect, QTextDocument *doc, int posInDocument, const QTextFormat &format);
+
+    QImage image(const QTextImageFormat &format);
+
+Q_SIGNALS:
+    void imagesLoaded();
+
 protected:
     QVariant loadResource(int type, const QUrl &name);
 
+    QDeclarativePixmap *loadPixmap(QDeclarativeContext *context, const QUrl &name);
+
 private slots:
     void requestFinished();
 
diff --git a/src/quick/items/qquicktextedit.cpp b/src/quick/items/qquicktextedit.cpp
index f1dcadad67..0ecaf4cf05 100644
--- a/src/quick/items/qquicktextedit.cpp
+++ b/src/quick/items/qquicktextedit.cpp
@@ -1773,6 +1773,7 @@ void QQuickTextEditPrivate::init()
 #endif
     FAST_CONNECT(document, SIGNAL(undoAvailable(bool)), q, SIGNAL(canUndoChanged()));
     FAST_CONNECT(document, SIGNAL(redoAvailable(bool)), q, SIGNAL(canRedoChanged()));
+    FAST_CONNECT(document, SIGNAL(imagesLoaded()), q, SLOT(updateSize()));
 
     document->setDefaultFont(font);
     document->setDocumentMargin(textMargin);
diff --git a/src/quick/items/qquicktextedit_p.h b/src/quick/items/qquicktextedit_p.h
index 508f564c88..8cdd984735 100644
--- a/src/quick/items/qquicktextedit_p.h
+++ b/src/quick/items/qquicktextedit_p.h
@@ -214,6 +214,10 @@ public:
     qreal paintedWidth() const;
     qreal paintedHeight() const;
 
+    QUrl baseUrl() const;
+    void setBaseUrl(const QUrl &url);
+    void resetBaseUrl();
+
     Q_INVOKABLE QRectF positionToRectangle(int) const;
     Q_INVOKABLE int positionAt(int x, int y) const;
     Q_INVOKABLE void moveCursorSelection(int pos);
@@ -283,9 +287,9 @@ private Q_SLOTS:
     void updateDocument();
     void updateCursor();
     void q_updateAlignment();
+    void updateSize();
 
 private:
-    void updateSize();
     void updateTotalLines();
     void updateImageCache(const QRectF &rect = QRectF());
 
diff --git a/src/quick/items/qquicktextedit_p_p.h b/src/quick/items/qquicktextedit_p_p.h
index bf7edf5f03..801bca0ff9 100644
--- a/src/quick/items/qquicktextedit_p_p.h
+++ b/src/quick/items/qquicktextedit_p_p.h
@@ -82,6 +82,9 @@ public:
     {
     }
 
+    static QQuickTextEditPrivate *get(QQuickTextEdit *item) {
+        return static_cast<QQuickTextEditPrivate *>(QObjectPrivate::get(item)); }
+
     void init();
 
     void updateDefaultTextOption();
diff --git a/src/quick/items/qquicktextnode.cpp b/src/quick/items/qquicktextnode.cpp
index dedc456aaa..804e83fcd2 100644
--- a/src/quick/items/qquicktextnode.cpp
+++ b/src/quick/items/qquicktextnode.cpp
@@ -56,6 +56,7 @@
 #include <qtexttable.h>
 #include <qtextlist.h>
 #include <private/qdeclarativestyledtext_p.h>
+#include <private/qquicktext_p_p.h>
 #include <private/qfont_p.h>
 #include <private/qfontengine_p.h>
 #include <private/qrawfont_p.h>
@@ -702,8 +703,15 @@ namespace {
 
             if (format.objectType() == QTextFormat::ImageObject) {
                 QTextImageFormat imageFormat = format.toImageFormat();
-                QTextImageHandler *imageHandler = static_cast<QTextImageHandler *>(handler);
-                image = imageHandler->image(textDocument, imageFormat);
+                if (QQuickTextDocumentWithImageResources *imageDoc = qobject_cast<QQuickTextDocumentWithImageResources *>(textDocument)) {
+                    image = imageDoc->image(imageFormat);
+
+                    if (image.isNull())
+                        return;
+                } else {
+                    QTextImageHandler *imageHandler = static_cast<QTextImageHandler *>(handler);
+                    image = imageHandler->image(textDocument, imageFormat);
+                }
             }
 
             if (image.isNull()) {
diff --git a/tests/auto/qtquick2/qquicktext/tst_qquicktext.cpp b/tests/auto/qtquick2/qquicktext/tst_qquicktext.cpp
index 0e8eab18be..fa9549afc7 100644
--- a/tests/auto/qtquick2/qquicktext/tst_qquicktext.cpp
+++ b/tests/auto/qtquick2/qquicktext/tst_qquicktext.cpp
@@ -39,6 +39,7 @@
 **
 ****************************************************************************/
 #include <qtest.h>
+#include <QtTest/QSignalSpy>
 #include <QTextDocument>
 #include <QtDeclarative/qdeclarativeengine.h>
 #include <QtDeclarative/qdeclarativecomponent.h>
diff --git a/tests/auto/qtquick2/qquicktextedit/data/embeddedImagesLocal.qml b/tests/auto/qtquick2/qquicktextedit/data/embeddedImagesLocal.qml
new file mode 100644
index 0000000000..150f7bd898
--- /dev/null
+++ b/tests/auto/qtquick2/qquicktextedit/data/embeddedImagesLocal.qml
@@ -0,0 +1,6 @@
+import QtQuick 2.0
+
+TextEdit {
+    textFormat: TextEdit.RichText
+    text: "<img src='http/exists.png'>"
+}
diff --git a/tests/auto/qtquick2/qquicktextedit/data/embeddedImagesLocalError.qml b/tests/auto/qtquick2/qquicktextedit/data/embeddedImagesLocalError.qml
new file mode 100644
index 0000000000..067b6d72da
--- /dev/null
+++ b/tests/auto/qtquick2/qquicktextedit/data/embeddedImagesLocalError.qml
@@ -0,0 +1,6 @@
+import QtQuick 2.0
+
+TextEdit {
+    textFormat: TextEdit.RichText
+    text: "<img src='http/notexists.png'>"
+}
diff --git a/tests/auto/qtquick2/qquicktextedit/data/embeddedImagesRemote.qml b/tests/auto/qtquick2/qquicktextedit/data/embeddedImagesRemote.qml
new file mode 100644
index 0000000000..a823882692
--- /dev/null
+++ b/tests/auto/qtquick2/qquicktextedit/data/embeddedImagesRemote.qml
@@ -0,0 +1,6 @@
+import QtQuick 2.0
+
+TextEdit {
+    textFormat: TextEdit.RichText
+    text: "<img src='http://127.0.0.1:42332/exists.png'>"
+}
diff --git a/tests/auto/qtquick2/qquicktextedit/data/embeddedImagesRemoteError.qml b/tests/auto/qtquick2/qquicktextedit/data/embeddedImagesRemoteError.qml
new file mode 100644
index 0000000000..c6172b68dc
--- /dev/null
+++ b/tests/auto/qtquick2/qquicktextedit/data/embeddedImagesRemoteError.qml
@@ -0,0 +1,6 @@
+import QtQuick 2.0
+
+TextEdit {
+    textFormat: TextEdit.RichText
+    text: "<img src='http://127.0.0.1:42332/notexists.png'>"
+}
diff --git a/tests/auto/qtquick2/qquicktextedit/data/http/exists.png b/tests/auto/qtquick2/qquicktextedit/data/http/exists.png
new file mode 100644
index 0000000000000000000000000000000000000000..399bd0b1d9d920e11f73922a112d5bbfabf7f01e
GIT binary patch
literal 2738
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

literal 0
HcmV?d00001

diff --git a/tests/auto/qtquick2/qquicktextedit/tst_qquicktextedit.cpp b/tests/auto/qtquick2/qquicktextedit/tst_qquicktextedit.cpp
index b35d955e2d..272ec19924 100644
--- a/tests/auto/qtquick2/qquicktextedit/tst_qquicktextedit.cpp
+++ b/tests/auto/qtquick2/qquicktextedit/tst_qquicktextedit.cpp
@@ -51,6 +51,7 @@
 #include <QtGui/qguiapplication.h>
 #include <private/qquicktextedit_p.h>
 #include <private/qquicktextedit_p_p.h>
+#include <private/qquicktext_p_p.h>
 #include <QFontMetrics>
 #include <QtQuick/QQuickView>
 #include <QDir>
@@ -174,6 +175,9 @@ private slots:
     void undo_keypressevents_data();
     void undo_keypressevents();
 
+    void embeddedImages();
+    void embeddedImages_data();
+
     void emptytags_QTBUG_22058();
 
 private:
@@ -3654,6 +3658,48 @@ void tst_qquicktextedit::undo_keypressevents()
     QVERIFY(textEdit->text().isEmpty());
 }
 
+void tst_qquicktextedit::embeddedImages_data()
+{
+    QTest::addColumn<QUrl>("qmlfile");
+    QTest::addColumn<QString>("error");
+    QTest::newRow("local") << testFileUrl("embeddedImagesLocal.qml") << "";
+    QTest::newRow("local-error") << testFileUrl("embeddedImagesLocalError.qml")
+        << testFileUrl("embeddedImagesLocalError.qml").toString()+":3:1: QML TextEdit: Cannot open: " + testFileUrl("http/notexists.png").toString();
+    QTest::newRow("remote") << testFileUrl("embeddedImagesRemote.qml") << "";
+    QTest::newRow("remote-error") << testFileUrl("embeddedImagesRemoteError.qml")
+        << testFileUrl("embeddedImagesRemoteError.qml").toString()+":3:1: QML TextEdit: Error downloading http://127.0.0.1:42332/notexists.png - server replied: Not found";
+}
+
+void tst_qquicktextedit::embeddedImages()
+{
+    QFETCH(QUrl, qmlfile);
+    QFETCH(QString, error);
+
+    TestHTTPServer server(42332);
+    server.serveDirectory(testFile("http"));
+
+    if (!error.isEmpty())
+        QTest::ignoreMessage(QtWarningMsg, error.toLatin1());
+
+    QDeclarativeComponent textComponent(&engine, qmlfile);
+    QQuickTextEdit *textObject = qobject_cast<QQuickTextEdit*>(textComponent.create());
+
+    QVERIFY(textObject != 0);
+    QTRY_COMPARE(QQuickTextEditPrivate::get(textObject)->document->resourcesLoading(), 0);
+
+    QPixmap pm(testFile("http/exists.png"));
+    if (error.isEmpty()) {
+        QCOMPARE(textObject->width(), double(pm.width()));
+        QCOMPARE(textObject->height(), double(pm.height()));
+    } else {
+        QVERIFY(16 != pm.width()); // check test is effective
+        QCOMPARE(textObject->width(), 16.0); // default size of QTextDocument broken image icon
+        QCOMPARE(textObject->height(), 16.0);
+    }
+
+    delete textObject;
+}
+
 void tst_qquicktextedit::emptytags_QTBUG_22058()
 {
     QQuickView canvas(testFileUrl("qtbug-22058.qml"));
-- 
GitLab