Load resources in in QTextDocument correctly
authorLars Knoll <lars.knoll@nokia.com>
Fri, 27 Apr 2012 20:05:32 +0000 (22:05 +0200)
committerQt by Nokia <qt-info@nokia.com>
Fri, 4 May 2012 13:31:02 +0000 (15:31 +0200)
In Qt 4, we loaded resources through the QTextEdit or
QTextControl if they were the parent of the document.
Modularization for Qt 5 broke this, as we can't cast
the parent to a QTextEdit anymore.

The fix is to make the loadResource() methods in QTextControl
and QTextEdit invokable and discover and invoke them at
runtime on the parent object.

Task-number: QTBUG-25116
Change-Id: Iba04bc16849b0c5ddcd275f12d1a386a8fe591bf
Reviewed-by: Girish Ramakrishnan <girish.1.ramakrishnan@nokia.com>
src/gui/text/qtextdocument.cpp
src/gui/text/qtextdocument.h
src/widgets/widgets/qtextedit.h
src/widgets/widgets/qwidgettextcontrol_p.h
tests/auto/widgets/widgets/qtextbrowser/tst_qtextbrowser.cpp

index 89f6d1a..ec660dd 100644 (file)
@@ -52,6 +52,7 @@
 #include <qtextcodec.h>
 #include <qthread.h>
 #include <qcoreapplication.h>
+#include <qmetaobject.h>
 
 #include "qtexthtmlparser_p.h"
 #include "qpainter.h"
@@ -1896,7 +1897,8 @@ void QTextDocument::addResource(int type, const QUrl &name, const QVariant &reso
     When called by Qt, \a type is one of the values of
     QTextDocument::ResourceType.
 
-    If the QTextDocument is a child object of a QTextEdit, QTextBrowser,
+    If the QTextDocument is a child object of a QObject that has an invokable
+    loadResource method such as QTextEdit, QTextBrowser
     or a QTextDocument itself then the default implementation tries
     to retrieve the data from the parent.
 */
@@ -1905,24 +1907,15 @@ QVariant QTextDocument::loadResource(int type, const QUrl &name)
     Q_D(QTextDocument);
     QVariant r;
 
-    QTextDocument *doc = qobject_cast<QTextDocument *>(parent());
-    if (doc) {
-        r = doc->loadResource(type, name);
-    }
-#if 0
-    // ### Qt5: reenable
-#ifndef QT_NO_TEXTEDIT
-    else if (QTextEdit *edit = qobject_cast<QTextEdit *>(parent())) {
-        QUrl resolvedName = edit->d_func()->resolveUrl(name);
-        r = edit->loadResource(type, resolvedName);
-    }
-#endif
-#ifndef QT_NO_TEXTCONTROL
-    else if (QWidgetTextControl *control = qobject_cast<QWidgetTextControl *>(parent())) {
-        r = control->loadResource(type, name);
+    QObject *p = parent();
+    if (p) {
+        const QMetaObject *me = p->metaObject();
+        int index = me->indexOfMethod("loadResource(int,QUrl)");
+        if (index >= 0) {
+            QMetaMethod loader = me->method(index);
+            loader.invoke(p, Q_RETURN_ARG(QVariant, r), Q_ARG(int, type), Q_ARG(QUrl, name));
+        }
     }
-#endif
-#endif
 
     // handle data: URLs
     if (r.isNull() && name.scheme().compare(QLatin1String("data"), Qt::CaseInsensitive) == 0) {
@@ -1933,7 +1926,7 @@ QVariant QTextDocument::loadResource(int type, const QUrl &name)
     }
 
     // if resource was not loaded try to load it here
-    if (!doc && r.isNull() && name.isRelative()) {
+    if (!qobject_cast<QTextDocument *>(p) && r.isNull() && name.isRelative()) {
         QUrl currentURL = d->url;
         QUrl resourceUrl = name;
 
index aeb431c..65ea1c8 100644 (file)
@@ -45,6 +45,7 @@
 #include <QtCore/qobject.h>
 #include <QtCore/qsize.h>
 #include <QtCore/qrect.h>
+#include <QtCore/qvariant.h>
 #include <QtGui/qfont.h>
 
 QT_BEGIN_HEADER
@@ -288,7 +289,7 @@ public Q_SLOTS:
 
 protected:
     virtual QTextObject *createObject(const QTextFormat &f);
-    virtual QVariant loadResource(int type, const QUrl &name);
+    Q_INVOKABLE virtual QVariant loadResource(int type, const QUrl &name);
 
     QTextDocument(QTextDocumentPrivate &dd, QObject *parent);
 public:
index 3148c7a..bc2cd49 100644 (file)
@@ -168,7 +168,7 @@ public:
 
     void ensureCursorVisible();
 
-    virtual QVariant loadResource(int type, const QUrl &name);
+    Q_INVOKABLE virtual QVariant loadResource(int type, const QUrl &name);
 #ifndef QT_NO_CONTEXTMENU
     QMenu *createStandardContextMenu();
     QMenu *createStandardContextMenu(const QPoint &position);
index f153267..d6e4d87 100644 (file)
@@ -120,7 +120,7 @@ public:
 
     virtual void ensureCursorVisible();
 
-    virtual QVariant loadResource(int type, const QUrl &name);
+    Q_INVOKABLE virtual QVariant loadResource(int type, const QUrl &name);
 #ifndef QT_NO_CONTEXTMENU
     QMenu *createStandardContextMenu(const QPointF &pos, QWidget *parent);
 #endif
index c78989e..8d4238b 100644 (file)
@@ -296,7 +296,6 @@ void tst_QTextBrowser::anchors()
 void tst_QTextBrowser::resourceAutoDetection()
 {
     browser->setHtml("<img src=\":/some/resource\"/>");
-QEXPECT_FAIL("", "FIXME: Resource detection broken", Continue);
     QCOMPARE(browser->lastResource.toString(), QString("qrc:/some/resource"));
 }
 
@@ -451,8 +450,7 @@ void tst_QTextBrowser::sourceInsideLoadResource()
 {
     QUrl url = QUrl::fromLocalFile("pagewithimage.html");
     browser->setSource(url);
-QEXPECT_FAIL("", "FIXME: Resource detection broken", Continue);
-    QCOMPARE(browser->lastResource.toLocalFile(), QUrl::fromLocalFile(QDir::current().filePath("foobar.png")).toString());
+    QCOMPARE(browser->lastResource, QUrl::fromLocalFile(QDir::current().filePath("foobar.png")));
     QEXPECT_FAIL("", "This is currently not supported", Continue);
     QCOMPARE(browser->sourceInsideLoadResource.toString(), url.toString());
 }