Support QT_TRANSLATE_NOOP in ListElement.
authorMichael Brasser <michael.brasser@nokia.com>
Wed, 27 Jul 2011 03:13:50 +0000 (13:13 +1000)
committerQt by Nokia <qt-info@nokia.com>
Thu, 28 Jul 2011 09:27:26 +0000 (11:27 +0200)
Task-number: QTBUG-16289
Change-Id: I13e6859de185478e2c6c9486d8deeda103dd7b90
Reviewed-on: http://codereview.qt.nokia.com/2238
Reviewed-by: Qt Sanity Bot <qt_sanity_bot@ovi.com>
Reviewed-by: Aaron Kennedy <aaron.kennedy@nokia.com>
src/declarative/util/qdeclarativelistmodel.cpp
tests/auto/declarative/qdeclarativelistmodel/tst_qdeclarativelistmodel.cpp

index e35d64b..d1496fc 100644 (file)
@@ -42,6 +42,8 @@
 #include "private/qdeclarativelistmodel_p_p.h"
 #include "private/qdeclarativelistmodelworkeragent_p.h"
 #include "private/qdeclarativeopenmetaobject_p.h"
+#include "parser/qdeclarativejsast_p.h"
+#include "parser/qdeclarativejsengine_p.h"
 
 #include <qdeclarativecustomparser_p.h>
 #include <qdeclarativeparser_p.h>
@@ -840,9 +842,32 @@ bool QDeclarativeListModelParser::compileProperty(const QDeclarativeCustomParser
                     QByteArray script = variant.asScript().toUtf8();
                     int v = evaluateEnum(script);
                     if (v<0) {
-                        if (script.startsWith("QT_TR_NOOP(\"") && script.endsWith("\")")) {
+                        using namespace QDeclarativeJS;
+                        AST::Node *node = variant.asAST();
+                        AST::StringLiteral *literal = 0;
+                        if (AST::CallExpression *callExpr = AST::cast<AST::CallExpression *>(node)) {
+                            if (AST::IdentifierExpression *idExpr = AST::cast<AST::IdentifierExpression *>(callExpr->base)) {
+                                if (idExpr->name->asString() == QLatin1String("QT_TR_NOOP")) {
+                                    if (callExpr->arguments && !callExpr->arguments->next)
+                                        literal = AST::cast<AST::StringLiteral *>(callExpr->arguments->expression);
+                                    if (!literal) {
+                                        error(prop, QDeclarativeListModel::tr("ListElement: improperly specified QT_TR_NOOP"));
+                                        return false;
+                                    }
+                                } else if (idExpr->name->asString() == QLatin1String("QT_TRANSLATE_NOOP")) {
+                                    if (callExpr->arguments && callExpr->arguments->next && !callExpr->arguments->next->next)
+                                        literal = AST::cast<AST::StringLiteral *>(callExpr->arguments->next->expression);
+                                    if (!literal) {
+                                        error(prop, QDeclarativeListModel::tr("ListElement: improperly specified QT_TRANSLATE_NOOP"));
+                                        return false;
+                                    }
+                                }
+                            }
+                        }
+
+                        if (literal) {
                             d[0] = char(QDeclarativeParser::Variant::String);
-                            d += script.mid(12,script.length()-14);
+                            d += literal->value->asString().toUtf8();
                         } else {
                             error(prop, QDeclarativeListModel::tr("ListElement: cannot use script for property value"));
                             return false;
index 3132239..1016e5d 100644 (file)
@@ -76,6 +76,7 @@ private slots:
     void static_types();
     void static_types_data();
     void static_i18n();
+    void static_i18n_data();
     void static_nestedElements();
     void static_nestedElements_data();
     void dynamic_data();
@@ -197,20 +198,62 @@ void tst_qdeclarativelistmodel::static_types()
     delete obj;
 }
 
+void tst_qdeclarativelistmodel::static_i18n_data()
+{
+    QTest::addColumn<QString>("qml");
+    QTest::addColumn<QVariant>("value");
+    QTest::addColumn<QString>("error");
+
+    QTest::newRow("QT_TR_NOOP")
+        << QString::fromUtf8("ListElement { foo: QT_TR_NOOP(\"na\303\257ve\") }")
+        << QVariant(QString::fromUtf8("na\303\257ve"))
+        << QString();
+
+    QTest::newRow("QT_TRANSLATE_NOOP")
+        << "ListElement { foo: QT_TRANSLATE_NOOP(\"MyListModel\", \"hello\") }"
+        << QVariant(QString("hello"))
+        << QString();
+
+    QTest::newRow("QT_TR_NOOP extra param")
+            << QString::fromUtf8("ListElement { foo: QT_TR_NOOP(\"hello\",\"world\") }")
+            << QVariant(QString())
+            << QString("ListElement: improperly specified QT_TR_NOOP");
+
+    QTest::newRow("QT_TRANSLATE_NOOP missing params")
+        << "ListElement { foo: QT_TRANSLATE_NOOP() }"
+        << QVariant(QString())
+        << QString("ListElement: improperly specified QT_TRANSLATE_NOOP");
+}
+
 void tst_qdeclarativelistmodel::static_i18n()
 {
-    QString expect = QString::fromUtf8("na\303\257ve");
+    QFETCH(QString, qml);
+    QFETCH(QVariant, value);
+    QFETCH(QString, error);
+
+    qml = "import QtQuick 2.0\nItem { property variant test: model.get(0).foo; ListModel { id: model; " + qml + " } }";
 
-    QString componentStr = "import QtQuick 2.0\nItem { property string prop1: model.get(0).prop1; property string prop2: model.get(0).prop2; ListModel { id: model; ListElement { prop1: \""+expect+"\"; prop2: QT_TR_NOOP(\""+expect+"\") } } }";
     QDeclarativeEngine engine;
     QDeclarativeComponent component(&engine);
-    component.setData(componentStr.toUtf8(), QUrl::fromLocalFile(""));
+    component.setData(qml.toUtf8(),
+                      QUrl::fromLocalFile(QString("dummy.qml")));
+
+    if (!error.isEmpty()) {
+        QVERIFY(component.isError());
+        QCOMPARE(component.errors().at(0).description(), error);
+        return;
+    }
+
+    QVERIFY(!component.isError());
+
     QObject *obj = component.create();
     QVERIFY(obj != 0);
-    QString prop1 = obj->property("prop1").toString();
-    QCOMPARE(prop1,expect);
-    QString prop2 = obj->property("prop2").toString();
-    QCOMPARE(prop2,expect); // (no, not translated, QT_TR_NOOP is a no-op)
+
+    QVariant actual = obj->property("test");
+
+    QCOMPARE(actual, value);
+    QCOMPARE(actual.toString(), value.toString());
+
     delete obj;
 }