diff options
author | Alan Alpert <alan.alpert@nokia.com> | 2010-03-23 11:29:00 (GMT) |
---|---|---|
committer | Alan Alpert <alan.alpert@nokia.com> | 2010-03-23 11:29:00 (GMT) |
commit | 56939d84ed5303dbc1b3926d1d5ae50d6512961e (patch) | |
tree | 84d3ed8ca7dacd6f57598c118e8972f592abf08a | |
parent | 90e401d350a75dfa365a8f3090514a2741f7bef6 (diff) | |
parent | 99788a16e70a36f5d1b525414829040aa808908a (diff) | |
download | Qt-56939d84ed5303dbc1b3926d1d5ae50d6512961e.zip Qt-56939d84ed5303dbc1b3926d1d5ae50d6512961e.tar.gz Qt-56939d84ed5303dbc1b3926d1d5ae50d6512961e.tar.bz2 |
Merge branch '4.7' of scm.dev.nokia.troll.no:qt/qt-qml into 4.7
Conflicts:
tests/auto/declarative/qdeclarativedom/data/importlib/sublib/qmldir
172 files changed, 3624 insertions, 3296 deletions
diff --git a/demos/declarative/flickr/flickr-desktop.qml b/demos/declarative/flickr/flickr-desktop.qml index 4de2202..63b6ea2 100644 --- a/demos/declarative/flickr/flickr-desktop.qml +++ b/demos/declarative/flickr/flickr-desktop.qml @@ -83,15 +83,17 @@ Item { Transition { from: "*"; to: "Details" SequentialAnimation { - ParentAction { } - NumberAnimation { properties: "x,y,scale,opacity,angle"; duration: 500; easing.type: "InOutQuad" } + ParentAnimation { + NumberAnimation { properties: "x,y,scale,opacity,angle"; duration: 500; easing.type: "InOutQuad" } + } } }, Transition { from: "Details"; to: "*" SequentialAnimation { - ParentAction { } - NumberAnimation { properties: "x,y,scale,opacity,angle"; duration: 500; easing.type: "InOutQuad" } + ParentAnimation { + NumberAnimation { properties: "x,y,scale,opacity,angle"; duration: 500; easing.type: "InOutQuad" } + } PropertyAction { targets: wrapper; properties: "z" } } } diff --git a/demos/declarative/flickr/mobile/GridDelegate.qml b/demos/declarative/flickr/mobile/GridDelegate.qml index 767315c..b54585b 100644 --- a/demos/declarative/flickr/mobile/GridDelegate.qml +++ b/demos/declarative/flickr/mobile/GridDelegate.qml @@ -52,14 +52,16 @@ transitions: [ Transition { from: "Show"; to: "Details" - ParentAction { } - NumberAnimation { properties: "x,y"; duration: 500; easing.type: "InOutQuad" } + ParentAnimation { + NumberAnimation { properties: "x,y"; duration: 500; easing.type: "InOutQuad" } + } }, Transition { from: "Details"; to: "Show" SequentialAnimation { - ParentAction { } - NumberAnimation { properties: "x,y"; duration: 500; easing.type: "InOutQuad" } + ParentAnimation { + NumberAnimation { properties: "x,y"; duration: 500; easing.type: "InOutQuad" } + } PropertyAction { targets: wrapper; properties: "z" } } } diff --git a/demos/declarative/photoviewer/PhotoViewerCore/AlbumDelegate.qml b/demos/declarative/photoviewer/PhotoViewerCore/AlbumDelegate.qml index fca7232..fb68cfc 100644 --- a/demos/declarative/photoviewer/PhotoViewerCore/AlbumDelegate.qml +++ b/demos/declarative/photoviewer/PhotoViewerCore/AlbumDelegate.qml @@ -25,8 +25,7 @@ Component { Item { Package.name: 'album' - id: albumWrapper - width: 210; height: 220 + id: albumWrapper; width: 210; height: 220 VisualDataModel { id: visualModel; delegate: PhotoDelegate { } @@ -34,13 +33,15 @@ Component { } BusyIndicator { + id: busyIndicator anchors { centerIn: parent; verticalCenterOffset: -20 } on: rssModel.status != XmlListModel.Ready } PathView { id: photosPathView; model: visualModel.parts.stack; pathItemCount: 5 - anchors.centerIn: parent; anchors.verticalCenterOffset: -20 + visible: !busyIndicator.visible + anchors.centerIn: parent; anchors.verticalCenterOffset: -30 path: Path { PathAttribute { name: 'z'; value: 9999.0 } PathLine { x: 1; y: 1 } @@ -48,21 +49,16 @@ Component { } } - Tag { - anchors.horizontalCenter: parent.horizontalCenter; anchors.bottom: parent.bottom - frontLabel: tag; backLabel: "Delete"; rotation: Math.random() * (2 * 6 + 1) - 6 - flipped: mainWindow.editMode - } - MouseArea { anchors.fill: parent - onClicked: { - if (mainWindow.editMode) { - photosModel.remove(index) - } else { - albumWrapper.state = 'inGrid' - } - } + onClicked: mainWindow.editMode ? photosModel.remove(index) : albumWrapper.state = 'inGrid' + } + + Tag { + anchors { horizontalCenter: parent.horizontalCenter; bottom: parent.bottom; bottomMargin: 10 } + frontLabel: tag; backLabel: "Delete"; flipped: mainWindow.editMode + onTagChanged: rssModel.tags = tag + onBackClicked: if (mainWindow.editMode) photosModel.remove(index); } states: [ @@ -77,10 +73,17 @@ Component { PropertyChanges { target: photosGridView; interactive: false } PropertyChanges { target: photosListView; interactive: true } PropertyChanges { target: photosShade; opacity: 1 } - PropertyChanges { target: backButton; y: -backTag.height - 8 } + PropertyChanges { target: backButton; y: -backButton.height - 8 } } ] + GridView.onAdd: NumberAnimation { target: albumWrapper; properties: "scale"; from: 0.0; to: 1.0 } + GridView.onRemove: SequentialAnimation { + PropertyAction { target: albumWrapper.GridView; property: "delayRemove"; value: true } + NumberAnimation { target: albumWrapper; property: "scale"; from: 1.0; to: 0.0 } + PropertyAction { target: albumWrapper.GridView; property: "delayRemove"; value: false } + } + transitions: [ Transition { from: '*'; to: 'inGrid' diff --git a/demos/declarative/photoviewer/PhotoViewerCore/Button.qml b/demos/declarative/photoviewer/PhotoViewerCore/Button.qml index fb28314..cdf86af 100644 --- a/demos/declarative/photoviewer/PhotoViewerCore/Button.qml +++ b/demos/declarative/photoviewer/PhotoViewerCore/Button.qml @@ -4,6 +4,7 @@ Item { id: container property alias label: labelText.text + property string tint: "" signal clicked width: labelText.width + 70 ; height: labelText.height + 18 @@ -16,6 +17,11 @@ Item { Image { anchors.fill: parent; source: "images/cardboard.png"; smooth: true } + Rectangle { + anchors.fill: container; color: container.tint; visible: container.tint != "" + opacity: 0.1; smooth: true + } + Text { id: labelText; font.pixelSize: 15; anchors.centerIn: parent; smooth: true } MouseArea { diff --git a/demos/declarative/photoviewer/PhotoViewerCore/EditableButton.qml b/demos/declarative/photoviewer/PhotoViewerCore/EditableButton.qml new file mode 100644 index 0000000..5ea79a1 --- /dev/null +++ b/demos/declarative/photoviewer/PhotoViewerCore/EditableButton.qml @@ -0,0 +1,53 @@ +import Qt 4.6 + +Item { + id: container + + property string label + property string tint: "" + signal clicked + signal labelChanged(string label) + + width: labelText.width + 70 ; height: labelText.height + 18 + + BorderImage { + anchors { fill: container; leftMargin: -6; topMargin: -6; rightMargin: -8; bottomMargin: -8 } + source: 'images/box-shadow.png'; smooth: true + border.left: 10; border.top: 10; border.right: 10; border.bottom: 10 + } + + Image { anchors.fill: parent; source: "images/cardboard.png"; smooth: true } + + Rectangle { + anchors.fill: container; color: container.tint; visible: container.tint != "" + opacity: 0.1; smooth: true + } + + Text { id: labelText; text: label; font.pixelSize: 15; anchors.centerIn: parent; smooth: true } + + TextInput { + id: textInput; text: label; font.pixelSize: 15; anchors.centerIn: parent; smooth: true; visible: false + Keys.onReturnPressed: container.labelChanged(textInput.text) + Keys.onEscapePressed: { + textInput.text = labelText.text + container.state = '' + } + } + + MouseArea { + anchors { fill: parent; leftMargin: -20; topMargin: -20; rightMargin: -20; bottomMargin: -20 } + onClicked: container.state = "editMode" + } + + states: State { + name: "editMode" + PropertyChanges { target: container; width: textInput.width + 70; height: textInput.height + 17 } + PropertyChanges { target: textInput; visible: true; focus: true } + PropertyChanges { target: labelText; visible: false } + } + + onLabelChanged: { + labelText.text = label + container.state = '' + } +} diff --git a/demos/declarative/photoviewer/PhotoViewerCore/PhotoDelegate.qml b/demos/declarative/photoviewer/PhotoViewerCore/PhotoDelegate.qml index ab36122..107aff1 100644 --- a/demos/declarative/photoviewer/PhotoViewerCore/PhotoDelegate.qml +++ b/demos/declarative/photoviewer/PhotoViewerCore/PhotoDelegate.qml @@ -33,8 +33,12 @@ Package { property int h: Script.getHeight(content) property double s: Script.calculateScale(w, h, photoWrapper.width) - color: '#878787'; anchors.centerIn: parent; smooth: true; border.color: 'white'; border.width: 3 + color: 'white'; anchors.centerIn: parent; smooth: true width: w * s; height: h * s; visible: originalImage.status != Image.Ready + Rectangle { + color: "#878787"; smooth: true + anchors { fill: parent; topMargin: 3; bottomMargin: 3; leftMargin: 3; rightMargin: 3 } + } } Rectangle { id: border; color: 'white'; anchors.centerIn: parent; smooth: true diff --git a/demos/declarative/photoviewer/PhotoViewerCore/Tag.qml b/demos/declarative/photoviewer/PhotoViewerCore/Tag.qml index d32fcd0..bf02fac 100644 --- a/demos/declarative/photoviewer/PhotoViewerCore/Tag.qml +++ b/demos/declarative/photoviewer/PhotoViewerCore/Tag.qml @@ -7,18 +7,23 @@ Flipable { property alias backLabel: backButton.label property int angle: 0 + property int randomAngle: Math.random() * (2 * 6 + 1) - 6 property bool flipped: false signal frontClicked signal backClicked + signal tagChanged(string tag) - front: Button { - id: frontButton; anchors.centerIn: parent; anchors.verticalCenterOffset: -20 + front: EditableButton { + id: frontButton; rotation: flipable.randomAngle + anchors { centerIn: parent; verticalCenterOffset: -20 } onClicked: flipable.frontClicked() + onLabelChanged: flipable.tagChanged(label) } back: Button { - id: backButton; anchors.centerIn: parent; anchors.verticalCenterOffset: -20 + id: backButton; tint: "red"; rotation: flipable.randomAngle + anchors { centerIn: parent; verticalCenterOffset: -20 } onClicked: flipable.backClicked() } diff --git a/demos/declarative/photoviewer/PhotoViewerCore/qmldir b/demos/declarative/photoviewer/PhotoViewerCore/qmldir index f94a560..d3c247f 100644 --- a/demos/declarative/photoviewer/PhotoViewerCore/qmldir +++ b/demos/declarative/photoviewer/PhotoViewerCore/qmldir @@ -2,6 +2,7 @@ AlbumDelegate AlbumDelegate.qml PhotoDelegate PhotoDelegate.qml ProgressBar ProgressBar.qml RssModel RssModel.qml +BusyIndicator BusyIndicator.qml +EditableButton EditableButton.qml Button Button.qml Tag Tag.qml -BusyIndicator BusyIndicator.qml diff --git a/demos/declarative/photoviewer/photoviewer.qml b/demos/declarative/photoviewer/photoviewer.qml index 5e4be4c..8feee02 100644 --- a/demos/declarative/photoviewer/photoviewer.qml +++ b/demos/declarative/photoviewer/photoviewer.qml @@ -13,8 +13,8 @@ Rectangle { ListModel { id: photosModel ListElement { tag: "Flowers" } - ListElement { tag: "Savanna" } - ListElement { tag: "Central Park" } + ListElement { tag: "Wildlife" } + ListElement { tag: "Prague" } } VisualDataModel { id: albumVisualModel; model: photosModel; delegate: AlbumDelegate {} } @@ -26,14 +26,20 @@ Rectangle { Column { spacing: 20; anchors { bottom: parent.bottom; right: parent.right; rightMargin: 20; bottomMargin: 20 } - Button { id: deleteButton; label: "Edit"; rotation: -2; onClicked: mainWindow.editMode = !mainWindow.editMode } Button { id: newButton; label: "New"; rotation: 3 + anchors.horizontalCenter: parent.horizontalCenter onClicked: { + mainWindow.editMode = false photosModel.append( { tag: "" } ) albumView.positionViewAtIndex(albumView.count - 1, GridView.Contain) } } + Button { + id: deleteButton; label: "Delete"; rotation: -2; + onClicked: mainWindow.editMode = !mainWindow.editMode + anchors.horizontalCenter: parent.horizontalCenter + } } Rectangle { diff --git a/demos/embedded/fluidlauncher/fluidlauncher.pro b/demos/embedded/fluidlauncher/fluidlauncher.pro index b2916d7..13274c3 100644 --- a/demos/embedded/fluidlauncher/fluidlauncher.pro +++ b/demos/embedded/fluidlauncher/fluidlauncher.pro @@ -180,10 +180,12 @@ symbian { mifs.sources += \ $$appResourceDir(demos/embedded/anomaly/anomaly.mif) - # Since Fluidlauncher itself doesn't link webkit, we won't get dependency automatically - executables.pkg_prerules += \ - "; Dependency to Qt Webkit" \ - "(0x200267C2), $${QT_MAJOR_VERSION}, $${QT_MINOR_VERSION}, $${QT_PATCH_VERSION}, {\"QtWebKit\"}" + isEmpty(QT_LIBINFIX) { + # Since Fluidlauncher itself doesn't link webkit, we won't get dependency automatically + executables.pkg_prerules += \ + "; Dependency to Qt Webkit" \ + "(0x200267C2), $${QT_MAJOR_VERSION}, $${QT_MINOR_VERSION}, $${QT_PATCH_VERSION}, {\"QtWebKit\"}" + } } contains(QT_CONFIG, phonon) { diff --git a/doc/src/declarative/declarativeui.qdoc b/doc/src/declarative/declarativeui.qdoc index ed63367..ca4c5da 100644 --- a/doc/src/declarative/declarativeui.qdoc +++ b/doc/src/declarative/declarativeui.qdoc @@ -83,7 +83,7 @@ completely new applications. QML is fully \l {Extending QML in C++}{extensible \list \o \l {QML Documents} \o \l {Property Binding} -\o \l {JavaScript Blocks} +\o \l {Integrating JavaScript} \o \l {QML Scope} \o \l {Network Transparency} \o \l {Data Models} diff --git a/doc/src/declarative/elements.qdoc b/doc/src/declarative/elements.qdoc index 75f8b97..e35d67c 100644 --- a/doc/src/declarative/elements.qdoc +++ b/doc/src/declarative/elements.qdoc @@ -78,7 +78,6 @@ The following table lists the QML elements provided by the Qt Declarative module \o \l ParentAnimation \o \l AnchorAnimation \o \l PropertyAction -\o \l ParentAction \o \l ScriptAction \o \l Transition \o \l SpringFollow diff --git a/doc/src/declarative/example-slideswitch.qdoc b/doc/src/declarative/example-slideswitch.qdoc index 42351c5..c14208e 100644 --- a/doc/src/declarative/example-slideswitch.qdoc +++ b/doc/src/declarative/example-slideswitch.qdoc @@ -121,7 +121,7 @@ states (\e on and \e off). This second function is called when the knob is released and we want to make sure that the knob does not end up between states (neither \e on nor \e off). If it is the case call the \c toggle() function otherwise we do nothing. -For more information on scripts see \l{qdeclarativejavascript.html}{JavaScript Blocks}. +For more information on scripts see \l{Integrating JavaScript}. \section2 Transition \snippet examples/declarative/slideswitch/content/Switch.qml 7 diff --git a/doc/src/declarative/javascriptblocks.qdoc b/doc/src/declarative/javascriptblocks.qdoc index 98183bb..0006967 100644 --- a/doc/src/declarative/javascriptblocks.qdoc +++ b/doc/src/declarative/javascriptblocks.qdoc @@ -41,95 +41,123 @@ /*! \page qdeclarativejavascript.html -\title JavaScript Blocks +\title Integrating JavaScript QML encourages building UIs declaratively, using \l {Property Binding} and the -composition of existing \l {QML Elements}. If imperative code is required to implement -more advanced behavior, the \l Script element can be used to add JavaScript code directly -to a QML file, or to include an external JavaScript file. +composition of existing \l {QML Elements}. To allow the implementation of more +advanced behavior, QML integrates tightly with imperative JavaScript code. -The \l Script element is a QML language \e intrinsic. It can be used anywhere in a -QML file, \e except as the root element of a file or sub-component, but cannot be -assigned to an object property or given an id. The included JavaScript is evaluated -in a scope chain. The \l {QML Scope} documentation covers the specifics of scoping -in QML. +The JavaScript environment provided by QML is stricter than that in a webbrowser. +In QML you cannot add, or modify, members of the JavaScript global object. It +is possible to do this accidentally by using a variable without declaring it. In +QML this will throw an exception, so all local variables should be explicitly +declared. -A restriction on the JavaScript used in QML is that you cannot add new members to the -global object. This happens transparently when you try to use a variable without -declaring it, and so declaring local variables is required when using Java script in -QML. +In addition to the standard JavaScript properties, the \l {QML Global Object} +includes a number of helper methods that simplify building UIs and interacting +with the QML environment. -The global object in QML has a variety of helper functions added to it, to aid UI -implementation. See \l{QML Global Object} for further details. +\section1 Inline JavaScript -Note that if you are adding a function that should be called by external elements, -you do not need the \l Script element. See \l {Extending types from QML#Adding new methods} -{Adding new methods} for information about adding slots that can be called externally. - -\section1 Inline Script - -Small blocks of JavaScript can be included directly inside a \l {QML Document} as -the body of the \l Script element. +Small JavaScript functions can be written inline with other QML declarations. +These inline functions are added as methods to the QML element that contains +them. \code -Rectangle { - Script { - function factorial(a) { - a = Integer(a); - if (a <= 0) - return 1; - else - return a * factorial(a - 1); - } +Item { + function factorial(a) { + a = Integer(a); + if (a <= 0) + return 1; + else + return a * factorial(a - 1); + } + + MouseRegion { + anchors.fill: parent + onClicked: print(factorial(10)) } } \endcode -Good programming practice dictates that only small script snippets should be written -inline. QML prohibits the declaration of anything other than functions in an inline -script block. For example, the following script is illegal as an inline script block -as it declares the non-function variable \c lastResult. +As methods, inline functions on the root element in a QML component can be +invoked by callers outside the component. If this is not desired, the method +can be added to a non-root element or, preferably, written in an external +JavaScript file. + +\section1 Separate JavaScript files + +Large blocks of JavaScript should be written in separate files. Like element +types, external JavaScript files are \c {import}'ed into QML files. + +The \c {factorial()} method used in the \l {Inline JavaScript} section could +be refactored into an external file, and accessed like this. \code -// Illegal inline code block -var lastResult = 0 -function factorial(a) { - a = Integer(a); - if (a <= 0) - lastResult = 1; - else - lastResult = a * factorial(a - 1); - return lastResult; +import "factorial.js" as MathFunctions +Item { + MouseRegion { + anchors.fill: parent + onClicked: print(MathFunctions.factorial(10)) + } } \endcode -\section1 Including an External File +Both relative and absolute JavaScript URLs can be imported. In the case of a +relative URL, the location is resolved relative to the location of the +\l {QML Document} that contains the import. If the script file is not accessible, +an error will occur. If the JavaScript needs to be fetched from a network +resource, the QML document will remain in the +\l {QDeclarativeComponent::status()}{waiting state} until the script has been +downloaded. -To avoid cluttering the QML file, large script blocks should be in a separate file. -The \l Script element's \c source property is used to load script from an external -file. +Imported JavaScript files are always qualified using the "as" keyword. The +qualifier for JavaScript files must be unique, so there is always a one-to-one +mapping between qualifiers and JavaScript files. -If the previous factorial code that was illegal as an inline script block was saved -into a "factorial.js" file, it could be included like this. +\section2 Code-Behind Implementation Files + +Most JavaScript files imported into a QML file are stateful, logic implementations +for the QML file importing them. In these cases, for QML component instances to +behave correctly each instance requires a separate copy of the JavaScript objects +and state. + +The default behavior when importing JavaScript files is to provide a unique, isolated +copy for each QML component instance. The code runs in the same scope as the QML +component instance and consequently can can access and manipulate the objects and +properties declared. + +\section2 Stateless JavaScript libraries + +Some JavaScript files act more like libraries - they provide a set of stateless +helper functions that take input and compute output, but never manipulate QML +component instances directly. + +As it would be wasteful for each QML component instance to have a unique copy of +these libraries, the JavaScript programmer can indicate a particular file is a +stateless library through the use of a pragma, as shown in the following example. \code -Rectangle { - Script { - source: "factorial.js" - } +.pragma library + +function factorial(a) { + a = Integer(a); + if (a <= 0) + return 1; + else + return a * factorial(a - 1); } \endcode -The \c source property may reference a relative file, or an absolute path. In the -case of a relative file, the location is resolved relative to the location of the -\l {QML Document} that contains the \l Script element. If the script file is not -accessible, an error will occur. If the source is on a network resource, the -enclosing QML document will remain in the \l {QDeclarativeComponent::status()}{waiting state} -until the script has been retrieved. +The pragma declaration must appear before any JavaScript code excluding comments. + +As they are shared, stateless library files cannot access QML component instance +objects or properties directly, although QML values can be passed as function +parameters. -\section1 Running Script at Startup +\section1 Running JavaScript at Startup -It is occasionally necessary to run a block of JavaScript code at application (or +It is occasionally necessary to run some imperative code at application (or component instance) "startup". While it is tempting to just include the startup script as \e {global code} in an external script file, this can have severe limitations as the QML environment may not have been fully established. For example, some objects @@ -144,10 +172,8 @@ The following QML code shows how to use the \c Component::onCompleted property. \code Rectangle { - Script { - function startupFunction() { - // ... startup code - } + function startupFunction() { + // ... startup code } Component.onCompleted: startupFunction(); @@ -155,21 +181,20 @@ Rectangle { \endcode Any element in a QML file - including nested elements and nested QML component -instances - can use this attached property. If there is more than one script to -execute at startup, they are run sequentially in an undefined order. +instances - can use this attached property. If there is more than one onCompleted +handler to execute at startup, they are run sequentially in an undefined order. -\section1 QML Script Restrictions +\section1 QML JavaScript Restrictions -QML \l Script blocks contain standard JavaScript code. QML introduces the following -restrictions. +QML executes standard JavaScript code, with the following restrictions: \list -\o Script code cannot modify the global object. +\o JavaScript code cannot modify the global object. In QML, the global object is constant - existing properties cannot be modified or deleted, and no new properties may be created. -Most JavaScript programs do not explicitly modify the global object. However, +Most JavaScript programs do not intentionally modify the global object. However, JavaScript's automatic creation of undeclared variables is an implicit modification of the global object, and is prohibited in QML. @@ -197,7 +222,7 @@ that includes the file and line number of the offending code. \o Global code is run in a reduced scope -During startup, if a \l Script block includes an external file with "global" +During startup, if a QML file includes an external JavaScript file with "global" code, it is executed in a scope that contains only the external file itself and the global object. That is, it will not have access to the QML objects and properties it \l {QML Scope}{normally would}. diff --git a/doc/src/declarative/propertybinding.qdoc b/doc/src/declarative/propertybinding.qdoc index 5d21fd1..02f9868 100644 --- a/doc/src/declarative/propertybinding.qdoc +++ b/doc/src/declarative/propertybinding.qdoc @@ -67,10 +67,8 @@ expression! Here are some examples of more complex bindings: \code Rectangle { - Script { - function calculateMyHeight() { - return Math.max(otherItem.height, thirdItem.height); - } + function calculateMyHeight() { + return Math.max(otherItem.height, thirdItem.height); } anchors.centerIn: parent diff --git a/doc/src/declarative/qdeclarativereference.qdoc b/doc/src/declarative/qdeclarativereference.qdoc index 01af7f5..b2cfba8 100644 --- a/doc/src/declarative/qdeclarativereference.qdoc +++ b/doc/src/declarative/qdeclarativereference.qdoc @@ -74,7 +74,7 @@ \list \o \l {QML Documents} \o \l {Property Binding} - \o \l {JavaScript Blocks} + \o \l {Integrating JavaScript} \o \l {QML Scope} \o \l {Network Transparency} \o \l {qmlmodels}{Data Models} diff --git a/doc/src/declarative/qtbinding.qdoc b/doc/src/declarative/qtbinding.qdoc index 66d537d..577e69a 100644 --- a/doc/src/declarative/qtbinding.qdoc +++ b/doc/src/declarative/qtbinding.qdoc @@ -90,9 +90,8 @@ the root context is available to all object instances. \section1 Simple Data To expose data to a QML component instance, applications set \l {QDeclarativeContext::setContextProperty()} -{context properties} which are then accessible by name from QML \l {Property Binding}s and -\l {JavaScript Blocks}. The following example shows how to expose a background color to a QML -file. +{context properties} which are then accessible by name from QML \l {Property Binding}s and JavaScript. +The following example shows how to expose a background color to a QML file. \table \row diff --git a/doc/src/declarative/scope.qdoc b/doc/src/declarative/scope.qdoc index 218af89..8ec784f 100644 --- a/doc/src/declarative/scope.qdoc +++ b/doc/src/declarative/scope.qdoc @@ -45,8 +45,10 @@ \tableofcontents -\l {Property Binding}s and \l {JavaScript Blocks} are executed in a scope chain automatically -established by QML when a component instance is constructed. QML is a \e {dynamically scoped} +NOTE: This documentation is out of data. + +\l {Property Binding}s and \l {Integrating JavaScript}{JavaScript} are executed in a scope chain +automatically established by QML when a component instance is constructed. QML is a \e {dynamically scoped} language. Different object instances instantiated from the same component can exist in different scope chains. diff --git a/examples/declarative/webview/content/Mapping/Map.qml b/examples/declarative/webview/content/Mapping/Map.qml index 6c3b021..38c42dd 100644 --- a/examples/declarative/webview/content/Mapping/Map.qml +++ b/examples/declarative/webview/content/Mapping/Map.qml @@ -6,16 +6,21 @@ Item { property real latitude: -34.397 property real longitude: 150.644 property string address: "" + property alias status: js.status WebView { id: map anchors.fill: parent url: "map.html" javaScriptWindowObjects: QtObject { + id: js WebView.windowObjectName: "qml" property real lat: page.latitude property real lng: page.longitude property string address: page.address - onAddressChanged: {map.evaluateJavaScript("goToAddress()")} + property string status: "Loading" + onAddressChanged: { if (map.url != "" && map.progress==1) map.evaluateJavaScript("goToAddress()") } } + pressGrabTime: 0 + onLoadFinished: { evaluateJavaScript("goToAddress()"); } } } diff --git a/examples/declarative/webview/content/Mapping/map.html b/examples/declarative/webview/content/Mapping/map.html index 72f426a..a8726fd 100755 --- a/examples/declarative/webview/content/Mapping/map.html +++ b/examples/declarative/webview/content/Mapping/map.html @@ -33,9 +33,14 @@ } if (map) req.bounds = map.getBounds() + window.qml.status = "Loading"; geocoder.geocode(req, function(results, status) { - if (status == google.maps.GeocoderStatus.OK) + if (status == google.maps.GeocoderStatus.OK) { + window.qml.status = "Ready"; goToLatLng(results[0].geometry.location,results[0].geometry.bounds); + } else { + window.qml.status = "Error"; + } }); } } diff --git a/examples/declarative/webview/googleMaps.qml b/examples/declarative/webview/googleMaps.qml index a04fecb..a0926f5 100644 --- a/examples/declarative/webview/googleMaps.qml +++ b/examples/declarative/webview/googleMaps.qml @@ -21,6 +21,7 @@ Map { radius: 5 anchors.bottom: parent.bottom anchors.bottomMargin: 5 + opacity: map.status == "Ready" ? 1 : 0 x: 70 TextInput { id: input @@ -29,4 +30,12 @@ Map { Keys.onReturnPressed: map.address = input.text } } + Text { + id: loading + anchors.centerIn: parent + text: map.status == "Error" ? "Error" : "Loading" + opacity: map.status == "Ready" ? 0 : 1 + font.pixelSize: 30 + Behavior on opacity {NumberAnimation{}} + } } diff --git a/mkspecs/common/symbian/symbian.conf b/mkspecs/common/symbian/symbian.conf index 4dd81b0..090f3b6 100644 --- a/mkspecs/common/symbian/symbian.conf +++ b/mkspecs/common/symbian/symbian.conf @@ -71,12 +71,16 @@ QMAKE_LIBS_GUI = $$QMAKE_LIBS_CORE -lfbscli -lbitgdi -lhal -lgdi -lws32 QMAKE_LIBS_NETWORK = QMAKE_LIBS_EGL = -llibEGL QMAKE_LIBS_OPENGL = -QMAKE_LIBS_OPENVG = -llibOpenVG -lgraphicsresource -lfbscli -lbitgdi -lgdi +QMAKE_LIBS_OPENVG = -llibOpenVG -lfbscli -lbitgdi -lgdi QMAKE_LIBS_THREAD = -llibpthread QMAKE_LIBS_COMPAT = QMAKE_LIBS_QT_ENTRY = -llibcrt0.lib QMAKE_LIBS_S60 = -lavkon +exists($${EPOCROOT}epoc32/include/platform/sgresource/sgimage.h) { + QMAKE_LIBS_OPENVG += -lsgresource +} + contains(QMAKE_HOST.os,Windows) { QMAKE_COPY = copy /y QMAKE_COPY_DIR = xcopy /s /q /y /i diff --git a/mkspecs/features/symbian/data_caging_paths.prf b/mkspecs/features/symbian/data_caging_paths.prf index 3ed5661..6f40bb5 100644 --- a/mkspecs/features/symbian/data_caging_paths.prf +++ b/mkspecs/features/symbian/data_caging_paths.prf @@ -74,7 +74,7 @@ exists($${EPOCROOT}epoc32/include/data_caging_paths.prf) { BOOTDATA_DIR = /resource/bootdata } -isEmpty(QT_PLUGINS_BASE_DIR): QT_PLUGINS_BASE_DIR = /$$RESOURCE_FILES_DIR/qt/plugins +isEmpty(QT_PLUGINS_BASE_DIR): QT_PLUGINS_BASE_DIR = /$$RESOURCE_FILES_DIR/qt$${QT_LIBINFIX}/plugins isEmpty(HW_ZDIR): HW_ZDIR = epoc32/data/z isEmpty(REG_RESOURCE_DIR): REG_RESOURCE_DIR = /private/10003a3f/apps isEmpty(REG_RESOURCE_IMPORT_DIR): REG_RESOURCE_IMPORT_DIR = /private/10003a3f/import/apps
\ No newline at end of file diff --git a/mkspecs/features/symbian/default_post.prf b/mkspecs/features/symbian/default_post.prf index d29e460..0564e9b 100644 --- a/mkspecs/features/symbian/default_post.prf +++ b/mkspecs/features/symbian/default_post.prf @@ -5,7 +5,7 @@ contains(TEMPLATE, ".*app") { QMAKE_LIBS += } else:contains(QT, gui):contains(CONFIG,qt) { S60MAIN_LIBS = -leuser - QMAKE_LIBS += -lqtmain.lib $$S60MAIN_LIBS + QMAKE_LIBS += -lqtmain$${QT_LIBINFIX}.lib $$S60MAIN_LIBS } else { QMAKE_LIBS += $$QMAKE_LIBS_QT_ENTRY } diff --git a/mkspecs/features/symbian/qt.prf b/mkspecs/features/symbian/qt.prf index 294a68c..2dc614f 100644 --- a/mkspecs/features/symbian/qt.prf +++ b/mkspecs/features/symbian/qt.prf @@ -24,7 +24,7 @@ INCLUDEPATH = $$PREPEND_INCLUDEPATH $$INCLUDEPATH # Add dependency to Qt package to all other projects besides Qt libs. # Note: Qt libs with full capabilities has UID3 of 0x2001E61C, # while self-signed version typically has temporary UID3 of 0xE001E61C. -contains(CONFIG, qt):!contains(TARGET.UID3, 0x2001E61C):!contains(TARGET.UID3, 0xE001E61C) { +contains(CONFIG, qt):!contains(TARGET.UID3, 0x2001E61C):!contains(TARGET.UID3, 0xE001E61C):isEmpty(QT_LIBINFIX) { default_deployment.pkg_prerules += \ "; Default dependency to Qt libraries" \ "(0x2001E61C), $${QT_MAJOR_VERSION}, $${QT_MINOR_VERSION}, $${QT_PATCH_VERSION}, {\"Qt\"}" @@ -43,5 +43,5 @@ isEmpty(TARGET.EPOCHEAPSIZE):TARGET.EPOCHEAPSIZE = 0x020000 0x800000 # Workaround for the fact that Gnupoc and Symbian chose different approaches to # the letter casing of headers. contains(CONFIG, is_using_gnupoc) { - INCLUDEPATH += $$QT_SOURCE_TREE/mkspecs/common/symbian/header-wrappers + INCLUDEPATH += $$[QT_INSTALL_PREFIX]/mkspecs/common/symbian/header-wrappers } diff --git a/src/3rdparty/phonon/mmf/abstractaudioeffect.cpp b/src/3rdparty/phonon/mmf/abstractaudioeffect.cpp index 132eb79..6cfeb76 100644 --- a/src/3rdparty/phonon/mmf/abstractaudioeffect.cpp +++ b/src/3rdparty/phonon/mmf/abstractaudioeffect.cpp @@ -20,7 +20,6 @@ along with this library. If not, see <http://www.gnu.org/licenses/>. #include "abstractaudioeffect.h" #include "audioplayer.h" -#include "mmf_videoplayer.h" QT_BEGIN_NAMESPACE diff --git a/src/3rdparty/phonon/mmf/abstractaudioeffect.h b/src/3rdparty/phonon/mmf/abstractaudioeffect.h index 436e8e4..d71993b 100644 --- a/src/3rdparty/phonon/mmf/abstractaudioeffect.h +++ b/src/3rdparty/phonon/mmf/abstractaudioeffect.h @@ -28,7 +28,6 @@ along with this library. If not, see <http://www.gnu.org/licenses/>. #include "audioplayer.h" #include "effectparameter.h" #include "mmf_medianode.h" -#include "mmf_videoplayer.h" class CMdaAudioOutputStream; diff --git a/src/3rdparty/phonon/mmf/abstractplayer.cpp b/src/3rdparty/phonon/mmf/abstractplayer.cpp index 53973eb..421155b 100644 --- a/src/3rdparty/phonon/mmf/abstractplayer.cpp +++ b/src/3rdparty/phonon/mmf/abstractplayer.cpp @@ -96,7 +96,7 @@ void MMF::AbstractPlayer::volumeChanged(qreal volume) // Video output //----------------------------------------------------------------------------- -void MMF::AbstractPlayer::setVideoOutput(VideoOutput* videoOutput) +void MMF::AbstractPlayer::setVideoOutput(AbstractVideoOutput* videoOutput) { m_videoOutput = videoOutput; videoOutputChanged(); diff --git a/src/3rdparty/phonon/mmf/abstractplayer.h b/src/3rdparty/phonon/mmf/abstractplayer.h index cec5568..92bd87e 100644 --- a/src/3rdparty/phonon/mmf/abstractplayer.h +++ b/src/3rdparty/phonon/mmf/abstractplayer.h @@ -24,7 +24,7 @@ along with this library. If not, see <http://www.gnu.org/licenses/>. #include <QObject> -#include "videooutput.h" +#include "abstractvideooutput.h" class RFile; @@ -34,7 +34,6 @@ namespace Phonon { namespace MMF { -class VideoOutput; /** * @short Interface which abstracts from MediaObject the current @@ -79,7 +78,7 @@ public: virtual void volumeChanged(qreal volume); - void setVideoOutput(VideoOutput* videoOutput); + void setVideoOutput(AbstractVideoOutput *videoOutput); /** * Records error message and changes state to ErrorState @@ -156,7 +155,7 @@ private: protected: // Not owned - VideoOutput* m_videoOutput; + AbstractVideoOutput* m_videoOutput; qreal m_volume; diff --git a/src/3rdparty/phonon/mmf/abstractvideooutput.cpp b/src/3rdparty/phonon/mmf/abstractvideooutput.cpp new file mode 100644 index 0000000..3fe66fc --- /dev/null +++ b/src/3rdparty/phonon/mmf/abstractvideooutput.cpp @@ -0,0 +1,177 @@ +/* This file is part of the KDE project. + +Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). + +This library is free software: you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation, either version 2.1 or 3 of the License. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with this library. If not, see <http://www.gnu.org/licenses/>. + +*/ + +#include "abstractvideooutput.h" +#include "utils.h" + +#ifndef QT_NO_DEBUG +#include "objectdump.h" +#endif + +#include <QtCore/private/qcore_symbian_p.h> // for qt_TSize2QSize + +#include <QMoveEvent> +#include <QResizeEvent> + +#include <coecntrl.h> + +QT_BEGIN_NAMESPACE + +using namespace Phonon; +using namespace Phonon::MMF; + +/*! \class MMF::AbstractVideoOutput + \internal +*/ + +//----------------------------------------------------------------------------- +// Constants +//----------------------------------------------------------------------------- + +static const Phonon::VideoWidget::AspectRatio DefaultAspectRatio = + Phonon::VideoWidget::AspectRatioAuto; +static const Phonon::VideoWidget::ScaleMode DefaultScaleMode = + Phonon::VideoWidget::FitInView; + + +//----------------------------------------------------------------------------- +// Constructor / destructor +//----------------------------------------------------------------------------- + +MMF::AbstractVideoOutput::AbstractVideoOutput(QWidget *parent) + : QWidget(parent) + , m_aspectRatio(DefaultAspectRatio) + , m_scaleMode(DefaultScaleMode) +{ + +} + +MMF::AbstractVideoOutput::~AbstractVideoOutput() +{ + +} + +void MMF::AbstractVideoOutput::setVideoSize(const QSize &frameSize) +{ + TRACE_CONTEXT(AbstractVideoOutput::setVideoSize, EVideoInternal); + TRACE("oldSize %d %d newSize %d %d", + m_videoFrameSize.width(), m_videoFrameSize.height(), + frameSize.width(), frameSize.height()); + + if (frameSize != m_videoFrameSize) { + m_videoFrameSize = frameSize; + updateGeometry(); + } +} + + +//----------------------------------------------------------------------------- +// QWidget +//----------------------------------------------------------------------------- + +QSize MMF::AbstractVideoOutput::sizeHint() const +{ + // TODO: replace this with a more sensible default + QSize result(320, 240); + + if (!m_videoFrameSize.isNull()) + result = m_videoFrameSize; + + return result; +} + + +//----------------------------------------------------------------------------- +// Public functions +//----------------------------------------------------------------------------- + +RWindowBase* MMF::AbstractVideoOutput::videoWindow() const +{ + CCoeControl *control = internalWinId(); + if (!control) + control = effectiveWinId(); + + RWindowBase *window = 0; + if (control) + window = control->DrawableWindow(); + + return window; +} + +QSize MMF::AbstractVideoOutput::videoWindowSize() const +{ + QSize result; + if (RWindowBase *const window = videoWindow()) + result = qt_TSize2QSize(window->Size()); + return result; +} + +Phonon::VideoWidget::AspectRatio MMF::AbstractVideoOutput::aspectRatio() const +{ + return m_aspectRatio; +} + +void MMF::AbstractVideoOutput::setAspectRatio + (Phonon::VideoWidget::AspectRatio aspectRatio) +{ + if (m_aspectRatio != aspectRatio) { + m_aspectRatio = aspectRatio; + emit aspectRatioChanged(); + } +} + +Phonon::VideoWidget::ScaleMode MMF::AbstractVideoOutput::scaleMode() const +{ + return m_scaleMode; +} + +void MMF::AbstractVideoOutput::setScaleMode + (Phonon::VideoWidget::ScaleMode scaleMode) +{ + if (m_scaleMode != scaleMode) { + m_scaleMode = scaleMode; + emit scaleModeChanged(); + } +} + + +//----------------------------------------------------------------------------- +// Private functions +//----------------------------------------------------------------------------- + +void MMF::AbstractVideoOutput::dump() const +{ +#ifndef QT_NO_DEBUG + TRACE_CONTEXT(AbstractVideoOutput::dump, EVideoInternal); + + QScopedPointer<ObjectDump::QVisitor> visitor(new ObjectDump::QVisitor); + visitor->setPrefix("Phonon::MMF"); // to aid searchability of logs + ObjectDump::addDefaultAnnotators(*visitor); + TRACE("Dumping tree from leaf 0x%08x:", this); + ObjectDump::dumpTreeFromLeaf(*this, *visitor); + + QScopedPointer<ObjectDump::QDumper> dumper(new ObjectDump::QDumper); + dumper->setPrefix("Phonon::MMF"); // to aid searchability of logs + ObjectDump::addDefaultAnnotators(*dumper); + TRACE_0("Dumping AbstractVideoOutput:"); + dumper->dumpObject(*this); +#endif +} + +QT_END_NAMESPACE + diff --git a/src/3rdparty/phonon/mmf/videooutput.h b/src/3rdparty/phonon/mmf/abstractvideooutput.h index 3e9c036..61bcd0f 100644 --- a/src/3rdparty/phonon/mmf/videooutput.h +++ b/src/3rdparty/phonon/mmf/abstractvideooutput.h @@ -16,14 +16,15 @@ along with this library. If not, see <http://www.gnu.org/licenses/>. */ -#ifndef PHONON_MMF_VIDEOOUTPUT_H -#define PHONON_MMF_VIDEOOUTPUT_H +#ifndef PHONON_MMF_ABSTRACTVIDEOOUTPUT_H +#define PHONON_MMF_ABSTRACTVIDEOOUTPUT_H #include <QtGui/QWidget> #include <QVector> #include <QRect> #include "defs.h" +#include <phonon/abstractvideooutput.h> #include <phonon/videowidget.h> #include <e32std.h> @@ -35,21 +36,25 @@ namespace Phonon { namespace MMF { -class AncestorMoveMonitor; -class VideoOutput : public QWidget +/** + * @short ABC for widget on which video is displayed + * + * @see DsaVideoOutput, SurfaceVideoOutput + */ +class AbstractVideoOutput + : public QWidget { Q_OBJECT public: - VideoOutput(AncestorMoveMonitor* ancestorMoveMonitor, QWidget* parent); - ~VideoOutput(); + ~AbstractVideoOutput(); // Set size of video frame. Called by VideoPlayer. - void setVideoSize(const QSize& size); + void setVideoSize(const QSize &size); - RWindowBase* videoWindow(); - const QRect& videoWindowRect() const; + RWindowBase* videoWindow() const; + QSize videoWindowSize() const; Phonon::VideoWidget::AspectRatio aspectRatio() const; void setAspectRatio(Phonon::VideoWidget::AspectRatio aspectRatio); @@ -57,41 +62,24 @@ public: Phonon::VideoWidget::ScaleMode scaleMode() const; void setScaleMode(Phonon::VideoWidget::ScaleMode scaleMode); - // Called by AncestorMoveMonitor - void ancestorMoved(); - // Debugging output void dump() const; -public Q_SLOTS: - void beginNativePaintEvent(const QRect& /*controlRect*/); - void endNativePaintEvent(const QRect& /*controlRect*/); - Q_SIGNALS: void videoWindowChanged(); void aspectRatioChanged(); void scaleModeChanged(); - void beginVideoWindowNativePaint(); - void endVideoWindowNativePaint(); protected: - // Override QWidget functions - QSize sizeHint() const; - void paintEvent(QPaintEvent* event); - void resizeEvent(QResizeEvent* event); - void moveEvent(QMoveEvent* event); - bool event(QEvent* event); + AbstractVideoOutput(QWidget *parent); private: - void getVideoWindowRect(); - void registerForAncestorMoved(); + // QWidget + QSize sizeHint() const; private: - // Not owned - AncestorMoveMonitor* m_ancestorMoveMonitor; - + // Dimensions of the video clip QSize m_videoFrameSize; - QRect m_videoWindowRect; Phonon::VideoWidget::AspectRatio m_aspectRatio; Phonon::VideoWidget::ScaleMode m_scaleMode; diff --git a/src/3rdparty/phonon/mmf/abstractvideoplayer.cpp b/src/3rdparty/phonon/mmf/abstractvideoplayer.cpp new file mode 100644 index 0000000..8cb9db5 --- /dev/null +++ b/src/3rdparty/phonon/mmf/abstractvideoplayer.cpp @@ -0,0 +1,490 @@ +/* This file is part of the KDE project. + +Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). + +This library is free software: you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation, either version 2.1 or 3 of the License. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with this library. If not, see <http://www.gnu.org/licenses/>. + +*/ + +#include <QUrl> +#include <QTimer> +#include <QWidget> + +#include <coemain.h> // for CCoeEnv + +#include "abstractvideoplayer.h" +#include "utils.h" + +#ifndef QT_NO_DEBUG +#include "objectdump.h" +#endif + +QT_BEGIN_NAMESPACE + +using namespace Phonon; +using namespace Phonon::MMF; + +/*! \class MMF::AbstractVideoPlayer + \internal +*/ + +//----------------------------------------------------------------------------- +// Constructor / destructor +//----------------------------------------------------------------------------- + +MMF::AbstractVideoPlayer::AbstractVideoPlayer(MediaObject *parent, const AbstractPlayer *player) + : AbstractMediaPlayer(parent, player) + , m_wsSession(CCoeEnv::Static()->WsSession()) + , m_screenDevice(*CCoeEnv::Static()->ScreenDevice()) + , m_window(0) + , m_scaleWidth(1.0) + , m_scaleHeight(1.0) + , m_totalTime(0) +{ + +} + +void MMF::AbstractVideoPlayer::construct() +{ + TRACE_CONTEXT(AbstractVideoPlayer::AbstractVideoPlayer, EVideoApi); + TRACE_ENTRY_0(); + + if (m_videoOutput) { + initVideoOutput(); + m_window = m_videoOutput->videoWindow(); + } + + createPlayer(); + + TRACE_EXIT_0(); +} + +MMF::AbstractVideoPlayer::~AbstractVideoPlayer() +{ + TRACE_CONTEXT(AbstractVideoPlayer::~AbstractVideoPlayer, EVideoApi); + TRACE_ENTRY_0(); + + // QObject destructor removes all signal-slot connections involving this + // object, so we do not need to disconnect from m_videoOutput here. + + TRACE_EXIT_0(); +} + +CVideoPlayerUtility* MMF::AbstractVideoPlayer::nativePlayer() const +{ + return m_player.data(); +} + +//----------------------------------------------------------------------------- +// Public API +//----------------------------------------------------------------------------- + +void MMF::AbstractVideoPlayer::doPlay() +{ + TRACE_CONTEXT(AbstractVideoPlayer::doPlay, EVideoApi); + + handlePendingParametersChanged(); + + m_player->Play(); +} + +void MMF::AbstractVideoPlayer::doPause() +{ + TRACE_CONTEXT(AbstractVideoPlayer::doPause, EVideoApi); + + TRAPD(err, m_player->PauseL()); + if (KErrNone != err && state() != ErrorState) { + TRACE("PauseL error %d", err); + setError(tr("Pause failed"), err); + } +} + +void MMF::AbstractVideoPlayer::doStop() +{ + m_player->Stop(); +} + +void MMF::AbstractVideoPlayer::doSeek(qint64 ms) +{ + TRACE_CONTEXT(AbstractVideoPlayer::doSeek, EVideoApi); + + TRAPD(err, m_player->SetPositionL(TTimeIntervalMicroSeconds(ms * 1000))); + + if (KErrNone != err) + setError(tr("Seek failed"), err); +} + +int MMF::AbstractVideoPlayer::setDeviceVolume(int mmfVolume) +{ + TRAPD(err, m_player->SetVolumeL(mmfVolume)); + return err; +} + +int MMF::AbstractVideoPlayer::openFile(RFile &file) +{ + TRAPD(err, m_player->OpenFileL(file)); + return err; +} + +int MMF::AbstractVideoPlayer::openUrl(const QString &url) +{ + TRAPD(err, m_player->OpenUrlL(qt_QString2TPtrC(url))); + return err; +} + +int MMF::AbstractVideoPlayer::bufferStatus() const +{ + int result = 0; + TRAP_IGNORE(m_player->GetVideoLoadingProgressL(result)); + return result; +} + +void MMF::AbstractVideoPlayer::close() +{ + m_player->Close(); +} + +bool MMF::AbstractVideoPlayer::hasVideo() const +{ + return true; +} + +qint64 MMF::AbstractVideoPlayer::currentTime() const +{ + TRACE_CONTEXT(AbstractVideoPlayer::currentTime, EVideoApi); + + TTimeIntervalMicroSeconds us; + TRAPD(err, us = m_player->PositionL()) + + qint64 result = 0; + + if (KErrNone == err) { + result = toMilliSeconds(us); + } else { + TRACE("PositionL error %d", err); + + // If we don't cast away constness here, we simply have to ignore + // the error. + const_cast<AbstractVideoPlayer*>(this)->setError(tr("Getting position failed"), err); + } + + return result; +} + +qint64 MMF::AbstractVideoPlayer::totalTime() const +{ + return m_totalTime; +} + + +//----------------------------------------------------------------------------- +// Public slots +//----------------------------------------------------------------------------- + +void MMF::AbstractVideoPlayer::videoWindowChanged() +{ + TRACE_CONTEXT(AbstractVideoPlayer::videoOutputRegionChanged, EVideoInternal); + TRACE_ENTRY("state %d", state()); + + m_window = m_videoOutput ? m_videoOutput->videoWindow() : 0; + + handleVideoWindowChanged(); + + TRACE_EXIT_0(); +} + +void MMF::AbstractVideoPlayer::aspectRatioChanged() +{ + TRACE_CONTEXT(AbstractVideoPlayer::aspectRatioChanged, EVideoInternal); + TRACE_ENTRY("state %d aspectRatio %d", state()); + + updateScaleFactors(m_videoOutput->videoWindowSize()); + + TRACE_EXIT_0(); +} + +void MMF::AbstractVideoPlayer::scaleModeChanged() +{ + TRACE_CONTEXT(AbstractVideoPlayer::scaleModeChanged, EVideoInternal); + TRACE_ENTRY("state %d", state()); + + updateScaleFactors(m_videoOutput->videoWindowSize()); + + TRACE_EXIT_0(); +} + + +//----------------------------------------------------------------------------- +// MVideoPlayerUtilityObserver callbacks +//----------------------------------------------------------------------------- + +void MMF::AbstractVideoPlayer::MvpuoOpenComplete(TInt aError) +{ + TRACE_CONTEXT(AbstractVideoPlayer::MvpuoOpenComplete, EVideoApi); + TRACE_ENTRY("state %d error %d", state(), aError); + + __ASSERT_ALWAYS(LoadingState == state(), Utils::panic(InvalidStatePanic)); + + if (KErrNone == aError) + m_player->Prepare(); + else + setError(tr("Opening clip failed"), aError); + + TRACE_EXIT_0(); +} + +void MMF::AbstractVideoPlayer::MvpuoPrepareComplete(TInt aError) +{ + TRACE_CONTEXT(AbstractVideoPlayer::MvpuoPrepareComplete, EVideoApi); + TRACE_ENTRY("state %d error %d", state(), aError); + + __ASSERT_ALWAYS(LoadingState == state(), Utils::panic(InvalidStatePanic)); + + TRAPD(err, getVideoClipParametersL(aError)); + + if (KErrNone == err) { + maxVolumeChanged(m_player->MaxVolume()); + + if (m_videoOutput) + m_videoOutput->setVideoSize(m_videoFrameSize); + + prepareCompleted(); + handlePendingParametersChanged(); + + emit totalTimeChanged(totalTime()); + changeState(StoppedState); + } else { + setError(tr("Buffering clip failed"), err); + } + + TRACE_EXIT_0(); +} + +void MMF::AbstractVideoPlayer::getVideoClipParametersL(TInt aError) +{ + User::LeaveIfError(aError); + + // Get frame size + TSize size; + m_player->VideoFrameSizeL(size); + m_videoFrameSize = QSize(size.iWidth, size.iHeight); + + // Get duration + m_totalTime = toMilliSeconds(m_player->DurationL()); +} + + +void MMF::AbstractVideoPlayer::MvpuoFrameReady(CFbsBitmap &aFrame, TInt aError) +{ + TRACE_CONTEXT(AbstractVideoPlayer::MvpuoFrameReady, EVideoApi); + TRACE_ENTRY("state %d error %d", state(), aError); + + Q_UNUSED(aFrame); + Q_UNUSED(aError); // suppress warnings in release builds + + TRACE_EXIT_0(); +} + +void MMF::AbstractVideoPlayer::MvpuoPlayComplete(TInt aError) +{ + TRACE_CONTEXT(AbstractVideoPlayer::MvpuoPlayComplete, EVideoApi) + TRACE_ENTRY("state %d error %d", state(), aError); + + // Call base class function which handles end of playback for both + // audio and video clips. + playbackComplete(aError); + + TRACE_EXIT_0(); +} + +void MMF::AbstractVideoPlayer::MvpuoEvent(const TMMFEvent &aEvent) +{ + TRACE_CONTEXT(AbstractVideoPlayer::MvpuoEvent, EVideoApi); + TRACE_ENTRY("state %d", state()); + + Q_UNUSED(aEvent); + + TRACE_EXIT_0(); +} + + +//----------------------------------------------------------------------------- +// MVideoLoadingObserver callbacks +//----------------------------------------------------------------------------- + +void MMF::AbstractVideoPlayer::MvloLoadingStarted() +{ + bufferingStarted(); +} + +void MMF::AbstractVideoPlayer::MvloLoadingComplete() +{ + bufferingComplete(); +} + + +//----------------------------------------------------------------------------- +// Video window updates +//----------------------------------------------------------------------------- + +void MMF::AbstractVideoPlayer::videoOutputChanged() +{ + TRACE_CONTEXT(AbstractVideoPlayer::videoOutputChanged, EVideoInternal); + TRACE_ENTRY_0(); + + if (m_videoOutput) + initVideoOutput(); + + videoWindowChanged(); + + TRACE_EXIT_0(); +} + +void MMF::AbstractVideoPlayer::initVideoOutput() +{ + bool connected = connect( + m_videoOutput, SIGNAL(videoWindowChanged()), + this, SLOT(videoWindowChanged()) + ); + Q_ASSERT(connected); + + connected = connect( + m_videoOutput, SIGNAL(aspectRatioChanged()), + this, SLOT(aspectRatioChanged()) + ); + Q_ASSERT(connected); + + connected = connect( + m_videoOutput, SIGNAL(scaleModeChanged()), + this, SLOT(scaleModeChanged()) + ); + Q_ASSERT(connected); + + // Suppress warnings in release builds + Q_UNUSED(connected); + + // Do these after all connections are complete, to ensure + // that any signals generated get to their destinations. + m_videoOutput->winId(); + m_videoOutput->setVideoSize(m_videoFrameSize); +} + +// Helper function for aspect ratio / scale mode handling +QSize scaleToAspect(const QSize &srcRect, int aspectWidth, int aspectHeight) +{ + const qreal aspectRatio = qreal(aspectWidth) / aspectHeight; + + int width = srcRect.width(); + int height = srcRect.width() / aspectRatio; + if (height > srcRect.height()){ + height = srcRect.height(); + width = srcRect.height() * aspectRatio; + } + return QSize(width, height); +} + +void MMF::AbstractVideoPlayer::updateScaleFactors(const QSize &windowSize, bool apply) +{ + if (m_videoFrameSize.isValid()) { + QRect videoRect; + + // Calculate size of smallest rect which contains video frame size + // and conforms to aspect ratio + switch (m_videoOutput->aspectRatio()) { + case Phonon::VideoWidget::AspectRatioAuto: + videoRect.setSize(m_videoFrameSize); + break; + + case Phonon::VideoWidget::AspectRatioWidget: + videoRect.setSize(windowSize); + break; + + case Phonon::VideoWidget::AspectRatio4_3: + videoRect.setSize(scaleToAspect(m_videoFrameSize, 4, 3)); + break; + + case Phonon::VideoWidget::AspectRatio16_9: + videoRect.setSize(scaleToAspect(m_videoFrameSize, 16, 9)); + break; + } + + // Scale to fill the window width + const int windowWidth = windowSize.width(); + const int windowHeight = windowSize.height(); + const qreal windowScaleFactor = qreal(windowWidth) / videoRect.width(); + int videoWidth = windowWidth; + int videoHeight = videoRect.height() * windowScaleFactor; + + const qreal windowToVideoHeightRatio = qreal(windowHeight) / videoHeight; + + switch (m_videoOutput->scaleMode()) { + case Phonon::VideoWidget::ScaleAndCrop: + if (videoHeight < windowHeight) { + videoWidth *= windowToVideoHeightRatio; + videoHeight = windowHeight; + } + break; + case Phonon::VideoWidget::FitInView: + default: + if (videoHeight > windowHeight) { + videoWidth *= windowToVideoHeightRatio; + videoHeight = windowHeight; + } + break; + } + + // Calculate scale factors + m_scaleWidth = 100.0f * videoWidth / m_videoFrameSize.width(); + m_scaleHeight = 100.0f * videoHeight / m_videoFrameSize.height(); + + if (apply) + parametersChanged(ScaleFactors); + } +} + +void MMF::AbstractVideoPlayer::parametersChanged(VideoParameters parameters) +{ + if (state() == LoadingState) + m_pendingChanges |= parameters; + else + handleParametersChanged(parameters); +} + +void MMF::AbstractVideoPlayer::handlePendingParametersChanged() +{ + if (m_pendingChanges) + handleParametersChanged(m_pendingChanges); + m_pendingChanges = 0; +} + + +//----------------------------------------------------------------------------- +// Metadata +//----------------------------------------------------------------------------- + +int MMF::AbstractVideoPlayer::numberOfMetaDataEntries() const +{ + int numberOfEntries = 0; + TRAP_IGNORE(numberOfEntries = m_player->NumberOfMetaDataEntriesL()); + return numberOfEntries; +} + +QPair<QString, QString> MMF::AbstractVideoPlayer::metaDataEntry(int index) const +{ + CMMFMetaDataEntry *entry = 0; + QT_TRAP_THROWING(entry = m_player->MetaDataEntryL(index)); + return QPair<QString, QString>(qt_TDesC2QString(entry->Name()), qt_TDesC2QString(entry->Value())); +} + +QT_END_NAMESPACE + diff --git a/src/3rdparty/phonon/mmf/abstractvideoplayer.h b/src/3rdparty/phonon/mmf/abstractvideoplayer.h new file mode 100644 index 0000000..d854793 --- /dev/null +++ b/src/3rdparty/phonon/mmf/abstractvideoplayer.h @@ -0,0 +1,171 @@ +/* This file is part of the KDE project. + +Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). + +This library is free software: you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation, either version 2.1 or 3 of the License. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with this library. If not, see <http://www.gnu.org/licenses/>. + +*/ + +#ifndef PHONON_MMF_ABSTRACTVIDEOPLAYER_H +#define PHONON_MMF_ABSTRACTVIDEOPLAYER_H + +#include <videoplayer.h> // from epoc32/include + +#include <QSize> + +#include "abstractmediaplayer.h" +#include "abstractvideooutput.h" +#include "defs.h" + +QT_BEGIN_NAMESPACE + +namespace Phonon +{ +namespace MMF +{ +/** + * @short ABC for classes which wrap the MMF video player utility + * + * On devices which use the legacy graphics subsystem which does not + * support surfaces, video rendering is done via Direct Screen Access using + * the CVideoPlayerUtility API. On devices with a graphics subsystem which + * does support surfaces, video rendering is done using the + * CVideoPlayerUtility2 API. Because CVideoPlayerUtility2 inherits from + * CVideoPlayerUtility, AbstractVideoPlayer holds a pointer to the latter. + * + * @see DsaVideoPlayer, SurfaceVideoPlayer + */ +class AbstractVideoPlayer + : public AbstractMediaPlayer + , public MVideoPlayerUtilityObserver + , public MVideoLoadingObserver +{ + Q_OBJECT + +public: + ~AbstractVideoPlayer(); + + typedef CVideoPlayerUtility NativePlayer; + NativePlayer *nativePlayer() const; + + // AbstractPlayer + virtual void doPlay(); + virtual void doPause(); + virtual void doStop(); + virtual void doSeek(qint64 milliseconds); + virtual int setDeviceVolume(int mmfVolume); + virtual int openFile(RFile &file); + virtual int openUrl(const QString &url); + virtual int bufferStatus() const; + virtual void close(); + + // MediaObjectInterface + virtual bool hasVideo() const; + virtual qint64 currentTime() const; + virtual qint64 totalTime() const; + + // AbstractPlayer + virtual void videoOutputChanged(); + + // AbstractMediaPlayer + virtual int numberOfMetaDataEntries() const; + virtual QPair<QString, QString> metaDataEntry(int index) const; + +public Q_SLOTS: + void videoWindowChanged(); + void aspectRatioChanged(); + void scaleModeChanged(); + +protected: + AbstractVideoPlayer(MediaObject *parent, const AbstractPlayer *player); + void construct(); + virtual void initVideoOutput(); + void updateScaleFactors(const QSize &windowSize, bool apply = true); + + // Called when a video parameter changes. If the underlying native API is + // ready to handle the change, it is propagated immediately, otherwise the + // change is recorded in m_pendingChanged and handled later by + // handlePendingParametersChanged(). + void parametersChanged(VideoParameters parameter); + + // Implementation must initialize the m_player pointer. + virtual void createPlayer() = 0; + + // Called from the MvpuoPrepareComplete callback. Allows derived class to + // calculate clipping rectangles and scale factors prior to starting + // playback. + virtual void prepareCompleted() = 0; + + // Called when native video window handle changes. Derived class may defer + // propagation of this change to the MMF video player utility by calling + // parametersChanged(). + virtual void handleVideoWindowChanged() = 0; + + // Called when the derived class must handle changes which have been made + // to video parameters such as window handle, screen rectangle and scale + // factors. Guaranteed to be called only when the underlying MMF video + // player object is ready to handle changes to these parameters. + virtual void handleParametersChanged(VideoParameters parameters) = 0; + +private: + void getVideoClipParametersL(TInt aError); + + // Called when native player API enters a state in which it is able to + // handle pending changes such as new video window handle, updated scale + // factors etc. + void handlePendingParametersChanged(); + +private: + // MVideoPlayerUtilityObserver + virtual void MvpuoOpenComplete(TInt aError); + virtual void MvpuoPrepareComplete(TInt aError); + virtual void MvpuoFrameReady(CFbsBitmap &aFrame, TInt aError); + virtual void MvpuoPlayComplete(TInt aError); + virtual void MvpuoEvent(const TMMFEvent &aEvent); + + // MVideoLoadingObserver + virtual void MvloLoadingStarted(); + virtual void MvloLoadingComplete(); + +protected: + QScopedPointer<NativePlayer> m_player; + + // Not owned + RWsSession& m_wsSession; + CWsScreenDevice& m_screenDevice; + RWindowBase* m_window; + + // Scaling factors for video display, expressed as percentages + TReal32 m_scaleWidth; + TReal32 m_scaleHeight; + + // Dimensions of the video clip + QSize m_videoFrameSize; + +private: + // Bitmask of parameters which have changed while the MMF video player + // object is not yet ready to receive these changes. + // See handlePendingParametersChanged(). + VideoParameters m_pendingChanges; + + // Duration of the video clip + qint64 m_totalTime; + +}; + +} +} + +QT_END_NAMESPACE + +#endif diff --git a/src/3rdparty/phonon/mmf/ancestormovemonitor.cpp b/src/3rdparty/phonon/mmf/ancestormovemonitor.cpp index 18ced94..f0d1be2 100644 --- a/src/3rdparty/phonon/mmf/ancestormovemonitor.cpp +++ b/src/3rdparty/phonon/mmf/ancestormovemonitor.cpp @@ -18,7 +18,8 @@ along with this library. If not, see <http://www.gnu.org/licenses/>. #include "ancestormovemonitor.h" #include "utils.h" -#include "videooutput.h" + +#include "videooutput_dsa.h" #include <QCoreApplication> @@ -59,7 +60,7 @@ AncestorMoveMonitor::~AncestorMoveMonitor() // Public functions //----------------------------------------------------------------------------- -void AncestorMoveMonitor::registerTarget(VideoOutput *target) +void AncestorMoveMonitor::registerTarget(DsaVideoOutput *target) { TRACE_CONTEXT(AncestorMoveMonitor::registerTarget, EVideoInternal); TRACE_ENTRY("target 0x%08x", target); @@ -93,7 +94,7 @@ void AncestorMoveMonitor::registerTarget(VideoOutput *target) TRACE_EXIT_0(); } -void AncestorMoveMonitor::unRegisterTarget(VideoOutput *target) +void AncestorMoveMonitor::unRegisterTarget(DsaVideoOutput *target) { TRACE_CONTEXT(AncestorMoveMonitor::unRegisterTarget, EVideoInternal); TRACE_ENTRY("target 0x%08x", target); @@ -126,7 +127,7 @@ bool AncestorMoveMonitor::eventFilter(QObject *watched, QEvent *event) const Hash::const_iterator it = m_hash.find(watched); if(it != m_hash.end()) { const TargetList& targetList = it.value(); - VideoOutput* target = 0; + DsaVideoOutput* target = 0; foreach(target, targetList) { switch (event->type()) { @@ -166,7 +167,7 @@ void AncestorMoveMonitor::dump() const QObject *ancestor = it.key(); TRACE("ancestor 0x%08x", ancestor); const TargetList& targetList = it.value(); - VideoOutput* target = 0; + DsaVideoOutput* target = 0; foreach(target, targetList) { TRACE(" target 0x%08x", target); } @@ -174,7 +175,5 @@ void AncestorMoveMonitor::dump() #endif } - - QT_END_NAMESPACE diff --git a/src/3rdparty/phonon/mmf/ancestormovemonitor.h b/src/3rdparty/phonon/mmf/ancestormovemonitor.h index 0e681aa..f3a022d 100644 --- a/src/3rdparty/phonon/mmf/ancestormovemonitor.h +++ b/src/3rdparty/phonon/mmf/ancestormovemonitor.h @@ -29,7 +29,7 @@ namespace Phonon { namespace MMF { -class VideoOutput; +class DsaVideoOutput; class AncestorMoveMonitor : public QObject { @@ -49,7 +49,7 @@ public: * ancestor list to be updated - therefore it should be called when * the target receives a ParentChange event. */ - void registerTarget(VideoOutput *target); + void registerTarget(DsaVideoOutput *target); /** * Remove target from the monitor. @@ -57,7 +57,7 @@ public: * The target will no longer receive notification when move events are * delivered to its ancestors. */ - void unRegisterTarget(VideoOutput *target); + void unRegisterTarget(DsaVideoOutput *target); protected: /** @@ -77,7 +77,7 @@ private: * therefore a set, however we use QList rather than QSet for * efficiency of iteration. */ - typedef QList<VideoOutput *> TargetList; + typedef QList<DsaVideoOutput *> TargetList; /** * Map from widget on which the move event occurs, to widgets which @@ -92,4 +92,4 @@ private: QT_END_NAMESPACE -#endif +#endif // !PHONON_MMF_ANCESTORMOVEMONITOR_H diff --git a/src/3rdparty/phonon/mmf/backend.cpp b/src/3rdparty/phonon/mmf/backend.cpp index 3568a49..2cec43b 100644 --- a/src/3rdparty/phonon/mmf/backend.cpp +++ b/src/3rdparty/phonon/mmf/backend.cpp @@ -24,7 +24,6 @@ along with this library. If not, see <http://www.gnu.org/licenses/>. #include <apmstd.h> // for TDataType #include "abstractaudioeffect.h" -#include "ancestormovemonitor.h" #include "audiooutput.h" #include "audioplayer.h" #include "backend.h" @@ -44,7 +43,9 @@ using namespace Phonon::MMF; Backend::Backend(QObject *parent) : QObject(parent) +#ifndef PHONON_MMF_VIDEO_SURFACES , m_ancestorMoveMonitor(new AncestorMoveMonitor(this)) +#endif , m_effectFactory(new EffectFactory(this)) { TRACE_CONTEXT(Backend::Backend, EBackend); @@ -86,8 +87,15 @@ QObject *Backend::createObject(BackendInterface::Class c, QObject *parent, const static_cast<EffectFactory::Type>(args.first().toInt()); return m_effectFactory->createAudioEffect(type, parent); } + case VideoWidgetClass: - result = new VideoWidget(m_ancestorMoveMonitor.data(), qobject_cast<QWidget *>(parent)); + { + VideoWidget *widget = new VideoWidget(qobject_cast<QWidget *>(parent)); +#ifndef PHONON_MMF_VIDEO_SURFACES + widget->setAncestorMoveMonitor(m_ancestorMoveMonitor.data()); +#endif + result = widget; + } break; default: diff --git a/src/3rdparty/phonon/mmf/backend.h b/src/3rdparty/phonon/mmf/backend.h index 9361544..a45c92a 100644 --- a/src/3rdparty/phonon/mmf/backend.h +++ b/src/3rdparty/phonon/mmf/backend.h @@ -19,7 +19,10 @@ along with this library. If not, see <http://www.gnu.org/licenses/>. #ifndef PHONON_MMF_BACKEND_H #define PHONON_MMF_BACKEND_H +#ifndef PHONON_MMF_VIDEO_SURFACES #include "ancestormovemonitor.h" +#endif + #include "effectfactory.h" #include <phonon/mediasource.h> @@ -53,7 +56,9 @@ Q_SIGNALS: void objectDescriptionChanged(ObjectDescriptionType); private: +#ifndef PHONON_MMF_VIDEO_SURFACES QScopedPointer<AncestorMoveMonitor> m_ancestorMoveMonitor; +#endif QScopedPointer<EffectFactory> m_effectFactory; }; diff --git a/src/3rdparty/phonon/mmf/defs.h b/src/3rdparty/phonon/mmf/defs.h index 1a93aa9..1ed8250 100644 --- a/src/3rdparty/phonon/mmf/defs.h +++ b/src/3rdparty/phonon/mmf/defs.h @@ -35,6 +35,15 @@ enum MediaType { MediaTypeAudio, MediaTypeVideo }; + +enum VideoParameter { + WindowHandle = 0x1, + WindowScreenRect = 0x2, + ScaleFactors = 0x4 +}; +Q_DECLARE_FLAGS(VideoParameters, VideoParameter) +Q_DECLARE_OPERATORS_FOR_FLAGS(VideoParameters) + } } diff --git a/src/3rdparty/phonon/mmf/mediaobject.cpp b/src/3rdparty/phonon/mmf/mediaobject.cpp index 9744774..ee459e6 100644 --- a/src/3rdparty/phonon/mmf/mediaobject.cpp +++ b/src/3rdparty/phonon/mmf/mediaobject.cpp @@ -22,7 +22,13 @@ along with this library. If not, see <http://www.gnu.org/licenses/>. #include "dummyplayer.h" #include "utils.h" #include "utils.h" -#include "mmf_videoplayer.h" + +#ifdef PHONON_MMF_VIDEO_SURFACES +#include "videoplayer_surface.h" +#else +#include "videoplayer_dsa.h" +#endif + #include "videowidget.h" #include "mediaobject.h" @@ -293,7 +299,11 @@ void MMF::MediaObject::createPlayer(const MediaSource &source) break; case MediaTypeVideo: - newPlayer = new VideoPlayer(this, oldPlayer); +#ifdef PHONON_MMF_VIDEO_SURFACES + newPlayer = SurfaceVideoPlayer::create(this, oldPlayer); +#else + newPlayer = DsaVideoPlayer::create(this, oldPlayer); +#endif break; } @@ -383,7 +393,7 @@ void MMF::MediaObject::disconnectMediaObject(MediaObject * /*mediaObject*/) // Video output //----------------------------------------------------------------------------- -void MMF::MediaObject::setVideoOutput(VideoOutput* videoOutput) +void MMF::MediaObject::setVideoOutput(AbstractVideoOutput* videoOutput) { m_player->setVideoOutput(videoOutput); } diff --git a/src/3rdparty/phonon/mmf/mediaobject.h b/src/3rdparty/phonon/mmf/mediaobject.h index d6248e2..62e0a0e 100644 --- a/src/3rdparty/phonon/mmf/mediaobject.h +++ b/src/3rdparty/phonon/mmf/mediaobject.h @@ -38,7 +38,7 @@ namespace Phonon namespace MMF { class AbstractPlayer; -class VideoOutput; +class AbstractVideoOutput; /** * @short Facade class which wraps MMF client utility instance @@ -85,7 +85,7 @@ public: */ AbstractPlayer *abstractPlayer() const; - void setVideoOutput(VideoOutput* videoOutput); + void setVideoOutput(AbstractVideoOutput* videoOutput); public Q_SLOTS: void volumeChanged(qreal volume); diff --git a/src/3rdparty/phonon/mmf/mmf_videoplayer.cpp b/src/3rdparty/phonon/mmf/mmf_videoplayer.cpp deleted file mode 100644 index 127edb4..0000000 --- a/src/3rdparty/phonon/mmf/mmf_videoplayer.cpp +++ /dev/null @@ -1,658 +0,0 @@ -/* This file is part of the KDE project. - -Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). - -This library is free software: you can redistribute it and/or modify -it under the terms of the GNU Lesser General Public License as published by -the Free Software Foundation, either version 2.1 or 3 of the License. - -This library is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public License -along with this library. If not, see <http://www.gnu.org/licenses/>. - -*/ - -#include <QApplication> // for QApplication::activeWindow -#include <QUrl> -#include <QTimer> -#include <QWidget> - -#include <coemain.h> // for CCoeEnv -#include <coecntrl.h> - -#include "mmf_videoplayer.h" -#include "utils.h" - -#ifndef QT_NO_DEBUG -#include "objectdump.h" -#endif - -QT_BEGIN_NAMESPACE - -using namespace Phonon; -using namespace Phonon::MMF; - -/*! \class MMF::VideoPlayer - \internal -*/ - -//----------------------------------------------------------------------------- -// Constructor / destructor -//----------------------------------------------------------------------------- - -MMF::VideoPlayer::VideoPlayer(MediaObject *parent, const AbstractPlayer *player) - : AbstractMediaPlayer(parent, player) - , m_wsSession(CCoeEnv::Static()->WsSession()) - , m_screenDevice(*CCoeEnv::Static()->ScreenDevice()) - , m_window(0) - , m_totalTime(0) - , m_pendingChanges(false) - , m_dsaActive(false) -{ - construct(); -} - -void MMF::VideoPlayer::construct() -{ - TRACE_CONTEXT(VideoPlayer::VideoPlayer, EVideoApi); - TRACE_ENTRY_0(); - - getVideoWindow(); - - const TInt priority = 0; - const TMdaPriorityPreference preference = EMdaPriorityPreferenceNone; - - CVideoPlayerUtility *player = 0; - QT_TRAP_THROWING(player = CVideoPlayerUtility::NewL - ( - *this, - priority, preference, - m_wsSession, m_screenDevice, - *m_window, - m_videoRect, m_videoRect - ) - ); - m_player.reset(player); - - // CVideoPlayerUtility::NewL starts DSA - m_dsaActive = true; - - m_player->RegisterForVideoLoadingNotification(*this); - - TRACE_EXIT_0(); -} - -MMF::VideoPlayer::~VideoPlayer() -{ - TRACE_CONTEXT(VideoPlayer::~VideoPlayer, EVideoApi); - TRACE_ENTRY_0(); - - // QObject destructor removes all signal-slot connections involving this - // object, so we do not need to disconnect from m_videoOutput here. - - TRACE_EXIT_0(); -} - -CVideoPlayerUtility* MMF::VideoPlayer::nativePlayer() const -{ - return m_player.data(); -} - -//----------------------------------------------------------------------------- -// Public API -//----------------------------------------------------------------------------- - -void MMF::VideoPlayer::doPlay() -{ - TRACE_CONTEXT(VideoPlayer::doPlay, EVideoApi); - - applyPendingChanges(); - - m_player->Play(); -} - -void MMF::VideoPlayer::doPause() -{ - TRACE_CONTEXT(VideoPlayer::doPause, EVideoApi); - - TRAPD(err, m_player->PauseL()); - if (KErrNone != err && state() != ErrorState) { - TRACE("PauseL error %d", err); - setError(tr("Pause failed"), err); - } -} - -void MMF::VideoPlayer::doStop() -{ - m_player->Stop(); -} - -void MMF::VideoPlayer::doSeek(qint64 ms) -{ - TRACE_CONTEXT(VideoPlayer::doSeek, EVideoApi); - - TRAPD(err, m_player->SetPositionL(TTimeIntervalMicroSeconds(ms * 1000))); - - if(KErrNone != err) - setError(tr("Seek failed"), err); -} - -int MMF::VideoPlayer::setDeviceVolume(int mmfVolume) -{ - TRAPD(err, m_player->SetVolumeL(mmfVolume)); - return err; -} - -int MMF::VideoPlayer::openFile(RFile& file) -{ - TRAPD(err, m_player->OpenFileL(file)); - return err; -} - -int MMF::VideoPlayer::openUrl(const QString& url) -{ - TRAPD(err, m_player->OpenUrlL(qt_QString2TPtrC(url))); - return err; -} - -int MMF::VideoPlayer::bufferStatus() const -{ - int result = 0; - TRAP_IGNORE(m_player->GetVideoLoadingProgressL(result)); - return result; -} - -void MMF::VideoPlayer::close() -{ - m_player->Close(); -} - -bool MMF::VideoPlayer::hasVideo() const -{ - return true; -} - -qint64 MMF::VideoPlayer::currentTime() const -{ - TRACE_CONTEXT(VideoPlayer::currentTime, EVideoApi); - - TTimeIntervalMicroSeconds us; - TRAPD(err, us = m_player->PositionL()) - - qint64 result = 0; - - if (KErrNone == err) { - result = toMilliSeconds(us); - } else { - TRACE("PositionL error %d", err); - - // If we don't cast away constness here, we simply have to ignore - // the error. - const_cast<VideoPlayer*>(this)->setError(tr("Getting position failed"), err); - } - - return result; -} - -qint64 MMF::VideoPlayer::totalTime() const -{ - return m_totalTime; -} - - -//----------------------------------------------------------------------------- -// MVideoPlayerUtilityObserver callbacks -//----------------------------------------------------------------------------- - -void MMF::VideoPlayer::MvpuoOpenComplete(TInt aError) -{ - TRACE_CONTEXT(VideoPlayer::MvpuoOpenComplete, EVideoApi); - TRACE_ENTRY("state %d error %d", state(), aError); - - __ASSERT_ALWAYS(LoadingState == state(), Utils::panic(InvalidStatePanic)); - - if (KErrNone == aError) - m_player->Prepare(); - else - setError(tr("Opening clip failed"), aError); - - TRACE_EXIT_0(); -} - -void MMF::VideoPlayer::MvpuoPrepareComplete(TInt aError) -{ - TRACE_CONTEXT(VideoPlayer::MvpuoPrepareComplete, EVideoApi); - TRACE_ENTRY("state %d error %d", state(), aError); - - __ASSERT_ALWAYS(LoadingState == state(), Utils::panic(InvalidStatePanic)); - - TRAPD(err, doPrepareCompleteL(aError)); - - if (KErrNone == err) { - maxVolumeChanged(m_player->MaxVolume()); - - if (m_videoOutput) - m_videoOutput->setVideoSize(m_videoFrameSize); - - updateVideoRect(); - applyPendingChanges(); - - emit totalTimeChanged(totalTime()); - changeState(StoppedState); - } else { - setError(tr("Buffering clip failed"), err); - } - - TRACE_EXIT_0(); -} - -void MMF::VideoPlayer::doPrepareCompleteL(TInt aError) -{ - User::LeaveIfError(aError); - - // Get frame size - TSize size; - m_player->VideoFrameSizeL(size); - m_videoFrameSize = QSize(size.iWidth, size.iHeight); - - // Get duration - m_totalTime = toMilliSeconds(m_player->DurationL()); -} - - -void MMF::VideoPlayer::MvpuoFrameReady(CFbsBitmap &aFrame, TInt aError) -{ - TRACE_CONTEXT(VideoPlayer::MvpuoFrameReady, EVideoApi); - TRACE_ENTRY("state %d error %d", state(), aError); - - Q_UNUSED(aFrame); - Q_UNUSED(aError); // suppress warnings in release builds - - TRACE_EXIT_0(); -} - -void MMF::VideoPlayer::MvpuoPlayComplete(TInt aError) -{ - TRACE_CONTEXT(VideoPlayer::MvpuoPlayComplete, EVideoApi) - TRACE_ENTRY("state %d error %d", state(), aError); - - // Call base class function which handles end of playback for both - // audio and video clips. - playbackComplete(aError); - - TRACE_EXIT_0(); -} - -void MMF::VideoPlayer::MvpuoEvent(const TMMFEvent &aEvent) -{ - TRACE_CONTEXT(VideoPlayer::MvpuoEvent, EVideoApi); - TRACE_ENTRY("state %d", state()); - - Q_UNUSED(aEvent); - - TRACE_EXIT_0(); -} - - -//----------------------------------------------------------------------------- -// MVideoLoadingObserver callbacks -//----------------------------------------------------------------------------- - -void MMF::VideoPlayer::MvloLoadingStarted() -{ - bufferingStarted(); -} - -void MMF::VideoPlayer::MvloLoadingComplete() -{ - bufferingComplete(); -} - - -//----------------------------------------------------------------------------- -// Video window updates -//----------------------------------------------------------------------------- - -void MMF::VideoPlayer::getVideoWindow() -{ - TRACE_CONTEXT(VideoPlayer::getVideoWindow, EVideoInternal); - TRACE_ENTRY_0(); - - if(m_videoOutput) { - // Dump information to log, only in debug builds - m_videoOutput->dump(); - - initVideoOutput(); - videoWindowChanged(); - } else - // Top-level window - m_window = QApplication::activeWindow()->effectiveWinId()->DrawableWindow(); - - TRACE_EXIT_0(); -} - -void MMF::VideoPlayer::videoOutputChanged() -{ - TRACE_CONTEXT(VideoPlayer::videoOutputChanged, EVideoInternal); - TRACE_ENTRY_0(); - - if (m_videoOutput) { - initVideoOutput(); - videoWindowChanged(); - } - - TRACE_EXIT_0(); -} - -void MMF::VideoPlayer::initVideoOutput() -{ - m_videoOutput->winId(); - m_videoOutput->setVideoSize(m_videoFrameSize); - - bool connected = connect( - m_videoOutput, SIGNAL(videoWindowChanged()), - this, SLOT(videoWindowChanged()) - ); - Q_ASSERT(connected); - - connected = connect( - m_videoOutput, SIGNAL(beginVideoWindowNativePaint()), - this, SLOT(suspendDirectScreenAccess()) - ); - Q_ASSERT(connected); - - connected = connect( - m_videoOutput, SIGNAL(endVideoWindowNativePaint()), - this, SLOT(resumeDirectScreenAccess()) - ); - Q_ASSERT(connected); - - connected = connect( - m_videoOutput, SIGNAL(aspectRatioChanged()), - this, SLOT(aspectRatioChanged()) - ); - Q_ASSERT(connected); - - connected = connect( - m_videoOutput, SIGNAL(scaleModeChanged()), - this, SLOT(scaleModeChanged()) - ); - Q_ASSERT(connected); - - // Suppress warnings in release builds - Q_UNUSED(connected); -} - -void MMF::VideoPlayer::videoWindowChanged() -{ - TRACE_CONTEXT(VideoPlayer::videoOutputRegionChanged, EVideoInternal); - TRACE_ENTRY("state %d", state()); - - m_window = m_videoOutput->videoWindow(); - updateVideoRect(); - - TRACE_EXIT_0(); -} - -void MMF::VideoPlayer::suspendDirectScreenAccess() -{ - m_dsaWasActive = stopDirectScreenAccess(); -} - -void MMF::VideoPlayer::resumeDirectScreenAccess() -{ - if(m_dsaWasActive) { - startDirectScreenAccess(); - m_dsaWasActive = false; - } -} - -void MMF::VideoPlayer::startDirectScreenAccess() -{ - if(!m_dsaActive) { - TRAPD(err, m_player->StartDirectScreenAccessL()); - if(KErrNone == err) - m_dsaActive = true; - else - setError(tr("Video display error"), err); - } -} - -bool MMF::VideoPlayer::stopDirectScreenAccess() -{ - const bool dsaWasActive = m_dsaActive; - if(m_dsaActive) { - TRAPD(err, m_player->StopDirectScreenAccessL()); - if(KErrNone == err) - m_dsaActive = false; - else - setError(tr("Video display error"), err); - } - return dsaWasActive; -} - -// Helper function for aspect ratio / scale mode handling -QSize scaleToAspect(const QSize& srcRect, int aspectWidth, int aspectHeight) -{ - const qreal aspectRatio = qreal(aspectWidth) / aspectHeight; - - int width = srcRect.width(); - int height = srcRect.width() / aspectRatio; - if (height > srcRect.height()){ - height = srcRect.height(); - width = srcRect.height() * aspectRatio; - } - return QSize(width, height); -} - -void MMF::VideoPlayer::updateVideoRect() -{ - QRect videoRect; - QRect windowRect = m_videoOutput->videoWindowRect(); - - // Clip to physical window size - // This is due to a defect in the layout when running on S60 3.2, which - // results in the rectangle of the video widget extending outside the - // screen in certain circumstances. These include the initial startup - // of the mediaplayer demo in portrait mode. When this rectangle is - // passed to the CVideoPlayerUtility, no video is rendered. - const TSize screenSize = m_screenDevice.SizeInPixels(); - const QRect screenRect(0, 0, screenSize.iWidth, screenSize.iHeight); - windowRect = windowRect.intersected(screenRect); - - const QSize windowSize = windowRect.size(); - - // Calculate size of smallest rect which contains video frame size - // and conforms to aspect ratio - switch (m_videoOutput->aspectRatio()) { - case Phonon::VideoWidget::AspectRatioAuto: - videoRect.setSize(m_videoFrameSize); - break; - - case Phonon::VideoWidget::AspectRatioWidget: - videoRect.setSize(windowSize); - break; - - case Phonon::VideoWidget::AspectRatio4_3: - videoRect.setSize(scaleToAspect(m_videoFrameSize, 4, 3)); - break; - - case Phonon::VideoWidget::AspectRatio16_9: - videoRect.setSize(scaleToAspect(m_videoFrameSize, 16, 9)); - break; - } - - // Scale to fill the window width - const int windowWidth = windowSize.width(); - const int windowHeight = windowSize.height(); - const qreal windowScaleFactor = qreal(windowWidth) / videoRect.width(); - int videoWidth = windowWidth; - int videoHeight = videoRect.height() * windowScaleFactor; - - const qreal windowToVideoHeightRatio = qreal(windowHeight) / videoHeight; - - switch(m_videoOutput->scaleMode()) { - case Phonon::VideoWidget::ScaleAndCrop: - if(videoHeight < windowHeight) { - videoWidth *= windowToVideoHeightRatio; - videoHeight = windowHeight; - } - break; - case Phonon::VideoWidget::FitInView: - default: - if(videoHeight > windowHeight) { - videoWidth *= windowToVideoHeightRatio; - videoHeight = windowHeight; - } - break; - } - - // Calculate scale factors - m_scaleWidth = 100.0f * videoWidth / m_videoFrameSize.width(); - m_scaleHeight = 100.0f * videoHeight / m_videoFrameSize.height(); - - m_videoRect = qt_QRect2TRect(windowRect); - - if (state() == LoadingState) - m_pendingChanges = true; - else { - applyVideoWindowChange(); - m_pendingChanges = false; - } -} - -void MMF::VideoPlayer::aspectRatioChanged() -{ - TRACE_CONTEXT(VideoPlayer::aspectRatioChanged, EVideoInternal); - TRACE_ENTRY("state %d aspectRatio %d", state()); - - updateVideoRect(); - - TRACE_EXIT_0(); -} - -void MMF::VideoPlayer::scaleModeChanged() -{ - TRACE_CONTEXT(VideoPlayer::scaleModeChanged, EVideoInternal); - TRACE_ENTRY("state %d", state()); - - updateVideoRect(); - - TRACE_EXIT_0(); -} - -#ifndef QT_NO_DEBUG - -// The following code is for debugging problems related to video visibility. It allows -// the VideoPlayer instance to query the window server in order to determine the -// DSA drawing region for the video window. - -class CDummyAO : public CActive -{ -public: - CDummyAO() : CActive(CActive::EPriorityStandard) { CActiveScheduler::Add(this); } - void RunL() { } - void DoCancel() { } - TRequestStatus& Status() { return iStatus; } - void SetActive() { CActive::SetActive(); } -}; - -void getDsaRegion(RWsSession &session, const RWindowBase &window) -{ - RDirectScreenAccess dsa(session); - TInt err = dsa.Construct(); - CDummyAO ao; - RRegion* region; - err = dsa.Request(region, ao.Status(), window); - ao.SetActive(); - dsa.Close(); - ao.Cancel(); - if (region) { - qDebug() << "Phonon::MMF::getDsaRegion count" << region->Count(); - for (int i=0; i<region->Count(); ++i) { - const TRect& rect = region->RectangleList()[i]; - qDebug() << "Phonon::MMF::getDsaRegion rect" - << rect.iTl.iX << rect.iTl.iY << rect.iBr.iX << rect.iBr.iY; - } - region->Close(); - } -} - -#endif // _DEBUG - -void MMF::VideoPlayer::applyPendingChanges() -{ - if(m_pendingChanges) - applyVideoWindowChange(); - - m_pendingChanges = false; -} - -void MMF::VideoPlayer::applyVideoWindowChange() -{ - TRACE_CONTEXT(VideoPlayer::applyVideoWindowChange, EVideoInternal); - TRACE_ENTRY_0(); - -#ifndef QT_NO_DEBUG - getDsaRegion(m_wsSession, *m_window); -#endif - - static const TBool antialias = ETrue; - - TRAPD(err, m_player->SetScaleFactorL(m_scaleWidth, m_scaleHeight, antialias)); - if(KErrNone != err) { - TRACE("SetScaleFactorL (1) err %d", err); - setError(tr("Video display error"), err); - } - - if(KErrNone == err) { - TRAP(err, - m_player->SetDisplayWindowL - ( - m_wsSession, m_screenDevice, - *m_window, - m_videoRect, m_videoRect - ) - ); - - if (KErrNone != err) { - TRACE("SetDisplayWindowL err %d", err); - setError(tr("Video display error"), err); - } else { - m_dsaActive = true; - TRAP(err, m_player->SetScaleFactorL(m_scaleWidth, m_scaleHeight, antialias)); - if(KErrNone != err) { - TRACE("SetScaleFactorL (2) err %d", err); - setError(tr("Video display error"), err); - } - } - } - - TRACE_EXIT_0(); -} - - -//----------------------------------------------------------------------------- -// Metadata -//----------------------------------------------------------------------------- - -int MMF::VideoPlayer::numberOfMetaDataEntries() const -{ - int numberOfEntries = 0; - TRAP_IGNORE(numberOfEntries = m_player->NumberOfMetaDataEntriesL()); - return numberOfEntries; -} - -QPair<QString, QString> MMF::VideoPlayer::metaDataEntry(int index) const -{ - CMMFMetaDataEntry *entry = 0; - QT_TRAP_THROWING(entry = m_player->MetaDataEntryL(index)); - return QPair<QString, QString>(qt_TDesC2QString(entry->Name()), qt_TDesC2QString(entry->Value())); -} - -QT_END_NAMESPACE - diff --git a/src/3rdparty/phonon/mmf/mmf_videoplayer.h b/src/3rdparty/phonon/mmf/mmf_videoplayer.h deleted file mode 100644 index 0253ab9..0000000 --- a/src/3rdparty/phonon/mmf/mmf_videoplayer.h +++ /dev/null @@ -1,138 +0,0 @@ -/* This file is part of the KDE project. - -Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). - -This library is free software: you can redistribute it and/or modify -it under the terms of the GNU Lesser General Public License as published by -the Free Software Foundation, either version 2.1 or 3 of the License. - -This library is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public License -along with this library. If not, see <http://www.gnu.org/licenses/>. - -*/ - -#ifndef PHONON_MMF_VIDEOPLAYER_H -#define PHONON_MMF_VIDEOPLAYER_H - -#include <videoplayer.h> // from epoc32/include - -#include "abstractmediaplayer.h" -#include "videooutput.h" - -QT_BEGIN_NAMESPACE - -namespace Phonon -{ -namespace MMF -{ -/** - * @short Wrapper over MMF video client utility - * - * See - * <a href="http://wiki.forum.nokia.com/index.php/How_to_play_a_video_file_using_CVideoPlayerUtility">How to - * play a video file using CVideoPlayerUtility</a> - */ -class VideoPlayer : public AbstractMediaPlayer - , public MVideoPlayerUtilityObserver - , public MVideoLoadingObserver -{ - Q_OBJECT - -public: - VideoPlayer(MediaObject *parent = 0, const AbstractPlayer *player = 0); - virtual ~VideoPlayer(); - - typedef CVideoPlayerUtility NativePlayer; - NativePlayer *nativePlayer() const; - - // AbstractPlayer - virtual void doPlay(); - virtual void doPause(); - virtual void doStop(); - virtual void doSeek(qint64 milliseconds); - virtual int setDeviceVolume(int mmfVolume); - virtual int openFile(RFile& file); - virtual int openUrl(const QString& url); - virtual int bufferStatus() const; - virtual void close(); - - // MediaObjectInterface - virtual bool hasVideo() const; - virtual qint64 currentTime() const; - virtual qint64 totalTime() const; - - // AbstractPlayer - virtual void videoOutputChanged(); - - // AbstractMediaPlayer - virtual int numberOfMetaDataEntries() const; - virtual QPair<QString, QString> metaDataEntry(int index) const; - -public Q_SLOTS: - void videoWindowChanged(); - void aspectRatioChanged(); - void scaleModeChanged(); - void suspendDirectScreenAccess(); - void resumeDirectScreenAccess(); - -private: - void construct(); - - void doPrepareCompleteL(TInt aError); - - void getVideoWindow(); - void initVideoOutput(); - void updateVideoRect(); - - void applyPendingChanges(); - void applyVideoWindowChange(); - - void startDirectScreenAccess(); - bool stopDirectScreenAccess(); - -private: - // MVideoPlayerUtilityObserver - virtual void MvpuoOpenComplete(TInt aError); - virtual void MvpuoPrepareComplete(TInt aError); - virtual void MvpuoFrameReady(CFbsBitmap &aFrame, TInt aError); - virtual void MvpuoPlayComplete(TInt aError); - virtual void MvpuoEvent(const TMMFEvent &aEvent); - - // MVideoLoadingObserver - virtual void MvloLoadingStarted(); - virtual void MvloLoadingComplete(); - -private: - QScopedPointer<NativePlayer> m_player; - - // Not owned - RWsSession& m_wsSession; - CWsScreenDevice& m_screenDevice; - RWindowBase* m_window; - - /* Extent of the video display - will be clipped to m_windowRect */ - TRect m_videoRect; - - TReal32 m_scaleWidth; - TReal32 m_scaleHeight; - - QSize m_videoFrameSize; - qint64 m_totalTime; - - bool m_pendingChanges; - bool m_dsaActive; - bool m_dsaWasActive; - -}; - -} -} - -QT_END_NAMESPACE - -#endif diff --git a/src/3rdparty/phonon/mmf/videooutput.cpp b/src/3rdparty/phonon/mmf/videooutput.cpp deleted file mode 100644 index 119dcb1..0000000 --- a/src/3rdparty/phonon/mmf/videooutput.cpp +++ /dev/null @@ -1,303 +0,0 @@ -/* This file is part of the KDE project. - -Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). - -This library is free software: you can redistribute it and/or modify -it under the terms of the GNU Lesser General Public License as published by -the Free Software Foundation, either version 2.1 or 3 of the License. - -This library is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public License -along with this library. If not, see <http://www.gnu.org/licenses/>. - -*/ - -#include "ancestormovemonitor.h" -#include "utils.h" -#include "videooutput.h" - -#ifndef QT_NO_DEBUG -#include "objectdump.h" -#endif - -#include <QPaintEvent> -#include <QPainter> -#include <QMoveEvent> -#include <QResizeEvent> - -#include <QtCore/private/qcore_symbian_p.h> // for qt_TRect2QRect -#include <QtGui/private/qwidget_p.h> // to access QWExtra - -#include <coecntrl.h> - -#include <coemain.h> // for CCoeEnv - -QT_BEGIN_NAMESPACE - -using namespace Phonon; -using namespace Phonon::MMF; - -/*! \class MMF::VideoOutput - \internal -*/ - -//----------------------------------------------------------------------------- -// Constants -//----------------------------------------------------------------------------- - -static const Phonon::VideoWidget::AspectRatio DefaultAspectRatio = - Phonon::VideoWidget::AspectRatioAuto; -static const Phonon::VideoWidget::ScaleMode DefaultScaleMode = - Phonon::VideoWidget::FitInView; - - -//----------------------------------------------------------------------------- -// Constructor / destructor -//----------------------------------------------------------------------------- - -MMF::VideoOutput::VideoOutput - (AncestorMoveMonitor* ancestorMoveMonitor, QWidget* parent) - : QWidget(parent) - , m_ancestorMoveMonitor(ancestorMoveMonitor) - , m_aspectRatio(DefaultAspectRatio) - , m_scaleMode(DefaultScaleMode) -{ - TRACE_CONTEXT(VideoOutput::VideoOutput, EVideoInternal); - TRACE_ENTRY("parent 0x%08x", parent); - - setPalette(QPalette(Qt::black)); - setAttribute(Qt::WA_OpaquePaintEvent, true); - setAttribute(Qt::WA_NoSystemBackground, true); - setAutoFillBackground(false); - - qt_widget_private(this)->extraData()->nativePaintMode = QWExtra::ZeroFill; - qt_widget_private(this)->extraData()->receiveNativePaintEvents = true; - - getVideoWindowRect(); - registerForAncestorMoved(); - - dump(); - - TRACE_EXIT_0(); -} - -MMF::VideoOutput::~VideoOutput() -{ - TRACE_CONTEXT(VideoOutput::~VideoOutput, EVideoInternal); - TRACE_ENTRY_0(); - - m_ancestorMoveMonitor->unRegisterTarget(this); - - TRACE_EXIT_0(); -} - -void MMF::VideoOutput::setVideoSize(const QSize& frameSize) -{ - TRACE_CONTEXT(VideoOutput::setVideoSize, EVideoInternal); - TRACE("oldSize %d %d newSize %d %d", - m_videoFrameSize.width(), m_videoFrameSize.height(), - frameSize.width(), frameSize.height()); - - if (frameSize != m_videoFrameSize) { - m_videoFrameSize = frameSize; - updateGeometry(); - } -} - -void MMF::VideoOutput::ancestorMoved() -{ - TRACE_CONTEXT(VideoOutput::ancestorMoved, EVideoInternal); - TRACE_ENTRY_0(); - - RWindowBase *const window = videoWindow(); - - if(window) { - const TPoint newWindowPosSymbian = window->AbsPosition(); - const QPoint newWindowPos(newWindowPosSymbian.iX, newWindowPosSymbian.iY); - - if(newWindowPos != m_videoWindowRect.topLeft()) { - m_videoWindowRect.moveTo(newWindowPos); - emit videoWindowChanged(); - } - } - - TRACE_EXIT_0(); -} - -//----------------------------------------------------------------------------- -// QWidget -//----------------------------------------------------------------------------- - -QSize MMF::VideoOutput::sizeHint() const -{ - // TODO: replace this with a more sensible default - QSize result(320, 240); - - if (!m_videoFrameSize.isNull()) - result = m_videoFrameSize; - - return result; -} - -void MMF::VideoOutput::paintEvent(QPaintEvent* event) -{ - TRACE_CONTEXT(VideoOutput::paintEvent, EVideoInternal); - TRACE("rect %d %d - %d %d", - event->rect().left(), event->rect().top(), - event->rect().right(), event->rect().bottom()); - TRACE("regions %d", event->region().rectCount()); - TRACE("type %d", event->type()); - - // Do nothing -} - -void MMF::VideoOutput::resizeEvent(QResizeEvent* event) -{ - TRACE_CONTEXT(VideoOutput::resizeEvent, EVideoInternal); - TRACE("%d %d -> %d %d", - event->oldSize().width(), event->oldSize().height(), - event->size().width(), event->size().height()); - - if(event->size() != event->oldSize()) { - m_videoWindowRect.setSize(event->size()); - emit videoWindowChanged(); - } -} - -void MMF::VideoOutput::moveEvent(QMoveEvent* event) -{ - TRACE_CONTEXT(VideoOutput::moveEvent, EVideoInternal); - TRACE("%d %d -> %d %d", - event->oldPos().x(), event->oldPos().y(), - event->pos().x(), event->pos().y()); - - if(event->pos() != event->oldPos()) { - m_videoWindowRect.moveTo(event->pos()); - emit videoWindowChanged(); - } -} - -bool MMF::VideoOutput::event(QEvent* event) -{ - TRACE_CONTEXT(VideoOutput::event, EVideoInternal); - - if (event->type() == QEvent::WinIdChange) { - TRACE_0("WinIdChange"); - getVideoWindowRect(); - emit videoWindowChanged(); - return true; - } else if (event->type() == QEvent::ParentChange) { - // Tell ancestor move monitor to update ancestor list for this widget - registerForAncestorMoved(); - return true; - } else - return QWidget::event(event); -} - - -//----------------------------------------------------------------------------- -// Public functions -//----------------------------------------------------------------------------- - -RWindowBase* MMF::VideoOutput::videoWindow() -{ - CCoeControl *control = internalWinId(); - if(!control) - control = effectiveWinId(); - - RWindowBase *window = 0; - if(control) - window = control->DrawableWindow(); - - return window; -} - -const QRect& MMF::VideoOutput::videoWindowRect() const -{ - return m_videoWindowRect; -} - -Phonon::VideoWidget::AspectRatio MMF::VideoOutput::aspectRatio() const -{ - return m_aspectRatio; -} - -void MMF::VideoOutput::setAspectRatio - (Phonon::VideoWidget::AspectRatio aspectRatio) -{ - if(m_aspectRatio != aspectRatio) { - m_aspectRatio = aspectRatio; - emit aspectRatioChanged(); - } -} - -Phonon::VideoWidget::ScaleMode MMF::VideoOutput::scaleMode() const -{ - return m_scaleMode; -} - -void MMF::VideoOutput::setScaleMode - (Phonon::VideoWidget::ScaleMode scaleMode) -{ - if(m_scaleMode != scaleMode) { - m_scaleMode = scaleMode; - emit scaleModeChanged(); - } -} - - -//----------------------------------------------------------------------------- -// Private functions -//----------------------------------------------------------------------------- - -void MMF::VideoOutput::getVideoWindowRect() -{ - RWindowBase *const window = videoWindow(); - if(window) - m_videoWindowRect = - qt_TRect2QRect(TRect(window->AbsPosition(), window->Size())); -} - -void MMF::VideoOutput::registerForAncestorMoved() -{ - m_ancestorMoveMonitor->registerTarget(this); -} - -void MMF::VideoOutput::dump() const -{ -#ifndef QT_NO_DEBUG - TRACE_CONTEXT(VideoOutput::dump, EVideoInternal); - - QScopedPointer<ObjectDump::QVisitor> visitor(new ObjectDump::QVisitor); - visitor->setPrefix("Phonon::MMF"); // to aid searchability of logs - ObjectDump::addDefaultAnnotators(*visitor); - TRACE("Dumping tree from leaf 0x%08x:", this); - ObjectDump::dumpTreeFromLeaf(*this, *visitor); - - QScopedPointer<ObjectDump::QDumper> dumper(new ObjectDump::QDumper); - dumper->setPrefix("Phonon::MMF"); // to aid searchability of logs - ObjectDump::addDefaultAnnotators(*dumper); - TRACE_0("Dumping VideoOutput:"); - dumper->dumpObject(*this); -#endif -} - -void MMF::VideoOutput::beginNativePaintEvent(const QRect& /*controlRect*/) -{ - emit beginVideoWindowNativePaint(); -} - -void MMF::VideoOutput::endNativePaintEvent(const QRect& /*controlRect*/) -{ - // Ensure that draw ops are executed into the WSERV output framebuffer - CCoeEnv::Static()->WsSession().Flush(); - - emit endVideoWindowNativePaint(); -} - -QT_END_NAMESPACE - diff --git a/src/3rdparty/phonon/mmf/videooutput_dsa.cpp b/src/3rdparty/phonon/mmf/videooutput_dsa.cpp new file mode 100644 index 0000000..a5e2ac8 --- /dev/null +++ b/src/3rdparty/phonon/mmf/videooutput_dsa.cpp @@ -0,0 +1,177 @@ +/* This file is part of the KDE project. + +Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). + +This library is free software: you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation, either version 2.1 or 3 of the License. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with this library. If not, see <http://www.gnu.org/licenses/>. + +*/ + +#include <QtCore/private/qcore_symbian_p.h> // for qt_TRect2QRect +#include <QtGui/private/qwidget_p.h> // to access QWExtra +#include <QResizeEvent> +#include <QMoveEvent> + +#include <coemain.h> // for CCoeEnv + +#include "ancestormovemonitor.h" +#include "utils.h" +#include "videooutput_dsa.h" + +QT_BEGIN_NAMESPACE + +using namespace Phonon; +using namespace Phonon::MMF; + +DsaVideoOutput::DsaVideoOutput(QWidget *parent) + : AbstractVideoOutput(parent) + , m_ancestorMoveMonitor(0) +{ + TRACE_CONTEXT(DsaVideoOutput::DsaVideoOutput, EVideoInternal); + TRACE_ENTRY("parent 0x%08x", parent); + + setPalette(QPalette(Qt::black)); + setAttribute(Qt::WA_OpaquePaintEvent, true); + setAttribute(Qt::WA_NoSystemBackground, true); + setAutoFillBackground(false); + + qt_widget_private(this)->extraData()->nativePaintMode = QWExtra::ZeroFill; + qt_widget_private(this)->extraData()->receiveNativePaintEvents = true; + + getVideoWindowScreenRect(); + + dump(); + + TRACE_EXIT_0(); +} + +DsaVideoOutput::~DsaVideoOutput() +{ + TRACE_CONTEXT(DsaVideoOutput::~DsaVideoOutput, EVideoInternal); + TRACE_ENTRY_0(); + + m_ancestorMoveMonitor->unRegisterTarget(this); + + TRACE_EXIT_0(); +} + +//----------------------------------------------------------------------------- +// Public functions +//----------------------------------------------------------------------------- + +void MMF::DsaVideoOutput::setAncestorMoveMonitor(AncestorMoveMonitor *monitor) +{ + m_ancestorMoveMonitor = monitor; + registerForAncestorMoved(); +} + +const QRect& MMF::DsaVideoOutput::videoWindowScreenRect() const +{ + return m_videoWindowScreenRect; +} + +void MMF::DsaVideoOutput::ancestorMoved() +{ + TRACE_CONTEXT(DsaVideoOutput::ancestorMoved, EVideoInternal); + TRACE_ENTRY_0(); + + RWindowBase *const window = videoWindow(); + + if (window) { + const TPoint newWindowPosSymbian = window->AbsPosition(); + const QPoint newWindowPos(newWindowPosSymbian.iX, newWindowPosSymbian.iY); + + if (newWindowPos != m_videoWindowScreenRect.topLeft()) { + m_videoWindowScreenRect.moveTo(newWindowPos); + emit videoWindowScreenRectChanged(); + } + } + + TRACE_EXIT_0(); +} + +void MMF::DsaVideoOutput::beginNativePaintEvent(const QRect & /*controlRect*/) +{ + emit beginVideoWindowNativePaint(); +} + +void MMF::DsaVideoOutput::endNativePaintEvent(const QRect & /*controlRect*/) +{ + // Ensure that draw ops are executed into the WSERV output framebuffer + CCoeEnv::Static()->WsSession().Flush(); + + emit endVideoWindowNativePaint(); +} + +//----------------------------------------------------------------------------- +// Private functions +//----------------------------------------------------------------------------- + +void MMF::DsaVideoOutput::getVideoWindowScreenRect() +{ + RWindowBase *const window = videoWindow(); + if (window) + m_videoWindowScreenRect = + qt_TRect2QRect(TRect(window->AbsPosition(), window->Size())); +} + +void MMF::DsaVideoOutput::registerForAncestorMoved() +{ + m_ancestorMoveMonitor->registerTarget(this); +} + +void MMF::DsaVideoOutput::resizeEvent(QResizeEvent *event) +{ + TRACE_CONTEXT(DsaVideoOutput::resizeEvent, EVideoInternal); + TRACE("%d %d -> %d %d", + event->oldSize().width(), event->oldSize().height(), + event->size().width(), event->size().height()); + + if (event->size() != event->oldSize()) { + m_videoWindowScreenRect.setSize(event->size()); + emit videoWindowScreenRectChanged(); + } +} + +void MMF::DsaVideoOutput::moveEvent(QMoveEvent *event) +{ + TRACE_CONTEXT(DsaVideoOutput::moveEvent, EVideoInternal); + TRACE("%d %d -> %d %d", + event->oldPos().x(), event->oldPos().y(), + event->pos().x(), event->pos().y()); + + if (event->pos() != event->oldPos()) { + m_videoWindowScreenRect.moveTo(event->pos()); + emit videoWindowScreenRectChanged(); + } +} + +bool MMF::DsaVideoOutput::event(QEvent *event) +{ + TRACE_CONTEXT(DsaVideoOutput::event, EVideoInternal); + + if (event->type() == QEvent::WinIdChange) { + TRACE_0("WinIdChange"); + getVideoWindowScreenRect(); + emit videoWindowChanged(); + return true; + } else if (event->type() == QEvent::ParentChange) { + // Tell ancestor move monitor to update ancestor list for this widget + registerForAncestorMoved(); + return true; + } else { + return QWidget::event(event); + } +} + +QT_END_NAMESPACE + diff --git a/src/3rdparty/phonon/mmf/videooutput_dsa.h b/src/3rdparty/phonon/mmf/videooutput_dsa.h new file mode 100644 index 0000000..c37dad8 --- /dev/null +++ b/src/3rdparty/phonon/mmf/videooutput_dsa.h @@ -0,0 +1,109 @@ +/* This file is part of the KDE project. + +Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). + +This library is free software: you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation, either version 2.1 or 3 of the License. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with this library. If not, see <http://www.gnu.org/licenses/>. + +*/ + +#ifndef PHONON_MMF_VIDEOOUTPUT_DSA_H +#define PHONON_MMF_VIDEOOUTPUT_DSA_H + +#include <QRect> + +#include "phonon/mmf/abstractvideooutput.h" + +QT_BEGIN_NAMESPACE + +class QResizeEvent; +class QMoveEvent; + +namespace Phonon +{ +namespace MMF +{ +class AncestorMoveMonitor; + +/** + * @short Widget on which video is displayed by DSA rendering + * + * This implementation is used on devices with the legacy graphics + * subsystem, which does not support surfaces. On such devices, + * video rendering is done via Direct Screen Access (DSA), whereby + * the video decoder writes directly to the framebuffer. To ensure + * that the window server and video decoder do not try to draw to + * the same screen region at the same time, the video subsystem + * first requests permission to perform DSA. If the window server + * needs to draw to this screen region (for example to display a + * message dialog), it first notifies the video subsystem that it + * must stop rendering to this region. + * + * @see SurfaceVideoOutput + */ +class DsaVideoOutput + : public AbstractVideoOutput +{ + Q_OBJECT + +public: + DsaVideoOutput(QWidget *parent); + ~DsaVideoOutput(); + + void setAncestorMoveMonitor(AncestorMoveMonitor *monitor); + + // Get absolute screen rectangle for video window + const QRect& videoWindowScreenRect() const; + + // Called by AncestorMoveMonitor + void ancestorMoved(); + +public Q_SLOTS: + // Callbacks received from Symbian QtGui implementation, when it + // begins / ends blitting the video widget's backing store to the + // window server. + void beginNativePaintEvent(const QRect & /*controlRect*/); + void endNativePaintEvent(const QRect & /*controlRect*/); + +Q_SIGNALS: + void videoWindowScreenRectChanged(); + + // Emitted when the Symbian QtGui implementation begins / ends + // blitting the video widget's backing store to the window server. + void beginVideoWindowNativePaint(); + void endVideoWindowNativePaint(); + +private: + void getVideoWindowScreenRect(); + void registerForAncestorMoved(); + + // QWidget + void resizeEvent(QResizeEvent *event); + void moveEvent(QMoveEvent *event); + bool event(QEvent *event); + +private: + // Not owned + AncestorMoveMonitor* m_ancestorMoveMonitor; + + // Absolute screen rectangle on which video is displayed + QRect m_videoWindowScreenRect; + +}; + +} +} + +QT_END_NAMESPACE + +#endif // !PHONON_MMF_VIDEOOUTPUT_DSA_H + diff --git a/src/3rdparty/phonon/mmf/videooutput_surface.cpp b/src/3rdparty/phonon/mmf/videooutput_surface.cpp new file mode 100644 index 0000000..e9b2d3f --- /dev/null +++ b/src/3rdparty/phonon/mmf/videooutput_surface.cpp @@ -0,0 +1,87 @@ +/* This file is part of the KDE project. + +Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). + +This library is free software: you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation, either version 2.1 or 3 of the License. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with this library. If not, see <http://www.gnu.org/licenses/>. + +*/ + +#include <QResizeEvent> + +#include <QtCore/private/qcore_symbian_p.h> // for qt_TRect2QRect +#include <QtGui/private/qwidget_p.h> // to access QWExtra + +#include "utils.h" +#include "videooutput_surface.h" + +QT_BEGIN_NAMESPACE + +using namespace Phonon; +using namespace Phonon::MMF; + +SurfaceVideoOutput::SurfaceVideoOutput(QWidget *parent) + : AbstractVideoOutput(parent) +{ + TRACE_CONTEXT(SurfaceVideoOutput::SurfaceVideoOutput, EVideoInternal); + TRACE_ENTRY("parent 0x%08x", parent); + + qt_widget_private(this)->createExtra(); + qt_widget_private(this)->extraData()->nativePaintMode = QWExtra::Disable; + + TRACE_EXIT_0(); +} + +SurfaceVideoOutput::~SurfaceVideoOutput() +{ + TRACE_CONTEXT(SurfaceVideoOutput::~SurfaceVideoOutput, EVideoInternal); + TRACE_ENTRY_0(); + + TRACE_EXIT_0(); +} + +//----------------------------------------------------------------------------- +// Public functions +//----------------------------------------------------------------------------- + + +//----------------------------------------------------------------------------- +// Private functions +//----------------------------------------------------------------------------- + +void MMF::SurfaceVideoOutput::resizeEvent(QResizeEvent *event) +{ + TRACE_CONTEXT(SurfaceVideoOutput::resizeEvent, EVideoInternal); + TRACE("%d %d -> %d %d", + event->oldSize().width(), event->oldSize().height(), + event->size().width(), event->size().height()); + + if (event->size() != event->oldSize()) + emit videoWindowSizeChanged(); +} + +bool MMF::SurfaceVideoOutput::event(QEvent *event) +{ + TRACE_CONTEXT(SurfaceVideoOutput::event, EVideoInternal); + + if (event->type() == QEvent::WinIdChange) { + TRACE_0("WinIdChange"); + emit videoWindowChanged(); + return true; + } else { + return QWidget::event(event); + } +} + + +QT_END_NAMESPACE + diff --git a/src/3rdparty/phonon/mmf/videooutput_surface.h b/src/3rdparty/phonon/mmf/videooutput_surface.h new file mode 100644 index 0000000..0b22a710 --- /dev/null +++ b/src/3rdparty/phonon/mmf/videooutput_surface.h @@ -0,0 +1,66 @@ +/* This file is part of the KDE project. + +Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). + +This library is free software: you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation, either version 2.1 or 3 of the License. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with this library. If not, see <http://www.gnu.org/licenses/>. + +*/ + +#ifndef PHONON_MMF_VIDEOOUTPUT_SURFACE_H +#define PHONON_MMF_VIDEOOUTPUT_SURFACE_H + +#include "phonon/mmf/abstractvideooutput.h" + +QT_BEGIN_NAMESPACE + +class QResizeEvent; + +namespace Phonon +{ +namespace MMF +{ + +/** + * @short Widget on which video is displayed by rendering to a surface + * + * This implementation is used on devices with a graphics subsystem which + * supports surfaces. + * + * @see DsaVideoOutput + */ +class SurfaceVideoOutput + : public AbstractVideoOutput +{ + Q_OBJECT + +public: + SurfaceVideoOutput(QWidget *parent); + ~SurfaceVideoOutput(); + +Q_SIGNALS: + void videoWindowSizeChanged(); + +private: + // QWidget + void resizeEvent(QResizeEvent *event); + bool event(QEvent *event); + +}; + +} +} + +QT_END_NAMESPACE + +#endif // !PHONON_MMF_VIDEOOUTPUT_SURFACE_H + diff --git a/src/3rdparty/phonon/mmf/videoplayer_dsa.cpp b/src/3rdparty/phonon/mmf/videoplayer_dsa.cpp new file mode 100644 index 0000000..21cdb16 --- /dev/null +++ b/src/3rdparty/phonon/mmf/videoplayer_dsa.cpp @@ -0,0 +1,285 @@ +/* This file is part of the KDE project. + +Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). + +This library is free software: you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation, either version 2.1 or 3 of the License. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with this library. If not, see <http://www.gnu.org/licenses/>. + +*/ + +#include <coecntrl.h> // for CCoeControl + +#include <QApplication> // for QApplication::activeWindow +#include <QtCore/private/qcore_symbian_p.h> // for qt_TRect2QRect + +#include "utils.h" +#include "videooutput_dsa.h" +#include "videoplayer_dsa.h" + +QT_BEGIN_NAMESPACE + +using namespace Phonon; +using namespace Phonon::MMF; + +// Two-phase constructor idiom is used because construct() calls virtual +// functions and therefore cannot be called from the AbstractVideoPlayer +// C++ constructor. +DsaVideoPlayer* DsaVideoPlayer::create(MediaObject *parent, + const AbstractPlayer *player) +{ + QScopedPointer<DsaVideoPlayer> self(new DsaVideoPlayer(parent, player)); + self->construct(); + return self.take(); +} + +DsaVideoPlayer::DsaVideoPlayer(MediaObject *parent, const AbstractPlayer *player) + : AbstractVideoPlayer(parent, player) + , m_dsaActive(false) + , m_dsaWasActive(false) +{ + +} + +DsaVideoPlayer::~DsaVideoPlayer() +{ + +} + + +//----------------------------------------------------------------------------- +// Public functions +//----------------------------------------------------------------------------- + +void MMF::DsaVideoPlayer::videoWindowScreenRectChanged() +{ + QRect windowRect = static_cast<DsaVideoOutput *>(m_videoOutput)->videoWindowScreenRect(); + + // Clip to physical window size + // This is due to a defect in the layout when running on S60 3.2, which + // results in the rectangle of the video widget extending outside the + // screen in certain circumstances. These include the initial startup + // of the mediaplayer demo in portrait mode. When this rectangle is + // passed to the CVideoPlayerUtility, no video is rendered. + const TSize screenSize = m_screenDevice.SizeInPixels(); + const QRect screenRect(0, 0, screenSize.iWidth, screenSize.iHeight); + windowRect = windowRect.intersected(screenRect); + + // Recalculate scale factors. Pass 'false' as second parameter in order to + // suppress application of the change to the player - this is done at the end + // of the function. + updateScaleFactors(windowRect.size(), false); + + m_videoScreenRect = qt_QRect2TRect(windowRect); + + parametersChanged(WindowScreenRect | ScaleFactors); +} + +void MMF::DsaVideoPlayer::suspendDirectScreenAccess() +{ + m_dsaWasActive = stopDirectScreenAccess(); +} + +void MMF::DsaVideoPlayer::resumeDirectScreenAccess() +{ + if (m_dsaWasActive) { + startDirectScreenAccess(); + m_dsaWasActive = false; + } +} + + +//----------------------------------------------------------------------------- +// Private functions +//----------------------------------------------------------------------------- + +void MMF::DsaVideoPlayer::createPlayer() +{ + // A window handle must be provided in order to construct + // CVideoPlayerUtility. If no VideoOutput has yet been connected to this + // player, we temporarily use the top-level application window handle. + // No video ever gets rendered into this window; SetDisplayWindowL is + // always called before rendering actually begins. + if (!m_window) + m_window = QApplication::activeWindow()->effectiveWinId()->DrawableWindow(); + + const TInt priority = 0; + const TMdaPriorityPreference preference = EMdaPriorityPreferenceNone; + + CVideoPlayerUtility *player = 0; + QT_TRAP_THROWING(player = CVideoPlayerUtility::NewL(*this, + priority, preference, + m_wsSession, m_screenDevice, + *m_window, + m_videoScreenRect, m_videoScreenRect)); + m_player.reset(player); + + // CVideoPlayerUtility::NewL starts DSA + m_dsaActive = true; + + m_player->RegisterForVideoLoadingNotification(*this); +} + +void MMF::DsaVideoPlayer::initVideoOutput() +{ + bool connected = connect( + m_videoOutput, SIGNAL(videoWindowScreenRectChanged()), + this, SLOT(videoWindowScreenRectChanged()) + ); + Q_ASSERT(connected); + + connected = connect( + m_videoOutput, SIGNAL(beginVideoWindowNativePaint()), + this, SLOT(suspendDirectScreenAccess()) + ); + Q_ASSERT(connected); + + connected = connect( + m_videoOutput, SIGNAL(endVideoWindowNativePaint()), + this, SLOT(resumeDirectScreenAccess()) + ); + Q_ASSERT(connected); + + // Suppress warnings in release builds + Q_UNUSED(connected); + + AbstractVideoPlayer::initVideoOutput(); +} + +void MMF::DsaVideoPlayer::prepareCompleted() +{ + videoWindowScreenRectChanged(); +} + +void MMF::DsaVideoPlayer::handleVideoWindowChanged() +{ + if (!m_window) { + m_window = QApplication::activeWindow()->effectiveWinId()->DrawableWindow(); + m_videoScreenRect = TRect(); + } + + parametersChanged(WindowHandle | WindowScreenRect); +} + +#ifndef QT_NO_DEBUG + +// The following code is for debugging problems related to video visibility. It allows +// the VideoPlayer instance to query the window server in order to determine the +// DSA drawing region for the video window. + +class CDummyAO : public CActive +{ +public: + CDummyAO() : CActive(CActive::EPriorityStandard) { CActiveScheduler::Add(this); } + void RunL() { } + void DoCancel() { } + TRequestStatus& Status() { return iStatus; } + void SetActive() { CActive::SetActive(); } +}; + +void getDsaRegion(RWsSession &session, const RWindowBase &window) +{ + RDirectScreenAccess dsa(session); + TInt err = dsa.Construct(); + CDummyAO ao; + RRegion* region; + err = dsa.Request(region, ao.Status(), window); + ao.SetActive(); + dsa.Close(); + ao.Cancel(); + if (region) { + qDebug() << "Phonon::MMF::getDsaRegion count" << region->Count(); + for (int i=0; i<region->Count(); ++i) { + const TRect& rect = region->RectangleList()[i]; + qDebug() << "Phonon::MMF::getDsaRegion rect" + << rect.iTl.iX << rect.iTl.iY << rect.iBr.iX << rect.iBr.iY; + } + region->Close(); + } +} + +#endif // QT_NO_DEBUG + +void MMF::DsaVideoPlayer::handleParametersChanged(VideoParameters parameters) +{ + TRACE_CONTEXT(DsaVideoPlayer::handleParametersChanged, EVideoInternal); + TRACE_ENTRY_0(); + +#ifndef QT_NO_DEBUG + getDsaRegion(m_wsSession, *m_window); +#endif + + static const TBool antialias = ETrue; + int err = KErrNone; + + if (parameters & ScaleFactors) { + TRAP(err, m_player->SetScaleFactorL(m_scaleWidth, m_scaleHeight, + antialias)); + if(KErrNone != err) { + TRACE("SetScaleFactorL (1) err %d", err); + setError(tr("Video display error"), err); + } + } + + if (KErrNone == err) { + if (parameters & WindowHandle || parameters & WindowScreenRect) { + TRAP(err, + m_player->SetDisplayWindowL(m_wsSession, m_screenDevice, + *m_window, + m_videoScreenRect, + m_videoScreenRect)); + } + + if (KErrNone != err) { + TRACE("SetDisplayWindowL err %d", err); + setError(tr("Video display error"), err); + } else { + m_dsaActive = true; + if (parameters & ScaleFactors) { + TRAP(err, m_player->SetScaleFactorL(m_scaleWidth, m_scaleHeight, + antialias)); + if (KErrNone != err) { + TRACE("SetScaleFactorL (2) err %d", err); + setError(tr("Video display error"), err); + } + } + } + } + + TRACE_EXIT_0(); +} + +void MMF::DsaVideoPlayer::startDirectScreenAccess() +{ + if (!m_dsaActive) { + TRAPD(err, m_player->StartDirectScreenAccessL()); + if (KErrNone == err) + m_dsaActive = true; + else + setError(tr("Video display error"), err); + } +} + +bool MMF::DsaVideoPlayer::stopDirectScreenAccess() +{ + const bool dsaWasActive = m_dsaActive; + if (m_dsaActive) { + TRAPD(err, m_player->StopDirectScreenAccessL()); + if (KErrNone == err) + m_dsaActive = false; + else + setError(tr("Video display error"), err); + } + return dsaWasActive; +} + +QT_END_NAMESPACE + diff --git a/src/3rdparty/phonon/mmf/videoplayer_dsa.h b/src/3rdparty/phonon/mmf/videoplayer_dsa.h new file mode 100644 index 0000000..45cc47d --- /dev/null +++ b/src/3rdparty/phonon/mmf/videoplayer_dsa.h @@ -0,0 +1,92 @@ +/* This file is part of the KDE project. + +Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). + +This library is free software: you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation, either version 2.1 or 3 of the License. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with this library. If not, see <http://www.gnu.org/licenses/>. + +*/ + +#ifndef PHONON_MMF_VIDEOPLAYER_DSA_H +#define PHONON_MMF_VIDEOPLAYER_DSA_H + +#include "abstractvideoplayer.h" + +QT_BEGIN_NAMESPACE + +namespace Phonon +{ +namespace MMF +{ + +/** + * @short Wrapper over the MMF video player utility (DSA version) + * + * This implementation is used on devices with the legacy graphics + * subsystem, which does not support surfaces. On such devices, + * video rendering is done via Direct Screen Access (DSA), whereby + * the video decoder writes directly to the framebuffer. To ensure + * that the window server and video decoder do not try to draw to + * the same screen region at the same time, the video subsystem + * first requests permission to perform DSA. If the window server + * needs to draw to this screen region (for example to display a + * message dialog), it first notifies the video subsystem that it + * must stop rendering to this region. + * + * @see SurfaceVideoPlayer + */ +class DsaVideoPlayer + : public AbstractVideoPlayer +{ + Q_OBJECT + +public: + // Factory function + static DsaVideoPlayer* create(MediaObject *parent = 0, + const AbstractPlayer *player = 0); + ~DsaVideoPlayer(); + +public Q_SLOTS: + void videoWindowScreenRectChanged(); + void suspendDirectScreenAccess(); + void resumeDirectScreenAccess(); + +private: + DsaVideoPlayer(MediaObject *parent, const AbstractPlayer *player); + + // AbstractVideoPlayer + void createPlayer(); + void initVideoOutput(); + void prepareCompleted(); + void handleVideoWindowChanged(); + void handleParametersChanged(VideoParameters parameters); + + void startDirectScreenAccess(); + bool stopDirectScreenAccess(); + +private: + bool m_dsaActive; + bool m_dsaWasActive; + + // Absolute screen rectangle on which video is displayed + TRect m_videoScreenRect; + +}; + +} +} + +QT_END_NAMESPACE + +#endif // !PHONON_MMF_VIDEOPLAYER_DSA_H + + diff --git a/src/3rdparty/phonon/mmf/videoplayer_surface.cpp b/src/3rdparty/phonon/mmf/videoplayer_surface.cpp new file mode 100644 index 0000000..5f234e5 --- /dev/null +++ b/src/3rdparty/phonon/mmf/videoplayer_surface.cpp @@ -0,0 +1,150 @@ +/* This file is part of the KDE project. + +Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). + +This library is free software: you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation, either version 2.1 or 3 of the License. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with this library. If not, see <http://www.gnu.org/licenses/>. + +*/ + +#include <videoplayer2.h> + +#include <QtCore/private/qcore_symbian_p.h> // for qt_QRect2TRect + +#include "utils.h" +#include "videooutput_surface.h" +#include "videoplayer_surface.h" + +QT_BEGIN_NAMESPACE + +using namespace Phonon; +using namespace Phonon::MMF; + +// Two-phase constructor idiom is used because construct() calls virtual +// functions and therefore cannot be called from the AbstractVideoPlayer +// C++ constructor. +SurfaceVideoPlayer* SurfaceVideoPlayer::create(MediaObject *parent, + const AbstractPlayer *player) +{ + QScopedPointer<SurfaceVideoPlayer> self(new SurfaceVideoPlayer(parent, player)); + self->construct(); + return self.take(); +} + +SurfaceVideoPlayer::SurfaceVideoPlayer(MediaObject *parent, const AbstractPlayer *player) + : AbstractVideoPlayer(parent, player) + , m_displayWindow(0) +{ + +} + +SurfaceVideoPlayer::~SurfaceVideoPlayer() +{ + +} + + +//----------------------------------------------------------------------------- +// Public functions +//----------------------------------------------------------------------------- + +void MMF::SurfaceVideoPlayer::videoWindowSizeChanged() +{ + updateScaleFactors(m_videoOutput->videoWindowSize()); +} + + +//----------------------------------------------------------------------------- +// Private functions +//----------------------------------------------------------------------------- + +void MMF::SurfaceVideoPlayer::createPlayer() +{ + const TInt priority = 0; + const TMdaPriorityPreference preference = EMdaPriorityPreferenceNone; + + CVideoPlayerUtility2 *player = 0; + QT_TRAP_THROWING(player = CVideoPlayerUtility2::NewL(*this, + priority, preference)); + m_player.reset(player); +} + +void MMF::SurfaceVideoPlayer::initVideoOutput() +{ + bool connected = connect( + m_videoOutput, SIGNAL(videoWindowSizeChanged()), + this, SLOT(videoWindowSizeChanged()) + ); + Q_ASSERT(connected); + + // Suppress warnings in release builds + Q_UNUSED(connected); + + AbstractVideoPlayer::initVideoOutput(); +} + +void MMF::SurfaceVideoPlayer::prepareCompleted() +{ + videoWindowSizeChanged(); +} + +void MMF::SurfaceVideoPlayer::handleVideoWindowChanged() +{ + parametersChanged(WindowHandle); +} + +void MMF::SurfaceVideoPlayer::handleParametersChanged(VideoParameters parameters) +{ + CVideoPlayerUtility2 *player = static_cast<CVideoPlayerUtility2 *>(m_player.data()); + + int err = KErrNone; + + TRect rect; + + if (m_videoOutput) { + m_videoOutput->dump(); + const QSize size = m_videoOutput->videoWindowSize(); + rect.SetSize(TSize(size.width(), size.height())); + } + + if (parameters & WindowHandle) { + if (m_displayWindow) + player->RemoveDisplayWindow(*m_displayWindow); + + RWindow *window = static_cast<RWindow *>(m_window); + if (window) { + window->SetBackgroundColor(TRgb(0, 0, 0, 255)); + TRAP(err, player->AddDisplayWindowL(m_wsSession, m_screenDevice, *window, rect, rect)); + if (KErrNone != err) { + setError(tr("Video display error"), err); + window = 0; + } + } + m_displayWindow = window; + } + + if (KErrNone == err) { + if (parameters & ScaleFactors) { + Q_ASSERT(m_displayWindow); + TRAP(err, player->SetVideoExtentL(*m_displayWindow, rect)); + if (KErrNone == err) + TRAP(err, player->SetWindowClipRectL(*m_displayWindow, rect)); + if (KErrNone == err) + TRAP(err, player->SetScaleFactorL(*m_displayWindow, m_scaleWidth, m_scaleHeight)); + if (KErrNone != err) + setError(tr("Video display error"), err); + } + } +} + +QT_END_NAMESPACE + diff --git a/src/3rdparty/phonon/mmf/videoplayer_surface.h b/src/3rdparty/phonon/mmf/videoplayer_surface.h new file mode 100644 index 0000000..c05da9c --- /dev/null +++ b/src/3rdparty/phonon/mmf/videoplayer_surface.h @@ -0,0 +1,78 @@ +/* This file is part of the KDE project. + +Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). + +This library is free software: you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation, either version 2.1 or 3 of the License. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with this library. If not, see <http://www.gnu.org/licenses/>. + +*/ + +#ifndef PHONON_MMF_VIDEOPLAYER_SURFACE_H +#define PHONON_MMF_VIDEOPLAYER_SURFACE_H + +#include "abstractvideoplayer.h" + +class RWindow; + +QT_BEGIN_NAMESPACE + +namespace Phonon +{ +namespace MMF +{ + +/** + * @short Wrapper over the MMF video player utility (surface version) + * + * This implementation is used on devices with a graphics subsystem which + * supports surfaces. + * + * @see DsaVideoPlayer + */ +class SurfaceVideoPlayer + : public AbstractVideoPlayer +{ + Q_OBJECT + +public: + // Factory function + static SurfaceVideoPlayer* create(MediaObject *parent = 0, + const AbstractPlayer *player = 0); + ~SurfaceVideoPlayer(); + +public Q_SLOTS: + void videoWindowSizeChanged(); + +private: + SurfaceVideoPlayer(MediaObject *parent, const AbstractPlayer *player); + + // AbstractVideoPlayer + void createPlayer(); + void initVideoOutput(); + void prepareCompleted(); + void handleVideoWindowChanged(); + void handleParametersChanged(VideoParameters parameters); + +private: + // Window handle which has been passed to the MMF via + // CVideoPlayerUtility2::SetDisplayWindowL + RWindow* m_displayWindow; + +}; + +} +} + +QT_END_NAMESPACE + +#endif // !PHONON_MMF_VIDEOPLAYER_SURFACE_H + diff --git a/src/3rdparty/phonon/mmf/videowidget.cpp b/src/3rdparty/phonon/mmf/videowidget.cpp index bc9acfd..4ed9979 100644 --- a/src/3rdparty/phonon/mmf/videowidget.cpp +++ b/src/3rdparty/phonon/mmf/videowidget.cpp @@ -18,10 +18,15 @@ along with this library. If not, see <http://www.gnu.org/licenses/>. #include "mediaobject.h" #include "utils.h" -#include "videooutput.h" #include "videowidget.h" +#ifdef PHONON_MMF_VIDEO_SURFACES +#include "videooutput_surface.h" +#else +#include "videooutput_dsa.h" +#endif + QT_BEGIN_NAMESPACE using namespace Phonon; @@ -45,10 +50,13 @@ static const qreal DefaultSaturation = 1.0; // Constructor / destructor //----------------------------------------------------------------------------- -MMF::VideoWidget::VideoWidget - (AncestorMoveMonitor* ancestorMoveMonitor, QWidget* parent) +MMF::VideoWidget::VideoWidget(QWidget *parent) : MediaNode(parent) - , m_videoOutput(new VideoOutput(ancestorMoveMonitor, parent)) +#ifdef PHONON_MMF_VIDEO_SURFACES + , m_videoOutput(new SurfaceVideoOutput(parent)) +#else + , m_videoOutput(new DsaVideoOutput(parent)) +#endif , m_brightness(DefaultBrightness) , m_contrast(DefaultContrast) , m_hue(DefaultHue) @@ -68,6 +76,13 @@ MMF::VideoWidget::~VideoWidget() TRACE_EXIT_0(); } +#ifndef PHONON_MMF_VIDEO_SURFACES +void MMF::VideoWidget::setAncestorMoveMonitor(AncestorMoveMonitor *monitor) +{ + static_cast<DsaVideoOutput *>(m_videoOutput.data())->setAncestorMoveMonitor(monitor); +} +#endif + //----------------------------------------------------------------------------- // VideoWidgetInterface diff --git a/src/3rdparty/phonon/mmf/videowidget.h b/src/3rdparty/phonon/mmf/videowidget.h index 899dca6..3b6283e 100644 --- a/src/3rdparty/phonon/mmf/videowidget.h +++ b/src/3rdparty/phonon/mmf/videowidget.h @@ -19,8 +19,8 @@ along with this library. If not, see <http://www.gnu.org/licenses/>. #ifndef PHONON_MMF_VIDEOWIDGET_H #define PHONON_MMF_VIDEOWIDGET_H +#include "abstractvideooutput.h" #include "mmf_medianode.h" -#include "videooutput.h" #include <QtGui/QWidget> #include <phonon/videowidget.h> @@ -32,8 +32,9 @@ namespace Phonon { namespace MMF { +#ifndef PHONON_MMF_VIDEO_SURFACES class AncestorMoveMonitor; -class VideoOutput; +#endif class VideoWidget : public MediaNode , public Phonon::VideoWidgetInterface @@ -42,9 +43,13 @@ class VideoWidget : public MediaNode Q_INTERFACES(Phonon::VideoWidgetInterface) public: - VideoWidget(AncestorMoveMonitor* ancestorMoveMonitor, QWidget* parent); + VideoWidget(QWidget* parent); ~VideoWidget(); +#ifndef PHONON_MMF_VIDEO_SURFACES + void setAncestorMoveMonitor(AncestorMoveMonitor *ancestorMoveMonitor); +#endif + // VideoWidgetInterface virtual Phonon::VideoWidget::AspectRatio aspectRatio() const; virtual void setAspectRatio(Phonon::VideoWidget::AspectRatio aspectRatio); @@ -66,7 +71,7 @@ protected: void disconnectMediaObject(MediaObject *mediaObject); private: - QScopedPointer<VideoOutput> m_videoOutput; + QScopedPointer<AbstractVideoOutput> m_videoOutput; qreal m_brightness; qreal m_contrast; diff --git a/src/3rdparty/webkit/WebKit/qt/Api/qgraphicswebview.cpp b/src/3rdparty/webkit/WebKit/qt/Api/qgraphicswebview.cpp index ceb5ee1..a80c5d3 100644 --- a/src/3rdparty/webkit/WebKit/qt/Api/qgraphicswebview.cpp +++ b/src/3rdparty/webkit/WebKit/qt/Api/qgraphicswebview.cpp @@ -30,6 +30,7 @@ #include <QtGui/qapplication.h> #include <QtGui/qgraphicssceneevent.h> #include <QtGui/qstyleoption.h> +#include <QtGui/qinputcontext.h> #if defined(Q_WS_X11) #include <QX11Info> #endif @@ -63,6 +64,8 @@ public: void _q_doLoadFinished(bool success); + void _q_updateMicroFocus(); + QGraphicsWebView* q; QWebPage* page; }; @@ -80,6 +83,20 @@ void QGraphicsWebViewPrivate::_q_doLoadFinished(bool success) emit q->loadFinished(success); } +void QGraphicsWebViewPrivate::_q_updateMicroFocus() +{ +#if !defined(QT_NO_IM) && (defined(Q_WS_X11) || defined(Q_WS_QWS) || defined(Q_OS_SYMBIAN)) + // Ideally, this should be handled by a common call to an updateMicroFocus function + // in QGraphicsItem. See http://bugreports.qt.nokia.com/browse/QTBUG-7578. + QList<QGraphicsView*> views = q->scene()->views(); + for (int c = 0; c < views.size(); ++c) { + QInputContext* ic = views.at(c)->inputContext(); + if (ic) + ic->update(); + } +#endif +} + void QGraphicsWebViewPrivate::scroll(int dx, int dy, const QRect& rectToScroll) { q->scroll(qreal(dx), qreal(dy), QRectF(rectToScroll)); @@ -435,6 +452,8 @@ void QGraphicsWebView::setPage(QWebPage* page) this, SIGNAL(statusBarMessage(QString))); connect(d->page, SIGNAL(linkClicked(QUrl)), this, SIGNAL(linkClicked(QUrl))); + connect(d->page, SIGNAL(microFocusChanged()), + this, SLOT(_q_updateMicroFocus())); } /*! diff --git a/src/3rdparty/webkit/WebKit/qt/Api/qgraphicswebview.h b/src/3rdparty/webkit/WebKit/qt/Api/qgraphicswebview.h index f3afb4c..68379a2 100644 --- a/src/3rdparty/webkit/WebKit/qt/Api/qgraphicswebview.h +++ b/src/3rdparty/webkit/WebKit/qt/Api/qgraphicswebview.h @@ -140,3 +140,4 @@ private: }; #endif // QGraphicsWebView_h + Q_PRIVATE_SLOT(d, void _q_updateMicroFocus()) diff --git a/src/3rdparty/webkit/WebKit/qt/ChangeLog b/src/3rdparty/webkit/WebKit/qt/ChangeLog index e54c176..a5441cd 100644 --- a/src/3rdparty/webkit/WebKit/qt/ChangeLog +++ b/src/3rdparty/webkit/WebKit/qt/ChangeLog @@ -1,3 +1,15 @@ +2010-03-21 Kristian Amlie <kristian.amlie@nokia.com> + + Reviewed by Simon Hausmann. + + Fixed updating the VKB display when inputting into QGraphicsWebView. + https://bugs.webkit.org/show_bug.cgi?id=36292 + + * Api/qgraphicswebview.cpp: + (QGraphicsWebViewPrivate::_q_updateMicroFocus): + (QGraphicsWebView::setPage): + * Api/qgraphicswebview.h: + 2010-03-04 Simon Hausmann <simon.hausmann@nokia.com> Reviewed by Kenneth Rohde Christiansen. diff --git a/src/corelib/animation/qanimationgroup.cpp b/src/corelib/animation/qanimationgroup.cpp index a89f949..2decda3 100644 --- a/src/corelib/animation/qanimationgroup.cpp +++ b/src/corelib/animation/qanimationgroup.cpp @@ -244,7 +244,7 @@ QAbstractAnimation *QAnimationGroup::takeAnimation(int index) // in ChildRemoved event d->animations.removeAt(index); animation->setParent(0); - d->animationRemovedAt(index); + d->animationRemoved(index, animation); return animation; } @@ -285,7 +285,7 @@ bool QAnimationGroup::event(QEvent *event) } -void QAnimationGroupPrivate::animationRemovedAt(int index) +void QAnimationGroupPrivate::animationRemoved(int index, QAbstractAnimation *) { Q_Q(QAnimationGroup); Q_UNUSED(index); diff --git a/src/corelib/animation/qanimationgroup_p.h b/src/corelib/animation/qanimationgroup_p.h index 394773b..45603b3 100644 --- a/src/corelib/animation/qanimationgroup_p.h +++ b/src/corelib/animation/qanimationgroup_p.h @@ -72,8 +72,19 @@ public: isGroup = true; } - virtual void animationInsertedAt(int index) { Q_UNUSED(index) }; - virtual void animationRemovedAt(int index); + virtual void animationInsertedAt(int) { } + virtual void animationRemoved(int, QAbstractAnimation *); + + void disconnectUncontrolledAnimation(QAbstractAnimation *anim) + { + //0 for the signal here because we might be called from the animation destructor + QObject::disconnect(anim, 0, q_func(), SLOT(_q_uncontrolledAnimationFinished())); + } + + void connectUncontrolledAnimation(QAbstractAnimation *anim) + { + QObject::connect(anim, SIGNAL(finished()), q_func(), SLOT(_q_uncontrolledAnimationFinished())); + } QList<QAbstractAnimation *> animations; }; diff --git a/src/corelib/animation/qparallelanimationgroup.cpp b/src/corelib/animation/qparallelanimationgroup.cpp index eaa0364..280afed 100644 --- a/src/corelib/animation/qparallelanimationgroup.cpp +++ b/src/corelib/animation/qparallelanimationgroup.cpp @@ -246,11 +246,9 @@ void QParallelAnimationGroupPrivate::_q_uncontrolledAnimationFinished() void QParallelAnimationGroupPrivate::disconnectUncontrolledAnimations() { - Q_Q(QParallelAnimationGroup); - QHash<QAbstractAnimation *, int>::iterator it = uncontrolledFinishTime.begin(); while (it != uncontrolledFinishTime.end()) { - QObject::disconnect(it.key(), SIGNAL(finished()), q, SLOT(_q_uncontrolledAnimationFinished())); + disconnectUncontrolledAnimation(it.key()); ++it; } @@ -259,13 +257,11 @@ void QParallelAnimationGroupPrivate::disconnectUncontrolledAnimations() void QParallelAnimationGroupPrivate::connectUncontrolledAnimations() { - Q_Q(QParallelAnimationGroup); - for (int i = 0; i < animations.size(); ++i) { QAbstractAnimation *animation = animations.at(i); if (animation->duration() == -1 || animation->loopCount() < 0) { uncontrolledFinishTime[animation] = -1; - QObject::connect(animation, SIGNAL(finished()), q, SLOT(_q_uncontrolledAnimationFinished())); + connectUncontrolledAnimation(animation); } } } @@ -305,6 +301,13 @@ bool QParallelAnimationGroupPrivate::isUncontrolledAnimationFinished(QAbstractAn return uncontrolledFinishTime.value(anim, -1) >= 0; } +void QParallelAnimationGroupPrivate::animationRemoved(int index, QAbstractAnimation *anim) +{ + QAnimationGroupPrivate::animationRemoved(index, anim); + disconnectUncontrolledAnimation(anim); + uncontrolledFinishTime.remove(anim); +} + /*! \reimp */ diff --git a/src/corelib/animation/qparallelanimationgroup_p.h b/src/corelib/animation/qparallelanimationgroup_p.h index a74d496..cab4fa9 100644 --- a/src/corelib/animation/qparallelanimationgroup_p.h +++ b/src/corelib/animation/qparallelanimationgroup_p.h @@ -80,6 +80,8 @@ public: void connectUncontrolledAnimations(); void disconnectUncontrolledAnimations(); + void animationRemoved(int index, QAbstractAnimation *); + // private slot void _q_uncontrolledAnimationFinished(); }; diff --git a/src/corelib/animation/qsequentialanimationgroup.cpp b/src/corelib/animation/qsequentialanimationgroup.cpp index 8ab084a..7617c1f 100644 --- a/src/corelib/animation/qsequentialanimationgroup.cpp +++ b/src/corelib/animation/qsequentialanimationgroup.cpp @@ -479,7 +479,7 @@ void QSequentialAnimationGroupPrivate::activateCurrentAnimation(bool intermediat // connects to the finish signal of uncontrolled animations if (currentAnimation->totalDuration() == -1) - QObject::connect(currentAnimation, SIGNAL(finished()), q, SLOT(_q_uncontrolledAnimationFinished())); + connectUncontrolledAnimation(currentAnimation); currentAnimation->start(); if (!intermediate && state == QSequentialAnimationGroup::Paused) @@ -496,7 +496,7 @@ void QSequentialAnimationGroupPrivate::_q_uncontrolledAnimationFinished() actualDuration.append(-1); actualDuration[currentAnimationIndex] = currentAnimation->currentTime(); - QObject::disconnect(currentAnimation, SIGNAL(finished()), q, SLOT(_q_uncontrolledAnimationFinished())); + disconnectUncontrolledAnimation(currentAnimation); if ((direction == QAbstractAnimation::Forward && currentAnimation == animations.last()) || (direction == QAbstractAnimation::Backward && currentAnimationIndex == 0)) { @@ -543,10 +543,10 @@ void QSequentialAnimationGroupPrivate::animationInsertedAt(int index) the group at index \a index. The animation is no more listed when this method is called. */ -void QSequentialAnimationGroupPrivate::animationRemovedAt(int index) +void QSequentialAnimationGroupPrivate::animationRemoved(int index, QAbstractAnimation *anim) { Q_Q(QSequentialAnimationGroup); - QAnimationGroupPrivate::animationRemovedAt(index); + QAnimationGroupPrivate::animationRemoved(index, anim); Q_ASSERT(currentAnimation); // currentAnimation should always be set @@ -555,7 +555,10 @@ void QSequentialAnimationGroupPrivate::animationRemovedAt(int index) const int currentIndex = animations.indexOf(currentAnimation); if (currentIndex == -1) { - //we're removing the current animation, let's update it to another one + //we're removing the current animation + + disconnectUncontrolledAnimation(currentAnimation); + if (index < animations.count()) setCurrentAnimation(index); //let's try to take the next one else if (index > 0) diff --git a/src/corelib/animation/qsequentialanimationgroup_p.h b/src/corelib/animation/qsequentialanimationgroup_p.h index a55e136..de69916 100644 --- a/src/corelib/animation/qsequentialanimationgroup_p.h +++ b/src/corelib/animation/qsequentialanimationgroup_p.h @@ -85,7 +85,7 @@ public: void activateCurrentAnimation(bool intermediate = false); void animationInsertedAt(int index); - void animationRemovedAt(int index); + void animationRemoved(int index, QAbstractAnimation *anim); bool atEnd() const; diff --git a/src/corelib/global/qglobal.h b/src/corelib/global/qglobal.h index 6437fb7..3118f8f 100644 --- a/src/corelib/global/qglobal.h +++ b/src/corelib/global/qglobal.h @@ -2429,12 +2429,15 @@ QT3_SUPPORT Q_CORE_EXPORT const char *qInstallPathSysconf(); #define Q_SYMBIAN_FIXED_POINTER_CURSORS #define Q_SYMBIAN_HAS_EXTENDED_BITMAP_TYPE #define Q_SYMBIAN_WINDOW_SIZE_CACHE -//enabling new graphics resources -#define QT_SYMBIAN_SUPPORTS_SGIMAGE #define QT_SYMBIAN_SUPPORTS_ADVANCED_POINTER +//enabling new graphics resources +#ifdef SYMBIAN_GRAPHICS_EGL_SGIMAGELITE +# define QT_SYMBIAN_SUPPORTS_SGIMAGE +#endif + #ifdef SYMBIAN_GRAPHICS_WSERV_QT_EFFECTS -#define Q_SYMBIAN_SEMITRANSPARENT_BG_SURFACE +# define Q_SYMBIAN_SEMITRANSPARENT_BG_SURFACE #endif #endif diff --git a/src/corelib/io/qprocess_symbian.cpp b/src/corelib/io/qprocess_symbian.cpp index 8902f7d..92212fe 100644 --- a/src/corelib/io/qprocess_symbian.cpp +++ b/src/corelib/io/qprocess_symbian.cpp @@ -237,11 +237,15 @@ static void qt_create_symbian_commandline(const QStringList &arguments, QString --i; endQuote += QLatin1String("\\"); } - commandLine += QLatin1String(" \"") + tmp.left(i) + endQuote; + commandLine += QLatin1String("\"") + tmp.left(i) + endQuote + QLatin1Char(' '); } else { - commandLine += QLatin1Char(' ') + tmp; + commandLine += tmp + QLatin1Char(' '); } } + + // Chop the extra trailing space if any arguments were appended + if (arguments.size()) + commandLine.chop(1); } static TInt qt_create_symbian_process(RProcess **proc, const QString &programName, const QStringList &arguments) diff --git a/src/corelib/kernel/qcore_symbian_p.cpp b/src/corelib/kernel/qcore_symbian_p.cpp index 0257ac4..402eccf 100644 --- a/src/corelib/kernel/qcore_symbian_p.cpp +++ b/src/corelib/kernel/qcore_symbian_p.cpp @@ -132,9 +132,10 @@ private: void init() { #ifdef Q_WS_S60 - _LIT(KLibName_3_1, "qts60plugin_3_1.dll"); - _LIT(KLibName_3_2, "qts60plugin_3_2.dll"); - _LIT(KLibName_5_0, "qts60plugin_5_0.dll"); + _LIT(KLibName_3_1, "qts60plugin_3_1" QT_LIBINFIX_UNICODE L".dll"); + _LIT(KLibName_3_2, "qts60plugin_3_2" QT_LIBINFIX_UNICODE L".dll"); + _LIT(KLibName_5_0, "qts60plugin_5_0" QT_LIBINFIX_UNICODE L".dll"); + TPtrC libName; TInt uidValue; switch (QSysInfo::s60Version()) { diff --git a/src/corelib/kernel/qcore_symbian_p.h b/src/corelib/kernel/qcore_symbian_p.h index 9f282d5..4a515ce 100644 --- a/src/corelib/kernel/qcore_symbian_p.h +++ b/src/corelib/kernel/qcore_symbian_p.h @@ -60,6 +60,15 @@ #include <qhash.h> #include <f32file.h> +#define QT_LSTRING2(x) L##x +#define QT_LSTRING(x) QT_LSTRING2(x) + +#if defined(QT_LIBINFIX) +# define QT_LIBINFIX_UNICODE QT_LSTRING(QT_LIBINFIX) +#else +# define QT_LIBINFIX_UNICODE L"" +#endif + QT_BEGIN_HEADER QT_BEGIN_NAMESPACE diff --git a/src/corelib/kernel/qobjectdefs.h b/src/corelib/kernel/qobjectdefs.h index b045c42..555a1f5 100644 --- a/src/corelib/kernel/qobjectdefs.h +++ b/src/corelib/kernel/qobjectdefs.h @@ -78,6 +78,7 @@ class QString; #define Q_CLASSINFO(name, value) #define Q_INTERFACES(x) #define Q_PROPERTY(text) +#define Q_PRIVATE_PROPERTY(d, text) #define Q_OVERRIDE(text) #define Q_ENUMS(x) #define Q_FLAGS(x) @@ -178,6 +179,7 @@ private: #define Q_CLASSINFO(name, value) Q_CLASSINFO(name, value) #define Q_INTERFACES(x) Q_INTERFACES(x) #define Q_PROPERTY(text) Q_PROPERTY(text) +#define Q_PRIVATE_PROPERTY(d, text) Q_PRIVATE_PROPERTY(d, text) #define Q_OVERRIDE(text) Q_OVERRIDE(text) #define Q_ENUMS(x) Q_ENUMS(x) #define Q_FLAGS(x) Q_FLAGS(x) diff --git a/src/declarative/QmlChanges.txt b/src/declarative/QmlChanges.txt index 7c584b4d..1d96688 100644 --- a/src/declarative/QmlChanges.txt +++ b/src/declarative/QmlChanges.txt @@ -10,6 +10,7 @@ Removed DateTimeFormatter (use Qt.formatDateTime() instead) Using WebView now requires "import org.webkit 1.0" Using Particles now requires "import Qt.labs.particles 1.0" AnchorAnimation must now be used to animate anchor changes (and not NumberAnimation) +Removed ParentAction (use ParentAnimation instead) C++ API ------- @@ -25,6 +26,44 @@ syntax has been introduced: Item { Behavior on x {}; NumberAnimation on y {} } Only the syntax has changed, the behavior is identical. +Script element removed +---------------------- +Inline Script{} blocks have been deprecated, and will soon be removed entirely. +If you used Script to write inline javascript code, it can simply be removed. +For example + +Item { + Script { + function doSomething() {} + } +} + +becomes + +Item { + function doSomething() {} +} + +If you used Script to include external JavaScript files, you can replace the +Script element with an “import” line. For example + +MouseArea { + Script { + source: “foo.js” + } + onClicked: foo() +} + +becomes + +Import “foo.js” as Foo +MouseArea { + onClicked: Foo.foo() +} + +The “as” qualifier is mandatory for script imports (as opposed to type +imports where it is optional). + ============================================================================= The changes below are pre Qt 4.7.0 alpha diff --git a/src/declarative/graphicsitems/qdeclarativeloader.cpp b/src/declarative/graphicsitems/qdeclarativeloader.cpp index 745734e..3cbafd6 100644 --- a/src/declarative/graphicsitems/qdeclarativeloader.cpp +++ b/src/declarative/graphicsitems/qdeclarativeloader.cpp @@ -185,6 +185,9 @@ void QDeclarativeLoader::setSource(const QUrl &url) if (d->source == url) return; + if (!qmlContext(this)->isSafeOrigin(url)) + return; + d->clear(); d->source = url; diff --git a/src/declarative/graphicsitems/qdeclarativetextinput.cpp b/src/declarative/graphicsitems/qdeclarativetextinput.cpp index 01167dc..b049728 100644 --- a/src/declarative/graphicsitems/qdeclarativetextinput.cpp +++ b/src/declarative/graphicsitems/qdeclarativetextinput.cpp @@ -220,6 +220,7 @@ void QDeclarativeTextInput::setHAlign(HAlignment align) if(align == d->hAlign) return; d->hAlign = align; + updateRect(); emit horizontalAlignmentChanged(d->hAlign); } diff --git a/src/declarative/qml/parser/qdeclarativejs.g b/src/declarative/qml/parser/qdeclarativejs.g index 493ad25..0256c52 100644 --- a/src/declarative/qml/parser/qdeclarativejs.g +++ b/src/declarative/qml/parser/qdeclarativejs.g @@ -665,7 +665,9 @@ case $rule_number: { sym(1).Node = node; - if (! node) { + if (node) { + node->importToken = loc(1); + } else { diagnostic_messages.append(DiagnosticMessage(DiagnosticMessage::Error, loc(1), QLatin1String("Expected a qualified name id or a string literal"))); diff --git a/src/declarative/qml/parser/qdeclarativejsparser.cpp b/src/declarative/qml/parser/qdeclarativejsparser.cpp index c86e047..9205ef4 100644 --- a/src/declarative/qml/parser/qdeclarativejsparser.cpp +++ b/src/declarative/qml/parser/qdeclarativejsparser.cpp @@ -284,7 +284,9 @@ case 20: { sym(1).Node = node; - if (! node) { + if (node) { + node->importToken = loc(1); + } else { diagnostic_messages.append(DiagnosticMessage(DiagnosticMessage::Error, loc(1), QLatin1String("Expected a qualified name id or a string literal"))); diff --git a/src/declarative/qml/qdeclarativecompiler.cpp b/src/declarative/qml/qdeclarativecompiler.cpp index 28c2210..e668553 100644 --- a/src/declarative/qml/qdeclarativecompiler.cpp +++ b/src/declarative/qml/qdeclarativecompiler.cpp @@ -2131,7 +2131,7 @@ bool QDeclarativeCompiler::buildPropertyOnAssignment(QDeclarativeParser::Propert buildDynamicMeta(baseObj, ForceCreation); v->type = isPropertyValue ? Value::ValueSource : Value::ValueInterceptor; } else { - COMPILE_EXCEPTION(v, QCoreApplication::translate("QDeclarativeCompiler","\"%1\" cannot operate on \"%2\"").arg(v->object->typeName.constData()).arg(prop->name.constData())); + COMPILE_EXCEPTION(v, QCoreApplication::translate("QDeclarativeCompiler","\"%1\" cannot operate on \"%2\"").arg(QString::fromUtf8(v->object->typeName)).arg(QString::fromUtf8(prop->name))); } return true; diff --git a/src/declarative/qml/qdeclarativecompositetypemanager.cpp b/src/declarative/qml/qdeclarativecompositetypemanager.cpp index c883805..c59e5e2 100644 --- a/src/declarative/qml/qdeclarativecompositetypemanager.cpp +++ b/src/declarative/qml/qdeclarativecompositetypemanager.cpp @@ -570,12 +570,15 @@ int QDeclarativeCompositeTypeManager::resolveTypes(QDeclarativeCompositeTypeData } } + QString errorString; if (!QDeclarativeEnginePrivate::get(engine)-> - addToImport(&unit->imports, qmldircomponentsnetwork, imp.uri, imp.qualifier, vmaj, vmin, imp.type)) + addToImport(&unit->imports, qmldircomponentsnetwork, imp.uri, imp.qualifier, vmaj, vmin, imp.type, &errorString)) { QDeclarativeError error; error.setUrl(unit->imports.baseUrl()); - error.setDescription(tr("Import %1 unavailable").arg(imp.uri)); + error.setDescription(errorString); + error.setLine(imp.location.start.line); + error.setColumn(imp.location.start.column); unit->status = QDeclarativeCompositeTypeData::Error; unit->errorType = QDeclarativeCompositeTypeData::GeneralError; unit->errors << error; @@ -605,7 +608,8 @@ int QDeclarativeCompositeTypeManager::resolveTypes(QDeclarativeCompositeTypeData QLatin1String("."), QString(), -1, -1, - QDeclarativeScriptParser::Import::File); + QDeclarativeScriptParser::Import::File, + 0); // error ignored (just means no fallback) } diff --git a/src/declarative/qml/qdeclarativecontext.cpp b/src/declarative/qml/qdeclarativecontext.cpp index 85896c4..ab3849a 100644 --- a/src/declarative/qml/qdeclarativecontext.cpp +++ b/src/declarative/qml/qdeclarativecontext.cpp @@ -361,6 +361,22 @@ QVariant QDeclarativeContext::contextProperty(const QString &name) const return value; } +bool QDeclarativeContext::isSafeOrigin(const QUrl &src) const +{ + if (src.isRelative()) + return true; + if (src.scheme()==QLatin1String("https")) + return true; + + QUrl base = baseUrl(); + if (src.host() == base.host() && src.port() == base.port()) // including files (with no host) + return true; + + qWarning() << src << "is not a safe origin from" << base; + + return false; +} + /*! Resolves the URL \a src relative to the URL of the containing component. diff --git a/src/declarative/qml/qdeclarativecontext.h b/src/declarative/qml/qdeclarativecontext.h index a349628..959af8b 100644 --- a/src/declarative/qml/qdeclarativecontext.h +++ b/src/declarative/qml/qdeclarativecontext.h @@ -85,6 +85,8 @@ public: void setBaseUrl(const QUrl &); QUrl baseUrl() const; + bool isSafeOrigin(const QUrl &src) const; + private: friend class QDeclarativeVME; friend class QDeclarativeEngine; diff --git a/src/declarative/qml/qdeclarativecontext_p.h b/src/declarative/qml/qdeclarativecontext_p.h index ecf3ec8..f07045e 100644 --- a/src/declarative/qml/qdeclarativecontext_p.h +++ b/src/declarative/qml/qdeclarativecontext_p.h @@ -81,7 +81,7 @@ class QDeclarativeBinding_Id; class QDeclarativeCompiledBindings; class QDeclarativeContextData; -class Q_DECLARATIVE_EXPORT QDeclarativeContextPrivate : public QObjectPrivate +class QDeclarativeContextPrivate : public QObjectPrivate { Q_DECLARE_PUBLIC(QDeclarativeContext) public: diff --git a/src/declarative/qml/qdeclarativeengine.cpp b/src/declarative/qml/qdeclarativeengine.cpp index 0bedbeb..d4872e2 100644 --- a/src/declarative/qml/qdeclarativeengine.cpp +++ b/src/declarative/qml/qdeclarativeengine.cpp @@ -1418,6 +1418,11 @@ struct QDeclarativeEnginePrivate::ImportedNamespace { } }; +static bool greaterThan(const QString &s1, const QString &s2) +{ + return s1 > s2; +} + class QDeclarativeImportsPrivate { public: QDeclarativeImportsPrivate() : ref(1) @@ -1495,6 +1500,8 @@ public: // add fileImportPath last, this is *not* search order. paths += QDeclarativeEnginePrivate::get(engine)->fileImportPath; + qSort(paths.begin(), paths.end(), greaterThan); // Ensure subdirs preceed their parents. + QString stableRelativePath = dir; foreach( QString path, paths) { if (dir.startsWith(path)) { @@ -1510,7 +1517,7 @@ public: - bool add(const QUrl& base, const QDeclarativeDirComponents &qmldircomponentsnetwork, const QString& uri_arg, const QString& prefix, int vmaj, int vmin, QDeclarativeScriptParser::Import::Type importType, QDeclarativeEngine *engine) + bool add(const QUrl& base, const QDeclarativeDirComponents &qmldircomponentsnetwork, const QString& uri_arg, const QString& prefix, int vmaj, int vmin, QDeclarativeScriptParser::Import::Type importType, QDeclarativeEngine *engine, QString *errorString) { QDeclarativeDirComponents qmldircomponents = qmldircomponentsnetwork; QString uri = uri_arg; @@ -1545,11 +1552,11 @@ public: paths += applicationDirPath; paths += QDeclarativeEnginePrivate::get(engine)->environmentImportPath; - #if (QT_VERSION >= QT_VERSION_CHECK(4,7,0)) +#if (QT_VERSION >= QT_VERSION_CHECK(4,7,0)) QString builtinPath = QLibraryInfo::location(QLibraryInfo::ImportsPath); - #else +#else QString builtinPath; - #endif +#endif if (!builtinPath.isEmpty()) paths += builtinPath; @@ -1569,12 +1576,31 @@ public: } } + if (!found) { + found = QDeclarativeMetaType::isModule(uri.toUtf8(), vmaj, vmin); + if (!found) { + if (errorString) { + bool anyversion = QDeclarativeMetaType::isModule(uri.toUtf8(), 0, 0); + if (anyversion) + *errorString = QDeclarativeEngine::tr("module \"%1\" version %2.%3 is not installed").arg(uri_arg).arg(vmaj).arg(vmin); + else + *errorString = QDeclarativeEngine::tr("module \"%1\" is not installed").arg(uri_arg); + } + return false; + } + } } else { if (importType == QDeclarativeScriptParser::Import::File && qmldircomponents.isEmpty()) { QUrl importUrl = base.resolved(QUrl(uri + QLatin1String("/qmldir"))); QString localFileOrQrc = toLocalFileOrQrc(importUrl); if (!localFileOrQrc.isEmpty()) { + QString dir = toLocalFileOrQrc(base.resolved(QUrl(uri))); + if (dir.isEmpty() || !QDir().exists(dir)) { + if (errorString) + *errorString = QDeclarativeEngine::tr("\"%1\": no such directory").arg(uri_arg); + return false; // local import dirs must exist + } uri = resolvedUri(toLocalFileOrQrc(base.resolved(QUrl(uri))), engine); qmldircomponents = importExtension(localFileOrQrc, uri, @@ -1582,6 +1608,20 @@ public: if (uri.endsWith(QLatin1Char('/'))) uri.chop(1); + } else { + if (prefix.isEmpty()) { + // directory must at least exist for valid import + QString localFileOrQrc = toLocalFileOrQrc(base.resolved(QUrl(uri))); + if (localFileOrQrc.isEmpty() || !QDir().exists(localFileOrQrc)) { + if (errorString) { + if (localFileOrQrc.isEmpty()) + *errorString = QDeclarativeEngine::tr("import \"%1\" has no qmldir and no namespace").arg(uri); + else + *errorString = QDeclarativeEngine::tr("\"%1\": no such directory").arg(uri); + } + return false; + } + } } } @@ -1955,12 +1995,12 @@ QString QDeclarativeEnginePrivate::resolvePlugin(const QDir &dir, const QString The base URL must already have been set with Import::setBaseUrl(). */ -bool QDeclarativeEnginePrivate::addToImport(Imports* imports, const QDeclarativeDirComponents &qmldircomponentsnetwork, const QString& uri, const QString& prefix, int vmaj, int vmin, QDeclarativeScriptParser::Import::Type importType) const +bool QDeclarativeEnginePrivate::addToImport(Imports* imports, const QDeclarativeDirComponents &qmldircomponentsnetwork, const QString& uri, const QString& prefix, int vmaj, int vmin, QDeclarativeScriptParser::Import::Type importType, QString *errorString) const { QDeclarativeEngine *engine = QDeclarativeEnginePrivate::get(const_cast<QDeclarativeEnginePrivate *>(this)); if (qmlImportTrace()) qDebug().nospace() << "QDeclarativeEngine::addToImport " << imports << " " << uri << " " << vmaj << '.' << vmin << " " << (importType==QDeclarativeScriptParser::Import::Library? "Library" : "File") << " as " << prefix; - bool ok = imports->d->add(imports->d->base,qmldircomponentsnetwork, uri,prefix,vmaj,vmin,importType, engine); + bool ok = imports->d->add(imports->d->base,qmldircomponentsnetwork, uri,prefix,vmaj,vmin,importType, engine, errorString); return ok; } diff --git a/src/declarative/qml/qdeclarativeengine_p.h b/src/declarative/qml/qdeclarativeengine_p.h index 6532d30..06b5027 100644 --- a/src/declarative/qml/qdeclarativeengine_p.h +++ b/src/declarative/qml/qdeclarativeengine_p.h @@ -283,7 +283,8 @@ public: bool addToImport(Imports*, const QDeclarativeDirComponents &qmldircomponentsnetwork, const QString& uri, const QString& prefix, int vmaj, int vmin, - QDeclarativeScriptParser::Import::Type importType) const; + QDeclarativeScriptParser::Import::Type importType, + QString *errorString) const; bool resolveType(const Imports&, const QByteArray& type, QDeclarativeType** type_return, QUrl* url_return, int *version_major, int *version_minor, diff --git a/src/declarative/qml/qdeclarativemetatype.cpp b/src/declarative/qml/qdeclarativemetatype.cpp index b32e575..c512d97 100644 --- a/src/declarative/qml/qdeclarativemetatype.cpp +++ b/src/declarative/qml/qdeclarativemetatype.cpp @@ -98,6 +98,13 @@ struct QDeclarativeMetaTypeData typedef QHash<int, QDeclarativeMetaType::StringConverter> StringConverters; StringConverters stringConverters; + struct ModuleInfo { + ModuleInfo(int maj, int min) : vmajor(maj), vminor(min) {} + int vmajor, vminor; + }; + typedef QHash<QByteArray, ModuleInfo> ModuleInfoHash; + ModuleInfoHash modules; + QBitArray objects; QBitArray interfaces; QBitArray lists; @@ -441,9 +448,30 @@ int QDeclarativePrivate::registerType(const QDeclarativePrivate::RegisterType &t data->objects.setBit(type.typeId, true); if (type.listId) data->lists.setBit(type.listId, true); + if (type.uri) { + QByteArray mod(type.uri); + QDeclarativeMetaTypeData::ModuleInfoHash::Iterator it = data->modules.find(mod); + if (it == data->modules.end() + || ((*it).vmajor < type.versionMajor || ((*it).vmajor == type.versionMajor && (*it).vminor < type.versionMinor))) { + data->modules.insert(mod, QDeclarativeMetaTypeData::ModuleInfo(type.versionMajor,type.versionMinor)); + } + } + return index; } +/* + Have any types been registered for \a module with at least versionMajor.versionMinor. +*/ +bool QDeclarativeMetaType::isModule(const QByteArray &module, int versionMajor, int versionMinor) +{ + QDeclarativeMetaTypeData *data = metaTypeData(); + QDeclarativeMetaTypeData::ModuleInfoHash::Iterator it = data->modules.find(module); + return it != data->modules.end() + && ((*it).vmajor > versionMajor || + ((*it).vmajor == versionMajor && (*it).vminor >= versionMinor)); +} + QObject *QDeclarativeMetaType::toQObject(const QVariant &v, bool *ok) { if (!isQObject(v.userType())) { diff --git a/src/declarative/qml/qdeclarativemetatype_p.h b/src/declarative/qml/qdeclarativemetatype_p.h index 1a36f10..e70b4bf 100644 --- a/src/declarative/qml/qdeclarativemetatype_p.h +++ b/src/declarative/qml/qdeclarativemetatype_p.h @@ -97,6 +97,8 @@ public: typedef QVariant (*StringConverter)(const QString &); static void registerCustomStringConverter(int, StringConverter); static StringConverter customStringConverter(int); + + static bool isModule(const QByteArray &module, int versionMajor, int versionMinor); }; class QDeclarativeTypePrivate; diff --git a/src/declarative/qml/qdeclarativeworkerscript.cpp b/src/declarative/qml/qdeclarativeworkerscript.cpp index 10c0b54..a7ed358 100644 --- a/src/declarative/qml/qdeclarativeworkerscript.cpp +++ b/src/declarative/qml/qdeclarativeworkerscript.cpp @@ -201,11 +201,11 @@ QScriptValue QDeclarativeWorkerScriptEnginePrivate::sendMessage(QScriptContext * if (!script) return engine->undefinedValue(); - p->m_lock.lock(); + QMutexLocker(&p->m_lock); + if (script->owner) QCoreApplication::postEvent(script->owner, new WorkerDataEvent(0, scriptValueToVariant(ctxt->argument(0)))); - p->m_lock.unlock(); return engine->undefinedValue(); } diff --git a/src/declarative/util/qdeclarativeanimation.cpp b/src/declarative/util/qdeclarativeanimation.cpp index d47dcc5..1fb3d99 100644 --- a/src/declarative/util/qdeclarativeanimation.cpp +++ b/src/declarative/util/qdeclarativeanimation.cpp @@ -1006,212 +1006,6 @@ void QDeclarativePropertyAction::transition(QDeclarativeStateActions &actions, } } - - -/*! - \qmlclass ParentAction QDeclarativeParentAction - \since 4.7 - \inherits Animation - \brief The ParentAction element allows parent changes during animation. - - ParentAction provides a way to specify at what point in a Transition a ParentChange should - occur. - \qml - State { - ParentChange { - target: myItem - parent: newParent - } - } - Transition { - SequentialAnimation { - PropertyAnimation { ... } - ParentAction {} //reparent myItem now - PropertyAnimation { ... } - } - } - \endqml - - It also provides a way to explicitly reparent an item during an animation. - \qml - SequentialAnimation { - ParentAction { target: myItem; parent: newParent } - PropertyAnimation {} - } - \endqml - - The ParentAction is immediate - it is not animated in any way. -*/ - -QDeclarativeParentAction::QDeclarativeParentAction(QObject *parent) -: QDeclarativeAbstractAnimation(*(new QDeclarativeParentActionPrivate), parent) -{ - Q_D(QDeclarativeParentAction); - d->init(); -} - -QDeclarativeParentAction::~QDeclarativeParentAction() -{ -} - -void QDeclarativeParentActionPrivate::init() -{ - Q_Q(QDeclarativeParentAction); - cpa = new QActionAnimation; - QDeclarative_setParent_noEvent(cpa, q); -} - -/*! - \qmlproperty Item ParentAction::target - - This property holds a target item to reparent. - - In the following example, \c myItem will be reparented by the ParentAction, while - \c myOtherItem will not. - \qml - State { - ParentChange { - target: myItem - parent: newParent - } - ParentChange { - target: myOtherItem - parent: otherNewParent - } - } - Transition { - SequentialAnimation { - PropertyAnimation { ... } - ParentAction { target: myItem } - PropertyAnimation { ... } - } - } - \endqml - - */ -QDeclarativeItem *QDeclarativeParentAction::object() const -{ - Q_D(const QDeclarativeParentAction); - return d->pcTarget; -} - -void QDeclarativeParentAction::setObject(QDeclarativeItem *target) -{ - Q_D(QDeclarativeParentAction); - d->pcTarget = target; -} - -/*! - \qmlproperty Item ParentAction::parent - - The item to reparent to (i.e. the new parent). - */ -QDeclarativeItem *QDeclarativeParentAction::parent() const -{ - Q_D(const QDeclarativeParentAction); - return d->pcParent; -} - -void QDeclarativeParentAction::setParent(QDeclarativeItem *parent) -{ - Q_D(QDeclarativeParentAction); - d->pcParent = parent; -} - -void QDeclarativeParentActionPrivate::doAction() -{ - QDeclarativeParentChange pc; - pc.setObject(pcTarget); - pc.setParent(pcParent); - pc.execute(); -} - -QAbstractAnimation *QDeclarativeParentAction::qtAnimation() -{ - Q_D(QDeclarativeParentAction); - return d->cpa; -} - -void QDeclarativeParentAction::transition(QDeclarativeStateActions &actions, - QDeclarativeProperties &modified, - TransitionDirection direction) -{ - Q_D(QDeclarativeParentAction); - Q_UNUSED(modified); - Q_UNUSED(direction); - - struct QDeclarativeParentActionData : public QAbstractAnimationAction - { - QDeclarativeParentActionData(): pc(0) {} - ~QDeclarativeParentActionData() { delete pc; } - - QDeclarativeStateActions actions; - bool reverse; - QDeclarativeParentChange *pc; - virtual void doAction() - { - for (int ii = 0; ii < actions.count(); ++ii) { - const QDeclarativeAction &action = actions.at(ii); - if (reverse) - action.event->reverse(); - else - action.event->execute(); - } - } - }; - - QDeclarativeParentActionData *data = new QDeclarativeParentActionData; - - //### need to correctly handle modified/done - - bool hasExplicit = false; - if (d->pcTarget && d->pcParent) { - data->reverse = false; - QDeclarativeAction myAction; - QDeclarativeParentChange *pc = new QDeclarativeParentChange; - pc->setObject(d->pcTarget); - pc->setParent(d->pcParent); - myAction.event = pc; - data->pc = pc; - data->actions << myAction; - hasExplicit = true; - } - - if (!hasExplicit) - for (int ii = 0; ii < actions.count(); ++ii) { - QDeclarativeAction &action = actions[ii]; - - if (action.event && action.event->typeName() == QLatin1String("ParentChange") - && (!d->pcTarget || static_cast<QDeclarativeParentChange*>(action.event)->object() == d->pcTarget)) { - QDeclarativeAction myAction = action; - data->reverse = action.reverseEvent; - //### this logic differs from PropertyAnimation - // (probably a result of modified vs. done) - if (d->pcParent) { - //### should we disallow this case? - QDeclarativeParentChange *pc = new QDeclarativeParentChange; - pc->setObject(d->pcTarget); - pc->setParent(static_cast<QDeclarativeParentChange*>(action.event)->parent()); - myAction.event = pc; - data->pc = pc; - data->actions << myAction; - break; //only match one - } else { - action.actionDone = true; - data->actions << myAction; - } - } - } - - if (data->actions.count()) { - d->cpa->setAnimAction(data, QAbstractAnimation::DeleteWhenStopped); - } else { - delete data; - } -} - - - /*! \qmlclass NumberAnimation QDeclarativeNumberAnimation \since 4.7 @@ -1342,9 +1136,10 @@ void QDeclarativeVector3dAnimation::setTo(QVector3D t) \brief The RotationAnimation element allows you to animate rotations. RotationAnimation is a specialized PropertyAnimation that gives control - over the direction of rotation. By default, it will rotate - via the shortest path; for example, a rotation from 20 to 340 degrees will - rotation 40 degrees counterclockwise. + over the direction of rotation. By default, it will rotate in the direction + of the numerical change; a rotation from 0 to 240 will rotate 220 degrees + clockwise, while a rotation from 240 to 0 will rotate 220 degrees + counterclockwise. When used in a transition RotationAnimation will rotate all properties named "rotation" or "angle". You can override this by providing @@ -1359,7 +1154,7 @@ void QDeclarativeVector3dAnimation::setTo(QVector3D t) State { name: "-90"; PropertyChanges { target: myItem; rotation: -90 } } } transition: Transition { - RotationAnimation { } + RotationAnimation { direction: RotationAnimation.Shortest } } \endqml */ @@ -1411,7 +1206,7 @@ QDeclarativeRotationAnimation::QDeclarativeRotationAnimation(QObject *parent) { Q_D(QDeclarativeRotationAnimation); d->interpolatorType = QMetaType::QReal; - d->interpolator = reinterpret_cast<QVariantAnimation::Interpolator>(&_q_interpolateShortestRotation); + d->interpolator = QVariantAnimationPrivate::getInterpolator(d->interpolatorType); d->defaultProperties = QLatin1String("rotation,angle"); } @@ -1474,7 +1269,7 @@ void QDeclarativeRotationAnimation::setTo(qreal t) A rotation from 10 to 350 will rotate 20 degrees counterclockwise. \endtable - The default direction is Shortest. + The default direction is Numerical. */ QDeclarativeRotationAnimation::RotationDirection QDeclarativeRotationAnimation::direction() const { @@ -2483,7 +2278,11 @@ QDeclarativeItem *QDeclarativeParentAnimation::target() const void QDeclarativeParentAnimation::setTarget(QDeclarativeItem *target) { Q_D(QDeclarativeParentAnimation); + if (target == d->target) + return; + d->target = target; + emit targetChanged(); } /*! @@ -2501,7 +2300,11 @@ QDeclarativeItem *QDeclarativeParentAnimation::newParent() const void QDeclarativeParentAnimation::setNewParent(QDeclarativeItem *newParent) { Q_D(QDeclarativeParentAnimation); + if (newParent == d->newParent) + return; + d->newParent = newParent; + emit newParentChanged(); } /*! @@ -2526,7 +2329,11 @@ QDeclarativeItem *QDeclarativeParentAnimation::via() const void QDeclarativeParentAnimation::setVia(QDeclarativeItem *via) { Q_D(QDeclarativeParentAnimation); + if (via == d->via) + return; + d->via = via; + emit viaChanged(); } //### mirrors same-named function in QDeclarativeItem @@ -2561,10 +2368,10 @@ void QDeclarativeParentAnimation::transition(QDeclarativeStateActions &actions, { Q_D(QDeclarativeParentAnimation); - struct QDeclarativeParentActionData : public QAbstractAnimationAction + struct QDeclarativeParentAnimationData : public QAbstractAnimationAction { - QDeclarativeParentActionData() {} - ~QDeclarativeParentActionData() { qDeleteAll(pc); } + QDeclarativeParentAnimationData() {} + ~QDeclarativeParentAnimationData() { qDeleteAll(pc); } QDeclarativeStateActions actions; //### reverse should probably apply on a per-action basis @@ -2582,8 +2389,8 @@ void QDeclarativeParentAnimation::transition(QDeclarativeStateActions &actions, } }; - QDeclarativeParentActionData *data = new QDeclarativeParentActionData; - QDeclarativeParentActionData *viaData = new QDeclarativeParentActionData; + QDeclarativeParentAnimationData *data = new QDeclarativeParentAnimationData; + QDeclarativeParentAnimationData *viaData = new QDeclarativeParentAnimationData; bool hasExplicit = false; if (d->target && d->newParent) { diff --git a/src/declarative/util/qdeclarativeanimation_p.h b/src/declarative/util/qdeclarativeanimation_p.h index 925eb36..356b015 100644 --- a/src/declarative/util/qdeclarativeanimation_p.h +++ b/src/declarative/util/qdeclarativeanimation_p.h @@ -227,32 +227,6 @@ protected: }; class QDeclarativeItem; -class QDeclarativeParentActionPrivate; -class QDeclarativeParentAction : public QDeclarativeAbstractAnimation -{ - Q_OBJECT - Q_DECLARE_PRIVATE(QDeclarativeParentAction) - - Q_PROPERTY(QDeclarativeItem *target READ object WRITE setObject) - Q_PROPERTY(QDeclarativeItem *parent READ parent WRITE setParent) //### newParent - -public: - QDeclarativeParentAction(QObject *parent=0); - virtual ~QDeclarativeParentAction(); - - QDeclarativeItem *object() const; - void setObject(QDeclarativeItem *); - - QDeclarativeItem *parent() const; - void setParent(QDeclarativeItem *); - -protected: - virtual void transition(QDeclarativeStateActions &actions, - QDeclarativeProperties &modified, - TransitionDirection direction); - virtual QAbstractAnimation *qtAnimation(); -}; - class QDeclarativePropertyAnimationPrivate; class Q_AUTOTEST_EXPORT QDeclarativePropertyAnimation : public QDeclarativeAbstractAnimation { @@ -456,9 +430,9 @@ class QDeclarativeParentAnimation : public QDeclarativeAnimationGroup Q_OBJECT Q_DECLARE_PRIVATE(QDeclarativeParentAnimation) - Q_PROPERTY(QDeclarativeItem *target READ target WRITE setTarget) - Q_PROPERTY(QDeclarativeItem *newParent READ newParent WRITE setNewParent) - Q_PROPERTY(QDeclarativeItem *via READ via WRITE setVia) + Q_PROPERTY(QDeclarativeItem *target READ target WRITE setTarget NOTIFY targetChanged) + Q_PROPERTY(QDeclarativeItem *newParent READ newParent WRITE setNewParent NOTIFY newParentChanged) + Q_PROPERTY(QDeclarativeItem *via READ via WRITE setVia NOTIFY viaChanged) public: QDeclarativeParentAnimation(QObject *parent=0); @@ -473,6 +447,11 @@ public: QDeclarativeItem *via() const; void setVia(QDeclarativeItem *); +Q_SIGNALS: + void targetChanged(); + void newParentChanged(); + void viaChanged(); + protected: virtual void transition(QDeclarativeStateActions &actions, QDeclarativeProperties &modified, @@ -506,7 +485,6 @@ QML_DECLARE_TYPE(QDeclarativeAbstractAnimation) QML_DECLARE_TYPE(QDeclarativePauseAnimation) QML_DECLARE_TYPE(QDeclarativeScriptAction) QML_DECLARE_TYPE(QDeclarativePropertyAction) -QML_DECLARE_TYPE(QDeclarativeParentAction) QML_DECLARE_TYPE(QDeclarativePropertyAnimation) QML_DECLARE_TYPE(QDeclarativeColorAnimation) QML_DECLARE_TYPE(QDeclarativeNumberAnimation) diff --git a/src/declarative/util/qdeclarativeanimation_p_p.h b/src/declarative/util/qdeclarativeanimation_p_p.h index 0460312..55aacfa 100644 --- a/src/declarative/util/qdeclarativeanimation_p_p.h +++ b/src/declarative/util/qdeclarativeanimation_p_p.h @@ -300,22 +300,6 @@ public: QActionAnimation *spa; }; -class QDeclarativeParentActionPrivate : public QDeclarativeAbstractAnimationPrivate -{ - Q_DECLARE_PUBLIC(QDeclarativeParentAction) -public: - QDeclarativeParentActionPrivate() - : QDeclarativeAbstractAnimationPrivate(), pcTarget(0), pcParent(0) {} - - void init(); - - QDeclarativeItem *pcTarget; - QDeclarativeItem *pcParent; - - void doAction(); - QActionAnimation *cpa; -}; - class QDeclarativeAnimationGroupPrivate : public QDeclarativeAbstractAnimationPrivate { Q_DECLARE_PUBLIC(QDeclarativeAnimationGroup) @@ -369,7 +353,7 @@ class QDeclarativeRotationAnimationPrivate : public QDeclarativePropertyAnimatio { Q_DECLARE_PUBLIC(QDeclarativeRotationAnimation) public: - QDeclarativeRotationAnimationPrivate() : direction(QDeclarativeRotationAnimation::Shortest) {} + QDeclarativeRotationAnimationPrivate() : direction(QDeclarativeRotationAnimation::Numerical) {} QDeclarativeRotationAnimation::RotationDirection direction; }; diff --git a/src/declarative/util/qdeclarativestate_p_p.h b/src/declarative/util/qdeclarativestate_p_p.h index 6f52219..558c99b 100644 --- a/src/declarative/util/qdeclarativestate_p_p.h +++ b/src/declarative/util/qdeclarativestate_p_p.h @@ -58,8 +58,8 @@ #include "qdeclarativeanimation_p_p.h" #include "qdeclarativetransitionmanager_p_p.h" -#include <qdeclarativeproperty_p.h> -#include <qdeclarativeguard_p.h> +#include <private/qdeclarativeproperty_p.h> +#include <private/qdeclarativeguard_p.h> #include <private/qobject_p.h> diff --git a/src/declarative/util/qdeclarativestateoperations.cpp b/src/declarative/util/qdeclarativestateoperations.cpp index 96c75a9..163d220 100644 --- a/src/declarative/util/qdeclarativestateoperations.cpp +++ b/src/declarative/util/qdeclarativestateoperations.cpp @@ -168,7 +168,7 @@ void QDeclarativeParentChangePrivate::doChange(QDeclarativeItem *targetParent, Q for the original and new parent). You can specify at which point in a transition you want a ParentChange to occur by - using a ParentAnimation or ParentAction. + using a ParentAnimation. */ diff --git a/src/declarative/util/qdeclarativetransition.cpp b/src/declarative/util/qdeclarativetransition.cpp index ac07b10..4326a55 100644 --- a/src/declarative/util/qdeclarativetransition.cpp +++ b/src/declarative/util/qdeclarativetransition.cpp @@ -67,7 +67,7 @@ QT_BEGIN_NAMESPACE \ingroup group_states */ -//ParallelAnimationWrapperallows us to do a "callback" when the animation finishes, rather than connecting +//ParallelAnimationWrapper allows us to do a "callback" when the animation finishes, rather than connecting //and disconnecting signals and slots frequently class ParallelAnimationWrapper : public QParallelAnimationGroup { @@ -195,7 +195,11 @@ QString QDeclarativeTransition::fromState() const void QDeclarativeTransition::setFromState(const QString &f) { Q_D(QDeclarativeTransition); + if (f == d->fromState) + return; + d->fromState = f; + emit fromChanged(); } /*! @@ -213,7 +217,11 @@ bool QDeclarativeTransition::reversible() const void QDeclarativeTransition::setReversible(bool r) { Q_D(QDeclarativeTransition); + if (r == d->reversible) + return; + d->reversible = r; + emit reversibleChanged(); } QString QDeclarativeTransition::toState() const @@ -225,7 +233,11 @@ QString QDeclarativeTransition::toState() const void QDeclarativeTransition::setToState(const QString &t) { Q_D(QDeclarativeTransition); + if (t == d->toState) + return; + d->toState = t; + emit toChanged(); } /*! diff --git a/src/declarative/util/qdeclarativetransition_p.h b/src/declarative/util/qdeclarativetransition_p.h index 861111a..2f9e7b5 100644 --- a/src/declarative/util/qdeclarativetransition_p.h +++ b/src/declarative/util/qdeclarativetransition_p.h @@ -62,9 +62,9 @@ class Q_DECLARATIVE_EXPORT QDeclarativeTransition : public QObject Q_OBJECT Q_DECLARE_PRIVATE(QDeclarativeTransition) - Q_PROPERTY(QString from READ fromState WRITE setFromState) - Q_PROPERTY(QString to READ toState WRITE setToState) - Q_PROPERTY(bool reversible READ reversible WRITE setReversible) + Q_PROPERTY(QString from READ fromState WRITE setFromState NOTIFY fromChanged) + Q_PROPERTY(QString to READ toState WRITE setToState NOTIFY toChanged) + Q_PROPERTY(bool reversible READ reversible WRITE setReversible NOTIFY reversibleChanged) Q_PROPERTY(QDeclarativeListProperty<QDeclarativeAbstractAnimation> animations READ animations) Q_CLASSINFO("DefaultProperty", "animations") Q_CLASSINFO("DeferredPropertyNames", "animations") @@ -90,6 +90,11 @@ public: void setReversed(bool r); void stop(); + +Q_SIGNALS: + void fromChanged(); + void toChanged(); + void reversibleChanged(); }; QT_END_NAMESPACE diff --git a/src/declarative/util/qdeclarativeutilmodule.cpp b/src/declarative/util/qdeclarativeutilmodule.cpp index cb35734..46c9b73 100644 --- a/src/declarative/util/qdeclarativeutilmodule.cpp +++ b/src/declarative/util/qdeclarativeutilmodule.cpp @@ -85,7 +85,6 @@ void QDeclarativeUtilModule::defineModule() qmlRegisterType<QDeclarativeNumberAnimation>("Qt",4,6,"NumberAnimation"); qmlRegisterType<QDeclarativePackage>("Qt",4,6,"Package"); qmlRegisterType<QDeclarativeParallelAnimation>("Qt",4,6,"ParallelAnimation"); - qmlRegisterType<QDeclarativeParentAction>("Qt",4,6,"ParentAction"); qmlRegisterType<QDeclarativeParentAnimation>("Qt",4,6,"ParentAnimation"); qmlRegisterType<QDeclarativeParentChange>("Qt",4,6,"ParentChange"); qmlRegisterType<QDeclarativePauseAnimation>("Qt",4,6,"PauseAnimation"); diff --git a/src/gui/graphicsview/qgraphicsscene.cpp b/src/gui/graphicsview/qgraphicsscene.cpp index 159c997..bcdc7d3 100644 --- a/src/gui/graphicsview/qgraphicsscene.cpp +++ b/src/gui/graphicsview/qgraphicsscene.cpp @@ -4301,6 +4301,12 @@ static void _q_paintIntoCache(QPixmap *pix, QGraphicsItem *item, const QRegion & if (!subPix.isNull()) { // Blit the subpixmap into the main pixmap. pixmapPainter.begin(pix); + if (item->cacheMode() == QGraphicsItem::DeviceCoordinateCache + && itemToPixmap.type() > QTransform::TxTranslate) { + pixmapPainter.setCompositionMode(QPainter::CompositionMode_SourceAtop); + } else { + pixmapPainter.setCompositionMode(QPainter::CompositionMode_Source); + } pixmapPainter.setClipRegion(pixmapExposed); pixmapPainter.drawPixmap(br.topLeft(), subPix); pixmapPainter.end(); diff --git a/src/gui/graphicsview/qgraphicswidget.cpp b/src/gui/graphicsview/qgraphicswidget.cpp index 87416b4..669dd61 100644 --- a/src/gui/graphicsview/qgraphicswidget.cpp +++ b/src/gui/graphicsview/qgraphicswidget.cpp @@ -384,7 +384,7 @@ void QGraphicsWidget::setGeometry(const QRectF &rect) } QSizeF oldSize = size(); QGraphicsLayoutItem::setGeometry(newGeom); - + emit geometryChanged(); // Send resize event bool resized = newGeom.size() != oldSize; if (resized) { diff --git a/src/gui/graphicsview/qgraphicswidget.h b/src/gui/graphicsview/qgraphicswidget.h index 4bea5be..87c669b 100644 --- a/src/gui/graphicsview/qgraphicswidget.h +++ b/src/gui/graphicsview/qgraphicswidget.h @@ -73,7 +73,7 @@ class Q_GUI_EXPORT QGraphicsWidget : public QGraphicsObject, public QGraphicsLay Q_PROPERTY(QPalette palette READ palette WRITE setPalette) Q_PROPERTY(QFont font READ font WRITE setFont) Q_PROPERTY(Qt::LayoutDirection layoutDirection READ layoutDirection WRITE setLayoutDirection RESET unsetLayoutDirection) - Q_PROPERTY(QSizeF size READ size WRITE resize) + Q_PROPERTY(QSizeF size READ size WRITE resize NOTIFY geometryChanged) Q_PROPERTY(QSizeF minimumSize READ minimumSize WRITE setMinimumSize) Q_PROPERTY(QSizeF preferredSize READ preferredSize WRITE setPreferredSize) Q_PROPERTY(QSizeF maximumSize READ maximumSize WRITE setMaximumSize) @@ -81,12 +81,11 @@ class Q_GUI_EXPORT QGraphicsWidget : public QGraphicsObject, public QGraphicsLay Q_PROPERTY(Qt::FocusPolicy focusPolicy READ focusPolicy WRITE setFocusPolicy) Q_PROPERTY(Qt::WindowFlags windowFlags READ windowFlags WRITE setWindowFlags) Q_PROPERTY(QString windowTitle READ windowTitle WRITE setWindowTitle) - Q_PROPERTY(QRectF geometry READ geometry WRITE setGeometry) + Q_PROPERTY(QRectF geometry READ geometry WRITE setGeometry NOTIFY geometryChanged) Q_PROPERTY(bool autoFillBackground READ autoFillBackground WRITE setAutoFillBackground) public: QGraphicsWidget(QGraphicsItem *parent = 0, Qt::WindowFlags wFlags = 0); ~QGraphicsWidget(); - QGraphicsLayout *layout() const; void setLayout(QGraphicsLayout *layout); void adjustSize(); @@ -179,6 +178,9 @@ public: using QObject::children; #endif +Q_SIGNALS: + void geometryChanged(); + public Q_SLOTS: bool close(); diff --git a/src/gui/itemviews/qabstractitemview.cpp b/src/gui/itemviews/qabstractitemview.cpp index 0f99949..a4722f7 100644 --- a/src/gui/itemviews/qabstractitemview.cpp +++ b/src/gui/itemviews/qabstractitemview.cpp @@ -104,7 +104,7 @@ QAbstractItemViewPrivate::QAbstractItemViewPrivate() horizontalScrollMode(QAbstractItemView::ScrollPerItem), currentIndexSet(false), wrapItemText(false), - delayedPendingLayout(false) + delayedPendingLayout(true) { } @@ -131,8 +131,6 @@ void QAbstractItemViewPrivate::init() viewport->setBackgroundRole(QPalette::Base); - doDelayedItemsLayout(); - q->setAttribute(Qt::WA_InputMethodEnabled); #ifdef QT_SOFTKEYS_ENABLED diff --git a/src/gui/itemviews/qheaderview.cpp b/src/gui/itemviews/qheaderview.cpp index 586e5d4..cd9ee15 100644 --- a/src/gui/itemviews/qheaderview.cpp +++ b/src/gui/itemviews/qheaderview.cpp @@ -2220,16 +2220,24 @@ void QHeaderView::mouseMoveEvent(QMouseEvent *e) case QHeaderViewPrivate::MoveSection: { if (qAbs(pos - d->firstPos) >= QApplication::startDragDistance() || !d->sectionIndicator->isHidden()) { - int indicatorCenter = (d->orientation == Qt::Horizontal - ? d->sectionIndicator->width() - : d->sectionIndicator->height()) / 2; - int centerOffset = indicatorCenter - d->sectionIndicatorOffset; - // This will drop the moved section to the position under the center of the indicator. - // If centerOffset is 0, the section will be moved to the position of the mouse cursor. - int visual = visualIndexAt(pos + centerOffset); + int visual = visualIndexAt(pos); if (visual == -1) return; - d->target = d->logicalIndex(visual); + int posThreshold = d->headerSectionPosition(visual) + d->headerSectionSize(visual) / 2; + int moving = visualIndex(d->section); + if (visual < moving) { + if (pos < posThreshold) + d->target = d->logicalIndex(visual); + else + d->target = d->logicalIndex(visual + 1); + } else if (visual > moving) { + if (pos > posThreshold) + d->target = d->logicalIndex(visual); + else + d->target = d->logicalIndex(visual - 1); + } else { + d->target = d->section; + } d->updateSectionIndicator(d->section, pos); } return; diff --git a/src/gui/itemviews/qitemselectionmodel.cpp b/src/gui/itemviews/qitemselectionmodel.cpp index cab002e..d6e68f6 100644 --- a/src/gui/itemviews/qitemselectionmodel.cpp +++ b/src/gui/itemviews/qitemselectionmodel.cpp @@ -527,6 +527,27 @@ void QItemSelection::split(const QItemSelectionRange &range, } } + +void QItemSelectionModelPrivate::initModel(QAbstractItemModel *model) +{ + this->model = model; + if (model) { + Q_Q(QItemSelectionModel); + QObject::connect(model, SIGNAL(rowsAboutToBeRemoved(QModelIndex,int,int)), + q, SLOT(_q_rowsAboutToBeRemoved(QModelIndex,int,int))); + QObject::connect(model, SIGNAL(columnsAboutToBeRemoved(QModelIndex,int,int)), + q, SLOT(_q_columnsAboutToBeRemoved(QModelIndex,int,int))); + QObject::connect(model, SIGNAL(rowsAboutToBeInserted(QModelIndex,int,int)), + q, SLOT(_q_rowsAboutToBeInserted(QModelIndex,int,int))); + QObject::connect(model, SIGNAL(columnsAboutToBeInserted(QModelIndex,int,int)), + q, SLOT(_q_columnsAboutToBeInserted(QModelIndex,int,int))); + QObject::connect(model, SIGNAL(layoutAboutToBeChanged()), + q, SLOT(_q_layoutAboutToBeChanged())); + QObject::connect(model, SIGNAL(layoutChanged()), + q, SLOT(_q_layoutChanged())); + } +} + /*! \internal @@ -793,6 +814,10 @@ static QItemSelection mergeIndexes(const QList<QPersistentModelIndex> &indexes) while (++i < colSpans.count()) { QModelIndex nextTl = colSpans.at(i).topLeft(); QModelIndex nextBr = colSpans.at(i).bottomRight(); + + if (nextTl.parent() != tl.parent()) + break; // we can't merge selection ranges from different parents + if ((nextTl.column() == prevTl.column()) && (nextBr.column() == br.column()) && (nextTl.row() == prevTl.row() + 1) && (nextBr.row() == br.row() + 1)) { br = nextBr; @@ -890,21 +915,7 @@ void QItemSelectionModelPrivate::_q_layoutChanged() QItemSelectionModel::QItemSelectionModel(QAbstractItemModel *model) : QObject(*new QItemSelectionModelPrivate, model) { - d_func()->model = model; - if (model) { - connect(model, SIGNAL(rowsAboutToBeRemoved(QModelIndex,int,int)), - this, SLOT(_q_rowsAboutToBeRemoved(QModelIndex,int,int))); - connect(model, SIGNAL(columnsAboutToBeRemoved(QModelIndex,int,int)), - this, SLOT(_q_columnsAboutToBeRemoved(QModelIndex,int,int))); - connect(model, SIGNAL(rowsAboutToBeInserted(QModelIndex,int,int)), - this, SLOT(_q_rowsAboutToBeInserted(QModelIndex,int,int))); - connect(model, SIGNAL(columnsAboutToBeInserted(QModelIndex,int,int)), - this, SLOT(_q_columnsAboutToBeInserted(QModelIndex,int,int))); - connect(model, SIGNAL(layoutAboutToBeChanged()), - this, SLOT(_q_layoutAboutToBeChanged())); - connect(model, SIGNAL(layoutChanged()), - this, SLOT(_q_layoutChanged())); - } + d_func()->initModel(model); } /*! @@ -913,21 +924,7 @@ QItemSelectionModel::QItemSelectionModel(QAbstractItemModel *model) QItemSelectionModel::QItemSelectionModel(QAbstractItemModel *model, QObject *parent) : QObject(*new QItemSelectionModelPrivate, parent) { - d_func()->model = model; - if (model) { - connect(model, SIGNAL(rowsAboutToBeRemoved(QModelIndex,int,int)), - this, SLOT(_q_rowsAboutToBeRemoved(QModelIndex,int,int))); - connect(model, SIGNAL(columnsAboutToBeRemoved(QModelIndex,int,int)), - this, SLOT(_q_columnsAboutToBeRemoved(QModelIndex,int,int))); - connect(model, SIGNAL(rowsAboutToBeInserted(QModelIndex,int,int)), - this, SLOT(_q_rowsAboutToBeInserted(QModelIndex,int,int))); - connect(model, SIGNAL(columnsAboutToBeInserted(QModelIndex,int,int)), - this, SLOT(_q_columnsAboutToBeInserted(QModelIndex,int,int))); - connect(model, SIGNAL(layoutAboutToBeChanged()), - this, SLOT(_q_layoutAboutToBeChanged())); - connect(model, SIGNAL(layoutChanged()), - this, SLOT(_q_layoutChanged())); - } + d_func()->initModel(model); } /*! @@ -936,21 +933,7 @@ QItemSelectionModel::QItemSelectionModel(QAbstractItemModel *model, QObject *par QItemSelectionModel::QItemSelectionModel(QItemSelectionModelPrivate &dd, QAbstractItemModel *model) : QObject(dd, model) { - d_func()->model = model; - if (model) { - connect(model, SIGNAL(rowsAboutToBeRemoved(QModelIndex,int,int)), - this, SLOT(_q_rowsAboutToBeRemoved(QModelIndex,int,int))); - connect(model, SIGNAL(columnsAboutToBeRemoved(QModelIndex,int,int)), - this, SLOT(_q_columnsAboutToBeRemoved(QModelIndex,int,int))); - connect(model, SIGNAL(rowsAboutToBeInserted(QModelIndex,int,int)), - this, SLOT(_q_rowsAboutToBeInserted(QModelIndex,int,int))); - connect(model, SIGNAL(columnsAboutToBeInserted(QModelIndex,int,int)), - this, SLOT(_q_columnsAboutToBeInserted(QModelIndex,int,int))); - connect(model, SIGNAL(layoutAboutToBeChanged()), - this, SLOT(_q_layoutAboutToBeChanged())); - connect(model, SIGNAL(layoutChanged()), - this, SLOT(_q_layoutChanged())); - } + dd.initModel(model); } /*! @@ -958,21 +941,6 @@ QItemSelectionModel::QItemSelectionModel(QItemSelectionModelPrivate &dd, QAbstra */ QItemSelectionModel::~QItemSelectionModel() { - Q_D(QItemSelectionModel); - if (d->model) { - disconnect(d->model, SIGNAL(rowsAboutToBeRemoved(QModelIndex,int,int)), - this, SLOT(_q_rowsAboutToBeRemoved(QModelIndex,int,int))); - disconnect(d->model, SIGNAL(columnsAboutToBeRemoved(QModelIndex,int,int)), - this, SLOT(_q_columnsAboutToBeRemoved(QModelIndex,int,int))); - disconnect(d->model, SIGNAL(rowsAboutToBeInserted(QModelIndex,int,int)), - this, SLOT(_q_rowsAboutToBeInserted(QModelIndex,int,int))); - disconnect(d->model, SIGNAL(columnsAboutToBeInserted(QModelIndex,int,int)), - this, SLOT(_q_columnsAboutToBeInserted(QModelIndex,int,int))); - disconnect(d->model, SIGNAL(layoutAboutToBeChanged()), - this, SLOT(_q_layoutAboutToBeChanged())); - disconnect(d->model, SIGNAL(layoutChanged()), - this, SLOT(_q_layoutChanged())); - } } /*! diff --git a/src/gui/itemviews/qitemselectionmodel_p.h b/src/gui/itemviews/qitemselectionmodel_p.h index 30583b2..5afa90d 100644 --- a/src/gui/itemviews/qitemselectionmodel_p.h +++ b/src/gui/itemviews/qitemselectionmodel_p.h @@ -70,6 +70,8 @@ public: QItemSelection expandSelection(const QItemSelection &selection, QItemSelectionModel::SelectionFlags command) const; + void initModel(QAbstractItemModel *model); + void _q_rowsAboutToBeRemoved(const QModelIndex &parent, int start, int end); void _q_columnsAboutToBeRemoved(const QModelIndex &parent, int start, int end); void _q_rowsAboutToBeInserted(const QModelIndex &parent, int start, int end); diff --git a/src/gui/kernel/qapplication.cpp b/src/gui/kernel/qapplication.cpp index fea8c37..9fe6c87 100644 --- a/src/gui/kernel/qapplication.cpp +++ b/src/gui/kernel/qapplication.cpp @@ -903,6 +903,14 @@ void QApplicationPrivate::initialize() { QWidgetPrivate::mapper = new QWidgetMapper; QWidgetPrivate::allWidgets = new QWidgetSet; + +#if !defined(Q_WS_X11) && !defined(Q_WS_QWS) + // initialize the graphics system - on X11 this is initialized inside + // qt_init() in qapplication_x11.cpp because of several reasons. + // On QWS, the graphics system is set by the QScreen plugin. + graphics_system = QGraphicsSystemFactory::create(graphics_system_name); +#endif + if (qt_appType != QApplication::Tty) (void) QApplication::style(); // trigger creation of application style // trigger registering of QVariant's GUI types @@ -936,13 +944,7 @@ void QApplicationPrivate::initialize() // Set up which span functions should be used in raster engine... qInitDrawhelperAsm(); - -#if !defined(Q_WS_X11) && !defined(Q_WS_QWS) - // initialize the graphics system - on X11 this is initialized inside - // qt_init() in qapplication_x11.cpp because of several reasons. - // On QWS, the graphics system is set by the QScreen plugin. - graphics_system = QGraphicsSystemFactory::create(graphics_system_name); -#endif + #ifndef QT_NO_WHEELEVENT QApplicationPrivate::wheel_scroll_lines = 3; #endif diff --git a/src/gui/kernel/qtooltip.cpp b/src/gui/kernel/qtooltip.cpp index c912129..1343959 100644 --- a/src/gui/kernel/qtooltip.cpp +++ b/src/gui/kernel/qtooltip.cpp @@ -368,7 +368,16 @@ void QTipLabel::placeTip(const QPoint &pos, QWidget *w) #ifdef Q_WS_MAC - QRect screen = QApplication::desktop()->availableGeometry(getTipScreen(pos, w)); + // When in full screen mode, there is no Dock nor Menu so we can use + // the whole screen for displaying the tooltip. However when not in + // full screen mode we need to save space for the dock, so we use + // availableGeometry instead. + extern bool qt_mac_app_fullscreen; //qapplication_mac.mm + QRect screen; + if(qt_mac_app_fullscreen) + screen = QApplication::desktop()->screenGeometry(getTipScreen(pos, w)); + else + screen = QApplication::desktop()->availableGeometry(getTipScreen(pos, w)); #else QRect screen = QApplication::desktop()->screenGeometry(getTipScreen(pos, w)); #endif diff --git a/src/gui/kernel/qwidget_x11.cpp b/src/gui/kernel/qwidget_x11.cpp index 10fb009..9660de5 100644 --- a/src/gui/kernel/qwidget_x11.cpp +++ b/src/gui/kernel/qwidget_x11.cpp @@ -369,7 +369,7 @@ Q_GUI_EXPORT void qt_x11_wait_for_window_manager(QWidget* w) // ConfigureNotify ... MapNotify ... Expose enum State { - Initial, Reparented, Mapped + Initial, Mapped } state = Initial; do { @@ -377,33 +377,15 @@ Q_GUI_EXPORT void qt_x11_wait_for_window_manager(QWidget* w) XNextEvent(X11->display, &ev); qApp->x11ProcessEvent(&ev); - if (w->windowFlags() & Qt::X11BypassWindowManagerHint) { - switch (state) { - case Initial: - case Reparented: - if (ev.type == MapNotify && ev.xany.window == winid) - state = Mapped; - break; - case Mapped: - if (ev.type == Expose && ev.xany.window == winid) - return; - break; - } - } else { - switch (state) { - case Initial: - if (ev.type == ReparentNotify && ev.xany.window == winid) - state = Reparented; - break; - case Reparented: - if (ev.type == MapNotify && ev.xany.window == winid) - state = Mapped; - break; - case Mapped: - if (ev.type == Expose && ev.xany.window == winid) - return; - break; - } + switch (state) { + case Initial: + if (ev.type == MapNotify && ev.xany.window == winid) + state = Mapped; + break; + case Mapped: + if (ev.type == Expose && ev.xany.window == winid) + return; + break; } } else { if (!XEventsQueued(X11->display, QueuedAfterFlush)) diff --git a/src/gui/painting/qpainter.cpp b/src/gui/painting/qpainter.cpp index a1ed8f5..db4ace4 100644 --- a/src/gui/painting/qpainter.cpp +++ b/src/gui/painting/qpainter.cpp @@ -5414,10 +5414,15 @@ void QPainter::drawPixmap(const QRectF &r, const QPixmap &pm, const QRectF &sr) scale(w / sw, h / sh); setBackgroundMode(Qt::TransparentMode); setRenderHint(Antialiasing, renderHints() & SmoothPixmapTransform); - QBrush brush(d->state->pen.color(), pm); + QBrush brush; + + if (sw == pm.width() && sh == pm.height()) + brush = QBrush(d->state->pen.color(), pm); + else + brush = QBrush(d->state->pen.color(), pm.copy(sx, sy, sw, sh)); + setBrush(brush); setPen(Qt::NoPen); - setBrushOrigin(QPointF(-sx, -sy)); drawRect(QRectF(0, 0, sw, sh)); restore(); diff --git a/src/gui/painting/qpainterpath.h b/src/gui/painting/qpainterpath.h index 296ce33..15d83b8 100644 --- a/src/gui/painting/qpainterpath.h +++ b/src/gui/painting/qpainterpath.h @@ -288,6 +288,8 @@ public: QPainterPath createStroke(const QPainterPath &path) const; private: + Q_DISABLE_COPY(QPainterPathStroker) + friend class QX11PaintEngine; QScopedPointer<QPainterPathStrokerPrivate> d_ptr; diff --git a/src/gui/s60framework/qs60mainapplication.cpp b/src/gui/s60framework/qs60mainapplication.cpp index 2a7c4aa..41ac1a8 100644 --- a/src/gui/s60framework/qs60mainapplication.cpp +++ b/src/gui/s60framework/qs60mainapplication.cpp @@ -41,6 +41,7 @@ // INCLUDE FILES #include <exception> +#include <private/qcore_symbian_p.h> #include "qs60maindocument.h" #include "qs60mainapplication_p.h" #include "qs60mainapplication.h" @@ -57,17 +58,17 @@ CApaApplication *newS60Application() return new QS60MainApplication; } -_LIT(KQtWrapperResourceFile, "\\resource\\apps\\s60main.rsc"); +_LIT(KQtWrapperResourceFile, "\\resource\\apps\\s60main" QT_LIBINFIX_UNICODE L".rsc"); /*! \class QS60MainApplication \since 4.6 \brief The QS60MainApplication class provides support for migration from S60. - + \warning This class is provided only to get access to S60 specific functionality in the application framework classes. It is not portable. We strongly recommend against using it in new applications. - + The QS60MainApplication provides a helper class for use in migrating from existing S60 based applications to Qt based applications. It is used in the exact same way as the \c CAknApplication class from diff --git a/src/gui/s60framework/qs60mainappui.cpp b/src/gui/s60framework/qs60mainappui.cpp index 012985b..3b5b9d3 100644 --- a/src/gui/s60framework/qs60mainappui.cpp +++ b/src/gui/s60framework/qs60mainappui.cpp @@ -45,7 +45,15 @@ #include <eikmenub.h> #include <eikmenup.h> #include <barsread.h> -#include <s60main.rsg> +#include <qconfig.h> +#if defined(QT_LIBINFIX_UNQUOTED) +// Two level macro needed for proper expansion of libinfix +# define QT_S60MAIN_RSG_2(x) <s60main##x##.rsg> +# define QT_S60MAIN_RSG(x) QT_S60MAIN_RSG_2(x) +# include QT_S60MAIN_RSG(QT_LIBINFIX_UNQUOTED) +#else +# include <s60main.rsg> +#endif #include <avkon.rsg> #include "qs60mainappui.h" diff --git a/src/gui/s60framework/s60framework.pri b/src/gui/s60framework/s60framework.pri index e177a33..f9d89dc 100644 --- a/src/gui/s60framework/s60framework.pri +++ b/src/gui/s60framework/s60framework.pri @@ -4,6 +4,7 @@ minimalAppResource31 = \ "SOURCEPATH s60framework" \ "START RESOURCE s60main.rss" \ + "TARGET s60main$${QT_LIBINFIX}" \ "HEADER" \ "TARGETPATH /resource/apps" \ "END" @@ -19,3 +20,5 @@ HEADERS += s60framework/qs60mainapplication_p.h \ s60framework/qs60mainapplication.h \ s60framework/qs60mainappui.h \ s60framework/qs60maindocument.h + +!isEmpty(QT_LIBINFIX): DEFINES += QT_LIBINFIX_UNQUOTED=$$QT_LIBINFIX
\ No newline at end of file diff --git a/src/gui/styles/qs60style.cpp b/src/gui/styles/qs60style.cpp index a2ebebb..750e19f 100644 --- a/src/gui/styles/qs60style.cpp +++ b/src/gui/styles/qs60style.cpp @@ -2069,11 +2069,11 @@ void QS60Style::drawPrimitive(PrimitiveElement element, const QStyleOption *opti break; case PE_IndicatorViewItemCheck: #ifndef QT_NO_ITEMVIEWS - if (const QListView *listItem = (qobject_cast<const QListView *>(widget))) { + if (const QAbstractItemView *itemView = (qobject_cast<const QAbstractItemView *>(widget))) { if (const QStyleOptionViewItemV4 *vopt = qstyleoption_cast<const QStyleOptionViewItemV4 *>(option)) { const bool checkBoxVisible = vopt->features & QStyleOptionViewItemV2::HasCheckIndicator; - const bool singleSelection = listItem->selectionMode() == - QAbstractItemView::SingleSelection || listItem->selectionMode() == QAbstractItemView::NoSelection; + const bool singleSelection = itemView->selectionMode() == + QAbstractItemView::SingleSelection || itemView->selectionMode() == QAbstractItemView::NoSelection; // draw either checkbox at the beginning if (checkBoxVisible && singleSelection) { drawPrimitive(PE_IndicatorCheckBox, option, painter, widget); @@ -2475,6 +2475,12 @@ int QS60Style::styleHint(StyleHint sh, const QStyleOption *opt, const QWidget *w { int retValue = -1; switch (sh) { + case SH_RequestSoftwareInputPanel: + if (QS60StylePrivate::isSingleClickUi()) + retValue = RSIP_OnMouseClick; + else + retValue = RSIP_OnMouseClickAndAlreadyFocused; + break; case SH_ComboBox_Popup: retValue = true; break; @@ -2531,9 +2537,6 @@ int QS60Style::styleHint(StyleHint sh, const QStyleOption *opt, const QWidget *w case SH_UnderlineShortcut: retValue = 0; break; - case SH_RequestSoftwareInputPanel: - retValue = RSIP_OnMouseClickAndAlreadyFocused; - break; case SH_FormLayoutWrapPolicy: retValue = QFormLayout::WrapLongRows; break; diff --git a/src/gui/styles/qs60style_s60.cpp b/src/gui/styles/qs60style_s60.cpp index ecac3d6..6138e85 100644 --- a/src/gui/styles/qs60style_s60.cpp +++ b/src/gui/styles/qs60style_s60.cpp @@ -1121,7 +1121,7 @@ QColor QS60StylePrivate::s60Color(QS60StyleEnums::ColorLists list, &KAknsIIDQsnParentColors, &KAknsIIDQsnTextColors }; - Q_ASSERT((int)list <= (int)sizeof(idMap)/sizeof(idMap[0])); + Q_ASSERT((int)list < (int)sizeof(idMap)/sizeof(idMap[0])); const QColor color = QS60StyleModeSpecifics::colorValue(*idMap[(int) list], index - 1); return option ? QS60StylePrivate::stateColor(color, option) : color; } diff --git a/src/gui/styles/qwindowsmobilestyle.cpp b/src/gui/styles/qwindowsmobilestyle.cpp index 6e77409..5f939d0 100644 --- a/src/gui/styles/qwindowsmobilestyle.cpp +++ b/src/gui/styles/qwindowsmobilestyle.cpp @@ -5076,6 +5076,10 @@ void QWindowsMobileStyle::drawPrimitive(PrimitiveElement element, const QStyleOp color = option->palette.buttonText().color(); QImage image; int xoffset, yoffset; + bool isTabBarArrow = widget && widget->parent() + && widget->inherits("QToolButton") + && widget->parent()->inherits("QTabBar"); + switch (element) { case PE_IndicatorArrowUp: image = d->imageArrowUp; @@ -5090,12 +5094,12 @@ void QWindowsMobileStyle::drawPrimitive(PrimitiveElement element, const QStyleOp case PE_IndicatorArrowLeft: image = d->imageArrowLeft; xoffset = 8; - yoffset = 2; + yoffset = isTabBarArrow ? 12 : 2; break; case PE_IndicatorArrowRight: image = d->imageArrowRight; xoffset = 8; - yoffset = 2; + yoffset = isTabBarArrow ? 12 : 2; break; case PE_IndicatorArrowUpBig: image = d->imageArrowUpBig; @@ -6949,10 +6953,11 @@ int QWindowsMobileStyle::pixelMetric(PixelMetric pm, const QStyleOption *opt, co case PM_SliderThickness: ret = d->doubleControls ? windowsMobileSliderThickness * 2: windowsMobileSliderThickness; break; - case PM_TabBarScrollButtonWidth: - ret = d->doubleControls ? 14 * 2 : 18; - case PM_CheckBoxLabelSpacing: - case PM_RadioButtonLabelSpacing: + case PM_TabBarScrollButtonWidth: + ret = d->doubleControls ? 14 * 2 : 18; + break; + case PM_CheckBoxLabelSpacing: + case PM_RadioButtonLabelSpacing: ret = d->doubleControls ? 6 * 2 : 6; break; // Returns the number of pixels to use for the business part of the diff --git a/src/gui/text/qtextlayout.cpp b/src/gui/text/qtextlayout.cpp index cc6793d..766053c 100644 --- a/src/gui/text/qtextlayout.cpp +++ b/src/gui/text/qtextlayout.cpp @@ -1644,28 +1644,67 @@ namespace { struct LineBreakHelper { - LineBreakHelper() : glyphCount(0), maxGlyphs(0), manualWrap(false) {} + LineBreakHelper() + : glyphCount(0), maxGlyphs(0), currentPosition(0), fontEngine(0), logClusters(0), + manualWrap(false) + { + } + QScriptLine tmpData; QScriptLine spaceData; + QGlyphLayout glyphs; + int glyphCount; int maxGlyphs; + int currentPosition; QFixed minw; QFixed softHyphenWidth; QFixed rightBearing; + QFixed minimumRightBearing; + + QFontEngine *fontEngine; + const unsigned short *logClusters; bool manualWrap; bool checkFullOtherwiseExtend(QScriptLine &line); + + QFixed calculateNewWidth(const QScriptLine &line) const { + return line.textWidth + tmpData.textWidth + spaceData.textWidth + softHyphenWidth + - qMin(rightBearing, QFixed()); + } + + inline glyph_t currentGlyph() const + { + Q_ASSERT(currentPosition > 0); + return glyphs.glyphs[logClusters[currentPosition - 1]]; + } + + inline void adjustRightBearing() + { + if (currentPosition <= 0) + return; + + glyph_metrics_t gi = fontEngine->boundingBox(currentGlyph()); + if (gi.isValid()) + rightBearing = qMin(QFixed(), gi.xoff - gi.x - gi.width); + } + + inline void resetRightBearing() + { + rightBearing = QFixed(1); // Any positive number is defined as invalid since only + // negative right bearings are interesting to us. + } }; inline bool LineBreakHelper::checkFullOtherwiseExtend(QScriptLine &line) { LB_DEBUG("possible break width %f, spacew=%f", tmpData.textWidth.toReal(), spaceData.textWidth.toReal()); - QFixed newWidth = line.textWidth + tmpData.textWidth + spaceData.textWidth + softHyphenWidth + rightBearing; + QFixed newWidth = calculateNewWidth(line); if (line.length && !manualWrap && (newWidth > line.width || glyphCount > maxGlyphs)) return true; @@ -1741,13 +1780,12 @@ void QTextLine::layout_helper(int maxGlyphs) Qt::Alignment alignment = eng->option.alignment(); const HB_CharAttributes *attributes = eng->attributes(); - int pos = line.from; + lbh.currentPosition = line.from; int end = 0; - QGlyphLayout glyphs; - const unsigned short *logClusters = eng->layoutData->logClustersPtr; + lbh.logClusters = eng->layoutData->logClustersPtr; while (newItem < eng->layoutData->items.size()) { - lbh.rightBearing = 0; + lbh.resetRightBearing(); lbh.softHyphenWidth = 0; if (newItem != item) { item = newItem; @@ -1755,13 +1793,19 @@ void QTextLine::layout_helper(int maxGlyphs) if (!current.num_glyphs) { eng->shape(item); attributes = eng->attributes(); - logClusters = eng->layoutData->logClustersPtr; + lbh.logClusters = eng->layoutData->logClustersPtr; } - pos = qMax(line.from, current.position); + lbh.currentPosition = qMax(line.from, current.position); end = current.position + eng->length(item); - glyphs = eng->shapedGlyphs(¤t); + lbh.glyphs = eng->shapedGlyphs(¤t); } const QScriptItem ¤t = eng->layoutData->items[item]; + QFontEngine *fontEngine = eng->fontEngine(current); + if (lbh.fontEngine != fontEngine) { + lbh.fontEngine = fontEngine; + lbh.minimumRightBearing = qMin(QFixed(), + QFixed::fromReal(fontEngine->minRightBearing())); + } lbh.tmpData.leading = qMax(lbh.tmpData.leading + lbh.tmpData.ascent, current.leading + current.ascent) - qMax(lbh.tmpData.ascent, @@ -1791,8 +1835,8 @@ void QTextLine::layout_helper(int maxGlyphs) if (!line.length && !lbh.tmpData.length) line.setDefaultHeight(eng); if (eng->option.flags() & QTextOption::ShowLineAndParagraphSeparators) { - addNextCluster(pos, end, lbh.tmpData, lbh.glyphCount, - current, logClusters, glyphs); + addNextCluster(lbh.currentPosition, end, lbh.tmpData, lbh.glyphCount, + current, lbh.logClusters, lbh.glyphs); } else { lbh.tmpData.length++; } @@ -1811,10 +1855,10 @@ void QTextLine::layout_helper(int maxGlyphs) ++lbh.glyphCount; if (lbh.checkFullOtherwiseExtend(line)) goto found; - } else if (attributes[pos].whiteSpace) { - while (pos < end && attributes[pos].whiteSpace) - addNextCluster(pos, end, lbh.spaceData, lbh.glyphCount, - current, logClusters, glyphs); + } else if (attributes[lbh.currentPosition].whiteSpace) { + while (lbh.currentPosition < end && attributes[lbh.currentPosition].whiteSpace) + addNextCluster(lbh.currentPosition, end, lbh.spaceData, lbh.glyphCount, + current, lbh.logClusters, lbh.glyphs); if (!lbh.manualWrap && lbh.spaceData.textWidth > line.width) { lbh.spaceData.textWidth = line.width; // ignore spaces that fall out of the line. @@ -1823,19 +1867,19 @@ void QTextLine::layout_helper(int maxGlyphs) } else { bool sb_or_ws = false; do { - addNextCluster(pos, end, lbh.tmpData, lbh.glyphCount, - current, logClusters, glyphs); + addNextCluster(lbh.currentPosition, end, lbh.tmpData, lbh.glyphCount, + current, lbh.logClusters, lbh.glyphs); - if (attributes[pos].whiteSpace || attributes[pos-1].lineBreakType != HB_NoBreak) { + if (attributes[lbh.currentPosition].whiteSpace || attributes[lbh.currentPosition-1].lineBreakType != HB_NoBreak) { sb_or_ws = true; break; - } else if (breakany && attributes[pos].charStop) { + } else if (breakany && attributes[lbh.currentPosition].charStop) { break; } - } while (pos < end); + } while (lbh.currentPosition < end); lbh.minw = qMax(lbh.tmpData.textWidth, lbh.minw); - if (pos && attributes[pos - 1].lineBreakType == HB_SoftHyphen) { + if (lbh.currentPosition && attributes[lbh.currentPosition - 1].lineBreakType == HB_SoftHyphen) { // if we are splitting up a word because of // a soft hyphen then we ... // @@ -1853,43 +1897,40 @@ void QTextLine::layout_helper(int maxGlyphs) // and thus become invisible again. // if (line.length) - lbh.softHyphenWidth = glyphs.advances_x[logClusters[pos - 1]]; + lbh.softHyphenWidth = lbh.glyphs.advances_x[lbh.logClusters[lbh.currentPosition - 1]]; else if (breakany) - lbh.tmpData.textWidth += glyphs.advances_x[logClusters[pos - 1]]; + lbh.tmpData.textWidth += lbh.glyphs.advances_x[lbh.logClusters[lbh.currentPosition - 1]]; } // The actual width of the text needs to take the right bearing into account. The // right bearing is left-ward, which means that if the rightmost pixel is to the right // of the advance of the glyph, the bearing will be negative. We flip the sign // for the code to be more readable. Logic borrowed from qfontmetrics.cpp. - if (pos) { - QFontEngine *fontEngine = eng->fontEngine(current); - glyph_t glyph = glyphs.glyphs[logClusters[pos - 1]]; - glyph_metrics_t gi = fontEngine->boundingBox(glyph); - if (gi.isValid()) - lbh.rightBearing = qMax(QFixed(), -(gi.xoff - gi.x - gi.width)); - } + // We ignore the right bearing if the minimum negative bearing is too little to + // expand the text beyond the edge. + if (sb_or_ws|breakany) { + if (lbh.calculateNewWidth(line) + lbh.minimumRightBearing > line.width) + lbh.adjustRightBearing(); + if (lbh.checkFullOtherwiseExtend(line)) { + if (!breakany) { + line.textWidth += lbh.softHyphenWidth; + } - if ((sb_or_ws|breakany) && lbh.checkFullOtherwiseExtend(line)) { - if (!breakany) { - line.textWidth += lbh.softHyphenWidth; + goto found; } - - line.textAdvance = line.textWidth; - line.textWidth += lbh.rightBearing; - - goto found; } } - if (pos == end) + if (lbh.currentPosition == end) newItem = item + 1; } LB_DEBUG("reached end of line"); lbh.checkFullOtherwiseExtend(line); +found: + if (lbh.rightBearing > 0) // If right bearing has not yet been adjusted + lbh.adjustRightBearing(); line.textAdvance = line.textWidth; - line.textWidth += lbh.rightBearing; + line.textWidth -= qMin(QFixed(), lbh.rightBearing); -found: if (line.length == 0) { LB_DEBUG("no break available in line, adding temp: length %d, width %f, space: length %d, width %f", lbh.tmpData.length, lbh.tmpData.textWidth.toReal(), diff --git a/src/network/access/qhttpnetworkconnectionchannel.cpp b/src/network/access/qhttpnetworkconnectionchannel.cpp index 806452c..1d8224c 100644 --- a/src/network/access/qhttpnetworkconnectionchannel.cpp +++ b/src/network/access/qhttpnetworkconnectionchannel.cpp @@ -353,6 +353,7 @@ void QHttpNetworkConnectionChannel::_q_receiveReply() replyPrivate->autoDecompress = false; } if (replyPrivate->statusCode == 100) { + replyPrivate->clearHttpLayerInformation(); replyPrivate->state = QHttpNetworkReplyPrivate::ReadingStatusState; break; // ignore } diff --git a/src/network/access/qhttpnetworkreply.cpp b/src/network/access/qhttpnetworkreply.cpp index 984f557..338236e 100644 --- a/src/network/access/qhttpnetworkreply.cpp +++ b/src/network/access/qhttpnetworkreply.cpp @@ -219,7 +219,7 @@ QHttpNetworkReplyPrivate::~QHttpNetworkReplyPrivate() { } -void QHttpNetworkReplyPrivate::clear() +void QHttpNetworkReplyPrivate::clearHttpLayerInformation() { state = NothingDoneState; statusCode = 100; @@ -229,18 +229,24 @@ void QHttpNetworkReplyPrivate::clear() currentChunkSize = 0; currentChunkRead = 0; connectionCloseEnabled = true; - connection = 0; - connectionChannel = 0; #ifndef QT_NO_COMPRESS if (initInflate) inflateEnd(&inflateStrm); #endif initInflate = false; streamEnd = false; - autoDecompress = false; fields.clear(); } +// TODO: Isn't everything HTTP layer related? We don't need to set connection and connectionChannel to 0 at all +void QHttpNetworkReplyPrivate::clear() +{ + connection = 0; + connectionChannel = 0; + autoDecompress = false; + clearHttpLayerInformation(); +} + // QHttpNetworkReplyPrivate qint64 QHttpNetworkReplyPrivate::bytesAvailable() const { @@ -539,6 +545,11 @@ qint64 QHttpNetworkReplyPrivate::readHeader(QAbstractSocket *socket) || fragment.endsWith("\r\n\n") || fragment.endsWith("\n\n")) allHeaders = true; + + // there is another case: We have no headers. Then the fragment equals just the line ending + if ((fragment.length() == 2 && fragment.endsWith("\r\n")) + || (fragment.length() == 1 && fragment.endsWith("\n"))) + allHeaders = true; } } } while (!allHeaders && haveRead > 0); diff --git a/src/network/access/qhttpnetworkreply_p.h b/src/network/access/qhttpnetworkreply_p.h index fa240ec..4011c78 100644 --- a/src/network/access/qhttpnetworkreply_p.h +++ b/src/network/access/qhttpnetworkreply_p.h @@ -172,6 +172,7 @@ public: bool findChallenge(bool forProxy, QByteArray &challenge) const; QAuthenticatorPrivate::Method authenticationMethod(bool isProxy) const; void clear(); + void clearHttpLayerInformation(); qint64 readReplyBodyRaw(QIODevice *in, QByteDataBuffer *out, qint64 size); qint64 readReplyBodyChunked(QIODevice *in, QByteDataBuffer *out); diff --git a/src/opengl/qglbuffer.cpp b/src/opengl/qglbuffer.cpp index 2ab7c32..223243c 100644 --- a/src/opengl/qglbuffer.cpp +++ b/src/opengl/qglbuffer.cpp @@ -289,6 +289,10 @@ bool QGLBuffer::read(int offset, void *data, int count) */ void QGLBuffer::write(int offset, const void *data, int count) { +#ifndef QT_NO_DEBUG + if (!isCreated()) + qWarning("QGLBuffer::allocate(): buffer not created"); +#endif Q_D(QGLBuffer); if (d->guard.id()) glBufferSubData(d->type, offset, count, data); @@ -305,6 +309,10 @@ void QGLBuffer::write(int offset, const void *data, int count) */ void QGLBuffer::allocate(const void *data, int count) { +#ifndef QT_NO_DEBUG + if (!isCreated()) + qWarning("QGLBuffer::allocate(): buffer not created"); +#endif Q_D(QGLBuffer); if (d->guard.id()) glBufferData(d->type, count, data, d->actualUsagePattern); @@ -336,6 +344,10 @@ void QGLBuffer::allocate(const void *data, int count) */ bool QGLBuffer::bind() const { +#ifndef QT_NO_DEBUG + if (!isCreated()) + qWarning("QGLBuffer::bind(): buffer not created"); +#endif Q_D(const QGLBuffer); GLuint bufferId = d->guard.id(); if (bufferId) { @@ -364,6 +376,10 @@ bool QGLBuffer::bind() const */ void QGLBuffer::release() const { +#ifndef QT_NO_DEBUG + if (!isCreated()) + qWarning("QGLBuffer::release(): buffer not created"); +#endif Q_D(const QGLBuffer); if (d->guard.id()) glBindBuffer(d->type, 0); @@ -372,31 +388,23 @@ void QGLBuffer::release() const #undef ctx /*! - Binds a raw \a bufferId to the specified buffer \a type - in the current QGLContext. Returns false if there is - no context current or the GL buffer extension could - not be resolved. + Releases the buffer associated with \a type in the current + QGLContext. - This function is a direct call to \c{glBindBuffer()} for - use when the caller does not have a QGLBuffer but does - have a raw \a bufferId. It can also be used to release - the current buffer when the caller does not know which - QGLBuffer object is currently bound: + This function is a direct call to \c{glBindBuffer(type, 0)} + for use when the caller does not know which QGLBuffer has + been bound to the context but wants to make sure that it + is released. \code - QGLBuffer::bind(QGLBuffer::VertexBuffer, 0); + QGLBuffer::release(QGLBuffer::VertexBuffer); \endcode */ -bool QGLBuffer::bind(QGLBuffer::Type type, uint bufferId) +void QGLBuffer::release(QGLBuffer::Type type) { const QGLContext *ctx = QGLContext::currentContext(); - if (ctx) { - if (qt_resolve_buffer_extensions(const_cast<QGLContext *>(ctx))) { - glBindBuffer(GLenum(type), GLuint(bufferId)); - return true; - } - } - return false; + if (ctx && qt_resolve_buffer_extensions(const_cast<QGLContext *>(ctx))) + glBindBuffer(GLenum(type), 0); } #define ctx d->guard.context() @@ -407,7 +415,7 @@ bool QGLBuffer::bind(QGLBuffer::Type type, uint bufferId) \sa isCreated() */ -uint QGLBuffer::bufferId() const +GLuint QGLBuffer::bufferId() const { Q_D(const QGLBuffer); return d->guard.id(); @@ -453,6 +461,10 @@ int QGLBuffer::size() const void *QGLBuffer::map(QGLBuffer::Access access) { Q_D(QGLBuffer); +#ifndef QT_NO_DEBUG + if (!isCreated()) + qWarning("QGLBuffer::map(): buffer not created"); +#endif if (!d->guard.id()) return 0; if (!glMapBufferARB) @@ -476,6 +488,10 @@ void *QGLBuffer::map(QGLBuffer::Access access) bool QGLBuffer::unmap() { Q_D(QGLBuffer); +#ifndef QT_NO_DEBUG + if (!isCreated()) + qWarning("QGLBuffer::unmap(): buffer not created"); +#endif if (!d->guard.id()) return false; if (!glUnmapBufferARB) diff --git a/src/opengl/qglbuffer.h b/src/opengl/qglbuffer.h index a060733..2fe1f1f 100644 --- a/src/opengl/qglbuffer.h +++ b/src/opengl/qglbuffer.h @@ -43,6 +43,7 @@ #define QGLBUFFER_H #include <QtCore/qscopedpointer.h> +#include <QtOpenGL/qgl.h> QT_BEGIN_HEADER @@ -97,9 +98,9 @@ public: bool bind() const; void release() const; - static bool bind(QGLBuffer::Type type, uint bufferId); + static void release(QGLBuffer::Type type); - uint bufferId() const; + GLuint bufferId() const; int size() const; diff --git a/src/openvg/openvg.pro b/src/openvg/openvg.pro index c8c9917..3790492 100644 --- a/src/openvg/openvg.pro +++ b/src/openvg/openvg.pro @@ -33,6 +33,8 @@ contains(QT_CONFIG, egl) { qwindowsurface_vgegl.cpp } +symbian: DEFINES += QVG_RECREATE_ON_SIZE_CHANGE + include(../qbase.pri) unix:QMAKE_PKGCONFIG_REQUIRES = QtCore QtGui diff --git a/src/openvg/qpixmapdata_vg.cpp b/src/openvg/qpixmapdata_vg.cpp index 53f6b4c..e66d80b 100644 --- a/src/openvg/qpixmapdata_vg.cpp +++ b/src/openvg/qpixmapdata_vg.cpp @@ -45,10 +45,10 @@ #include "qvg_p.h" #include "qvgimagepool_p.h" -#ifdef QT_SYMBIAN_SUPPORTS_SGIMAGE #include <private/qt_s60_p.h> #include <fbs.h> -#include <graphics/sgimage.h> +#ifdef QT_SYMBIAN_SUPPORTS_SGIMAGE +#include <sgresource/sgimage.h> typedef EGLImageKHR (*pfnEglCreateImageKHR)(EGLDisplay, EGLContext, EGLenum, EGLClientBuffer, EGLint*); typedef EGLBoolean (*pfnEglDestroyImageKHR)(EGLDisplay, EGLImageKHR); typedef VGImage (*pfnVgCreateEGLImageTargetKHR)(VGeglImageKHR); @@ -465,23 +465,24 @@ void QVGPixmapData::fromNativeType(void* pixmap, NativeType type) TInt err = 0; - err = SgDriver::Open(); - if(err != KErrNone) { + RSgDriver driver; + err = driver.Open(); + if (err != KErrNone) { cleanup(); return; } - if(sgImage->IsNull()) { + if (sgImage->IsNull()) { cleanup(); - SgDriver::Close(); + driver.Close(); return; } TSgImageInfo sgImageInfo; err = sgImage->GetInfo(sgImageInfo); - if(err != KErrNone) { + if (err != KErrNone) { cleanup(); - SgDriver::Close(); + driver.Close(); return; } @@ -489,9 +490,9 @@ void QVGPixmapData::fromNativeType(void* pixmap, NativeType type) pfnEglDestroyImageKHR eglDestroyImageKHR = (pfnEglDestroyImageKHR) eglGetProcAddress("eglDestroyImageKHR"); pfnVgCreateEGLImageTargetKHR vgCreateEGLImageTargetKHR = (pfnVgCreateEGLImageTargetKHR) eglGetProcAddress("vgCreateEGLImageTargetKHR"); - if(eglGetError() != EGL_SUCCESS || !eglCreateImageKHR || !eglDestroyImageKHR || !vgCreateEGLImageTargetKHR) { + if (eglGetError() != EGL_SUCCESS || !eglCreateImageKHR || !eglDestroyImageKHR || !vgCreateEGLImageTargetKHR) { cleanup(); - SgDriver::Close(); + driver.Close(); return; } @@ -502,17 +503,17 @@ void QVGPixmapData::fromNativeType(void* pixmap, NativeType type) (EGLClientBuffer)sgImage, (EGLint*)KEglImageAttribs); - if(eglGetError() != EGL_SUCCESS) { + if (eglGetError() != EGL_SUCCESS) { cleanup(); - SgDriver::Close(); + driver.Close(); return; } vgImage = vgCreateEGLImageTargetKHR(eglImage); - if(vgGetError() != VG_NO_ERROR) { + if (vgGetError() != VG_NO_ERROR) { cleanup(); eglDestroyImageKHR(QEgl::display(), eglImage); - SgDriver::Close(); + driver.Close(); return; } @@ -526,7 +527,7 @@ void QVGPixmapData::fromNativeType(void* pixmap, NativeType type) setSerialNumber(++qt_vg_pixmap_serial); // release stuff eglDestroyImageKHR(QEgl::display(), eglImage); - SgDriver::Close(); + driver.Close(); } else if (type == QPixmapData::FbsBitmap) { CFbsBitmap *bitmap = reinterpret_cast<CFbsBitmap*>(pixmap); @@ -584,29 +585,25 @@ void* QVGPixmapData::toNativeType(NativeType type) if (type == QPixmapData::SgImage) { toVGImage(); - if(!isValid() || vgImage == VG_INVALID_HANDLE) + if (!isValid() || vgImage == VG_INVALID_HANDLE) return 0; TInt err = 0; - err = SgDriver::Open(); - if(err != KErrNone) + RSgDriver driver; + err = driver.Open(); + if (err != KErrNone) return 0; TSgImageInfo sgInfo; sgInfo.iPixelFormat = EUidPixelFormatARGB_8888_PRE; sgInfo.iSizeInPixels.SetSize(w, h); - sgInfo.iUsage = ESgUsageOpenVgImage | ESgUsageOpenVgTarget; - sgInfo.iShareable = ETrue; - sgInfo.iCpuAccess = ESgCpuAccessNone; - sgInfo.iScreenId = KSgScreenIdMain; //KSgScreenIdAny; - sgInfo.iUserAttributes = NULL; - sgInfo.iUserAttributeCount = 0; + sgInfo.iUsage = ESgUsageBitOpenVgImage | ESgUsageBitOpenVgSurface; RSgImage *sgImage = q_check_ptr(new RSgImage()); err = sgImage->Create(sgInfo, NULL, NULL); - if(err != KErrNone) { - SgDriver::Close(); + if (err != KErrNone) { + driver.Close(); return 0; } @@ -614,8 +611,8 @@ void* QVGPixmapData::toNativeType(NativeType type) pfnEglDestroyImageKHR eglDestroyImageKHR = (pfnEglDestroyImageKHR) eglGetProcAddress("eglDestroyImageKHR"); pfnVgCreateEGLImageTargetKHR vgCreateEGLImageTargetKHR = (pfnVgCreateEGLImageTargetKHR) eglGetProcAddress("vgCreateEGLImageTargetKHR"); - if(eglGetError() != EGL_SUCCESS || !eglCreateImageKHR || !eglDestroyImageKHR || !vgCreateEGLImageTargetKHR) { - SgDriver::Close(); + if (eglGetError() != EGL_SUCCESS || !eglCreateImageKHR || !eglDestroyImageKHR || !vgCreateEGLImageTargetKHR) { + driver.Close(); return 0; } @@ -625,17 +622,17 @@ void* QVGPixmapData::toNativeType(NativeType type) EGL_NATIVE_PIXMAP_KHR, (EGLClientBuffer)sgImage, (EGLint*)KEglImageAttribs); - if(eglGetError() != EGL_SUCCESS) { + if (eglGetError() != EGL_SUCCESS) { sgImage->Close(); - SgDriver::Close(); + driver.Close(); return 0; } VGImage dstVgImage = vgCreateEGLImageTargetKHR(eglImage); - if(vgGetError() != VG_NO_ERROR) { + if (vgGetError() != VG_NO_ERROR) { eglDestroyImageKHR(QEgl::display(), eglImage); sgImage->Close(); - SgDriver::Close(); + driver.Close(); return 0; } @@ -643,14 +640,14 @@ void* QVGPixmapData::toNativeType(NativeType type) vgImage, 0, 0, w, h, VG_FALSE); - if(vgGetError() != VG_NO_ERROR) { + if (vgGetError() != VG_NO_ERROR) { sgImage->Close(); sgImage = 0; } // release stuff vgDestroyImage(dstVgImage); eglDestroyImageKHR(QEgl::display(), eglImage); - SgDriver::Close(); + driver.Close(); return reinterpret_cast<void*>(sgImage); } else if (type == QPixmapData::FbsBitmap) { CFbsBitmap *bitmap = q_check_ptr(new CFbsBitmap); diff --git a/src/plugins/phonon/mmf/mmf.pro b/src/plugins/phonon/mmf/mmf.pro index cfaca9d..da41f18 100644 --- a/src/plugins/phonon/mmf/mmf.pro +++ b/src/plugins/phonon/mmf/mmf.pro @@ -20,13 +20,16 @@ phonon_mmf_audio_drm { # '#include <videoplayer.h>' picks up the Symbian header, as intended. PREPEND_INCLUDEPATH = /epoc32/include +PREPEND_INCLUDEPATH += $$QT_SOURCE_TREE/src/3rdparty + INCLUDEPATH += $$MW_LAYER_SYSTEMINCLUDE HEADERS += \ $$PHONON_MMF_DIR/abstractaudioeffect.h \ $$PHONON_MMF_DIR/abstractmediaplayer.h \ $$PHONON_MMF_DIR/abstractplayer.h \ - $$PHONON_MMF_DIR/ancestormovemonitor.h \ + $$PHONON_MMF_DIR/abstractvideooutput.h \ + $$PHONON_MMF_DIR/abstractvideoplayer.h \ $$PHONON_MMF_DIR/audioequalizer.h \ $$PHONON_MMF_DIR/audiooutput.h \ $$PHONON_MMF_DIR/audioplayer.h \ @@ -40,23 +43,22 @@ HEADERS += \ $$PHONON_MMF_DIR/loudness.h \ $$PHONON_MMF_DIR/mediaobject.h \ $$PHONON_MMF_DIR/mmf_medianode.h \ - $$PHONON_MMF_DIR/mmf_videoplayer.h \ $$PHONON_MMF_DIR/stereowidening.h \ $$PHONON_MMF_DIR/objectdump.h \ $$PHONON_MMF_DIR/objectdump_symbian.h \ $$PHONON_MMF_DIR/objecttree.h \ $$PHONON_MMF_DIR/utils.h \ - $$PHONON_MMF_DIR/videooutput.h \ $$PHONON_MMF_DIR/videowidget.h SOURCES += \ $$PHONON_MMF_DIR/abstractaudioeffect.cpp \ $$PHONON_MMF_DIR/abstractmediaplayer.cpp \ $$PHONON_MMF_DIR/abstractplayer.cpp \ - $$PHONON_MMF_DIR/ancestormovemonitor.cpp \ $$PHONON_MMF_DIR/audioequalizer.cpp \ $$PHONON_MMF_DIR/audiooutput.cpp \ $$PHONON_MMF_DIR/audioplayer.cpp \ + $$PHONON_MMF_DIR/abstractvideooutput.cpp \ + $$PHONON_MMF_DIR/abstractvideoplayer.cpp \ $$PHONON_MMF_DIR/backend.cpp \ $$PHONON_MMF_DIR/bassboost.cpp \ $$PHONON_MMF_DIR/dummyplayer.cpp \ @@ -66,15 +68,34 @@ SOURCES += \ $$PHONON_MMF_DIR/loudness.cpp \ $$PHONON_MMF_DIR/mediaobject.cpp \ $$PHONON_MMF_DIR/mmf_medianode.cpp \ - $$PHONON_MMF_DIR/mmf_videoplayer.cpp \ $$PHONON_MMF_DIR/stereowidening.cpp \ $$PHONON_MMF_DIR/objectdump.cpp \ $$PHONON_MMF_DIR/objectdump_symbian.cpp \ $$PHONON_MMF_DIR/objecttree.cpp \ $$PHONON_MMF_DIR/utils.cpp \ - $$PHONON_MMF_DIR/videooutput.cpp \ $$PHONON_MMF_DIR/videowidget.cpp +# Test for whether the build environment supports video rendering to graphics +# surfaces. +exists($${EPOCROOT}epoc32/include/platform/videoplayer2.h) { + HEADERS += \ + $$PHONON_MMF_DIR/videooutput_surface.h \ + $$PHONON_MMF_DIR/videoplayer_surface.h + SOURCES += \ + $$PHONON_MMF_DIR/videooutput_surface.cpp \ + $$PHONON_MMF_DIR/videoplayer_surface.cpp + DEFINES += PHONON_MMF_VIDEO_SURFACES +} else { + HEADERS += \ + $$PHONON_MMF_DIR/ancestormovemonitor.h \ + $$PHONON_MMF_DIR/videooutput_dsa.h \ + $$PHONON_MMF_DIR/videoplayer_dsa.h + SOURCES += \ + $$PHONON_MMF_DIR/ancestormovemonitor.cpp \ + $$PHONON_MMF_DIR/videooutput_dsa.cpp \ + $$PHONON_MMF_DIR/videoplayer_dsa.cpp \ +} + LIBS += -lcone LIBS += -lws32 diff --git a/src/plugins/qpluginbase.pri b/src/plugins/qpluginbase.pri index 3dd3d2e..8b119b5 100644 --- a/src/plugins/qpluginbase.pri +++ b/src/plugins/qpluginbase.pri @@ -17,5 +17,6 @@ wince*:LIBS += $$QMAKE_LIBS_GUI symbian: { TARGET.EPOCALLOWDLLDATA=1 TARGET.CAPABILITY = All -Tcb + TARGET = $${TARGET}$${QT_LIBINFIX} load(armcc_warnings) } diff --git a/src/plugins/s60/3_1/3_1.pro b/src/plugins/s60/3_1/3_1.pro index 58ff5ce..9437f3d 100644 --- a/src/plugins/s60/3_1/3_1.pro +++ b/src/plugins/s60/3_1/3_1.pro @@ -1,6 +1,6 @@ include(../s60pluginbase.pri) -TARGET = qts60plugin_3_1 +TARGET = qts60plugin_3_1$${QT_LIBINFIX} SOURCES += ../src/qlocale_3_1.cpp \ ../src/qdesktopservices_3_1.cpp \ diff --git a/src/plugins/s60/3_2/3_2.pro b/src/plugins/s60/3_2/3_2.pro index 7700677..0524866 100644 --- a/src/plugins/s60/3_2/3_2.pro +++ b/src/plugins/s60/3_2/3_2.pro @@ -1,6 +1,6 @@ include(../s60pluginbase.pri) -TARGET = qts60plugin_3_2 +TARGET = qts60plugin_3_2$${QT_LIBINFIX} contains(S60_VERSION, 3.1) { SOURCES += ../src/qlocale_3_1.cpp \ diff --git a/src/plugins/s60/5_0/5_0.pro b/src/plugins/s60/5_0/5_0.pro index 164dfaa..00aea1b 100644 --- a/src/plugins/s60/5_0/5_0.pro +++ b/src/plugins/s60/5_0/5_0.pro @@ -1,6 +1,6 @@ include(../s60pluginbase.pri) -TARGET = qts60plugin_5_0 +TARGET = qts60plugin_5_0$${QT_LIBINFIX} contains(S60_VERSION, 3.1) { SOURCES += ../src/qlocale_3_1.cpp \ diff --git a/src/s60installs/s60installs.pro b/src/s60installs/s60installs.pro index b2e873f..db1ee4d 100644 --- a/src/s60installs/s60installs.pro +++ b/src/s60installs/s60installs.pro @@ -7,25 +7,38 @@ symbian: { SUBDIRS= # WARNING: Changing TARGET name will break Symbian SISX upgrade functionality # DO NOT TOUCH TARGET VARIABLE IF YOU ARE NOT SURE WHAT YOU ARE DOING - TARGET = "Qt" - TARGET.UID3 = 0x2001E61C + TARGET = "Qt$${QT_LIBINFIX}" + + isEmpty(QT_LIBINFIX) { + TARGET.UID3 = 0x2001E61C + + # sqlite3 is expected to be already found on phone if infixed configuration is built. + sqlitedeployment = \ + "; Deploy sqlite onto phone that does not have it already" \ + "@\"$$PWD/sqlite3.sis\", (0x2002af5f)" + qtlibraries.pkg_postrules += sqlitedeployment + } else { + # Always use experimental UID for infixed configuration to avoid UID clash + TARGET.UID3 = 0xE001E61C + } VERSION=$${QT_MAJOR_VERSION}.$${QT_MINOR_VERSION}.$${QT_PATCH_VERSION} symbian-abld|symbian-sbsv2 { - qtresources.sources = $${EPOCROOT}$$HW_ZDIR$$APP_RESOURCE_DIR/s60main.rsc + qtresources.sources = $${EPOCROOT}$$HW_ZDIR$$APP_RESOURCE_DIR/s60main$${QT_LIBINFIX}.rsc } else { - qtresources.sources = $$QMAKE_LIBDIR_QT/s60main.rsc + qtresources.sources = $$QMAKE_LIBDIR_QT/s60main$${QT_LIBINFIX}.rsc DESTDIR = $$QMAKE_LIBDIR_QT } qtresources.path = c:$$APP_RESOURCE_DIR + DEPLOYMENT += qtresources qtlibraries.sources = \ - $$QMAKE_LIBDIR_QT/QtCore.dll \ - $$QMAKE_LIBDIR_QT/QtXml.dll \ - $$QMAKE_LIBDIR_QT/QtGui.dll \ - $$QMAKE_LIBDIR_QT/QtNetwork.dll \ - $$QMAKE_LIBDIR_QT/QtTest.dll \ - $$QMAKE_LIBDIR_QT/QtSql.dll + $$QMAKE_LIBDIR_QT/QtCore$${QT_LIBINFIX}.dll \ + $$QMAKE_LIBDIR_QT/QtXml$${QT_LIBINFIX}.dll \ + $$QMAKE_LIBDIR_QT/QtGui$${QT_LIBINFIX}.dll \ + $$QMAKE_LIBDIR_QT/QtNetwork$${QT_LIBINFIX}.dll \ + $$QMAKE_LIBDIR_QT/QtTest$${QT_LIBINFIX}.dll \ + $$QMAKE_LIBDIR_QT/QtSql$${QT_LIBINFIX}.dll symbian-abld|symbian-sbsv2 { pluginLocations = $${EPOCROOT}epoc32/release/$(PLATFORM)/$(TARGET) @@ -35,20 +48,16 @@ symbian: { qts60plugindeployment = \ "IF package(0x1028315F)" \ - " \"$$pluginLocations/qts60plugin_5_0.dll\" - \"c:\\sys\\bin\\qts60plugin_5_0.dll\"" \ + " \"$$pluginLocations/qts60plugin_5_0$${QT_LIBINFIX}.dll\" - \"c:\\sys\\bin\\qts60plugin_5_0$${QT_LIBINFIX}.dll\"" \ "ELSEIF package(0x102752AE)" \ - " \"$$pluginLocations/qts60plugin_3_2.dll\" - \"c:\\sys\\bin\\qts60plugin_3_2.dll\"" \ + " \"$$pluginLocations/qts60plugin_3_2$${QT_LIBINFIX}.dll\" - \"c:\\sys\\bin\\qts60plugin_3_2$${QT_LIBINFIX}.dll\"" \ "ELSEIF package(0x102032BE)" \ - " \"$$pluginLocations/qts60plugin_3_1.dll\" - \"c:\\sys\\bin\\qts60plugin_3_1.dll\"" \ + " \"$$pluginLocations/qts60plugin_3_1$${QT_LIBINFIX}.dll\" - \"c:\\sys\\bin\\qts60plugin_3_1$${QT_LIBINFIX}.dll\"" \ "ELSE" \ - " \"$$pluginLocations/qts60plugin_5_0.dll\" - \"c:\\sys\\bin\\qts60plugin_5_0.dll\"" \ + " \"$$pluginLocations/qts60plugin_5_0$${QT_LIBINFIX}.dll\" - \"c:\\sys\\bin\\qts60plugin_5_0$${QT_LIBINFIX}.dll\"" \ "ENDIF" qtlibraries.pkg_postrules += qts60plugindeployment - sqlitedeployment = \ - "; Deploy sqlite onto phone that does not have it already" \ - "@\"$$PWD/sqlite3.sis\", (0x2002af5f)" - qtlibraries.pkg_postrules += sqlitedeployment qtlibraries.path = c:/sys/bin @@ -72,18 +81,18 @@ symbian: { } qtlibraries.pkg_prerules += "(0x2002af5f), 0, 5, 0, {\"sqlite3\"}" - !contains(QT_CONFIG, no-jpeg): imageformats_plugins.sources += $$QT_BUILD_TREE/plugins/imageformats/qjpeg.dll - !contains(QT_CONFIG, no-gif): imageformats_plugins.sources += $$QT_BUILD_TREE/plugins/imageformats/qgif.dll - !contains(QT_CONFIG, no-mng): imageformats_plugins.sources += $$QT_BUILD_TREE/plugins/imageformats/qmng.dll - !contains(QT_CONFIG, no-tiff): imageformats_plugins.sources += $$QT_BUILD_TREE/plugins/imageformats/qtiff.dll - !contains(QT_CONFIG, no-ico): imageformats_plugins.sources += $$QT_BUILD_TREE/plugins/imageformats/qico.dll + !contains(QT_CONFIG, no-jpeg): imageformats_plugins.sources += $$QT_BUILD_TREE/plugins/imageformats/qjpeg$${QT_LIBINFIX}.dll + !contains(QT_CONFIG, no-gif): imageformats_plugins.sources += $$QT_BUILD_TREE/plugins/imageformats/qgif$${QT_LIBINFIX}.dll + !contains(QT_CONFIG, no-mng): imageformats_plugins.sources += $$QT_BUILD_TREE/plugins/imageformats/qmng$${QT_LIBINFIX}.dll + !contains(QT_CONFIG, no-tiff): imageformats_plugins.sources += $$QT_BUILD_TREE/plugins/imageformats/qtiff$${QT_LIBINFIX}.dll + !contains(QT_CONFIG, no-ico): imageformats_plugins.sources += $$QT_BUILD_TREE/plugins/imageformats/qico$${QT_LIBINFIX}.dll imageformats_plugins.path = c:$$QT_PLUGINS_BASE_DIR/imageformats - codecs_plugins.sources = $$QT_BUILD_TREE/plugins/codecs/qcncodecs.dll $$QT_BUILD_TREE/plugins/codecs/qjpcodecs.dll $$QT_BUILD_TREE/plugins/codecs/qtwcodecs.dll $$QT_BUILD_TREE/plugins/codecs/qkrcodecs.dll + codecs_plugins.sources = $$QT_BUILD_TREE/plugins/codecs/qcncodecs$${QT_LIBINFIX}.dll $$QT_BUILD_TREE/plugins/codecs/qjpcodecs$${QT_LIBINFIX}.dll $$QT_BUILD_TREE/plugins/codecs/qtwcodecs$${QT_LIBINFIX}.dll $$QT_BUILD_TREE/plugins/codecs/qkrcodecs$${QT_LIBINFIX}.dll codecs_plugins.path = c:$$QT_PLUGINS_BASE_DIR/codecs contains(QT_CONFIG, phonon-backend) { - phonon_backend_plugins.sources += $$QMAKE_LIBDIR_QT/phonon_mmf.dll + phonon_backend_plugins.sources += $$QMAKE_LIBDIR_QT/phonon_mmf$${QT_LIBINFIX}.dll phonon_backend_plugins.path = c:$$QT_PLUGINS_BASE_DIR/phonon_backend DEPLOYMENT += phonon_backend_plugins @@ -94,10 +103,9 @@ symbian: { qtbackup.path = c:/private/10202D56/import/packages/$$replace(TARGET.UID3, 0x,) bearer_plugins.path = c:$$QT_PLUGINS_BASE_DIR/bearer - bearer_plugins.sources += $$QT_BUILD_TREE/plugins/bearer/qsymbianbearer.dll + bearer_plugins.sources += $$QT_BUILD_TREE/plugins/bearer/qsymbianbearer$${QT_LIBINFIX}.dll - DEPLOYMENT += qtresources \ - qtlibraries \ + DEPLOYMENT += qtlibraries \ qtbackup \ imageformats_plugins \ codecs_plugins \ @@ -105,37 +113,37 @@ symbian: { bearer_plugins contains(QT_CONFIG, svg): { - qtlibraries.sources += $$QMAKE_LIBDIR_QT/QtSvg.dll - imageformats_plugins.sources += $$QT_BUILD_TREE/plugins/imageformats/qsvg.dll - iconengines_plugins.sources = $$QT_BUILD_TREE/plugins/iconengines/qsvgicon.dll + qtlibraries.sources += $$QMAKE_LIBDIR_QT/QtSvg$${QT_LIBINFIX}.dll + imageformats_plugins.sources += $$QT_BUILD_TREE/plugins/imageformats/qsvg$${QT_LIBINFIX}.dll + iconengines_plugins.sources = $$QT_BUILD_TREE/plugins/iconengines/qsvgicon$${QT_LIBINFIX}.dll iconengines_plugins.path = c:$$QT_PLUGINS_BASE_DIR/iconengines DEPLOYMENT += iconengines_plugins } contains(QT_CONFIG, phonon): { - qtlibraries.sources += $$QMAKE_LIBDIR_QT/phonon.dll + qtlibraries.sources += $$QMAKE_LIBDIR_QT/phonon$${QT_LIBINFIX}.dll } contains(QT_CONFIG, script): { - qtlibraries.sources += $$QMAKE_LIBDIR_QT/QtScript.dll + qtlibraries.sources += $$QMAKE_LIBDIR_QT/QtScript$${QT_LIBINFIX}.dll } contains(QT_CONFIG, xmlpatterns): { - qtlibraries.sources += $$QMAKE_LIBDIR_QT/QtXmlPatterns.dll + qtlibraries.sources += $$QMAKE_LIBDIR_QT/QtXmlPatterns$${QT_LIBINFIX}.dll } contains(QT_CONFIG, declarative): { - qtlibraries.sources += $$QMAKE_LIBDIR_QT/QtDeclarative.dll + qtlibraries.sources += $$QMAKE_LIBDIR_QT/QtDeclarative$${QT_LIBINFIX}.dll } graphicssystems_plugins.path = c:$$QT_PLUGINS_BASE_DIR/graphicssystems contains(QT_CONFIG, openvg) { - qtlibraries.sources += $$QMAKE_LIBDIR_QT/QtOpenVG.dll - graphicssystems_plugins.sources += $$QT_BUILD_TREE/plugins/graphicssystems/qvggraphicssystem.dll + qtlibraries.sources += $$QMAKE_LIBDIR_QT/QtOpenVG$${QT_LIBINFIX}.dll + graphicssystems_plugins.sources += $$QT_BUILD_TREE/plugins/graphicssystems/qvggraphicssystem$${QT_LIBINFIX}.dll } contains(QT_CONFIG, multimedia) { - qtlibraries.sources += $$QMAKE_LIBDIR_QT/QtMultimedia.dll + qtlibraries.sources += $$QMAKE_LIBDIR_QT/QtMultimedia$${QT_LIBINFIX}.dll } BLD_INF_RULES.prj_exports += "qt.iby $$CORE_MW_LAYER_IBY_EXPORT_PATH(qt.iby)" diff --git a/src/script/api/qscriptengine.cpp b/src/script/api/qscriptengine.cpp index 294c3a0..356b4d0 100644 --- a/src/script/api/qscriptengine.cpp +++ b/src/script/api/qscriptengine.cpp @@ -3318,7 +3318,7 @@ void QScriptEngine::installTranslatorFunctions(const QScriptValue &object) JSC::JSValue jscObject = d->scriptValueToJSCValue(object); JSC::JSGlobalObject *glob = d->originalGlobalObject(); if (!jscObject || !jscObject.isObject()) - jscObject = glob; + jscObject = d->globalObject(); // unsigned attribs = JSC::DontEnum; JSC::asObject(jscObject)->putDirectFunction(exec, new (exec)JSC::NativeFunctionWrapper(exec, glob->prototypeFunctionStructure(), 5, JSC::Identifier(exec, "qsTranslate"), QScript::functionQsTranslate)); JSC::asObject(jscObject)->putDirectFunction(exec, new (exec)JSC::NativeFunctionWrapper(exec, glob->prototypeFunctionStructure(), 2, JSC::Identifier(exec, "QT_TRANSLATE_NOOP"), QScript::functionQsTranslateNoOp)); diff --git a/src/script/api/qscriptvalue.cpp b/src/script/api/qscriptvalue.cpp index a3af2d4..5db1165 100644 --- a/src/script/api/qscriptvalue.cpp +++ b/src/script/api/qscriptvalue.cpp @@ -1609,7 +1609,7 @@ QScriptValue QScriptValue::call(const QScriptValue &thisObject, JSC::MarkedArgumentBuffer applyArgs; if (!array.isUndefinedOrNull()) { if (!array.isObject()) { - return d->engine->scriptValueFromJSCValue(JSC::throwError(exec, JSC::TypeError)); + return d->engine->scriptValueFromJSCValue(JSC::throwError(exec, JSC::TypeError, "Arguments must be an array")); } if (JSC::asObject(array)->classInfo() == &JSC::Arguments::info) JSC::asArguments(array)->fillArgList(exec, applyArgs); @@ -1620,8 +1620,7 @@ QScriptValue QScriptValue::call(const QScriptValue &thisObject, for (unsigned i = 0; i < length; ++i) applyArgs.append(JSC::asArray(array)->get(exec, i)); } else { - Q_ASSERT_X(false, Q_FUNC_INFO, "implement me"); -// return JSC::throwError(exec, JSC::TypeError); + return d->engine->scriptValueFromJSCValue(JSC::throwError(exec, JSC::TypeError, "Arguments must be an array")); } } diff --git a/src/script/bridge/qscriptclassobject.cpp b/src/script/bridge/qscriptclassobject.cpp index a7b5f48..dd229f1 100644 --- a/src/script/bridge/qscriptclassobject.cpp +++ b/src/script/bridge/qscriptclassobject.cpp @@ -234,7 +234,7 @@ JSC::JSObject* ClassObjectDelegate::construct(JSC::ExecState *exec, JSC::JSObjec QScriptClass *scriptClass = static_cast<ClassObjectDelegate*>(delegate)->scriptClass(); QScriptEnginePrivate *eng_p = scriptEngineFromExec(exec); - //JSC::ExecState *oldFrame = eng_p->currentFrame; + JSC::ExecState *oldFrame = eng_p->currentFrame; eng_p->pushContext(exec, JSC::JSValue(), args, callee, true); QScriptContext *ctx = eng_p->contextForFrame(eng_p->currentFrame); @@ -242,6 +242,8 @@ JSC::JSObject* ClassObjectDelegate::construct(JSC::ExecState *exec, JSC::JSObjec QScriptValue result = qvariant_cast<QScriptValue>(scriptClass->extension(QScriptClass::Callable, qVariantFromValue(ctx))); if (!result.isObject()) result = defaultObject; + eng_p->popContext(); + eng_p->currentFrame = oldFrame; return JSC::asObject(eng_p->scriptValueToJSCValue(result)); } diff --git a/src/tools/moc/generator.cpp b/src/tools/moc/generator.cpp index 6729c62..9a982d0 100644 --- a/src/tools/moc/generator.cpp +++ b/src/tools/moc/generator.cpp @@ -738,18 +738,23 @@ void Generator::generateMetacall() const PropertyDef &p = cdef->propertyList.at(propindex); if (p.read.isEmpty()) continue; + QByteArray prefix; + if (p.inPrivateClass.size()) { + prefix = p.inPrivateClass; + prefix.append("->"); + } if (p.gspec == PropertyDef::PointerSpec) - fprintf(out, " case %d: _a[0] = const_cast<void*>(reinterpret_cast<const void*>(%s())); break;\n", - propindex, p.read.constData()); + fprintf(out, " case %d: _a[0] = const_cast<void*>(reinterpret_cast<const void*>(%s%s())); break;\n", + propindex, prefix.constData(), p.read.constData()); else if (p.gspec == PropertyDef::ReferenceSpec) - fprintf(out, " case %d: _a[0] = const_cast<void*>(reinterpret_cast<const void*>(&%s())); break;\n", - propindex, p.read.constData()); + fprintf(out, " case %d: _a[0] = const_cast<void*>(reinterpret_cast<const void*>(&%s%s())); break;\n", + propindex, prefix.constData(), p.read.constData()); else if (cdef->enumDeclarations.value(p.type, false)) - fprintf(out, " case %d: *reinterpret_cast<int*>(_v) = QFlag(%s()); break;\n", - propindex, p.read.constData()); + fprintf(out, " case %d: *reinterpret_cast<int*>(_v) = QFlag(%s%s()); break;\n", + propindex, prefix.constData(), p.read.constData()); else - fprintf(out, " case %d: *reinterpret_cast< %s*>(_v) = %s(); break;\n", - propindex, p.type.constData(), p.read.constData()); + fprintf(out, " case %d: *reinterpret_cast< %s*>(_v) = %s%s(); break;\n", + propindex, p.type.constData(), prefix.constData(), p.read.constData()); } fprintf(out, " }\n"); } @@ -768,12 +773,17 @@ void Generator::generateMetacall() const PropertyDef &p = cdef->propertyList.at(propindex); if (p.write.isEmpty()) continue; + QByteArray prefix; + if (p.inPrivateClass.size()) { + prefix = p.inPrivateClass; + prefix.append("->"); + } if (cdef->enumDeclarations.value(p.type, false)) { - fprintf(out, " case %d: %s(QFlag(*reinterpret_cast<int*>(_v))); break;\n", - propindex, p.write.constData()); + fprintf(out, " case %d: %s%s(QFlag(*reinterpret_cast<int*>(_v))); break;\n", + propindex, prefix.constData(), p.write.constData()); } else { - fprintf(out, " case %d: %s(*reinterpret_cast< %s*>(_v)); break;\n", - propindex, p.write.constData(), p.type.constData()); + fprintf(out, " case %d: %s%s(*reinterpret_cast< %s*>(_v)); break;\n", + propindex, prefix.constData(), p.write.constData(), p.type.constData()); } } fprintf(out, " }\n"); @@ -791,8 +801,13 @@ void Generator::generateMetacall() const PropertyDef &p = cdef->propertyList.at(propindex); if (!p.reset.endsWith(')')) continue; - fprintf(out, " case %d: %s; break;\n", - propindex, p.reset.constData()); + QByteArray prefix; + if (p.inPrivateClass.size()) { + prefix = p.inPrivateClass; + prefix.append("->"); + } + fprintf(out, " case %d: %s%s; break;\n", + propindex, prefix.constData(), p.reset.constData()); } fprintf(out, " }\n"); } diff --git a/src/tools/moc/keywords.cpp b/src/tools/moc/keywords.cpp index abc6be0..df1ba0d 100644 --- a/src/tools/moc/keywords.cpp +++ b/src/tools/moc/keywords.cpp @@ -43,12 +43,12 @@ // DO NOT EDIT. static const short keyword_trans[][128] = { - {0,0,0,0,0,0,0,0,0,525,522,0,0,0,0,0, + {0,0,0,0,0,0,0,0,0,533,530,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 525,252,523,526,0,38,239,524,25,26,236,234,30,235,27,237, + 533,252,531,534,0,38,239,532,25,26,236,234,30,235,27,237, 22,22,22,22,22,22,22,22,22,22,34,41,23,39,24,43, 0,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, - 8,21,8,8,8,8,8,8,8,8,8,31,527,32,238,8, + 8,21,8,8,8,8,8,8,8,8,8,31,535,32,238,8, 0,1,2,3,4,5,6,7,8,9,8,8,10,11,12,13, 14,8,15,16,17,18,19,20,8,8,8,36,245,37,248,0}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, @@ -190,7 +190,7 @@ static const short keyword_trans[][128] = { {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,42,0,0,0,28,0, - 530,530,530,530,530,530,530,530,530,530,0,0,0,0,0,0, + 538,538,538,538,538,538,538,538,538,538,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, @@ -349,7 +349,7 @@ static const short keyword_trans[][128] = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,529,0,0,0,0,528, + 0,0,0,0,0,0,0,0,0,0,537,0,0,0,0,536, 0,0,0,0,0,0,0,0,0,0,0,0,0,258,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, @@ -430,6 +430,14 @@ static const short keyword_trans[][128] = { {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 522,0,0,481,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, + {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,497,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,486, @@ -925,12 +933,12 @@ static const struct {CHARACTER, 0, 84, 478, CHARACTER}, {CHARACTER, 0, 69, 479, CHARACTER}, {CHARACTER, 0, 95, 480, CHARACTER}, - {CHARACTER, 0, 83, 481, CHARACTER}, + {CHARACTER, 48, 0, 0, CHARACTER}, {CHARACTER, 0, 76, 482, CHARACTER}, {CHARACTER, 0, 79, 483, CHARACTER}, {CHARACTER, 0, 84, 484, CHARACTER}, {Q_PRIVATE_SLOT_TOKEN, 0, 0, 0, CHARACTER}, - {CHARACTER, 48, 0, 0, CHARACTER}, + {CHARACTER, 49, 0, 0, CHARACTER}, {CHARACTER, 0, 77, 487, CHARACTER}, {CHARACTER, 0, 79, 488, CHARACTER}, {CHARACTER, 0, 67, 489, CHARACTER}, @@ -967,6 +975,14 @@ static const struct {CHARACTER, 0, 76, 520, CHARACTER}, {CHARACTER, 0, 69, 521, CHARACTER}, {Q_SCRIPTABLE_TOKEN, 0, 0, 0, CHARACTER}, + {CHARACTER, 0, 82, 523, CHARACTER}, + {CHARACTER, 0, 79, 524, CHARACTER}, + {CHARACTER, 0, 80, 525, CHARACTER}, + {CHARACTER, 0, 69, 526, CHARACTER}, + {CHARACTER, 0, 82, 527, CHARACTER}, + {CHARACTER, 0, 84, 528, CHARACTER}, + {CHARACTER, 0, 89, 529, CHARACTER}, + {Q_PRIVATE_PROPERTY_TOKEN, 0, 0, 0, CHARACTER}, {NEWLINE, 0, 0, 0, NOTOKEN}, {QUOTE, 0, 0, 0, NOTOKEN}, {SINGLEQUOTE, 0, 0, 0, NOTOKEN}, diff --git a/src/tools/moc/moc.cpp b/src/tools/moc/moc.cpp index 94ad56f..680b8a5 100644 --- a/src/tools/moc/moc.cpp +++ b/src/tools/moc/moc.cpp @@ -658,6 +658,9 @@ void Moc::parse() case Q_PRIVATE_SLOT_TOKEN: parseSlotInPrivate(&def, access); break; + case Q_PRIVATE_PROPERTY_TOKEN: + parsePrivateProperty(&def); + break; case ENUM: { EnumDef enumDef; if (parseEnum(&enumDef)) @@ -872,11 +875,8 @@ void Moc::parseSignals(ClassDef *def) } } - -void Moc::parseProperty(ClassDef *def) +void Moc::createPropertyDef(PropertyDef &propDef) { - next(LPAREN); - PropertyDef propDef; QByteArray type = parseType().name; if (type.isEmpty()) error(); @@ -964,7 +964,6 @@ void Moc::parseProperty(ClassDef *def) error(2); } } - next(RPAREN); if (propDef.read.isNull()) { QByteArray msg; msg += "Property declaration "; @@ -988,6 +987,41 @@ void Moc::parseProperty(ClassDef *def) propDef.constant = false; warning(msg.constData()); } +} + +void Moc::parseProperty(ClassDef *def) +{ + next(LPAREN); + PropertyDef propDef; + createPropertyDef(propDef); + next(RPAREN); + + + if(!propDef.notify.isEmpty()) + def->notifyableProperties++; + def->propertyList += propDef; +} + +void Moc::parsePrivateProperty(ClassDef *def) +{ + next(LPAREN); + PropertyDef propDef; + next(IDENTIFIER); + propDef.inPrivateClass = lexem(); + while (test(SCOPE)) { + propDef.inPrivateClass += lexem(); + next(IDENTIFIER); + propDef.inPrivateClass += lexem(); + } + // also allow void functions + if (test(LPAREN)) { + next(RPAREN); + propDef.inPrivateClass += "()"; + } + + next(COMMA); + + createPropertyDef(propDef); if(!propDef.notify.isEmpty()) def->notifyableProperties++; diff --git a/src/tools/moc/moc.h b/src/tools/moc/moc.h index 10abfc6..d365ed5 100644 --- a/src/tools/moc/moc.h +++ b/src/tools/moc/moc.h @@ -116,7 +116,7 @@ struct FunctionDef struct PropertyDef { PropertyDef():notifyId(-1), constant(false), final(false), gspec(ValueSpec){} - QByteArray name, type, read, write, reset, designable, scriptable, editable, stored, user, notify; + QByteArray name, type, read, write, reset, designable, scriptable, editable, stored, user, notify, inPrivateClass; int notifyId; bool constant; bool final; @@ -217,6 +217,7 @@ public: void parseSlots(ClassDef *def, FunctionDef::Access access); void parseSignals(ClassDef *def); void parseProperty(ClassDef *def); + void createPropertyDef(PropertyDef &def); void parseEnumOrFlag(ClassDef *def, bool isFlag); void parseFlag(ClassDef *def); void parseClassInfo(ClassDef *def); @@ -224,6 +225,7 @@ public: void parseDeclareInterface(); void parseDeclareMetatype(); void parseSlotInPrivate(ClassDef *def, FunctionDef::Access access); + void parsePrivateProperty(ClassDef *def); void parseFunctionArguments(FunctionDef *def); diff --git a/src/tools/moc/token.cpp b/src/tools/moc/token.cpp index 98307a1..3da9446 100644 --- a/src/tools/moc/token.cpp +++ b/src/tools/moc/token.cpp @@ -179,6 +179,7 @@ const char *tokenTypeName(Token t) case Q_SIGNAL_TOKEN: return "Q_SIGNAL_TOKEN"; case Q_SLOT_TOKEN: return "Q_SLOT_TOKEN"; case Q_PRIVATE_SLOT_TOKEN: return "Q_PRIVATE_SLOT_TOKEN"; + case Q_PRIVATE_PROPERTY_TOKEN: return "Q_PRIVATE_PROPERTY_TOKEN"; case SPECIAL_TREATMENT_MARK: return "SPECIAL_TREATMENT_MARK"; case MOC_INCLUDE_BEGIN: return "MOC_INCLUDE_BEGIN"; case MOC_INCLUDE_END: return "MOC_INCLUDE_END"; diff --git a/src/tools/moc/token.h b/src/tools/moc/token.h index 6b1ad7d..6ca3d84 100644 --- a/src/tools/moc/token.h +++ b/src/tools/moc/token.h @@ -185,6 +185,7 @@ enum Token { Q_QT3_SUPPORT_TOKEN, Q_INVOKABLE_TOKEN, Q_SCRIPTABLE_TOKEN, + Q_PRIVATE_PROPERTY_TOKEN, Q_META_TOKEN_END, SPECIAL_TREATMENT_MARK = Q_META_TOKEN_END, MOC_INCLUDE_BEGIN, diff --git a/src/tools/moc/util/generate_keywords.cpp b/src/tools/moc/util/generate_keywords.cpp index 0641b40..88f187d 100644 --- a/src/tools/moc/util/generate_keywords.cpp +++ b/src/tools/moc/util/generate_keywords.cpp @@ -248,7 +248,7 @@ static const Keyword keywords[] = { { "Q_SIGNAL", "Q_SIGNAL_TOKEN" }, { "Q_SLOT", "Q_SLOT_TOKEN" }, { "Q_SCRIPTABLE", "Q_SCRIPTABLE_TOKEN" }, - + { "Q_PRIVATE_PROPERTY", "Q_PRIVATE_PROPERTY_TOKEN" }, { "\n", "NEWLINE" }, { "\"", "QUOTE" }, { "\'", "SINGLEQUOTE" }, diff --git a/tests/auto/declarative/qdeclarativeanimations/tst_qdeclarativeanimations.cpp b/tests/auto/declarative/qdeclarativeanimations/tst_qdeclarativeanimations.cpp index 076afea..bce7166 100644 --- a/tests/auto/declarative/qdeclarativeanimations/tst_qdeclarativeanimations.cpp +++ b/tests/auto/declarative/qdeclarativeanimations/tst_qdeclarativeanimations.cpp @@ -180,7 +180,7 @@ void tst_qdeclarativeanimations::simpleRotation() QVERIFY(animation.target() == &rect); QVERIFY(animation.property() == "rotation"); QVERIFY(animation.to() == 270); - QVERIFY(animation.direction() == QDeclarativeRotationAnimation::Shortest); + QVERIFY(animation.direction() == QDeclarativeRotationAnimation::Numerical); animation.start(); QVERIFY(animation.isRunning()); QTest::qWait(animation.duration()); @@ -193,7 +193,7 @@ void tst_qdeclarativeanimations::simpleRotation() QVERIFY(animation.isPaused()); animation.setCurrentTime(125); QVERIFY(animation.currentTime() == 125); - QCOMPARE(rect.rotation(), qreal(-45)); + QCOMPARE(rect.rotation(), qreal(135)); } void tst_qdeclarativeanimations::alwaysRunToEnd() diff --git a/tests/auto/declarative/qdeclarativedom/data/importdir/Bar.qml b/tests/auto/declarative/qdeclarativedom/data/import/Bar.qml index 2d1a4a3..2d1a4a3 100644 --- a/tests/auto/declarative/qdeclarativedom/data/importdir/Bar.qml +++ b/tests/auto/declarative/qdeclarativedom/data/import/Bar.qml diff --git a/tests/auto/declarative/qdeclarativedom/data/importlib/sublib/qmldir/Foo.qml b/tests/auto/declarative/qdeclarativedom/data/importlib/sublib/Foo.qml index 2d1a4a3..2d1a4a3 100644 --- a/tests/auto/declarative/qdeclarativedom/data/importlib/sublib/qmldir/Foo.qml +++ b/tests/auto/declarative/qdeclarativedom/data/importlib/sublib/Foo.qml diff --git a/tests/auto/declarative/qdeclarativedom/data/importlib/sublib/qmldir b/tests/auto/declarative/qdeclarativedom/data/importlib/sublib/qmldir new file mode 100644 index 0000000..5bdd17b --- /dev/null +++ b/tests/auto/declarative/qdeclarativedom/data/importlib/sublib/qmldir @@ -0,0 +1 @@ +Foo Foo.qml diff --git a/tests/auto/declarative/qdeclarativedom/tst_qdeclarativedom.cpp b/tests/auto/declarative/qdeclarativedom/tst_qdeclarativedom.cpp index 6cd0bdb..adea384 100644 --- a/tests/auto/declarative/qdeclarativedom/tst_qdeclarativedom.cpp +++ b/tests/auto/declarative/qdeclarativedom/tst_qdeclarativedom.cpp @@ -340,9 +340,8 @@ void tst_qdeclarativedom::loadImports() "Item {}"; QDeclarativeEngine engine; - engine.addImportPath(SRCDIR "/data"); QDeclarativeDomDocument document; - QVERIFY(document.load(&engine, qml)); + QVERIFY(document.load(&engine, qml, QUrl::fromLocalFile(SRCDIR "/data/dummy.qml"))); QCOMPARE(document.imports().size(), 5); diff --git a/tests/auto/declarative/qdeclarativeinstruction/tst_qdeclarativeinstruction.cpp b/tests/auto/declarative/qdeclarativeinstruction/tst_qdeclarativeinstruction.cpp index 5f6d9a4..c747bfc 100644 --- a/tests/auto/declarative/qdeclarativeinstruction/tst_qdeclarativeinstruction.cpp +++ b/tests/auto/declarative/qdeclarativeinstruction/tst_qdeclarativeinstruction.cpp @@ -507,8 +507,16 @@ void tst_qdeclarativeinstruction::dump() { QDeclarativeInstruction i; + i.line = 48; + i.type = QDeclarativeInstruction::StoreImportedScript; + i.storeScript.value = 2; + data->bytecode << i; + } + + { + QDeclarativeInstruction i; i.line = 50; - i.type = (QDeclarativeInstruction::Type)(QDeclarativeInstruction::Defer + 1); // Non-existant + i.type = (QDeclarativeInstruction::Type)(1234); // Non-existant data->bytecode << i; } @@ -564,7 +572,8 @@ void tst_qdeclarativeinstruction::dump() << "45\t\t47\tPOP_VALUE\t\t35\t8" << "46\t\t48\tDEFER\t\t\t7" << "47\t\tNA\tDEFER\t\t\t7" - << "48\t\t50\tXXX UNKOWN INSTRUCTION\t47" + << "48\t\t48\tSTORE_IMPORTED_SCRIPT\t2" + << "49\t\t50\tXXX UNKOWN INSTRUCTION\t1234" << "-------------------------------------------------------------------------------"; messages = QStringList(); diff --git a/tests/auto/declarative/qdeclarativelanguage/data/importNewerVersion.errors.txt b/tests/auto/declarative/qdeclarativelanguage/data/importNewerVersion.errors.txt new file mode 100644 index 0000000..413f096 --- /dev/null +++ b/tests/auto/declarative/qdeclarativelanguage/data/importNewerVersion.errors.txt @@ -0,0 +1 @@ +1:1:module "Test" version 2.0 is not installed diff --git a/tests/auto/declarative/qdeclarativelanguage/data/importNewerVersion.qml b/tests/auto/declarative/qdeclarativelanguage/data/importNewerVersion.qml new file mode 100644 index 0000000..c4a0d38 --- /dev/null +++ b/tests/auto/declarative/qdeclarativelanguage/data/importNewerVersion.qml @@ -0,0 +1,3 @@ +import Test 2.0 + +MyTypeObject { } diff --git a/tests/auto/declarative/qdeclarativelanguage/data/importNonExist.errors.txt b/tests/auto/declarative/qdeclarativelanguage/data/importNonExist.errors.txt new file mode 100644 index 0000000..1baf05c --- /dev/null +++ b/tests/auto/declarative/qdeclarativelanguage/data/importNonExist.errors.txt @@ -0,0 +1 @@ +2:1:"will-not-be-found": no such directory diff --git a/tests/auto/declarative/qdeclarativelanguage/data/importNonExist.qml b/tests/auto/declarative/qdeclarativelanguage/data/importNonExist.qml new file mode 100644 index 0000000..ec6aa2b --- /dev/null +++ b/tests/auto/declarative/qdeclarativelanguage/data/importNonExist.qml @@ -0,0 +1,5 @@ +// imports... +import "will-not-be-found" +import Qt 4.6 + +Rectangle { } diff --git a/tests/auto/declarative/qdeclarativelanguage/tst_qdeclarativelanguage.cpp b/tests/auto/declarative/qdeclarativelanguage/tst_qdeclarativelanguage.cpp index 9188d72..42426a2 100644 --- a/tests/auto/declarative/qdeclarativelanguage/tst_qdeclarativelanguage.cpp +++ b/tests/auto/declarative/qdeclarativelanguage/tst_qdeclarativelanguage.cpp @@ -264,6 +264,8 @@ void tst_qdeclarativelanguage::errors_data() QTest::newRow("importNamespaceConflict") << "importNamespaceConflict.qml" << "importNamespaceConflict.errors.txt" << false; QTest::newRow("importVersionMissing (builtin)") << "importVersionMissingBuiltIn.qml" << "importVersionMissingBuiltIn.errors.txt" << false; QTest::newRow("importVersionMissing (installed)") << "importVersionMissingInstalled.qml" << "importVersionMissingInstalled.errors.txt" << false; + QTest::newRow("importNonExist (installed)") << "importNonExist.qml" << "importNonExist.errors.txt" << false; + QTest::newRow("importNewerVersion (installed)") << "importNewerVersion.qml" << "importNewerVersion.errors.txt" << false; QTest::newRow("invalidImportID") << "invalidImportID.qml" << "invalidImportID.errors.txt" << false; QTest::newRow("signal.1") << "signal.1.qml" << "signal.1.errors.txt" << false; diff --git a/tests/auto/declarative/qdeclarativelistmodel/tst_qdeclarativelistmodel.cpp b/tests/auto/declarative/qdeclarativelistmodel/tst_qdeclarativelistmodel.cpp index 7a10ad0..576fe21 100644 --- a/tests/auto/declarative/qdeclarativelistmodel/tst_qdeclarativelistmodel.cpp +++ b/tests/auto/declarative/qdeclarativelistmodel/tst_qdeclarativelistmodel.cpp @@ -290,8 +290,6 @@ void tst_QDeclarativeListModel::dynamic_worker_data() void tst_QDeclarativeListModel::dynamic_worker() { - QSKIP("Skip, awaiting imminent fixes", SkipAll); - QFETCH(QString, script); QFETCH(int, result); QFETCH(QString, warning); @@ -342,7 +340,6 @@ void tst_QDeclarativeListModel::dynamic_worker() void tst_QDeclarativeListModel::convertNestedToFlat_fail() { - QSKIP("Skip, awaiting imminent fixes", SkipAll); // If a model has nested data, it cannot be used at all from a worker script QFETCH(QString, script); @@ -390,8 +387,6 @@ void tst_QDeclarativeListModel::convertNestedToFlat_ok() // If a model only has plain data, it can be modified from a worker script. However, // once the model is used from a worker script, it no longer accepts nested data - QSKIP("Skip, awaiting imminent fixes", SkipAll); - QFETCH(QString, script); QDeclarativeListModel model; diff --git a/tests/auto/declarative/qdeclarativeloader/data/differentorigin.qml b/tests/auto/declarative/qdeclarativeloader/data/differentorigin.qml new file mode 100644 index 0000000..e682d1c --- /dev/null +++ b/tests/auto/declarative/qdeclarativeloader/data/differentorigin.qml @@ -0,0 +1,3 @@ +import Qt 4.6 + +Loader { source: "http://evil.place/evil.qml" } diff --git a/tests/auto/declarative/qdeclarativeloader/data/sameorigin-load.qml b/tests/auto/declarative/qdeclarativeloader/data/sameorigin-load.qml new file mode 100644 index 0000000..e281246 --- /dev/null +++ b/tests/auto/declarative/qdeclarativeloader/data/sameorigin-load.qml @@ -0,0 +1,3 @@ +import Qt 4.6 + +Item { } diff --git a/tests/auto/declarative/qdeclarativeloader/data/sameorigin.qml b/tests/auto/declarative/qdeclarativeloader/data/sameorigin.qml new file mode 100644 index 0000000..e7f5a14 --- /dev/null +++ b/tests/auto/declarative/qdeclarativeloader/data/sameorigin.qml @@ -0,0 +1,3 @@ +import Qt 4.6 + +Loader { source: "sameorigin-load.qml" } diff --git a/tests/auto/declarative/qdeclarativeloader/tst_qdeclarativeloader.cpp b/tests/auto/declarative/qdeclarativeloader/tst_qdeclarativeloader.cpp index 2c20836..0deac3a 100644 --- a/tests/auto/declarative/qdeclarativeloader/tst_qdeclarativeloader.cpp +++ b/tests/auto/declarative/qdeclarativeloader/tst_qdeclarativeloader.cpp @@ -86,6 +86,8 @@ private slots: void noResizeGraphicsWidget(); void networkRequestUrl(); void failNetworkRequest(); + void networkSafety(); + void networkSafety_data(); // void networkComponent(); void deleteComponentCrash(); @@ -394,7 +396,7 @@ void tst_QDeclarativeLoader::networkRequestUrl() server.serveDirectory(SRCDIR "/data"); QDeclarativeComponent component(&engine); - component.setData(QByteArray("import Qt 4.6\nLoader { source: \"http://127.0.0.1:14445/Rect120x60.qml\" }"), TEST_FILE("")); + component.setData(QByteArray("import Qt 4.6\nLoader { source: \"http://127.0.0.1:14445/Rect120x60.qml\" }"), QUrl("http://127.0.0.1:14445/dummy.qml")); QDeclarativeLoader *loader = qobject_cast<QDeclarativeLoader*>(component.create()); QVERIFY(loader != 0); @@ -448,7 +450,7 @@ void tst_QDeclarativeLoader::failNetworkRequest() QTest::ignoreMessage(QtWarningMsg, "(:-1: Network error for URL http://127.0.0.1:14445/IDontExist.qml) "); QDeclarativeComponent component(&engine); - component.setData(QByteArray("import Qt 4.6\nLoader { source: \"http://127.0.0.1:14445/IDontExist.qml\" }"), TEST_FILE("")); + component.setData(QByteArray("import Qt 4.6\nLoader { source: \"http://127.0.0.1:14445/IDontExist.qml\" }"), QUrl("http://127.0.0.1:14445/dummy.qml")); QDeclarativeLoader *loader = qobject_cast<QDeclarativeLoader*>(component.create()); QVERIFY(loader != 0); @@ -483,6 +485,41 @@ void tst_QDeclarativeLoader::deleteComponentCrash() delete item; } +void tst_QDeclarativeLoader::networkSafety_data() +{ + QTest::addColumn<QUrl>("url"); + QTest::addColumn<QString>("message"); + + QTest::newRow("same origin") << QUrl("http://127.0.0.1:14445/sameorigin.qml") << QString(); + QTest::newRow("different origin") << QUrl("http://127.0.0.1:14445/differentorigin.qml") << QString(" QUrl( \"http://evil.place/evil.qml\" ) is not a safe origin from QUrl( \"http://127.0.0.1:14445/differentorigin.qml\" ) "); +} + +void tst_QDeclarativeLoader::networkSafety() +{ + TestHTTPServer server(SERVER_PORT); + QVERIFY(server.isValid()); + server.serveDirectory(SRCDIR "/data"); + + QFETCH(QUrl, url); + QFETCH(QString, message); + + if (!message.isEmpty()) + QTest::ignoreMessage(QtWarningMsg, message.toLatin1()); + + QDeclarativeComponent component(&engine, url); + TRY_WAIT(component.status() == QDeclarativeComponent::Ready); + QDeclarativeLoader *loader = qobject_cast<QDeclarativeLoader*>(component.create()); + QVERIFY(loader != 0); + + if (message.isEmpty()) { + TRY_WAIT(loader->status() == QDeclarativeLoader::Ready); + } else { + TRY_WAIT(loader->status() == QDeclarativeLoader::Null); + } + + delete loader; +} + QTEST_MAIN(tst_QDeclarativeLoader) #include "tst_qdeclarativeloader.moc" diff --git a/tests/auto/declarative/qdeclarativemoduleplugin/plugin.qml b/tests/auto/declarative/qdeclarativemoduleplugin/data/works.qml index f29ae24..f29ae24 100644 --- a/tests/auto/declarative/qdeclarativemoduleplugin/plugin.qml +++ b/tests/auto/declarative/qdeclarativemoduleplugin/data/works.qml diff --git a/tests/auto/declarative/qdeclarativemoduleplugin/com/nokia/AutoTestQmlPluginType/qmldir b/tests/auto/declarative/qdeclarativemoduleplugin/imports/com/nokia/AutoTestQmlPluginType/qmldir index 0a8b5d4..0a8b5d4 100644 --- a/tests/auto/declarative/qdeclarativemoduleplugin/com/nokia/AutoTestQmlPluginType/qmldir +++ b/tests/auto/declarative/qdeclarativemoduleplugin/imports/com/nokia/AutoTestQmlPluginType/qmldir diff --git a/tests/auto/declarative/qdeclarativemoduleplugin/plugin/plugin.pro b/tests/auto/declarative/qdeclarativemoduleplugin/plugin/plugin.pro index 035cb7d..fc77225 100644 --- a/tests/auto/declarative/qdeclarativemoduleplugin/plugin/plugin.pro +++ b/tests/auto/declarative/qdeclarativemoduleplugin/plugin/plugin.pro @@ -2,5 +2,5 @@ TEMPLATE = lib CONFIG += plugin SOURCES = plugin.cpp QT = core declarative -DESTDIR = ../com/nokia/AutoTestQmlPluginType +DESTDIR = ../imports/com/nokia/AutoTestQmlPluginType diff --git a/tests/auto/declarative/qdeclarativemoduleplugin/tst_qdeclarativemoduleplugin.cpp b/tests/auto/declarative/qdeclarativemoduleplugin/tst_qdeclarativemoduleplugin.cpp index 1335c7c..26199d3 100644 --- a/tests/auto/declarative/qdeclarativemoduleplugin/tst_qdeclarativemoduleplugin.cpp +++ b/tests/auto/declarative/qdeclarativemoduleplugin/tst_qdeclarativemoduleplugin.cpp @@ -48,8 +48,8 @@ class tst_qdeclarativemoduleplugin : public QObject { Q_OBJECT public: - tst_qdeclarativemoduleplugin() { - QCoreApplication::addLibraryPath(QLatin1String(SRCDIR) + QDir::separator() + QLatin1String("plugin")); + tst_qdeclarativemoduleplugin() + { } private slots: @@ -103,9 +103,10 @@ void tst_qdeclarativemoduleplugin::importsPlugin() { QSKIP("Fix me", SkipAll); QDeclarativeEngine engine; + engine.addImportPath(QLatin1String(SRCDIR) + QDir::separator() + QLatin1String("imports")); QTest::ignoreMessage(QtWarningMsg, "plugin created"); QTest::ignoreMessage(QtWarningMsg, "import worked"); - QDeclarativeComponent component(&engine, TEST_FILE("plugin.qml")); + QDeclarativeComponent component(&engine, TEST_FILE("data/works.qml")); foreach (QDeclarativeError err, component.errors()) qWarning() << err; VERIFY_ERRORS(0); diff --git a/tests/auto/declarative/qdeclarativetextinput/tst_qdeclarativetextinput.cpp b/tests/auto/declarative/qdeclarativetextinput/tst_qdeclarativetextinput.cpp index 8b513e8..e623df6 100644 --- a/tests/auto/declarative/qdeclarativetextinput/tst_qdeclarativetextinput.cpp +++ b/tests/auto/declarative/qdeclarativetextinput/tst_qdeclarativetextinput.cpp @@ -72,6 +72,7 @@ private slots: void readOnly(); void sendRequestSoftwareInputPanelEvent(); + void setHAlignClearCache(); private: void simulateKey(QDeclarativeView *, int key); @@ -651,6 +652,38 @@ void tst_qdeclarativetextinput::sendRequestSoftwareInputPanelEvent() QCOMPARE(ic.softwareInputPanelEventReceived, true); } +class MyTextInput : public QDeclarativeTextInput +{ +public: + MyTextInput(QDeclarativeItem *parent = 0) : QDeclarativeTextInput(parent) + { + nbPaint = 0; + } + void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) + { + nbPaint++; + QDeclarativeTextInput::paint(painter, option, widget); + } + int nbPaint; +}; + +void tst_qdeclarativetextinput::setHAlignClearCache() +{ + QGraphicsScene scene; + QGraphicsView view(&scene); + MyTextInput input; + input.setText("Hello world"); + scene.addItem(&input); + view.show(); + QApplication::setActiveWindow(&view); + QTest::qWaitForWindowShown(&view); + QCOMPARE(input.nbPaint, 1); + input.setHAlign(QDeclarativeTextInput::AlignRight); + QApplication::processEvents(); + //Changing the alignment should trigger a repaint + QCOMPARE(input.nbPaint, 2); +} + QTEST_MAIN(tst_qdeclarativetextinput) #include "tst_qdeclarativetextinput.moc" diff --git a/tests/auto/declarative/visual/animation/parentAction/data/parentAction.0.png b/tests/auto/declarative/visual/animation/parentAction/data/parentAction.0.png Binary files differdeleted file mode 100644 index a0032f8..0000000 --- a/tests/auto/declarative/visual/animation/parentAction/data/parentAction.0.png +++ /dev/null diff --git a/tests/auto/declarative/visual/animation/parentAction/data/parentAction.1.png b/tests/auto/declarative/visual/animation/parentAction/data/parentAction.1.png Binary files differdeleted file mode 100644 index 958b6af..0000000 --- a/tests/auto/declarative/visual/animation/parentAction/data/parentAction.1.png +++ /dev/null diff --git a/tests/auto/declarative/visual/animation/parentAction/data/parentAction.2.png b/tests/auto/declarative/visual/animation/parentAction/data/parentAction.2.png Binary files differdeleted file mode 100644 index 3a1811f..0000000 --- a/tests/auto/declarative/visual/animation/parentAction/data/parentAction.2.png +++ /dev/null diff --git a/tests/auto/declarative/visual/animation/parentAction/data/parentAction.3.png b/tests/auto/declarative/visual/animation/parentAction/data/parentAction.3.png Binary files differdeleted file mode 100644 index 36064c2..0000000 --- a/tests/auto/declarative/visual/animation/parentAction/data/parentAction.3.png +++ /dev/null diff --git a/tests/auto/declarative/visual/animation/parentAction/data/parentAction.4.png b/tests/auto/declarative/visual/animation/parentAction/data/parentAction.4.png Binary files differdeleted file mode 100644 index c493a1d..0000000 --- a/tests/auto/declarative/visual/animation/parentAction/data/parentAction.4.png +++ /dev/null diff --git a/tests/auto/declarative/visual/animation/parentAction/data/parentAction.5.png b/tests/auto/declarative/visual/animation/parentAction/data/parentAction.5.png Binary files differdeleted file mode 100644 index c493a1d..0000000 --- a/tests/auto/declarative/visual/animation/parentAction/data/parentAction.5.png +++ /dev/null diff --git a/tests/auto/declarative/visual/animation/parentAction/data/parentAction.qml b/tests/auto/declarative/visual/animation/parentAction/data/parentAction.qml deleted file mode 100644 index de27af7..0000000 --- a/tests/auto/declarative/visual/animation/parentAction/data/parentAction.qml +++ /dev/null @@ -1,1207 +0,0 @@ -import Qt.VisualTest 4.6 - -VisualTest { - Frame { - msec: 0 - } - Frame { - msec: 16 - hash: "23ce049cd7e715c28f5845fd1a1fc195" - } - Frame { - msec: 32 - hash: "23ce049cd7e715c28f5845fd1a1fc195" - } - Frame { - msec: 48 - hash: "23ce049cd7e715c28f5845fd1a1fc195" - } - Frame { - msec: 64 - hash: "23ce049cd7e715c28f5845fd1a1fc195" - } - Frame { - msec: 80 - hash: "23ce049cd7e715c28f5845fd1a1fc195" - } - Frame { - msec: 96 - hash: "23ce049cd7e715c28f5845fd1a1fc195" - } - Frame { - msec: 112 - hash: "23ce049cd7e715c28f5845fd1a1fc195" - } - Frame { - msec: 128 - hash: "23ce049cd7e715c28f5845fd1a1fc195" - } - Frame { - msec: 144 - hash: "23ce049cd7e715c28f5845fd1a1fc195" - } - Frame { - msec: 160 - hash: "23ce049cd7e715c28f5845fd1a1fc195" - } - Frame { - msec: 176 - hash: "23ce049cd7e715c28f5845fd1a1fc195" - } - Frame { - msec: 192 - hash: "23ce049cd7e715c28f5845fd1a1fc195" - } - Frame { - msec: 208 - hash: "23ce049cd7e715c28f5845fd1a1fc195" - } - Frame { - msec: 224 - hash: "23ce049cd7e715c28f5845fd1a1fc195" - } - Frame { - msec: 240 - hash: "23ce049cd7e715c28f5845fd1a1fc195" - } - Frame { - msec: 256 - hash: "23ce049cd7e715c28f5845fd1a1fc195" - } - Frame { - msec: 272 - hash: "23ce049cd7e715c28f5845fd1a1fc195" - } - Frame { - msec: 288 - hash: "23ce049cd7e715c28f5845fd1a1fc195" - } - Frame { - msec: 304 - hash: "23ce049cd7e715c28f5845fd1a1fc195" - } - Frame { - msec: 320 - hash: "23ce049cd7e715c28f5845fd1a1fc195" - } - Frame { - msec: 336 - hash: "23ce049cd7e715c28f5845fd1a1fc195" - } - Frame { - msec: 352 - hash: "23ce049cd7e715c28f5845fd1a1fc195" - } - Frame { - msec: 368 - hash: "23ce049cd7e715c28f5845fd1a1fc195" - } - Frame { - msec: 384 - hash: "23ce049cd7e715c28f5845fd1a1fc195" - } - Frame { - msec: 400 - hash: "23ce049cd7e715c28f5845fd1a1fc195" - } - Frame { - msec: 416 - hash: "23ce049cd7e715c28f5845fd1a1fc195" - } - Frame { - msec: 432 - hash: "23ce049cd7e715c28f5845fd1a1fc195" - } - Frame { - msec: 448 - hash: "23ce049cd7e715c28f5845fd1a1fc195" - } - Frame { - msec: 464 - hash: "23ce049cd7e715c28f5845fd1a1fc195" - } - Frame { - msec: 480 - hash: "23ce049cd7e715c28f5845fd1a1fc195" - } - Frame { - msec: 496 - hash: "23ce049cd7e715c28f5845fd1a1fc195" - } - Frame { - msec: 512 - hash: "23ce049cd7e715c28f5845fd1a1fc195" - } - Frame { - msec: 528 - hash: "23ce049cd7e715c28f5845fd1a1fc195" - } - Frame { - msec: 544 - hash: "23ce049cd7e715c28f5845fd1a1fc195" - } - Frame { - msec: 560 - hash: "23ce049cd7e715c28f5845fd1a1fc195" - } - Frame { - msec: 576 - hash: "23ce049cd7e715c28f5845fd1a1fc195" - } - Mouse { - type: 2 - button: 1 - buttons: 1 - x: 150; y: 274 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 592 - hash: "23ce049cd7e715c28f5845fd1a1fc195" - } - Frame { - msec: 608 - hash: "a7bb3d44c8bcf403906afa86f5bc3062" - } - Frame { - msec: 624 - hash: "2b366e6009e70fa0227a1fee662fe1bf" - } - Frame { - msec: 640 - hash: "c12869fb8002aa36c3bfad7fd0979240" - } - Frame { - msec: 656 - hash: "56c583e77b5e0a8707e977dc937c2acf" - } - Frame { - msec: 672 - hash: "6b191d57a45a3f2d010a7f44064e409a" - } - Frame { - msec: 688 - hash: "9457ee33c999a63fa4bd4db5c3ceac8b" - } - Frame { - msec: 704 - hash: "446b23b662640ad6ad8c456f956fe73a" - } - Frame { - msec: 720 - hash: "23c59708069406486e4979c7d59f3f4a" - } - Frame { - msec: 736 - hash: "c9ce43ddca79b5b6f26af2c2259dc071" - } - Frame { - msec: 752 - hash: "e838229ba70c30112918f19bb471fa34" - } - Frame { - msec: 768 - hash: "0cbaeddb2ff6408a37a68fc685e2bca0" - } - Frame { - msec: 784 - hash: "616b4ec719586b151ba3d709e51038bf" - } - Frame { - msec: 800 - hash: "89b2c709f5c3083c204a9450e605c1d4" - } - Frame { - msec: 816 - hash: "427a5c2d13631d899ff2d673e762f114" - } - Frame { - msec: 832 - hash: "958aa9ca5a6b91aa6dfbc2a1ae3e2deb" - } - Frame { - msec: 848 - hash: "09a3ac0010ed8f3df2cfa7ed9d0a92e4" - } - Frame { - msec: 864 - hash: "5607ea54f9990f3232d6f56080e1ef15" - } - Frame { - msec: 880 - hash: "600682467c55288b9d5e65299637dd72" - } - Frame { - msec: 896 - hash: "bc7a238611574a13650f854ceac35032" - } - Frame { - msec: 912 - hash: "e5f6b19b3685a96d4d0c3b8384513643" - } - Frame { - msec: 928 - hash: "d5d23b0fc09136fd1ae121e311866cc3" - } - Frame { - msec: 944 - hash: "5099e5edd1a6bd37f5f6c836a6ca7644" - } - Frame { - msec: 960 - image: "parentAction.0.png" - } - Frame { - msec: 976 - hash: "97dd20f7774cfd8379e1d1b44f8ddc7b" - } - Frame { - msec: 992 - hash: "ab2deea9e4f8c43ed58b5a355800ecda" - } - Frame { - msec: 1008 - hash: "88ec383ce368259d3cc18612b6f5b941" - } - Frame { - msec: 1024 - hash: "f84b20b849a77e50717f99b9d844240e" - } - Frame { - msec: 1040 - hash: "6c042360c2d24ad56cec32d01ce82d6b" - } - Frame { - msec: 1056 - hash: "c86b464720192f3e039fa5d8ab5f09bb" - } - Frame { - msec: 1072 - hash: "35ec432fdf91fcd1dfcd945cfe785b09" - } - Frame { - msec: 1088 - hash: "27a2ec28e4fef006622e8211fd709853" - } - Frame { - msec: 1104 - hash: "8454d1f5ed89551e2a403c869885116a" - } - Frame { - msec: 1120 - hash: "7e33aed53dc4338c168274d972c8e711" - } - Frame { - msec: 1136 - hash: "e0192ea2049d6bae6012f00406630a92" - } - Frame { - msec: 1152 - hash: "a2ea5489a373084169024035a0f69e71" - } - Frame { - msec: 1168 - hash: "6947a72c4d959b90dafdaddcac815b3e" - } - Frame { - msec: 1184 - hash: "0e22cc3c96d0934095b7254f0f28b18b" - } - Frame { - msec: 1200 - hash: "72529ddc6f2678a783aedf445d7038a4" - } - Frame { - msec: 1216 - hash: "38f03c0ee50488ffd23a2fb3d3445461" - } - Frame { - msec: 1232 - hash: "b441721ed30c787874a2a71a94e1ba44" - } - Frame { - msec: 1248 - hash: "1e37f26d78590414b2ef01c72ad136a9" - } - Frame { - msec: 1264 - hash: "88e4af80d068485ebd8c3d51f9bbfe8d" - } - Frame { - msec: 1280 - hash: "107707216c16c629d8409cf006f9f2dc" - } - Frame { - msec: 1296 - hash: "f56f3f4f140ac072f7df47eddfc76844" - } - Frame { - msec: 1312 - hash: "41239a9d8ed793c24967875aabeae8a5" - } - Frame { - msec: 1328 - hash: "30035e37320dae4f9ead01a30895eb38" - } - Frame { - msec: 1344 - hash: "fb2f535b42b862b65f8adb3ad1a46779" - } - Frame { - msec: 1360 - hash: "e10ba7f74d52fc963e20a4647ff0d620" - } - Frame { - msec: 1376 - hash: "5abf5388566bed2fdb71afc8cd7cfe9b" - } - Frame { - msec: 1392 - hash: "91990471563e3c8292e8e8325a1d17a2" - } - Frame { - msec: 1408 - hash: "59a6293a48f83a9197adcffed3f32f15" - } - Frame { - msec: 1424 - hash: "db3e75df318e9f0d239ce9b76e92eff3" - } - Frame { - msec: 1440 - hash: "3b5c64bc64a701edb5c2e40b23443bc3" - } - Frame { - msec: 1456 - hash: "9db08c0375148b2317427591b5f43608" - } - Frame { - msec: 1472 - hash: "2d761f1530846eff87a7625a120e0afd" - } - Frame { - msec: 1488 - hash: "c5460f8c58b83c2ac15842ddb023ad4f" - } - Frame { - msec: 1504 - hash: "0efb51810a2dc359c7964268c98ea8eb" - } - Frame { - msec: 1520 - hash: "b92a42012df57eb261badf1f518b8e67" - } - Frame { - msec: 1536 - hash: "8d348bae62af2d35bdfee806a1c39910" - } - Frame { - msec: 1552 - hash: "762d9bb4ed11d249bfd902a541129d60" - } - Frame { - msec: 1568 - hash: "bddbd9f64a9f7156984feccd5fa94093" - } - Frame { - msec: 1584 - hash: "353a98e1573b0518941ff22bf2776244" - } - Frame { - msec: 1600 - hash: "1765aed97e29f25dee93a77a06557b82" - } - Frame { - msec: 1616 - hash: "73b5c2bdb7f268f7a33e129c8ba44013" - } - Frame { - msec: 1632 - hash: "46ac1976fb9932d0ef6e0b5927386ad9" - } - Frame { - msec: 1648 - hash: "90b5b5b46c9c352e8be41cc74f96133a" - } - Frame { - msec: 1664 - hash: "0efe0036577c890fd45cd7dd53014616" - } - Frame { - msec: 1680 - hash: "7f32df17481abf40ccb33afe6d17085d" - } - Frame { - msec: 1696 - hash: "1fa8544c48a476764f4f8278c14b651d" - } - Frame { - msec: 1712 - hash: "f8f06ece30f690deeba5999ce63bf40b" - } - Frame { - msec: 1728 - hash: "885b230f4b2fe380c7cf68955940d206" - } - Frame { - msec: 1744 - hash: "d0fc5aa4df46099bb46a1d7db30baa09" - } - Frame { - msec: 1760 - hash: "8fa7fe5197cbe1ff67f8a2c47f1f0740" - } - Frame { - msec: 1776 - hash: "aa3b3b03460daf54f085551e1a46c08b" - } - Frame { - msec: 1792 - hash: "35a1728a2430027a9474fb7d61090643" - } - Frame { - msec: 1808 - hash: "2b1cff3986b8b03f1061176a4722b0f9" - } - Frame { - msec: 1824 - hash: "8047be1b35ee3d5078a68c6cdc35eeb7" - } - Frame { - msec: 1840 - hash: "7f7afa48bb7d612b354c8488e72c8339" - } - Frame { - msec: 1856 - hash: "691a876caefce9aa0f5140c17059b8f4" - } - Frame { - msec: 1872 - hash: "903bec66e47db766dc431f060726988c" - } - Frame { - msec: 1888 - hash: "f13593fc891f0b050c01b61963019da1" - } - Frame { - msec: 1904 - hash: "aa00de965bdb370a5974b195c3fb38af" - } - Frame { - msec: 1920 - image: "parentAction.1.png" - } - Frame { - msec: 1936 - hash: "168d3e27261c0943e6262b6be27adfb0" - } - Frame { - msec: 1952 - hash: "6fafebd0b396e7c0a78c767c6af936ba" - } - Frame { - msec: 1968 - hash: "827e3a3fcd6fd8588e9fcc043769b3a8" - } - Frame { - msec: 1984 - hash: "155329bf1c1a6f6c37bf7e6e8a92c59b" - } - Frame { - msec: 2000 - hash: "d3008d1e7cee5170171699ef6fb9aa81" - } - Frame { - msec: 2016 - hash: "5c1244e7806e131a6063f22a66e4eb12" - } - Frame { - msec: 2032 - hash: "fcd6b372229a6cf14face81e9d614456" - } - Frame { - msec: 2048 - hash: "bf1a375a81bf43c5671cccc62e9a0462" - } - Frame { - msec: 2064 - hash: "0e22404508470baaa6621f37361951fa" - } - Frame { - msec: 2080 - hash: "45046f28c103caa161e41861f71731c4" - } - Frame { - msec: 2096 - hash: "7a92731c713470a2b2c91fd6b83447de" - } - Frame { - msec: 2112 - hash: "7a92731c713470a2b2c91fd6b83447de" - } - Frame { - msec: 2128 - hash: "7a92731c713470a2b2c91fd6b83447de" - } - Frame { - msec: 2144 - hash: "7a92731c713470a2b2c91fd6b83447de" - } - Frame { - msec: 2160 - hash: "7a92731c713470a2b2c91fd6b83447de" - } - Frame { - msec: 2176 - hash: "7a92731c713470a2b2c91fd6b83447de" - } - Frame { - msec: 2192 - hash: "7a92731c713470a2b2c91fd6b83447de" - } - Frame { - msec: 2208 - hash: "7a92731c713470a2b2c91fd6b83447de" - } - Frame { - msec: 2224 - hash: "7a92731c713470a2b2c91fd6b83447de" - } - Frame { - msec: 2240 - hash: "7a92731c713470a2b2c91fd6b83447de" - } - Frame { - msec: 2256 - hash: "7a92731c713470a2b2c91fd6b83447de" - } - Frame { - msec: 2272 - hash: "7a92731c713470a2b2c91fd6b83447de" - } - Frame { - msec: 2288 - hash: "7a92731c713470a2b2c91fd6b83447de" - } - Frame { - msec: 2304 - hash: "7a92731c713470a2b2c91fd6b83447de" - } - Frame { - msec: 2320 - hash: "7a92731c713470a2b2c91fd6b83447de" - } - Frame { - msec: 2336 - hash: "7a92731c713470a2b2c91fd6b83447de" - } - Frame { - msec: 2352 - hash: "7a92731c713470a2b2c91fd6b83447de" - } - Frame { - msec: 2368 - hash: "7a92731c713470a2b2c91fd6b83447de" - } - Frame { - msec: 2384 - hash: "7a92731c713470a2b2c91fd6b83447de" - } - Frame { - msec: 2400 - hash: "7a92731c713470a2b2c91fd6b83447de" - } - Frame { - msec: 2416 - hash: "7a92731c713470a2b2c91fd6b83447de" - } - Frame { - msec: 2432 - hash: "7a92731c713470a2b2c91fd6b83447de" - } - Frame { - msec: 2448 - hash: "7a92731c713470a2b2c91fd6b83447de" - } - Frame { - msec: 2464 - hash: "7a92731c713470a2b2c91fd6b83447de" - } - Frame { - msec: 2480 - hash: "7a92731c713470a2b2c91fd6b83447de" - } - Frame { - msec: 2496 - hash: "7a92731c713470a2b2c91fd6b83447de" - } - Frame { - msec: 2512 - hash: "7a92731c713470a2b2c91fd6b83447de" - } - Frame { - msec: 2528 - hash: "7a92731c713470a2b2c91fd6b83447de" - } - Frame { - msec: 2544 - hash: "7a92731c713470a2b2c91fd6b83447de" - } - Frame { - msec: 2560 - hash: "7a92731c713470a2b2c91fd6b83447de" - } - Frame { - msec: 2576 - hash: "7a92731c713470a2b2c91fd6b83447de" - } - Frame { - msec: 2592 - hash: "7a92731c713470a2b2c91fd6b83447de" - } - Frame { - msec: 2608 - hash: "7a92731c713470a2b2c91fd6b83447de" - } - Frame { - msec: 2624 - hash: "7a92731c713470a2b2c91fd6b83447de" - } - Frame { - msec: 2640 - hash: "7a92731c713470a2b2c91fd6b83447de" - } - Frame { - msec: 2656 - hash: "7a92731c713470a2b2c91fd6b83447de" - } - Frame { - msec: 2672 - hash: "7a92731c713470a2b2c91fd6b83447de" - } - Frame { - msec: 2688 - hash: "7a92731c713470a2b2c91fd6b83447de" - } - Frame { - msec: 2704 - hash: "7a92731c713470a2b2c91fd6b83447de" - } - Frame { - msec: 2720 - hash: "7a92731c713470a2b2c91fd6b83447de" - } - Frame { - msec: 2736 - hash: "7a92731c713470a2b2c91fd6b83447de" - } - Frame { - msec: 2752 - hash: "7a92731c713470a2b2c91fd6b83447de" - } - Mouse { - type: 3 - button: 1 - buttons: 0 - x: 150; y: 274 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 2768 - hash: "7a92731c713470a2b2c91fd6b83447de" - } - Frame { - msec: 2784 - hash: "44a0b46c21bd4c76d44883ba146e3614" - } - Frame { - msec: 2800 - hash: "2224abc3333a2bc5fa1cf3c4e8d6a6f9" - } - Frame { - msec: 2816 - hash: "ea9c05c0295a300e21aacbdfd5b4968e" - } - Frame { - msec: 2832 - hash: "e630e2893f89a6ae536bcbd1a084af07" - } - Frame { - msec: 2848 - hash: "af56f1e79eb3746efb9e4bcbc3fbced8" - } - Frame { - msec: 2864 - hash: "96be8c3ba0d7a85c6f6df877b869b563" - } - Frame { - msec: 2880 - image: "parentAction.2.png" - } - Frame { - msec: 2896 - hash: "603d8684cb6f097e3ab2a2e5ef053112" - } - Frame { - msec: 2912 - hash: "0433d242d1dd40a3792f55f807ebbff4" - } - Frame { - msec: 2928 - hash: "1190067cacc7361f6cfe09f153c7a07e" - } - Frame { - msec: 2944 - hash: "98e917880471511122847ad8a406e3a3" - } - Frame { - msec: 2960 - hash: "fff06869074a3a6c5823ed3fb6fa7a43" - } - Frame { - msec: 2976 - hash: "602d95daee8f160a0fd784931d0a06bd" - } - Frame { - msec: 2992 - hash: "f7e466bbd52f40e88ff567758f4db835" - } - Frame { - msec: 3008 - hash: "54417a4c4fb71d458439ad2e2126f8e1" - } - Frame { - msec: 3024 - hash: "fe150dd5056b9dbf1cd0b196e9a7a47b" - } - Frame { - msec: 3040 - hash: "1384c871bead85916f7bfcdebc370697" - } - Frame { - msec: 3056 - hash: "5f13339cc0e604b75a9d1d85342fa717" - } - Frame { - msec: 3072 - hash: "655069d61b7a44e729a2cbb33d683c3e" - } - Frame { - msec: 3088 - hash: "2324e9e4a02e41855b066983dbf0e61d" - } - Frame { - msec: 3104 - hash: "0217baf091325b95c033ba073bd68ce5" - } - Frame { - msec: 3120 - hash: "c27854c3af5b58db85846a1762ab18ba" - } - Frame { - msec: 3136 - hash: "45246ee6383ceb6260f84571a885ba90" - } - Frame { - msec: 3152 - hash: "d82ded86f093d1a376994cacf43d0343" - } - Frame { - msec: 3168 - hash: "c9179d30f80c6101bca2bed40d6a859f" - } - Frame { - msec: 3184 - hash: "a63e032d20a9d985c6c345434d98a364" - } - Frame { - msec: 3200 - hash: "fc7d6797ce15edf7fadb9dae691ecd5c" - } - Frame { - msec: 3216 - hash: "76cf37ad8c50fed8b1900784b647819c" - } - Frame { - msec: 3232 - hash: "256aab3690c9ba928bb4d4dd3bbfc756" - } - Frame { - msec: 3248 - hash: "90cab52fdefbae4e7d0f0f93b46ebeb0" - } - Frame { - msec: 3264 - hash: "badb5103bf826dc467f6e620cc2b47be" - } - Frame { - msec: 3280 - hash: "e7d0e437de5ebc0fa07b2a4ef11159cb" - } - Frame { - msec: 3296 - hash: "5931b1c3932ab91446324165d7e2603a" - } - Frame { - msec: 3312 - hash: "ce1808db90ba955ab3cb845500f4c013" - } - Frame { - msec: 3328 - hash: "142f8a440d1fe2d868f47ba3006de9d7" - } - Frame { - msec: 3344 - hash: "10d32a6cc90319ea66d7f2c1241590ce" - } - Frame { - msec: 3360 - hash: "7f633559d715396e6de451b3dd2fadbd" - } - Frame { - msec: 3376 - hash: "d44590ae51ceef5e082747c44bc41be9" - } - Frame { - msec: 3392 - hash: "2b498181668fb1fbf65294d575654929" - } - Frame { - msec: 3408 - hash: "7efeeffd08e4de440da83511313de729" - } - Frame { - msec: 3424 - hash: "8de2331393d1e712192d11ed096836d3" - } - Frame { - msec: 3440 - hash: "fa9381ef2e295865a9b8cb9b36a0eacf" - } - Frame { - msec: 3456 - hash: "97debc4432c5ecb7f606a81e5411b02c" - } - Frame { - msec: 3472 - hash: "eb4c1bb1f4398e3c18182c28a015be76" - } - Frame { - msec: 3488 - hash: "a976aa509f4c6f309d9a6011eeae02aa" - } - Frame { - msec: 3504 - hash: "457de7ee05e0ef0ef120a3d4e371c02e" - } - Frame { - msec: 3520 - hash: "0c01f9f150fe33155fa20703735a6d27" - } - Frame { - msec: 3536 - hash: "5af4f80624082a264010247ea8630a1a" - } - Frame { - msec: 3552 - hash: "b23a1191d149549fa29a61b6dc70f037" - } - Frame { - msec: 3568 - hash: "e00fb32cb13b1347e4b7b9fdbcca68e5" - } - Frame { - msec: 3584 - hash: "fef0503c82f253f8bc3fb3e705a98aa7" - } - Frame { - msec: 3600 - hash: "7a9beca28340d2aa89da5e05f5ac2a55" - } - Frame { - msec: 3616 - hash: "f3c57ea07ab486ffa1f46da60de0b8f1" - } - Frame { - msec: 3632 - hash: "ef0a4ad9ac339fd6ea50dbe6baa9387f" - } - Frame { - msec: 3648 - hash: "1b317a9eb4ce022f005d551546c688a4" - } - Frame { - msec: 3664 - hash: "628e912a4a26800b9b7b5e60e60e3a7d" - } - Frame { - msec: 3680 - hash: "3587b75e4d834a88729754d2c2a4b193" - } - Frame { - msec: 3696 - hash: "084bc1360a38123589baec5aae15b4ff" - } - Frame { - msec: 3712 - hash: "47f0f6c3cdf456826a6fd6846e58dcc8" - } - Frame { - msec: 3728 - hash: "ed982c4c3ebd132baaaf43efad40a3f7" - } - Frame { - msec: 3744 - hash: "d7ddce47c23fada4c69d53d934582d71" - } - Frame { - msec: 3760 - hash: "74f2f911bee26c4c551f4c70596753ae" - } - Frame { - msec: 3776 - hash: "3ed7cbf10dfce3a485d7878766cf9da6" - } - Frame { - msec: 3792 - hash: "87a74257551ab6c7fcfe05e815482ae9" - } - Frame { - msec: 3808 - hash: "4f63e4904e97d4ce832b20b7317a9958" - } - Frame { - msec: 3824 - hash: "f912da8781e547c6e28890655c1b8884" - } - Frame { - msec: 3840 - image: "parentAction.3.png" - } - Frame { - msec: 3856 - hash: "faa640ccf993324400254ffb862ac279" - } - Frame { - msec: 3872 - hash: "b67f342424d1b9a364b09da8994fcd6b" - } - Frame { - msec: 3888 - hash: "b2407732194c1e0c2a9bfb379b94b562" - } - Frame { - msec: 3904 - hash: "55733608d0302ef90c124322ac6d8dc6" - } - Frame { - msec: 3920 - hash: "734f5b628a26d3d7c91ee84fb26d5b5f" - } - Frame { - msec: 3936 - hash: "27839fefa4a218cd77843358392bb874" - } - Frame { - msec: 3952 - hash: "8cac19559d37bd2b581cef0a4c707753" - } - Frame { - msec: 3968 - hash: "91422870aa1471571e7dd8ff5103f76c" - } - Frame { - msec: 3984 - hash: "7156166d5f8d13483467ef515627c95d" - } - Frame { - msec: 4000 - hash: "6028e8374c2ce42a9a9e85b4a8b53027" - } - Frame { - msec: 4016 - hash: "17c99592be58d2e03f9f173c47c0649b" - } - Frame { - msec: 4032 - hash: "6084b53186c6a7eda38ac7fa34bf45ce" - } - Frame { - msec: 4048 - hash: "e82131a8a5a06519f49308bbc25738cf" - } - Frame { - msec: 4064 - hash: "77bdb69cbe55d9c503c6aa1c0f974d87" - } - Frame { - msec: 4080 - hash: "b2346ec5d376651347281d5fb00fc4d7" - } - Frame { - msec: 4096 - hash: "36a3b72c9d7f09795c546855a269801d" - } - Frame { - msec: 4112 - hash: "4e5478b33baca797f3f8f72c2c6c51ad" - } - Frame { - msec: 4128 - hash: "e59d12be3ed1f58de010d385ddfe78e5" - } - Frame { - msec: 4144 - hash: "9674106a146effd47c2724a2dd82ae84" - } - Frame { - msec: 4160 - hash: "862cec781f169f713032e6d52d3616ce" - } - Frame { - msec: 4176 - hash: "c8d47bdfb6518ef4827677023313d559" - } - Frame { - msec: 4192 - hash: "19413931b3e788067dfaef39b47d30ff" - } - Frame { - msec: 4208 - hash: "600e426532c0348cd622257b0773efd5" - } - Frame { - msec: 4224 - hash: "6d975e259d4efa108375d271451531c1" - } - Frame { - msec: 4240 - hash: "50b0da4848564c063694202ce16ea808" - } - Frame { - msec: 4256 - hash: "0a9450739031f680735b5210e6a30c3f" - } - Frame { - msec: 4272 - hash: "23ce049cd7e715c28f5845fd1a1fc195" - } - Frame { - msec: 4288 - hash: "23ce049cd7e715c28f5845fd1a1fc195" - } - Frame { - msec: 4304 - hash: "23ce049cd7e715c28f5845fd1a1fc195" - } - Frame { - msec: 4320 - hash: "23ce049cd7e715c28f5845fd1a1fc195" - } - Frame { - msec: 4336 - hash: "23ce049cd7e715c28f5845fd1a1fc195" - } - Frame { - msec: 4352 - hash: "23ce049cd7e715c28f5845fd1a1fc195" - } - Frame { - msec: 4368 - hash: "23ce049cd7e715c28f5845fd1a1fc195" - } - Frame { - msec: 4384 - hash: "23ce049cd7e715c28f5845fd1a1fc195" - } - Frame { - msec: 4400 - hash: "23ce049cd7e715c28f5845fd1a1fc195" - } - Frame { - msec: 4416 - hash: "23ce049cd7e715c28f5845fd1a1fc195" - } - Frame { - msec: 4432 - hash: "23ce049cd7e715c28f5845fd1a1fc195" - } - Frame { - msec: 4448 - hash: "23ce049cd7e715c28f5845fd1a1fc195" - } - Frame { - msec: 4464 - hash: "23ce049cd7e715c28f5845fd1a1fc195" - } - Frame { - msec: 4480 - hash: "23ce049cd7e715c28f5845fd1a1fc195" - } - Frame { - msec: 4496 - hash: "23ce049cd7e715c28f5845fd1a1fc195" - } - Frame { - msec: 4512 - hash: "23ce049cd7e715c28f5845fd1a1fc195" - } - Frame { - msec: 4528 - hash: "23ce049cd7e715c28f5845fd1a1fc195" - } - Frame { - msec: 4544 - hash: "23ce049cd7e715c28f5845fd1a1fc195" - } - Key { - type: 6 - key: 16777249 - modifiers: 67108864 - text: "" - autorep: false - count: 1 - } - Frame { - msec: 4560 - hash: "23ce049cd7e715c28f5845fd1a1fc195" - } - Frame { - msec: 4576 - hash: "23ce049cd7e715c28f5845fd1a1fc195" - } - Frame { - msec: 4592 - hash: "23ce049cd7e715c28f5845fd1a1fc195" - } - Frame { - msec: 4608 - hash: "23ce049cd7e715c28f5845fd1a1fc195" - } - Frame { - msec: 4624 - hash: "23ce049cd7e715c28f5845fd1a1fc195" - } - Frame { - msec: 4640 - hash: "23ce049cd7e715c28f5845fd1a1fc195" - } - Frame { - msec: 4656 - hash: "23ce049cd7e715c28f5845fd1a1fc195" - } - Frame { - msec: 4672 - hash: "23ce049cd7e715c28f5845fd1a1fc195" - } - Frame { - msec: 4688 - hash: "23ce049cd7e715c28f5845fd1a1fc195" - } - Frame { - msec: 4704 - hash: "23ce049cd7e715c28f5845fd1a1fc195" - } -} diff --git a/tests/auto/declarative/visual/animation/parentAction/parentAction.qml b/tests/auto/declarative/visual/animation/parentAction/parentAction.qml deleted file mode 100644 index eb3103e..0000000 --- a/tests/auto/declarative/visual/animation/parentAction/parentAction.qml +++ /dev/null @@ -1,55 +0,0 @@ -import Qt 4.6 - -Rectangle { - width: 400; height: 400 - Item { - scale: .5 - rotation: 15 - transformOrigin: "Center" - x: 10; y: 10 - Rectangle { - id: myRect - x: 5 - width: 100; height: 100 - transformOrigin: "BottomLeft" - color: "red" - } - } - MouseArea { - id: clickable - anchors.fill: parent - } - - Item { - x: 200; y: 200 - rotation: 52; - scale: 2 - Item { - id: newParent - x: 100; y: 100 - } - } - - states: State { - name: "moved" - when: clickable.pressed - ParentChange { - target: myRect - parent: newParent - } - PropertyChanges { - target: myRect - rotation: -52 - scale: 1 - color: "blue" - } - } - - transitions: Transition { - SequentialAnimation { - ColorAnimation { duration: 500} - ParentAction {} - NumberAnimation { properties: "rotation, scale"; duration: 1000 } - } - } -} diff --git a/tests/auto/moc/tst_moc.cpp b/tests/auto/moc/tst_moc.cpp index fad4845..30c2721 100644 --- a/tests/auto/moc/tst_moc.cpp +++ b/tests/auto/moc/tst_moc.cpp @@ -484,6 +484,7 @@ private slots: void singleFunctionKeywordSignalAndSlot(); void templateGtGt(); void qprivateslots(); + void qprivateproperties(); void inlineSlotsWithThrowDeclaration(); void warnOnPropertyWithoutREAD(); void constructors(); @@ -1071,6 +1072,56 @@ void tst_Moc::qprivateslots() QVERIFY(mobj->indexOfMethod("method1()") != -1); //tast204730 } +class PrivatePropertyTest : public QObject +{ + Q_OBJECT + Q_PROPERTY(int foo READ foo WRITE setFoo); + Q_PRIVATE_PROPERTY(d, int bar READ bar WRITE setBar); + Q_PRIVATE_PROPERTY(PrivatePropertyTest::d, int plop READ plop WRITE setPlop); + Q_PRIVATE_PROPERTY(PrivatePropertyTest::d_func(), int baz READ baz WRITE setBaz); + class MyDPointer { + public: + MyDPointer() : mBar(0), mPlop(0) {} + int bar() { return mBar ; } + void setBar(int value) { mBar = value; } + int plop() { return mPlop ; } + void setPlop(int value) { mPlop = value; } + int baz() { return mBaz ; } + void setBaz(int value) { mBaz = value; } + private: + int mBar; + int mPlop; + int mBaz; + }; +public: + PrivatePropertyTest() : mFoo(0), d (new MyDPointer) {} + int foo() { return mFoo ; } + void setFoo(int value) { mFoo = value; } + MyDPointer *d_func() {return d;} +private: + int mFoo; + MyDPointer *d; +}; + + +void tst_Moc::qprivateproperties() +{ + PrivatePropertyTest test; + + test.setProperty("foo", 1); + QCOMPARE(test.property("foo"), qVariantFromValue(1)); + + test.setProperty("bar", 2); + QCOMPARE(test.property("bar"), qVariantFromValue(2)); + + test.setProperty("plop", 3); + QCOMPARE(test.property("plop"), qVariantFromValue(3)); + + test.setProperty("baz", 4); + QCOMPARE(test.property("baz"), qVariantFromValue(4)); + +} + #include "task189996.h" void InlineSlotsWithThrowDeclaration::c() throw() {} diff --git a/tests/auto/qaccessibility/tst_qaccessibility.cpp b/tests/auto/qaccessibility/tst_qaccessibility.cpp index 133cb33..e5a332a 100644 --- a/tests/auto/qaccessibility/tst_qaccessibility.cpp +++ b/tests/auto/qaccessibility/tst_qaccessibility.cpp @@ -3923,9 +3923,8 @@ void tst_QAccessibility::comboBoxTest() acc = QAccessible::queryAccessibleInterface(cb); - QRect accRect = acc->rect(0); for (int i = 1; i < acc->childCount(); ++i) { - QVERIFY(accRect.contains(acc->rect(i))); + QTRY_VERIFY(acc->rect(0).contains(acc->rect(i))); } QCOMPARE(acc->doAction(QAccessible::Press, 2), true); QTest::qWait(400); diff --git a/tests/auto/qgraphicsscene/tst_qgraphicsscene.cpp b/tests/auto/qgraphicsscene/tst_qgraphicsscene.cpp index d37ff76..a155222 100644 --- a/tests/auto/qgraphicsscene/tst_qgraphicsscene.cpp +++ b/tests/auto/qgraphicsscene/tst_qgraphicsscene.cpp @@ -284,6 +284,7 @@ private slots: void task250680_childClip(); void taskQTBUG_5904_crashWithDeviceCoordinateCache(); void taskQT657_paintIntoCacheWithTransparentParts(); + void taskQTBUG_7863_paintIntoCacheWithTransparentParts(); }; void tst_QGraphicsScene::initTestCase() @@ -4349,12 +4350,14 @@ void tst_QGraphicsScene::taskQTBUG_5904_crashWithDeviceCoordinateCache() void tst_QGraphicsScene::taskQT657_paintIntoCacheWithTransparentParts() { + // Test using DeviceCoordinateCache and opaque item QWidget *w = new QWidget(); - w->setPalette(Qt::blue); + w->setPalette(QColor(0, 0, 255)); w->setGeometry(0, 0, 50, 50); QGraphicsScene *scene = new QGraphicsScene(); - QGraphicsView *view = new QGraphicsView(scene); + CustomView *view = new CustomView; + view->setScene(scene); QGraphicsProxyWidget *proxy = scene->addWidget(w); proxy->setCacheMode(QGraphicsItem::DeviceCoordinateCache); @@ -4362,13 +4365,14 @@ void tst_QGraphicsScene::taskQT657_paintIntoCacheWithTransparentParts() view->show(); QTest::qWaitForWindowShown(view); - w->update(10,10,10,10); + view->repaints = 0; + proxy->update(10, 10, 10, 10); QTest::qWait(50); + QTRY_VERIFY(view->repaints > 0); QPixmap pix; QGraphicsItemPrivate* itemp = QGraphicsItemPrivate::get(proxy); - QPixmapCache::Key key = itemp->extraItemCache()->deviceData.value(view->viewport()).key; - QVERIFY(QPixmapCache::find(key, &pix)); + QTRY_VERIFY(QPixmapCache::find(itemp->extraItemCache()->deviceData.value(view->viewport()).key, &pix)); QTransform t = proxy->sceneTransform(); // Map from scene coordinates to pixmap coordinates. @@ -4383,6 +4387,138 @@ void tst_QGraphicsScene::taskQT657_paintIntoCacheWithTransparentParts() for(int j = 0; j < im.height(); j++) QCOMPARE(qAlpha(im.pixel(i, j)), 255); } + + delete w; +} + +void tst_QGraphicsScene::taskQTBUG_7863_paintIntoCacheWithTransparentParts() +{ + // Test using DeviceCoordinateCache and semi-transparent item + { + QGraphicsRectItem *backItem = new QGraphicsRectItem(0, 0, 100, 100); + backItem->setBrush(QColor(255, 255, 0)); + QGraphicsRectItem *rectItem = new QGraphicsRectItem(0, 0, 50, 50); + rectItem->setBrush(QColor(0, 0, 255, 125)); + rectItem->setParentItem(backItem); + + QGraphicsScene *scene = new QGraphicsScene(); + CustomView *view = new CustomView; + view->setScene(scene); + + scene->addItem(backItem); + rectItem->setCacheMode(QGraphicsItem::DeviceCoordinateCache); + backItem->rotate(15); + + view->show(); + QTest::qWaitForWindowShown(view); + view->repaints = 0; + rectItem->update(10, 10, 10, 10); + QTest::qWait(50); + QTRY_VERIFY(view->repaints > 0); + + QPixmap pix; + QGraphicsItemPrivate* itemp = QGraphicsItemPrivate::get(rectItem); + QTRY_VERIFY(QPixmapCache::find(itemp->extraItemCache()->deviceData.value(view->viewport()).key, &pix)); + + QTransform t = rectItem->sceneTransform(); + // Map from scene coordinates to pixmap coordinates. + // X origin in the pixmap is the most-left point + // of the item's boundingRect in the scene. + qreal adjust = t.mapRect(rectItem->boundingRect().toRect()).left(); + QRect rect = t.mapRect(QRect(10, 10, 10, 10)).adjusted(-adjust, 0, -adjust + 1, 1); + QPixmap subpix = pix.copy(rect); + + QImage im = subpix.toImage(); + for(int i = 0; i < im.width(); i++) { + for(int j = 0; j < im.height(); j++) { + QCOMPARE(qAlpha(im.pixel(i, j)), 125); + } + } + + delete view; + } + + // Test using ItemCoordinateCache and opaque item + { + QGraphicsRectItem *rectItem = new QGraphicsRectItem(0, 0, 50, 50); + rectItem->setBrush(QColor(0, 0, 255)); + + QGraphicsScene *scene = new QGraphicsScene(); + CustomView *view = new CustomView; + view->setScene(scene); + + scene->addItem(rectItem); + rectItem->setCacheMode(QGraphicsItem::ItemCoordinateCache); + rectItem->rotate(15); + + view->show(); + QTest::qWaitForWindowShown(view); + view->repaints = 0; + rectItem->update(10, 10, 10, 10); + QTest::qWait(50); + QTRY_VERIFY(view->repaints > 0); + + QPixmap pix; + QGraphicsItemPrivate* itemp = QGraphicsItemPrivate::get(rectItem); + QTRY_VERIFY(QPixmapCache::find(itemp->extraItemCache()->key, &pix)); + + QTransform t = rectItem->sceneTransform(); + // Map from scene coordinates to pixmap coordinates. + // X origin in the pixmap is the most-left point + // of the item's boundingRect in the scene. + qreal adjust = t.mapRect(rectItem->boundingRect().toRect()).left(); + QRect rect = t.mapRect(QRect(10, 10, 10, 10)).adjusted(-adjust, 0, -adjust + 1, 1); + QPixmap subpix = pix.copy(rect); + + QImage im = subpix.toImage(); + for(int i = 0; i < im.width(); i++) { + for(int j = 0; j < im.height(); j++) + QCOMPARE(qAlpha(im.pixel(i, j)), 255); + } + + delete view; + } + + // Test using ItemCoordinateCache and semi-transparent item + { + QGraphicsRectItem *rectItem = new QGraphicsRectItem(0, 0, 50, 50); + rectItem->setBrush(QColor(0, 0, 255, 125)); + + QGraphicsScene *scene = new QGraphicsScene(); + CustomView *view = new CustomView; + view->setScene(scene); + + scene->addItem(rectItem); + rectItem->setCacheMode(QGraphicsItem::ItemCoordinateCache); + rectItem->rotate(15); + + view->show(); + QTest::qWaitForWindowShown(view); + view->repaints = 0; + rectItem->update(10, 10, 10, 10); + QTest::qWait(50); + QTRY_VERIFY(view->repaints > 0); + + QPixmap pix; + QGraphicsItemPrivate* itemp = QGraphicsItemPrivate::get(rectItem); + QTRY_VERIFY(QPixmapCache::find(itemp->extraItemCache()->key, &pix)); + + QTransform t = rectItem->sceneTransform(); + // Map from scene coordinates to pixmap coordinates. + // X origin in the pixmap is the most-left point + // of the item's boundingRect in the scene. + qreal adjust = t.mapRect(rectItem->boundingRect().toRect()).left(); + QRect rect = t.mapRect(QRect(10, 10, 10, 10)).adjusted(-adjust, 0, -adjust + 1, 1); + QPixmap subpix = pix.copy(rect); + + QImage im = subpix.toImage(); + for(int i = 0; i < im.width(); i++) { + for(int j = 0; j < im.height(); j++) + QCOMPARE(qAlpha(im.pixel(i, j)), 125); + } + + delete view; + } } QTEST_MAIN(tst_QGraphicsScene) diff --git a/tests/auto/qgraphicswidget/tst_qgraphicswidget.cpp b/tests/auto/qgraphicswidget/tst_qgraphicswidget.cpp index 6941d23..587b7d5 100644 --- a/tests/auto/qgraphicswidget/tst_qgraphicswidget.cpp +++ b/tests/auto/qgraphicswidget/tst_qgraphicswidget.cpp @@ -462,7 +462,7 @@ void tst_QGraphicsWidget::focusWidget() QFETCH(int, childWithFocus); SubQGraphicsWidget *widget = children[childWithFocus]; widget->setFocus(); - QVERIFY(widget->hasFocus()); + QTRY_VERIFY(widget->hasFocus()); QCOMPARE(parent->focusWidget(), static_cast<QGraphicsWidget*>(widget)); } } @@ -479,23 +479,23 @@ void tst_QGraphicsWidget::focusWidget2() scene.addItem(widget); - QVERIFY(!widget->hasFocus()); + QTRY_VERIFY(!widget->hasFocus()); widget->setFocusPolicy(Qt::StrongFocus); - QVERIFY(!widget->hasFocus()); + QTRY_VERIFY(!widget->hasFocus()); QGraphicsWidget *subWidget = new QGraphicsWidget(widget); - QVERIFY(!subWidget->hasFocus()); + QTRY_VERIFY(!subWidget->hasFocus()); scene.setFocus(); - QVERIFY(!widget->hasFocus()); - QVERIFY(!subWidget->hasFocus()); + QTRY_VERIFY(!widget->hasFocus()); + QTRY_VERIFY(!subWidget->hasFocus()); widget->setFocus(); - QVERIFY(widget->hasFocus()); - QCOMPARE(focusInSpy.count(), 1); - QVERIFY(!subWidget->hasFocus()); + QTRY_VERIFY(widget->hasFocus()); + QTRY_COMPARE(focusInSpy.count(), 1); + QTRY_VERIFY(!subWidget->hasFocus()); QGraphicsWidget *otherSubWidget = new QGraphicsWidget; EventSpy otherFocusInSpy(otherSubWidget, QEvent::FocusIn); @@ -504,18 +504,18 @@ void tst_QGraphicsWidget::focusWidget2() otherSubWidget->setFocusPolicy(Qt::StrongFocus); otherSubWidget->setParentItem(widget); - QVERIFY(widget->hasFocus()); + QTRY_VERIFY(widget->hasFocus()); QCOMPARE(scene.focusItem(), (QGraphicsItem *)widget); - QVERIFY(!subWidget->hasFocus()); - QVERIFY(!otherSubWidget->hasFocus()); + QTRY_VERIFY(!subWidget->hasFocus()); + QTRY_VERIFY(!otherSubWidget->hasFocus()); widget->hide(); - QVERIFY(!widget->hasFocus()); // lose but still has subfocus + QTRY_VERIFY(!widget->hasFocus()); // lose but still has subfocus QCOMPARE(focusInSpy.count(), 1); QCOMPARE(focusOutSpy.count(), 1); widget->show(); - QVERIFY(!widget->hasFocus()); // no regain + QTRY_VERIFY(!widget->hasFocus()); // no regain QCOMPARE(focusInSpy.count(), 1); QCOMPARE(focusOutSpy.count(), 1); @@ -523,24 +523,24 @@ void tst_QGraphicsWidget::focusWidget2() // try to setup subFocus on item that can't take focus subWidget->setFocus(); - QVERIFY(!subWidget->hasFocus()); + QTRY_VERIFY(!subWidget->hasFocus()); QVERIFY(!scene.focusItem()); // but isn't the scene's focus item // try to setup subFocus on item that can take focus otherSubWidget->setFocus(); - QVERIFY(!otherSubWidget->hasFocus()); + QTRY_VERIFY(!otherSubWidget->hasFocus()); QCOMPARE(widget->focusWidget(), otherSubWidget); QVERIFY(!scene.focusItem()); // but isn't the scene's focus item widget->show(); - QCOMPARE(scene.focusItem(), (QGraphicsItem *)otherSubWidget); // but isn't the scene's focus item + QTRY_COMPARE(scene.focusItem(), (QGraphicsItem *)otherSubWidget); // but isn't the scene's focus item QCOMPARE(otherFocusInSpy.count(), 1); QCOMPARE(otherFocusOutSpy.count(), 0); delete otherSubWidget; - QCOMPARE(otherFocusOutSpy.count(), 1); + QTRY_COMPARE(otherFocusOutSpy.count(), 1); QVERIFY(!scene.focusItem()); QVERIFY(!widget->focusWidget()); } @@ -579,16 +579,16 @@ void tst_QGraphicsWidget::focusPolicy() SubQGraphicsWidget *widget = new SubQGraphicsWidget; scene.addItem(widget); - QCOMPARE(Qt::NoFocus, widget->focusPolicy()); + QTRY_COMPARE(Qt::NoFocus, widget->focusPolicy()); QFETCH(Qt::FocusPolicy, focusPolicy1); widget->setFocusPolicy(focusPolicy1); - QCOMPARE(widget->focusPolicy(), focusPolicy1); + QTRY_COMPARE(widget->focusPolicy(), focusPolicy1); bool isFocusable = widget->flags() & QGraphicsItem::ItemIsFocusable; bool wasFocusable = isFocusable; - QVERIFY(isFocusable == (focusPolicy1 != Qt::NoFocus)); + QTRY_VERIFY(isFocusable == (focusPolicy1 != Qt::NoFocus)); widget->setFocus(); - QCOMPARE(widget->hasFocus(), isFocusable); + QTRY_COMPARE(widget->hasFocus(), isFocusable); QFETCH(Qt::FocusPolicy, focusPolicy2); widget->setFocusPolicy(focusPolicy2); @@ -691,25 +691,21 @@ void tst_QGraphicsWidget::fontChangedEvent() EventSpy rootSpyFont(root, QEvent::FontChange); EventSpy rootSpyPolish(root, QEvent::Polish); - QCOMPARE(rootSpyFont.count(), 0); - QApplication::processEvents(); //The polish event is sent - QCOMPARE(rootSpyPolish.count(), 1); - QApplication::processEvents(); //Process events to see if we get the font change event + QTRY_COMPARE(rootSpyFont.count(), 0); + QTRY_COMPARE(rootSpyPolish.count(), 1); //The font is still the same so no fontChangeEvent - QCOMPARE(rootSpyFont.count(), 0); + QTRY_COMPARE(rootSpyFont.count(), 0); QFont font; font.setPointSize(43); root->setFont(font); - QApplication::processEvents(); //Process events to get the font change event //The font changed - QCOMPARE(rootSpyFont.count(), 1); + QTRY_COMPARE(rootSpyFont.count(), 1); //then roll back to the default one. root->setFont(appFont); - QApplication::processEvents(); //Process events to get the font change event //The font changed - QCOMPARE(rootSpyFont.count(), 2); + QTRY_COMPARE(rootSpyFont.count(), 2); } void tst_QGraphicsWidget::fontPropagationWidgetItemWidget() @@ -770,11 +766,13 @@ void tst_QGraphicsWidget::geometry() { SubQGraphicsWidget widget; QCOMPARE(widget.geometry(), QRectF(widget.pos(), widget.size())); - + QSignalSpy spy(&widget, SIGNAL(geometryChanged())); QFETCH(QPointF, pos); QFETCH(QSizeF, size); widget.setPos(pos); widget.resize(size); + if (!size.isNull()) + QCOMPARE(spy.count(), 1); QCOMPARE(widget.geometry(), QRectF(pos, size)); } @@ -843,7 +841,6 @@ void tst_QGraphicsWidget::initStyleOption() qt_x11_wait_for_window_manager(&view); #endif QApplication::setActiveWindow(&view); - QTest::qWait(25); QTRY_COMPARE(QApplication::activeWindow(), &view); view.setAlignment(Qt::AlignTop | Qt::AlignLeft); @@ -868,7 +865,6 @@ void tst_QGraphicsWidget::initStyleOption() view.resize(300, 300); view.show(); QTest::qWaitForWindowShown(&view); - QTest::qWait(20); sendMouseMove(view.viewport(), view.mapFromScene(widget->mapToScene(widget->boundingRect().center()))); } @@ -921,9 +917,7 @@ void tst_QGraphicsWidget::layout() } widget.setLayout(layout); - QTest::qWait(25); - - QCOMPARE(widget.layout(), static_cast<QGraphicsLayout*>(layout)); + QTRY_COMPARE(widget.layout(), static_cast<QGraphicsLayout*>(layout)); for (int i = 0; i < children.count(); ++i) { SubQGraphicsWidget *item = children[i]; QCOMPARE(item->parentWidget(), (QGraphicsWidget *)&widget); @@ -963,10 +957,9 @@ void tst_QGraphicsWidget::layoutDirection() view->show(); QTest::qWaitForWindowShown(view); for (int i = 0; i < children.count(); ++i) { - QCOMPARE(children[i]->layoutDirection(), layoutDirection); - QCOMPARE(children[i]->testAttribute(Qt::WA_SetLayoutDirection), false); + QTRY_COMPARE(children[i]->layoutDirection(), layoutDirection); + QTRY_COMPARE(children[i]->testAttribute(Qt::WA_SetLayoutDirection), false); view->repaint(); - QApplication::processEvents(); QTRY_COMPARE(children[i]->m_painterLayoutDirection, layoutDirection); } delete view; @@ -1179,7 +1172,6 @@ void tst_QGraphicsWidget::setTabOrder() qt_x11_wait_for_window_manager(&view); #endif QApplication::setActiveWindow(&view); - QTest::qWait(25); QTRY_COMPARE(QApplication::activeWindow(), &view); QGraphicsWidget *lastItem = 0; @@ -1200,7 +1192,6 @@ void tst_QGraphicsWidget::setTabOrder() if (!children.isEmpty()) { QGraphicsWidget *first = children.first(); view.viewport()->setFocus(); - QApplication::processEvents(); QTRY_VERIFY(view.viewport()->hasFocus()); first->setFocus(); QVERIFY(first->hasFocus()); @@ -1461,18 +1452,14 @@ void tst_QGraphicsWidget::verifyFocusChain() QTest::qWaitForWindowShown(window); lineEdit->setFocus(); - QTest::qWait(25); QTRY_VERIFY(lineEdit->hasFocus()); QTest::keyPress(QApplication::focusWidget(), Qt::Key_Tab); - QTest::qWait(25); QTRY_VERIFY(w1_1->hasFocus()); QTest::keyPress(QApplication::focusWidget(), Qt::Key_Tab); - QTest::qWait(25); QTRY_VERIFY(w1_2->hasFocus()); // remove the tabFocusFirst and insert new item delete w1_1; // calls _q_removeItemLater - QTest::qWait(25); SubQGraphicsWidget *w1_3 = new SubQGraphicsWidget; w1_3->setFocusPolicy(Qt::StrongFocus); w1_3->setData(0, "w1_3"); @@ -1480,14 +1467,11 @@ void tst_QGraphicsWidget::verifyFocusChain() scene.addItem(w1_3); QTRY_VERIFY(w1_2->hasFocus()); QTest::keyPress(QApplication::focusWidget(), Qt::Key_Backtab); - QTest::qWait(25); QTRY_VERIFY(lineEdit->hasFocus()); // tabFocusFirst should now point to w1_2 QTest::keyPress(QApplication::focusWidget(), Qt::Key_Tab); - QTest::qWait(25); QTRY_VERIFY(w1_2->hasFocus()); QTest::keyPress(QApplication::focusWidget(), Qt::Key_Tab); - QTest::qWait(25); QTRY_VERIFY(w1_3->hasFocus()); scene.removeItem(w1_2); // does not call _q_removeItemLater delete w1_2; // calls _q_removeItemLater @@ -1498,16 +1482,12 @@ void tst_QGraphicsWidget::verifyFocusChain() w1_4->setGeometry(75,0,25, 25); scene.addItem(w1_4); QTRY_VERIFY(w1_3->hasFocus()); - QTest::qWait(25); QTRY_VERIFY(compareFocusChain(view, QList<QGraphicsItem*>() << w1_3 << w1_4)); QTest::keyPress(QApplication::focusWidget(), Qt::Key_Backtab); - QTest::qWait(25); QTRY_VERIFY(lineEdit->hasFocus()); // tabFocusFirst should now point to w1_3 QTest::keyPress(QApplication::focusWidget(), Qt::Key_Tab); - QTest::qWait(25); QTRY_VERIFY(w1_3->hasFocus()); - QTest::qWait(25); QTRY_VERIFY(compareFocusChain(view, QList<QGraphicsItem*>() << w1_3 << w1_4)); delete window; } @@ -1522,7 +1502,6 @@ void tst_QGraphicsWidget::updateFocusChainWhenChildDie() qt_x11_wait_for_window_manager(&view); #endif QApplication::setActiveWindow(&view); - QTest::qWait(25); QTRY_COMPARE(QApplication::activeWindow(), &view); // delete item in focus chain with no focus and verify chain @@ -1756,31 +1735,29 @@ void tst_QGraphicsWidget::setSizes() widget->setPreferredSize(pref); widget->setMaximumSize(max); - QApplication::processEvents(); - for (i = 0; i < compareInstructions.count(); ++i) { Inst input = compareInstructions.at(i); switch (input.first) { case MinimumSize: - QCOMPARE(widget->minimumSize(), input.second.toSizeF()); + QTRY_COMPARE(widget->minimumSize(), input.second.toSizeF()); break; case PreferredSize: - QCOMPARE(widget->preferredSize(), input.second.toSizeF()); + QTRY_COMPARE(widget->preferredSize(), input.second.toSizeF()); break; case MaximumSize: - QCOMPARE(widget->maximumSize(), input.second.toSizeF()); + QTRY_COMPARE(widget->maximumSize(), input.second.toSizeF()); break; case Size: - QCOMPARE(widget->size(), input.second.toSizeF()); + QTRY_COMPARE(widget->size(), input.second.toSizeF()); break; case MinimumWidth: - QCOMPARE(widget->minimumWidth(), qreal(input.second.toDouble())); + QTRY_COMPARE(widget->minimumWidth(), qreal(input.second.toDouble())); break; case PreferredWidth: - QCOMPARE(widget->preferredWidth(), qreal(input.second.toDouble())); + QTRY_COMPARE(widget->preferredWidth(), qreal(input.second.toDouble())); break; case MaximumWidth: - QCOMPARE(widget->maximumWidth(), qreal(input.second.toDouble())); + QTRY_COMPARE(widget->maximumWidth(), qreal(input.second.toDouble())); break; default: qWarning("instruction not implemented"); @@ -1835,14 +1812,13 @@ void tst_QGraphicsWidget::task236127_bspTreeIndexFails() #ifdef Q_WS_X11 qt_x11_wait_for_window_manager(&view); #endif - QTest::qWait(100); - QVERIFY(!scene.itemAt(25, 25)); + QTRY_VERIFY(!scene.itemAt(25, 25)); widget->setGeometry(0, 112, 360, 528); - QCOMPARE(scene.itemAt(15, 120), (QGraphicsItem *)widget); + QTRY_COMPARE(scene.itemAt(15, 120), (QGraphicsItem *)widget); widget2->setGeometry(0, 573, 360, 67); - QCOMPARE(scene.itemAt(15, 120), (QGraphicsItem *)widget); - QCOMPARE(scene.itemAt(50, 585), (QGraphicsItem *)widget2); + QTRY_COMPARE(scene.itemAt(15, 120), (QGraphicsItem *)widget); + QTRY_COMPARE(scene.itemAt(50, 585), (QGraphicsItem *)widget2); } void tst_QGraphicsWidget::defaultSize() @@ -1857,7 +1833,6 @@ void tst_QGraphicsWidget::defaultSize() #ifdef Q_WS_X11 qt_x11_wait_for_window_manager(&view); #endif - QTest::qWait(50); QSizeF initialSize = widget->size(); widget->resize(initialSize); @@ -1867,9 +1842,8 @@ void tst_QGraphicsWidget::defaultSize() widget->setPreferredSize(60, 60); widget->setMaximumSize(110, 110); widget->setVisible(true); - QTest::qWait(50); // should still have its size set to initialsize - QCOMPARE(widget->geometry().size(), initialSize); + QTRY_COMPARE(widget->geometry().size(), initialSize); } @@ -2391,7 +2365,6 @@ void tst_QGraphicsWidget::painterStateProtectionOnWindowFrame() scene.addItem(widget); view.show(); QTest::qWaitForWindowShown(&view); - QTest::qWait(500); } class ProxyStyle : public QCommonStyle @@ -2480,7 +2453,6 @@ void tst_QGraphicsWidget::task250119_shortcutContext() view.setScene(&scene); view.show(); QApplication::setActiveWindow(&view); - QTest::qWait(25); QTRY_COMPARE(QApplication::activeWindow(), &view); @@ -2735,9 +2707,7 @@ void tst_QGraphicsWidget::respectHFW() QTest::qWaitForWindowShown(view); { // here we go - simulate a interactive resize of the window - QTest::qWait(100); QTest::mouseMove(view, view->mapFromScene(71, 71)); // bottom right corner - QTest::qWait(100); QTest::mousePress(view->viewport(), Qt::LeftButton, 0, view->mapFromScene(71, 71), 200); view->grabMouse(); @@ -2751,10 +2721,9 @@ void tst_QGraphicsWidget::respectHFW() QApplication::sendEvent(view->viewport(), &e); view->releaseMouse(); } - QTest::qWait(100); const QSizeF winSize = window->size(); qreal minHFW = window->effectiveSizeHint(Qt::MinimumSize, QSizeF(winSize.width(), -1)).height(); - QVERIFY(qAbs(minHFW - winSize.height()) < 1); + QTRY_VERIFY(qAbs(minHFW - winSize.height()) < 1); #endif } @@ -2806,7 +2775,7 @@ void tst_QGraphicsWidget::addChildInpolishEvent() view.resize(200, 200); view.show(); QTest::qWaitForWindowShown(&view); - QCOMPARE(PolishWidget::numberOfPolish, 2); + QTRY_COMPARE(PolishWidget::numberOfPolish, 2); } void tst_QGraphicsWidget::polishEvent() @@ -2853,10 +2822,8 @@ void tst_QGraphicsWidget::polishEvent2() widget->events.clear(); - QApplication::processEvents(); - // Make sure the item got polish event. - QVERIFY(widget->events.contains(QEvent::Polish)); + QTRY_VERIFY(widget->events.contains(QEvent::Polish)); } void tst_QGraphicsWidget::autoFillBackground() @@ -2902,11 +2869,9 @@ void tst_QGraphicsWidget::initialShow() view.show(); QTest::qWaitForWindowShown(&view); - QTest::qWait(100); scene.addItem(widget); - QTest::qWait(100); - QCOMPARE(widget->repaints, 1); + QTRY_COMPARE(widget->repaints, 1); } void tst_QGraphicsWidget::initialShow2() @@ -2935,7 +2900,6 @@ void tst_QGraphicsWidget::initialShow2() const int expectedRepaintCount = paintSpy.count(); delete dummyView; dummyView = 0; - QTest::qWait(200); MyGraphicsWidget *widget = new MyGraphicsWidget; widget->resize(100, 100); @@ -2948,7 +2912,7 @@ void tst_QGraphicsWidget::initialShow2() view.show(); QTest::qWaitForWindowShown(&view); - QCOMPARE(widget->repaints, expectedRepaintCount); + QTRY_COMPARE(widget->repaints, expectedRepaintCount); } void tst_QGraphicsWidget::QT_BUG_6544_tabFocusFirstUnsetWhenRemovingItems() diff --git a/tests/auto/qnetworkreply/tst_qnetworkreply.cpp b/tests/auto/qnetworkreply/tst_qnetworkreply.cpp index e11900e..4922a89 100644 --- a/tests/auto/qnetworkreply/tst_qnetworkreply.cpp +++ b/tests/auto/qnetworkreply/tst_qnetworkreply.cpp @@ -205,6 +205,10 @@ private Q_SLOTS: #endif void ioGetFromHttpBrokenServer_data(); void ioGetFromHttpBrokenServer(); + void ioGetFromHttpStatus100_data(); + void ioGetFromHttpStatus100(); + void ioGetFromHttpNoHeaders_data(); + void ioGetFromHttpNoHeaders(); void ioGetFromHttpWithCache_data(); void ioGetFromHttpWithCache(); @@ -2159,6 +2163,60 @@ void tst_QNetworkReply::ioGetFromHttpBrokenServer() QVERIFY(reply->error() != QNetworkReply::NoError); } +void tst_QNetworkReply::ioGetFromHttpStatus100_data() +{ + QTest::addColumn<QByteArray>("dataToSend"); + QTest::newRow("normal") << QByteArray("HTTP/1.1 100 Continue\r\n\r\nHTTP/1.1 200 OK\r\nContent-Length: 0\r\n\r\n"); + QTest::newRow("minimal") << QByteArray("HTTP/1.1 100 Continue\n\nHTTP/1.1 200 OK\r\nContent-Length: 0\r\n\r\n"); + QTest::newRow("minimal2") << QByteArray("HTTP/1.1 100 Continue\n\nHTTP/1.0 200 OK\r\n\r\n"); + QTest::newRow("minimal3") << QByteArray("HTTP/1.1 100 Continue\n\nHTTP/1.0 200 OK\n\n"); + QTest::newRow("with_headers") << QByteArray("HTTP/1.1 100 Continue\r\nBla: x\r\n\r\nHTTP/1.1 200 OK\r\nContent-Length: 0\r\n\r\n"); + QTest::newRow("with_headers2") << QByteArray("HTTP/1.1 100 Continue\nBla: x\n\nHTTP/1.1 200 OK\r\nContent-Length: 0\r\n\r\n"); +} + +void tst_QNetworkReply::ioGetFromHttpStatus100() +{ + QFETCH(QByteArray, dataToSend); + MiniHttpServer server(dataToSend); + server.doClose = true; + + QNetworkRequest request(QUrl("http://localhost:" + QString::number(server.serverPort()))); + QNetworkReplyPtr reply = manager.get(request); + + connect(reply, SIGNAL(finished()), &QTestEventLoop::instance(), SLOT(exitLoop())); + QTestEventLoop::instance().enterLoop(10); + QVERIFY(!QTestEventLoop::instance().timeout()); + + QCOMPARE(reply->url(), request.url()); + QCOMPARE(reply->error(), QNetworkReply::NoError); + QCOMPARE(reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(), 200); + QVERIFY(reply->rawHeader("bla").isNull()); +} + +void tst_QNetworkReply::ioGetFromHttpNoHeaders_data() +{ + QTest::addColumn<QByteArray>("dataToSend"); + QTest::newRow("justStatus+noheaders+disconnect") << QByteArray("HTTP/1.0 200 OK\r\n\r\n"); +} + +void tst_QNetworkReply::ioGetFromHttpNoHeaders() +{ + QFETCH(QByteArray, dataToSend); + MiniHttpServer server(dataToSend); + server.doClose = true; + + QNetworkRequest request(QUrl("http://localhost:" + QString::number(server.serverPort()))); + QNetworkReplyPtr reply = manager.get(request); + + connect(reply, SIGNAL(finished()), &QTestEventLoop::instance(), SLOT(exitLoop())); + QTestEventLoop::instance().enterLoop(10); + QVERIFY(!QTestEventLoop::instance().timeout()); + + QCOMPARE(reply->url(), request.url()); + QCOMPARE(reply->error(), QNetworkReply::NoError); + QCOMPARE(reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(), 200); +} + void tst_QNetworkReply::ioGetFromHttpWithCache_data() { qRegisterMetaType<MyMemoryCache::CachedContent>(); diff --git a/tests/auto/qparallelanimationgroup/tst_qparallelanimationgroup.cpp b/tests/auto/qparallelanimationgroup/tst_qparallelanimationgroup.cpp index fb0f3e0..d2d86fb 100644 --- a/tests/auto/qparallelanimationgroup/tst_qparallelanimationgroup.cpp +++ b/tests/auto/qparallelanimationgroup/tst_qparallelanimationgroup.cpp @@ -75,6 +75,8 @@ private slots: void loopCount(); void autoAdd(); void pauseResume(); + + void QTBUG8910_crashWhenRemovingUncontrolledAnimation(); }; tst_QParallelAnimationGroup::tst_QParallelAnimationGroup() @@ -999,9 +1001,22 @@ void tst_QParallelAnimationGroup::pauseResume() QCOMPARE(spy.count(), 2); //this shouldn't have changed group.resume(); QCOMPARE(spy.count(), 2); //this shouldn't have changed +} - +void tst_QParallelAnimationGroup::QTBUG8910_crashWhenRemovingUncontrolledAnimation() +{ + QParallelAnimationGroup group; + TestAnimation *anim = new TestAnimation; + anim->setLoopCount(-1); + TestAnimation *anim2 = new TestAnimation; + anim2->setLoopCount(-1); + group.addAnimation(anim); + group.addAnimation(anim2); + group.start(); + delete anim; + // it would crash here because the internals of the group would still have a reference to anim + delete anim2; } diff --git a/tests/auto/qscriptclass/tst_qscriptclass.cpp b/tests/auto/qscriptclass/tst_qscriptclass.cpp index aca33ce..b4dbe73 100644 --- a/tests/auto/qscriptclass/tst_qscriptclass.cpp +++ b/tests/auto/qscriptclass/tst_qscriptclass.cpp @@ -98,7 +98,12 @@ public: NotCallable, CallableReturnsSum, CallableReturnsArgument, - CallableReturnsInvalidVariant + CallableReturnsInvalidVariant, + CallableReturnsGlobalObject, + CallableReturnsThisObject, + CallableReturnsCallee, + CallableReturnsArgumentsObject, + CallableInitializesThisObject }; TestClass(QScriptEngine *engine); @@ -348,7 +353,7 @@ QVariant TestClass::extension(Extension extension, qsreal sum = 0; for (int i = 0; i < ctx->argumentCount(); ++i) sum += ctx->argument(i).toNumber(); - QScriptValueIterator it(ctx->thisObject()); + QScriptValueIterator it(ctx->callee()); while (it.hasNext()) { it.next(); sum += it.value().toNumber(); @@ -358,6 +363,17 @@ QVariant TestClass::extension(Extension extension, return qVariantFromValue(ctx->argument(0)); } else if (m_callableMode == CallableReturnsInvalidVariant) { return QVariant(); + } else if (m_callableMode == CallableReturnsGlobalObject) { + return qVariantFromValue(engine()->globalObject()); + } else if (m_callableMode == CallableReturnsThisObject) { + return qVariantFromValue(ctx->thisObject()); + } else if (m_callableMode == CallableReturnsCallee) { + return qVariantFromValue(ctx->callee()); + } else if (m_callableMode == CallableReturnsArgumentsObject) { + return qVariantFromValue(ctx->argumentsObject()); + } else if (m_callableMode == CallableInitializesThisObject) { + engine()->newQObject(ctx->thisObject(), engine()); + return QVariant(); } } else if (extension == HasInstance) { Q_ASSERT(m_hasInstance); @@ -797,9 +813,11 @@ void tst_QScriptClass::extension() QVERIFY(cls.supportsExtension(QScriptClass::Callable)); QScriptValue obj = eng.newObject(&cls); + eng.globalObject().setProperty("obj", obj); obj.setProperty("one", QScriptValue(&eng, 1)); obj.setProperty("two", QScriptValue(&eng, 2)); obj.setProperty("three", QScriptValue(&eng, 3)); + // From C++ cls.clearReceivedArgs(); { QScriptValueList args; @@ -810,8 +828,18 @@ void tst_QScriptClass::extension() QVERIFY(ret.isNumber()); QCOMPARE(ret.toNumber(), qsreal(15)); } + // From JS + cls.clearReceivedArgs(); + { + QScriptValue ret = eng.evaluate("obj(4, 5)"); + QCOMPARE(cls.lastExtensionType(), QScriptClass::Callable); + QCOMPARE(cls.lastExtensionArgument().userType(), qMetaTypeId<QScriptContext*>()); + QVERIFY(ret.isNumber()); + QCOMPARE(ret.toNumber(), qsreal(15)); + } cls.setCallableMode(TestClass::CallableReturnsArgument); + // From C++ cls.clearReceivedArgs(); { QScriptValue ret = obj.call(obj, QScriptValueList() << 123); @@ -843,6 +871,13 @@ void tst_QScriptClass::extension() QScriptValue ret = obj.call(obj, QScriptValueList() << QScriptValue()); QVERIFY(ret.isUndefined()); } + // From JS + cls.clearReceivedArgs(); + { + QScriptValue ret = eng.evaluate("obj(123)"); + QVERIFY(ret.isNumber()); + QCOMPARE(ret.toInt32(), 123); + } cls.setCallableMode(TestClass::CallableReturnsInvalidVariant); { @@ -850,13 +885,92 @@ void tst_QScriptClass::extension() QVERIFY(ret.isUndefined()); } + cls.setCallableMode(TestClass::CallableReturnsThisObject); + // From C++ + { + QScriptValue ret = obj.call(obj); + QVERIFY(ret.isObject()); + QVERIFY(ret.strictlyEquals(obj)); + } + // From JS + { + QScriptValue ret = eng.evaluate("obj()"); + QVERIFY(ret.isObject()); + QVERIFY(ret.strictlyEquals(eng.globalObject())); + } + + cls.setCallableMode(TestClass::CallableReturnsCallee); + // From C++ + { + QScriptValue ret = obj.call(); + QVERIFY(ret.isObject()); + QVERIFY(ret.strictlyEquals(obj)); + } + // From JS + { + QScriptValue ret = eng.evaluate("obj()"); + QVERIFY(ret.isObject()); + QVERIFY(ret.strictlyEquals(obj)); + } + + cls.setCallableMode(TestClass::CallableReturnsArgumentsObject); + // From C++ + { + QScriptValue ret = obj.call(obj, QScriptValueList() << 123); + QVERIFY(ret.isObject()); + QVERIFY(ret.property("length").isNumber()); + QCOMPARE(ret.property("length").toInt32(), 1); + QVERIFY(ret.property(0).isNumber()); + QCOMPARE(ret.property(0).toInt32(), 123); + } + // From JS + { + QScriptValue ret = eng.evaluate("obj(123)"); + QVERIFY(ret.isObject()); + QVERIFY(ret.property("length").isNumber()); + QCOMPARE(ret.property("length").toInt32(), 1); + QVERIFY(ret.property(0).isNumber()); + QCOMPARE(ret.property(0).toInt32(), 123); + } + // construct() + // From C++ cls.clearReceivedArgs(); + cls.setCallableMode(TestClass::CallableReturnsGlobalObject); { QScriptValue ret = obj.construct(); QCOMPARE(cls.lastExtensionType(), QScriptClass::Callable); QCOMPARE(cls.lastExtensionArgument().userType(), qMetaTypeId<QScriptContext*>()); QVERIFY(ret.isObject()); + QVERIFY(ret.strictlyEquals(eng.globalObject())); + } + // From JS + cls.clearReceivedArgs(); + { + QScriptValue ret = eng.evaluate("new obj()"); + QCOMPARE(cls.lastExtensionType(), QScriptClass::Callable); + QCOMPARE(cls.lastExtensionArgument().userType(), qMetaTypeId<QScriptContext*>()); + QVERIFY(ret.isObject()); + QVERIFY(ret.strictlyEquals(eng.globalObject())); + } + // From C++ + cls.clearReceivedArgs(); + cls.setCallableMode(TestClass::CallableInitializesThisObject); + { + QScriptValue ret = obj.construct(); + QCOMPARE(cls.lastExtensionType(), QScriptClass::Callable); + QCOMPARE(cls.lastExtensionArgument().userType(), qMetaTypeId<QScriptContext*>()); + QVERIFY(ret.isQObject()); + QCOMPARE(ret.toQObject(), (QObject*)&eng); + } + // From JS + cls.clearReceivedArgs(); + { + QScriptValue ret = eng.evaluate("new obj()"); + QCOMPARE(cls.lastExtensionType(), QScriptClass::Callable); + QCOMPARE(cls.lastExtensionArgument().userType(), qMetaTypeId<QScriptContext*>()); + QVERIFY(ret.isQObject()); + QCOMPARE(ret.toQObject(), (QObject*)&eng); } } // HasInstance diff --git a/tests/auto/qscriptengine/tst_qscriptengine.cpp b/tests/auto/qscriptengine/tst_qscriptengine.cpp index d9beb45..e71d7c3 100644 --- a/tests/auto/qscriptengine/tst_qscriptengine.cpp +++ b/tests/auto/qscriptengine/tst_qscriptengine.cpp @@ -150,6 +150,7 @@ private slots: void getSetAgent(); void reentrancy(); void incDecNonObjectProperty(); + void installTranslatorFunctions_data(); void installTranslatorFunctions(); void functionScopes(); void nativeFunctionScopes(); @@ -4119,22 +4120,46 @@ void tst_QScriptEngine:: incDecNonObjectProperty() } } +void tst_QScriptEngine::installTranslatorFunctions_data() +{ + QTest::addColumn<bool>("useCustomGlobalObject"); + + QTest::newRow("Default global object") << false; + QTest::newRow("Custom global object") << true; +} + void tst_QScriptEngine::installTranslatorFunctions() { + QFETCH(bool, useCustomGlobalObject); + QScriptEngine eng; - QScriptValue global = eng.globalObject(); + QScriptValue globalOrig = eng.globalObject(); + QScriptValue global; + if (useCustomGlobalObject) { + global = eng.newObject(); + eng.setGlobalObject(global); + } else { + global = globalOrig; + } QVERIFY(!global.property("qsTranslate").isValid()); QVERIFY(!global.property("QT_TRANSLATE_NOOP").isValid()); QVERIFY(!global.property("qsTr").isValid()); QVERIFY(!global.property("QT_TR_NOOP").isValid()); - QVERIFY(!global.property("String").property("prototype").property("arg").isValid()); + QVERIFY(!globalOrig.property("String").property("prototype").property("arg").isValid()); eng.installTranslatorFunctions(); QVERIFY(global.property("qsTranslate").isFunction()); QVERIFY(global.property("QT_TRANSLATE_NOOP").isFunction()); QVERIFY(global.property("qsTr").isFunction()); QVERIFY(global.property("QT_TR_NOOP").isFunction()); - QVERIFY(global.property("String").property("prototype").property("arg").isFunction()); + QVERIFY(globalOrig.property("String").property("prototype").property("arg").isFunction()); + + if (useCustomGlobalObject) { + QVERIFY(!globalOrig.property("qsTranslate").isValid()); + QVERIFY(!globalOrig.property("QT_TRANSLATE_NOOP").isValid()); + QVERIFY(!globalOrig.property("qsTr").isValid()); + QVERIFY(!globalOrig.property("QT_TR_NOOP").isValid()); + } { QScriptValue ret = eng.evaluate("qsTr('foo')"); diff --git a/tests/auto/qscriptvalue/tst_qscriptvalue.cpp b/tests/auto/qscriptvalue/tst_qscriptvalue.cpp index 5b79340..dc369aa 100644 --- a/tests/auto/qscriptvalue/tst_qscriptvalue.cpp +++ b/tests/auto/qscriptvalue/tst_qscriptvalue.cpp @@ -2573,6 +2573,10 @@ void tst_QScriptValue::call() // call with something else as arguments QScriptValue ret5 = fun.call(QScriptValue(), QScriptValue(&eng, 123.0)); QCOMPARE(ret5.isError(), true); + // call with a non-array object as arguments + QScriptValue ret6 = fun.call(QScriptValue(), eng.globalObject()); + QVERIFY(ret6.isError()); + QCOMPARE(ret6.toString(), QString::fromLatin1("TypeError: Arguments must be an array")); } // calling things that are not functions @@ -2705,6 +2709,10 @@ void tst_QScriptValue::construct() // construct with something else as arguments QScriptValue ret5 = fun.construct(QScriptValue(&eng, 123.0)); QCOMPARE(ret5.isError(), true); + // construct with a non-array object as arguments + QScriptValue ret6 = fun.construct(eng.globalObject()); + QVERIFY(ret6.isError()); + QCOMPARE(ret6.toString(), QString::fromLatin1("TypeError: Arguments must be an array")); } // construct on things that are not functions diff --git a/tools/configure/configureapp.cpp b/tools/configure/configureapp.cpp index 8a47991..0aca545 100644 --- a/tools/configure/configureapp.cpp +++ b/tools/configure/configureapp.cpp @@ -973,6 +973,10 @@ void Configure::parseCmdLine() if(i==argCount) break; dictionary[ "QT_LIBINFIX" ] = configCmdLine.at(i); + if (dictionary.contains("XQMAKESPEC") && dictionary["XQMAKESPEC"].startsWith("symbian")) { + dictionary[ "QT_INSTALL_PLUGINS" ] = + QString("\\resource\\qt%1\\plugins").arg(dictionary[ "QT_LIBINFIX" ]); + } } else if( configCmdLine.at(i) == "-D" ) { ++i; if (i==argCount) @@ -3063,6 +3067,8 @@ void Configure::generateConfigfiles() qconfigList += "QT_NO_CRASHHANDLER"; qconfigList += "QT_NO_PRINTER"; qconfigList += "QT_NO_SYSTEMTRAYICON"; + if (dictionary.contains("QT_LIBINFIX")) + tmpStream << QString("#define QT_LIBINFIX \"%1\"").arg(dictionary["QT_LIBINFIX"]) << endl; } qconfigList.sort(); diff --git a/tools/runonphone/trksignalhandler.cpp b/tools/runonphone/trksignalhandler.cpp index 9fe2035..18a2c0c 100644 --- a/tools/runonphone/trksignalhandler.cpp +++ b/tools/runonphone/trksignalhandler.cpp @@ -125,7 +125,7 @@ void TrkSignalHandler::finished() void TrkSignalHandler::applicationOutputReceived(const QString &output) { - d->out << output; + d->out << output << flush; } void TrkSignalHandler::copyProgress(int percent) |