diff options
author | Michael Brasser <michael.brasser@nokia.com> | 2009-08-25 22:57:29 (GMT) |
---|---|---|
committer | Michael Brasser <michael.brasser@nokia.com> | 2009-08-25 22:57:29 (GMT) |
commit | 314c6ec54e4cb4e2ec936ada7e0a112a60b87832 (patch) | |
tree | a5444e7cae8d40eb549b70dd4473057f6b3cda09 | |
parent | 8e580cebef7128666017ba39d41aa620a1d2eddf (diff) | |
parent | 0094735947164aef8f8e6539c535199b29ed6f4e (diff) | |
download | Qt-314c6ec54e4cb4e2ec936ada7e0a112a60b87832.zip Qt-314c6ec54e4cb4e2ec936ada7e0a112a60b87832.tar.gz Qt-314c6ec54e4cb4e2ec936ada7e0a112a60b87832.tar.bz2 |
Merge branch 'kinetic-declarativeui' of git@scm.dev.nokia.troll.no:qt/kinetic into kinetic-declarativeui
78 files changed, 1054 insertions, 516 deletions
diff --git a/demos/declarative/flickr/content/ImageDetails.qml b/demos/declarative/flickr/common/ImageDetails.qml index 8098273..8098273 100644 --- a/demos/declarative/flickr/content/ImageDetails.qml +++ b/demos/declarative/flickr/common/ImageDetails.qml diff --git a/demos/declarative/flickr/content/LikeOMeter.qml b/demos/declarative/flickr/common/LikeOMeter.qml index 754dbb1..754dbb1 100644 --- a/demos/declarative/flickr/content/LikeOMeter.qml +++ b/demos/declarative/flickr/common/LikeOMeter.qml diff --git a/demos/declarative/flickr/content/Loading.qml b/demos/declarative/flickr/common/Loading.qml index ff2c829..ff2c829 100644 --- a/demos/declarative/flickr/content/Loading.qml +++ b/demos/declarative/flickr/common/Loading.qml diff --git a/demos/declarative/flickr/content/MediaButton.qml b/demos/declarative/flickr/common/MediaButton.qml index 0ffd596..0ffd596 100644 --- a/demos/declarative/flickr/content/MediaButton.qml +++ b/demos/declarative/flickr/common/MediaButton.qml diff --git a/demos/declarative/flickr/content/MediaLineEdit.qml b/demos/declarative/flickr/common/MediaLineEdit.qml index 500a402..500a402 100644 --- a/demos/declarative/flickr/content/MediaLineEdit.qml +++ b/demos/declarative/flickr/common/MediaLineEdit.qml diff --git a/demos/declarative/flickr/content/Progress.qml b/demos/declarative/flickr/common/Progress.qml index 00ef901..00ef901 100644 --- a/demos/declarative/flickr/content/Progress.qml +++ b/demos/declarative/flickr/common/Progress.qml diff --git a/demos/declarative/flickr/common/RssModel.qml b/demos/declarative/flickr/common/RssModel.qml new file mode 100644 index 0000000..ed9fd5c --- /dev/null +++ b/demos/declarative/flickr/common/RssModel.qml @@ -0,0 +1,20 @@ +import Qt 4.6 + +XmlListModel { + property string tags : "" + + source: "http://api.flickr.com/services/feeds/photos_public.gne?"+(tags ? "tags="+tags+"&" : "")+"format=rss2" + query: "/rss/channel/item" + namespaceDeclarations: "declare namespace media=\"http://search.yahoo.com/mrss/\";" + + XmlRole { name: "title"; query: "title/string()" } + XmlRole { name: "imagePath"; query: "media:thumbnail/@url/string()" } + XmlRole { name: "url"; query: "media:content/@url/string()" } + XmlRole { name: "description"; query: "description/string()" } + XmlRole { name: "tags"; query: "media:category/string()" } + XmlRole { name: "photoWidth"; query: "media:content/@width/string()" } + XmlRole { name: "photoHeight"; query: "media:content/@height/string()" } + XmlRole { name: "photoType"; query: "media:content/@type/string()" } + XmlRole { name: "photoAuthor"; query: "author/string()" } + XmlRole { name: "photoDate"; query: "pubDate/string()" } +} diff --git a/demos/declarative/flickr/content/ScrollBar.qml b/demos/declarative/flickr/common/ScrollBar.qml index 89d51e2..89d51e2 100644 --- a/demos/declarative/flickr/content/ScrollBar.qml +++ b/demos/declarative/flickr/common/ScrollBar.qml diff --git a/demos/declarative/flickr/content/Slider.qml b/demos/declarative/flickr/common/Slider.qml index b88636d..b88636d 100644 --- a/demos/declarative/flickr/content/Slider.qml +++ b/demos/declarative/flickr/common/Slider.qml diff --git a/demos/declarative/flickr/content/Star.qml b/demos/declarative/flickr/common/Star.qml index 006e86ad..006e86ad 100644 --- a/demos/declarative/flickr/content/Star.qml +++ b/demos/declarative/flickr/common/Star.qml diff --git a/demos/declarative/flickr/content/pics/background.png b/demos/declarative/flickr/common/pics/background.png Binary files differindex 5b37072..5b37072 100644 --- a/demos/declarative/flickr/content/pics/background.png +++ b/demos/declarative/flickr/common/pics/background.png diff --git a/demos/declarative/flickr/content/pics/button-pressed.png b/demos/declarative/flickr/common/pics/button-pressed.png Binary files differindex e434d32..e434d32 100644 --- a/demos/declarative/flickr/content/pics/button-pressed.png +++ b/demos/declarative/flickr/common/pics/button-pressed.png diff --git a/demos/declarative/flickr/content/pics/button-pressed.sci b/demos/declarative/flickr/common/pics/button-pressed.sci index d3b16e2..d3b16e2 100644 --- a/demos/declarative/flickr/content/pics/button-pressed.sci +++ b/demos/declarative/flickr/common/pics/button-pressed.sci diff --git a/demos/declarative/flickr/content/pics/button.png b/demos/declarative/flickr/common/pics/button.png Binary files differindex 56a63ce..56a63ce 100644 --- a/demos/declarative/flickr/content/pics/button.png +++ b/demos/declarative/flickr/common/pics/button.png diff --git a/demos/declarative/flickr/content/pics/button.sci b/demos/declarative/flickr/common/pics/button.sci index d3b16e2..d3b16e2 100644 --- a/demos/declarative/flickr/content/pics/button.sci +++ b/demos/declarative/flickr/common/pics/button.sci diff --git a/demos/declarative/flickr/content/pics/ghns_star.png b/demos/declarative/flickr/common/pics/ghns_star.png Binary files differindex 4ad43cc..4ad43cc 100644 --- a/demos/declarative/flickr/content/pics/ghns_star.png +++ b/demos/declarative/flickr/common/pics/ghns_star.png diff --git a/demos/declarative/flickr/content/pics/loading.png b/demos/declarative/flickr/common/pics/loading.png Binary files differindex 47a1589..47a1589 100644 --- a/demos/declarative/flickr/content/pics/loading.png +++ b/demos/declarative/flickr/common/pics/loading.png diff --git a/demos/declarative/flickr/content/pics/reflection.png b/demos/declarative/flickr/common/pics/reflection.png Binary files differindex c143a48..c143a48 100644 --- a/demos/declarative/flickr/content/pics/reflection.png +++ b/demos/declarative/flickr/common/pics/reflection.png diff --git a/demos/declarative/flickr/content/pics/shadow-bottom.png b/demos/declarative/flickr/common/pics/shadow-bottom.png Binary files differindex 523f6e7..523f6e7 100644 --- a/demos/declarative/flickr/content/pics/shadow-bottom.png +++ b/demos/declarative/flickr/common/pics/shadow-bottom.png diff --git a/demos/declarative/flickr/content/pics/shadow-corner.png b/demos/declarative/flickr/common/pics/shadow-corner.png Binary files differindex ef8c856..ef8c856 100644 --- a/demos/declarative/flickr/content/pics/shadow-corner.png +++ b/demos/declarative/flickr/common/pics/shadow-corner.png diff --git a/demos/declarative/flickr/content/pics/shadow-right-screen.png b/demos/declarative/flickr/common/pics/shadow-right-screen.png Binary files differindex 9856c4f..9856c4f 100644 --- a/demos/declarative/flickr/content/pics/shadow-right-screen.png +++ b/demos/declarative/flickr/common/pics/shadow-right-screen.png diff --git a/demos/declarative/flickr/content/pics/shadow-right.png b/demos/declarative/flickr/common/pics/shadow-right.png Binary files differindex f534a35..f534a35 100644 --- a/demos/declarative/flickr/content/pics/shadow-right.png +++ b/demos/declarative/flickr/common/pics/shadow-right.png diff --git a/demos/declarative/flickr/flickr.qml b/demos/declarative/flickr/flickr-desktop.qml index d8a27d5..5effc42 100644 --- a/demos/declarative/flickr/flickr.qml +++ b/demos/declarative/flickr/flickr-desktop.qml @@ -1,6 +1,6 @@ import Qt 4.6 -import "content" +import "common" Item { id: MainWindow; width: 800; height: 450 @@ -8,25 +8,6 @@ Item { property bool showPathView : false resources: [ - XmlListModel { - id: FeedModel - property string tags : TagsEdit.text - source: "http://api.flickr.com/services/feeds/photos_public.gne?"+(tags ? "tags="+tags+"&" : "")+"format=rss2" - query: "/rss/channel/item" - namespaceDeclarations: "declare namespace media=\"http://search.yahoo.com/mrss/\";" - - XmlRole { name: "title"; query: "title/string()" } - XmlRole { name: "imagePath"; query: "media:thumbnail/@url/string()" } - XmlRole { name: "url"; query: "media:content/@url/string()" } - XmlRole { name: "description"; query: "description/string()" } - XmlRole { name: "tags"; query: "media:category/string()" } - XmlRole { name: "photoWidth"; query: "media:content/@width/string()" } - XmlRole { name: "photoHeight"; query: "media:content/@height/string()" } - XmlRole { name: "photoType"; query: "media:content/@type/string()" } - XmlRole { name: "photoAuthor"; query: "author/string()" } - XmlRole { name: "photoDate"; query: "pubDate/string()" } - }, - Component { id: PhotoDelegate Item { @@ -72,9 +53,9 @@ Item { Item { id: Shadows - Image { source: "content/pics/shadow-right.png"; x: WhiteRect.width; height: WhiteRect.height } - Image { source: "content/pics/shadow-bottom.png"; y: WhiteRect.height; width: WhiteRect.width } - Image { id: Corner; source: "content/pics/shadow-corner.png"; x: WhiteRect.width; y: WhiteRect.height } + Image { source: "common/pics/shadow-right.png"; x: WhiteRect.width; height: WhiteRect.height } + Image { source: "common/pics/shadow-bottom.png"; y: WhiteRect.height; width: WhiteRect.width } + Image { id: Corner; source: "common/pics/shadow-corner.png"; x: WhiteRect.width; y: WhiteRect.height } } } @@ -123,17 +104,17 @@ Item { anchors.fill: parent - Image { source: "content/pics/background.png"; anchors.fill: parent } - - Loading { anchors.centerIn: parent; visible: FeedModel.status } + Image { source: "common/pics/background.png"; anchors.fill: parent } + RssModel { id: RssModel; tags : TagsEdit.text } + Loading { anchors.centerIn: parent; visible: RssModel.status } GridView { - id: PhotoGridView; model: FeedModel; delegate: PhotoDelegate; cacheBuffer: 100 + id: PhotoGridView; model: RssModel; delegate: PhotoDelegate; cacheBuffer: 100 cellWidth: 105; cellHeight: 105; x:32; y: 80; width: 800; height: 330; z: 1 } PathView { - id: PhotoPathView; model: FeedModel; delegate: PhotoDelegate + id: PhotoPathView; model: RssModel; delegate: PhotoDelegate y: -380; width: 800; height: 330; pathItemCount: 10; z: 1 path: Path { startX: -50; startY: 40; @@ -175,7 +156,7 @@ Item { text: "Update" anchors.right: ViewModeButton.left; anchors.rightMargin: 5 anchors.top: ViewModeButton.top - onClicked: { FeedModel.reload(); } + onClicked: { RssModel.reload(); } } MediaLineEdit { @@ -205,7 +186,7 @@ Item { Text { id: CategoryText; anchors.horizontalCenter: parent.horizontalCenter; y: 15; text: "Flickr - " + - (FeedModel.tags=="" ? "Uploads from everyone" : "Recent Uploads tagged " + FeedModel.tags) + (RssModel.tags=="" ? "Uploads from everyone" : "Recent Uploads tagged " + RssModel.tags) font.pointSize: 20; font.bold: true; color: "white"; style: "Raised"; styleColor: "black" } } diff --git a/demos/declarative/flickr/flickr-mobile.qml b/demos/declarative/flickr/flickr-mobile.qml new file mode 100644 index 0000000..a4692a3 --- /dev/null +++ b/demos/declarative/flickr/flickr-mobile.qml @@ -0,0 +1,51 @@ +import Qt 4.6 +import "common" as Common +import "mobile" as Mobile + +Item { + id: Screen; width: 320; height: 480 + property bool inListView : false + + Rectangle { + id: Background + anchors.fill: parent; color: "#343434"; + + Image { source: "mobile/images/stripes.png"; fillMode: "Tile"; anchors.fill: parent; opacity: 0.3 } + + Common.RssModel { id: RssModel } + Common.Loading { anchors.centerIn: parent; visible: RssModel.status } + + Item { + id: Views + x: 2; width: parent.width - 4 + anchors.top: TitleBar.bottom; anchors.bottom: ToolBar.top + + Mobile.GridDelegate { id: GridDelegate } + GridView { + id: PhotoGridView; model: RssModel; delegate: GridDelegate; cacheBuffer: 100 + cellWidth: 79; cellHeight: 79; width: parent.width; height: parent.height - 1 + } + + Mobile.ListDelegate { id: ListDelegate } + ListView { + id: PhotoListView; model: RssModel; delegate: ListDelegate + width: parent.width; height: parent.height; x: -(parent.width * 1.5); cacheBuffer: 100; + } + } + + Common.ImageDetails { id: ImageDetails; width: parent.width; x: parent.width; height: parent.height } + Mobile.TitleBar { id: TitleBar; width: parent.width; height: 40; opacity: 0.9 } + Mobile.ToolBar { id: ToolBar; height: 40; anchors.bottom: parent.bottom; width: parent.width; opacity: 0.9 } + + states: [ + State { + name: "ListView"; when: Screen.inListView == true + PropertyChanges { target: PhotoListView; x: 0 } + PropertyChanges { target: PhotoGridView; x: -(parent.width * 1.5) } + } + ] + transitions: [ + Transition { NumberAnimation { properties: "x"; duration: 500; easing: "easeInOutQuad" } } + ] + } +} diff --git a/demos/declarative/flickr/flickr2.qml b/demos/declarative/flickr/flickr2.qml deleted file mode 100644 index d9b1f60..0000000 --- a/demos/declarative/flickr/flickr2.qml +++ /dev/null @@ -1,261 +0,0 @@ -import Qt 4.6 - -import "content" - -Item { - id: MainWindow; width: 800; height: 450 - - property bool showPathView : false - - VisualModel { - id: MyVisualModel - model: - XmlListModel { - id: FeedModel - property string tags : TagsEdit.text - source: "http://api.flickr.com/services/feeds/photos_public.gne?"+(tags ? "tags="+tags+"&" : "")+"format=rss2" - query: "/rss/channel/item" - namespaceDeclarations: "declare namespace media=\"http://search.yahoo.com/mrss/\";" - - XmlRole { name: "title"; query: "title/string()" } - XmlRole { name: "imagePath"; query: "media:thumbnail/@url/string()" } - XmlRole { name: "url"; query: "media:content/@url/string()" } - XmlRole { name: "description"; query: "description/string()" } - XmlRole { name: "tags"; query: "media:category/string()" } - XmlRole { name: "photoWidth"; query: "media:content/@width/string()" } - XmlRole { name: "photoHeight"; query: "media:content/@height/string()" } - XmlRole { name: "photoType"; query: "media:content/@type/string()" } - XmlRole { name: "photoAuthor"; query: "author/string()" } - XmlRole { name: "photoDate"; query: "pubDate/string()" } - } - - delegate: Package { - Item { - id: Wrapper; width: 85; height: 85; scale: {1.0} - z: PathViewPackage.PathView.z - property real angle: 0 * 0 - - transform: [ - Rotation { - id: Rotation; origin.x: 30; axis.x: 30; axis.y: 60; axis.z: 0 - angle: Wrapper.angle - } - ] - - Connection { - sender: Background.imageDetails; signal: "closed()" - script: { if (Wrapper.state == 'Details') Wrapper.state = '' } - } - - Script { - function photoClicked() { - Background.imageDetails.photoTitle = title; - Background.imageDetails.photoDescription = description; - Background.imageDetails.photoTags = tags; - Background.imageDetails.photoWidth = photoWidth; - Background.imageDetails.photoHeight = photoHeight; - Background.imageDetails.photoType = photoType; - Background.imageDetails.photoAuthor = photoAuthor; - Background.imageDetails.photoDate = photoDate; - Background.imageDetails.photoUrl = url; - Background.imageDetails.rating = 0; - Wrapper.state = "Details"; - } - } - - Rectangle { - id: WhiteRect; anchors.fill: parent; color: "white"; radius: 5 - - Loading { x: 26; y: 26; visible: Thumb.status!=1 } - Image { id: Thumb; source: imagePath; x: 5; y: 5 } - - Item { - id: Shadows - Image { source: "content/pics/shadow-right.png"; x: WhiteRect.width; height: WhiteRect.height } - Image { source: "content/pics/shadow-bottom.png"; y: WhiteRect.height; width: WhiteRect.width } - Image { id: Corner; source: "content/pics/shadow-corner.png"; x: WhiteRect.width; y: WhiteRect.height } - } - } - - MouseRegion { anchors.fill: Wrapper; onClicked: { photoClicked() } } - - states: [ - State { - name: "Details" - PropertyChanges { target: Background.imageDetails; z: 2 } - ParentChange { target: Wrapper; parent: Background.imageDetails.frontContainer } - PropertyChanges { target: Wrapper; x: 45; y: 35; scale: 1; z: 1000 } - PropertyChanges { target: Rotation; angle: 0 } - PropertyChanges { target: Shadows; opacity: 0 } - PropertyChanges { target: Background.imageDetails; y: 20 } - PropertyChanges { target: PhotoGridView; y: "-480" } - PropertyChanges { target: PhotoPathView; y: "-480" } - PropertyChanges { target: ViewModeButton; opacity: 0 } - PropertyChanges { target: TagsEdit; opacity: 0 } - PropertyChanges { target: FetchButton; opacity: 0 } - PropertyChanges { target: CategoryText; y: "-50" } - } - ] - - transitions: [ - Transition { - from: "*"; to: "Details" - ParentAction { } - NumberAnimation { properties: "x,y,scale,opacity,angle"; duration: 500; easing: "easeInOutQuad" } - }, - Transition { - from: "Details"; to: "*" - SequentialAnimation { - ParentAction { } - NumberAnimation { properties: "x,y,scale,opacity,angle"; duration: 500; easing: "easeInOutQuad" } - PropertyAction { target: Wrapper; properties: "z" } - } - } - ] - } - - Item { - Package.name: "pathView" - id: PathViewPackage; width: 85; height: 85 - } - - Item { - Package.name: "gridView" - id: GridViewPackage; width: 85; height: 85 - } - - Item { - id: MyItem - state: MainWindow.showPathView ? "pathView" : "gridView" - states: [ - State { - name: "gridView" - PropertyChanges { target: Wrapper; explicit: true; property: "moveToParent"; value: GridViewPackage } - }, - State { - name: "pathView" - PropertyChanges { target: Wrapper; scale: PathViewPackage.PathView.scale; angle: PathViewPackage.PathView.angle; } - PropertyChanges { target: Wrapper; explicit: true; moveToParent: PathViewPackage } - } - ] - transitions: [ - Transition { - to: "pathView" - SequentialAnimation { - PropertyAction { target: Wrapper; property: "moveToParent" } - ParallelAnimation { - NumberAnimation { - target: Wrapper - properties: "x,y" - to: 0 - easing: "easeOutQuad" - duration: 350 - } - NumberAnimation { target: Wrapper; properties: "scale,angle"; duration: 350 } - } - } - }, - Transition { - to: "gridView" - SequentialAnimation { - PauseAnimation { duration: Math.floor(index/7)*100 } - PropertyAction { target: Wrapper; property: "moveToParent" } - ParallelAnimation { - NumberAnimation { - target: Wrapper - properties: "x,y" - to: 0 - easing: "easeOutQuad" - duration: 250 - } - NumberAnimation { target: Wrapper; properties: "scale,angle"; duration: 250 } - } - } - } - ] - } - } - } - - - Item { - id: Background - property var imageDetails: ImageDetails - - Image { source: "content/pics/background.png" } - - GridView { - id: PhotoGridView; model: MyVisualModel.parts.gridView - cellWidth: 105; cellHeight: 105; x:32; y: 80; width: 800; height: 330; z: 1 - cacheBuffer: 100 - } - - PathView { - id: PhotoPathView; model: MyVisualModel.parts.pathView - y: 80; width: 800; height: 330; z: 1 - pathItemCount: 10; snapPosition: 0.001 - path: Path { - startX: -150; startY: 40; - - PathAttribute { name: "scale"; value: 0.9 } - PathAttribute { name: "angle"; value: -45 } - PathPercent { value: 0 } - PathLine { x: -50; y: 40 } - - PathPercent { value: 0.001 } - - PathCubic { - x: 400; y: 220 - control1X: 140; control1Y: 40 - control2X: 210; control2Y: 220 - } - - PathAttribute { name: "scale"; value: 1.2 } - PathAttribute { name: "z"; value: 1 } - PathAttribute { name: "angle"; value: 0 } - - PathCubic { - x: 850; y: 40 - control2X: 660; control2Y: 40 - control1X: 590; control1Y: 220 - } - - PathPercent { value: 0.999 } - PathLine { x: 950; y: 40 } - PathPercent { value: 1.0 } - PathAttribute { name: "scale"; value: 0.9 } - PathAttribute { name: "angle"; value: 45 } - } - } - - ImageDetails { id: ImageDetails; width: 750; x: 25; y: 500; height: 410 } - - MediaButton { - id: ViewModeButton; x: 680; y: 410; text: "View Mode" - onClicked: { if (MainWindow.showPathView == true) MainWindow.showPathView = false; else MainWindow.showPathView = true } - } - - MediaButton { - id: FetchButton - text: "Update" - anchors.right: ViewModeButton.left; anchors.rightMargin: 5 - anchors.top: ViewModeButton.top - onClicked: { FeedModel.reload(); } - } - - MediaLineEdit { - id: TagsEdit; - label: "Tags" - anchors.right: FetchButton.left; anchors.rightMargin: 5 - anchors.top: ViewModeButton.top - } - - } - - Text { - id: CategoryText; anchors.horizontalCenter: parent.horizontalCenter; y: 15; - text: "Flickr - " + - (FeedModel.tags=="" ? "Uploads from everyone" : "Recent Uploads tagged " + FeedModel.tags) - font.pointSize: 16; font.bold: true; color: "white"; style: "Raised"; styleColor: "black" - } -} diff --git a/demos/declarative/flickr/mobile/Button.qml b/demos/declarative/flickr/mobile/Button.qml new file mode 100644 index 0000000..275408c --- /dev/null +++ b/demos/declarative/flickr/mobile/Button.qml @@ -0,0 +1,41 @@ +import Qt 4.6 + +Item { + id: Container + + signal clicked + + property string text + + BorderImage { + id: Image + source: "images/toolbutton2.sci" + width: Container.width; height: Container.height + } + BorderImage { + id: Pressed + opacity: 0 + source: "images/toolbutton2.sci" + width: Container.width; height: Container.height + } + MouseRegion { + id: MouseRegion + anchors.fill: Image + onClicked: { Container.clicked(); } + } + Text { + color: "white" + anchors.centerIn: Image; font.bold: true + text: Container.text; style: "Raised"; styleColor: "black" + } + states: [ + State { + name: "Pressed" + when: MouseRegion.pressed == true + PropertyChanges { + target: Pressed + opacity: 1 + } + } + ] +} diff --git a/demos/declarative/flickr/mobile/GridDelegate.qml b/demos/declarative/flickr/mobile/GridDelegate.qml new file mode 100644 index 0000000..8090cd4 --- /dev/null +++ b/demos/declarative/flickr/mobile/GridDelegate.qml @@ -0,0 +1,74 @@ + import Qt 4.6 + + Component { + id: PhotoDelegate + Item { + id: Wrapper; width: 79; height: 79 + + Script { + function photoClicked() { + ImageDetails.photoTitle = title; + ImageDetails.photoDescription = description; + ImageDetails.photoTags = tags; + ImageDetails.photoWidth = photoWidth; + ImageDetails.photoHeight = photoHeight; + ImageDetails.photoType = photoType; + ImageDetails.photoAuthor = photoAuthor; + ImageDetails.photoDate = photoDate; + ImageDetails.photoUrl = url; + ImageDetails.rating = 0; + ScaleMe.state = "Details"; + } + } + + Item { + anchors.centerIn: parent + scale: 0.0 + scale: Behavior { NumberAnimation { easing: "easeInOutQuad"} } + id: ScaleMe + + Rectangle { height: 79; width: 79; id: BlackRect; anchors.centerIn: parent; color: "black"; smooth: true } + Rectangle { + id: WhiteRect; width: 77; height: 77; anchors.centerIn: parent; color: "#dddddd"; smooth: true + Image { id: Thumb; source: imagePath; x: 1; y: 1; smooth: true} + Image { source: "mobile/images/gloss.png"; smooth: true} + } + + Connection { + sender: ToolBar.button2; signal: "clicked()" + script: if (ScaleMe.state == 'Details' ) ScaleMe.state = 'Show'; + } + + states: [ + State { + name: "Show"; when: Thumb.status == 1 + PropertyChanges { target: ScaleMe; scale: 1 } + }, + State { + name: "Details"; extend: "Show" + ParentChange { target: Wrapper; parent: ImageDetails.frontContainer } + PropertyChanges { target: Wrapper; x: 20; y: 60 } + PropertyChanges { target: ImageDetails; x: 0 } + PropertyChanges { target: Views; x: -parent.width } + PropertyChanges { target: ToolBar.button2; text: "Back" } + } + ] + transitions: [ + Transition { + from: "Show"; to: "Details" + ParentAction { } + NumberAnimation { properties: "x,y,opacity,angle"; duration: 500; easing: "easeInOutQuad" } + }, + Transition { + from: "Details"; to: "Show" + SequentialAnimation { + ParentAction { } + NumberAnimation { properties: "x,y,opacity,angle"; duration: 500; easing: "easeInOutQuad" } + PropertyAction { target: Wrapper; properties: "z" } + } + } + ] + } + MouseRegion { anchors.fill: Wrapper; onClicked: { photoClicked() } } + } + } diff --git a/demos/declarative/flickr/mobile/ListDelegate.qml b/demos/declarative/flickr/mobile/ListDelegate.qml new file mode 100644 index 0000000..b9ec7f2 --- /dev/null +++ b/demos/declarative/flickr/mobile/ListDelegate.qml @@ -0,0 +1,24 @@ +import Qt 4.6 + +Component { + id: ListDelegate + Item { + id: Wrapper; width: Wrapper.ListView.view.width; height: 86 + Item { + id: MoveMe + Rectangle { color: "black"; opacity: Wrapper.ListView.index % 2 ? 0.2 : 0.3; height: 84; width: Wrapper.width; y: 1 } + Rectangle { + id: WhiteRect; x: 6; y: 4; width: 77; height: 77; color: "white"; smooth: true + + Image { id: Thumb; source: imagePath; x: 1; y: 1 } + Image { source: "images/gloss.png" } + } + Column { + x: 92; width: Wrapper.ListView.view.width - 95; y: 15; spacing: 2 + Text { text: title; color: "white"; width: parent.width; font.bold: true; elide: "ElideRight"; style: "Raised"; styleColor: "black" } + Text { text: photoAuthor; color: "white"; width: parent.width; elide: "ElideLeft"; color: "#cccccc"; style: "Raised"; styleColor: "black" } + Text { text: photoDate; color: "white"; width: parent.width; elide: "ElideRight"; color: "#cccccc"; style: "Raised"; styleColor: "black" } + } + } + } +} diff --git a/demos/declarative/flickr/mobile/TitleBar.qml b/demos/declarative/flickr/mobile/TitleBar.qml new file mode 100644 index 0000000..59b8365 --- /dev/null +++ b/demos/declarative/flickr/mobile/TitleBar.qml @@ -0,0 +1,74 @@ +import Qt 4.6 + +Item { + id: TitleBar + + BorderImage { source: "images/titlebar2.sci"; width: parent.width; height: parent.height + 14; y: -7 } + + Item { + id: Container + width: (parent.width * 2) - 55 ; height: parent.height + + Script { + function accept() { + RssModel.tags = Editor.text + TitleBar.state = "" + } + } + + Text { + id: CategoryText + anchors.left: parent.left; anchors.right: TagButton.left + anchors.leftMargin: 10; anchors.rightMargin: 10 + anchors.verticalCenter: parent.verticalCenter + elide: "ElideLeft" + text: (RssModel.tags=="" ? "Uploads from everyone" : "Recent Uploads tagged " + RssModel.tags) + font.pointSize: 10; font.bold: true; color: "white"; style: "Raised"; styleColor: "black" + } + + Button { + id: TagButton; x: TitleBar.width - 50; y: 3; width: 45; height: 32; text: "..." + onClicked: if (TitleBar.state == "Tags") accept(); else TitleBar.state = "Tags" + } + + Item { + id: LineEdit + anchors.left: TagButton.right; anchors.leftMargin: 5; y: 4 + anchors.right: parent.right; anchors.rightMargin: 5; height: parent.height - 9 + BorderImage { source: "images/lineedit.sci"; anchors.fill: parent } + + TextInput { + id: Editor + anchors.left: parent.left; anchors.right: parent.right + anchors.leftMargin: 10; anchors.rightMargin: 10 + anchors.verticalCenter: parent.verticalCenter + cursorVisible: true; font.bold: true + color: "#151515"; highlightColor: "green" + } + KeyProxy { + id: Proxy + anchors.fill: parent + targets: [(ReturnKey), (Editor)] + } + Item { + id: ReturnKey + Keys.onReturnPressed: accept() + Keys.onEscapePressed: TitleBar.state = "" + } + } + } + states: [ + State { + name: "Tags" + PropertyChanges { target: Container; x: -TagButton.x + 5 } + PropertyChanges { target: TagButton; text: "OK" } + PropertyChanges { target: Proxy; focus: true } + } + ] + transitions: [ + Transition { + from: "*"; to: "*" + NumberAnimation { properties: "x"; easing: "easeInOutQuad" } + } + ] +} diff --git a/demos/declarative/flickr/mobile/ToolBar.qml b/demos/declarative/flickr/mobile/ToolBar.qml new file mode 100644 index 0000000..aa78c52 --- /dev/null +++ b/demos/declarative/flickr/mobile/ToolBar.qml @@ -0,0 +1,23 @@ +import Qt 4.6 + +Item { + id: Toolbar + property var button2: Button2 + + BorderImage { source: "images/titlebar2.sci"; width: parent.width; height: parent.height + 14; y: -7 } + + Button { anchors.left: parent.left; anchors.leftMargin: 5; y: 3; width: 140; height: 32; text: "Update"; onClicked: RssModel.reload() } + + Button { + id: Button2 + anchors.right: parent.right; anchors.rightMargin: 5; y: 3; width: 140; height: 32; text: "View mode" + onClicked: { + if (Button2.text == "View mode") { + if (Screen.inListView == true) + Screen.inListView = false; + else + Screen.inListView = true + } + } + } +} diff --git a/demos/declarative/flickr/mobile/images/gloss.png b/demos/declarative/flickr/mobile/images/gloss.png Binary files differnew file mode 100644 index 0000000..5d370cd --- /dev/null +++ b/demos/declarative/flickr/mobile/images/gloss.png diff --git a/demos/declarative/flickr/mobile/images/lineedit.png b/demos/declarative/flickr/mobile/images/lineedit.png Binary files differnew file mode 100644 index 0000000..2cc38dc --- /dev/null +++ b/demos/declarative/flickr/mobile/images/lineedit.png diff --git a/demos/declarative/flickr/mobile/images/lineedit.sci b/demos/declarative/flickr/mobile/images/lineedit.sci new file mode 100644 index 0000000..7c5ec6c --- /dev/null +++ b/demos/declarative/flickr/mobile/images/lineedit.sci @@ -0,0 +1,5 @@ +gridLeft: 10 +gridTop: 10 +gridBottom: 10 +gridRight: 10 +imageFile: lineedit.png diff --git a/demos/declarative/flickr/mobile/images/stripes.png b/demos/declarative/flickr/mobile/images/stripes.png Binary files differnew file mode 100644 index 0000000..9f36727 --- /dev/null +++ b/demos/declarative/flickr/mobile/images/stripes.png diff --git a/demos/declarative/flickr/mobile/images/titlebar2.png b/demos/declarative/flickr/mobile/images/titlebar2.png Binary files differnew file mode 100644 index 0000000..51c9008 --- /dev/null +++ b/demos/declarative/flickr/mobile/images/titlebar2.png diff --git a/demos/declarative/flickr/mobile/images/titlebar2.sci b/demos/declarative/flickr/mobile/images/titlebar2.sci new file mode 100644 index 0000000..e8fc2d1 --- /dev/null +++ b/demos/declarative/flickr/mobile/images/titlebar2.sci @@ -0,0 +1,5 @@ +gridLeft: 22 +gridTop: 10 +gridBottom: 10 +gridRight: 22 +imageFile: titlebar2.png diff --git a/demos/declarative/flickr/mobile/images/toolbutton2.png b/demos/declarative/flickr/mobile/images/toolbutton2.png Binary files differnew file mode 100644 index 0000000..8862898 --- /dev/null +++ b/demos/declarative/flickr/mobile/images/toolbutton2.png diff --git a/demos/declarative/flickr/mobile/images/toolbutton2.sci b/demos/declarative/flickr/mobile/images/toolbutton2.sci new file mode 100644 index 0000000..e3118b0 --- /dev/null +++ b/demos/declarative/flickr/mobile/images/toolbutton2.sci @@ -0,0 +1,5 @@ +gridLeft: 15 +gridTop: 4 +gridBottom: 4 +gridRight: 15 +imageFile: toolbutton2.png diff --git a/demos/declarative/samegame/SameGame.qml b/demos/declarative/samegame/SameGame.qml index d476e8b..0da5679 100644 --- a/demos/declarative/samegame/SameGame.qml +++ b/demos/declarative/samegame/SameGame.qml @@ -1,34 +1,57 @@ import Qt 4.6 - import "content" Rectangle { - id: page; width: 460; height: 700; color: activePalette.window + id: Screen + width: 490; height: 720 + Script { source: "content/samegame.js" } + SystemPalette { id: activePalette; colorGroup: Qt.Active } - Rectangle { - id: gameCanvas - property int score: 0 - z:20; y:20; color: "white"; border.width: 1 - width:parent.width - tileSize - (parent.width % tileSize); - height:parent.height - tileSize - (parent.height % tileSize); - anchors.horizontalCenter: parent.horizontalCenter - Image { id:background; - source: "content/pics/background.png" - anchors.fill: parent + + Item { + width: parent.width; anchors.top: parent.top; anchors.bottom: ToolBar.top + + Image { + id: background + anchors.fill: parent; source: "content/pics/background.png" + fillMode: "PreserveAspectCrop" } - MouseRegion { id: gameMR - anchors.fill: parent; onClicked: handleClick(mouse.x,mouse.y); + + Item { + id: gameCanvas + property int score: 0 + + z: 20; anchors.centerIn: parent + width: parent.width - (parent.width % tileSize); + height: parent.height - (parent.height % tileSize); + + MouseRegion { + id: gameMR + anchors.fill: parent; onClicked: handleClick(mouse.x,mouse.y); + } } } - Dialog { id: dialog; anchors.centerIn: parent; z: 21} - Button { - id: btnA; text: "New Game"; onClicked: {initBoard();} - anchors.top: gameCanvas.bottom; anchors.topMargin: 4; anchors.left: gameCanvas.left; - } - Text { - text: "Score: " + gameCanvas.score; width:100; font.pointSize:14 - anchors.top: gameCanvas.bottom; anchors.topMargin: 4; anchors.right: gameCanvas.right; + Dialog { id: dialog; anchors.centerIn: parent; z: 21 } + + Rectangle { + id: ToolBar + color: activePalette.window + height: 32; width: parent.width + anchors.bottom: Screen.bottom + + Button { + id: btnA; text: "New Game"; onClicked: {initBoard();} + anchors.left: parent.left; anchors.leftMargin: 3 + anchors.verticalCenter: parent.verticalCenter + } + + Text { + id: Score + text: "Score: " + gameCanvas.score; font.bold: true + anchors.right: parent.right; anchors.rightMargin: 3 + anchors.verticalCenter: parent.verticalCenter + } } } diff --git a/demos/declarative/samegame/content/Button.qml b/demos/declarative/samegame/content/Button.qml index 70b175c..2354218 100644 --- a/demos/declarative/samegame/content/Button.qml +++ b/demos/declarative/samegame/content/Button.qml @@ -1,18 +1,25 @@ import Qt 4.6 -Rectangle { - id: page; color: activePalette.button; width: txtItem.width+20; height: txtItem.height+4 - border.width: 1; border.color: activePalette.mid; radius: 10; +Rectangle { + id: Container + signal clicked property string text: "Button" - gradient: Gradient { - GradientStop { id:topGrad; position: 0.0; - color: if(mr.pressed){activePalette.dark;}else{activePalette.light;}} + + color: activePalette.button; smooth: true + width: txtItem.width + 20; height: txtItem.height + 6 + border.width: 1; border.color: activePalette.darker(activePalette.button); radius: 8; + + gradient: Gradient { + GradientStop { + id: topGrad; position: 0.0 + color: if (mr.pressed) { activePalette.dark } else { activePalette.light } } GradientStop { position: 1.0; color: activePalette.button } } - MouseRegion { id:mr; anchors.fill: parent; onClicked: page.clicked() } + + MouseRegion { id: mr; anchors.fill: parent; onClicked: Container.clicked() } + Text { - id: txtItem; text: page.text; anchors.centerIn: page; color: activePalette.buttonText - font.pointSize: 14; + id: txtItem; text: Container.text; anchors.centerIn: Container; color: activePalette.buttonText } } diff --git a/demos/declarative/samegame/content/Dialog.qml b/demos/declarative/samegame/content/Dialog.qml index a3c5f33..72c7900 100644 --- a/demos/declarative/samegame/content/Dialog.qml +++ b/demos/declarative/samegame/content/Dialog.qml @@ -2,7 +2,7 @@ import Qt 4.6 Rectangle { id: page - color: "white"; border.width: 1; width: 200; height: 60; + color: "white"; border.width: 1; width: MyText.width + 20; height: 60; property string text: "Hello World!" opacity: 0 opacity: Behavior { @@ -11,5 +11,5 @@ Rectangle { NumberAnimation {property: "opacity"; to: 0; duration: 1500 } } } - Text { anchors.centerIn: parent; text: parent.text } + Text { id: MyText; anchors.centerIn: parent; text: parent.text } } diff --git a/examples/declarative/loader/loader.pro b/examples/declarative/loader/loader.pro index baa5b8c..089eaff 100644 --- a/examples/declarative/loader/loader.pro +++ b/examples/declarative/loader/loader.pro @@ -1,7 +1,7 @@ SOURCES = main.cpp RESOURCES = loader.qrc -QT += script declarative +QT += script declarative network target.path = $$[QT_INSTALL_EXAMPLES]/declarative/loader sources.files = $$SOURCES $$HEADERS $$RESOURCES $$FORMS loader.pro diff --git a/examples/declarative/loader/main.cpp b/examples/declarative/loader/main.cpp index d018181..68f20d4 100644 --- a/examples/declarative/loader/main.cpp +++ b/examples/declarative/loader/main.cpp @@ -10,8 +10,11 @@ #include <QDebug> #include <QmlContext> #include <QmlComponent> +#include <QmlEngine> #include <qfxview.h> #include <QDebug> +#include <QNetworkDiskCache> +#include <QNetworkAccessManager> QFxView *canvas = 0; @@ -148,6 +151,24 @@ public slots: } }; +class ConfiguredNetworkAccessManager : public QNetworkAccessManager { +public: + ConfiguredNetworkAccessManager() + { + QNetworkDiskCache *cache = new QNetworkDiskCache; + cache->setCacheDirectory(QDir::tempPath()+QLatin1String("/qml-loader-network-cache")); + setCache(cache); + } + + QNetworkReply *createRequest (Operation op, const QNetworkRequest &req, QIODevice * outgoingData) + { + QNetworkRequest request = req; + request.setAttribute(QNetworkRequest::CacheLoadControlAttribute, QNetworkRequest::PreferCache); + request.setAttribute(QNetworkRequest::HttpPipeliningAllowedAttribute, true); + return QNetworkAccessManager::createRequest(op,request,outgoingData); + } +}; + int main(int argc, char *argv[]) { @@ -162,6 +183,8 @@ int main(int argc, char *argv[]) canvas = new QFxView; canvas->setFocusPolicy(Qt::StrongFocus); + canvas->engine()->setNetworkAccessManager(new ConfiguredNetworkAccessManager); + mw->setCentralWidget(canvas); QMenuBar *mb = mw->menuBar(); diff --git a/examples/declarative/webview/content/SpinSquare.qml b/examples/declarative/webview/content/SpinSquare.qml index 6d5ada3..95159b6 100644 --- a/examples/declarative/webview/content/SpinSquare.qml +++ b/examples/declarative/webview/content/SpinSquare.qml @@ -2,7 +2,7 @@ import Qt 4.6 Item { property var period : 250 - propert var color : "black" + property var color : "black" id: Root Item { diff --git a/examples/declarative/webview/evalandattach.html b/examples/declarative/webview/evalandattach.html new file mode 100644 index 0000000..c0992bb --- /dev/null +++ b/examples/declarative/webview/evalandattach.html @@ -0,0 +1,31 @@ +<body bgcolor=gray onload="ftext.confirmed.connect (ftext_confirmed); "> + <script> + do_it = function () {var oPressed = document.getElementById('pressed'); + oPressed.innerHTML = 'MouseRegion in QML clicked!';}; + ftext_confirmed = function () { statusText1.text = ftext.text; var oT = document.getElementById('htmlTextInput'); oT.value = ftext.text } + </script> + <table border=1> + <tr> + <td> </td> + <td id='pressed'></td> + </tr> + <tr> + <td><label for='htmlTextInput'>Type something:</label></td> + <td><input type='text' name='htmlTextInput' size='25' id='htmlTextInput' + onfocus="statusText2.text = 'Focus in html text input.'"></td> + </tr> + <tr> + <td><label for='htmlButton'> </label></td> + <td> + <input type='button' id='htmlButton' value='Push' + onclick="var oText = document.getElementById('htmlTextInput'); statusText1.text = oText.value; ftext.text = oText.value" /> + </tr> + </table> + <p> + Below a qml(QFxItem) object inside webkit: + </p> + <object data=content/FieldText.qml TYPE=application/x-qt-plugin id="ftext_id" text="" label="Cool:" width="200" + objectname="ftext"> + </object> +</body> + diff --git a/examples/declarative/webview/evalandattach.qml b/examples/declarative/webview/evalandattach.qml new file mode 100644 index 0000000..bf7f25e --- /dev/null +++ b/examples/declarative/webview/evalandattach.qml @@ -0,0 +1,55 @@ +import Qt 4.6 + +Item { + height: 640 + width: 360 + Text { + id: teksti + text: webView.statusText1 + anchors.top: parent.top + height: 30 + anchors.left: parent.left + width: parent.width/2 + } + + Text { + id: teksti2 + text: webView.statusText2 + anchors.top: parent.top + height: 30 + anchors.left: teksti.right + anchors.right: parent.right + } + + MouseRegion { + anchors.fill: teksti + onClicked: { webView.evaluateJavaScript ("do_it()") } + } + + WebView { + id: webView + property alias statusText1: txt.text + property alias statusText2: txt2.text + anchors.top: teksti.bottom + anchors.bottom: parent.bottom + anchors.left: parent.left + anchors.right: parent.right + focus: true + interactive: true + settings.pluginsEnabled: true + javaScriptWindowObjects: [ + Object { + id: txt + WebView.windowObjectName: "statusText1" + property string text: "Click me!" + }, + Object { + id: txt2 + WebView.windowObjectName: "statusText2" + property string text: "" + } + ] + url: "evalandattach.html" + } + +} diff --git a/src/declarative/extra/qfxanimatedimageitem.cpp b/src/declarative/extra/qfxanimatedimageitem.cpp index d366111..5a491e0 100644 --- a/src/declarative/extra/qfxanimatedimageitem.cpp +++ b/src/declarative/extra/qfxanimatedimageitem.cpp @@ -201,7 +201,6 @@ void QFxAnimatedImageItem::setSource(const QUrl &url) } else { d->status = Loading; QNetworkRequest req(d->url); - req.setAttribute(QNetworkRequest::CacheLoadControlAttribute, QNetworkRequest::PreferCache); d->reply = qmlContext(this)->engine()->networkAccessManager()->get(req); QObject::connect(d->reply, SIGNAL(finished()), this, SLOT(movieRequestFinished())); diff --git a/src/declarative/extra/qmlfontloader.cpp b/src/declarative/extra/qmlfontloader.cpp index 2f54f24..5373d02 100644 --- a/src/declarative/extra/qmlfontloader.cpp +++ b/src/declarative/extra/qmlfontloader.cpp @@ -121,7 +121,6 @@ void QmlFontLoader::setSource(const QUrl &url) #endif { QNetworkRequest req(d->url); - req.setAttribute(QNetworkRequest::CacheLoadControlAttribute, QNetworkRequest::PreferCache); d->reply = qmlEngine(this)->networkAccessManager()->get(req); QObject::connect(d->reply, SIGNAL(finished()), this, SLOT(replyFinished())); } diff --git a/src/declarative/extra/qmlxmllistmodel.cpp b/src/declarative/extra/qmlxmllistmodel.cpp index 077e9a9..9b74799 100644 --- a/src/declarative/extra/qmlxmllistmodel.cpp +++ b/src/declarative/extra/qmlxmllistmodel.cpp @@ -605,7 +605,6 @@ void QmlXmlListModel::reload() emit statusChanged(d->status); QNetworkRequest req(d->src); - req.setAttribute(QNetworkRequest::CacheLoadControlAttribute, QNetworkRequest::PreferCache); d->reply = qmlContext(this)->engine()->networkAccessManager()->get(req); QObject::connect(d->reply, SIGNAL(finished()), this, SLOT(requestFinished())); QObject::connect(d->reply, SIGNAL(downloadProgress(qint64,qint64)), diff --git a/src/declarative/fx/qfxborderimage.cpp b/src/declarative/fx/qfxborderimage.cpp index 16677e0..60faa84 100644 --- a/src/declarative/fx/qfxborderimage.cpp +++ b/src/declarative/fx/qfxborderimage.cpp @@ -187,7 +187,6 @@ void QFxBorderImage::setSource(const QUrl &url) #endif { QNetworkRequest req(d->url); - req.setAttribute(QNetworkRequest::CacheLoadControlAttribute, QNetworkRequest::PreferCache); d->sciReply = qmlEngine(this)->networkAccessManager()->get(req); QObject::connect(d->sciReply, SIGNAL(finished()), this, SLOT(sciRequestFinished())); diff --git a/src/declarative/fx/qfxitem.cpp b/src/declarative/fx/qfxitem.cpp index feb4e8c..7938dc9 100644 --- a/src/declarative/fx/qfxitem.cpp +++ b/src/declarative/fx/qfxitem.cpp @@ -299,6 +299,229 @@ void QFxContents::setItem(QFxItem *item) calcWidth(); } +/* + Key filters can be installed on a QFxItem, but not removed. Currently they + are only used by attached objects (which are only destroyed on Item + destruction), so this isn't a problem. If in future this becomes any form + of public API, they will have to support removal too. +*/ +class QFxItemKeyFilter +{ +public: + QFxItemKeyFilter(QFxItem * = 0); + virtual ~QFxItemKeyFilter(); + + virtual void keyPressed(QKeyEvent *event); + virtual void keyReleased(QKeyEvent *event); + +private: + QFxItemKeyFilter *m_next; +}; + +QFxItemKeyFilter::QFxItemKeyFilter(QFxItem *item) +: m_next(0) +{ + QFxItemPrivate *p = + item?static_cast<QFxItemPrivate *>(QGraphicsItemPrivate::get(item)):0; + if (p) { + m_next = p->keyHandler; + p->keyHandler = this; + } +} + +QFxItemKeyFilter::~QFxItemKeyFilter() +{ +} + +void QFxItemKeyFilter::keyPressed(QKeyEvent *event) +{ + if (m_next) m_next->keyPressed(event); +} + +void QFxItemKeyFilter::keyReleased(QKeyEvent *event) +{ + if (m_next) m_next->keyReleased(event); +} + +class QFxKeyNavigationAttachedPrivate : public QObjectPrivate +{ +public: + QFxKeyNavigationAttachedPrivate() + : QObjectPrivate(), left(0), right(0), up(0), down(0) {} + + QFxItem *left; + QFxItem *right; + QFxItem *up; + QFxItem *down; +}; + +class QFxKeyNavigationAttached : public QObject, public QFxItemKeyFilter +{ + Q_OBJECT + Q_DECLARE_PRIVATE(QFxKeyNavigationAttached); + + Q_PROPERTY(QFxItem *left READ left WRITE setLeft NOTIFY changed); + Q_PROPERTY(QFxItem *right READ right WRITE setRight NOTIFY changed); + Q_PROPERTY(QFxItem *up READ up WRITE setUp NOTIFY changed); + Q_PROPERTY(QFxItem *down READ down WRITE setDown NOTIFY changed); +public: + QFxKeyNavigationAttached(QObject * = 0); + + QFxItem *left() const; + void setLeft(QFxItem *); + QFxItem *right() const; + void setRight(QFxItem *); + QFxItem *up() const; + void setUp(QFxItem *); + QFxItem *down() const; + void setDown(QFxItem *); + + static QFxKeyNavigationAttached *qmlAttachedProperties(QObject *); + +signals: + void changed(); + +private: + virtual void keyPressed(QKeyEvent *event); + virtual void keyReleased(QKeyEvent *event); +}; + +QFxKeyNavigationAttached::QFxKeyNavigationAttached(QObject *parent) +: QObject(*(new QFxKeyNavigationAttachedPrivate), parent), + QFxItemKeyFilter(qobject_cast<QFxItem*>(parent)) +{ +} + +QFxKeyNavigationAttached * +QFxKeyNavigationAttached::qmlAttachedProperties(QObject *obj) +{ + return new QFxKeyNavigationAttached(obj); +} + +QFxItem *QFxKeyNavigationAttached::left() const +{ + Q_D(const QFxKeyNavigationAttached); + return d->left; +} + +void QFxKeyNavigationAttached::setLeft(QFxItem *i) +{ + Q_D(QFxKeyNavigationAttached); + d->left = i; + emit changed(); +} + +QFxItem *QFxKeyNavigationAttached::right() const +{ + Q_D(const QFxKeyNavigationAttached); + return d->right; +} + +void QFxKeyNavigationAttached::setRight(QFxItem *i) +{ + Q_D(QFxKeyNavigationAttached); + d->right = i; + emit changed(); +} + +QFxItem *QFxKeyNavigationAttached::up() const +{ + Q_D(const QFxKeyNavigationAttached); + return d->up; +} + +void QFxKeyNavigationAttached::setUp(QFxItem *i) +{ + Q_D(QFxKeyNavigationAttached); + d->up = i; + emit changed(); +} + +QFxItem *QFxKeyNavigationAttached::down() const +{ + Q_D(const QFxKeyNavigationAttached); + return d->down; +} + +void QFxKeyNavigationAttached::setDown(QFxItem *i) +{ + Q_D(QFxKeyNavigationAttached); + d->down = i; + emit changed(); +} + +void QFxKeyNavigationAttached::keyPressed(QKeyEvent *event) +{ + Q_D(QFxKeyNavigationAttached); + + event->ignore(); + + switch(event->key()) { + case Qt::Key_Left: + if (d->left) { + d->left->setFocus(true); + event->accept(); + } + break; + case Qt::Key_Right: + if (d->right) { + d->right->setFocus(true); + event->accept(); + } + break; + case Qt::Key_Up: + if (d->up) { + d->up->setFocus(true); + event->accept(); + } + break; + case Qt::Key_Down: + if (d->down) { + d->down->setFocus(true); + event->accept(); + } + break; + default: + break; + } + + if (!event->isAccepted()) QFxItemKeyFilter::keyPressed(event); +} + +void QFxKeyNavigationAttached::keyReleased(QKeyEvent *event) +{ + Q_D(QFxKeyNavigationAttached); + + event->ignore(); + + switch(event->key()) { + case Qt::Key_Left: + if (d->left) { + event->accept(); + } + break; + case Qt::Key_Right: + if (d->right) { + event->accept(); + } + break; + case Qt::Key_Up: + if (d->up) { + event->accept(); + } + break; + case Qt::Key_Down: + if (d->down) { + event->accept(); + } + break; + default: + break; + } + + if (!event->isAccepted()) QFxItemKeyFilter::keyReleased(event); +} + /*! \qmlclass Keys \brief The Keys attached property provides key handling to Items. @@ -616,7 +839,7 @@ public: bool enabled; }; -class QFxKeysAttached : public QObject +class QFxKeysAttached : public QObject, public QFxItemKeyFilter { Q_OBJECT Q_DECLARE_PRIVATE(QFxKeysAttached); @@ -681,8 +904,8 @@ signals: void volumeDownPressed(QFxKeyEvent *event); private: - void keyPressed(QKeyEvent *event); - void keyReleased(QKeyEvent *event); + virtual void keyPressed(QKeyEvent *event); + virtual void keyReleased(QKeyEvent *event); const char *keyToSignal(int key) { QByteArray keySignal; @@ -704,8 +927,6 @@ private: }; static const SigMap sigMap[]; - static QHash<QObject*, QFxKeysAttached*> attachedProperties; - friend class QFxItem; }; const QFxKeysAttached::SigMap QFxKeysAttached::sigMap[] = { @@ -738,24 +959,19 @@ const QFxKeysAttached::SigMap QFxKeysAttached::sigMap[] = { { 0, 0 } }; -QHash<QObject*, QFxKeysAttached*> QFxKeysAttached::attachedProperties; - bool QFxKeysAttachedPrivate::isConnected(const char *signalName) { return isSignalConnected(signalIndex(signalName)); } QFxKeysAttached::QFxKeysAttached(QObject *parent) - : QObject(*(new QFxKeysAttachedPrivate), parent) +: QObject(*(new QFxKeysAttachedPrivate), parent), + QFxItemKeyFilter(qobject_cast<QFxItem*>(parent)) { - if (QFxItem *item = qobject_cast<QFxItem*>(parent)) - item->setKeyHandler(this); } QFxKeysAttached::~QFxKeysAttached() { - if (QFxItem *item = qobject_cast<QFxItem*>(parent())) - item->setKeyHandler(0); } void QFxKeysAttached::keyPressed(QKeyEvent *event) @@ -780,6 +996,8 @@ void QFxKeysAttached::keyPressed(QKeyEvent *event) if (!ke.isAccepted()) emit pressed(&ke); event->setAccepted(ke.isAccepted()); + + if (!event->isAccepted()) QFxItemKeyFilter::keyPressed(event); } void QFxKeysAttached::keyReleased(QKeyEvent *event) @@ -792,19 +1010,15 @@ void QFxKeysAttached::keyReleased(QKeyEvent *event) QFxKeyEvent ke(*event); emit released(&ke); event->setAccepted(ke.isAccepted()); + + if (!event->isAccepted()) QFxItemKeyFilter::keyReleased(event); } QFxKeysAttached *QFxKeysAttached::qmlAttachedProperties(QObject *obj) { - QFxKeysAttached *rv = attachedProperties.value(obj); - if (!rv) { - rv = new QFxKeysAttached(obj); - attachedProperties.insert(obj, rv); - } - return rv; + return new QFxKeysAttached(obj); } - /*! \qmlclass Item QFxItem \brief The Item is the most basic of all visual items in QML. @@ -1423,12 +1637,6 @@ void QFxItem::geometryChanged(const QRectF &newGeometry, } } -void QFxItem::setKeyHandler(QFxKeysAttached *handler) -{ - Q_D(QFxItem); - d->keyHandler = handler; -} - /*! \reimp */ @@ -2438,6 +2646,8 @@ QT_END_NAMESPACE QML_DECLARE_TYPE(QFxKeysAttached) QML_DEFINE_TYPE(Qt,4,6,(QT_VERSION&0x00ff00)>>8,Keys,QFxKeysAttached) +QML_DECLARE_TYPE(QFxKeyNavigationAttached) +QML_DEFINE_TYPE(Qt,4,6,(QT_VERSION&0x00ff00)>>8,KeyNavigation,QFxKeyNavigationAttached) #include "moc_qfxitem.cpp" #include "qfxitem.moc" diff --git a/src/declarative/fx/qfxitem.h b/src/declarative/fx/qfxitem.h index 89c2cf1..cb2d97a 100644 --- a/src/declarative/fx/qfxitem.h +++ b/src/declarative/fx/qfxitem.h @@ -63,7 +63,6 @@ class QmlTransition; class QFxKeyEvent; class QFxAnchors; class QFxItemPrivate; -class QFxKeysAttached; class Q_DECLARATIVE_EXPORT QFxItem : public QGraphicsObject, public QmlParserStatus { Q_OBJECT @@ -197,11 +196,8 @@ private: QFxAnchorLine verticalCenter() const; QFxAnchorLine baseline() const; - void setKeyHandler(QFxKeysAttached *); - friend class QmlStatePrivate; friend class QFxAnchors; - friend class QFxKeysAttached; Q_DISABLE_COPY(QFxItem) Q_DECLARE_PRIVATE_D(QGraphicsItem::d_ptr, QFxItem) }; diff --git a/src/declarative/fx/qfxitem_p.h b/src/declarative/fx/qfxitem_p.h index 1d4bef3..d30e324 100644 --- a/src/declarative/fx/qfxitem_p.h +++ b/src/declarative/fx/qfxitem_p.h @@ -67,7 +67,7 @@ QT_BEGIN_NAMESPACE class QNetworkReply; -class QFxKeysAttached; +class QFxItemKeyFilter; //### merge into private? class QFxContents : public QObject @@ -209,7 +209,7 @@ public: bool _keepMouse:1; bool smooth:1; - QFxKeysAttached *keyHandler; + QFxItemKeyFilter *keyHandler; qreal width; qreal height; diff --git a/src/declarative/fx/qfxlistview.cpp b/src/declarative/fx/qfxlistview.cpp index 59ece18..4b28462 100644 --- a/src/declarative/fx/qfxlistview.cpp +++ b/src/declarative/fx/qfxlistview.cpp @@ -59,7 +59,7 @@ public: attachedProperties.remove(parent()); } - Q_PROPERTY(QFxListView *view READ view) + Q_PROPERTY(QFxListView *view READ view CONSTANT) QFxListView *view() { return m_view; } Q_PROPERTY(bool isCurrentItem READ isCurrentItem NOTIFY currentItemChanged) diff --git a/src/declarative/fx/qfxpixmapcache.cpp b/src/declarative/fx/qfxpixmapcache.cpp index 0ca77c3..7fc713b 100644 --- a/src/declarative/fx/qfxpixmapcache.cpp +++ b/src/declarative/fx/qfxpixmapcache.cpp @@ -218,7 +218,6 @@ QNetworkReply *QFxPixmapCache::get(QmlEngine *engine, const QUrl& url, QPixmap * QFxSharedNetworkReplyHash::Iterator iter = qfxActiveNetworkReplies.find(key); if (iter == qfxActiveNetworkReplies.end()) { QNetworkRequest req(url); - req.setAttribute(QNetworkRequest::CacheLoadControlAttribute, QNetworkRequest::PreferCache); QSharedNetworkReply *item = new QSharedNetworkReply(engine->networkAccessManager()->get(req)); iter = qfxActiveNetworkReplies.insert(key, item); } else { diff --git a/src/declarative/fx/qfxwebview.cpp b/src/declarative/fx/qfxwebview.cpp index 347c9c2..7247837 100644 --- a/src/declarative/fx/qfxwebview.cpp +++ b/src/declarative/fx/qfxwebview.cpp @@ -333,7 +333,7 @@ void QFxWebView::setUrl(const QUrl &url) d->idealwidth>0 ? d->idealwidth : width(), d->idealheight>0 ? d->idealheight : height())); - Q_ASSERT(!url.isRelative()); + Q_ASSERT(url.isEmpty() || !url.isRelative()); if (isComponentComplete()) page()->mainFrame()->load(url); diff --git a/src/declarative/qml/qmlbindingoptimizations.cpp b/src/declarative/qml/qmlbindingoptimizations.cpp index e1f4a90..e4ca358 100644 --- a/src/declarative/qml/qmlbindingoptimizations.cpp +++ b/src/declarative/qml/qmlbindingoptimizations.cpp @@ -64,6 +64,11 @@ QmlBinding_Id::QmlBinding_Id(QObject *object, int propertyIdx, QmlAbstractExpression::setContext(context); } +QmlBinding_Id::~QmlBinding_Id() +{ + removeFromContext(); +} + void QmlBinding_Id::setEnabled(bool e) { if (e) { @@ -103,7 +108,7 @@ void QmlBinding_Id::update() } } -void QmlBinding_Id::reset() +void QmlBinding_Id::removeFromContext() { if (m_prev) { *m_prev = m_next; @@ -111,6 +116,11 @@ void QmlBinding_Id::reset() m_next = 0; m_prev = 0; } +} + +void QmlBinding_Id::reset() +{ + removeFromContext(); QObject *o = 0; void *a[] = { &o, 0 }; diff --git a/src/declarative/qml/qmlbindingoptimizations_p.h b/src/declarative/qml/qmlbindingoptimizations_p.h index 2d2ffec..ab264c7 100644 --- a/src/declarative/qml/qmlbindingoptimizations_p.h +++ b/src/declarative/qml/qmlbindingoptimizations_p.h @@ -65,7 +65,8 @@ class QmlBinding_Id : public QmlAbstractExpression, { public: QmlBinding_Id(QObject *object, int propertyIdx, - QmlContext *context, int id); + QmlContext *context, int id); + virtual ~QmlBinding_Id(); // Inherited from QmlAbstractBinding virtual void setEnabled(bool); @@ -75,6 +76,8 @@ public: void reset(); private: + void removeFromContext(); + QmlBinding_Id **m_prev; QmlBinding_Id *m_next; diff --git a/src/declarative/qml/qmlcompiler.cpp b/src/declarative/qml/qmlcompiler.cpp index 1771cb4..bbcc64d 100644 --- a/src/declarative/qml/qmlcompiler.cpp +++ b/src/declarative/qml/qmlcompiler.cpp @@ -1176,11 +1176,19 @@ bool QmlCompiler::buildProperty(QmlParser::Property *prop, } QmlType *type = 0; - QmlEnginePrivate::get(engine)->resolveType(unit->imports, prop->name, &type, 0); - // 0: attached properties not supported in QML component files - - if (!type || !type->attachedPropertiesType()) + QmlEnginePrivate::ImportedNamespace *typeNamespace = 0; + QmlEnginePrivate::get(engine)->resolveType(unit->imports, prop->name, + &type, 0, 0, 0, &typeNamespace); + + if (typeNamespace) { + // ### We might need to indicate that this property is a namespace + // for the DOM API + COMPILE_CHECK(buildPropertyInNamespace(typeNamespace, prop, obj, + ctxt)); + return true; + } else if (!type || !type->attachedPropertiesType()) { COMPILE_EXCEPTION(prop, "Non-existant attached object"); + } if (!prop->value) COMPILE_EXCEPTION(prop, "Invalid attached object assignment"); @@ -1265,6 +1273,40 @@ bool QmlCompiler::buildProperty(QmlParser::Property *prop, return true; } +bool +QmlCompiler::buildPropertyInNamespace(QmlEnginePrivate::ImportedNamespace *ns, + QmlParser::Property *nsProp, + QmlParser::Object *obj, + const BindingContext &ctxt) +{ + if (!nsProp->value) + COMPILE_EXCEPTION(nsProp, "Invalid use of namespace"); + + foreach (Property *prop, nsProp->value->properties) { + + if (!isAttachedPropertyName(prop->name)) + COMPILE_EXCEPTION(prop, "Not an attached property name"); + + // Setup attached property data + + QmlType *type = 0; + QmlEnginePrivate::get(engine)->resolveTypeInNamespace(ns, prop->name, + &type, 0, 0, 0); + + if (!type || !type->attachedPropertiesType()) + COMPILE_EXCEPTION(prop, "Non-existant attached object"); + + if (!prop->value) + COMPILE_EXCEPTION(prop, "Invalid attached object assignment"); + + Q_ASSERT(type->attachedPropertiesFunction()); + prop->index = type->index(); + prop->value->metatype = type->attachedPropertiesType(); + + COMPILE_CHECK(buildAttachedProperty(prop, obj, ctxt)); + } +} + void QmlCompiler::genValueProperty(QmlParser::Property *prop, QmlParser::Object *obj) { @@ -1407,11 +1449,19 @@ bool QmlCompiler::buildIdProperty(QmlParser::Property *prop, prop->values.at(0)->object) COMPILE_EXCEPTION(prop, "Invalid use of id property"); - QString val = prop->values.at(0)->primitive(); + QmlParser::Value *idValue = prop->values.at(0); + QString val = idValue->primitive(); if (!isValidId(val)) COMPILE_EXCEPTION(prop, val << "is not a valid object id"); + // We disallow id's that conflict with import prefixes + QmlEnginePrivate::ImportedNamespace *ns = 0; + QmlEnginePrivate::get(engine)->resolveType(unit->imports, val.toUtf8(), + 0, 0, 0, 0, &ns); + if (ns) + COMPILE_EXCEPTION(idValue, "id conflicts with namespace prefix"); + if (compileState.ids.contains(val)) COMPILE_EXCEPTION(prop, "id is not unique"); diff --git a/src/declarative/qml/qmlcompiler_p.h b/src/declarative/qml/qmlcompiler_p.h index 58279c4..c42c2d9 100644 --- a/src/declarative/qml/qmlcompiler_p.h +++ b/src/declarative/qml/qmlcompiler_p.h @@ -60,6 +60,7 @@ #include <private/qmlinstruction_p.h> #include <private/qmlcompositetypemanager_p.h> #include <private/qmlparser_p.h> +#include <private/qmlengine_p.h> QT_BEGIN_NAMESPACE @@ -165,6 +166,10 @@ private: const BindingContext &); bool buildProperty(QmlParser::Property *prop, QmlParser::Object *obj, const BindingContext &); + bool buildPropertyInNamespace(QmlEnginePrivate::ImportedNamespace *ns, + QmlParser::Property *prop, + QmlParser::Object *obj, + const BindingContext &); bool buildIdProperty(QmlParser::Property *prop, QmlParser::Object *obj); bool buildAttachedProperty(QmlParser::Property *prop, QmlParser::Object *obj, diff --git a/src/declarative/qml/qmlcompositetypemanager.cpp b/src/declarative/qml/qmlcompositetypemanager.cpp index 5bf2dc0..1b1f67c 100644 --- a/src/declarative/qml/qmlcompositetypemanager.cpp +++ b/src/declarative/qml/qmlcompositetypemanager.cpp @@ -327,26 +327,18 @@ void QmlCompositeTypeManager::compile(QmlCompositeTypeData *unit) } QUrl url; - QmlEnginePrivate::ImportedNamespace *s; - QByteArray localTypeName; - - QmlEnginePrivate::get(engine)->resolveNamespace(unit->imports, typeName, &s, &localTypeName); - if (QmlEnginePrivate::get(engine)->resolveTypeInNamespace(s, localTypeName, &ref.type, &url)) { - int majorVersion; - int minorVersion; - if (s->getTypeInfo(localTypeName, 0, &majorVersion, &minorVersion)) { - foreach (QmlParser::Object *obj, parserRef->refObjects) { - // store namespace for DOM - obj->majorVersion = majorVersion; - obj->minorVersion = minorVersion; - } - } - } else { - // try base url - url = unit->imports.baseUrl().resolved(QUrl(QLatin1String(typeName + ".qml"))); + int majorVersion; + int minorVersion; + if (!QmlEnginePrivate::get(engine)->resolveType(unit->imports, typeName, &ref.type, &url, &majorVersion, &minorVersion, 0)) { + // XXX could produce error message here. } if (ref.type) { + foreach (QmlParser::Object *obj, parserRef->refObjects) { + // store namespace for DOM + obj->majorVersion = majorVersion; + obj->minorVersion = minorVersion; + } unit->types << ref; continue; } diff --git a/src/declarative/qml/qmldom.cpp b/src/declarative/qml/qmldom.cpp index 2aaf492..9e12485 100644 --- a/src/declarative/qml/qmldom.cpp +++ b/src/declarative/qml/qmldom.cpp @@ -765,8 +765,11 @@ Text { id: MyText } */ QString QmlDomObject::objectId() const { - if (d->object) return d->object->id; - else return QByteArray(); + if (d->object) { + return d->object->id; + } else { + return QString(); + } } /*! diff --git a/src/declarative/qml/qmlengine.cpp b/src/declarative/qml/qmlengine.cpp index fd18b26..7923eda 100644 --- a/src/declarative/qml/qmlengine.cpp +++ b/src/declarative/qml/qmlengine.cpp @@ -1072,7 +1072,7 @@ void QmlObjectScriptClass::setProperty(QScriptValue &object, } -struct QmlImportedNamespacePrivate { +struct QmlEnginePrivate::ImportedNamespace { QStringList urls; QList<int> majversions; QList<int> minversions; @@ -1122,7 +1122,7 @@ struct QmlImportedNamespacePrivate { return QUrl(); } - QmlType *findBuiltin(const QByteArray& type, QByteArray* found=0) const + QmlType *findBuiltin(const QByteArray& type, int *vmajor, int *vminor) const { for (int i=0; i<urls.count(); ++i) { int vmaj = majversions.at(i); @@ -1131,7 +1131,8 @@ struct QmlImportedNamespacePrivate { qt += "/"; qt += type; QmlType *t = QmlMetaType::qmlType(qt,vmaj,vmin); - if (found) *found = qt; + if (vmajor) *vmajor = vmaj; + if (vminor) *vminor = vmin; if (t) return t; } return 0; @@ -1140,6 +1141,16 @@ struct QmlImportedNamespacePrivate { class QmlImportsPrivate { public: + QmlImportsPrivate() : ref(1) + { + } + + ~QmlImportsPrivate() + { + foreach (QmlEnginePrivate::ImportedNamespace* s, set.values()) + delete s; + } + bool add(const QUrl& base, const QString& uri, const QString& prefix, int vmaj, int vmin, QmlScriptParser::Import::Type importType, const QStringList& importPath) { QmlEnginePrivate::ImportedNamespace *s; @@ -1177,10 +1188,10 @@ public: } else { url = base.resolved(QUrl(url)).toString(); } - s->d->urls.append(url); - s->d->majversions.append(vmaj); - s->d->minversions.append(vmin); - s->d->isLibrary.append(importType == QmlScriptParser::Import::Library); + s->urls.append(url); + s->majversions.append(vmaj); + s->minversions.append(vmin); + s->isLibrary.append(importType == QmlScriptParser::Import::Library); return true; } @@ -1202,13 +1213,13 @@ public: } QString unqualifiedtype = type.mid(slash+1); if (s) - return s->d->find(unqualifiedtype); + return s->find(unqualifiedtype); else return QUrl(); } - QmlType *findBuiltin(const QByteArray& type, QByteArray* found=0) + QmlType *findBuiltin(const QByteArray& type, int *vmajor, int *vminor) { QmlEnginePrivate::ImportedNamespace *s = 0; int slash = type.indexOf('/'); @@ -1226,42 +1237,39 @@ public: } QByteArray unqualifiedtype = slash < 0 ? type : type.mid(slash+1); // common-case opt (QString::mid works fine, but slower) if (s) - return s->d->findBuiltin(unqualifiedtype,found); + return s->findBuiltin(unqualifiedtype,vmajor,vminor); else return 0; - } + } QmlEnginePrivate::ImportedNamespace *findNamespace(const QString& type) { return set.value(type); } - void resolveNamespace(const QByteArray &type, QmlEnginePrivate::ImportedNamespace **ns, QByteArray *unqualifiedType) - { - QmlEnginePrivate::ImportedNamespace *s = 0; - int slash = type.indexOf('/'); - if (slash >= 0) { - while (!s) { - s = set.value(QString::fromLatin1(type.left(slash))); - int nslash = type.indexOf('/',slash+1); - if (nslash > 0) - slash = nslash; - else - break; - } - } else { - s = &unqualifiedset; - } - - *ns = s; - *unqualifiedType = slash < 0 ? type : type.mid(slash+1); // common-case opt (QString::mid works fine, but slower) - } + QUrl base; + int ref; private: QmlEnginePrivate::ImportedNamespace unqualifiedset; QHash<QString,QmlEnginePrivate::ImportedNamespace* > set; }; +QmlEnginePrivate::Imports::Imports(const Imports ©) : + d(copy.d) +{ + ++d->ref; +} + +QmlEnginePrivate::Imports &QmlEnginePrivate::Imports::operator =(const Imports ©) +{ + ++copy.d->ref; + if (--d->ref == 0) + delete d; + d = copy.d; + return *this; +} + QmlEnginePrivate::Imports::Imports() : d(new QmlImportsPrivate) { @@ -1269,6 +1277,8 @@ QmlEnginePrivate::Imports::Imports() : QmlEnginePrivate::Imports::~Imports() { + if (--d->ref == 0) + delete d; } /*! @@ -1276,38 +1286,15 @@ QmlEnginePrivate::Imports::~Imports() */ void QmlEnginePrivate::Imports::setBaseUrl(const QUrl& url) { - base = url; -} - -QmlEnginePrivate::ImportedNamespace::ImportedNamespace() - : d(new QmlImportedNamespacePrivate) -{ -} - -QmlEnginePrivate::ImportedNamespace::~ImportedNamespace() -{ - delete d; + d->base = url; } -bool QmlEnginePrivate::ImportedNamespace::getTypeInfo(const QByteArray &typeName, QString *uri, int *majorVersion, int *minorVersion) +/*! + Returns the base URL to be used for all relative file imports added. +*/ +QUrl QmlEnginePrivate::Imports::baseUrl() const { - for (int i=0; i<d->urls.count(); ++i) { - int vmaj = d->majversions.at(i); - int vmin = d->minversions.at(i); - QByteArray qt = d->urls.at(i).toLatin1(); - qt += "/"; - qt += typeName; - if (QmlMetaType::qmlType(qt,vmaj,vmin)) { - if (uri) - *uri = d->urls.at(i); - if (majorVersion) - *majorVersion = d->majversions.at(i); - if (minorVersion) - *minorVersion = d->minversions.at(i); - return true; - } - } - return false; + return d->base; } /*! @@ -1344,7 +1331,7 @@ void QmlEngine::addImportPath(const QString& path) */ bool QmlEnginePrivate::addToImport(Imports* imports, const QString& uri, const QString& prefix, int vmaj, int vmin, QmlScriptParser::Import::Type importType) const { - bool ok = imports->d->add(imports->base,uri,prefix,vmaj,vmin,importType,fileImportPath); + bool ok = imports->d->add(imports->d->base,uri,prefix,vmaj,vmin,importType,fileImportPath); if (qmlImportTrace()) qDebug() << "QmlEngine::addToImport(" << imports << uri << prefix << vmaj << "." << vmin << (importType==QmlScriptParser::Import::Library? "Library" : "File") << ": " << ok; return ok; @@ -1362,11 +1349,21 @@ bool QmlEnginePrivate::addToImport(Imports* imports, const QString& uri, const Q \sa addToImport() */ -bool QmlEnginePrivate::resolveType(const Imports& imports, const QByteArray& type, QmlType** type_return, QUrl* url_return, ImportedNamespace** ns_return) const +bool QmlEnginePrivate::resolveType(const Imports& imports, const QByteArray& type, QmlType** type_return, QUrl* url_return, int *vmaj, int *vmin, ImportedNamespace** ns_return) const { + if (ns_return) { + *ns_return = imports.d->findNamespace(QLatin1String(type)); + if (*ns_return) + return true; + } if (type_return) { - QmlType* t = imports.d->findBuiltin(type); - if (!t) t = QmlMetaType::qmlType(type,0,0); // Try global namespace + QmlType* t = imports.d->findBuiltin(type,vmaj,vmin); + if (!t) { + // XXX do we really still need this? + t = QmlMetaType::qmlType(type,0,0); // Try global namespace + if (vmin) *vmin = 0; + if (vmaj) *vmaj = 0; + } if (t) { if (type_return) *type_return = t; if (qmlImportTrace()) @@ -1377,7 +1374,7 @@ bool QmlEnginePrivate::resolveType(const Imports& imports, const QByteArray& typ if (url_return) { QUrl url = imports.d->find(QLatin1String(type)); if (!url.isValid()) - url = imports.base.resolved(QUrl(QLatin1String(type + ".qml"))); + url = imports.d->base.resolved(QUrl(QLatin1String(type + ".qml"))); if (url.isValid()) { if (url_return) *url_return = url; @@ -1386,11 +1383,6 @@ bool QmlEnginePrivate::resolveType(const Imports& imports, const QByteArray& typ return true; } } - if (ns_return) { - *ns_return = imports.d->findNamespace(QLatin1String(type)); - if (*ns_return) - return true; - } if (qmlImportTrace()) qDebug() << "QmlEngine::resolveType" << type << " not found"; return false; @@ -1399,16 +1391,6 @@ bool QmlEnginePrivate::resolveType(const Imports& imports, const QByteArray& typ /*! \internal - Splits a fully qualified type name into the namespace and the unqualified type name. -*/ -void QmlEnginePrivate::resolveNamespace(const Imports& imports, const QByteArray &type, ImportedNamespace **ns, QByteArray *unqualifiedType) const -{ - imports.d->resolveNamespace(type, ns, unqualifiedType); -} - -/*! - \internal - Searching \e only in the namespace \a ns (previously returned in a call to resolveType(), \a type is found and returned to either a QmlType stored at \a type_return, or @@ -1416,31 +1398,14 @@ void QmlEnginePrivate::resolveNamespace(const Imports& imports, const QByteArray If either return pointer is 0, the corresponding search is not done. */ -bool QmlEnginePrivate::resolveTypeInNamespace(ImportedNamespace* ns, const QByteArray& type, QmlType** type_return, QUrl* url_return ) const +void QmlEnginePrivate::resolveTypeInNamespace(ImportedNamespace* ns, const QByteArray& type, QmlType** type_return, QUrl* url_return, int *vmaj, int *vmin ) const { - if (!ns) - return false; - if (type_return) { - QmlType* t = ns->d->findBuiltin(type); - if (!t) t = QmlMetaType::qmlType(type,0,0); // Try global namespace - if (t) { - *type_return = t; - if (qmlImportTrace()) - qDebug() << "QmlEngine::resolveTypeInNamespace" << type << "= (builtin)"; - return true; - } + *type_return = ns->findBuiltin(type,vmaj,vmin); } if (url_return) { - QUrl url = ns->d->find(QLatin1String(type)); - if (url.isValid()) { - if (url_return) *url_return = url; - if (qmlImportTrace()) - qDebug() << "QmlEngine::resolveType" << type << "=" << url; - return true; - } + *url_return = ns->find(QLatin1String(type)); } - return false; } QT_END_NAMESPACE diff --git a/src/declarative/qml/qmlengine_p.h b/src/declarative/qml/qmlengine_p.h index c84b3b5..53b2967 100644 --- a/src/declarative/qml/qmlengine_p.h +++ b/src/declarative/qml/qmlengine_p.h @@ -188,31 +188,26 @@ public: struct Imports { Imports(); ~Imports(); - void setBaseUrl(const QUrl& url); - QUrl baseUrl() const { return base; } - private: - friend class QmlEnginePrivate; - QUrl base; - QmlImportsPrivate *d; - }; + Imports(const Imports ©); + Imports &operator =(const Imports ©); - struct ImportedNamespace { - ImportedNamespace(); - ~ImportedNamespace(); + void setBaseUrl(const QUrl& url); + QUrl baseUrl() const; - bool getTypeInfo(const QByteArray &typeName, QString *uri, int *vmaj, int *vmin); private: - friend class QmlImportsPrivate; friend class QmlEnginePrivate; - class QmlImportedNamespacePrivate *d; + QmlImportsPrivate *d; }; + struct ImportedNamespace; bool addToImport(Imports*, const QString& uri, const QString& prefix, int vmaj, int vmin, QmlScriptParser::Import::Type importType) const; - - bool resolveType(const Imports&, const QByteArray& type, QmlType** type_return, QUrl* url_return, ImportedNamespace** ns_return=0) const; - - void resolveNamespace(const Imports& imports, const QByteArray &type, ImportedNamespace **s, QByteArray *unqualifiedType) const; - bool resolveTypeInNamespace(ImportedNamespace*, const QByteArray& type, QmlType** type_return, QUrl* url_return ) const; + bool resolveType(const Imports&, const QByteArray& type, + QmlType** type_return, QUrl* url_return, + int *version_major, int *version_minor, + ImportedNamespace** ns_return) const; + void resolveTypeInNamespace(ImportedNamespace*, const QByteArray& type, + QmlType** type_return, QUrl* url_return, + int *version_major, int *version_minor ) const; static QScriptValue qmlScriptObject(QObject*, QmlEngine*); @@ -224,6 +219,7 @@ public: static QmlEnginePrivate *get(QmlEngine *e) { return e->d_func(); } }; + class QmlScriptClass : public QScriptClass { public: diff --git a/src/declarative/qml/qmlmetaproperty.cpp b/src/declarative/qml/qmlmetaproperty.cpp index 99f9f0c..cc5e4ee 100644 --- a/src/declarative/qml/qmlmetaproperty.cpp +++ b/src/declarative/qml/qmlmetaproperty.cpp @@ -224,7 +224,7 @@ void QmlMetaPropertyPrivate::initProperty(QObject *obj, const QString &name) if (typeData) { QmlType *t = 0; - enginePrivate->resolveType(typeData->imports, name.toLatin1(), &t, 0); + enginePrivate->resolveType(typeData->imports, name.toLatin1(), &t, 0, 0, 0, 0); if (t && t->attachedPropertiesFunction()) { attachedFunc = t->index(); if (attachedFunc != -1) diff --git a/src/declarative/qml/qmlvaluetype.cpp b/src/declarative/qml/qmlvaluetype.cpp index 7af3c56..4ae2070 100644 --- a/src/declarative/qml/qmlvaluetype.cpp +++ b/src/declarative/qml/qmlvaluetype.cpp @@ -103,6 +103,16 @@ void QmlPointFValueType::write(QObject *obj, int idx) QMetaObject::metacall(obj, QMetaObject::WriteProperty, idx, a); } +QVariant QmlPointFValueType::value() +{ + return QVariant(point); +} + +void QmlPointFValueType::setValue(QVariant value) +{ + point = qvariant_cast<QPointF>(value); +} + qreal QmlPointFValueType::x() const { return point.x(); @@ -140,6 +150,16 @@ void QmlPointValueType::write(QObject *obj, int idx) QMetaObject::metacall(obj, QMetaObject::WriteProperty, idx, a); } +QVariant QmlPointValueType::value() +{ + return QVariant(point); +} + +void QmlPointValueType::setValue(QVariant value) +{ + point = qvariant_cast<QPoint>(value); +} + int QmlPointValueType::x() const { return point.x(); @@ -177,6 +197,16 @@ void QmlSizeFValueType::write(QObject *obj, int idx) QMetaObject::metacall(obj, QMetaObject::WriteProperty, idx, a); } +QVariant QmlSizeFValueType::value() +{ + return QVariant(size); +} + +void QmlSizeFValueType::setValue(QVariant value) +{ + size = qvariant_cast<QSizeF>(value); +} + qreal QmlSizeFValueType::width() const { return size.width(); @@ -214,6 +244,16 @@ void QmlSizeValueType::write(QObject *obj, int idx) QMetaObject::metacall(obj, QMetaObject::WriteProperty, idx, a); } +QVariant QmlSizeValueType::value() +{ + return QVariant(size); +} + +void QmlSizeValueType::setValue(QVariant value) +{ + size = qvariant_cast<QSize>(value); +} + int QmlSizeValueType::width() const { return size.width(); @@ -251,6 +291,16 @@ void QmlRectFValueType::write(QObject *obj, int idx) QMetaObject::metacall(obj, QMetaObject::WriteProperty, idx, a); } +QVariant QmlRectFValueType::value() +{ + return QVariant(rect); +} + +void QmlRectFValueType::setValue(QVariant value) +{ + rect = qvariant_cast<QRectF>(value); +} + qreal QmlRectFValueType::x() const { return rect.x(); @@ -308,6 +358,16 @@ void QmlRectValueType::write(QObject *obj, int idx) QMetaObject::metacall(obj, QMetaObject::WriteProperty, idx, a); } +QVariant QmlRectValueType::value() +{ + return QVariant(rect); +} + +void QmlRectValueType::setValue(QVariant value) +{ + rect = qvariant_cast<QRect>(value); +} + int QmlRectValueType::x() const { return rect.x(); @@ -365,6 +425,16 @@ void QmlVector3DValueType::write(QObject *obj, int idx) QMetaObject::metacall(obj, QMetaObject::WriteProperty, idx, a); } +QVariant QmlVector3DValueType::value() +{ + return QVariant(vector); +} + +void QmlVector3DValueType::setValue(QVariant value) +{ + vector = qvariant_cast<QVector3D>(value); +} + qreal QmlVector3DValueType::x() const { return vector.x(); @@ -412,6 +482,17 @@ void QmlFontValueType::write(QObject *obj, int idx) QMetaObject::metacall(obj, QMetaObject::WriteProperty, idx, a); } +QVariant QmlFontValueType::value() +{ + return QVariant(font); +} + +void QmlFontValueType::setValue(QVariant value) +{ + font = qvariant_cast<QFont>(value); +} + + QString QmlFontValueType::family() const { return font.family(); diff --git a/src/declarative/qml/qmlvaluetype_p.h b/src/declarative/qml/qmlvaluetype_p.h index 7a3620c..a56feec 100644 --- a/src/declarative/qml/qmlvaluetype_p.h +++ b/src/declarative/qml/qmlvaluetype_p.h @@ -68,6 +68,8 @@ public: QmlValueType(QObject *parent = 0); virtual void read(QObject *, int) = 0; virtual void write(QObject *, int) = 0; + virtual QVariant value() = 0; + virtual void setValue(QVariant) = 0; }; class QmlValueTypeFactory @@ -91,6 +93,8 @@ public: virtual void read(QObject *, int); virtual void write(QObject *, int); + virtual QVariant value(); + virtual void setValue(QVariant value); qreal x() const; qreal y() const; @@ -111,6 +115,8 @@ public: virtual void read(QObject *, int); virtual void write(QObject *, int); + virtual QVariant value(); + virtual void setValue(QVariant value); int x() const; int y() const; @@ -131,6 +137,8 @@ public: virtual void read(QObject *, int); virtual void write(QObject *, int); + virtual QVariant value(); + virtual void setValue(QVariant value); qreal width() const; qreal height() const; @@ -151,6 +159,8 @@ public: virtual void read(QObject *, int); virtual void write(QObject *, int); + virtual QVariant value(); + virtual void setValue(QVariant value); int width() const; int height() const; @@ -173,6 +183,8 @@ public: virtual void read(QObject *, int); virtual void write(QObject *, int); + virtual QVariant value(); + virtual void setValue(QVariant value); qreal x() const; qreal y() const; @@ -200,6 +212,8 @@ public: virtual void read(QObject *, int); virtual void write(QObject *, int); + virtual QVariant value(); + virtual void setValue(QVariant value); int x() const; int y() const; @@ -226,6 +240,8 @@ public: virtual void read(QObject *, int); virtual void write(QObject *, int); + virtual QVariant value(); + virtual void setValue(QVariant value); qreal x() const; qreal y() const; @@ -252,6 +268,8 @@ public: virtual void read(QObject *, int); virtual void write(QObject *, int); + virtual QVariant value(); + virtual void setValue(QVariant value); QString family() const; void setFamily(const QString &); diff --git a/src/declarative/util/qmlscript.cpp b/src/declarative/util/qmlscript.cpp index 0bff047..de2128d 100644 --- a/src/declarative/util/qmlscript.cpp +++ b/src/declarative/util/qmlscript.cpp @@ -151,7 +151,6 @@ void QmlScript::setSource(const QUrl &source) #endif { QNetworkRequest req(d->url); - req.setAttribute(QNetworkRequest::CacheLoadControlAttribute, QNetworkRequest::PreferCache); d->reply = qmlEngine(this)->networkAccessManager()->get(req); QObject::connect(d->reply, SIGNAL(finished()), this, SLOT(replyFinished())); diff --git a/src/declarative/util/qmlstate.h b/src/declarative/util/qmlstate.h index d15bd4a..0b48449 100644 --- a/src/declarative/util/qmlstate.h +++ b/src/declarative/util/qmlstate.h @@ -81,7 +81,7 @@ public: void deleteFromBinding(); }; -class ActionEvent +class ActionEvent { public: virtual ~ActionEvent(); @@ -126,7 +126,7 @@ class Q_DECLARATIVE_EXPORT QmlState : public QObject Q_PROPERTY(QString name READ name WRITE setName) Q_PROPERTY(QmlBinding *when READ when WRITE setWhen) - Q_PROPERTY(QString extends READ extends WRITE setExtends) + Q_PROPERTY(QString extend READ extends WRITE setExtends) Q_PROPERTY(QmlList<QmlStateOperation *>* changes READ changes) Q_CLASSINFO("DefaultProperty", "changes") @@ -137,7 +137,7 @@ public: QString name() const; void setName(const QString &); - /*'when' is a QmlBinding to limit state changes oscillation + /*'when' is a QmlBinding to limit state changes oscillation due to the unpredictable order of evaluation of bound expressions*/ bool isWhenKnown() const; QmlBinding *when() const; diff --git a/src/gui/math3d/qvector3d.cpp b/src/gui/math3d/qvector3d.cpp index 0e3f4e1..15d7e76 100644 --- a/src/gui/math3d/qvector3d.cpp +++ b/src/gui/math3d/qvector3d.cpp @@ -44,6 +44,7 @@ #include "qvector4d.h" #include <QtCore/qmath.h> #include <QtCore/qdebug.h> +#include <QtCore/qvariant.h> QT_BEGIN_NAMESPACE @@ -282,6 +283,14 @@ void QVector3D::normalize() */ /*! + Returns the vector as a QVariant +*/ +QVector3D::operator QVariant () const +{ + return QVariant(QVariant::Vector3D, this); +} + +/*! Returns the dot product of \a v1 and \a v2. */ qreal QVector3D::dotProduct(const QVector3D& v1, const QVector3D& v2) diff --git a/src/gui/math3d/qvector3d.h b/src/gui/math3d/qvector3d.h index 36292d2..b625946 100644 --- a/src/gui/math3d/qvector3d.h +++ b/src/gui/math3d/qvector3d.h @@ -95,6 +95,8 @@ public: QVector3D &operator*=(const QVector3D& vector); QVector3D &operator/=(qreal divisor); + operator QVariant() const; + static qreal dotProduct(const QVector3D& v1, const QVector3D& v2); static QVector3D crossProduct(const QVector3D& v1, const QVector3D& v2); static QVector3D normal(const QVector3D& v1, const QVector3D& v2); diff --git a/tests/auto/declarative/qmlparser/failingComponent.qml b/tests/auto/declarative/qmlparser/FailingComponent.qml index 1c01e3d..1c01e3d 100644 --- a/tests/auto/declarative/qmlparser/failingComponent.qml +++ b/tests/auto/declarative/qmlparser/FailingComponent.qml diff --git a/tests/auto/declarative/qmlparser/failingComponent.errors.txt b/tests/auto/declarative/qmlparser/failingComponent.errors.txt index 388fa76..190a649 100644 --- a/tests/auto/declarative/qmlparser/failingComponent.errors.txt +++ b/tests/auto/declarative/qmlparser/failingComponent.errors.txt @@ -1,2 +1,2 @@ --1:-1:Unable to create type FailingComponent +3:5:Unable to create type FailingComponent 4:5:Cannot assign to non-existant property "a" diff --git a/tests/auto/declarative/qmlparser/invalidID.5.errors.txt b/tests/auto/declarative/qmlparser/invalidID.5.errors.txt new file mode 100644 index 0000000..b0a63a0 --- /dev/null +++ b/tests/auto/declarative/qmlparser/invalidID.5.errors.txt @@ -0,0 +1 @@ +4:9:id conflicts with namespace prefix diff --git a/tests/auto/declarative/qmlparser/invalidID.5.qml b/tests/auto/declarative/qmlparser/invalidID.5.qml new file mode 100644 index 0000000..0545b0d --- /dev/null +++ b/tests/auto/declarative/qmlparser/invalidID.5.qml @@ -0,0 +1,6 @@ +import Test 1.0 +import Test 1.0 as Hello +MyQmlObject { + id: Hello +} + diff --git a/tests/auto/declarative/qmlparser/tst_qmlparser.cpp b/tests/auto/declarative/qmlparser/tst_qmlparser.cpp index a9c4351..3047bb0 100644 --- a/tests/auto/declarative/qmlparser/tst_qmlparser.cpp +++ b/tests/auto/declarative/qmlparser/tst_qmlparser.cpp @@ -135,6 +135,8 @@ void tst_qmlparser::errors_data() QTest::newRow("invalidID.2") << "invalidID.2.qml" << "invalidID.2.errors.txt" << false; QTest::newRow("invalidID.3") << "invalidID.3.qml" << "invalidID.3.errors.txt" << false; QTest::newRow("invalidID.4") << "invalidID.4.qml" << "invalidID.4.errors.txt" << false; + QTest::newRow("invalidID.5") << "invalidID.5.qml" << "invalidID.5.errors.txt" << false; + QTest::newRow("unsupportedProperty") << "unsupportedProperty.qml" << "unsupportedProperty.errors.txt" << false; QTest::newRow("nullDotProperty") << "nullDotProperty.qml" << "nullDotProperty.errors.txt" << true; diff --git a/tests/auto/declarative/qmlparser/unregisteredObject.errors.txt b/tests/auto/declarative/qmlparser/unregisteredObject.errors.txt index 11e4e16..bc4f7f4 100644 --- a/tests/auto/declarative/qmlparser/unregisteredObject.errors.txt +++ b/tests/auto/declarative/qmlparser/unregisteredObject.errors.txt @@ -1 +1 @@ --1:-1:Type UnregisteredObject unavailable +2:1:Type UnregisteredObject unavailable diff --git a/tools/qmlviewer/qmlviewer.cpp b/tools/qmlviewer/qmlviewer.cpp index ae61fd0..272ebcb 100644 --- a/tools/qmlviewer/qmlviewer.cpp +++ b/tools/qmlviewer/qmlviewer.cpp @@ -191,6 +191,19 @@ private: QString customargs; }; +class ConfiguredNetworkAccessManager : public QNetworkAccessManager { +public: + ConfiguredNetworkAccessManager() { } + + QNetworkReply *createRequest (Operation op, const QNetworkRequest &req, QIODevice * outgoingData) + { + QNetworkRequest request = req; + request.setAttribute(QNetworkRequest::CacheLoadControlAttribute, QNetworkRequest::PreferCache); + request.setAttribute(QNetworkRequest::HttpPipeliningAllowedAttribute, true); + return QNetworkAccessManager::createRequest(op,request,outgoingData); + } +}; + QString QmlViewer::getVideoFileName() { QString title = convertAvailable || ffmpegAvailable ? tr("Save Video File") : tr("Save PNG Frames"); @@ -240,6 +253,7 @@ QmlViewer::QmlViewer(QWidget *parent, Qt::WindowFlags flags) canvas->setAttribute(Qt::WA_OpaquePaintEvent); canvas->setAttribute(Qt::WA_NoSystemBackground); canvas->setContentResizable(!skin || !scaleSkin); + canvas->engine()->setNetworkAccessManager(new ConfiguredNetworkAccessManager); canvas->setFocus(); QObject::connect(canvas, SIGNAL(sceneResized(QSize)), this, SLOT(sceneResized(QSize))); @@ -966,7 +980,7 @@ void QmlViewer::setupProxy() else proxyFactory->unsetHttpProxy(); nam->setProxyFactory(proxyFactory); - } +} void QmlViewer::setNetworkCacheSize(int size) { |