diff options
author | Martin Jones <martin.jones@nokia.com> | 2010-03-29 05:43:19 (GMT) |
---|---|---|
committer | Martin Jones <martin.jones@nokia.com> | 2010-03-29 05:43:19 (GMT) |
commit | be53372df21a099474ac0b28b95f29a077a8b3f0 (patch) | |
tree | 4f1ccca05a3d219bc21d275e3173bb3b0f040304 | |
parent | 7f01d8851f912051b35af7dd078372c9970d45fe (diff) | |
parent | 28bd5d733ba1b0eedd3fff24ad42ab0e5e87a2e6 (diff) | |
download | Qt-be53372df21a099474ac0b28b95f29a077a8b3f0.zip Qt-be53372df21a099474ac0b28b95f29a077a8b3f0.tar.gz Qt-be53372df21a099474ac0b28b95f29a077a8b3f0.tar.bz2 |
Merge branch '4.7' of scm.dev.nokia.troll.no:qt/qt-qml into 4.7
48 files changed, 1083 insertions, 528 deletions
diff --git a/doc/src/declarative/extending.qdoc b/doc/src/declarative/extending.qdoc index 3dce8c3..b6aa9da 100644 --- a/doc/src/declarative/extending.qdoc +++ b/doc/src/declarative/extending.qdoc @@ -654,9 +654,8 @@ declaring a new property, and the corresponding C++ type. \row \o string \o QString \row \o url \o QUrl \row \o color \o QColor -\row \o date \o QDate +\row \o date \o QDateTime \row \o var \o QVariant -\row \o variant \o QVariant \endtable QML supports two methods for adding a new property to a type: a new property diff --git a/doc/src/declarative/globalobject.qdoc b/doc/src/declarative/globalobject.qdoc index 9f6be12..addc192 100644 --- a/doc/src/declarative/globalobject.qdoc +++ b/doc/src/declarative/globalobject.qdoc @@ -301,4 +301,9 @@ When a database is first created, an INI file is also created specifying its cha This data can be used by application tools. +\section1 Logging + +\c console.log() and \c console.debug() can be used to print information +to the console. See \l{Debugging QML} for more information. + */ diff --git a/doc/src/declarative/modules.qdoc b/doc/src/declarative/modules.qdoc index ae014c0..13658d8 100644 --- a/doc/src/declarative/modules.qdoc +++ b/doc/src/declarative/modules.qdoc @@ -42,159 +42,106 @@ /*! \page qdeclarativemodules.html \title Modules -\section1 QML Modules. -QUERY: Is a directory with no qmldir really a module? Assumed NO. +\section1 QML Modules -A \bold module is a collection of QML types. These types can be defined in QML, or in C++ -through a QDeclarativeExtensionPlugin. They can then be collected into a directory to comprise -a module. +A \bold {QML module} is a collection of QML types. They allow you to organize your QML content +into independent units. Modules have an optional versioning mechanism that allows for independent +upgradability of the modules. -Additionally a module can also be a collection of types which was compiled into your application, see \l{Extending QML in C++}. +There are two types of modules: +location modules (defined by a URL), +and +installed modules (defined by a URI). -While a directory containing types can be used to organize QML components, QML modules also contain a \c qmldir file. -This file provides a manifest of all types available in the module, -and allows versioned imports (among other things). A directory containing only QML files or plugins behaves similarly -to a module, but a QML module requires a \c qmldir file (unless it is written in C++ and compiled into your application). - -\section2 The \c qmldir File - -QML modules containing installed files and remote content require a file \c qmldir which specifies the -mapping from all type names to versioned QML files. It is a list of lines of the form: - -\code -# <Comment> -<TypeName> <InitialVersion> <File> -plugin <Name> [<Path>] -\endcode - -# <Comment> lines are ignored, and can be used for comments. - -<TypeName> <InitialVersion> <File> lines are used to add QML files as types. -<TypeName> is the type being made available; <InitialVersion> is a version -number like \c 4.0; <File> is the (relative) -file name of the QML file defining the type. - -plugin <Name> [<Path>] lines are used to add plugins (QDeclarativeExtensionPlugin subclasses -written in C++) to the module. The line starts with the keyword 'plugin'; <Name> is the -name of the library; <Path> is an optional argument specifying the full path to the directory -containing the plugin file, if it is omitted then the directory is assumed to be the same as -the directory of the qmldir file. Note that <Name> is not usually the same as the file name -of the plugin binary, which is platform dependent e.g. the library MyAppTypes would produce a libMyAppTypes.so on linux and MyAppTypes.dll on windows. - -The same type can be provided by different files in different versions, in which -case later earlier versions (eg. 1.2) must precede earlier versions (eg. 1.0), -since the \e first name-version match is used. - -Installed files do not need to import the module of which they are a part, as they can refer -to the other QML files in the module as relative (local) files. -If the module is imported from a remote location, those files must nevertheless be listed in -the \c qmldir file. Internal files can be marked with the \c internal keyword, to ensure -they are not visible outside the module: +Location modules types are defined in QML files and \l{QDeclarativeExtensionPlugin}{QML C++ plugins} +in a directory refered to directly by +the location URL, either on the local filesystem, or as a network resource. The URL that locates them +can be relative, in which case they actual URL is resolved by the QML file containing the import. +When importing a location module, a quoted URL is used: \code -internal <TypeName> <File> +import "https://qml.nokia.com/qml/example" 1.0 +import "https://qml.nokia.com/qml/example" as NokiaExample +import "mymodule" 1.0 +import "mymodule" \endcode -Installed and remote files \e must be referred to by version information described above, -local files \e may have it. - -The versioning system ensures that a given QML file will work regardless of the version -of installed software, since a versioned import \e only imports types for that version, -leaving other identifiers available, even if the actual installed version might otherwise -use those identifiers. - -\section1 Importing Modules - -To use types from a module it must be imported using the \c import statement. Successive -import statements override earlier import statements, however, since imports have version -qualifiers, changes in modules do not alter the semantics of imports. - -While it is possible to import some modules without specifying a version this is only advisable -during prototyping, where version numbers mean very little. The rest of the time it is recommended that -you take advantage of the versioning capabilities of the language. - -You can import a directory in the same way that you import a module, except that you cannot specify a version -number. This will import all the types in that directory as QML files or as part of plugins. - -Types \link adding-types defined in C++\endlink can be from types your application defines, standard QML types, -or types defined in plugins. To use any such types, you must import -the module defining them. For example, to use types from Qt, import it: +Installed modules can \e only be on the local file system or in application C++ code. Again they +are defined in QML files and \l{QDeclarativeExtensionPlugin}{QML C++ plugins} in a directory, +but the directory is indirectly referred to by the URI. The mapping to actual content is either +by application C++ code registering a C++ type to a module URI (see \l{Extending QML in C++}), +or in the referenced subdirectory of a path on the import path (see below). +When importing a location module, an un-quoted URI is used: \code -import Qt 4.6 +import com.nokia.qml.mymodule 1.0 +import com.nokia.qml.mymodule as MyModule \endcode -This makes available all types in Qt that were available in Qt 4.6, regardless of the -actual version of Qt executing the QML. So even if Qt 4.7 adds a type that would conflict -with a type you defined while using 4.6, that type is not imported, so there is no conflict. - -Types defined by plugins are made using QDeclarativeExtensionPlugin. Installed plugins and QML files -can both contribute types to the same module. +For either type of module, a \c qmldir file in the module directory defines the content of the module. This file is +optional for location modules, but only for local filesystem content or a single remote content with a namespace. +The second exception is explained in more detail in the section below on Namespaces. -\section1 Importing Types Defined in QML +\seciont2 The Import Path -When importing types \link components defined using QML\endlink, the syntax depends -on whether or not the types are installed on the system. +Installed modules are searched for on the import path. +The \c -L option to the \l {Qt Declarative UI Runtime}{qml} runtime adds paths to the import path. +From C++, the path is available via \l QDeclarativeEngine::importPathList() and can be prepended to +using \l QDeclarativeEngine::addImportPath(). -\section2 Installed QML Files +\section2 The \c qmldir File -To import types defined in QML files that are installed on the system running the -QML, a URI import is used: +Installed QML modules and remote content without a namespace require a file \c qmldir which +specifies the mapping from all type names to versioned QML files. It is a list of lines of the form: \code -import com.nokia.Example 1.0 +# <Comment> +<TypeName> [<InitialVersion>] <File> +internal <Name> <File> +plugin <Name> [<Path>] \endcode -Files imported in this way are found on the paths added by QDeclarativeEngine::addImportPath(), -which by default only inludes \c $QTDIR/qml, so the above would make available those types -defined in \c $QTDIR/qml/com/nokia/Example which are specified as being in version 1.0. -Installed plugins and QML files can both contribute types to the same module. - -The specification of types to versions is given by a special file, \c qmldir which must -exist in the module directory. The syntax is described below. - -The \c -L option to the \l {Qt Declarative UI Runtime}{qml} application also adds paths to the import path. - - -\section2 Local QML Files - -To import types defined in QML files in directories relative to the file importing them, -a quoted import directory is used: - -\code -import "path" -\endcode +# <Comment> lines are ignored, and can be used for comments. -This allows all components defined in the directory \c path to be used in -the component where this statement appears. Because no version number is specified, -all types in the directory will be imported. +<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 +number like \c 4.0; <File> is the (relative) +file name of the QML file defining the type. -In this case, and only this case, it is not necessary for the directory to include -a \c qmldir file, nor is it necessary to provide a version qualifier. The basis of this is -that the files in the subdirectory are assumed to be packaged with the importer, and therefore -they form a single versioned unit. It is however recommended that you add a qmldir file and create -a QML module, as this provides additional options such as more flexible versioning. If the directory -is a module then you can use a version qualifier, like below +Installed files do not need to import the module of which they are a part, as they can refer +to the other QML files in the module as relative (local) files, but +if the module is imported from a remote location, those files must nevertheless be listed in +the \c qmldir file. Types which you do not wish to export to users of your module +may be marked with the \c internal keyword: \code -import "path" 1.0 +internal <TypeName> <File> \endcode +\c plugin <Name> [<Path>] lines are used to add \l{QDeclarativeExtensionPlugin}{QML C++ plugins} +to the module. <Name> is the +name of the library. <Path> is an optional argument specifying the full path to the directory +containing the plugin file; if it is omitted then the directory is assumed to be the same as +the directory of the \c qmldir file. Note that <Name> is not usually the same as the file name +of the plugin binary, which is platform dependent; e.g. the library MyAppTypes would produce +a libMyAppTypes.so on Linux and MyAppTypes.dll on Windows. -\section2 Remote QML Files - -To import types defined in QML file at arbitrary network locations, a quoted absolute URL is used: +The same type can be provided by different files in different versions, in which +case later earlier versions (eg. 1.2) must precede earlier versions (eg. 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. -\code -import "http://url/.../" 1.0 -\endcode +Installed and remote files without a namespace \e must be referred to by version information described above, +local files \e may have it. -This works the same as for relative directory imports, except that the target location contain a QML module (\e must -include a \c qmldir file), and a version qualifier must be given. +The versioning system ensures that a given QML file will work regardless of the version +of installed software, since a versioned import \e only imports types for that version, +leaving other identifiers available, even if the actual installed version might otherwise +provide those identifiers. -\section1 Namespaces - Named Imports +\section2 Namespaces - Named Imports When importing content it by default imports types into the global namespace. You may choose to import the module into another namespace, either to allow identically-named @@ -220,20 +167,15 @@ import Qt 4.6 as Nokia import Ovi 1.0 as Nokia \endcode -There is one special module, called Qt, which contains all of the types that are part of -Qt Declarative. While it still needs to be imported, this module can be used in all QML -files. - -While import statements are need to make any types available in QML, the directory of the +While import statements are needed to make any types available in QML, the directory of the current file is implicitly loaded. This is the exact same as if you had added 'import "."' to -every QML file. The effect of this is that you can automatically use Types defined in C++ plugins +every QML file. The effect of this is that you can automatically use types defined in C++ plugins or QML files if they reside in the same directory. - */ /* -See original requirement QT-558. +Original requirement is QT-558. */ diff --git a/doc/src/declarative/qmlruntime.qdoc b/doc/src/declarative/qmlruntime.qdoc index cfef536..8bb3ec7 100644 --- a/doc/src/declarative/qmlruntime.qdoc +++ b/doc/src/declarative/qmlruntime.qdoc @@ -42,6 +42,7 @@ /*! \page qmlruntime.html \title Qt Declarative UI Runtime + \keyword qml runtime \ingroup qttools This page documents the \e{Declarative UI Runtime} for the Qt GUI @@ -148,8 +149,8 @@ import QDeclarativeViewer 1.0 as QDeclarativeViewer Item { - QDeclarativeViewer.Screen { id: viewerScreen } - state: (viewerScreen.orientation == QDeclarativeViewer.Screen.Landscape) ? 'landscape' : '' + QDeclarativeViewer.Screen { id: screen } + state: (screen.orientation == QDeclarativeViewer.Screen.Landscape) ? 'landscape' : '' } \endcode diff --git a/examples/declarative/colorbrowser/colorbrowser.qml b/examples/declarative/colorbrowser/colorbrowser.qml deleted file mode 100644 index d4c21e7..0000000 --- a/examples/declarative/colorbrowser/colorbrowser.qml +++ /dev/null @@ -1,101 +0,0 @@ -import Qt 4.6 -import 'qml' - -Rectangle { - id: mainWindow - width: 800; height: 480; color: '#454545' - - VisualDataModel { id: colorsVisualModel; delegate: colorsDelegate; model: ColorsModel } - - Component { - id: colorsDelegate - Package { - - Item { - Package.name: 'grid' - GridView { - id: gridView; model: visualModel.parts.grid; width: mainWindow.width; height: mainWindow.height - cellWidth: 160; cellHeight: 160; interactive: false - onCurrentIndexChanged: listView.positionViewAtIndex(currentIndex, ListView.Contain) - } - } - - Item { - Package.name: 'fullscreen' - ListView { - id: listView; model: visualModel.parts.list; orientation: Qt.Horizontal - width: mainWindow.width; height: mainWindow.height; interactive: false - onCurrentIndexChanged: gridView.positionViewAtIndex(currentIndex, GridView.Contain) - highlightRangeMode: ListView.StrictlyEnforceRange; snapMode: ListView.SnapOneItem - } - } - - Item { - Package.name: 'stack' - id: wrapper - width: 260; height: 240 - - VisualDataModel { id: visualModel; model: colors; delegate: ColorDelegate {} } - - PathView { - id: pathView; model: visualModel.parts.stack; anchors.centerIn: parent - pathItemCount: 3 - path: Path { - PathAttribute { name: 'z'; value: 9999.0 } - PathLine { x: 1; y: 1 } - PathAttribute { name: 'z'; value: 0.0 } - } - } - - Item { - anchors.horizontalCenter: parent.horizontalCenter; anchors.bottom: parent.bottom; anchors.bottomMargin: 20 - width: albumTitle.width + 20 ; height: albumTitle.height + 4 - Text { id: albumTitle; text: name; color: 'white'; font.bold: true; anchors.centerIn: parent } - } - - MouseArea { anchors.fill: parent; onClicked: wrapper.state = 'inGrid' } - - states: [ - State { - name: 'inGrid' - PropertyChanges { target: gridView; interactive: true } - PropertyChanges { target: shade; opacity: 1 } - }, - State { - name: 'fullscreen'; extend: 'inGrid' - PropertyChanges { target: gridView; interactive: false } - PropertyChanges { target: listView; interactive: true } - PropertyChanges { target: infobox; opacity: 1 } - } - ] - - transitions: [ - Transition { - from: ''; to: 'inGrid'; reversible: true - NumberAnimation { target: shade; properties: 'opacity'; duration: 300 } - }, - Transition { - from: 'inGrid'; to: 'fullscreen'; reversible: true - SequentialAnimation { - PauseAnimation { duration: 300 } - NumberAnimation { target: infobox; properties: 'opacity'; duration: 300 } - } - } - ] - } - } - } - - GridView { width: parent.width; height: parent.height; cellWidth: 260; cellHeight: 240; model: colorsVisualModel.parts.stack } - Rectangle { id: shade; color: '#454545'; width: parent.width; height: parent.height; opacity: 0 } - ListView { anchors.fill: parent; model: colorsVisualModel.parts.grid; interactive: false } - ListView { anchors.fill: parent; model: colorsVisualModel.parts.fullscreen; interactive: false } - Item { id: foreground; anchors.fill: parent } - - Column { - id: infobox; opacity: 0 - anchors { left: parent.left; leftMargin: 20; bottom: parent.bottom; bottomMargin: 20 } - Text { id: infoColorName; color: '#eeeeee'; style: Text.Outline; styleColor: '#222222'; font.pointSize: 18 } - Text { id: infoColorHex; color: '#eeeeee'; style: Text.Outline; styleColor: '#222222'; font.pointSize: 14 } - } -} diff --git a/examples/declarative/colorbrowser/dummydata/ColorsModel.qml b/examples/declarative/colorbrowser/dummydata/ColorsModel.qml deleted file mode 100644 index eefbcfe..0000000 --- a/examples/declarative/colorbrowser/dummydata/ColorsModel.qml +++ /dev/null @@ -1,96 +0,0 @@ -import Qt 4.6 - -ListModel { - id: colorsModel - - ListElement { - name: "Reds" - colors: [ - ListElement { name: "Fire Brick"; hex: "#B22222" }, - ListElement { name: "Fire Brick 1"; hex: "#FF3030" }, - ListElement { name: "Fire Brick 2"; hex: "#EE2C2C" }, - ListElement { name: "Fire Brick 3"; hex: "#CD2626" }, - ListElement { name: "Fire Brick 4"; hex: "#8B1A1A" }, - ListElement { name: "Red"; hex: "#FF0000" }, - ListElement { name: "Red 2"; hex: "#EE0000" }, - ListElement { name: "Red 3"; hex: "#CD0000" }, - ListElement { name: "Red 4"; hex: "#8B0000" }, - ListElement { name: "Tomato"; hex: "#FF6347" }, - ListElement { name: "Tomato 2"; hex: "#EE5C42" }, - ListElement { name: "Tomato 3"; hex: "#CD4F39" }, - ListElement { name: "Tomato 4"; hex: "#8B3626" }, - ListElement { name: "Orange Red"; hex: "#FF4500" }, - ListElement { name: "Orange Red 2"; hex: "#EE4000" }, - ListElement { name: "Orange Red 3"; hex: "#CD3700" }, - ListElement { name: "Orange Red 4"; hex: "#8B2500" }, - ListElement { name: "Indian Red 2"; hex: "#EE6363" }, - ListElement { name: "Indian Red 3"; hex: "#CD5555" }, - ListElement { name: "Indian Red 4"; hex: "#8B3A3A" }, - ListElement { name: "Brown"; hex: "#A52A2A" }, - ListElement { name: "Brown 1"; hex: "#FF4040" }, - ListElement { name: "Brown 2"; hex: "#EE3B3B" }, - ListElement { name: "Brown 3"; hex: "#CD3333" }, - ListElement { name: "Brown 4"; hex: "#8B2323" } - ] - } - ListElement { - name: "Greens" - colors: [ - ListElement { name: "Green"; hex: "#008000" }, - ListElement { name: "Green 2"; hex: "#00EE00" }, - ListElement { name: "Green 3"; hex: "#00CD00" }, - ListElement { name: "Green 4"; hex: "#008B00" }, - ListElement { name: "Dark Green"; hex: "#006400" }, - ListElement { name: "Sap Green"; hex: "#308014" }, - ListElement { name: "Medium Spring Green"; hex: "#00FA9A" }, - ListElement { name: "Spring Green"; hex: "#00FF7F" }, - ListElement { name: "Spring Green 1"; hex: "#00EE76" }, - ListElement { name: "Spring Green 2"; hex: "#00CD66" }, - ListElement { name: "Spring Green 3"; hex: "#008B45" }, - ListElement { name: "Medium Sea Green"; hex: "#3CB371" }, - ListElement { name: "Sea Green 1"; hex: "#54FF9F" }, - ListElement { name: "Sea Green 2"; hex: "#4EEE94" }, - ListElement { name: "Sea Green 3"; hex: "#43CD80" }, - ListElement { name: "Sea Green 4"; hex: "#2E8B57" }, - ListElement { name: "Emerald Green"; hex: "#00C957" }, - ListElement { name: "Mint"; hex: "#BDFCC9" }, - ListElement { name: "Cobalt Green"; hex: "#3D9140" }, - ListElement { name: "Dark Sea Green"; hex: "#8FBC8F" }, - ListElement { name: "Dark Sea Green 1"; hex: "#C1FFC1" }, - ListElement { name: "Dark Sea Green 2"; hex: "#B4EEB4" }, - ListElement { name: "Dark Sea Green 3"; hex: "#9BCD9B" }, - ListElement { name: "Dark Sea Green 4"; hex: "#698B69" }, - ListElement { name: "Lime Green"; hex: "#00FF00" } - ] - } - ListElement { - name: "Blues" - colors: [ - ListElement { name: "Dark Slate Blue"; hex: "#483D8B" }, - ListElement { name: "Light Slate Blue"; hex: "#8470FF" }, - ListElement { name: "Medium Slate Blue"; hex: "#7B68EE" }, - ListElement { name: "Slate Blue"; hex: "#6A5ACD" }, - ListElement { name: "Blue"; hex: "#0000FF" }, - ListElement { name: "Midnight Blue"; hex: "#191970" }, - ListElement { name: "Cobalt"; hex: "#3D59AB" }, - ListElement { name: "Royal Blue"; hex: "#4169E1" }, - ListElement { name: "Corn Flower Blue"; hex: "#6495ED" }, - ListElement { name: "Light Steel Blue"; hex: "#B0C4DE" }, - ListElement { name: "Light Steel Blue 1"; hex: "#CAE1FF" }, - ListElement { name: "Light Steel Blue 2"; hex: "#BCD2EE" }, - ListElement { name: "Light Steel Blue 3"; hex: "#A2B5CD" }, - ListElement { name: "Dodger Blue"; hex: "#1E90FF" }, - ListElement { name: "Dodger Blue 2"; hex: "#1C86EE" }, - ListElement { name: "Dodger Blue 3"; hex: "#1874CD" }, - ListElement { name: "Dodger Blue 4"; hex: "#104E8B" }, - ListElement { name: "Steel Blue"; hex: "#4682B4" }, - ListElement { name: "Light Sky Blue"; hex: "#87CEFA" }, - ListElement { name: "Sky Blue"; hex: "#87CEEB" }, - ListElement { name: "Peacock"; hex: "#33A1C9" }, - ListElement { name: "Light Blue"; hex: "#ADD8E6" }, - ListElement { name: "Powder Blue"; hex: "#B0E0E6" }, - ListElement { name: "Cadet Blue"; hex: "#5F9EA0" }, - ListElement { name: "Cyan"; hex: "#00FFFF" } - ] - } -} diff --git a/examples/declarative/colorbrowser/qml/ColorDelegate.qml b/examples/declarative/colorbrowser/qml/ColorDelegate.qml deleted file mode 100644 index c123d12..0000000 --- a/examples/declarative/colorbrowser/qml/ColorDelegate.qml +++ /dev/null @@ -1,114 +0,0 @@ -import Qt 4.6 - -Package { - Item { id: stack; Package.name: 'stack'; width: 110; height: 110; z: stack.PathView.z } - Item { id: list; Package.name: 'list'; width: mainWindow.width + 4; height: 110 } - Item { id: grid; Package.name: 'grid'; width: 110; height: 110 } - - Item { - id: delegate - - property double randomAngle: Math.random() * (2 * 8 + 1) - 8 - property bool open: false - - width: 110; height: 110; z: stack.PathView.z - - Image { x: -6; y: -5; source: 'box-shadow.png'; smooth: true; } - Rectangle { color: hex; anchors.fill: parent; smooth: true } - Image { id: box; source: 'box.png'; smooth: true; anchors.fill: parent } - - Binding { - target: infoColorName; property: 'text' - value: name; when: delegate.open && list.ListView.isCurrentItem - } - - Binding { - target: infoColorHex; property: 'text' - value: hex; when: delegate.open && list.ListView.isCurrentItem - } - - MouseArea { - anchors.fill: parent - acceptedButtons: Qt.RightButton | Qt.LeftButton - onClicked: { - if (wrapper.state == 'inGrid' && mouse.button == Qt.RightButton) { - wrapper.state = '' - } else if (wrapper.state == 'inGrid') { - grid.GridView.view.currentIndex = index; - wrapper.state = 'fullscreen' - } else { - grid.GridView.view.currentIndex = index; - wrapper.state = 'inGrid' - } - } - } - - states: [ - State { - name: 'stacked'; when: wrapper.state == '' - ParentChange { target: delegate; parent: stack; x: 0; y: 0; rotation: delegate.randomAngle } - PropertyChanges { target: delegate; visible: stack.PathView.onPath ? 1.0 : 0.0 } - }, - State { - name: 'inGrid'; when: wrapper.state == 'inGrid' - ParentChange { target: delegate; parent: grid; x: 24; y: 24 } - PropertyChanges { target: delegate; open: true } - }, - State { - name: 'fullscreen'; when: wrapper.state == 'fullscreen' - ParentChange { target: delegate; parent: list; x: 0; y: 0; width: mainWindow.width; height: mainWindow.height } - PropertyChanges { target: box; opacity: 0 } - PropertyChanges { target: delegate; open: true } - } - ] - - transitions: [ - Transition { - from: 'stacked'; to: 'inGrid' - SequentialAnimation { - PauseAnimation { duration: 20 * index } - ParentAnimation { - target: delegate; via: foreground - NumberAnimation { targets: delegate; properties: 'x,y,width,height,rotation'; duration: 600; easing.type: 'OutBack' } - } - } - }, - Transition { - from: 'inGrid'; to: 'stacked' - ParentAnimation { - target: delegate; via: foreground - NumberAnimation { properties: 'x,y,width,height,rotation'; duration: 300; easing.type: 'InOutQuad' } - } - }, - Transition { - from: 'inGrid'; to: 'fullscreen' - SequentialAnimation { - PauseAnimation { duration: grid.GridView.isCurrentItem ? 0 : 300 } - ParentAnimation { - target: delegate; via: foreground - NumberAnimation { - properties: 'x,y,width,height,opacity' - duration: grid.GridView.isCurrentItem ? 300 : 1; easing.type: 'InOutQuad' - } - } - } - }, - Transition { - from: 'fullscreen'; to: 'inGrid' - SequentialAnimation { - PauseAnimation { duration: grid.GridView.isCurrentItem ? 3 : 0 } - ParallelAnimation { - ParentAnimation { - target: delegate; via: foreground - NumberAnimation { - properties: 'x,y,width,height' - duration: grid.GridView.isCurrentItem ? 300 : 1; easing.type: 'InOutQuad' - } - } - NumberAnimation { properties: 'opacity'; duration: grid.GridView.isCurrentItem ? 300 : 1; easing.type: 'InOutQuad' } - } - } - } - ] - } -} diff --git a/examples/declarative/colorbrowser/qml/box-shadow.png b/examples/declarative/colorbrowser/qml/box-shadow.png Binary files differdeleted file mode 100644 index 3281a37..0000000 --- a/examples/declarative/colorbrowser/qml/box-shadow.png +++ /dev/null diff --git a/examples/declarative/colorbrowser/qml/box.png b/examples/declarative/colorbrowser/qml/box.png Binary files differdeleted file mode 100644 index 86538aa..0000000 --- a/examples/declarative/colorbrowser/qml/box.png +++ /dev/null diff --git a/examples/declarative/declarative.pro b/examples/declarative/declarative.pro index b8c0200..bddfbee 100644 --- a/examples/declarative/declarative.pro +++ b/examples/declarative/declarative.pro @@ -5,7 +5,8 @@ SUBDIRS = \ extending \ imageprovider \ objectlistmodel \ - plugins + plugins \ + widgets # These examples contain no C++ and can simply be copied sources.files = \ @@ -14,12 +15,12 @@ sources.files = \ behaviours \ border-image \ clocks \ - colorbrowser \ connections \ dial \ dynamic \ effects \ fillmode \ + focus \ focusscope \ fonts \ gridview \ diff --git a/examples/declarative/focus/Core/ContextMenu.qml b/examples/declarative/focus/Core/ContextMenu.qml new file mode 100644 index 0000000..bd6d8a2 --- /dev/null +++ b/examples/declarative/focus/Core/ContextMenu.qml @@ -0,0 +1,15 @@ +import Qt 4.6 + +FocusScope { + id: container + property bool open: false + + Item { + anchors.fill: parent + + Rectangle { + anchors.fill: parent; color: "#D1DBBD"; focus: true + Keys.onRightPressed: mainView.focus = true + } + } +} diff --git a/examples/declarative/focus/Core/GridMenu.qml b/examples/declarative/focus/Core/GridMenu.qml new file mode 100644 index 0000000..03d837a --- /dev/null +++ b/examples/declarative/focus/Core/GridMenu.qml @@ -0,0 +1,54 @@ +import Qt 4.6 + +FocusScope { + property alias interactive: gridView.interactive + + onWantsFocusChanged: if (wantsFocus) mainView.state = "" + + Rectangle { + clip: true; anchors.fill: parent + gradient: Gradient { + GradientStop { position: 0.0; color: "#193441" } + GradientStop { position: 1.0; color: Qt.darker("#193441") } + } + + GridView { + id: gridView; cellWidth: 152; cellHeight: 152; focus: true + x: 20; width: parent.width - 40; height: parent.height + model: 12 + KeyNavigation.down: listViews + KeyNavigation.left: contextMenu + + delegate: Item { + id: container; width: GridView.view.cellWidth; height: GridView.view.cellHeight + + Rectangle { + id: content + color: "transparent"; smooth: true + anchors.centerIn: parent; width: container.width - 40; height: container.height - 40; radius: 10 + Rectangle { color: "#91AA9D"; x: 3; y: 3; width: parent.width - 6; height: parent.height - 6; radius: 8 } + Image { source: "images/qt-logo.png"; anchors.centerIn: parent; smooth: true } + } + + MouseArea { + id: mouseArea; anchors.fill: parent; hoverEnabled: true + onClicked: { + GridView.view.currentIndex = index + container.focus = true + gridMenu.focus = true + mainView.focus = true + } + } + + states: State { + name: "active"; when: container.focus == true + PropertyChanges { target: content; color: "#FCFFF5"; scale: 1.1 } + } + + transitions: Transition { + NumberAnimation { properties: "scale"; duration: 100 } + } + } + } + } +} diff --git a/examples/declarative/focus/Core/ListViewDelegate.qml b/examples/declarative/focus/Core/ListViewDelegate.qml new file mode 100644 index 0000000..b7e067a --- /dev/null +++ b/examples/declarative/focus/Core/ListViewDelegate.qml @@ -0,0 +1,39 @@ +import Qt 4.6 + +Component { + Item { + id: container + x: 5; width: ListView.view.width - 10; height: 60 + + Rectangle { + id: content + color: "transparent"; smooth: true + anchors.centerIn: parent; width: container.width - 40; height: container.height - 10; radius: 10 + Rectangle { color: "#91AA9D"; x: 3; y: 3; width: parent.width - 6; height: parent.height - 6; radius: 8 } + Text { + text: "List element " + (index + 1); color: "#193441"; font.bold: false; anchors.centerIn: parent + font.pixelSize: 14 + } + } + + MouseArea { + id: mouseArea; anchors.fill: parent; hoverEnabled: true + onClicked: { + ListView.view.currentIndex = index + container.focus = true + ListView.view.focus = true + listViews.focus = true + mainView.focus = true + } + } + + states: State { + name: "active"; when: container.focus == true + PropertyChanges { target: content; color: "#FCFFF5"; scale: 1.1 } + } + + transitions: Transition { + NumberAnimation { properties: "scale"; duration: 100 } + } + } +} diff --git a/examples/declarative/focus/Core/ListViews.qml b/examples/declarative/focus/Core/ListViews.qml new file mode 100644 index 0000000..3cc4836 --- /dev/null +++ b/examples/declarative/focus/Core/ListViews.qml @@ -0,0 +1,47 @@ +import Qt 4.6 + +FocusScope { + clip: true + + onWantsFocusChanged: if (wantsFocus) mainView.state = "showListViews" + + ListView { + id: list1 + delegate: ListViewDelegate {} + y: wantsFocus ? 10 : 40; focus: true; width: parent.width / 3; height: parent.height - 20 + model: 10; KeyNavigation.up: gridMenu; KeyNavigation.left: contextMenu; KeyNavigation.right: list2 + Behavior on y { NumberAnimation { duration: 600; easing.type: "OutQuint" } } + } + + ListView { + id: list2 + delegate: ListViewDelegate {} + y: wantsFocus ? 10 : 40; x: parent.width / 3; width: parent.width / 3; height: parent.height - 20 + model: 10; KeyNavigation.up: gridMenu; KeyNavigation.left: list1; KeyNavigation.right: list3 + Behavior on y { NumberAnimation { duration: 600; easing.type: "OutQuint" } } + } + + ListView { + id: list3 + delegate: ListViewDelegate {} + y: wantsFocus ? 10 : 40; x: 2 * parent.width / 3; width: parent.width / 3; height: parent.height - 20 + model: 10; KeyNavigation.up: gridMenu; KeyNavigation.left: list2 + Behavior on y { NumberAnimation { duration: 600; easing.type: "OutQuint" } } + } + + Rectangle { width: parent.width; height: 1; color: "#D1DBBD" } + Rectangle { + y: 1; width: parent.width; height: 10 + gradient: Gradient { + GradientStop { position: 0.0; color: "#3E606F" } + GradientStop { position: 1.0; color: "transparent" } + } + } + Rectangle { + y: parent.height - 10; width: parent.width; height: 10 + gradient: Gradient { + GradientStop { position: 1.0; color: "#3E606F" } + GradientStop { position: 0.0; color: "transparent" } + } + } +} diff --git a/examples/declarative/focus/Core/images/arrow.png b/examples/declarative/focus/Core/images/arrow.png Binary files differnew file mode 100644 index 0000000..14978c2 --- /dev/null +++ b/examples/declarative/focus/Core/images/arrow.png diff --git a/examples/declarative/focus/Core/images/qt-logo.png b/examples/declarative/focus/Core/images/qt-logo.png Binary files differnew file mode 100644 index 0000000..14ddf2a --- /dev/null +++ b/examples/declarative/focus/Core/images/qt-logo.png diff --git a/examples/declarative/focus/Core/qmldir b/examples/declarative/focus/Core/qmldir new file mode 100644 index 0000000..0460d9c --- /dev/null +++ b/examples/declarative/focus/Core/qmldir @@ -0,0 +1,4 @@ +ContextMenu ContextMenu.qml +GridMenu GridMenu.qml +ListViews Listviews.qml +ListViewDelegate ListViewDelegate.qml diff --git a/examples/declarative/focus/focus.qml b/examples/declarative/focus/focus.qml new file mode 100644 index 0000000..a8dc3c8 --- /dev/null +++ b/examples/declarative/focus/focus.qml @@ -0,0 +1,50 @@ +import Qt 4.6 +import "Core" 1.0 + +Rectangle { + id: window; width: 800; height: 480; color: "#3E606F" + + FocusScope { + id: mainView; focus: true; width: parent.width; height: parent.height + + GridMenu { + id: gridMenu; focus: true + width: parent.width; height: 320; interactive: parent.wantsFocus + } + + ListViews { id: listViews; y: 320; width: parent.width; height: 320 } + + Rectangle { id: shade; color: "black"; opacity: 0; anchors.fill: parent } + + states: State { + name: "showListViews" + PropertyChanges { target: gridMenu; y: -160 } + PropertyChanges { target: listViews; y: 160 } + } + + transitions: Transition { + NumberAnimation { properties: "y"; duration: 600; easing.type: "OutQuint" } + } + } + + Image { + source: "Core/images/arrow.png"; rotation: 90; anchors.verticalCenter: parent.verticalCenter + MouseArea { + anchors { fill: parent; leftMargin: -10; topMargin: -10; rightMargin: -10; bottomMargin: -10 } + onClicked: window.state = "contextMenuOpen" + } + } + + ContextMenu { id: contextMenu; x: -265; width: 260; height: parent.height } + + states: State { + name: "contextMenuOpen"; when: !mainView.wantsFocus + PropertyChanges { target: contextMenu; x: 0; open: true } + PropertyChanges { target: mainView; x: 130 } + PropertyChanges { target: shade; opacity: 0.25 } + } + + transitions: Transition { + NumberAnimation { properties: "x,opacity"; duration: 600; easing.type: "OutQuint" } + } +} diff --git a/examples/declarative/imageprovider/imageprovider-example.qml b/examples/declarative/imageprovider/imageprovider-example.qml index a1f2794..a895821 100644 --- a/examples/declarative/imageprovider/imageprovider-example.qml +++ b/examples/declarative/imageprovider/imageprovider-example.qml @@ -1,5 +1,5 @@ import Qt 4.6 -import ImageProviderCore 1.0 +import "ImageProviderCore" //![0] ListView { width: 100 @@ -16,6 +16,7 @@ ListView { } Image { source: modelData + sourceSize: "50x25" } } } diff --git a/examples/declarative/imageprovider/imageprovider.cpp b/examples/declarative/imageprovider/imageprovider.cpp index 011a63b..4c4aa94 100644 --- a/examples/declarative/imageprovider/imageprovider.cpp +++ b/examples/declarative/imageprovider/imageprovider.cpp @@ -61,11 +61,21 @@ class ColorImageProvider : public QDeclarativeImageProvider { public: // This is run in a low priority thread. - QImage request(const QString &id) { - QImage image(100, 50, QImage::Format_RGB32); + QImage request(const QString &id, QSize *size, const QSize &req_size) + { + if (size) *size = QSize(100,50); + QImage image( + req_size.width() > 0 ? req_size.width() : 100, + req_size.height() > 0 ? req_size.height() : 50, + QImage::Format_RGB32); image.fill(QColor(id).rgba()); QPainter p(&image); + QFont f = p.font(); + f.setPixelSize(30); + p.setFont(f); p.setPen(Qt::black); + if (req_size.isValid()) + p.scale(req_size.width()/100.0, req_size.height()/50.0); p.drawText(QRectF(0,0,100,50),Qt::AlignCenter,id); return image; } diff --git a/examples/declarative/widgets/MyWidgets/qmldir b/examples/declarative/widgets/MyWidgets/qmldir new file mode 100644 index 0000000..dc1d10e --- /dev/null +++ b/examples/declarative/widgets/MyWidgets/qmldir @@ -0,0 +1 @@ +plugin mywidgetsplugin diff --git a/examples/declarative/widgets/README b/examples/declarative/widgets/README new file mode 100644 index 0000000..f85a1e8 --- /dev/null +++ b/examples/declarative/widgets/README @@ -0,0 +1,4 @@ +To run: + + make install + qml mywidgets.qml diff --git a/examples/declarative/widgets/mywidgets.cpp b/examples/declarative/widgets/mywidgets.cpp new file mode 100644 index 0000000..e17240d --- /dev/null +++ b/examples/declarative/widgets/mywidgets.cpp @@ -0,0 +1,99 @@ +/**************************************************************************** +** +** 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 examples 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 <QtDeclarative/QDeclarativeExtensionPlugin> +#include <QtDeclarative/qdeclarative.h> +#include <QtGui/QGraphicsProxyWidget> +#include <QtGui/QPushButton> +#include <QDebug> + +class MyPushButton : public QGraphicsProxyWidget +{ + Q_OBJECT + Q_PROPERTY(QString text READ text WRITE setText NOTIFY textChanged) + +public: + MyPushButton(QGraphicsItem* parent = 0) + : QGraphicsProxyWidget(parent) + { + widget = new QPushButton("MyPushButton"); + widget->setAttribute(Qt::WA_NoSystemBackground); + setWidget(widget); + + QObject::connect(widget, SIGNAL(clicked(bool)), this, SIGNAL(clicked(bool))); + } + + QString text() const + { + return widget->text(); + } + + void setText(const QString& text) + { + if (text != widget->text()) { + widget->setText(text); + emit textChanged(); + } + } + +Q_SIGNALS: + void clicked(bool); + void textChanged(); + +private: + QPushButton *widget; +}; + +class MyWidgetsPlugin : public QDeclarativeExtensionPlugin +{ + Q_OBJECT +public: + void registerTypes(const char *uri) + { + qmlRegisterType<MyPushButton>(uri, 1, 0, "MyPushButton"); + } +}; + +#include "mywidgets.moc" + +QML_DECLARE_TYPE(MyPushButton) + +Q_EXPORT_PLUGIN2(mywidgetsplugin, MyWidgetsPlugin); diff --git a/examples/declarative/widgets/mywidgets.pro b/examples/declarative/widgets/mywidgets.pro new file mode 100644 index 0000000..258edb1 --- /dev/null +++ b/examples/declarative/widgets/mywidgets.pro @@ -0,0 +1,19 @@ +TEMPLATE = lib +DESTDIR = MyWidgets +TARGET = mywidgetsplugin +CONFIG += qt plugin +QT += declarative +VERSION = 1.0.0 + +SOURCES += mywidgets.cpp + +sources.files += mywidgets.pro mywidgets.cpp mywidgets.qml + +sources.path += $$[QT_INSTALL_EXAMPLES]/declarative/plugins + +target.path += $$[QT_INSTALL_EXAMPLES]/declarative/plugins + +INSTALLS += sources target + +symbian: include($$QT_SOURCE_TREE/examples/symbianpkgrules.pri) + diff --git a/examples/declarative/widgets/mywidgets.qml b/examples/declarative/widgets/mywidgets.qml new file mode 100644 index 0000000..b1efed4 --- /dev/null +++ b/examples/declarative/widgets/mywidgets.qml @@ -0,0 +1,53 @@ +import Qt 4.6 +import "MyWidgets" 1.0 + +Rectangle { + id: window + width: 640; height: 480; color: palette.window + + property int margin: 30 + + SystemPalette { id: palette } + + MyPushButton { + id: button1; x: margin; y: margin; text: "Right"; onClicked: window.state = "right" + transformOriginPoint: Qt.point(width / 2, height / 2) + } + + MyPushButton { + id: button2; x: margin; y: margin + 30; text: "Bottom"; onClicked: window.state = "bottom" + transformOriginPoint: Qt.point(width / 2, height / 2) + } + + MyPushButton { + id: button3; x: margin; y: margin + 60; text: "Quit"; onClicked: Qt.quit() + transformOriginPoint: Qt.point(width / 2, height / 2) + } + + states: [ + State { + name: "right" + PropertyChanges { target: button1; x: window.width - width - margin; text: "Left"; onClicked: window.state = "" } + PropertyChanges { target: button2; x: window.width - width - margin } + PropertyChanges { target: button3; x: window.width - width - margin } + PropertyChanges { target: window; color: Qt.darker(palette.window) } + }, + State { + name: "bottom" + PropertyChanges { target: button1; y: window.height - height - margin; rotation: 180 } + PropertyChanges { + target: button2; x: button1.x + button1.width + 10; y: window.height - height - margin; rotation: 180 + text: "Top"; onClicked: window.state = "" + } + PropertyChanges { target: button3; x: button2.x + button2.width + 10; y: window.height - height - margin; rotation: 180 } + PropertyChanges { target: window; color: Qt.lighter(palette.window) } + } + ] + + transitions: Transition { + ParallelAnimation { + NumberAnimation { properties: "x,y,rotation"; duration: 600; easing.type: "OutQuad" } + ColorAnimation { target: window; duration: 600 } + } + } +} diff --git a/src/declarative/qml/qdeclarativecompiler.cpp b/src/declarative/qml/qdeclarativecompiler.cpp index a9d90f3..f1a673f 100644 --- a/src/declarative/qml/qdeclarativecompiler.cpp +++ b/src/declarative/qml/qdeclarativecompiler.cpp @@ -2428,10 +2428,18 @@ bool QDeclarativeCompiler::buildDynamicMeta(QDeclarativeParser::Object *obj, Dyn propertyType = QVariant::Color; type = "QColor"; break; + case Object::DynamicProperty::Time: + propertyType = QVariant::Time; + type = "QTime"; + break; case Object::DynamicProperty::Date: propertyType = QVariant::Date; type = "QDate"; break; + case Object::DynamicProperty::DateTime: + propertyType = QVariant::DateTime; + type = "QDateTime"; + break; } ((QDeclarativeVMEMetaData *)dynamicData.data())->propertyCount++; diff --git a/src/declarative/qml/qdeclarativeengine.cpp b/src/declarative/qml/qdeclarativeengine.cpp index dea5a40..5335b8c 100644 --- a/src/declarative/qml/qdeclarativeengine.cpp +++ b/src/declarative/qml/qdeclarativeengine.cpp @@ -1306,13 +1306,14 @@ QScriptValue QDeclarativeEnginePrivate::tint(QScriptContext *ctxt, QScriptEngine QScriptValue QDeclarativeEnginePrivate::scriptValueFromVariant(const QVariant &val) { if (val.userType() == qMetaTypeId<QDeclarativeListReference>()) { - QDeclarativeListReferencePrivate *p = QDeclarativeListReferencePrivate::get((QDeclarativeListReference*)val.constData()); + QDeclarativeListReferencePrivate *p = + QDeclarativeListReferencePrivate::get((QDeclarativeListReference*)val.constData()); if (p->object) { return listClass->newList(p->property, p->propertyType); } else { return scriptEngine.nullValue(); } - } + } bool objOk; QObject *obj = QDeclarativeMetaType::toQObject(val, &objOk); @@ -1809,25 +1810,39 @@ QUrl QDeclarativeEnginePrivate::Imports::baseUrl() const Adds \a path as a directory where installed QML components are defined in a URL-based directory structure. - For example, if you add \c /opt/MyApp/lib/imports and then load QML - that imports \c com.mycompany.Feature, then QDeclarativeEngine will look + \sa importPathList() +*/ +void QDeclarativeEngine::addImportPath(const QString& path) +{ + if (qmlImportTrace()) + qDebug() << "QDeclarativeEngine::addImportPath" << path; + Q_D(QDeclarativeEngine); + d->fileImportPath.prepend(path); +} + + +/*! + Returns the list of directories with the engine searches for + installed modules. + + For example, if \c /opt/MyApp/lib/imports is in the path, then QML that + imports \c com.mycompany.Feature will cause the QDeclarativeEngine to look in \c /opt/MyApp/lib/imports/com/mycompany/Feature/ for the components - provided by that module. A \c qmldir file is required for definiting the + provided by that module. A \c qmldir file is required for defining the type version mapping and possibly declarative extensions plugins. - The engine searches in the base directory of the qml file, then - the paths added via addImportPath(), then in the directory containing the + In addition to this list, + the engine searches in the directory containing the application executable (QCoreApplication::applicationDirPath()), then the paths specified in the \c QML_IMPORT_PATH environment variable, then the builtin \c ImportsPath from QLibraryInfo. + \sa addImportPath() */ -void QDeclarativeEngine::addImportPath(const QString& path) +QStringList QDeclarativeEngine::importPathList() const { - if (qmlImportTrace()) - qDebug() << "QDeclarativeEngine::addImportPath" << path; - Q_D(QDeclarativeEngine); - d->fileImportPath.prepend(path); + Q_D(const QDeclarativeEngine); + return d->fileImportPath; } /*! diff --git a/src/declarative/qml/qdeclarativeengine.h b/src/declarative/qml/qdeclarativeengine.h index 19e81b6..a24962e 100644 --- a/src/declarative/qml/qdeclarativeengine.h +++ b/src/declarative/qml/qdeclarativeengine.h @@ -78,6 +78,7 @@ public: void clearComponentCache(); void addImportPath(const QString& dir); + QStringList importPathList() const; bool importExtension(const QString &fileName, const QString &uri); void setNetworkAccessManagerFactory(QDeclarativeNetworkAccessManagerFactory *); diff --git a/src/declarative/qml/qdeclarativeparser_p.h b/src/declarative/qml/qdeclarativeparser_p.h index 476b027..f432024 100644 --- a/src/declarative/qml/qdeclarativeparser_p.h +++ b/src/declarative/qml/qdeclarativeparser_p.h @@ -203,7 +203,7 @@ namespace QDeclarativeParser DynamicProperty(); DynamicProperty(const DynamicProperty &); - enum Type { Variant, Int, Bool, Real, String, Url, Color, Date, Alias, Custom, CustomList }; + enum Type { Variant, Int, Bool, Real, String, Url, Color, Time, Date, DateTime, Alias, Custom, CustomList }; bool isDefaultProperty; Type type; diff --git a/src/declarative/qml/qdeclarativescriptparser.cpp b/src/declarative/qml/qdeclarativescriptparser.cpp index 49bd3b7..9fff294 100644 --- a/src/declarative/qml/qdeclarativescriptparser.cpp +++ b/src/declarative/qml/qdeclarativescriptparser.cpp @@ -528,9 +528,14 @@ bool ProcessAST::visit(AST::UiPublicMember *node) { "string", Object::DynamicProperty::String, "QString" }, { "url", Object::DynamicProperty::Url, "QUrl" }, { "color", Object::DynamicProperty::Color, "QColor" }, - { "date", Object::DynamicProperty::Date, "QDate" }, - { "var", Object::DynamicProperty::Variant, "QVariant" }, - { "variant", Object::DynamicProperty::Variant, "QVariant" } + // Internally QTime, QDate and QDateTime are all supported. + // To be more consistent with JavaScript we expose only + // QDateTime as it matches closely with the Date JS type. + // We also call it "date" to match. + // { "time", Object::DynamicProperty::Time, "QTime" }, + // { "date", Object::DynamicProperty::Date, "QDate" }, + { "date", Object::DynamicProperty::DateTime, "QDateTime" }, + { "var", Object::DynamicProperty::Variant, "QVariant" } }; const int propTypeNameToTypesCount = sizeof(propTypeNameToTypes) / sizeof(propTypeNameToTypes[0]); diff --git a/src/declarative/qml/qdeclarativevmemetaobject.cpp b/src/declarative/qml/qdeclarativevmemetaobject.cpp index f9c99ee..9a7bdd6 100644 --- a/src/declarative/qml/qdeclarativevmemetaobject.cpp +++ b/src/declarative/qml/qdeclarativevmemetaobject.cpp @@ -47,19 +47,340 @@ #include "qdeclarativeexpression_p.h" #include "qdeclarativecontext_p.h" -#include <QColor> -#include <QDate> -#include <QtCore/qlist.h> -#include <QtCore/qdebug.h> +Q_DECLARE_METATYPE(QScriptValue); QT_BEGIN_NAMESPACE +class QDeclarativeVMEVariant +{ +public: + inline QDeclarativeVMEVariant(); + inline ~QDeclarativeVMEVariant(); + + inline const void *dataPtr() const; + inline void *dataPtr(); + inline int dataType() const; + + inline QObject *asQObject(); + inline const QVariant &asQVariant(); + inline int asInt(); + inline bool asBool(); + inline double asDouble(); + inline const QString &asQString(); + inline const QUrl &asQUrl(); + inline const QColor &asQColor(); + inline const QTime &asQTime(); + inline const QDate &asQDate(); + inline const QDateTime &asQDateTime(); + inline const QScriptValue &asQScriptValue(); + + inline void setValue(QObject *); + inline void setValue(const QVariant &); + inline void setValue(int); + inline void setValue(bool); + inline void setValue(double); + inline void setValue(const QString &); + inline void setValue(const QUrl &); + inline void setValue(const QColor &); + inline void setValue(const QTime &); + inline void setValue(const QDate &); + inline void setValue(const QDateTime &); + inline void setValue(const QScriptValue &); + +private: + int type; + void *data[4]; // Large enough to hold all types + + inline void cleanup(); +}; + +QDeclarativeVMEVariant::QDeclarativeVMEVariant() +: type(QVariant::Invalid) +{ +} + +QDeclarativeVMEVariant::~QDeclarativeVMEVariant() +{ + cleanup(); +} + +void QDeclarativeVMEVariant::cleanup() +{ + if (type == QVariant::Invalid) { + } else if (type == QMetaType::QObjectStar || + type == QMetaType::Int || + type == QMetaType::Bool || + type == QMetaType::Double) { + type = QVariant::Invalid; + } else if (type == QMetaType::QString) { + ((QString *)dataPtr())->~QString(); + type = QVariant::Invalid; + } else if (type == QMetaType::QUrl) { + ((QUrl *)dataPtr())->~QUrl(); + type = QVariant::Invalid; + } else if (type == QMetaType::QColor) { + ((QColor *)dataPtr())->~QColor(); + type = QVariant::Invalid; + } else if (type == QMetaType::QTime) { + ((QTime *)dataPtr())->~QTime(); + type = QVariant::Invalid; + } else if (type == QMetaType::QDate) { + ((QDate *)dataPtr())->~QDate(); + type = QVariant::Invalid; + } else if (type == QMetaType::QDateTime) { + ((QDateTime *)dataPtr())->~QDateTime(); + type = QVariant::Invalid; + } else if (type == qMetaTypeId<QVariant>()) { + ((QVariant *)dataPtr())->~QVariant(); + type = QVariant::Invalid; + } else if (type == qMetaTypeId<QScriptValue>()) { + ((QScriptValue *)dataPtr())->~QScriptValue(); + type = QVariant::Invalid; + } + +} + +int QDeclarativeVMEVariant::dataType() const +{ + return type; +} + +const void *QDeclarativeVMEVariant::dataPtr() const +{ + return &data; +} + +void *QDeclarativeVMEVariant::dataPtr() +{ + return &data; +} + +QObject *QDeclarativeVMEVariant::asQObject() +{ + if (type != QMetaType::QObjectStar) + setValue((QObject *)0); + + return *(QObject **)(dataPtr()); +} + +const QVariant &QDeclarativeVMEVariant::asQVariant() +{ + if (type != QMetaType::QVariant) + setValue(QVariant()); + + return *(QVariant *)(dataPtr()); +} + +int QDeclarativeVMEVariant::asInt() +{ + if (type != QMetaType::Int) + setValue(int(0)); + + return *(int *)(dataPtr()); +} + +bool QDeclarativeVMEVariant::asBool() +{ + if (type != QMetaType::Bool) + setValue(bool(false)); + + return *(bool *)(dataPtr()); +} + +double QDeclarativeVMEVariant::asDouble() +{ + if (type != QMetaType::Double) + setValue(double(0)); + + return *(double *)(dataPtr()); +} + +const QString &QDeclarativeVMEVariant::asQString() +{ + if (type != QMetaType::QString) + setValue(QString()); + + return *(QString *)(dataPtr()); +} + +const QUrl &QDeclarativeVMEVariant::asQUrl() +{ + if (type != QMetaType::QUrl) + setValue(QUrl()); + + return *(QUrl *)(dataPtr()); +} + +const QColor &QDeclarativeVMEVariant::asQColor() +{ + if (type != QMetaType::QColor) + setValue(QColor()); + + return *(QColor *)(dataPtr()); +} + +const QTime &QDeclarativeVMEVariant::asQTime() +{ + if (type != QMetaType::QTime) + setValue(QTime()); + + return *(QTime *)(dataPtr()); +} + +const QDate &QDeclarativeVMEVariant::asQDate() +{ + if (type != QMetaType::QDate) + setValue(QDate()); + + return *(QDate *)(dataPtr()); +} + +const QDateTime &QDeclarativeVMEVariant::asQDateTime() +{ + if (type != QMetaType::QDateTime) + setValue(QDateTime()); + + return *(QDateTime *)(dataPtr()); +} + +const QScriptValue &QDeclarativeVMEVariant::asQScriptValue() +{ + if (type != qMetaTypeId<QScriptValue>()) + setValue(QScriptValue()); + + return *(QScriptValue *)(dataPtr()); +} + +void QDeclarativeVMEVariant::setValue(QObject *v) +{ + if (type != QMetaType::QObjectStar) { + cleanup(); + type = QMetaType::QObjectStar; + } + *(QObject **)(dataPtr()) = v; +} + +void QDeclarativeVMEVariant::setValue(const QVariant &v) +{ + if (type != qMetaTypeId<QVariant>()) { + cleanup(); + type = qMetaTypeId<QVariant>(); + new (dataPtr()) QVariant(v); + } else { + *(QVariant *)(dataPtr()) = v; + } +} + +void QDeclarativeVMEVariant::setValue(int v) +{ + if (type != QMetaType::Int) { + cleanup(); + type = QMetaType::Int; + } + *(int *)(dataPtr()) = v; +} + +void QDeclarativeVMEVariant::setValue(bool v) +{ + if (type != QMetaType::Bool) { + cleanup(); + type = QMetaType::Bool; + } + *(bool *)(dataPtr()) = v; +} + +void QDeclarativeVMEVariant::setValue(double v) +{ + if (type != QMetaType::Double) { + cleanup(); + type = QMetaType::Double; + } + *(double *)(dataPtr()) = v; +} + +void QDeclarativeVMEVariant::setValue(const QString &v) +{ + if (type != QMetaType::QString) { + cleanup(); + type = QMetaType::QString; + new (dataPtr()) QString(v); + } else { + *(QString *)(dataPtr()) = v; + } +} + +void QDeclarativeVMEVariant::setValue(const QUrl &v) +{ + if (type != QMetaType::QUrl) { + cleanup(); + type = QMetaType::QUrl; + new (dataPtr()) QUrl(v); + } else { + *(QUrl *)(dataPtr()) = v; + } +} + +void QDeclarativeVMEVariant::setValue(const QColor &v) +{ + if (type != QMetaType::QColor) { + cleanup(); + type = QMetaType::QColor; + new (dataPtr()) QColor(v); + } else { + *(QColor *)(dataPtr()) = v; + } +} + +void QDeclarativeVMEVariant::setValue(const QTime &v) +{ + if (type != QMetaType::QTime) { + cleanup(); + type = QMetaType::QTime; + new (dataPtr()) QTime(v); + } else { + *(QTime *)(dataPtr()) = v; + } +} + +void QDeclarativeVMEVariant::setValue(const QDate &v) +{ + if (type != QMetaType::QDate) { + cleanup(); + type = QMetaType::QDate; + new (dataPtr()) QDate(v); + } else { + *(QDate *)(dataPtr()) = v; + } +} + +void QDeclarativeVMEVariant::setValue(const QDateTime &v) +{ + if (type != QMetaType::QDateTime) { + cleanup(); + type = QMetaType::QDateTime; + new (dataPtr()) QDateTime(v); + } else { + *(QDateTime *)(dataPtr()) = v; + } +} + +void QDeclarativeVMEVariant::setValue(const QScriptValue &v) +{ + if (type != qMetaTypeId<QScriptValue>()) { + cleanup(); + type = qMetaTypeId<QScriptValue>(); + new (dataPtr()) QScriptValue(v); + } else { + *(QScriptValue *)(dataPtr()) = v; + } +} + QDeclarativeVMEMetaObject::QDeclarativeVMEMetaObject(QObject *obj, const QMetaObject *other, const QDeclarativeVMEMetaData *meta, QDeclarativeCompiledData *cdata) : object(obj), compiledData(cdata), ctxt(QDeclarativeDeclarativeData::get(obj)->outerContext), - metaData(meta), methods(0), parent(0) + metaData(meta), data(0), methods(0), parent(0) { compiledData->addref(); @@ -74,20 +395,18 @@ QDeclarativeVMEMetaObject::QDeclarativeVMEMetaObject(QObject *obj, propOffset = QAbstractDynamicMetaObject::propertyOffset(); methodOffset = QAbstractDynamicMetaObject::methodOffset(); - data = new QVariant[metaData->propertyCount]; - aConnected.resize(metaData->aliasCount); + data = new QDeclarativeVMEVariant[metaData->propertyCount]; + aConnected.resize(metaData->aliasCount); int list_type = qMetaTypeId<QDeclarativeListProperty<QObject> >(); + // ### Optimize for (int ii = 0; ii < metaData->propertyCount; ++ii) { int t = (metaData->propertyData() + ii)->propertyType; if (t == list_type) { - listProperties.append(new List(methodOffset + ii)); - data[ii] = QVariant::fromValue(QDeclarativeListProperty<QObject>(obj, listProperties.last(), list_append, - list_count, list_at, list_clear)); - } else if (t != -1) { - data[ii] = QVariant((QVariant::Type)t); - } + listProperties.append(List(methodOffset + ii)); + data[ii].setValue(listProperties.count() - 1); + } } } @@ -95,7 +414,6 @@ QDeclarativeVMEMetaObject::~QDeclarativeVMEMetaObject() { compiledData->release(); delete parent; - qDeleteAll(listProperties); delete [] data; delete [] methods; } @@ -145,11 +463,10 @@ int QDeclarativeVMEMetaObject::metaCall(QMetaObject::Call c, int _id, void **a) if (t == -1) { if (c == QMetaObject::ReadProperty) { - *reinterpret_cast<QVariant *>(a[0]) = data[id]; + *reinterpret_cast<QVariant *>(a[0]) = readVarPropertyAsVariant(id); } else if (c == QMetaObject::WriteProperty) { - needActivate = - (data[id] != *reinterpret_cast<QVariant *>(a[0])); - data[id] = *reinterpret_cast<QVariant *>(a[0]); + needActivate = (data[id].asQVariant() != *reinterpret_cast<QVariant *>(a[0])); + data[id].setValue(*reinterpret_cast<QVariant *>(a[0])); } } else { @@ -157,42 +474,86 @@ int QDeclarativeVMEMetaObject::metaCall(QMetaObject::Call c, int _id, void **a) if (c == QMetaObject::ReadProperty) { switch(t) { case QVariant::Int: - *reinterpret_cast<int *>(a[0]) = data[id].toInt(); + *reinterpret_cast<int *>(a[0]) = data[id].asInt(); break; case QVariant::Bool: - *reinterpret_cast<bool *>(a[0]) = data[id].toBool(); + *reinterpret_cast<bool *>(a[0]) = data[id].asBool(); break; case QVariant::Double: - *reinterpret_cast<double *>(a[0]) = data[id].toDouble(); + *reinterpret_cast<double *>(a[0]) = data[id].asDouble(); break; case QVariant::String: - *reinterpret_cast<QString *>(a[0]) = data[id].toString(); + *reinterpret_cast<QString *>(a[0]) = data[id].asQString(); break; case QVariant::Url: - *reinterpret_cast<QUrl *>(a[0]) = data[id].toUrl(); + *reinterpret_cast<QUrl *>(a[0]) = data[id].asQUrl(); break; case QVariant::Color: - *reinterpret_cast<QColor *>(a[0]) = data[id].value<QColor>(); + *reinterpret_cast<QColor *>(a[0]) = data[id].asQColor(); break; case QVariant::Date: - *reinterpret_cast<QDate *>(a[0]) = data[id].toDate(); + *reinterpret_cast<QDate *>(a[0]) = data[id].asQDate(); + break; + case QVariant::DateTime: + *reinterpret_cast<QDateTime *>(a[0]) = data[id].asQDateTime(); break; case QMetaType::QObjectStar: - *reinterpret_cast<QObject **>(a[0]) = data[id].value<QObject*>(); + *reinterpret_cast<QObject **>(a[0]) = data[id].asQObject(); break; default: break; } if (t == qMetaTypeId<QDeclarativeListProperty<QObject> >()) { + int listIndex = data[id].asInt(); + const List *list = &listProperties.at(listIndex); *reinterpret_cast<QDeclarativeListProperty<QObject> *>(a[0]) = - data[id].value<QDeclarativeListProperty<QObject> >(); + QDeclarativeListProperty<QObject>(object, (void *)list, + list_append, list_count, list_at, + list_clear); } } else if (c == QMetaObject::WriteProperty) { - QVariant value = QVariant((QVariant::Type)data[id].type(), a[0]); - needActivate = (data[id] != value); - data[id] = value; + switch(t) { + case QVariant::Int: + needActivate = *reinterpret_cast<int *>(a[0]) != data[id].asInt(); + data[id].setValue(*reinterpret_cast<int *>(a[0])); + break; + case QVariant::Bool: + needActivate = *reinterpret_cast<bool *>(a[0]) != data[id].asBool(); + data[id].setValue(*reinterpret_cast<bool *>(a[0])); + break; + case QVariant::Double: + needActivate = *reinterpret_cast<double *>(a[0]) != data[id].asDouble(); + data[id].setValue(*reinterpret_cast<double *>(a[0])); + break; + case QVariant::String: + needActivate = *reinterpret_cast<QString *>(a[0]) != data[id].asQString(); + data[id].setValue(*reinterpret_cast<QString *>(a[0])); + break; + case QVariant::Url: + needActivate = *reinterpret_cast<QUrl *>(a[0]) != data[id].asQUrl(); + data[id].setValue(*reinterpret_cast<QUrl *>(a[0])); + break; + case QVariant::Color: + needActivate = *reinterpret_cast<QColor *>(a[0]) != data[id].asQColor(); + data[id].setValue(*reinterpret_cast<QColor *>(a[0])); + break; + case QVariant::Date: + needActivate = *reinterpret_cast<QDate *>(a[0]) != data[id].asQDate(); + data[id].setValue(*reinterpret_cast<QDate *>(a[0])); + break; + case QVariant::DateTime: + needActivate = *reinterpret_cast<QDateTime *>(a[0]) != data[id].asQDateTime(); + data[id].setValue(*reinterpret_cast<QDateTime *>(a[0])); + break; + case QMetaType::QObjectStar: + needActivate = *reinterpret_cast<QObject **>(a[0]) != data[id].asQObject(); + data[id].setValue(*reinterpret_cast<QObject **>(a[0])); + break; + default: + break; + } } } @@ -316,6 +677,28 @@ QScriptValue QDeclarativeVMEMetaObject::method(int index) return methods[index]; } +QScriptValue QDeclarativeVMEMetaObject::readVarProperty(int id) +{ + if (data[id].dataType() == qMetaTypeId<QScriptValue>()) + return data[id].asQScriptValue(); + else + return QDeclarativeEnginePrivate::get(ctxt->engine)->scriptValueFromVariant(data[id].asQVariant()); +} + +QVariant QDeclarativeVMEMetaObject::readVarPropertyAsVariant(int id) +{ + if (data[id].dataType() == qMetaTypeId<QScriptValue>()) + return QDeclarativeEnginePrivate::get(ctxt->engine)->scriptValueToVariant(data[id].asQScriptValue()); + else + return data[id].asQVariant(); +} + +void QDeclarativeVMEMetaObject::writeVarProperty(int id, const QScriptValue &value) +{ + data[id].setValue(value); + activate(object, methodOffset + id, 0); +} + void QDeclarativeVMEMetaObject::listChanged(int id) { activate(object, methodOffset + id, 0); @@ -364,4 +747,22 @@ QScriptValue QDeclarativeVMEMetaObject::vmeMethod(int index) return method(index - methodOffset - plainSignals); } +QScriptValue QDeclarativeVMEMetaObject::vmeProperty(int index) +{ + if (index < propOffset) { + Q_ASSERT(parent); + return static_cast<QDeclarativeVMEMetaObject *>(parent)->vmeProperty(index); + } + return readVarProperty(index - propOffset); +} + +void QDeclarativeVMEMetaObject::setVMEProperty(int index, const QScriptValue &v) +{ + if (index < propOffset) { + Q_ASSERT(parent); + static_cast<QDeclarativeVMEMetaObject *>(parent)->setVMEProperty(index, v); + } + return writeVarProperty(index - propOffset, v); +} + QT_END_NAMESPACE diff --git a/src/declarative/qml/qdeclarativevmemetaobject_p.h b/src/declarative/qml/qdeclarativevmemetaobject_p.h index e11f6fa..839f0cd 100644 --- a/src/declarative/qml/qdeclarativevmemetaobject_p.h +++ b/src/declarative/qml/qdeclarativevmemetaobject_p.h @@ -58,6 +58,10 @@ #include <QtCore/QMetaObject> #include <QtCore/QBitArray> #include <QtCore/QPair> +#include <QtGui/QColor> +#include <QtCore/QDate> +#include <QtCore/qlist.h> +#include <QtCore/qdebug.h> #include <private/qobject_p.h> @@ -106,6 +110,7 @@ struct QDeclarativeVMEMetaData } }; +class QDeclarativeVMEVariant; class QDeclarativeRefCount; class QDeclarativeVMEMetaObject : public QAbstractDynamicMetaObject { @@ -116,6 +121,9 @@ public: void registerInterceptor(int index, int valueIndex, QDeclarativePropertyValueInterceptor *interceptor); QScriptValue vmeMethod(int index); + QScriptValue vmeProperty(int index); + void setVMEProperty(int index, const QScriptValue &); + protected: virtual int metaCall(QMetaObject::Call _c, int _id, void **_a); @@ -128,7 +136,8 @@ private: int propOffset; int methodOffset; - QVariant *data; + QDeclarativeVMEVariant *data; + QBitArray aConnected; QBitArray aInterceptors; QHash<int, QPair<int, QDeclarativePropertyValueInterceptor*> > interceptors; @@ -136,6 +145,10 @@ private: QScriptValue *methods; QScriptValue method(int); + QScriptValue readVarProperty(int); + QVariant readVarPropertyAsVariant(int); + void writeVarProperty(int, const QScriptValue &); + QAbstractDynamicMetaObject *parent; void listChanged(int); @@ -145,7 +158,7 @@ private: List(int lpi) : notifyIndex(lpi) {} int notifyIndex; }; - QList<List *> listProperties; + QList<List> listProperties; static void list_append(QDeclarativeListProperty<QObject> *, QObject *); static int list_count(QDeclarativeListProperty<QObject> *); diff --git a/src/declarative/util/qdeclarativelistmodel.cpp b/src/declarative/util/qdeclarativelistmodel.cpp index 3904458..1a28176 100644 --- a/src/declarative/util/qdeclarativelistmodel.cpp +++ b/src/declarative/util/qdeclarativelistmodel.cpp @@ -1250,14 +1250,9 @@ ModelNode::ModelNode() ModelNode::~ModelNode() { - ModelNode *node; - - QList<ModelNode *> nodeValues = properties.values(); - for (int ii = 0; ii < nodeValues.count(); ++ii) { - node = nodeValues[ii]; - if (node) { delete node; node = 0; } - } + qDeleteAll(properties.values()); + ModelNode *node; for (int ii = 0; ii < values.count(); ++ii) { node = qvariant_cast<ModelNode *>(values.at(ii)); if (node) { delete node; node = 0; } @@ -1279,7 +1274,9 @@ void ModelNode::setObjectValue(const QScriptValue& valuemap) { } else { value->values << v.toVariant(); } - properties.insert(it.name(),value); + if (properties.contains(it.name())) + delete properties[it.name()]; + properties.insert(it.name(), value); } } diff --git a/src/declarative/util/qdeclarativeopenmetaobject.cpp b/src/declarative/util/qdeclarativeopenmetaobject.cpp index 8c23354..6611885 100644 --- a/src/declarative/util/qdeclarativeopenmetaobject.cpp +++ b/src/declarative/util/qdeclarativeopenmetaobject.cpp @@ -222,9 +222,10 @@ int QDeclarativeOpenMetaObject::metaCall(QMetaObject::Call c, int id, void **a) propertyRead(propId); *reinterpret_cast<QVariant *>(a[0]) = d->getData(propId); } else if (c == QMetaObject::WriteProperty) { - if (d->data[propId].first != *reinterpret_cast<QVariant *>(a[0])) { + if (propId <= d->data.count() || d->data[propId].first != *reinterpret_cast<QVariant *>(a[0])) { propertyWrite(propId); d->writeData(propId, *reinterpret_cast<QVariant *>(a[0])); + propertyWritten(propId); activate(d->object, d->type->d->signalOffset + propId, 0); } } @@ -270,6 +271,11 @@ QVariant &QDeclarativeOpenMetaObject::operator[](const QByteArray &name) return d->getData(*iter); } +QVariant &QDeclarativeOpenMetaObject::operator[](int id) +{ + return d->getData(id); +} + void QDeclarativeOpenMetaObject::setValue(const QByteArray &name, const QVariant &val) { QHash<QByteArray, int>::ConstIterator iter = d->type->d->names.find(name); @@ -326,6 +332,10 @@ void QDeclarativeOpenMetaObject::propertyWrite(int) { } +void QDeclarativeOpenMetaObject::propertyWritten(int) +{ +} + void QDeclarativeOpenMetaObject::propertyCreated(int, QMetaPropertyBuilder &) { } diff --git a/src/declarative/util/qdeclarativeopenmetaobject_p.h b/src/declarative/util/qdeclarativeopenmetaobject_p.h index ec5ac17..9bb4c34 100644 --- a/src/declarative/util/qdeclarativeopenmetaobject_p.h +++ b/src/declarative/util/qdeclarativeopenmetaobject_p.h @@ -90,6 +90,7 @@ public: QVariant value(int) const; void setValue(int, const QVariant &); QVariant &operator[](const QByteArray &); + QVariant &operator[](int); int count() const; QByteArray name(int) const; @@ -109,6 +110,7 @@ protected: virtual void propertyRead(int); virtual void propertyWrite(int); + virtual void propertyWritten(int); virtual void propertyCreated(int, QMetaPropertyBuilder &); QAbstractDynamicMetaObject *parent() const; diff --git a/src/declarative/util/qdeclarativepropertymap.cpp b/src/declarative/util/qdeclarativepropertymap.cpp index fcea515..0bdd91b 100644 --- a/src/declarative/util/qdeclarativepropertymap.cpp +++ b/src/declarative/util/qdeclarativepropertymap.cpp @@ -41,6 +41,7 @@ #include "qdeclarativepropertymap.h" +#include <private/qmetaobjectbuilder_p.h> #include "qdeclarativeopenmetaobject_p.h" #include <QDebug> @@ -55,7 +56,8 @@ public: QDeclarativePropertyMapMetaObject(QDeclarativePropertyMap *obj, QDeclarativePropertyMapPrivate *objPriv); protected: - virtual void propertyWrite(int index); + virtual void propertyWritten(int index); + virtual void propertyCreated(int, QMetaPropertyBuilder &); private: QDeclarativePropertyMap *map; @@ -68,13 +70,13 @@ class QDeclarativePropertyMapPrivate : public QObjectPrivate public: QDeclarativePropertyMapMetaObject *mo; QStringList keys; - void emitChanged(const QString &key); + void emitChanged(const QString &key, const QVariant &value); }; -void QDeclarativePropertyMapPrivate::emitChanged(const QString &key) +void QDeclarativePropertyMapPrivate::emitChanged(const QString &key, const QVariant &value) { Q_Q(QDeclarativePropertyMap); - emit q->valueChanged(key); + emit q->valueChanged(key, value); } QDeclarativePropertyMapMetaObject::QDeclarativePropertyMapMetaObject(QDeclarativePropertyMap *obj, QDeclarativePropertyMapPrivate *objPriv) : QDeclarativeOpenMetaObject(obj) @@ -83,14 +85,19 @@ QDeclarativePropertyMapMetaObject::QDeclarativePropertyMapMetaObject(QDeclarativ priv = objPriv; } -void QDeclarativePropertyMapMetaObject::propertyWrite(int index) +void QDeclarativePropertyMapMetaObject::propertyWritten(int index) { - priv->emitChanged(QString::fromUtf8(name(index))); + priv->emitChanged(QString::fromUtf8(name(index)), operator[](index)); +} + +void QDeclarativePropertyMapMetaObject::propertyCreated(int, QMetaPropertyBuilder &b) +{ + priv->keys.append(QString::fromUtf8(b.name())); } /*! \class QDeclarativePropertyMap - \since 4.7 + \since 4.7 \brief The QDeclarativePropertyMap class allows you to set key-value pairs that can be used in bindings. QDeclarativePropertyMap provides a convenient way to expose domain data to the UI layer. @@ -172,8 +179,6 @@ QVariant QDeclarativePropertyMap::value(const QString &key) const void QDeclarativePropertyMap::insert(const QString &key, const QVariant &value) { Q_D(QDeclarativePropertyMap); - if (!d->keys.contains(key)) - d->keys.append(key); d->mo->setValue(key.toUtf8(), value); } @@ -249,10 +254,8 @@ QVariant &QDeclarativePropertyMap::operator[](const QString &key) //### optimize Q_D(QDeclarativePropertyMap); QByteArray utf8key = key.toUtf8(); - if (!d->keys.contains(key)) { - d->keys.append(key); + if (!d->keys.contains(key)) d->mo->setValue(utf8key, QVariant()); //force creation -- needed below - } return (*(d->mo))[utf8key]; } @@ -268,9 +271,9 @@ const QVariant QDeclarativePropertyMap::operator[](const QString &key) const } /*! - \fn void QDeclarativePropertyMap::valueChanged(const QString &key) + \fn void QDeclarativePropertyMap::valueChanged(const QString &key, const QVariant &value) This signal is emitted whenever one of the values in the map is changed. \a key - is the key corresponding to the value that was changed. + is the key corresponding to the \a value that was changed. \note valueChanged() is \bold NOT emitted when changes are made by calling insert() or clear() - it is only emitted when a value is updated from QML. diff --git a/src/declarative/util/qdeclarativepropertymap.h b/src/declarative/util/qdeclarativepropertymap.h index 513089f..e0b7ce3 100644 --- a/src/declarative/util/qdeclarativepropertymap.h +++ b/src/declarative/util/qdeclarativepropertymap.h @@ -76,7 +76,7 @@ public: const QVariant operator[](const QString &key) const; Q_SIGNALS: - void valueChanged(const QString &key); + void valueChanged(const QString &key, const QVariant &value); private: Q_DECLARE_PRIVATE(QDeclarativePropertyMap) diff --git a/src/declarative/util/qdeclarativeview.cpp b/src/declarative/util/qdeclarativeview.cpp index 8e65151..138fe3c 100644 --- a/src/declarative/util/qdeclarativeview.cpp +++ b/src/declarative/util/qdeclarativeview.cpp @@ -289,7 +289,6 @@ QDeclarativeView::~QDeclarativeView() void QDeclarativeView::setSource(const QUrl& url) { d->source = url; - d->engine.setBaseUrl(url); d->execute(); } diff --git a/src/imports/webkit/qdeclarativewebview.cpp b/src/imports/webkit/qdeclarativewebview.cpp index 0b85ae4..be3fca2 100644 --- a/src/imports/webkit/qdeclarativewebview.cpp +++ b/src/imports/webkit/qdeclarativewebview.cpp @@ -121,6 +121,10 @@ public: A WebView renders web content based on a URL. + This type is made available by importing the \c org.webkit module: + + \b{import org.webkit 1.0} + If the width and height of the item is not set, they will dynamically adjust to a size appropriate for the content. This width may be large for typical online web pages. diff --git a/tests/auto/declarative/qdeclarativeimage/data/heart-win32.png b/tests/auto/declarative/qdeclarativeimage/data/heart-win32.png Binary files differnew file mode 100644 index 0000000..351da13 --- /dev/null +++ b/tests/auto/declarative/qdeclarativeimage/data/heart-win32.png diff --git a/tests/auto/declarative/qdeclarativeimage/data/heart200-win32.png b/tests/auto/declarative/qdeclarativeimage/data/heart200-win32.png Binary files differnew file mode 100644 index 0000000..4976ff9 --- /dev/null +++ b/tests/auto/declarative/qdeclarativeimage/data/heart200-win32.png diff --git a/tests/auto/declarative/qdeclarativeimage/tst_qdeclarativeimage.cpp b/tests/auto/declarative/qdeclarativeimage/tst_qdeclarativeimage.cpp index c1bf2b8..ec9f4ec 100644 --- a/tests/auto/declarative/qdeclarativeimage/tst_qdeclarativeimage.cpp +++ b/tests/auto/declarative/qdeclarativeimage/tst_qdeclarativeimage.cpp @@ -260,7 +260,8 @@ void tst_qdeclarativeimage::pixmap() void tst_qdeclarativeimage::svg() { - QString componentStr = "import Qt 4.6\nImage { source: \"" SRCDIR "/data/heart.svg\"; sourceSize.width: 300; sourceSize.height: 300 }"; + QString src = QUrl::fromLocalFile(SRCDIR "/data/heart.svg").toString(); + QString componentStr = "import Qt 4.6\nImage { source: \"" + src + "\"; sourceSize.width: 300; sourceSize.height: 300 }"; QDeclarativeComponent component(&engine); component.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); QDeclarativeImage *obj = qobject_cast<QDeclarativeImage*>(component.create()); @@ -271,6 +272,8 @@ void tst_qdeclarativeimage::svg() QCOMPARE(obj->height(), 500.0); #if defined(Q_OS_MAC) QCOMPARE(obj->pixmap(), QPixmap(SRCDIR "/data/heart-mac.png")); +#elif defined(Q_OS_WIN32) + QCOMPARE(obj->pixmap(), QPixmap(SRCDIR "/data/heart-win32.png")); #else QCOMPARE(obj->pixmap(), QPixmap(SRCDIR "/data/heart.png")); #endif @@ -283,6 +286,8 @@ void tst_qdeclarativeimage::svg() QCOMPARE(obj->height(), 500.0); #if defined(Q_OS_MAC) QCOMPARE(obj->pixmap(), QPixmap(SRCDIR "/data/heart200-mac.png")); +#elif defined(Q_OS_WIN32) + QCOMPARE(obj->pixmap(), QPixmap(SRCDIR "/data/heart200-win32.png")); #else QCOMPARE(obj->pixmap(), QPixmap(SRCDIR "/data/heart200.png")); #endif @@ -291,7 +296,12 @@ void tst_qdeclarativeimage::svg() void tst_qdeclarativeimage::big() { - QString componentStr = "import Qt 4.6\nImage { source: \"" SRCDIR "/data/big.jpeg\"; sourceSize.width: 256; sourceSize.height: 256 }"; + // If the JPEG loader does not implement scaling efficiently, it would + // have to build a 400 MB image. That would be a bug in the JPEG loader. + + QString src = QUrl::fromLocalFile(SRCDIR "/data/big.jpeg").toString(); + QString componentStr = "import Qt 4.6\nImage { source: \"" + src + "\"; sourceSize.width: 256; sourceSize.height: 256 }"; + QDeclarativeComponent component(&engine); component.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); QDeclarativeImage *obj = qobject_cast<QDeclarativeImage*>(component.create()); diff --git a/tests/auto/declarative/qdeclarativelanguage/data/dynamicProperties.qml b/tests/auto/declarative/qdeclarativelanguage/data/dynamicProperties.qml index aef3269..bedab8c 100644 --- a/tests/auto/declarative/qdeclarativelanguage/data/dynamicProperties.qml +++ b/tests/auto/declarative/qdeclarativelanguage/data/dynamicProperties.qml @@ -10,5 +10,4 @@ QtObject { property url urlProperty: "main.qml" property date dateProperty: "1945-09-02" property var varProperty: "Hello World!" - property variant variantProperty: 12 } diff --git a/tests/auto/declarative/qdeclarativelanguage/tst_qdeclarativelanguage.cpp b/tests/auto/declarative/qdeclarativelanguage/tst_qdeclarativelanguage.cpp index eae78c4..e2cf5ca 100644 --- a/tests/auto/declarative/qdeclarativelanguage/tst_qdeclarativelanguage.cpp +++ b/tests/auto/declarative/qdeclarativelanguage/tst_qdeclarativelanguage.cpp @@ -586,7 +586,6 @@ void tst_qdeclarativelanguage::dynamicProperties() QCOMPARE(object->property("colorProperty"), QVariant(QColor("red"))); QCOMPARE(object->property("dateProperty"), QVariant(QDate(1945, 9, 2))); QCOMPARE(object->property("varProperty"), QVariant("Hello World!")); - QCOMPARE(object->property("variantProperty"), QVariant(12)); } // Test that nested types can use dynamic properties diff --git a/tests/auto/declarative/qdeclarativepropertymap/tst_qdeclarativepropertymap.cpp b/tests/auto/declarative/qdeclarativepropertymap/tst_qdeclarativepropertymap.cpp index 22c5581..c996a14 100644 --- a/tests/auto/declarative/qdeclarativepropertymap/tst_qdeclarativepropertymap.cpp +++ b/tests/auto/declarative/qdeclarativepropertymap/tst_qdeclarativepropertymap.cpp @@ -59,6 +59,8 @@ private slots: void clear(); void changed(); void count(); + + void crashBug(); }; void tst_QDeclarativePropertyMap::insert() @@ -123,7 +125,7 @@ void tst_QDeclarativePropertyMap::clear() void tst_QDeclarativePropertyMap::changed() { QDeclarativePropertyMap map; - QSignalSpy spy(&map, SIGNAL(valueChanged(const QString&))); + QSignalSpy spy(&map, SIGNAL(valueChanged(const QString&, const QVariant&))); map.insert(QLatin1String("key1"),100); map.insert(QLatin1String("key2"),200); QCOMPARE(spy.count(), 0); @@ -144,7 +146,9 @@ void tst_QDeclarativePropertyMap::changed() QCOMPARE(txt->text(), QString('X')); QCOMPARE(spy.count(), 1); QList<QVariant> arguments = spy.takeFirst(); + QCOMPARE(arguments.count(), 2); QCOMPARE(arguments.at(0).toString(),QLatin1String("key1")); + QCOMPARE(arguments.at(1).value<QVariant>(),QVariant("Hello World")); QCOMPARE(map.value(QLatin1String("key1")), QVariant("Hello World")); } @@ -166,6 +170,20 @@ void tst_QDeclarativePropertyMap::count() QCOMPARE(map.size(), map.count()); } +void tst_QDeclarativePropertyMap::crashBug() +{ + QDeclarativePropertyMap map; + + QDeclarativeEngine engine; + QDeclarativeContext context(&engine); + context.setContextProperty("map", &map); + + QDeclarativeComponent c(&engine); + c.setData("import Qt 4.6\nBinding { target: map; property: \"myProp\"; value: 10 + 23 }",QUrl()); + QObject *obj = c.create(&context); + delete obj; +} + QTEST_MAIN(tst_QDeclarativePropertyMap) #include "tst_qdeclarativepropertymap.moc" diff --git a/tests/auto/declarative/qmlvisual/qmlvisual.pro b/tests/auto/declarative/qmlvisual/qmlvisual.pro new file mode 100644 index 0000000..f2b3bca --- /dev/null +++ b/tests/auto/declarative/qmlvisual/qmlvisual.pro @@ -0,0 +1,7 @@ +load(qttest_p4) +contains(QT_CONFIG,declarative): QT += declarative +macx:CONFIG -= app_bundle + +SOURCES += tst_qmlvisual.cpp + +DEFINES += QT_TEST_SOURCE_DIR=\"\\\"$$PWD\\\"\" diff --git a/tests/benchmarks/declarative/qmltime/tests/vmemetaobject/null.qml b/tests/benchmarks/declarative/qmltime/tests/vmemetaobject/null.qml new file mode 100644 index 0000000..a31af5a --- /dev/null +++ b/tests/benchmarks/declarative/qmltime/tests/vmemetaobject/null.qml @@ -0,0 +1,13 @@ +import Qt 4.6 +import QmlTime 1.0 as QmlTime + +Item { + + QmlTime.Timer { + component: Component { + QtObject { + } + } + } + +} diff --git a/tests/benchmarks/declarative/qmltime/tests/vmemetaobject/property.qml b/tests/benchmarks/declarative/qmltime/tests/vmemetaobject/property.qml new file mode 100644 index 0000000..007d12a --- /dev/null +++ b/tests/benchmarks/declarative/qmltime/tests/vmemetaobject/property.qml @@ -0,0 +1,18 @@ +import Qt 4.6 +import QmlTime 1.0 as QmlTime + +Item { + + QmlTime.Timer { + component: Component { + QtObject { + property string s + property string s2 + property string s3 + property string s4 + } + } + } + +} + |