diff options
48 files changed, 788 insertions, 352 deletions
diff --git a/doc/src/declarative/advtutorial.qdoc b/doc/src/declarative/advtutorial.qdoc index 4c97e1a..2ca9418 100644 --- a/doc/src/declarative/advtutorial.qdoc +++ b/doc/src/declarative/advtutorial.qdoc @@ -423,7 +423,7 @@ Here is the \c saveHighScore() function in \c samegame.js: First we call \c sendHighScore() (explained in the section below) if it is possible to send the high scores to an online database. -Then, we use the \l{Offline Storage API} to maintain a persistant SQL database unique to this application. We create an offline storage database for the high scores using \c openDatabase() and prepare the data and SQL query that we want to use to save it. The offline storage API uses SQL queries for data manipulation and retrival, and in the \c db.transaction() call we use three SQL queries to initialize the database (if necessary), and then add to and retrieve high scores. To use the returned data, we turn it into a string with one line per row returned, and show a dialog containing that string. +Then, we use the \l{Offline Storage API} to maintain a persistent SQL database unique to this application. We create an offline storage database for the high scores using \c openDatabase() and prepare the data and SQL query that we want to use to save it. The offline storage API uses SQL queries for data manipulation and retrieval, and in the \c db.transaction() call we use three SQL queries to initialize the database (if necessary), and then add to and retrieve high scores. To use the returned data, we turn it into a string with one line per row returned, and show a dialog containing that string. This is one way of storing and displaying high scores locally, but certainly not the only way. A more complex alternative would be to create a high score dialog component, and pass it the results for processing and display (instead of reusing the \c Dialog). This would allow a more themeable dialog that could better present the high scores. If your QML is the UI for a C++ application, you could also have passed the score to a C++ function to store it locally in a variety of ways, including a simple format without SQL or in another SQL database. diff --git a/doc/src/declarative/extending.qdoc b/doc/src/declarative/extending.qdoc index a1ffde0..df8a1e7 100644 --- a/doc/src/declarative/extending.qdoc +++ b/doc/src/declarative/extending.qdoc @@ -719,7 +719,7 @@ it in two steps, like this: \endcode If a default value is not supplied or set later in the file, each type has a -default value for when none is explictly set. Below are the default values +default value for when none is explicitly set. Below are the default values of some of the types. For the remaining types the default values are undefined. \table @@ -823,7 +823,7 @@ A property alias declaration looks a lot like a property definition: As the aliasing property has the same type as the aliased property, an explicit type is omitted, and the special "alias" keyword is used. Instead of a default -value, a property alias includes a compulsary alias reference. The alias +value, a property alias includes a compulsory alias reference. The alias reference is used to locate the aliased property. While similar to a property binding, the alias reference syntax is highly restricted. @@ -993,7 +993,7 @@ Return values of type QVariant are also supported via Q_RETURN_ARG. \target components A component is a reusable type with a well-defined interface built entirely in -QML. Components appear as regular QML elements, and can be used interchangably +QML. Components appear as regular QML elements, and can be used interchangeably with core types. Components allow developers to create new types to be reused in other projects without the use of C++. Components can also help to reduce duplication inside one project by limiting the need for large numbers of @@ -1086,7 +1086,7 @@ Methods and signals may be added in the same way. As all external methods, signals and properties are accessible to external users, developers should ensure that setting these properties does not have -any undesirable side-effects. For most resiliance, root level properties should +any undesirable side-effects. For most resilience, root level properties should only be used for literal default values. When a root level property must be used inside the component - such as the children property - property aliases can be used to redirect this property to a "safe" location for external users. diff --git a/doc/src/declarative/focus.qdoc b/doc/src/declarative/focus.qdoc index 56ea165..c3c94c5 100644 --- a/doc/src/declarative/focus.qdoc +++ b/doc/src/declarative/focus.qdoc @@ -120,7 +120,7 @@ hand side of the following table shows what we would like to be able to write. Here we create two instances of our previously defined component, and set the second one to have focus. The intention is that when the \e A, \e B, or \e C keys are pressed, the second of the two components receives the event and -reponds accordingly. +responds accordingly. \table \row @@ -276,7 +276,7 @@ Focus scopes allow focus to allocation to be easily partitioned. Several QML items use it to this effect. \l ListView, for example, is itself a focus scope. Generally this isn't -noticable as \l ListView doesn't usually have manually added visual children. +noticeable as \l ListView doesn't usually have manually added visual children. By being a focus scope, \l ListView can focus the current list item without worrying about how that will effect the rest of the application. This allows the current item delegate to react to key presses. @@ -301,14 +301,4 @@ actually performs the work of handling the \e {Return} key. All of the QML view classes, such as \l PathView and \l GridView, behave in a similar manner to allow key handling in their respective delegates. - -\section1 Focus Panels - -Traditional UIs are composed of many top-level windows. Windows actually -perform two tasks - they act as the visual bounds for a widget, and they segment -focus. Each window has a separate focused widget, that becomes (to mix -terminologies) the \e {active focus} widget when the window is the active -window. - -### Focus panels do basically the same thing. */ diff --git a/doc/src/declarative/modules.qdoc b/doc/src/declarative/modules.qdoc index 044c1e7..25a61c9 100644 --- a/doc/src/declarative/modules.qdoc +++ b/doc/src/declarative/modules.qdoc @@ -233,7 +233,7 @@ internal <TypeName> <File> plugin <Name> [<Path>] \endcode -\bold {# <Commment>} lines are used for comments. They are ignored by the QML engine. +\bold {# <Comment>} lines are used for comments. They are ignored by the QML engine. \bold {<TypeName> [<InitialVersion>] <File>} lines are used to add QML files as types. <TypeName> is the type being made available, the optional <InitialVersion> is a version @@ -246,7 +246,7 @@ the \c qmldir file. Types which you do not wish to export to users of your modul may be marked with the \c internal keyword: \bold {internal <TypeName> <File>}. The same type can be provided by different files in different versions, in which -case later versions (eg. 1.2) must precede earlier versions (eg. 1.0), +case later versions (e.g. 1.2) must precede earlier versions (e.g. 1.0), since the \e first name-version match is used and a request for a version of a type can be fulfilled by one defined in an earlier version of the module. If a user attempts to import a version earlier than the earliest provided or later than the latest provided, diff --git a/doc/src/declarative/propertybinding.qdoc b/doc/src/declarative/propertybinding.qdoc index 314bf67..f58d8fe 100644 --- a/doc/src/declarative/propertybinding.qdoc +++ b/doc/src/declarative/propertybinding.qdoc @@ -48,7 +48,7 @@ Rectangle { QML extends a standards compliant JavaScript engine, so any valid JavaScript expression can be used as a property binding. Bindings can access object properties, make function calls and even use builtin JavaScript objects like \e {Date} and \e {Math}. Assigning a constant value to a -property can even be thought of as a binding - afterall, a constant is a valid JavaScript +property can even be thought of as a binding - after all, a constant is a valid JavaScript expression! Here are some examples of more complex bindings: \code diff --git a/doc/src/declarative/qdeclarativeintro.qdoc b/doc/src/declarative/qdeclarativeintro.qdoc index 9d89edf..c97240c 100644 --- a/doc/src/declarative/qdeclarativeintro.qdoc +++ b/doc/src/declarative/qdeclarativeintro.qdoc @@ -173,7 +173,7 @@ Item { } \endcode -QML properties are what is known as \e typesafe. That is, they only allow you to assign a value that +QML properties are what is known as \e type-safe. That is, they only allow you to assign a value that matches the property type. For example, the \c x property of item is a real, and if you try to assign a string to it you will get an error. @@ -189,7 +189,7 @@ Each object can be given a special unique property called an \e id. No other obj same \l{QML Documents}{QML document} can have the same \c id value. Assigning an id enables the object to be referred to by other objects and scripts. -The first Rectangle element below has an \e id, "myRect". The second Rectange element defines its +The first Rectangle element below has an \e id, "myRect". The second Rectangle element defines its own width by referring to \tt myRect.width, which means it will have the same \tt width value as the first Rectangle element. diff --git a/doc/src/declarative/qdeclarativeperformance.qdoc b/doc/src/declarative/qdeclarativeperformance.qdoc index be8c029..061a71c 100644 --- a/doc/src/declarative/qdeclarativeperformance.qdoc +++ b/doc/src/declarative/qdeclarativeperformance.qdoc @@ -51,7 +51,7 @@ Rectangle { x: 20 width: 200; height: 200 } -Rectange { +Rectangle { id: rect2 x: rect1.x y: rect1.y + rect1.height @@ -68,7 +68,7 @@ Rectangle { x: 20 width: 200; height: 200 } -Rectange { +Rectangle { id: rect2 height: 200 anchors.left: rect1.left diff --git a/doc/src/declarative/qdeclarativesecurity.qdoc b/doc/src/declarative/qdeclarativesecurity.qdoc index 199e2da..7395af3 100644 --- a/doc/src/declarative/qdeclarativesecurity.qdoc +++ b/doc/src/declarative/qdeclarativesecurity.qdoc @@ -48,7 +48,7 @@ import "http://evil.com/evil.js" as Evil is equivalent to downloading "http://evil.com/evil.exe" and running it. The JavaScript execution environment of QML does not try to stop any particular accesses, including local file system access, just as for any native Qt application, so the "doEvil" function could do the same things -as a native Qt application, a Python application, a Perl script, ec. +as a native Qt application, a Python application, a Perl script, etc. As with any application accessing other content beyond it's control, a QML application should perform appropriate checks on untrusted data it loads. diff --git a/doc/src/declarative/qdeclarativestates.qdoc b/doc/src/declarative/qdeclarativestates.qdoc index 274040a..148726f 100644 --- a/doc/src/declarative/qdeclarativestates.qdoc +++ b/doc/src/declarative/qdeclarativestates.qdoc @@ -221,7 +221,7 @@ Rectangle { This \l Transition defines that if any \c x or \c y properties have changed during a state change within this item, their values should be animated over 500 -millliseconds. +milliseconds. See the \l Transitions documentation for more information. diff --git a/doc/src/declarative/qml-intro.qdoc b/doc/src/declarative/qml-intro.qdoc index b77611c..18fa439 100644 --- a/doc/src/declarative/qml-intro.qdoc +++ b/doc/src/declarative/qml-intro.qdoc @@ -262,7 +262,7 @@ myRectangle.top // Correct We can transform a graphical object to get additional effects. Rotate a piece of text by 180 degrees to display upside-down text. Rotate an image by 90 degrees to lay it on its side. These transformations require -additonal information. +additional information. For rotation, the additional information includes: the origin relative to the object being rotated, the axis of rotation, and the angle in degrees to diff --git a/doc/src/declarative/qtbinding.qdoc b/doc/src/declarative/qtbinding.qdoc index 35a05d2..53db5c7 100644 --- a/doc/src/declarative/qtbinding.qdoc +++ b/doc/src/declarative/qtbinding.qdoc @@ -134,7 +134,7 @@ the window text will update accordingly. To detect when a C++ property value - in this case the \c CustomPalette's \c text property - changes, the property must have a corresponding NOTIFY signal. The NOTIFY signal specifies a signal that is emitted whenever the property changes value. Implementers should take care to only emit the -signal if the value \e changes to prevent loops from occuring. Accessing a property from a +signal if the value \e changes to prevent loops from occurring. Accessing a property from a binding that does not have a NOTIFY signal will cause QML to issue a warning at runtime. \section2 Dynamic Structured Data @@ -256,7 +256,7 @@ For example: \snippet doc/src/snippets/declarative/qtbinding/resources/main.qml 0 Note that the resource system cannot be accessed from QML directly. If the main QML file is -loaded as a resource, all files specifed as relative paths in QML will also be loaded from +loaded as a resource, all files specified as relative paths in QML will also be loaded from the resource system. Using the resource system is completely transparent to the QML layer. This also means that if the main QML file is not loaded as a resource then files in the resource system cannot be accessed from QML. diff --git a/doc/src/declarative/qtprogrammers.qdoc b/doc/src/declarative/qtprogrammers.qdoc index c0639db..69e6358 100644 --- a/doc/src/declarative/qtprogrammers.qdoc +++ b/doc/src/declarative/qtprogrammers.qdoc @@ -32,7 +32,7 @@ \section1 Overview -While QML does not require Qt knowledge to use, if you \e are already familar with Qt, +While QML does not require Qt knowledge to use, if you \e are already familiar with Qt, much of your knowledge is directly relevant to learning and using QML. Of course, an application with a UI defined in QML also uses Qt for all the non-UI logic. @@ -103,7 +103,7 @@ So, to implement your reusable button, you would simply build a QML component. Parent widgets each provide a generic way to interface to one or more arbitrary other widgets. A QTabWidget provides an interface to multiple "pages", one of which is visible at any time, -and a mechnism for selecting among them (the QTabBar). A QScollArea provides scrollbars around +and a mechanism for selecting among them (the QTabBar). A QScollArea provides scrollbars around a widget that is otherwise too large to fit in available space. Nearly all such components can be created directly in QML. Only a few cases @@ -115,7 +115,7 @@ needs to be divided up into pages. A significant difference in the parenting concept with QML compare to QWidgets is that while child items are positioned relative to their parents, -there is no requirement that they be wholy contained ("clipped") to +there is no requirement that they be wholly contained ("clipped") to the parent (although the clipped property of the child Item does allow this where it is needed). This difference has rather far-reaching consequences, for example: diff --git a/doc/src/declarative/scope.qdoc b/doc/src/declarative/scope.qdoc index 5501242..17f8632 100644 --- a/doc/src/declarative/scope.qdoc +++ b/doc/src/declarative/scope.qdoc @@ -174,7 +174,7 @@ PathView { } \endcode -If the \l Image element omitted the \c root prefix, it would inadvertantly access +If the \l Image element omitted the \c root prefix, it would inadvertently access the unset \c {PathView.scale} attached property on itself. \section1 Component Scope diff --git a/doc/src/getting-started/gettingstartedqml.qdoc b/doc/src/getting-started/gettingstartedqml.qdoc index e2d6e72..a6159c3 100644 --- a/doc/src/getting-started/gettingstartedqml.qdoc +++ b/doc/src/getting-started/gettingstartedqml.qdoc @@ -122,7 +122,7 @@ items can anchor to another item, creating robust layouts. The \c MouseArea has many signal handlers that are called during mouse movements within - the specfied \c MouseArea boundaries. One of them is \c onClicked and it is called + the specified \c MouseArea boundaries. One of them is \c onClicked and it is called whenever the acceptable mouse button is clicked, the left click being the default. We can bind actions to the onClicked handler. In our example, \c console.log() outputs text whenever the mouse area is clicked. The function \c console.log() is a useful tool for @@ -546,7 +546,7 @@ a certain easing curve. An easing curve controls the animation rates and interpolation behavior during state transitions. The easing curve we chose is \l{PropertyAnimation::easing.type}{Easing.OutQuint}, which slows the movement near - the end of the animation. Pleae read \l {qdeclarativeanimation.html}{QML's Animation} + the end of the animation. Please read \l {qdeclarativeanimation.html}{QML's Animation} article. \snippet examples/tutorials/gettingStarted/gsQml/texteditor.qml transitions @@ -835,7 +835,7 @@ \c QDeclarativeListProperty<File>. The template type, \c File, needs to be a \c QObject derivative. Further, to create the \l {QDeclarativeListProperty}{QDeclarativeListProperty}, the list's accessor - and modifiers need to be passed to the consructor as function pointers. The list, + and modifiers need to be passed to the constructor as function pointers. The list, a \c QList in our case, also needs to be a list of \c File pointers. The constructor of \l {QDeclarativeListProperty}{QDeclarativeListProperty} @@ -980,7 +980,7 @@ Our \c FileMenu can now connect to their respective actions. The \c saveButton will transfer the text from the \c TextEdit onto the directory's \c fileContent property, then copy its file name from the editable text input. Finally, the button - calls the \c saveFile() function, saving the file. The \c sloadButton has a similar + calls the \c saveFile() function, saving the file. The \c loadButton has a similar execution. Also, the \c New action will empty the contents of the \c TextEdit. Further, the \c EditMenu buttons are connected to the \c TextEdit functions to copy, diff --git a/doc/src/images/qml-column.png b/doc/src/images/qml-column.png Binary files differnew file mode 100644 index 0000000..c589ad8 --- /dev/null +++ b/doc/src/images/qml-column.png diff --git a/doc/src/snippets/declarative/column/column.qml b/doc/src/snippets/declarative/column/column.qml index 45c6822..18e95e9 100644 --- a/doc/src/snippets/declarative/column/column.qml +++ b/doc/src/snippets/declarative/column/column.qml @@ -47,21 +47,21 @@ Item { Column { anchors.horizontalCenter: parent.horizontalCenter anchors.verticalCenter: parent.verticalCenter - + spacing: 5 Rectangle { color: "lightblue"; radius: 10.0 width: 300; height: 50 - Text { anchors.fill: parent - font.pointSize: 32; text: "Books" } } + Text { anchors.centerIn: parent + font.pointSize: 24; text: "Books" } } Rectangle { color: "gold"; radius: 10.0 width: 300; height: 50 - Text { anchors.fill: parent - font.pointSize: 32; text: "Music" } } + Text { anchors.centerIn: parent + font.pointSize: 24; text: "Music" } } Rectangle { color: "lightgreen"; radius: 10.0 width: 300; height: 50 - Text { anchors.fill: parent - font.pointSize: 32; text: "Movies" } } + Text { anchors.centerIn: parent + font.pointSize: 24; text: "Movies" } } } } //! [document] diff --git a/src/declarative/debugger/qdeclarativedebugservice.cpp b/src/declarative/debugger/qdeclarativedebugservice.cpp index d2ef00d..b98cd5d 100644 --- a/src/declarative/debugger/qdeclarativedebugservice.cpp +++ b/src/declarative/debugger/qdeclarativedebugservice.cpp @@ -219,8 +219,8 @@ QDeclarativeDebugServer *QDeclarativeDebugServer::instance() server->waitForConnection(); } } else { - qWarning(QString("QDeclarativeDebugServer: Ignoring \"-qmljsdebugger=%1\". " - "Format is -qmljsdebugger=port:<port>[,block]").arg( + qWarning(QString::fromAscii("QDeclarativeDebugServer: Ignoring \"-qmljsdebugger=%1\". " + "Format is -qmljsdebugger=port:<port>[,block]").arg( appD->qmljsDebugArguments).toAscii().constData()); } } diff --git a/src/declarative/declarative.pro b/src/declarative/declarative.pro index 510e7a5..299ca06 100644 --- a/src/declarative/declarative.pro +++ b/src/declarative/declarative.pro @@ -26,3 +26,7 @@ include(qml/qml.pri) include(debugger/debugger.pri) symbian:TARGET.UID3=0x2001E623 + +DEFINES += QT_NO_OPENTYPE +INCLUDEPATH += ../3rdparty/harfbuzz/src + diff --git a/src/declarative/graphicsitems/graphicsitems.pri b/src/declarative/graphicsitems/graphicsitems.pri index d420595..ffdeb29 100644 --- a/src/declarative/graphicsitems/graphicsitems.pri +++ b/src/declarative/graphicsitems/graphicsitems.pri @@ -49,7 +49,8 @@ HEADERS += \ $$PWD/qdeclarativelistview_p.h \ $$PWD/qdeclarativelayoutitem_p.h \ $$PWD/qdeclarativeitemchangelistener_p.h \ - $$PWD/qdeclarativegraphicswidget_p.h + $$PWD/qdeclarativegraphicswidget_p.h \ + $$PWD/qdeclarativetextlayout_p.h SOURCES += \ $$PWD/qdeclarativeitemsmodule.cpp \ @@ -81,4 +82,6 @@ SOURCES += \ $$PWD/qdeclarativevisualitemmodel.cpp \ $$PWD/qdeclarativelistview.cpp \ $$PWD/qdeclarativelayoutitem.cpp \ - $$PWD/qdeclarativegraphicswidget.cpp + $$PWD/qdeclarativegraphicswidget.cpp \ + $$PWD/qdeclarativetextlayout.cpp + diff --git a/src/declarative/graphicsitems/qdeclarativegridview.cpp b/src/declarative/graphicsitems/qdeclarativegridview.cpp index 8d08c99..8216ab7 100644 --- a/src/declarative/graphicsitems/qdeclarativegridview.cpp +++ b/src/declarative/graphicsitems/qdeclarativegridview.cpp @@ -2591,7 +2591,7 @@ void QDeclarativeGridView::itemsMoved(int from, int to, int count) while (moved.count()) { int idx = moved.begin().key(); FxGridItem *item = moved.take(idx); - if (item->item == d->currentItem->item) + if (d->currentItem && item->item == d->currentItem->item) item->setPosition(d->colPosAt(idx), d->rowPosAt(idx)); d->releaseItem(item); } diff --git a/src/declarative/graphicsitems/qdeclarativeimage.cpp b/src/declarative/graphicsitems/qdeclarativeimage.cpp index 9cd9ad6..08d237f 100644 --- a/src/declarative/graphicsitems/qdeclarativeimage.cpp +++ b/src/declarative/graphicsitems/qdeclarativeimage.cpp @@ -253,6 +253,15 @@ void QDeclarativeImage::setFillMode(FillMode mode) emit fillModeChanged(); } +/*! + + \qmlproperty real Image::paintedWidth + \qmlproperty real Image::paintedHeight + + These properties hold the size of the image that is actually painted. + In most cases it is the same as \c width and \c height, but when using a \c fillMode like + \c PreserveAspectFit \c paintedWidth or \c paintedHeight can be smaller than \c width and \c height. +*/ qreal QDeclarativeImage::paintedWidth() const { Q_D(const QDeclarativeImage); diff --git a/src/declarative/graphicsitems/qdeclarativelistview.cpp b/src/declarative/graphicsitems/qdeclarativelistview.cpp index c1e6aaa..6b46bc5 100644 --- a/src/declarative/graphicsitems/qdeclarativelistview.cpp +++ b/src/declarative/graphicsitems/qdeclarativelistview.cpp @@ -3090,7 +3090,7 @@ void QDeclarativeListView::itemsMoved(int from, int to, int count) while (moved.count()) { int idx = moved.begin().key(); FxListItem *item = moved.take(idx); - if (item->item == d->currentItem->item) + if (d->currentItem && item->item == d->currentItem->item) item->setPosition(d->positionAt(idx)); d->releaseItem(item); } diff --git a/src/declarative/graphicsitems/qdeclarativetext.cpp b/src/declarative/graphicsitems/qdeclarativetext.cpp index 1f4c1c7..65f1564 100644 --- a/src/declarative/graphicsitems/qdeclarativetext.cpp +++ b/src/declarative/graphicsitems/qdeclarativetext.cpp @@ -82,6 +82,19 @@ private: static QSet<QUrl> errors; }; +DEFINE_BOOL_CONFIG_OPTION(disableImageCache, QML_DISABLE_IMAGE_CACHE); + +QDeclarativeTextPrivate::QDeclarativeTextPrivate() +: color((QRgb)0), style(QDeclarativeText::Normal), + hAlign(QDeclarativeText::AlignLeft), vAlign(QDeclarativeText::AlignTop), elideMode(QDeclarativeText::ElideNone), + imgDirty(true), dirty(true), richText(false), singleline(false), cache(true), internalWidthUpdate(false), doc(0), + format(QDeclarativeText::AutoText), wrapMode(QDeclarativeText::NoWrap) +{ + cache = !disableImageCache(); + QGraphicsItemPrivate::acceptedMouseButtons = Qt::LeftButton; + QGraphicsItemPrivate::flags = QGraphicsItemPrivate::flags & ~QGraphicsItem::ItemHasNoContents; +} + QTextDocumentWithImageResources::QTextDocumentWithImageResources(QDeclarativeText *parent) : QTextDocument(parent), outstanding(0) { @@ -145,7 +158,6 @@ void QTextDocumentWithImageResources::requestFinished() void QTextDocumentWithImageResources::setText(const QString &text) { if (!m_resources.isEmpty()) { - qWarning("CLEAR"); qDeleteAll(m_resources); m_resources.clear(); outstanding = 0; @@ -792,7 +804,7 @@ void QDeclarativeTextPrivate::updateSize() //setup instance of QTextLayout for all cases other than richtext if (!richText) { - size = setupTextLayout(&layout); + size = setupTextLayout(); if (cachedLayoutSize != size) { q->prepareGeometryChange(); cachedLayoutSize = size; @@ -907,10 +919,10 @@ void QDeclarativeTextPrivate::drawOutline(int yOffset) imgCache = img; } -QSize QDeclarativeTextPrivate::setupTextLayout(QTextLayout *layout) +QSize QDeclarativeTextPrivate::setupTextLayout() { Q_Q(QDeclarativeText); - layout->setCacheEnabled(true); + layout.setCacheEnabled(true); int height = 0; qreal widthUsed = 0; @@ -920,25 +932,25 @@ QSize QDeclarativeTextPrivate::setupTextLayout(QTextLayout *layout) if ((wrapMode != QDeclarativeText::NoWrap || elideMode != QDeclarativeText::ElideNone) && q->widthValid()) lineWidth = q->width(); - QTextOption textOption = layout->textOption(); + QTextOption textOption = layout.textOption(); textOption.setWrapMode(QTextOption::WrapMode(wrapMode)); - layout->setTextOption(textOption); + layout.setTextOption(textOption); - layout->beginLayout(); + layout.beginLayout(); while (1) { - QTextLine line = layout->createLine(); + QTextLine line = layout.createLine(); if (!line.isValid()) break; if ((wrapMode != QDeclarativeText::NoWrap || elideMode != QDeclarativeText::ElideNone) && q->widthValid()) line.setLineWidth(lineWidth); } - layout->endLayout(); + layout.endLayout(); int x = 0; - for (int i = 0; i < layout->lineCount(); ++i) { - QTextLine line = layout->lineAt(i); + for (int i = 0; i < layout.lineCount(); ++i) { + QTextLine line = layout.lineAt(i); widthUsed = qMax(widthUsed, line.naturalTextWidth()); line.setPosition(QPointF(0, height)); height += int(line.height()); @@ -1000,7 +1012,7 @@ void QDeclarativeTextPrivate::drawWrappedText(QPainter *p, const QPointF &pos, b else p->setPen(color); p->setFont(font); - layout.draw(p, pos); + layout.draw(p , pos); } QPixmap QDeclarativeTextPrivate::richTextImage(bool drawStyle) @@ -1131,7 +1143,7 @@ void QDeclarativeText::paint(QPainter *p, const QStyleOptionGraphicsItem *, QWid } else { qreal y = boundingRect().y(); - bool needClip = !clip() && (d->cachedLayoutSize.width() > width() || + bool needClip = clip() && (d->cachedLayoutSize.width() > width() || d->cachedLayoutSize.height() > height()); if (needClip) { diff --git a/src/declarative/graphicsitems/qdeclarativetext_p_p.h b/src/declarative/graphicsitems/qdeclarativetext_p_p.h index 48552a7..db68558 100644 --- a/src/declarative/graphicsitems/qdeclarativetext_p_p.h +++ b/src/declarative/graphicsitems/qdeclarativetext_p_p.h @@ -55,6 +55,7 @@ #include "qdeclarativeitem.h" #include "private/qdeclarativeitem_p.h" +#include "private/qdeclarativetextlayout_p.h" #include <qdeclarative.h> @@ -69,18 +70,7 @@ class QDeclarativeTextPrivate : public QDeclarativeItemPrivate { Q_DECLARE_PUBLIC(QDeclarativeText) public: - QDeclarativeTextPrivate() - : color((QRgb)0), style(QDeclarativeText::Normal), - hAlign(QDeclarativeText::AlignLeft), vAlign(QDeclarativeText::AlignTop), elideMode(QDeclarativeText::ElideNone), - imgDirty(true), dirty(true), richText(false), singleline(false), cache(true), internalWidthUpdate(false), doc(0), - format(QDeclarativeText::AutoText), wrapMode(QDeclarativeText::NoWrap) - { -#if defined(QML_NO_TEXT_CACHE) - cache = false; -#endif - QGraphicsItemPrivate::acceptedMouseButtons = Qt::LeftButton; - QGraphicsItemPrivate::flags = QGraphicsItemPrivate::flags & ~QGraphicsItem::ItemHasNoContents; - } + QDeclarativeTextPrivate(); ~QDeclarativeTextPrivate(); @@ -101,7 +91,7 @@ public: QPixmap wrappedTextImage(bool drawStyle); void drawWrappedText(QPainter *p, const QPointF &pos, bool drawStyle); QPixmap richTextImage(bool drawStyle); - QSize setupTextLayout(QTextLayout *layout); + QSize setupTextLayout(); QString text; QFont font; @@ -121,7 +111,7 @@ public: bool cache:1; bool internalWidthUpdate:1; QTextDocumentWithImageResources *doc; - QTextLayout layout; + QDeclarativeTextLayout layout; QSize cachedLayoutSize; QDeclarativeText::TextFormat format; QDeclarativeText::WrapMode wrapMode; diff --git a/src/declarative/graphicsitems/qdeclarativetextlayout.cpp b/src/declarative/graphicsitems/qdeclarativetextlayout.cpp new file mode 100644 index 0000000..e8b5fb2 --- /dev/null +++ b/src/declarative/graphicsitems/qdeclarativetextlayout.cpp @@ -0,0 +1,358 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtDeclarative module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qdeclarativetextlayout_p.h" +#include <private/qstatictext_p.h> +#include <private/qfontengine_p.h> +#include <private/qtextengine_p.h> +#include <private/qpainter_p.h> +#include <private/qpaintengineex_p.h> + +QT_BEGIN_NAMESPACE + +class QDeclarativeTextLayoutPrivate +{ +public: + QDeclarativeTextLayoutPrivate() + : cached(false) {} + + QPointF position; + + bool cached; + QVector<QStaticTextItem> items; + QVector<QFixedPoint> positions; + QVector<glyph_t> glyphs; + QVector<QChar> chars; +}; + +Q_GUI_EXPORT extern int qt_defaultDpiX(); +Q_GUI_EXPORT extern int qt_defaultDpiY(); + +namespace { +class DrawTextItemRecorder: public QPaintEngine +{ + public: + DrawTextItemRecorder(bool untransformedCoordinates, bool useBackendOptimizations) + : m_inertText(0), m_dirtyPen(false), m_useBackendOptimizations(useBackendOptimizations), + m_untransformedCoordinates(untransformedCoordinates) + { + } + + virtual void updateState(const QPaintEngineState &newState) + { + if (newState.state() & QPaintEngine::DirtyPen) + m_dirtyPen = true; + } + + virtual void drawTextItem(const QPointF &position, const QTextItem &textItem) + { + int glyphOffset = m_inertText->glyphs.size(); // Store offset into glyph pool + int positionOffset = m_inertText->glyphs.size(); // Offset into position pool + int charOffset = m_inertText->chars.size(); + + const QTextItemInt &ti = static_cast<const QTextItemInt &>(textItem); + + bool needFreshCurrentItem = true; + if (!m_inertText->items.isEmpty()) { + QStaticTextItem &last = m_inertText->items[m_inertText->items.count() - 1]; + + if (last.fontEngine == ti.fontEngine && last.font == ti.font() && + (!m_dirtyPen || last.color == state->pen().color())) { + needFreshCurrentItem = false; + + last.numChars += ti.num_chars; + last.numGlyphs += ti.glyphs.numGlyphs; + + } + } + + if (needFreshCurrentItem) { + QStaticTextItem currentItem; + + currentItem.fontEngine = ti.fontEngine; + currentItem.font = ti.font(); + currentItem.charOffset = charOffset; + currentItem.numChars = ti.num_chars; + currentItem.numGlyphs = ti.glyphs.numGlyphs; + currentItem.glyphOffset = glyphOffset; + currentItem.positionOffset = positionOffset; + currentItem.useBackendOptimizations = m_useBackendOptimizations; + if (m_dirtyPen) + currentItem.color = state->pen().color(); + + m_inertText->items.append(currentItem); + } + + QTransform matrix = m_untransformedCoordinates ? QTransform() : state->transform(); + matrix.translate(position.x(), position.y()); + + QVarLengthArray<glyph_t> glyphs; + QVarLengthArray<QFixedPoint> positions; + ti.fontEngine->getGlyphPositions(ti.glyphs, matrix, ti.flags, glyphs, positions); + + int size = glyphs.size(); + Q_ASSERT(size == ti.glyphs.numGlyphs); + Q_ASSERT(size == positions.size()); + + m_inertText->glyphs.resize(m_inertText->glyphs.size() + size); + m_inertText->positions.resize(m_inertText->glyphs.size()); + m_inertText->chars.resize(m_inertText->chars.size() + ti.num_chars); + + glyph_t *glyphsDestination = m_inertText->glyphs.data() + glyphOffset; + qMemCopy(glyphsDestination, glyphs.constData(), sizeof(glyph_t) * ti.glyphs.numGlyphs); + + QFixedPoint *positionsDestination = m_inertText->positions.data() + positionOffset; + qMemCopy(positionsDestination, positions.constData(), sizeof(QFixedPoint) * ti.glyphs.numGlyphs); + + QChar *charsDestination = m_inertText->chars.data() + charOffset; + qMemCopy(charsDestination, ti.chars, sizeof(QChar) * ti.num_chars); + + } + + virtual void drawPolygon(const QPointF *, int , PolygonDrawMode ) + { + /* intentionally empty */ + } + + virtual bool begin(QPaintDevice *) { return true; } + virtual bool end() { return true; } + virtual void drawPixmap(const QRectF &, const QPixmap &, const QRectF &) {} + virtual Type type() const + { + return User; + } + + void begin(QDeclarativeTextLayoutPrivate *t) { + m_inertText = t; + m_dirtyPen = false; + } + + private: + QDeclarativeTextLayoutPrivate *m_inertText; + + bool m_dirtyPen; + bool m_useBackendOptimizations; + bool m_untransformedCoordinates; +}; + +class DrawTextItemDevice: public QPaintDevice +{ + public: + DrawTextItemDevice(bool untransformedCoordinates, bool useBackendOptimizations) + { + m_paintEngine = new DrawTextItemRecorder(untransformedCoordinates, + useBackendOptimizations); + } + + ~DrawTextItemDevice() + { + delete m_paintEngine; + } + + void begin(QDeclarativeTextLayoutPrivate *t) { + m_paintEngine->begin(t); + } + + int metric(PaintDeviceMetric m) const + { + int val; + switch (m) { + case PdmWidth: + case PdmHeight: + case PdmWidthMM: + case PdmHeightMM: + val = 0; + break; + case PdmDpiX: + case PdmPhysicalDpiX: + val = qt_defaultDpiX(); + break; + case PdmDpiY: + case PdmPhysicalDpiY: + val = qt_defaultDpiY(); + break; + case PdmNumColors: + val = 16777216; + break; + case PdmDepth: + val = 24; + break; + default: + val = 0; + qWarning("DrawTextItemDevice::metric: Invalid metric command"); + } + return val; + } + + virtual QPaintEngine *paintEngine() const + { + return m_paintEngine; + } + + private: + DrawTextItemRecorder *m_paintEngine; +}; + +struct InertTextPainter { + InertTextPainter() + : device(true, true), painter(&device) {} + + DrawTextItemDevice device; + QPainter painter; +}; +} + +Q_GLOBAL_STATIC(InertTextPainter, inertTextPainter); + +/*! +\class QDeclarativeTextLayout +\brief The QDeclarativeTextLayout class is a version of QStaticText that works with QTextLayouts. +\internal + +This class is basically a copy of the QStaticText code, but it is adapted to source its text from +QTextLayout. + +It is also considerably faster to create a QDeclarativeTextLayout than a QStaticText because it uses +a single, shared QPainter instance. QStaticText by comparison creates a new QPainter per instance. +As a consequence this means that QDeclarativeTextLayout is not re-enterant. Adding a lock around +the shared painter solves this, and only introduces a minor performance penalty, but is unnecessary +for QDeclarativeTextLayout's current use (QDeclarativeText is already tied to the GUI thread). +*/ + +QDeclarativeTextLayout::QDeclarativeTextLayout() +: d(0) +{ +} + +QDeclarativeTextLayout::QDeclarativeTextLayout(const QString &text) +: QTextLayout(text), d(0) +{ +} + +QDeclarativeTextLayout::~QDeclarativeTextLayout() +{ + if (d) delete d; +} + +void QDeclarativeTextLayout::beginLayout() +{ + if (d && d->cached) { + d->cached = false; + d->items.clear(); + d->positions.clear(); + d->glyphs.clear(); + d->chars.clear(); + d->position = QPointF(); + } + QTextLayout::beginLayout(); +} + +void QDeclarativeTextLayout::prepare() +{ + if (!d || !d->cached) { + + if (!d) + d = new QDeclarativeTextLayoutPrivate; + + InertTextPainter *itp = inertTextPainter(); + itp->device.begin(d); + QTextLayout::draw(&itp->painter, QPointF(0, 0)); + + glyph_t *glyphPool = d->glyphs.data(); + QFixedPoint *positionPool = d->positions.data(); + QChar *charPool = d->chars.data(); + + int itemCount = d->items.count(); + for (int ii = 0; ii < itemCount; ++ii) { + QStaticTextItem &item = d->items[ii]; + item.glyphs = glyphPool + item.glyphOffset; + item.glyphPositions = positionPool + item.positionOffset; + item.chars = charPool + item.charOffset; + } + + d->cached = true; + } +} + +void QDeclarativeTextLayout::draw(QPainter *painter, const QPointF &p) +{ + QPainterPrivate *priv = QPainterPrivate::get(painter); + + bool paintEngineSupportsTransformations = priv->extended && + (priv->extended->type() == QPaintEngine::OpenGL2 || + priv->extended->type() == QPaintEngine::OpenVG || + priv->extended->type() == QPaintEngine::OpenGL); + + if (!paintEngineSupportsTransformations) { + QTextLayout::draw(painter, p); + return; + } + + prepare(); + + int itemCount = d->items.count(); + + if (p != d->position) { + QFixed fx = QFixed::fromReal(p.x()); + QFixed fy = QFixed::fromReal(p.y()); + QFixed oldX = QFixed::fromReal(d->position.x()); + QFixed oldY = QFixed::fromReal(d->position.y()); + for (int item = 0; item < itemCount; ++item) { + QStaticTextItem &textItem = d->items[item]; + + for (int ii = 0; ii < textItem.numGlyphs; ++ii) { + textItem.glyphPositions[ii].x += fx - oldX; + textItem.glyphPositions[ii].y += fy - oldY; + } + textItem.userDataNeedsUpdate = true; + } + + d->position = p; + } + + for (int ii = 0; ii < itemCount; ++ii) { + QStaticTextItem &item = d->items[ii]; + priv->extended->drawStaticTextItem(&item); + } +} + +QT_END_NAMESPACE + diff --git a/src/declarative/graphicsitems/qdeclarativetextlayout_p.h b/src/declarative/graphicsitems/qdeclarativetextlayout_p.h new file mode 100644 index 0000000..90bf0e0 --- /dev/null +++ b/src/declarative/graphicsitems/qdeclarativetextlayout_p.h @@ -0,0 +1,74 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtDeclarative module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QDECLARATIVETEXTLAYOUT_P_H +#define QDECLARATIVETEXTLAYOUT_P_H + +#include <QtGui/qtextlayout.h> + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +QT_MODULE(Declarative) + +class QDeclarativeTextLayoutPrivate; +class QDeclarativeTextLayout : public QTextLayout +{ +public: + QDeclarativeTextLayout(); + QDeclarativeTextLayout(const QString &); + ~QDeclarativeTextLayout(); + + void beginLayout(); + + void prepare(); + void draw(QPainter *, const QPointF & = QPointF()); + +private: + QDeclarativeTextLayoutPrivate *d; +}; + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif // QDECLARATIVETEXTLAYOUT_P_H diff --git a/src/declarative/graphicsitems/qdeclarativevisualitemmodel_p.h b/src/declarative/graphicsitems/qdeclarativevisualitemmodel_p.h index e159786..f09d8dd 100644 --- a/src/declarative/graphicsitems/qdeclarativevisualitemmodel_p.h +++ b/src/declarative/graphicsitems/qdeclarativevisualitemmodel_p.h @@ -67,7 +67,6 @@ class Q_AUTOTEST_EXPORT QDeclarativeVisualModel : public QObject Q_PROPERTY(int count READ count NOTIFY countChanged) public: - QDeclarativeVisualModel(QObject *parent=0) : QObject(parent) {} virtual ~QDeclarativeVisualModel() {} enum ReleaseFlag { Referenced = 0x01, Destroyed = 0x02 }; @@ -79,7 +78,7 @@ public: virtual ReleaseFlags release(QDeclarativeItem *item) = 0; virtual bool completePending() const = 0; virtual void completeItem() = 0; - virtual QString stringValue(int, const QString &) { return QString(); } + virtual QString stringValue(int, const QString &) = 0; virtual int indexOf(QDeclarativeItem *item, QObject *objectContext) const = 0; diff --git a/src/declarative/qml/qdeclarativeengine.cpp b/src/declarative/qml/qdeclarativeengine.cpp index cffded3..9ca7858 100644 --- a/src/declarative/qml/qdeclarativeengine.cpp +++ b/src/declarative/qml/qdeclarativeengine.cpp @@ -207,7 +207,7 @@ For example: import QtQuick 1.0 Text { - color: Qt.rgba(255, 0, 0, 1) + color: Qt.rgba(1, 0, 0, 1) text: Qt.md5("hello, world") } \endqml @@ -284,9 +284,11 @@ QDeclarativeEnginePrivate::QDeclarativeEnginePrivate(QDeclarativeEngine *e) QUrl QDeclarativeScriptEngine::resolvedUrl(QScriptContext *context, const QUrl& url) { if (p) { - QDeclarativeContextData *ctxt = QDeclarativeEnginePrivate::get(this)->getContext(context); - Q_ASSERT(ctxt); - return ctxt->resolvedUrl(url); + QDeclarativeContextData *ctxt = p->getContext(context); + if (ctxt) + return ctxt->resolvedUrl(url); + else + return p->getUrl(context).resolved(url); } return baseUrl.resolved(url); } @@ -1146,12 +1148,8 @@ QScriptValue QDeclarativeEnginePrivate::createComponent(QScriptContext *ctxt, QS QString arg = ctxt->argument(0).toString(); if (arg.isEmpty()) return engine->nullValue(); - QUrl url; + QUrl url = QDeclarativeScriptEngine::get(engine)->resolvedUrl(ctxt, QUrl(arg)); QDeclarativeContextData* context = activeEnginePriv->getContext(ctxt); - if (context) - url = QUrl(context->resolvedUrl(QUrl(arg))); - else - url = activeEnginePriv->getUrl(ctxt).resolved(QUrl(arg)); QDeclarativeComponent *c = new QDeclarativeComponent(activeEngine, url, activeEngine); QDeclarativeComponentPrivate::get(c)->creationContext = context; QDeclarativeData::get(c, true)->setImplicitDestructible(); @@ -1635,7 +1633,7 @@ QScriptValue QDeclarativeEnginePrivate::desktopOpenUrl(QScriptContext *ctxt, QSc return QScriptValue(e, false); bool ret = false; #ifndef QT_NO_DESKTOPSERVICES - ret = QDesktopServices::openUrl(QUrl(ctxt->argument(0).toString())); + ret = QDesktopServices::openUrl(QDeclarativeScriptEngine::get(e)->resolvedUrl(ctxt, QUrl(ctxt->argument(0).toString()))); #endif return QScriptValue(e, ret); } diff --git a/src/declarative/qml/rewriter/rewriter.cpp b/src/declarative/qml/rewriter/rewriter.cpp deleted file mode 100644 index 6d2ccfb..0000000 --- a/src/declarative/qml/rewriter/rewriter.cpp +++ /dev/null @@ -1,102 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtDeclarative module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the Technology Preview License Agreement accompanying -** this package. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** If you have questions regarding the use of this file, please contact -** Nokia at qt-info@nokia.com. -** -** -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "private/rewriter_p.h" - -#include <qdeclarativejsast_p.h> - -QT_QML_BEGIN_NAMESPACE - -using namespace QDeclarativeJS; - -void Rewriter::replace(const AST::SourceLocation &loc, const QString &text) -{ replace(loc.offset, loc.length, text); } - -void Rewriter::remove(const AST::SourceLocation &loc) -{ return replace(loc.offset, loc.length, QString()); } - -void Rewriter::remove(const AST::SourceLocation &firstLoc, const AST::SourceLocation &lastLoc) -{ return replace(firstLoc.offset, lastLoc.offset + lastLoc.length - firstLoc.offset, QString()); } - -void Rewriter::insertTextBefore(const AST::SourceLocation &loc, const QString &text) -{ replace(loc.offset, 0, text); } - -void Rewriter::insertTextAfter(const AST::SourceLocation &loc, const QString &text) -{ replace(loc.offset + loc.length, 0, text); } - -void Rewriter::replace(int offset, int length, const QString &text) -{ textWriter.replace(offset, length, text); } - -void Rewriter::insertText(int offset, const QString &text) -{ replace(offset, 0, text); } - -void Rewriter::removeText(int offset, int length) -{ replace(offset, length, QString()); } - -QString Rewriter::textAt(const AST::SourceLocation &loc) const -{ return _code.mid(loc.offset, loc.length); } - -QString Rewriter::textAt(const AST::SourceLocation &firstLoc, const AST::SourceLocation &lastLoc) const -{ return _code.mid(firstLoc.offset, lastLoc.offset + lastLoc.length - firstLoc.offset); } - -void Rewriter::accept(QDeclarativeJS::AST::Node *node) -{ QDeclarativeJS::AST::Node::acceptChild(node, this); } - -void Rewriter::moveTextBefore(const AST::SourceLocation &firstLoc, - const AST::SourceLocation &lastLoc, - const AST::SourceLocation &loc) -{ - move(firstLoc.offset, lastLoc.offset + lastLoc.length - firstLoc.offset, loc.offset); -} - -void Rewriter::moveTextAfter(const AST::SourceLocation &firstLoc, - const AST::SourceLocation &lastLoc, - const AST::SourceLocation &loc) -{ - move(firstLoc.offset, lastLoc.offset + lastLoc.length - firstLoc.offset, loc.offset + loc.length); -} - -void Rewriter::move(int pos, int length, int to) -{ - textWriter.move(pos, length, to); -} - -QT_QML_END_NAMESPACE diff --git a/src/declarative/qml/rewriter/rewriter.pri b/src/declarative/qml/rewriter/rewriter.pri index 2c29061..a9fa1b5 100644 --- a/src/declarative/qml/rewriter/rewriter.pri +++ b/src/declarative/qml/rewriter/rewriter.pri @@ -2,8 +2,3 @@ INCLUDEPATH += $$PWD HEADERS += $$PWD/textwriter_p.h SOURCES += $$PWD/textwriter.cpp - -!no_ast_rewriter { - HEADERS += $$PWD/rewriter_p.h - SOURCES += $$PWD/rewriter.cpp -} diff --git a/src/declarative/qml/rewriter/rewriter_p.h b/src/declarative/qml/rewriter/rewriter_p.h deleted file mode 100644 index 4799469..0000000 --- a/src/declarative/qml/rewriter/rewriter_p.h +++ /dev/null @@ -1,153 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtDeclarative module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the Technology Preview License Agreement accompanying -** this package. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** If you have questions regarding the use of this file, please contact -** Nokia at qt-info@nokia.com. -** -** -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef REWRITER_H -#define REWRITER_H - -#include "private/textwriter_p.h" - -#include <qdeclarativejsastvisitor_p.h> - -#include <QtCore/QList> -#include <QtCore/QString> - -QT_BEGIN_HEADER -QT_QML_BEGIN_NAMESPACE - -namespace QDeclarativeJS { - -//////////////////////////////////////////////////////////////////////////////// -// Replacement -//////////////////////////////////////////////////////////////////////////////// -class Replacement -{ - int _offset; - int _length; - QString _text; - -public: - Replacement(int offset = 0, int length = 0, const QString &text = QString()) - : _offset(offset), _length(length), _text(text) - { } - - bool isNull() const { return _offset == _length; } - operator bool() const { return ! isNull(); } - - int offset() const { return _offset; } - int length() const { return _length; } - QString text() const { return _text; } -}; - - - -//////////////////////////////////////////////////////////////////////////////// -// Rewriter -//////////////////////////////////////////////////////////////////////////////// -class Rewriter: public AST::Visitor -{ -protected: - TextWriter textWriter; -public: - // - // Token based API - // - - /// Returns the text of the token at the given \a location. - QString textAt(const AST::SourceLocation &location) const; - - QString textAt(const AST::SourceLocation &firstLoc, - const AST::SourceLocation &lastLoc) const; - - /// Replace the token at \a loc with the given \a text. - void replace(const AST::SourceLocation &loc, const QString &text); - - /// Remove the token at the given \a location. - void remove(const AST::SourceLocation &location); - - /// Remove all tokens in the range [\a firstLoc, \a lastLoc]. - void remove(const AST::SourceLocation &firstLoc, const AST::SourceLocation &lastLoc); - - /// Insert \a text before the token at the given \a location. - void insertTextBefore(const AST::SourceLocation &location, const QString &text); - - /// Insert \a text after the token at the given \a location. - void insertTextAfter(const AST::SourceLocation &loc, const QString &text); - - void moveTextBefore(const AST::SourceLocation &firstLoc, - const AST::SourceLocation &lastLoc, - const AST::SourceLocation &loc); - - void moveTextAfter(const AST::SourceLocation &firstLoc, - const AST::SourceLocation &lastLoc, - const AST::SourceLocation &loc); - - // - // low-level offset based API - // - virtual void replace(int offset, int length, const QString &text); - virtual void move(int pos, int length, int to); - void insertText(int offset, const QString &text); - void removeText(int offset, int length); - - /// Visit the given \a node. - void accept(AST::Node *node); - - /// Returns the original unchanged source code. - QString code() const { return _code; } - - /// Returns the list of replacements. - QList<Replacement> replacementList() const { return _replacementList; } - -protected: - /// \internal - void setCode(const QString &code) { _code = code; } - -private: - QString _code; - QList<Replacement> _replacementList; -}; - -} // end of namespace QDeclarativeJS - -QT_QML_END_NAMESPACE -QT_END_HEADER - -#endif // REWRITER_H diff --git a/src/declarative/util/qdeclarativexmllistmodel.cpp b/src/declarative/util/qdeclarativexmllistmodel.cpp index 028fcbc..337b1e0 100644 --- a/src/declarative/util/qdeclarativexmllistmodel.cpp +++ b/src/declarative/util/qdeclarativexmllistmodel.cpp @@ -476,7 +476,7 @@ public: void QDeclarativeXmlListModelPrivate::append_role(QDeclarativeListProperty<QDeclarativeXmlListModelRole> *list, QDeclarativeXmlListModelRole *role) { QDeclarativeXmlListModel *_this = qobject_cast<QDeclarativeXmlListModel *>(list->object); - if (_this) { + if (_this && role) { int i = _this->d_func()->roleObjects.count(); _this->d_func()->roleObjects.append(role); if (_this->d_func()->roleNames.contains(role->name())) { diff --git a/tests/auto/declarative/qdeclarativeimage/tst_qdeclarativeimage.cpp b/tests/auto/declarative/qdeclarativeimage/tst_qdeclarativeimage.cpp index 6fce2ad..8f9b2ea 100644 --- a/tests/auto/declarative/qdeclarativeimage/tst_qdeclarativeimage.cpp +++ b/tests/auto/declarative/qdeclarativeimage/tst_qdeclarativeimage.cpp @@ -83,6 +83,7 @@ private slots: void big(); void tiling_QTBUG_6716(); void noLoading(); + void paintedWidthHeight(); private: template<typename T> @@ -395,6 +396,46 @@ void tst_qdeclarativeimage::noLoading() QTRY_COMPARE(statusSpy.count(), 2); } +void tst_qdeclarativeimage::paintedWidthHeight() +{ + { + QString src = QUrl::fromLocalFile(SRCDIR "/data/heart.png").toString(); + QString componentStr = "import QtQuick 1.0\nImage { source: \"" + src + "\"; width: 200; height: 25; fillMode: Image.PreserveAspectFit }"; + + QDeclarativeComponent component(&engine); + component.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); + QDeclarativeImage *obj = qobject_cast<QDeclarativeImage*>(component.create()); + QVERIFY(obj != 0); + QCOMPARE(obj->pixmap().width(), 300); + QCOMPARE(obj->pixmap().height(), 300); + QCOMPARE(obj->width(), 200.0); + QCOMPARE(obj->height(), 25.0); + QCOMPARE(obj->paintedWidth(), 25.0); + QCOMPARE(obj->paintedHeight(), 25.0); + QCOMPARE(obj->pixmap(), QPixmap(SRCDIR "/data/heart.png")); + + delete obj; + } + + { + QString src = QUrl::fromLocalFile(SRCDIR "/data/heart.png").toString(); + QString componentStr = "import QtQuick 1.0\nImage { source: \"" + src + "\"; width: 26; height: 175; fillMode: Image.PreserveAspectFit }"; + QDeclarativeComponent component(&engine); + component.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); + QDeclarativeImage *obj = qobject_cast<QDeclarativeImage*>(component.create()); + QVERIFY(obj != 0); + QCOMPARE(obj->pixmap().width(), 300); + QCOMPARE(obj->pixmap().height(), 300); + QCOMPARE(obj->width(), 26.0); + QCOMPARE(obj->height(), 175.0); + QCOMPARE(obj->paintedWidth(), 26.0); + QCOMPARE(obj->paintedHeight(), 26.0); + QCOMPARE(obj->pixmap(), QPixmap(SRCDIR "/data/heart.png")); + + delete obj; + } +} + /* Find an item with the specified objectName. If index is supplied then the item must also evaluate the {index} expression equal to index diff --git a/tests/auto/declarative/qdeclarativeitem/data/keystest.qml b/tests/auto/declarative/qdeclarativeitem/data/keystest.qml index aedccd9..3927f42 100644 --- a/tests/auto/declarative/qdeclarativeitem/data/keystest.qml +++ b/tests/auto/declarative/qdeclarativeitem/data/keystest.qml @@ -2,6 +2,9 @@ import QtQuick 1.0 Item { focus: true + + property bool isEnabled: Keys.enabled + Keys.onPressed: keysTestObject.keyPress(event.key, event.text, event.modifiers) Keys.onReleased: { keysTestObject.keyRelease(event.key, event.text, event.modifiers); event.accepted = true; } Keys.onReturnPressed: keysTestObject.keyPress(event.key, "Return", event.modifiers) diff --git a/tests/auto/declarative/qdeclarativeitem/tst_qdeclarativeitem.cpp b/tests/auto/declarative/qdeclarativeitem/tst_qdeclarativeitem.cpp index e9dad6b..bbbf73e 100644 --- a/tests/auto/declarative/qdeclarativeitem/tst_qdeclarativeitem.cpp +++ b/tests/auto/declarative/qdeclarativeitem/tst_qdeclarativeitem.cpp @@ -214,6 +214,9 @@ void tst_QDeclarativeItem::keys() QFocusEvent fe(QEvent::FocusIn); QApplication::sendEvent(canvas, &fe); + QVERIFY(canvas->rootObject()); + QCOMPARE(canvas->rootObject()->property("isEnabled").toBool(), true); + QKeyEvent key(QEvent::KeyPress, Qt::Key_A, Qt::NoModifier, "A", false, 1); QApplication::sendEvent(canvas, &key); QCOMPARE(testObject->mKey, int(Qt::Key_A)); @@ -285,6 +288,7 @@ void tst_QDeclarativeItem::keys() testObject->reset(); canvas->rootContext()->setContextProperty("enableKeyHanding", QVariant(false)); + QCOMPARE(canvas->rootObject()->property("isEnabled").toBool(), false); key = QKeyEvent(QEvent::KeyPress, Qt::Key_Return, Qt::NoModifier, "", false, 1); QApplication::sendEvent(canvas, &key); @@ -292,6 +296,7 @@ void tst_QDeclarativeItem::keys() QVERIFY(!key.isAccepted()); canvas->rootContext()->setContextProperty("enableKeyHanding", QVariant(true)); + QCOMPARE(canvas->rootObject()->property("isEnabled").toBool(), true); key = QKeyEvent(QEvent::KeyPress, Qt::Key_Return, Qt::NoModifier, "", false, 1); QApplication::sendEvent(canvas, &key); diff --git a/tests/auto/declarative/qdeclarativelanguage/tst_qdeclarativelanguage.cpp b/tests/auto/declarative/qdeclarativelanguage/tst_qdeclarativelanguage.cpp index 7f81fc0..8609a7e 100644 --- a/tests/auto/declarative/qdeclarativelanguage/tst_qdeclarativelanguage.cpp +++ b/tests/auto/declarative/qdeclarativelanguage/tst_qdeclarativelanguage.cpp @@ -128,6 +128,8 @@ private slots: void defaultPropertyListOrder(); void declaredPropertyValues(); void dontDoubleCallClassBegin(); + void reservedWords_data(); + void reservedWords(); void basicRemote_data(); void basicRemote(); @@ -1222,6 +1224,80 @@ void tst_qdeclarativelanguage::dontDoubleCallClassBegin() delete o; } +void tst_qdeclarativelanguage::reservedWords_data() +{ + QTest::addColumn<QByteArray>("word"); + + QTest::newRow("abstract") << QByteArray("abstract"); + QTest::newRow("as") << QByteArray("as"); + QTest::newRow("boolean") << QByteArray("boolean"); + QTest::newRow("break") << QByteArray("break"); + QTest::newRow("byte") << QByteArray("byte"); + QTest::newRow("case") << QByteArray("case"); + QTest::newRow("catch") << QByteArray("catch"); + QTest::newRow("char") << QByteArray("char"); + QTest::newRow("class") << QByteArray("class"); + QTest::newRow("continue") << QByteArray("continue"); + QTest::newRow("const") << QByteArray("const"); + QTest::newRow("debugger") << QByteArray("debugger"); + QTest::newRow("default") << QByteArray("default"); + QTest::newRow("delete") << QByteArray("delete"); + QTest::newRow("do") << QByteArray("do"); + QTest::newRow("double") << QByteArray("double"); + QTest::newRow("else") << QByteArray("else"); + QTest::newRow("enum") << QByteArray("enum"); + QTest::newRow("export") << QByteArray("export"); + QTest::newRow("extends") << QByteArray("extends"); + QTest::newRow("false") << QByteArray("false"); + QTest::newRow("final") << QByteArray("final"); + QTest::newRow("finally") << QByteArray("finally"); + QTest::newRow("float") << QByteArray("float"); + QTest::newRow("for") << QByteArray("for"); + QTest::newRow("function") << QByteArray("function"); + QTest::newRow("goto") << QByteArray("goto"); + QTest::newRow("if") << QByteArray("if"); + QTest::newRow("implements") << QByteArray("implements"); + QTest::newRow("import") << QByteArray("import"); + QTest::newRow("in") << QByteArray("in"); + QTest::newRow("instanceof") << QByteArray("instanceof"); + QTest::newRow("int") << QByteArray("int"); + QTest::newRow("interface") << QByteArray("interface"); + QTest::newRow("long") << QByteArray("long"); + QTest::newRow("native") << QByteArray("native"); + QTest::newRow("new") << QByteArray("new"); + QTest::newRow("null") << QByteArray("null"); + QTest::newRow("package") << QByteArray("package"); + QTest::newRow("private") << QByteArray("private"); + QTest::newRow("protected") << QByteArray("protected"); + QTest::newRow("public") << QByteArray("public"); + QTest::newRow("return") << QByteArray("return"); + QTest::newRow("short") << QByteArray("short"); + QTest::newRow("static") << QByteArray("static"); + QTest::newRow("super") << QByteArray("super"); + QTest::newRow("switch") << QByteArray("switch"); + QTest::newRow("synchronized") << QByteArray("synchronized"); + QTest::newRow("this") << QByteArray("this"); + QTest::newRow("throw") << QByteArray("throw"); + QTest::newRow("throws") << QByteArray("throws"); + QTest::newRow("transient") << QByteArray("transient"); + QTest::newRow("true") << QByteArray("true"); + QTest::newRow("try") << QByteArray("try"); + QTest::newRow("typeof") << QByteArray("typeof"); + QTest::newRow("var") << QByteArray("var"); + QTest::newRow("void") << QByteArray("void"); + QTest::newRow("volatile") << QByteArray("volatile"); + QTest::newRow("while") << QByteArray("while"); + QTest::newRow("with") << QByteArray("with"); +} + +void tst_qdeclarativelanguage::reservedWords() +{ + QFETCH(QByteArray, word); + QDeclarativeComponent component(&engine); + component.setData("import QtQuick 1.0\nQtObject { property string " + word + " }", QUrl()); + QCOMPARE(component.errorString(), QLatin1String(":2 Expected token `identifier'\n")); +} + // Check that first child of qml is of given type. Empty type insists on error. void tst_qdeclarativelanguage::testType(const QString& qml, const QString& type, const QString& expectederror) { diff --git a/tests/auto/declarative/qdeclarativelayoutitem/tst_qdeclarativelayoutitem.cpp b/tests/auto/declarative/qdeclarativelayoutitem/tst_qdeclarativelayoutitem.cpp index bbdba74..cc0f633 100644 --- a/tests/auto/declarative/qdeclarativelayoutitem/tst_qdeclarativelayoutitem.cpp +++ b/tests/auto/declarative/qdeclarativelayoutitem/tst_qdeclarativelayoutitem.cpp @@ -82,6 +82,11 @@ void tst_qdeclarativelayoutitem::test_resizing() QDeclarativeEngine engine; QDeclarativeComponent c(&engine, QUrl::fromLocalFile(SRCDIR "/data/layoutItem.qml")); QDeclarativeLayoutItem* obj = static_cast<QDeclarativeLayoutItem*>(c.create()); + QVERIFY(obj); + QCOMPARE(obj->minimumSize(), QSizeF(100,100)); + QCOMPARE(obj->preferredSize(), QSizeF(200,200)); + QCOMPARE(obj->maximumSize(), QSizeF(300,300)); + layout->addItem(obj); layout->setContentsMargins(0,0,0,0); widget->setContentsMargins(0,0,0,0); diff --git a/tests/auto/declarative/qdeclarativemousearea/tst_qdeclarativemousearea.cpp b/tests/auto/declarative/qdeclarativemousearea/tst_qdeclarativemousearea.cpp index e4ec01f..5e88450 100644 --- a/tests/auto/declarative/qdeclarativemousearea/tst_qdeclarativemousearea.cpp +++ b/tests/auto/declarative/qdeclarativemousearea/tst_qdeclarativemousearea.cpp @@ -356,6 +356,7 @@ void tst_QDeclarativeMouseArea::onMousePressRejected() canvas->show(); canvas->setFocus(); QVERIFY(canvas->rootObject() != 0); + QVERIFY(canvas->rootObject()->property("enabled").toBool()); QVERIFY(!canvas->rootObject()->property("mr1_pressed").toBool()); QVERIFY(!canvas->rootObject()->property("mr1_released").toBool()); diff --git a/tests/auto/declarative/qdeclarativepathview/data/closedPath.qml b/tests/auto/declarative/qdeclarativepathview/data/closedPath.qml new file mode 100644 index 0000000..08b0d2a --- /dev/null +++ b/tests/auto/declarative/qdeclarativepathview/data/closedPath.qml @@ -0,0 +1,24 @@ +import QtQuick 1.0 + +Path { + startY: 120 + startX: 160 + PathQuad { + y: 120 + x: 80 + controlY: 330 + controlX: 100 + } + PathLine { + y: 160 + x: 20 + } + PathCubic { + y: 120 + x: 160 + control1Y: 0 + control1X: 100 + control2Y: 000 + control2X: 200 + } +} diff --git a/tests/auto/declarative/qdeclarativepathview/data/openPath.qml b/tests/auto/declarative/qdeclarativepathview/data/openPath.qml new file mode 100644 index 0000000..328e3cd --- /dev/null +++ b/tests/auto/declarative/qdeclarativepathview/data/openPath.qml @@ -0,0 +1,10 @@ +import QtQuick 1.0 + +Path { + startY: 120 + startX: 160 + PathLine { + y: 160 + x: 20 + } +} diff --git a/tests/auto/declarative/qdeclarativepathview/tst_qdeclarativepathview.cpp b/tests/auto/declarative/qdeclarativepathview/tst_qdeclarativepathview.cpp index 3b5d438..65007a6 100644 --- a/tests/auto/declarative/qdeclarativepathview/tst_qdeclarativepathview.cpp +++ b/tests/auto/declarative/qdeclarativepathview/tst_qdeclarativepathview.cpp @@ -85,6 +85,7 @@ private slots: void pathUpdateOnStartChanged(); void package(); void emptyModel(); + void closed(); private: QDeclarativeView *createView(); @@ -786,6 +787,26 @@ void tst_QDeclarativePathView::emptyModel() delete canvas; } +void tst_QDeclarativePathView::closed() +{ + QDeclarativeEngine engine; + + { + QDeclarativeComponent c(&engine, QUrl::fromLocalFile(SRCDIR "/data/openPath.qml")); + QDeclarativePath *obj = qobject_cast<QDeclarativePath*>(c.create()); + QVERIFY(obj); + QCOMPARE(obj->isClosed(), false); + delete obj; + } + + { + QDeclarativeComponent c(&engine, QUrl::fromLocalFile(SRCDIR "/data/closedPath.qml")); + QDeclarativePath *obj = qobject_cast<QDeclarativePath*>(c.create()); + QVERIFY(obj); + QCOMPARE(obj->isClosed(), true); + delete obj; + } +} QDeclarativeView *tst_QDeclarativePathView::createView() { diff --git a/tests/auto/declarative/qdeclarativepositioners/tst_qdeclarativepositioners.cpp b/tests/auto/declarative/qdeclarativepositioners/tst_qdeclarativepositioners.cpp index 57a8354..254349f 100644 --- a/tests/auto/declarative/qdeclarativepositioners/tst_qdeclarativepositioners.cpp +++ b/tests/auto/declarative/qdeclarativepositioners/tst_qdeclarativepositioners.cpp @@ -322,7 +322,8 @@ void tst_QDeclarativePositioners::test_grid() QCOMPARE(five->x(), 50.0); QCOMPARE(five->y(), 50.0); - QDeclarativeItem *grid = canvas->rootObject()->findChild<QDeclarativeItem*>("grid"); + QDeclarativeGrid *grid = canvas->rootObject()->findChild<QDeclarativeGrid*>("grid"); + QCOMPARE(grid->flow(), QDeclarativeGrid::LeftToRight); QCOMPARE(grid->width(), 120.0); QCOMPARE(grid->height(), 100.0); @@ -355,7 +356,8 @@ void tst_QDeclarativePositioners::test_grid_topToBottom() QCOMPARE(five->x(), 50.0); QCOMPARE(five->y(), 50.0); - QDeclarativeItem *grid = canvas->rootObject()->findChild<QDeclarativeItem*>("grid"); + QDeclarativeGrid *grid = canvas->rootObject()->findChild<QDeclarativeGrid*>("grid"); + QCOMPARE(grid->flow(), QDeclarativeGrid::TopToBottom); QCOMPARE(grid->width(), 100.0); QCOMPARE(grid->height(), 120.0); @@ -670,10 +672,12 @@ void tst_QDeclarativePositioners::test_flow_implicit_resize() QCOMPARE(flow->height(), 120.0); canvas->rootObject()->setProperty("leftToRight", true); + QCOMPARE(flow->flow(), QDeclarativeFlow::LeftToRight); QCOMPARE(flow->width(), 220.0); QCOMPARE(flow->height(), 50.0); canvas->rootObject()->setProperty("leftToRight", false); + QCOMPARE(flow->flow(), QDeclarativeFlow::TopToBottom); QCOMPARE(flow->width(), 100.0); QCOMPARE(flow->height(), 120.0); diff --git a/tests/auto/declarative/qdeclarativeqt/data/openUrlExternally.qml b/tests/auto/declarative/qdeclarativeqt/data/openUrlExternally.qml index c9fb25e..dc4049c 100644 --- a/tests/auto/declarative/qdeclarativeqt/data/openUrlExternally.qml +++ b/tests/auto/declarative/qdeclarativeqt/data/openUrlExternally.qml @@ -2,4 +2,7 @@ import QtQuick 1.0 QtObject { Component.onCompleted: Qt.openUrlExternally("test:url") + + property bool testFile + onTestFileChanged: Qt.openUrlExternally("test.html") } diff --git a/tests/auto/declarative/qdeclarativeqt/data/openUrlExternally_lib.js b/tests/auto/declarative/qdeclarativeqt/data/openUrlExternally_lib.js new file mode 100644 index 0000000..702357a --- /dev/null +++ b/tests/auto/declarative/qdeclarativeqt/data/openUrlExternally_lib.js @@ -0,0 +1,9 @@ +.pragma library + +function loadTest() { + Qt.openUrlExternally("test:url") +} + +function loadFile() { + Qt.openUrlExternally("test.html") +} diff --git a/tests/auto/declarative/qdeclarativeqt/data/openUrlExternally_lib.qml b/tests/auto/declarative/qdeclarativeqt/data/openUrlExternally_lib.qml new file mode 100644 index 0000000..456653b --- /dev/null +++ b/tests/auto/declarative/qdeclarativeqt/data/openUrlExternally_lib.qml @@ -0,0 +1,9 @@ +import QtQuick 1.0 +import "openUrlExternally_lib.js" as Test + +Item { + Component.onCompleted: Test.loadTest(); + + property bool testFile + onTestFileChanged: Test.loadFile(); +} diff --git a/tests/auto/declarative/qdeclarativeqt/tst_qdeclarativeqt.cpp b/tests/auto/declarative/qdeclarativeqt/tst_qdeclarativeqt.cpp index 739b10a..9f45d74 100644 --- a/tests/auto/declarative/qdeclarativeqt/tst_qdeclarativeqt.cpp +++ b/tests/auto/declarative/qdeclarativeqt/tst_qdeclarativeqt.cpp @@ -75,6 +75,7 @@ private slots: void darker(); void tint(); void openUrlExternally(); + void openUrlExternally_pragmaLibrary(); void md5(); void createComponent(); void createComponent_pragmaLibrary(); @@ -321,6 +322,7 @@ void tst_qdeclarativeqt::openUrlExternally() MyUrlHandler handler; QDesktopServices::setUrlHandler("test", &handler, "noteCall"); + QDesktopServices::setUrlHandler("file", &handler, "noteCall"); QDeclarativeComponent component(&engine, TEST_FILE("openUrlExternally.qml")); QObject *object = component.create(); @@ -328,7 +330,35 @@ void tst_qdeclarativeqt::openUrlExternally() QCOMPARE(handler.called,1); QCOMPARE(handler.last, QUrl("test:url")); + object->setProperty("testFile", true); + + QCOMPARE(handler.called,2); + QCOMPARE(handler.last, TEST_FILE("test.html")); + + QDesktopServices::unsetUrlHandler("test"); + QDesktopServices::unsetUrlHandler("file"); +} + +void tst_qdeclarativeqt::openUrlExternally_pragmaLibrary() +{ + MyUrlHandler handler; + + QDesktopServices::setUrlHandler("test", &handler, "noteCall"); + QDesktopServices::setUrlHandler("file", &handler, "noteCall"); + + QDeclarativeComponent component(&engine, TEST_FILE("openUrlExternally_lib.qml")); + QObject *object = component.create(); + QVERIFY(object != 0); + QCOMPARE(handler.called,1); + QCOMPARE(handler.last, QUrl("test:url")); + + object->setProperty("testFile", true); + + QCOMPARE(handler.called,2); + QCOMPARE(handler.last, TEST_FILE("test.html")); + QDesktopServices::unsetUrlHandler("test"); + QDesktopServices::unsetUrlHandler("file"); } void tst_qdeclarativeqt::md5() diff --git a/tests/auto/declarative/qdeclarativexmllistmodel/data/roleCrash.qml b/tests/auto/declarative/qdeclarativexmllistmodel/data/roleCrash.qml new file mode 100644 index 0000000..492dad9 --- /dev/null +++ b/tests/auto/declarative/qdeclarativexmllistmodel/data/roleCrash.qml @@ -0,0 +1,7 @@ +import QtQuick 1.0 + +XmlListModel { + id: model + XmlRole {} + Component.onCompleted: model.roles = 0 +} diff --git a/tests/auto/declarative/qdeclarativexmllistmodel/tst_qdeclarativexmllistmodel.cpp b/tests/auto/declarative/qdeclarativexmllistmodel/tst_qdeclarativexmllistmodel.cpp index bd19bd3..a14f942 100644 --- a/tests/auto/declarative/qdeclarativexmllistmodel/tst_qdeclarativexmllistmodel.cpp +++ b/tests/auto/declarative/qdeclarativexmllistmodel/tst_qdeclarativexmllistmodel.cpp @@ -96,6 +96,8 @@ private slots: void threading_data(); void propertyChanges(); + void roleCrash(); + private: QString makeItemXmlAndData(const QString &data, QDeclarativeXmlModelData *modelData = 0) const { @@ -825,6 +827,15 @@ void tst_qdeclarativexmllistmodel::propertyChanges() delete model; } +void tst_qdeclarativexmllistmodel::roleCrash() +{ + // don't crash + QDeclarativeComponent component(&engine, QUrl::fromLocalFile(SRCDIR "/data/roleCrash.qml")); + QDeclarativeXmlListModel *model = qobject_cast<QDeclarativeXmlListModel*>(component.create()); + QVERIFY(model != 0); + delete model; +} + QTEST_MAIN(tst_qdeclarativexmllistmodel) #include "tst_qdeclarativexmllistmodel.moc" |