on xenial help sign in
Merge with trunk
0868a6bNick Dedekind
Components/ApplicationManagerWrapper.qml+10−1
@@ -29,6 +29,8 @@ Item {
29 property bool keyboardVisible: ApplicationManager.keyboardVisible
29 property bool keyboardVisible: ApplicationManager.keyboardVisible
30 property int keyboardHeight: ApplicationManager.keyboardHeight
30 property int keyboardHeight: ApplicationManager.keyboardHeight
31
31
32+ property bool fake: ApplicationManager.fake ? ApplicationManager.fake : false
33+
32 Component.onCompleted: {
34 Component.onCompleted: {
33 // Start the watcher so that the ApplicationManager applications model can be populated.
35 // Start the watcher so that the ApplicationManager applications model can be populated.
34 ApplicationManager.startWatcher();
36 ApplicationManager.startWatcher();
@@ -121,9 +123,16 @@ Item {
121 desktopFile = "/usr/share/applications/share-app.desktop"
123 desktopFile = "/usr/share/applications/share-app.desktop"
122 } else if (favoriteApplication == ApplicationManager.BrowserApplication) {
124 } else if (favoriteApplication == ApplicationManager.BrowserApplication) {
123 desktopFile = "/usr/share/applications/webbrowser-app.desktop"
125 desktopFile = "/usr/share/applications/webbrowser-app.desktop"
124− } else if (favoriteApplication == 4) { // ApplicationManager.PhoneApplication
126+ } else if (favoriteApplication == ApplicationManager.PhoneApplication) {
125 desktopFile = "/usr/share/applications/phone-app.desktop"
127 desktopFile = "/usr/share/applications/phone-app.desktop"
128+ } else if (favoriteApplication == ApplicationManager.DialerApplication) {
129+ desktopFile = "/usr/share/applications/dialer-app.desktop"
130+ } else if (favoriteApplication == ApplicationManager.MessagingApplication) {
131+ desktopFile = "/usr/share/applications/messaging-app.desktop"
132+ } else if (favoriteApplication == ApplicationManager.AddressbookApplication) {
133+ desktopFile = "/usr/share/applications/address-book-app.desktop"
126 }
134 }
135+
127 applicationManager.focusRequested(desktopFile);
136 applicationManager.focusRequested(desktopFile);
128 }
137 }
129 }
138 }
Components/CrossFadeImage.qml+3−1
@@ -85,7 +85,7 @@ Item {
85 Connections {
85 Connections {
86 target: __nextImage
86 target: __nextImage
87 onStatusChanged: {
87 onStatusChanged: {
88− if (__nextImage.status == Image.Ready) {
88+ if (__nextImage.status == Image.Ready || __nextImage.status == Image.Error) {
89 swapImages();
89 swapImages();
90 }
90 }
91 }
91 }
@@ -96,6 +96,7 @@ Item {
96 anchors.fill: parent
96 anchors.fill: parent
97 cache: false
97 cache: false
98 asynchronous: true
98 asynchronous: true
99+ fillMode: Image.PreserveAspectCrop
99 z: 1
100 z: 1
100 }
101 }
101
102
@@ -104,6 +105,7 @@ Item {
104 anchors.fill: parent
105 anchors.fill: parent
105 cache: false
106 cache: false
106 asynchronous: true
107 asynchronous: true
108+ fillMode: Image.PreserveAspectCrop
107 z: 0
109 z: 0
108 }
110 }
109
111
Components/Stage.qml+14
@@ -39,6 +39,7 @@ Showable {
39 type == ApplicationInfo.MainStage ? applicationManager.mainStageApplications
39 type == ApplicationInfo.MainStage ? applicationManager.mainStageApplications
40 : applicationManager.sideStageApplications
40 : applicationManager.sideStageApplications
41 property bool fullyShown: false
41 property bool fullyShown: false
42+ property bool fullyHidden: true
42 readonly property var focusedApplication:
43 readonly property var focusedApplication:
43 type == ApplicationInfo.MainStage ? applicationManager.mainStageFocusedApplication
44 type == ApplicationInfo.MainStage ? applicationManager.mainStageFocusedApplication
44 : applicationManager.sideStageFocusedApplication
45 : applicationManager.sideStageFocusedApplication
@@ -249,6 +250,19 @@ Showable {
249 }
250 }
250 }
251 }
251
252
253+ Connections {
254+ target: stage.applications
255+ onCountChanged: { __discardObsoleteScreenshots(); }
256+ ignoreUnknownSignals: true
257+ }
258+ onFullyHiddenChanged: { __discardObsoleteScreenshots(); }
259+ function __discardObsoleteScreenshots() {
260+ if (stage.fullyHidden && stage.applications && stage.applications.count == 0) {
261+ stage.focusedApplicationWhenUsingScreenshots = undefined;
262+ stage.__hideScreenshots();
263+ }
264+ }
265+
252
266
253 SequentialAnimation {
267 SequentialAnimation {
254 id: showStartingApplicationAnimation
268 id: showStartingApplicationAnimation
Dash/DashApps.qml+1−1
@@ -87,7 +87,7 @@ ScopeView {
87 model: scopeView.scope.categories
87 model: scopeView.scope.categories
88
88
89 delegate: Item {
89 delegate: Item {
90− Component.onCompleted: if (index == 3) scopeView.installedModel = Qt.binding(function() { return model.results; });
90+ Component.onCompleted: if (categoryId == "installed") scopeView.installedModel = Qt.binding(function() { return model.results; });
91 }
91 }
92 }
92 }
93
93
Dash/DashHome.qml+1
@@ -26,6 +26,7 @@ import "Music"
26
26
27ScopeView {
27ScopeView {
28 id: root
28 id: root
29+ objectName: "DashHome"
29
30
30 onMovementStarted: listView.showHeader()
31 onMovementStarted: listView.showHeader()
31
32
Dash/DashMusic.qml+2−2
@@ -52,7 +52,7 @@ ScopeView {
52
52
53 function getRenderer(categoryId) {
53 function getRenderer(categoryId) {
54 switch (categoryId) {
54 switch (categoryId) {
55− case 1: return "Music/MusicCarousel.qml"
55+ case "featured": return "Music/MusicCarousel.qml"
56 default: return "Music/MusicFilterGrid.qml"
56 default: return "Music/MusicFilterGrid.qml"
57 }
57 }
58 }
58 }
@@ -69,7 +69,7 @@ ScopeView {
69 id: base
69 id: base
70 highlightWhenPressed: false
70 highlightWhenPressed: false
71
71
72− property int categoryId: id
72+ property string categoryId: model.categoryId
73
73
74 Loader {
74 Loader {
75 anchors { top: parent.top; left: parent.left; right: parent.right }
75 anchors { top: parent.top; left: parent.left; right: parent.right }
Dash/DashVideos.qml+3−4
@@ -53,7 +53,7 @@ ScopeView {
53
53
54 function getRenderer(categoryId) {
54 function getRenderer(categoryId) {
55 switch (categoryId) {
55 switch (categoryId) {
56− case 1: return "Video/VideosCarousel.qml"
56+ case "featured": return "Video/VideosCarousel.qml"
57 default: return "Video/VideosFilterGrid.qml"
57 default: return "Video/VideosFilterGrid.qml"
58 }
58 }
59 }
59 }
@@ -102,8 +102,7 @@ ScopeView {
102 delegate: ListItems.Base {
102 delegate: ListItems.Base {
103 id: base
103 id: base
104 highlightWhenPressed: false
104 highlightWhenPressed: false
105− property int categoryIndex: index
105+ property string categoryId: model.categoryId
106− property int categoryId: id
107
106
108 Loader {
107 Loader {
109 id: loader
108 id: loader
@@ -119,7 +118,7 @@ ScopeView {
119 var dataItem;
118 var dataItem;
120 // VideosCarousel and VideosFilterGrid have different
119 // VideosCarousel and VideosFilterGrid have different
121 // clicked signals, accomodate for that
120 // clicked signals, accomodate for that
122− if (categoryId == 1) {
121+ if (categoryId == "featured") {
123 var fileUri = delegateItem.model.uri.replace(/^[^:]+:/, "")
122 var fileUri = delegateItem.model.uri.replace(/^[^:]+:/, "")
124 dataItem = {fileUri: fileUri, nfoUri: delegateItem.model.comment}
123 dataItem = {fileUri: fileUri, nfoUri: delegateItem.model.comment}
125 } else {
124 } else {
Dash/GenericScopeView.qml+9
@@ -114,7 +114,16 @@ ScopeView {
114 }
114 }
115 }
115 }
116
116
117+ function getDefaultRendererId(contentType) {
118+ switch (contentType) {
119+ default: return "grid";
120+ }
121+ }
122+
117 function getRenderer(rendererId, contentType) {
123 function getRenderer(rendererId, contentType) {
124+ if (rendererId == "default") {
125+ rendererId = getDefaultRendererId(contentType);
126+ }
118 switch (rendererId) {
127 switch (rendererId) {
119 case "grid": {
128 case "grid": {
120 switch (contentType) {
129 switch (contentType) {
Greeter/Greeter.qml+2−3
@@ -34,7 +34,7 @@ Showable {
34
34
35 property alias dragHandleWidth: dragHandle.width
35 property alias dragHandleWidth: dragHandle.width
36 property alias model: greeterContentLoader.model
36 property alias model: greeterContentLoader.model
37− property bool locked: shown && multiUser && !greeterContentLoader.promptless
37+ property bool locked: shown && !LightDM.Greeter.promptless
38
38
39 readonly property bool narrowMode: !multiUser && width <= units.gu(60)
39 readonly property bool narrowMode: !multiUser && width <= units.gu(60)
40 readonly property bool multiUser: LightDM.Users.count > 1
40 readonly property bool multiUser: LightDM.Users.count > 1
@@ -59,7 +59,6 @@ Showable {
59 anchors.fill: parent
59 anchors.fill: parent
60 property var model: LightDM.Users
60 property var model: LightDM.Users
61 property int currentIndex: 0
61 property int currentIndex: 0
62− property bool promptless: item ? item.promptless : false
63 property var infographicModel: LightDM.Infographic
62 property var infographicModel: LightDM.Infographic
64
63
65 source: required ? "GreeterContent.qml" : ""
64 source: required ? "GreeterContent.qml" : ""
@@ -113,7 +112,7 @@ Showable {
113 // UI element)
112 // UI element)
114 distanceThreshold: 0
113 distanceThreshold: 0
115
114
116− enabled: !greeter.locked
115+ enabled: greeter.narrowMode || !greeter.locked
117
116
118 direction: Direction.Leftwards
117 direction: Direction.Leftwards
119 }
118 }
Greeter/GreeterContent.qml−2
@@ -23,7 +23,6 @@ MouseArea {
23 id: root
23 id: root
24 anchors.fill: parent
24 anchors.fill: parent
25
25
26− property bool promptless: loginLoader.status == Loader.Ready && LightDM.Greeter.promptless
27 property bool ready: wallpaper.status == Image.Ready
26 property bool ready: wallpaper.status == Image.Ready
28 property bool leftTeaserPressed: teasingMouseArea.pressed &&
27 property bool leftTeaserPressed: teasingMouseArea.pressed &&
29 teasingMouseArea.mouseX < teasingMouseArea.width / 2
28 teasingMouseArea.mouseX < teasingMouseArea.width / 2
@@ -38,7 +37,6 @@ MouseArea {
38
37
39 source: shell.background
38 source: shell.background
40 anchors.fill: parent
39 anchors.fill: parent
41− crossFade: false
42 fadeInFirst: false
40 fadeInFirst: false
43 }
41 }
44
42
Greeter/Lockscreen.qml+9−9
@@ -69,7 +69,7 @@ Showable {
69 left: parent.left
69 left: parent.left
70 right: parent.right
70 right: parent.right
71 verticalCenter: parent.verticalCenter
71 verticalCenter: parent.verticalCenter
72− verticalCenterOffset: root.alphaNumeric ? -units.gu(10) : 0
72+ verticalCenterOffset: root.alphaNumeric ? -units.gu(10) : -units.gu(4)
73 }
73 }
74 property bool resetting: false
74 property bool resetting: false
75
75
@@ -107,11 +107,11 @@ Showable {
107 Column {
107 Column {
108 anchors {
108 anchors {
109 left: parent.left
109 left: parent.left
110− top: pinPadLoader.bottom
111− topMargin: units.gu(4)
112− right: parent.right
113 bottom: parent.bottom
110 bottom: parent.bottom
111+ bottomMargin: units.gu(4)
112+ right: parent.right
114 }
113 }
114+ height: childrenRect.height
115 spacing: units.gu(1)
115 spacing: units.gu(1)
116
116
117 Icon {
117 Icon {
@@ -120,8 +120,8 @@ Showable {
120 width: height
120 width: height
121 anchors.horizontalCenter: parent.horizontalCenter
121 anchors.horizontalCenter: parent.horizontalCenter
122 name: "phone-app-call-symbolic"
122 name: "phone-app-call-symbolic"
123− color: "white"
123+ color: "#f3f3e7"
124− opacity: 0.9
124+ opacity: 0.6
125
125
126 MouseArea {
126 MouseArea {
127 anchors.fill: parent
127 anchors.fill: parent
@@ -130,9 +130,9 @@ Showable {
130 }
130 }
131
131
132 Label {
132 Label {
133− text: i18n.tr("Emergency call")
133+ text: i18n.tr("Emergency Call")
134− color: "white"
134+ color: "#f3f3e7"
135− opacity: 0.9
135+ opacity: 0.6
136 fontSize: "medium"
136 fontSize: "medium"
137 anchors.horizontalCenter: parent.horizontalCenter
137 anchors.horizontalCenter: parent.horizontalCenter
138 }
138 }
Greeter/PinLockscreen.qml+110−41
@@ -16,15 +16,17 @@
16
16
17import QtQuick 2.0
17import QtQuick 2.0
18import Ubuntu.Components 0.1
18import Ubuntu.Components 0.1
19+import Ubuntu.Components.ListItems 0.1
19import "../Components"
20import "../Components"
20
21
21Column {
22Column {
22 id: root
23 id: root
23 anchors.centerIn: parent
24 anchors.centerIn: parent
24− spacing: units.gu(2.5)
25+ spacing: units.gu(3.5)
25
26
26 property alias placeholderText: pinentryField.placeholderText
27 property alias placeholderText: pinentryField.placeholderText
27− property int padWidth: units.gu(32)
28+ property int padWidth: units.gu(34)
29+ property int padHeight: units.gu(28)
28 property int pinLength: 4
30 property int pinLength: 4
29
31
30 signal entered(string passphrase)
32 signal entered(string passphrase)
@@ -37,70 +39,137 @@ Column {
37 }
39 }
38 }
40 }
39
41
40− TextField {
42+
43+ UbuntuShape {
41 id: pinentryField
44 id: pinentryField
42 objectName: "pinentryField"
45 objectName: "pinentryField"
43 anchors.horizontalCenter: parent.horizontalCenter
46 anchors.horizontalCenter: parent.horizontalCenter
44− width: units.gu(32)
47+ color: "#55000000"
48+ width:root.padWidth
45 height: units.gu(5)
49 height: units.gu(5)
46− echoMode: TextInput.Password
50+ radius: "medium"
47− font.pixelSize: units.dp(44)
51+ property string text: ""
48− color: "white"
52+ property string placeholderText: ""
49− opacity: 0.9
50− hasClearButton: false
51− horizontalAlignment: Text.AlignHCenter
52−
53 onTextChanged: {
53 onTextChanged: {
54+ pinentryFieldLabel.text = "";
55+ for (var i = 0; i < text.length; ++i) {
56+ pinentryFieldLabel.text += "•";
57+ }
54− if (pinentryField.text.length === root.pinLength) {
58+ if (text.length === root.pinLength) {
55− root.entered(pinentryField.text);
59+ root.entered(text);
56 }
60 }
57 }
61 }
58
62
59− // Using a MouseArea to eat clicks. We don't want to disable the TextField for styling reasons
63+ Label {
60− MouseArea {
64+ id: pinentryFieldLabel
61− anchors.fill: parent
65+ anchors.centerIn: parent
66+ font.pixelSize: units.dp(44)
67+ color: "#f3f3e7"
68+ opacity: 0.6
69+ }
70+ Label {
71+ id: pinentryFieldPlaceHolder
72+ anchors.centerIn: parent
73+ color: "grey"
74+ text: parent.placeholderText
75+ visible: pinentryFieldLabel.text.length == 0
62 }
76 }
63 }
77 }
64
78
65− Grid {
79+ UbuntuShape {
66 anchors {
80 anchors {
67 left: parent.left
81 left: parent.left
68 right: parent.right
82 right: parent.right
69 margins: (parent.width - root.padWidth) / 2
83 margins: (parent.width - root.padWidth) / 2
70 }
84 }
85+ height: root.padHeight
86+ color: "#55000000"
87+ radius: "medium"
88+
89+ ThinDivider {
90+ anchors {
91+ left: parent.left
92+ right: parent.right
93+ top: parent.top
94+ topMargin: root.padHeight / 4
95+ }
96+ }
97+ ThinDivider {
98+ anchors {
99+ left: parent.left
100+ right: parent.right
101+ verticalCenter: parent.verticalCenter
102+ }
103+ }
104+ ThinDivider {
105+ anchors {
106+ left: parent.left
107+ right: parent.right
108+ bottom: parent.bottom
109+ bottomMargin: root.padHeight / 4
110+ }
111+ }
71
112
72− columns: 3
113+ ThinDivider {
73− spacing: units.gu(1)
114+ anchors.centerIn: parent
115+ anchors.horizontalCenterOffset: -root.padWidth / 6
116+ width: root.padHeight
117+ rotation: -90
118+ }
119+ ThinDivider {
120+ anchors.centerIn: parent
121+ anchors.horizontalCenterOffset: root.padWidth / 6
122+ width: root.padHeight
123+ rotation: -90
124+ }
74
125
75− Repeater {
126+ Grid {
76− model: 9
127+ anchors {
128+ left: parent.left
129+ right: parent.right
130+ margins: (parent.width - root.padWidth) / 2
131+ }
77
132
133+ columns: 3
134+
135+ Repeater {
136+ model: 9
137+
78− PinPadButton {
138+ PinPadButton {
79− objectName: "pinPadButton" + (index + 1)
139+ objectName: "pinPadButton" + (index + 1)
140+ width: root.padWidth / 3
141+ height: root.padHeight / 4
80− text: index + 1
142+ text: index + 1
81
143
82− onClicked: {
144+ onClicked: {
83− pinentryField.text = pinentryField.text + text
145+ pinentryField.text = pinentryField.text + text;
146+ }
84 }
147 }
85 }
148 }
86− }
87
149
88− PinPadButton {
150+ PinPadButton {
89− objectName: "pinPadButtonBack"
151+ objectName: "pinPadButtonBack"
152+ width: root.padWidth / 3
153+ height: root.padHeight / 4
90− iconName: "back"
154+ iconName: "back"
91− onClicked: root.cancel();
155+ onClicked: root.cancel();
156+ }
92
157
93− }
94− PinPadButton {
158+ PinPadButton {
95− objectName: "pinPadButton0"
159+ objectName: "pinPadButton0"
160+ width: root.padWidth / 3
161+ height: root.padHeight / 4
96− text: "0"
162+ text: "0"
97− onClicked: pinentryField.text = pinentryField.text + text
163+ onClicked: pinentryField.text = pinentryField.text + text
164+ }
98
165
99− }
100− PinPadButton {
166+ PinPadButton {
101− objectName: "pinPadButtonErase"
167+ objectName: "pinPadButtonErase"
168+ width: root.padWidth / 3
169+ height: root.padHeight / 4
102− iconName: "erase"
170+ iconName: "erase"
103− onClicked: pinentryField.text = pinentryField.text.substring(0, pinentryField.text.length-1)
171+ onClicked: pinentryField.text = pinentryField.text.substring(0, pinentryField.text.length-1)
172+ }
104 }
173 }
105 }
174 }
106
175
Greeter/PinPadButton.qml+5−16
@@ -17,28 +17,20 @@
17import QtQuick 2.0
17import QtQuick 2.0
18import Ubuntu.Components 0.1
18import Ubuntu.Components 0.1
19
19
20−UbuntuShape {
20+Item {
21 id: root
21 id: root
22− width: units.gu(10)
23− height: units.gu(7)
24− radius: "medium"
25
22
26 property alias text: label.text
23 property alias text: label.text
27 property alias iconName: icon.name
24 property alias iconName: icon.name
28
25
29 signal clicked()
26 signal clicked()
30
27
31− Behavior on color {
32− ColorAnimation { duration: 100 }
33− }
34−
35 Label {
28 Label {
36 id: label
29 id: label
37 anchors.centerIn: parent
30 anchors.centerIn: parent
38− color: "white"
31+ color: "#f3f3e7"
39− fontSize: "x-large"
32+ fontSize: "large"
40− font.weight: Font.Light
33+ font.weight: Font.DemiBold
41− opacity: 0.9
42 }
34 }
43
35
44 Icon {
36 Icon {
@@ -46,14 +38,11 @@ UbuntuShape {
46 height: units.gu(3)
38 height: units.gu(3)
47 width: height
39 width: height
48 anchors.centerIn: parent
40 anchors.centerIn: parent
49− color: "white"
41+ color: "#f3f3e7"
50− opacity: 0.9
51 }
42 }
52
43
53 MouseArea {
44 MouseArea {
54 anchors.fill: parent
45 anchors.fill: parent
55 onClicked: root.clicked()
46 onClicked: root.clicked()
56− onPressed: root.color = Qt.rgba(0, 0, 0, 0.3)
57− onReleased: root.color = Qt.rgba(0, 0, 0, 0)
58 }
47 }
59}
48}
Panel/Indicators/client/IndicatorsClient.qml+8−9
@@ -27,16 +27,15 @@ Rectangle {
27
27
28 PageStack {
28 PageStack {
29 id: pages
29 id: pages
30−
31 anchors.fill: parent
30 anchors.fill: parent
32− Component.onCompleted: root.reset()
31+ Component.onCompleted: reset()
33− }
34
32
35− function reset() {
33+ function reset() {
36− pages.clear();
34+ clear();
37− var component = Qt.createComponent("IndicatorsList.qml");
35+ var component = Qt.createComponent("IndicatorsList.qml");
38− var page = component.createObject(pages);
36+ var page = component.createObject(pages);
39− console.log(component.errorString());
37+ console.log(component.errorString());
40− pages.push(page);
38+ push(page);
39+ }
41 }
40 }
42}
41}
Panel/Indicators/client/IndicatorsPage.qml+57−12
@@ -15,35 +15,80 @@
15 *
15 *
16 * Authors:
16 * Authors:
17 * Renato Araujo Oliveira Filho <renato@canonical.com>
17 * Renato Araujo Oliveira Filho <renato@canonical.com>
18+ * Nick Dedekind <nick.dedekind@canonical.com>
18 */
19 */
19
20
20import QtQuick 2.0
21import QtQuick 2.0
21import Ubuntu.Components 0.1
22import Ubuntu.Components 0.1
23+import Ubuntu.Components.ListItems 0.1 as ListItem
22
24
23Page {
25Page {
24− id: _page
26+ id: page
25
27
26 title: indicatorProperties && indicatorProperties.title ? indicatorProperties.title : ""
28 title: indicatorProperties && indicatorProperties.title ? indicatorProperties.title : ""
27 property variant indicatorProperties
29 property variant indicatorProperties
28− property alias pageSource : page_loader.source
30+ property string pageSource : pageLoader.source
29
31
30 anchors.fill: parent
32 anchors.fill: parent
31
33
34+ ListItem.Standard {
35+ id: visualCheckItem
36+ text: "Enable Visual Representation"
37+ control: Switch {
38+ id: visualCheck
39+ checked: true
40+ }
41+ }
42+
32 Loader {
43 Loader {
33− id: page_loader
44+ id: pageLoader
34− objectName: "page_loader"
45+ objectName: "pageLoader"
35
46
36− anchors.fill: parent
47+ anchors {
48+ top: visualCheckItem.bottom
49+ left: parent.left
50+ right: parent.right
51+ bottom: buttons.top
52+ topMargin: units.gu(2)
53+ bottomMargin: units.gu(2)
54+ }
55+ source : visualCheck.checked ? page.pageSource : "IndicatorsTree.qml"
37
56
38− onStatusChanged: {
57+ onLoaded: {
39− if (status == Loader.Ready) {
40− for(var pName in indicatorProperties) {
58+ for(var pName in indicatorProperties) {
41− if (item.hasOwnProperty(pName)) {
59+ if (item.hasOwnProperty(pName)) {
42− item[pName] = indicatorProperties[pName];
60+ item[pName] = indicatorProperties[pName];
43− }
44 }
61 }
45− item.start();
46 }
62 }
63+ item.start();
64+ }
65+ }
66+
67+ Item {
68+ id: buttons
69+ anchors {
70+ left: parent.left
71+ right: parent.right
72+ bottom: parent.bottom
73+ margins: units.gu(1)
74+ }
75+ height: childrenRect.height
76+
77+ Button {
78+ anchors {
79+ left: parent.left
80+ }
81+ text: "Back"
82+ onClicked: page.pageStack.reset()
83+ }
84+ Button {
85+ id: refresh
86+ visible: !visualCheck.checked
87+ anchors {
88+ right: parent.right
89+ }
90+ text: "Refresh"
91+ onClicked: pageLoader.item.refresh()
47 }
92 }
48 }
93 }
49}
94}
Panel/Indicators/client/IndicatorsTree.qmlnew file+62
@@ -0,0 +1,62 @@
1+/*
2+ * Copyright 2013 Canonical Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU Lesser General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU Lesser General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU Lesser General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ *
16+ * Authors:
17+ * Nick Dedekind <nick.dededkind@canonical.com>
18+ */
19+
20+import QtQuick 2.0
21+import Ubuntu.Components 0.1
22+import Unity.Indicators 0.1 as Indicators
23+import QMenuModel 0.1
24+import Ubuntu.Components.ListItems 0.1 as ListItem
25+
26+Page {
27+ id: page
28+ anchors.fill: parent
29+
30+ property alias busType: menuModel.busType
31+ property alias busName: menuModel.busName
32+ property string actionsObjectPath
33+ property var menuObjectPaths: undefined
34+ readonly property string device: "phone"
35+
36+ property string deviceMenuObjectPath: menuObjectPaths.hasOwnProperty(device) ? menuObjectPaths[device] : ""
37+
38+ function start() {
39+ menuModel.start();
40+ }
41+
42+ QDBusMenuModel {
43+ id: menuModel
44+ objectPath: page.deviceMenuObjectPath
45+ }
46+
47+ Indicators.ModelPrinter {
48+ id: printer
49+ model: menuModel
50+ }
51+
52+ Flickable {
53+ anchors.fill: parent
54+ contentHeight: all_data.height
55+ clip:true
56+ Text {
57+ id: all_data
58+ color: "white"
59+ text: printer.text
60+ }
61+ }
62+}
Shell.qml+92−35
@@ -15,10 +15,12 @@
15 */
15 */
16
16
17import QtQuick 2.0
17import QtQuick 2.0
18+import GSettings 1.0
18import Ubuntu.Application 0.1
19import Ubuntu.Application 0.1
19import Ubuntu.Components 0.1
20import Ubuntu.Components 0.1
20import Ubuntu.Gestures 0.1
21import Ubuntu.Gestures 0.1
21import LightDM 0.1 as LightDM
22import LightDM 0.1 as LightDM
23+import Powerd 0.1
22import "Dash"
24import "Dash"
23import "Greeter"
25import "Greeter"
24import "Launcher"
26import "Launcher"
@@ -36,12 +38,12 @@ FocusScope {
36
38
37 // this is only here to select the width / height of the window if not running fullscreen
39 // this is only here to select the width / height of the window if not running fullscreen
38 property bool tablet: false
40 property bool tablet: false
39− width: tablet ? units.gu(160) : ApplicationArguments.hasGeometry() ? ApplicationArguments.width() : units.gu(40)
41+ width: tablet ? units.gu(160) : applicationArguments.hasGeometry() ? applicationArguments.width() : units.gu(40)
40− height: tablet ? units.gu(100) : ApplicationArguments.hasGeometry() ? ApplicationArguments.height() : units.gu(71)
42+ height: tablet ? units.gu(100) : applicationArguments.hasGeometry() ? applicationArguments.height() : units.gu(71)
41
43
42 property real edgeSize: units.gu(2)
44 property real edgeSize: units.gu(2)
43− property url default_background: shell.width >= units.gu(60) ? "graphics/tablet_background.jpg" : "graphics/phone_background.jpg"
45+ property url defaultBackground: shell.width >= units.gu(60) ? "graphics/tablet_background.jpg" : "graphics/phone_background.jpg"
44− property url background: default_background
46+ property url background: backgroundSettings.pictureUri
45 readonly property real panelHeight: panel.panelHeight
47 readonly property real panelHeight: panel.panelHeight
46
48
47 property bool dashShown: dash.shown
49 property bool dashShown: dash.shown
@@ -112,6 +114,11 @@ FocusScope {
112 }
114 }
113 }
115 }
114
116
117+ GSettings {
118+ id: backgroundSettings
119+ schema.id: "org.gnome.desktop.background"
120+ }
121+
115 VolumeControl {
122 VolumeControl {
116 id: volumeControl
123 id: volumeControl
117 }
124 }
@@ -127,18 +134,31 @@ FocusScope {
127
134
128 Item {
135 Item {
129 id: underlay
136 id: underlay
137+ objectName: "underlay"
130 anchors.fill: parent
138 anchors.fill: parent
131− visible: !(panel.indicators.fullyOpened && shell.width <= panel.indicatorsMenuWidth)
132− && (stages.fullyHidden
133− || (stages.fullyShown && mainStage.usingScreenshots)
134− || !stages.fullyShown && (mainStage.usingScreenshots || (sideStage.shown && sideStage.usingScreenshots)))
135
139
136− Image {
140+ // Whether the underlay is fully covered by opaque UI elements.
141+ property bool fullyCovered: panel.indicators.fullyOpened && shell.width <= panel.indicatorsMenuWidth
142+
143+ // Whether the user should see the topmost application surface (if there's one at all).
144+ property bool applicationSurfaceShouldBeSeen:
145+ (mainStage.applications && mainStage.applications.count > 0)
146+ && (!stages.fullyHidden && !mainStage.usingScreenshots)
147+
148+ // NB! Application surfaces are stacked behing the shell one. So they can only be seen by the user
149+ // through the translucent parts of the shell surface.
150+ visible: !fullyCovered && !applicationSurfaceShouldBeSeen
151+
152+ CrossFadeImage {
137 id: backgroundImage
153 id: backgroundImage
154+ objectName: "backgroundImage"
138 source: shell.background
155 source: shell.background
139− sourceSize.width: parent.width
140− sourceSize.height: parent.height
141 anchors.fill: parent
156 anchors.fill: parent
157+ onStatusChanged: {
158+ if (status == Image.Error) {
159+ backgroundSettings.pictureUri = shell.defaultBackground
160+ }
161+ }
142 }
162 }
143
163
144 Rectangle {
164 Rectangle {
@@ -149,6 +169,7 @@ FocusScope {
149
169
150 Dash {
170 Dash {
151 id: dash
171 id: dash
172+ objectName: "dash"
152
173
153 available: !greeter.shown && !lockscreen.shown
174 available: !greeter.shown && !lockscreen.shown
154 hides: [stages, launcher, panel.indicators]
175 hides: [stages, launcher, panel.indicators]
@@ -176,13 +197,12 @@ FocusScope {
176 }
197 }
177 }
198 }
178
199
179− // FIXME: only necessary because stagesRevealer.animatedProgress and
200+ // FIXME: only necessary because stagesOuterContainer.showProgress and
180 // greeterRevealer.animatedProgress are not animated
201 // greeterRevealer.animatedProgress are not animated
181 Behavior on disappearingAnimationProgress { SmoothedAnimation { velocity: 5 }}
202 Behavior on disappearingAnimationProgress { SmoothedAnimation { velocity: 5 }}
182 }
203 }
183 }
204 }
184
205
185−
186 Item {
206 Item {
187 id: stagesOuterContainer
207 id: stagesOuterContainer
188
208
@@ -196,6 +216,7 @@ FocusScope {
196
216
197 Showable {
217 Showable {
198 id: stages
218 id: stages
219+ objectName: "stages"
199
220
200 x: width
221 x: width
201
222
@@ -246,12 +267,12 @@ FocusScope {
246 ignoreUnknownSignals: true
267 ignoreUnknownSignals: true
247 }
268 }
248
269
249−
250 Stage {
270 Stage {
251 id: mainStage
271 id: mainStage
252
272
253 anchors.fill: parent
273 anchors.fill: parent
254 fullyShown: stages.fullyShown
274 fullyShown: stages.fullyShown
275+ fullyHidden: stages.fullyHidden
255 shouldUseScreenshots: !fullyShown
276 shouldUseScreenshots: !fullyShown
256 rightEdgeEnabled: !sideStage.enabled
277 rightEdgeEnabled: !sideStage.enabled
257
278
@@ -336,7 +357,7 @@ FocusScope {
336 }
357 }
337
358
338 DragHandle {
359 DragHandle {
339− id: stagesRevealer
360+ id: stagesDragHandle
340
361
341 anchors.top: parent.top
362 anchors.top: parent.top
342 anchors.bottom: parent.bottom
363 anchors.bottom: parent.bottom
@@ -344,7 +365,11 @@ FocusScope {
344
365
345 width: shell.edgeSize
366 width: shell.edgeSize
346 direction: Direction.Leftwards
367 direction: Direction.Leftwards
347− enabled: mainStage.applications.count > 0 || sideStage.applications.count > 0
368+ property bool haveApps: mainStage.applications.count > 0 || sideStage.applications.count > 0
369+
370+ maxTotalDragDistance: haveApps ? parent.width : parent.width * 0.7
371+ // Make autocompletion impossible when !haveApps
372+ edgeDragEvaluator.minDragDistance: haveApps ? maxTotalDragDistance * 0.1 : Number.MAX_VALUE
348 }
373 }
349 }
374 }
350 }
375 }
@@ -402,9 +427,6 @@ FocusScope {
402
427
403 dragHandleWidth: shell.edgeSize
428 dragHandleWidth: shell.edgeSize
404
429
405− property var previousMainApp: null
406− property var previousSideApp: null
407−
408 onShownChanged: {
430 onShownChanged: {
409 if (shown) {
431 if (shown) {
410 lockscreen.reset();
432 lockscreen.reset();
@@ -414,27 +436,13 @@ FocusScope {
414 LightDM.Greeter.authenticate(LightDM.Users.data(0, LightDM.UserRoles.NameRole));
436 LightDM.Greeter.authenticate(LightDM.Users.data(0, LightDM.UserRoles.NameRole));
415 }
437 }
416 greeter.forceActiveFocus();
438 greeter.forceActiveFocus();
417− // FIXME: *FocusedApplication are not updated when unfocused, hence the need to check whether
418− // the stage was actually shown
419− if (mainStage.fullyShown) greeter.previousMainApp = applicationManager.mainStageFocusedApplication;
420− if (sideStage.fullyShown) greeter.previousSideApp = applicationManager.sideStageFocusedApplication;
421− applicationManager.unfocusCurrentApplication();
422− } else {
423− if (greeter.previousMainApp) {
424− applicationManager.focusApplication(greeter.previousMainApp);
425− greeter.previousMainApp = null;
426− }
427− if (greeter.previousSideApp) {
428− applicationManager.focusApplication(greeter.previousSideApp);
429− greeter.previousSideApp = null;
430− }
431 }
439 }
432 }
440 }
433
441
434 onUnlocked: greeter.hide()
442 onUnlocked: greeter.hide()
435 onSelected: {
443 onSelected: {
436 var bgPath = greeter.model.data(uid, LightDM.UserRoles.BackgroundPathRole)
444 var bgPath = greeter.model.data(uid, LightDM.UserRoles.BackgroundPathRole)
437− shell.background = bgPath ? bgPath : default_background
445+ shell.background = bgPath ? bgPath : defaultBackground
438 }
446 }
439
447
440 onLeftTeaserPressedChanged: {
448 onLeftTeaserPressedChanged: {
@@ -449,6 +457,41 @@ FocusScope {
449 blockInput: greeter.shown || lockscreen.shown
457 blockInput: greeter.shown || lockscreen.shown
450 }
458 }
451
459
460+ Connections {
461+ id: powerConnection
462+ target: Powerd
463+
464+ property var previousMainApp: null
465+ property var previousSideApp: null
466+
467+ function setFocused(focused) {
468+ if (!focused) {
469+ // FIXME: *FocusedApplication are not updated when unfocused, hence the need to check whether
470+ // the stage was actually shown
471+ if (mainStage.fullyShown) powerConnection.previousMainApp = applicationManager.mainStageFocusedApplication;
472+ if (sideStage.fullyShown) powerConnection.previousSideApp = applicationManager.sideStageFocusedApplication;
473+ applicationManager.unfocusCurrentApplication();
474+ } else {
475+ if (powerConnection.previousMainApp) {
476+ applicationManager.focusApplication(powerConnection.previousMainApp);
477+ powerConnection.previousMainApp = null;
478+ }
479+ if (powerConnection.previousSideApp) {
480+ applicationManager.focusApplication(powerConnection.previousSideApp);
481+ powerConnection.previousSideApp = null;
482+ }
483+ }
484+ }
485+
486+ onPowerStateChange: {
487+ if (state == 0) { // suspend
488+ powerConnection.setFocused(false);
489+ } else if (state == 1) { // active
490+ powerConnection.setFocused(true);
491+ }
492+ }
493+ }
494+
452 Item {
495 Item {
453 id: overlay
496 id: overlay
454
497
@@ -534,7 +577,7 @@ FocusScope {
534 anchors.bottom: parent.bottom
577 anchors.bottom: parent.bottom
535 width: parent.width
578 width: parent.width
536 dragAreaWidth: shell.edgeSize
579 dragAreaWidth: shell.edgeSize
537− available: !greeter.locked
580+ available: !greeter.shown || greeter.narrowMode
538 onDashItemSelected: {
581 onDashItemSelected: {
539 greeter.hide()
582 greeter.hide()
540 // Animate if moving between application and dash
583 // Animate if moving between application and dash
@@ -629,4 +672,18 @@ FocusScope {
629
672
630 enabled: shell.applicationManager && shell.applicationManager.keyboardVisible
673 enabled: shell.applicationManager && shell.applicationManager.keyboardVisible
631 }
674 }
675+
676+ Label {
677+ anchors.fill: parent
678+ visible: applicationManager.fake
679+ text: "EARLY ALPHA\nNOT READY FOR USE"
680+ color: "lightgrey"
681+ opacity: 0.2
682+ font.weight: Font.Black
683+ horizontalAlignment: Text.AlignHCenter
684+ verticalAlignment: Text.AlignVCenter
685+ fontSizeMode: Text.Fit
686+ font.pixelSize: height/2
687+ rotation: -45
688+ }
632}
689}
debian/changelog+145
@@ -1,3 +1,148 @@
1+unity8 (7.81.3+13.10.20130802-0ubuntu1) saucy; urgency=low
2+
3+ [ Michael Terry ]
4+ * Make hud autopilot tests more reliable by fixing how it calculates
5+ relative coordinates.
6+
7+ [ Albert Astals ]
8+ * Only update the "section" if we are not culling the item If the item
9+ is not shown we should not care about its section.
10+
11+ [ Ubuntu daily release ]
12+ * Automatic snapshot from revision 155
13+
14+ -- Ubuntu daily release <ps-jenkins@lists.canonical.com> Fri, 02 Aug 2013 02:40:11 +0000
15+
16+unity8 (7.81.3+13.10.20130801.1-0ubuntu1) saucy; urgency=low
17+
18+ [ Michał Sawicz ]
19+ * Add a disclaimer for the fake applications plugin.
20+
21+ [ Nick Dedekind ]
22+ * Removed animations from fake indicator pages.
23+
24+ [ Ubuntu daily release ]
25+ * Automatic snapshot from revision 152
26+
27+ -- Ubuntu daily release <ps-jenkins@lists.canonical.com> Thu, 01 Aug 2013 14:30:40 +0000
28+
29+unity8 (7.81.3+13.10.20130801ubuntu.unity.next-0ubuntu1) saucy; urgency=low
30+
31+ [ Michael Zanetti ]
32+ * implemented new Lockscreen design.
33+
34+ [ Michał Sawicz ]
35+ * Fix mock VideoPreview to use the string categoryId as well.
36+
37+ [ Nick Dedekind ]
38+ * Added a text tree representation of the qmenumodel to the
39+ indicators-client application.
40+
41+ [ Albert Astals ]
42+ * Don't need deelistmodel here.
43+
44+ [ Ubuntu daily release ]
45+ * Automatic snapshot from revision 149 (ubuntu-unity/next)
46+
47+ -- Ubuntu daily release <ps-jenkins@lists.canonical.com> Thu, 01 Aug 2013 02:32:03 +0000
48+
49+unity8 (7.81.3+13.10.20130730ubuntu.unity.next-0ubuntu1) saucy; urgency=low
50+
51+ [ Michał Sawicz ]
52+ * Adapt to Qt 5.1.
53+
54+ [ Albert Astals ]
55+ * Adapt to Qt 5.1.
56+
57+ [ Ubuntu daily release ]
58+ * Automatic snapshot from revision 143 (ubuntu-unity/next)
59+
60+ -- Ubuntu daily release <ps-jenkins@lists.canonical.com> Tue, 30 Jul 2013 02:33:12 +0000
61+
62+unity8 (7.81.3+13.10.20130729ubuntu.unity.next-0ubuntu1) saucy; urgency=low
63+
64+ [ Michal Hruby ]
65+ * Remove the variant conversions methods as they were moved to dee-qt.
66+
67+ [ Michał Sawicz ]
68+ * Re-enable passphrase tests under UInput.
69+ * Use the new string categoryIds in custom video and music scope
70+ views. (LP: #1199322)
71+
72+ [ Nick Dedekind ]
73+ * Behavioural changes for indicators - Part 1 - Use standard
74+ animations. - Search bar animation less distracting. - Hinting
75+ animation shows header. - Vertical velocity detector to reduce
76+ accidental menu switches in dragging phase.
77+
78+ [ Gustavo Pichorim Boiko ]
79+ * Add entries to the new applications resulted from the split of the
80+ phone-app.
81+
82+ [ Ubuntu daily release ]
83+ * Automatic snapshot from revision 141 (ubuntu-unity/next)
84+
85+ -- Ubuntu daily release <ps-jenkins@lists.canonical.com> Mon, 29 Jul 2013 03:41:07 +0000
86+
87+unity8 (7.81.3+13.10.20130726ubuntu.unity.next-0ubuntu1) saucy; urgency=low
88+
89+ [ Michal Hruby ]
90+ * Expose real category ids and not just indices.
91+ * Provide fallbacks for default renderer.
92+
93+ [ Daniel d'Andrada ]
94+ * Give a visual feedback on right-edge drag with no running apps (LP:
95+ #1116207). (LP: #1116207)
96+
97+ [ Albert Astals ]
98+ * Update m_firstVisibleIndex if there's no visible items anymore Also
99+ remove the check for m_visibleItems.isEmpty() on insert, the
100+ m_firstVisibleIndex == 0 already protects us against that.
101+
102+ [ Christopher Lee ]
103+ * Tests now use a default lightdm mock if not decorated. (LP:
104+ #1204772)
105+
106+ [ Ubuntu daily release ]
107+ * Automatic snapshot from revision 135 (ubuntu-unity/next)
108+
109+ -- Ubuntu daily release <ps-jenkins@lists.canonical.com> Fri, 26 Jul 2013 07:06:08 +0000
110+
111+unity8 (7.81.3+13.10.20130725ubuntu.unity.next-0ubuntu1) saucy; urgency=low
112+
113+ [ Michal Hruby ]
114+ * Fix adding items into an empty LVWPH.
115+
116+ [ Michał Sawicz ]
117+ * Move to using upstart in run_on_device.
118+ * Added heeding and qmltest for button-tint hint.
119+ * Refactoring and cleanup of the Unity8 Autopilot tests.
120+ * Hide the Unity launcher during autopiloting and skip battery tests
121+ if unavailable.
122+
123+ [ Ying-Chun Liu ]
124+ * Let GenericScope support loading different renderers.
125+
126+ [ Nick Dedekind ]
127+ * Removed overview from indicators.
128+ * Menus for indicators is now created prioritised by distance from
129+ current item to speed up user experience.
130+ * Add ApplicationArguments to know the geometry from start.
131+
132+ [ Mirco Müller ]
133+ * Added heeding and qmltest for button-tint hint.
134+
135+ [ Christopher Lee ]
136+ * Refactoring and cleanup of the Unity8 Autopilot tests.
137+
138+ [ Thomi Richards ]
139+ * Refactoring and cleanup of the Unity8 Autopilot tests.
140+
141+ [ Ubuntu daily release ]
142+ * Automatic snapshot from revision 129 (ubuntu-unity/next)
143+
144+ -- Ubuntu daily release <ps-jenkins@lists.canonical.com> Thu, 25 Jul 2013 03:02:12 +0000
145+
1unity8 (7.81.3+13.10.20130718ubuntu.unity.next-0ubuntu1) saucy; urgency=low
146unity8 (7.81.3+13.10.20130718ubuntu.unity.next-0ubuntu1) saucy; urgency=low
2
147
3 [ Andrea Cimitan ]
148 [ Andrea Cimitan ]
debian/control+6−2
@@ -4,7 +4,7 @@ Priority: optional
4Maintainer: Ubuntu Developers <ubuntu-devel-discuss@lists.ubuntu.com>
4Maintainer: Ubuntu Developers <ubuntu-devel-discuss@lists.ubuntu.com>
5Build-Depends: cmake,
5Build-Depends: cmake,
6 debhelper (>= 9),
6 debhelper (>= 9),
7− libdee-qt5-dev (>= 3.0),
7+ libdee-qt5-dev (>= 3.2),
8 libgl1-mesa-dev[!armhf] | libgl-dev[!armhf],
8 libgl1-mesa-dev[!armhf] | libgl-dev[!armhf],
9 libgl1-mesa-dri,
9 libgl1-mesa-dri,
10 libgles2-mesa-dev[armhf],
10 libgles2-mesa-dev[armhf],
@@ -56,8 +56,10 @@ Description: Indicators client test application
56
56
57Package: unity8
57Package: unity8
58Architecture: any
58Architecture: any
59+Depends: gsettings-desktop-schemas,
59−Depends: qmenumodel-qml,
60+ qmenumodel-qml,
60 qtdeclarative5-dee-plugin,
61 qtdeclarative5-dee-plugin,
62+ qtdeclarative5-gsettings1.0,
61 qtdeclarative5-ubuntu-ui-toolkit-plugin,
63 qtdeclarative5-ubuntu-ui-toolkit-plugin,
62 qtdeclarative5-unity-notifications-plugin | unity-notifications-impl,
64 qtdeclarative5-unity-notifications-plugin | unity-notifications-impl,
63 qtdeclarative5-xmllistmodel-plugin,
65 qtdeclarative5-xmllistmodel-plugin,
@@ -87,6 +89,8 @@ Depends: indicators-client (>= ${source:Version}),
87 ${misc:Depends},
89 ${misc:Depends},
88 ${python:Depends},
90 ${python:Depends},
89 ${shlibs:Depends},
91 ${shlibs:Depends},
92+Recommends: gir1.2-glib-2.0,
93+ python-gi,
90Description: Test package for Unity 8 shell
94Description: Test package for Unity 8 shell
91 Autopilot tests for the unity8 package
95 Autopilot tests for the unity8 package
92
96
debian/unity8-private.install+1
@@ -1,6 +1,7 @@
1usr/lib/*/unity8/qml/HudClient
1usr/lib/*/unity8/qml/HudClient
2usr/lib/*/unity8/qml/LightDM
2usr/lib/*/unity8/qml/LightDM
3usr/lib/*/unity8/qml/ListViewWithPageHeader
3usr/lib/*/unity8/qml/ListViewWithPageHeader
4+usr/lib/*/unity8/qml/Powerd
4usr/lib/*/unity8/qml/Ubuntu
5usr/lib/*/unity8/qml/Ubuntu
5usr/lib/*/unity8/qml/Unity
6usr/lib/*/unity8/qml/Unity
6usr/lib/*/unity8/qml/Utils
7usr/lib/*/unity8/qml/Utils
main.cpp+1−1
@@ -113,7 +113,7 @@ int main(int argc, char** argv)
113 view->setResizeMode(QQuickView::SizeRootObjectToView);
113 view->setResizeMode(QQuickView::SizeRootObjectToView);
114 view->setTitle("Qml Phone Shell");
114 view->setTitle("Qml Phone Shell");
115 view->engine()->setBaseUrl(QUrl::fromLocalFile(::shellAppDirectory()));
115 view->engine()->setBaseUrl(QUrl::fromLocalFile(::shellAppDirectory()));
116− view->rootContext()->setContextProperty("ApplicationArguments", &qmlArgs);
116+ view->rootContext()->setContextProperty("applicationArguments", &qmlArgs);
117 if (args.contains(QLatin1String("-frameless"))) {
117 if (args.contains(QLatin1String("-frameless"))) {
118 view->setFlags(Qt::FramelessWindowHint);
118 view->setFlags(Qt::FramelessWindowHint);
119 }
119 }
plugins/CMakeLists.txt+1
@@ -4,3 +4,4 @@ add_subdirectory(Unity)
4add_subdirectory(HudClient)
4add_subdirectory(HudClient)
5add_subdirectory(LightDM)
5add_subdirectory(LightDM)
6add_subdirectory(ListViewWithPageHeader)
6add_subdirectory(ListViewWithPageHeader)
7+add_subdirectory(Powerd)
plugins/ListViewWithPageHeader/CMakeLists.txt+5−1
@@ -4,7 +4,11 @@ include(Plugins)
4# There's no cmake var for v8 include path :-/
4# There's no cmake var for v8 include path :-/
5# so create one
5# so create one
6LIST(GET Qt5Core_INCLUDE_DIRS 0 QtCoreDir0)
6LIST(GET Qt5Core_INCLUDE_DIRS 0 QtCoreDir0)
7+if(${Qt5Core_VERSION_STRING} VERSION_LESS "5.1.0")
7−SET(Qt5V8_PRIVATE_INCLUDE_DIR ${QtCoreDir0}/../QtV8/${Qt5Core_VERSION_STRING}/QtV8)
8+ SET(Qt5V8_PRIVATE_INCLUDE_DIR ${QtCoreDir0}/../QtV8/${Qt5Core_VERSION_STRING}/QtV8)
9+else()
10+ SET(Qt5V8_PRIVATE_INCLUDE_DIR ${QtCoreDir0}/QtV8/${Qt5Core_VERSION_STRING}/QtV8)
11+endif()
8
12
9include_directories(
13include_directories(
10 ${CMAKE_CURRENT_SOURCE_DIR}
14 ${CMAKE_CURRENT_SOURCE_DIR}
plugins/ListViewWithPageHeader/listviewwithpageheader.cpp+97−13
@@ -96,7 +96,11 @@
96#include <qqmlengine.h>
96#include <qqmlengine.h>
97#pragma GCC diagnostic push
97#pragma GCC diagnostic push
98#pragma GCC diagnostic ignored "-pedantic"
98#pragma GCC diagnostic ignored "-pedantic"
99+#if (QT_VERSION < QT_VERSION_CHECK(5, 1, 0))
99#include <private/qquickvisualdatamodel_p.h>
100#include <private/qquickvisualdatamodel_p.h>
101+#else
102+#include <private/qqmldelegatemodel_p.h>
103+#endif
100#include <private/qqmlglobal_p.h>
104#include <private/qqmlglobal_p.h>
101#include <private/qquickitem_p.h>
105#include <private/qquickitem_p.h>
102#include <private/qquickanimation_p.h>
106#include <private/qquickanimation_p.h>
@@ -183,10 +187,17 @@ void ListViewWithPageHeader::setModel(QAbstractItemModel *model)
183 if (!m_delegateModel) {
187 if (!m_delegateModel) {
184 createDelegateModel();
188 createDelegateModel();
185 } else {
189 } else {
190+#if (QT_VERSION < QT_VERSION_CHECK(5, 1, 0))
186 disconnect(m_delegateModel, SIGNAL(modelUpdated(QQuickChangeSet,bool)), this, SLOT(onModelUpdated(QQuickChangeSet,bool)));
191 disconnect(m_delegateModel, SIGNAL(modelUpdated(QQuickChangeSet,bool)), this, SLOT(onModelUpdated(QQuickChangeSet,bool)));
187 }
192 }
188 m_delegateModel->setModel(QVariant::fromValue<QAbstractItemModel *>(model));
193 m_delegateModel->setModel(QVariant::fromValue<QAbstractItemModel *>(model));
189 connect(m_delegateModel, SIGNAL(modelUpdated(QQuickChangeSet,bool)), this, SLOT(onModelUpdated(QQuickChangeSet,bool)));
194 connect(m_delegateModel, SIGNAL(modelUpdated(QQuickChangeSet,bool)), this, SLOT(onModelUpdated(QQuickChangeSet,bool)));
195+#else
196+ disconnect(m_delegateModel, SIGNAL(modelUpdated(QQmlChangeSet,bool)), this, SLOT(onModelUpdated(QQmlChangeSet,bool)));
197+ }
198+ m_delegateModel->setModel(QVariant::fromValue<QAbstractItemModel *>(model));
199+ connect(m_delegateModel, SIGNAL(modelUpdated(QQmlChangeSet,bool)), this, SLOT(onModelUpdated(QQmlChangeSet,bool)));
200+#endif
190 Q_EMIT modelChanged();
201 Q_EMIT modelChanged();
191 // TODO?
202 // TODO?
192// Q_EMIT contentHeightChanged();
203// Q_EMIT contentHeightChanged();
@@ -269,7 +280,7 @@ void ListViewWithPageHeader::setSectionDelegate(QQmlComponent *delegate)
269
280
270 m_sectionDelegate = delegate;
281 m_sectionDelegate = delegate;
271
282
272− m_topSectionItem = getSectionItem(QString());
283+ m_topSectionItem = getSectionItem(-1, QString());
273 m_topSectionItem->setZ(3);
284 m_topSectionItem->setZ(3);
274 QQuickItemPrivate::get(m_topSectionItem)->setCulled(true);
285 QQuickItemPrivate::get(m_topSectionItem)->setCulled(true);
275
286
@@ -446,8 +457,13 @@ void ListViewWithPageHeader::viewportMoved(Qt::Orientations orient)
446
457
447void ListViewWithPageHeader::createDelegateModel()
458void ListViewWithPageHeader::createDelegateModel()
448{
459{
460+#if (QT_VERSION < QT_VERSION_CHECK(5, 1, 0))
449 m_delegateModel = new QQuickVisualDataModel(qmlContext(this), this);
461 m_delegateModel = new QQuickVisualDataModel(qmlContext(this), this);
450 connect(m_delegateModel, SIGNAL(createdItem(int,QQuickItem*)), this, SLOT(itemCreated(int,QQuickItem*)));
462 connect(m_delegateModel, SIGNAL(createdItem(int,QQuickItem*)), this, SLOT(itemCreated(int,QQuickItem*)));
463+#else
464+ m_delegateModel = new QQmlDelegateModel(qmlContext(this), this);
465+ connect(m_delegateModel, SIGNAL(createdItem(int,QObject*)), this, SLOT(itemCreated(int,QObject*)));
466+#endif
451 if (isComponentComplete())
467 if (isComponentComplete())
452 m_delegateModel->componentComplete();
468 m_delegateModel->componentComplete();
453 updateWatchedRoles();
469 updateWatchedRoles();
@@ -528,8 +544,13 @@ bool ListViewWithPageHeader::addVisibleItems(qreal fillFrom, qreal fillTo, bool
528void ListViewWithPageHeader::reallyReleaseItem(ListItem *listItem)
544void ListViewWithPageHeader::reallyReleaseItem(ListItem *listItem)
529{
545{
530 QQuickItem *item = listItem->m_item;
546 QQuickItem *item = listItem->m_item;
547+#if (QT_VERSION < QT_VERSION_CHECK(5, 1, 0))
531 QQuickVisualModel::ReleaseFlags flags = m_delegateModel->release(item);
548 QQuickVisualModel::ReleaseFlags flags = m_delegateModel->release(item);
532 if (flags & QQuickVisualModel::Destroyed) {
549 if (flags & QQuickVisualModel::Destroyed) {
550+#else
551+ QQmlDelegateModel::ReleaseFlags flags = m_delegateModel->release(item);
552+ if (flags & QQmlDelegateModel::Destroyed) {
553+#endif
533 item->setParentItem(nullptr);
554 item->setParentItem(nullptr);
534 }
555 }
535 delete listItem->m_sectionItem;
556 delete listItem->m_sectionItem;
@@ -578,16 +599,17 @@ QQuickItem *ListViewWithPageHeader::getSectionItem(int modelIndex, bool alreadyI
578 }
599 }
579 }
600 }
580
601
581− return getSectionItem(section);
602+ return getSectionItem(modelIndex, section);
582}
603}
583
604
584−QQuickItem *ListViewWithPageHeader::getSectionItem(const QString &sectionText)
605+QQuickItem *ListViewWithPageHeader::getSectionItem(int modelIndex, const QString &sectionText)
585{
606{
586 QQuickItem *sectionItem = nullptr;
607 QQuickItem *sectionItem = nullptr;
587
608
588 QQmlContext *creationContext = m_sectionDelegate->creationContext();
609 QQmlContext *creationContext = m_sectionDelegate->creationContext();
589 QQmlContext *context = new QQmlContext(creationContext ? creationContext : qmlContext(this));
610 QQmlContext *context = new QQmlContext(creationContext ? creationContext : qmlContext(this));
590 context->setContextProperty(QLatin1String("section"), sectionText);
611 context->setContextProperty(QLatin1String("section"), sectionText);
612+ context->setContextProperty(QLatin1String("delegateIndex"), modelIndex);
591 QObject *nobj = m_sectionDelegate->beginCreate(context);
613 QObject *nobj = m_sectionDelegate->beginCreate(context);
592 if (nobj) {
614 if (nobj) {
593 QQml_setParent_noEvent(context, nobj);
615 QQml_setParent_noEvent(context, nobj);
@@ -658,9 +680,27 @@ ListViewWithPageHeader::ListItem *ListViewWithPageHeader::createItem(int modelIn
658 return nullptr;
680 return nullptr;
659
681
660 m_asyncRequestedIndex = -1;
682 m_asyncRequestedIndex = -1;
683+#if (QT_VERSION < QT_VERSION_CHECK(5, 1, 0))
661 QQuickItem *item = m_delegateModel->item(modelIndex, asynchronous);
684 QQuickItem *item = m_delegateModel->item(modelIndex, asynchronous);
685+#else
686+ QObject* object = m_delegateModel->object(modelIndex, asynchronous);
687+ QQuickItem *item = qmlobject_cast<QQuickItem*>(object);
688+#endif
662 if (!item) {
689 if (!item) {
690+#if (QT_VERSION < QT_VERSION_CHECK(5, 1, 0))
663 m_asyncRequestedIndex = modelIndex;
691 m_asyncRequestedIndex = modelIndex;
692+#else
693+ if (object) {
694+ m_delegateModel->release(object);
695+ if (!m_delegateValidated) {
696+ m_delegateValidated = true;
697+ QObject* delegateObj = delegate();
698+ qmlInfo(delegateObj ? delegateObj : this) << "Delegate must be of Item type";
699+ }
700+ } else {
701+ m_asyncRequestedIndex = modelIndex;
702+ }
703+#endif
664 return 0;
704 return 0;
665 } else {
705 } else {
666// qDebug() << "ListViewWithPageHeader::createItem::We have the item" << modelIndex << item;
706// qDebug() << "ListViewWithPageHeader::createItem::We have the item" << modelIndex << item;
@@ -711,8 +751,18 @@ ListViewWithPageHeader::ListItem *ListViewWithPageHeader::createItem(int modelIn
711 }
751 }
712}
752}
713
753
754+#if (QT_VERSION < QT_VERSION_CHECK(5, 1, 0))
714void ListViewWithPageHeader::itemCreated(int modelIndex, QQuickItem *item)
755void ListViewWithPageHeader::itemCreated(int modelIndex, QQuickItem *item)
715{
756{
757+#else
758+void ListViewWithPageHeader::itemCreated(int modelIndex, QObject *object)
759+{
760+ QQuickItem *item = qmlobject_cast<QQuickItem*>(object);
761+ if (!item) {
762+ qWarning() << "ListViewWithPageHeader::itemCreated got a non item for index" << modelIndex;
763+ return;
764+ }
765+#endif
716// qDebug() << "ListViewWithPageHeader::itemCreated" << modelIndex << item;
766// qDebug() << "ListViewWithPageHeader::itemCreated" << modelIndex << item;
717
767
718 item->setParentItem(m_clipItem);
768 item->setParentItem(m_clipItem);
@@ -747,13 +797,22 @@ void ListViewWithPageHeader::onHeightChanged()
747 polish();
797 polish();
748}
798}
749
799
800+
801+#if (QT_VERSION < QT_VERSION_CHECK(5, 1, 0))
750void ListViewWithPageHeader::onModelUpdated(const QQuickChangeSet &changeSet, bool /*reset*/)
802void ListViewWithPageHeader::onModelUpdated(const QQuickChangeSet &changeSet, bool /*reset*/)
803+#else
804+void ListViewWithPageHeader::onModelUpdated(const QQmlChangeSet &changeSet, bool /*reset*/)
805+#endif
751{
806{
752 // TODO Do something with reset
807 // TODO Do something with reset
753// qDebug() << "ListViewWithPageHeader::onModelUpdated" << changeSet << reset;
808// qDebug() << "ListViewWithPageHeader::onModelUpdated" << changeSet << reset;
754 const auto oldFirstVisibleIndex = m_firstVisibleIndex;
809 const auto oldFirstVisibleIndex = m_firstVisibleIndex;
755
810
811+#if (QT_VERSION < QT_VERSION_CHECK(5, 1, 0))
756 Q_FOREACH(const QQuickChangeSet::Remove &remove, changeSet.removes()) {
812 Q_FOREACH(const QQuickChangeSet::Remove &remove, changeSet.removes()) {
813+#else
814+ Q_FOREACH(const QQmlChangeSet::Remove &remove, changeSet.removes()) {
815+#endif
757// qDebug() << "ListViewWithPageHeader::onModelUpdated Remove" << remove.index << remove.count;
816// qDebug() << "ListViewWithPageHeader::onModelUpdated Remove" << remove.index << remove.count;
758 if (remove.index + remove.count > m_firstVisibleIndex && remove.index < m_firstVisibleIndex + m_visibleItems.count()) {
817 if (remove.index + remove.count > m_firstVisibleIndex && remove.index < m_firstVisibleIndex + m_visibleItems.count()) {
759 const qreal oldFirstValidIndexPos = m_visibleItems.first()->y();
818 const qreal oldFirstValidIndexPos = m_visibleItems.first()->y();
@@ -785,10 +844,14 @@ void ListViewWithPageHeader::onModelUpdated(const QQuickChangeSet &changeSet, bo
785 }
844 }
786 if (growDown) {
845 if (growDown) {
787 adjustMinYExtent();
846 adjustMinYExtent();
788− } else if (remove.index <= m_firstVisibleIndex && !m_visibleItems.isEmpty()) {
847+ } else if (remove.index <= m_firstVisibleIndex) {
848+ if (!m_visibleItems.isEmpty()) {
789− // We removed the first item that is the one that positions the rest
849+ // We removed the first item that is the one that positions the rest
790− // position the new first item correctly
850+ // position the new first item correctly
791− m_visibleItems.first()->setY(oldFirstValidIndexPos);
851+ m_visibleItems.first()->setY(oldFirstValidIndexPos);
852+ } else {
853+ m_firstVisibleIndex = -1;
854+ }
792 }
855 }
793 } else if (remove.index + remove.count <= m_firstVisibleIndex) {
856 } else if (remove.index + remove.count <= m_firstVisibleIndex) {
794 m_firstVisibleIndex -= remove.count;
857 m_firstVisibleIndex -= remove.count;
@@ -803,10 +866,14 @@ void ListViewWithPageHeader::onModelUpdated(const QQuickChangeSet &changeSet, bo
803 }
866 }
804 }
867 }
805
868
869+#if (QT_VERSION < QT_VERSION_CHECK(5, 1, 0))
806 Q_FOREACH(const QQuickChangeSet::Insert &insert, changeSet.inserts()) {
870 Q_FOREACH(const QQuickChangeSet::Insert &insert, changeSet.inserts()) {
871+#else
872+ Q_FOREACH(const QQmlChangeSet::Insert &insert, changeSet.inserts()) {
873+#endif
807// qDebug() << "ListViewWithPageHeader::onModelUpdated Insert" << insert.index << insert.count;
874// qDebug() << "ListViewWithPageHeader::onModelUpdated Insert" << insert.index << insert.count;
808 const bool insertingInValidIndexes = insert.index > m_firstVisibleIndex && insert.index < m_firstVisibleIndex + m_visibleItems.count();
875 const bool insertingInValidIndexes = insert.index > m_firstVisibleIndex && insert.index < m_firstVisibleIndex + m_visibleItems.count();
809− const bool firstItemWithViewOnTop = insert.index == 0 && m_firstVisibleIndex == 0 && !m_visibleItems.isEmpty() && m_visibleItems.first()->y() + m_clipItem->y() > contentY();
876+ const bool firstItemWithViewOnTop = insert.index == 0 && m_firstVisibleIndex == 0 && m_visibleItems.first()->y() + m_clipItem->y() > contentY();
810 if (insertingInValidIndexes || firstItemWithViewOnTop)
877 if (insertingInValidIndexes || firstItemWithViewOnTop)
811 {
878 {
812 // If the items we are adding won't be really visible
879 // If the items we are adding won't be really visible
@@ -866,6 +933,14 @@ void ListViewWithPageHeader::onModelUpdated(const QQuickChangeSet &changeSet, bo
866 adjustMinYExtent();
933 adjustMinYExtent();
867 }
934 }
868
935
936+ for (int i = 0; i < m_visibleItems.count(); ++i) {
937+ ListItem *item = m_visibleItems[i];
938+ if (item->m_sectionItem) {
939+ QQmlContext *context = QQmlEngine::contextForObject(item->m_sectionItem)->parentContext();
940+ context->setContextProperty(QLatin1String("delegateIndex"), m_firstVisibleIndex + i);
941+ }
942+ }
943+
869 layout();
944 layout();
870 polish();
945 polish();
871 m_contentHeightDirty = true;
946 m_contentHeightDirty = true;
@@ -971,11 +1046,6 @@ void ListViewWithPageHeader::layout()
971 if (!cull && firstReallyVisibleItem == -1) {
1046 if (!cull && firstReallyVisibleItem == -1) {
972 firstReallyVisibleItem = modelIndex;
1047 firstReallyVisibleItem = modelIndex;
973 if (m_topSectionItem) {
1048 if (m_topSectionItem) {
974− // Update the top sticky section header
975− const QString section = m_delegateModel->stringValue(modelIndex, m_sectionProperty);
976− QQmlContext *context = QQmlEngine::contextForObject(m_topSectionItem)->parentContext();
977− context->setContextProperty(QLatin1String("section"), section);
978−
979 // Positing the top section sticky item is a two step process
1049 // Positing the top section sticky item is a two step process
980 // First we set it either we cull it (because it doesn't need to be sticked to the top)
1050 // First we set it either we cull it (because it doesn't need to be sticked to the top)
981 // or stick it to the top
1051 // or stick it to the top
@@ -992,8 +1062,22 @@ void ListViewWithPageHeader::layout()
992 QQuickItemPrivate::get(item->m_sectionItem)->setCulled(false);
1062 QQuickItemPrivate::get(item->m_sectionItem)->setCulled(false);
993 }
1063 }
994 } else {
1064 } else {
1065+ // Update the top sticky section header
1066+ const QString section = m_delegateModel->stringValue(modelIndex, m_sectionProperty);
1067+ QQmlContext *context = QQmlEngine::contextForObject(m_topSectionItem)->parentContext();
1068+ context->setContextProperty(QLatin1String("section"), section);
1069+
995 QQuickItemPrivate::get(m_topSectionItem)->setCulled(false);
1070 QQuickItemPrivate::get(m_topSectionItem)->setCulled(false);
996 m_topSectionItem->setY(topSectionStickPos);
1071 m_topSectionItem->setY(topSectionStickPos);
1072+ int delegateIndex = modelIndex;
1073+ // Look for the first index with this section text
1074+ while (delegateIndex > 0) {
1075+ const QString prevSection = m_delegateModel->stringValue(delegateIndex - 1, m_sectionProperty);
1076+ if (prevSection != section)
1077+ break;
1078+ delegateIndex--;
1079+ }
1080+ context->setContextProperty(QLatin1String("delegateIndex"), delegateIndex);
997 if (item->m_sectionItem) {
1081 if (item->m_sectionItem) {
998 QQuickItemPrivate::get(item->m_sectionItem)->setCulled(true);
1082 QQuickItemPrivate::get(item->m_sectionItem)->setCulled(true);
999 }
1083 }
plugins/ListViewWithPageHeader/listviewwithpageheader.h+19−2
@@ -24,9 +24,14 @@
24#pragma GCC diagnostic pop
24#pragma GCC diagnostic pop
25
25
26class QAbstractItemModel;
26class QAbstractItemModel;
27−class QQuickChangeSet;
28class QQuickNumberAnimation;
27class QQuickNumberAnimation;
28+#if (QT_VERSION < QT_VERSION_CHECK(5, 1, 0))
29+class QQuickChangeSet;
29class QQuickVisualDataModel;
30class QQuickVisualDataModel;
31+#else
32+class QQmlChangeSet;
33+class QQmlDelegateModel;
34+#endif
30
35
31
36
32/**
37/**
@@ -100,11 +105,19 @@ protected:
100 void updatePolish();
105 void updatePolish();
101
106
102private Q_SLOTS:
107private Q_SLOTS:
108+#if (QT_VERSION < QT_VERSION_CHECK(5, 1, 0))
103 void itemCreated(int modelIndex, QQuickItem *item);
109 void itemCreated(int modelIndex, QQuickItem *item);
110+#else
111+ void itemCreated(int modelIndex, QObject *object);
112+#endif
104 void onContentHeightChanged();
113 void onContentHeightChanged();
105 void onContentWidthChanged();
114 void onContentWidthChanged();
106 void onHeightChanged();
115 void onHeightChanged();
116+#if (QT_VERSION < QT_VERSION_CHECK(5, 1, 0))
107 void onModelUpdated(const QQuickChangeSet &changeSet, bool reset);
117 void onModelUpdated(const QQuickChangeSet &changeSet, bool reset);
118+#else
119+ void onModelUpdated(const QQmlChangeSet &changeSet, bool reset);
120+#endif
108 void onShowHeaderAnimationFinished();
121 void onShowHeaderAnimationFinished();
109
122
110private:
123private:
@@ -139,9 +152,13 @@ private:
139 void reallyReleaseItem(ListItem *item);
152 void reallyReleaseItem(ListItem *item);
140 void updateWatchedRoles();
153 void updateWatchedRoles();
141 QQuickItem *getSectionItem(int modelIndex, bool alreadyInserted);
154 QQuickItem *getSectionItem(int modelIndex, bool alreadyInserted);
142− QQuickItem *getSectionItem(const QString &sectionText);
155+ QQuickItem *getSectionItem(int modelIndex, const QString &sectionText);
143
156
157+#if (QT_VERSION < QT_VERSION_CHECK(5, 1, 0))
144 QQuickVisualDataModel *m_delegateModel;
158 QQuickVisualDataModel *m_delegateModel;
159+#else
160+ QQmlDelegateModel *m_delegateModel;
161+#endif
145
162
146 // Index we are waiting because we requested it asynchronously
163 // Index we are waiting because we requested it asynchronously
147 int m_asyncRequestedIndex;
164 int m_asyncRequestedIndex;
plugins/Powerd/CMakeLists.txtnew file+13
@@ -0,0 +1,13 @@
1+include(Plugins)
2+
3+add_definitions(-DSM_BUSNAME=systemBus)
4+
5+add_library(Powerd-qml MODULE
6+ plugin.cpp
7+ Powerd.cpp
8+ )
9+
10+qt5_use_modules(Powerd-qml DBus Qml)
11+
12+export_qmlfiles(Powerd Powerd)
13+export_qmlplugin(Powerd 0.1 Powerd TARGETS Powerd-qml)
plugins/Powerd/Powerd.cppnew file+36
@@ -0,0 +1,36 @@
1+/*
2+ * Copyright (C) 2013 Canonical, Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ *
16+ * Author: Michael Terry <michael.terry@canonical.com>
17+ */
18+
19+#include "Powerd.h"
20+
21+Powerd::Powerd(QObject* parent)
22+ : QObject(parent),
23+ powerd(NULL)
24+{
25+ powerd = new QDBusInterface("com.canonical.powerd",
26+ "/com/canonical/powerd",
27+ "com.canonical.powerd",
28+ QDBusConnection::SM_BUSNAME(), this);
29+
30+ powerd->connection().connect("com.canonical.powerd",
31+ "/com/canonical/powerd",
32+ "com.canonical.powerd",
33+ "SysPowerStateChange",
34+ this,
35+ SIGNAL(powerStateChange(int)));
36+}
plugins/Powerd/Powerd.hnew file+40
@@ -0,0 +1,40 @@
1+/*
2+ * Copyright (C) 2012,2013 Canonical, Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ *
16+ * Authors: Gerry Boland <gerry.boland@canonical.com>
17+ * Michael Terry <michael.terry@canonical.com>
18+ */
19+
20+#ifndef UNITY_POWERD_H
21+#define UNITY_POWERD_H
22+
23+#include <QtCore/QObject>
24+#include <QtDBus/QDBusInterface>
25+
26+class Powerd: public QObject
27+{
28+ Q_OBJECT
29+
30+public:
31+ explicit Powerd(QObject *parent = 0);
32+
33+Q_SIGNALS:
34+ void powerStateChange(int state);
35+
36+private:
37+ QDBusInterface *powerd;
38+};
39+
40+#endif
plugins/Powerd/plugin.cppnew file+36
@@ -0,0 +1,36 @@
1+/*
2+ * Copyright (C) 2012,2013 Canonical, Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ *
16+ * Authors: Gerry Boland <gerry.boland@canonical.com>
17+ * Michael Terry <michael.terry@canonical.com>
18+ */
19+
20+#include "plugin.h"
21+#include "Powerd.h"
22+
23+#include <QtQml/QtQml>
24+
25+static QObject *powerd_provider(QQmlEngine *engine, QJSEngine *scriptEngine)
26+{
27+ Q_UNUSED(engine)
28+ Q_UNUSED(scriptEngine)
29+ return new Powerd();
30+}
31+
32+void PowerdPlugin::registerTypes(const char *uri)
33+{
34+ Q_ASSERT(uri == QLatin1String("Powerd"));
35+ qmlRegisterSingletonType<Powerd>(uri, 0, 1, "Powerd", powerd_provider);
36+}
plugins/Powerd/plugin.hnew file+35
@@ -0,0 +1,35 @@
1+/*
2+ * Copyright (C) 2012,2013 Canonical, Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ *
16+ * Authors: Gerry Boland <gerry.boland@canonical.com>
17+ * Michael Terry <michael.terry@canonical.com>
18+ */
19+
20+#ifndef POWER_PLUGIN_H
21+#define POWER_PLUGIN_H
22+
23+#include <QtQml/QQmlEngine>
24+#include <QtQml/QQmlExtensionPlugin>
25+
26+class PowerdPlugin : public QQmlExtensionPlugin
27+{
28+ Q_OBJECT
29+ Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QQmlExtensionInterface")
30+
31+public:
32+ void registerTypes(const char *uri);
33+};
34+
35+#endif
plugins/Powerd/qmldirnew file+3
@@ -0,0 +1,3 @@
1+module Powerd
2+plugin Powerd-qml
3+typeinfo plugin.qmltypes
plugins/Unity/CMakeLists.txt+1−1
@@ -5,7 +5,7 @@ add_subdirectory(Indicators)
5
5
6# Dependencies
6# Dependencies
7include(FindPkgConfig)
7include(FindPkgConfig)
8−pkg_check_modules(QTDEE REQUIRED libdee-qt5)
8+pkg_check_modules(QTDEE REQUIRED libdee-qt5>=3.2)
9pkg_check_modules(UNITYCORE REQUIRED unity-core-6.0)
9pkg_check_modules(UNITYCORE REQUIRED unity-core-6.0)
10
10
11include_directories(
11include_directories(
plugins/Unity/Indicators/CMakeLists.txt+1
@@ -24,6 +24,7 @@ set(IndicatorsQML_SOURCES
24 indicatorsmanager.cpp
24 indicatorsmanager.cpp
25 indicatorsmodel.cpp
25 indicatorsmodel.cpp
26 menucontentactivator.cpp
26 menucontentactivator.cpp
27+ modelprinter.cpp
27 plugin.cpp
28 plugin.cpp
28)
29)
29add_definitions(-DUNITYINDICATORS_LIBRARY)
30add_definitions(-DUNITYINDICATORS_LIBRARY)
plugins/Unity/Indicators/modelprinter.cppnew file+114
@@ -0,0 +1,114 @@
1+/*
2+ * Copyright 2013 Canonical Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU Lesser General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU Lesser General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU Lesser General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ *
16+ * Authors:
17+ * Nick Dedekind <nick.dedekind@canonical.com>
18+ */
19+
20+// self
21+#include "modelprinter.h"
22+
23+// Qt
24+#include <QTextStream>
25+
26+ModelPrinter::ModelPrinter(QObject *parent)
27+ : QObject(parent)
28+ , m_model(NULL)
29+{
30+}
31+
32+void ModelPrinter::setSourceModel(QAbstractItemModel * sourceModel)
33+{
34+ if (m_model != NULL) {
35+ disconnect(m_model);
36+ }
37+ if (m_model != sourceModel) {
38+ m_model = sourceModel;
39+ Q_EMIT modelChanged();
40+ Q_EMIT textChanged();
41+ }
42+ if (m_model != NULL) {
43+ connect(m_model, SIGNAL(modelReset()), this, SIGNAL(textChanged()));
44+ connect(m_model, SIGNAL(rowsInserted(QModelIndex,int,int)), this, SIGNAL(textChanged()));
45+ connect(m_model, SIGNAL(rowsRemoved(QModelIndex,int,int)), this, SIGNAL(textChanged()));
46+ }
47+}
48+
49+QAbstractItemModel* ModelPrinter::sourceModel() const
50+{
51+ return m_model;
52+}
53+
54+QString ModelPrinter::text(const QModelIndex& index) const
55+{
56+ return recurseString(index, 0);
57+}
58+
59+QString tabify(int level) { QString str;
60+ for (int i = 0; i < level; i++) {
61+ str += " ";
62+ }
63+ return str;
64+}
65+
66+QString ModelPrinter::recurseString(const QModelIndex& index, int level) const
67+{
68+ if (!m_model)
69+ return "";
70+
71+ QString str;
72+ QTextStream stream(&str);
73+
74+ QHash<int, QByteArray> roleNames = m_model->roleNames();
75+ QList<int> roles = roleNames.keys();
76+ qSort(roles);
77+ Q_FOREACH(int role, roles) {
78+ QVariant vData = m_model->data(index, role);
79+ if (vData.canConvert(QMetaType::QVariantMap)) {
80+ QMapIterator<QString, QVariant> iter(vData.toMap());
81+ while (iter.hasNext()) {
82+ iter.next();
83+ stream << tabify(level)
84+ << roleNames[role]
85+ << "."
86+ << iter.key()
87+ << ": "
88+ << iter.value().toString()
89+ << endl;
90+ }
91+ }
92+ else {
93+ stream << tabify(level)
94+ << roleNames[role]
95+ << ": "
96+ << vData.toString()
97+ << endl;
98+ }
99+ }
100+
101+ int rowCount = m_model->rowCount(index);
102+ stream << tabify(level)
103+ << "child count"
104+ << ": "
105+ << rowCount
106+ << endl
107+ << endl;
108+
109+ for (int i = 0; i < rowCount; i++) {
110+ QModelIndex child = m_model->index(i, 0, index);
111+ str += recurseString(child, level+1);
112+ }
113+ return str;
114+}
plugins/Unity/Indicators/modelprinter.hnew file+50
@@ -0,0 +1,50 @@
1+/*
2+ * Copyright 2013 Canonical Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU Lesser General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU Lesser General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU Lesser General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ *
16+ * Authors:
17+ * Nick Dedekind <nick.dedekind@canonical.com>
18+ */
19+
20+#ifndef MODELPRINTER_H
21+#define MODELPRINTER_H
22+
23+#include <QSortFilterProxyModel>
24+
25+// This class acts as a namespace only, with the addition that its enums
26+// are registered to be exposed on the QML side.
27+class ModelPrinter : public QObject
28+{
29+ Q_OBJECT
30+
31+ Q_PROPERTY(QAbstractItemModel* model READ sourceModel WRITE setSourceModel NOTIFY modelChanged)
32+ Q_PROPERTY(QString text READ text NOTIFY textChanged)
33+public:
34+ ModelPrinter(QObject* parent=0);
35+
36+ void setSourceModel(QAbstractItemModel* sourceModel);
37+ QAbstractItemModel* sourceModel() const;
38+
39+ Q_INVOKABLE QString text(const QModelIndex& index = QModelIndex()) const;
40+
41+Q_SIGNALS:
42+ void modelChanged();
43+ void textChanged();
44+
45+private:
46+ QString recurseString(const QModelIndex& index, int level) const;
47+ QAbstractItemModel* m_model;
48+};
49+
50+#endif // MODELPRINTER_H
plugins/Unity/Indicators/plugin.cpp+2
@@ -28,6 +28,7 @@
28#include "indicatorsmodel.h"
28#include "indicatorsmodel.h"
29#include "indicators.h"
29#include "indicators.h"
30#include "menucontentactivator.h"
30#include "menucontentactivator.h"
31+#include "modelprinter.h"
31
32
32void IndicatorsPlugin::registerTypes(const char *uri)
33void IndicatorsPlugin::registerTypes(const char *uri)
33{
34{
@@ -36,6 +37,7 @@ void IndicatorsPlugin::registerTypes(const char *uri)
36 qmlRegisterType<IndicatorsManager>(uri, 0, 1, "IndicatorsManager");
37 qmlRegisterType<IndicatorsManager>(uri, 0, 1, "IndicatorsManager");
37 qmlRegisterType<FlatMenuProxyModel>(uri, 0, 1, "FlatMenuProxyModel");
38 qmlRegisterType<FlatMenuProxyModel>(uri, 0, 1, "FlatMenuProxyModel");
38 qmlRegisterType<IndicatorsModel>(uri, 0, 1, "IndicatorsModel");
39 qmlRegisterType<IndicatorsModel>(uri, 0, 1, "IndicatorsModel");
40+ qmlRegisterType<ModelPrinter>(uri, 0, 1, "ModelPrinter");
39 qmlRegisterType<MenuContentActivator>(uri, 0, 1, "MenuContentActivator");
41 qmlRegisterType<MenuContentActivator>(uri, 0, 1, "MenuContentActivator");
40
42
41 qmlRegisterUncreatableType<MenuContentState>(uri, 0, 1, "MenuContentState", "Can't create MenuContentState class");
43 qmlRegisterUncreatableType<MenuContentState>(uri, 0, 1, "MenuContentState", "Can't create MenuContentState class");
plugins/Unity/categories.cpp+6−3
@@ -34,7 +34,7 @@ enum CategoryColumn {
34Categories::Categories(QObject* parent)
34Categories::Categories(QObject* parent)
35 : DeeListModel(parent)
35 : DeeListModel(parent)
36{
36{
37− m_roles[Categories::RoleId] = "id";
37+ m_roles[Categories::RoleCategoryId] = "categoryId";
38 m_roles[Categories::RoleName] = "name";
38 m_roles[Categories::RoleName] = "name";
39 m_roles[Categories::RoleIcon] = "icon";
39 m_roles[Categories::RoleIcon] = "icon";
40 m_roles[Categories::RoleRenderer] = "renderer";
40 m_roles[Categories::RoleRenderer] = "renderer";
@@ -42,6 +42,7 @@ Categories::Categories(QObject* parent)
42 m_roles[Categories::RoleHints] = "hints";
42 m_roles[Categories::RoleHints] = "hints";
43 m_roles[Categories::RoleResults] = "results";
43 m_roles[Categories::RoleResults] = "results";
44 m_roles[Categories::RoleCount] = "count";
44 m_roles[Categories::RoleCount] = "count";
45+ m_roles[Categories::RoleCategoryIndex] = "categoryIndex";
45
46
46 // TODO This should not be needed but accumulatting the count changes
47 // TODO This should not be needed but accumulatting the count changes
47 // makes the visualization more stable and also makes crashes on fast
48 // makes the visualization more stable and also makes crashes on fast
@@ -130,8 +131,8 @@ Categories::data(const QModelIndex& index, int role) const
130 }
131 }
131
132
132 switch (role) {
133 switch (role) {
133− case RoleId:
134+ case RoleCategoryId:
134− return QVariant::fromValue(index.row());
135+ return DeeListModel::data(index, CategoryColumn::ID);
135 case RoleName:
136 case RoleName:
136 return DeeListModel::data(index, CategoryColumn::DISPLAY_NAME);
137 return DeeListModel::data(index, CategoryColumn::DISPLAY_NAME);
137 case RoleIcon:
138 case RoleIcon:
@@ -149,6 +150,8 @@ Categories::data(const QModelIndex& index, int role) const
149 return QVariant::fromValue(getResults(index.row()));
150 return QVariant::fromValue(getResults(index.row()));
150 case RoleCount:
151 case RoleCount:
151 return QVariant::fromValue(getResults(index.row())->rowCount());
152 return QVariant::fromValue(getResults(index.row())->rowCount());
153+ case RoleCategoryIndex:
154+ return QVariant::fromValue(index.row());
152 default:
155 default:
153 return QVariant();
156 return QVariant();
154 }
157 }
plugins/Unity/categories.h+3−2
@@ -42,14 +42,15 @@ public:
42 explicit Categories(QObject* parent = 0);
42 explicit Categories(QObject* parent = 0);
43
43
44 enum Roles {
44 enum Roles {
45− RoleId,
45+ RoleCategoryId,
46 RoleName,
46 RoleName,
47 RoleIcon,
47 RoleIcon,
48 RoleRenderer,
48 RoleRenderer,
49 RoleContentType,
49 RoleContentType,
50 RoleHints,
50 RoleHints,
51 RoleResults,
51 RoleResults,
52− RoleCount
52+ RoleCount,
53+ RoleCategoryIndex
53 };
54 };
54
55
55 QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const;
56 QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const;
plugins/Unity/previewinfohint.cpp+2−2
@@ -17,9 +17,9 @@
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 */
18 */
19
19
20+#include <deelistmodel.h>
20// local
21// local
21#include "previewinfohint.h"
22#include "previewinfohint.h"
22−#include "variantutils.h"
23
23
24PreviewInfoHint::PreviewInfoHint(QObject *parent):
24PreviewInfoHint::PreviewInfoHint(QObject *parent):
25 QObject(parent),
25 QObject(parent),
@@ -61,7 +61,7 @@ QString PreviewInfoHint::iconHint() const
61QVariant PreviewInfoHint::value() const
61QVariant PreviewInfoHint::value() const
62{
62{
63 if (m_unityInfoHint) {
63 if (m_unityInfoHint) {
64− return QVariantFromGVariant(m_unityInfoHint->value);
64+ return DeeListModel::VariantForData(m_unityInfoHint->value);
65 }
65 }
66 return QVariant();
66 return QVariant();
67}
67}
plugins/Unity/scope.h−3
@@ -29,9 +29,6 @@
29#include <UnityCore/Scope.h>
29#include <UnityCore/Scope.h>
30#include <UnityCore/Results.h>
30#include <UnityCore/Results.h>
31
31
32−// dee-qt
33−#include "deelistmodel.h"
34−
35#include "categories.h"
32#include "categories.h"
36
33
37class Preview;
34class Preview;
plugins/Unity/variantutils.cpp+2−118
@@ -17,131 +17,15 @@
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 */
18 */
19
19
20+#include <deelistmodel.h>
20#include "variantutils.h"
21#include "variantutils.h"
21
22
22−/* Returns floating ref */
23−GVariant* GVariantFromQVariant(const QVariant &var)
24−{
25− GVariant *gv = nullptr;
26−
27− switch (var.type()) {
28− case QVariant::String:
29− gv = g_variant_new_string(var.toString().toUtf8());
30− break;
31− case QVariant::UInt:
32− gv = g_variant_new_uint32(var.toUInt());
33− break;
34− case QVariant::Int:
35− gv = g_variant_new_int32(var.toInt());
36− break;
37− case QVariant::LongLong:
38− gv = g_variant_new_int64(var.toLongLong());
39− break;
40− case QVariant::ULongLong:
41− gv = g_variant_new_uint64(var.toULongLong());
42− break;
43− case QVariant::Double:
44− gv = g_variant_new_double(var.toDouble());
45− break;
46− case QVariant::Bool:
47− gv = g_variant_new_boolean(var.toBool());
48− break;
49− case QVariant::Hash: {
50− const auto hash = var.toHash();
51− GVariant **children = new GVariant*[hash.size()];
52− int cnt = 0;
53− QHash<QString, QVariant>::const_iterator it = hash.constBegin();
54− while (it != hash.constEnd()) {
55− GVariant *key = g_variant_new_string(it.key().toUtf8());
56− children[cnt++] = g_variant_new_dict_entry(key, g_variant_new_variant(GVariantFromQVariant(it.value())));
57− ++it;
58− }
59− gv = g_variant_new_array(G_VARIANT_TYPE("{sv}"), children, hash.size());
60− delete [] children;
61− break;
62− }
63− default:
64− break;
65− }
66− return gv;
67−}
68−
69−// implementation of this conversion taken from libdee-qt private utility function.
70−QVariant QVariantFromGVariant(GVariant *value)
71−{
72− /* We need to special-case a{sv} here as G_VARIANT_CLASS_ARRAY handles simple arrays;
73− we need to create QVariantHash, not a list */
74− if (g_variant_is_of_type(value, G_VARIANT_TYPE_VARDICT)) {
75− const gsize nChildren = g_variant_n_children(value);
76− QVariantHash hash;
77− for (gsize i = 0; i < nChildren; ++i)
78− {
79− GVariant* dict_entry = g_variant_get_child_value(value, i);
80−
81− gchar* dict_key;
82− GVariant *dict_var;
83− g_variant_get(dict_entry, "{&sv}", &dict_key, &dict_var);
84− hash.insert(QString::fromUtf8(dict_key), QVariantFromGVariant(dict_var));
85− g_variant_unref(dict_var);
86− g_variant_unref(dict_entry);
87− }
88− return hash;
89− }
90−
91− switch (g_variant_classify(value)) {
92− case G_VARIANT_CLASS_BOOLEAN:
93− return QVariant((bool) g_variant_get_boolean(value));
94− case G_VARIANT_CLASS_BYTE:
95− return QVariant((uchar) g_variant_get_byte(value));
96− case G_VARIANT_CLASS_INT16:
97− return QVariant((qint16) g_variant_get_int16(value));
98− case G_VARIANT_CLASS_UINT16:
99− return QVariant((quint16) g_variant_get_uint16(value));
100− case G_VARIANT_CLASS_INT32:
101− return QVariant((qint32) g_variant_get_int32(value));
102− case G_VARIANT_CLASS_UINT32:
103− return QVariant((quint32) g_variant_get_uint32(value));
104− case G_VARIANT_CLASS_INT64:
105− return QVariant((qint64) g_variant_get_int64(value));
106− case G_VARIANT_CLASS_UINT64:
107− return QVariant((quint64) g_variant_get_uint64(value));
108− case G_VARIANT_CLASS_DOUBLE:
109− return QVariant(g_variant_get_double(value));
110− case G_VARIANT_CLASS_STRING:
111− return QVariant(QString::fromUtf8(g_variant_get_string(value, NULL)));
112− case G_VARIANT_CLASS_ARRAY:
113− case G_VARIANT_CLASS_TUPLE:
114− {
115− const gsize nChildren = g_variant_n_children(value);
116− QList<QVariant> array;
117− for (gsize i = 0; i < nChildren; ++i)
118− {
119− GVariant* gvariant = g_variant_get_child_value(value, i);
120− array << QVariantFromGVariant(gvariant);
121− g_variant_unref(gvariant);
122− }
123− return array;
124− }
125− default:
126− /* Fallback on an empty QVariant.
127− FIXME: Missing conversion of following GVariant types:
128− - G_VARIANT_CLASS_HANDLE
129− - G_VARIANT_CLASS_OBJECT_PATH
130− - G_VARIANT_CLASS_SIGNATURE
131− - G_VARIANT_CLASS_VARIANT
132− - G_VARIANT_CLASS_MAYBE
133− - G_VARIANT_CLASS_DICT_ENTRY
134− */
135− return QVariant();
136− }
137−}
138−
139unity::glib::HintsMap convertToHintsMap(const QHash<QString, QVariant> &val)
23unity::glib::HintsMap convertToHintsMap(const QHash<QString, QVariant> &val)
140{
24{
141 unity::glib::HintsMap hintsMap;
25 unity::glib::HintsMap hintsMap;
142 QHash<QString, QVariant>::const_iterator it = val.constBegin();
26 QHash<QString, QVariant>::const_iterator it = val.constBegin();
143 while (it != val.constEnd()) {
27 while (it != val.constEnd()) {
144− hintsMap[it.key().toStdString()] = GVariantFromQVariant(it.value());
28+ hintsMap[it.key().toStdString()] = DeeListModel::DataFromVariant(it.value());
145 ++it;
29 ++it;
146 }
30 }
147 return hintsMap;
31 return hintsMap;
plugins/Unity/variantutils.h−2
@@ -26,8 +26,6 @@
26// libunity-core
26// libunity-core
27#include <UnityCore/Variant.h>
27#include <UnityCore/Variant.h>
28
28
29−GVariant* GVariantFromQVariant(const QVariant &value);
30−QVariant QVariantFromGVariant(GVariant *value);
31unity::glib::HintsMap convertToHintsMap(const QHash<QString, QVariant> &val);
29unity::glib::HintsMap convertToHintsMap(const QHash<QString, QVariant> &val);
32unity::glib::HintsMap convertToHintsMap(const QVariant &var);
30unity::glib::HintsMap convertToHintsMap(const QVariant &var);
33
31
po/ar.po+2−2
@@ -14,8 +14,8 @@ msgstr ""
14"MIME-Version: 1.0\n"
14"MIME-Version: 1.0\n"
15"Content-Type: text/plain; charset=UTF-8\n"
15"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Transfer-Encoding: 8bit\n"
16"Content-Transfer-Encoding: 8bit\n"
17−"X-Launchpad-Export-Date: 2013-07-17 07:49+0000\n"
17+"X-Launchpad-Export-Date: 2013-07-31 06:28+0000\n"
18−"X-Generator: Launchpad (build 16696)\n"
18+"X-Generator: Launchpad (build 16718)\n"
19
19
20#: Applications/applications.js:23
20#: Applications/applications.js:23
21msgid "Phone"
21msgid "Phone"
po/az.po+2−2
@@ -14,8 +14,8 @@ msgstr ""
14"MIME-Version: 1.0\n"
14"MIME-Version: 1.0\n"
15"Content-Type: text/plain; charset=UTF-8\n"
15"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Transfer-Encoding: 8bit\n"
16"Content-Transfer-Encoding: 8bit\n"
17−"X-Launchpad-Export-Date: 2013-07-17 07:49+0000\n"
17+"X-Launchpad-Export-Date: 2013-07-31 06:28+0000\n"
18−"X-Generator: Launchpad (build 16696)\n"
18+"X-Generator: Launchpad (build 16718)\n"
19
19
20#: Applications/applications.js:23
20#: Applications/applications.js:23
21msgid "Phone"
21msgid "Phone"
po/bg.po+2−2
@@ -15,8 +15,8 @@ msgstr ""
15"MIME-Version: 1.0\n"
15"MIME-Version: 1.0\n"
16"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Type: text/plain; charset=UTF-8\n"
17"Content-Transfer-Encoding: 8bit\n"
17"Content-Transfer-Encoding: 8bit\n"
18−"X-Launchpad-Export-Date: 2013-07-17 07:49+0000\n"
18+"X-Launchpad-Export-Date: 2013-07-31 06:28+0000\n"
19−"X-Generator: Launchpad (build 16696)\n"
19+"X-Generator: Launchpad (build 16718)\n"
20
20
21#: Applications/applications.js:23
21#: Applications/applications.js:23
22msgid "Phone"
22msgid "Phone"
po/ca.po+2−2
@@ -14,8 +14,8 @@ msgstr ""
14"MIME-Version: 1.0\n"
14"MIME-Version: 1.0\n"
15"Content-Type: text/plain; charset=UTF-8\n"
15"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Transfer-Encoding: 8bit\n"
16"Content-Transfer-Encoding: 8bit\n"
17−"X-Launchpad-Export-Date: 2013-07-17 07:49+0000\n"
17+"X-Launchpad-Export-Date: 2013-07-31 06:28+0000\n"
18−"X-Generator: Launchpad (build 16696)\n"
18+"X-Generator: Launchpad (build 16718)\n"
19
19
20#: Applications/applications.js:23
20#: Applications/applications.js:23
21msgid "Phone"
21msgid "Phone"
po/de.po+2−2
@@ -14,8 +14,8 @@ msgstr ""
14"MIME-Version: 1.0\n"
14"MIME-Version: 1.0\n"
15"Content-Type: text/plain; charset=UTF-8\n"
15"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Transfer-Encoding: 8bit\n"
16"Content-Transfer-Encoding: 8bit\n"
17−"X-Launchpad-Export-Date: 2013-07-17 07:49+0000\n"
17+"X-Launchpad-Export-Date: 2013-07-31 06:28+0000\n"
18−"X-Generator: Launchpad (build 16696)\n"
18+"X-Generator: Launchpad (build 16718)\n"
19
19
20#: Applications/applications.js:23
20#: Applications/applications.js:23
21msgid "Phone"
21msgid "Phone"
po/el.po+2−2
@@ -14,8 +14,8 @@ msgstr ""
14"MIME-Version: 1.0\n"
14"MIME-Version: 1.0\n"
15"Content-Type: text/plain; charset=UTF-8\n"
15"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Transfer-Encoding: 8bit\n"
16"Content-Transfer-Encoding: 8bit\n"
17−"X-Launchpad-Export-Date: 2013-07-17 07:49+0000\n"
17+"X-Launchpad-Export-Date: 2013-07-31 06:28+0000\n"
18−"X-Generator: Launchpad (build 16696)\n"
18+"X-Generator: Launchpad (build 16718)\n"
19
19
20#: Applications/applications.js:23
20#: Applications/applications.js:23
21msgid "Phone"
21msgid "Phone"
po/en_AU.po+2−2
@@ -14,8 +14,8 @@ msgstr ""
14"MIME-Version: 1.0\n"
14"MIME-Version: 1.0\n"
15"Content-Type: text/plain; charset=UTF-8\n"
15"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Transfer-Encoding: 8bit\n"
16"Content-Transfer-Encoding: 8bit\n"
17−"X-Launchpad-Export-Date: 2013-07-17 07:49+0000\n"
17+"X-Launchpad-Export-Date: 2013-07-31 06:28+0000\n"
18−"X-Generator: Launchpad (build 16696)\n"
18+"X-Generator: Launchpad (build 16718)\n"
19
19
20#: Applications/applications.js:23
20#: Applications/applications.js:23
21msgid "Phone"
21msgid "Phone"
po/en_GB.po+2−2
@@ -14,8 +14,8 @@ msgstr ""
14"MIME-Version: 1.0\n"
14"MIME-Version: 1.0\n"
15"Content-Type: text/plain; charset=UTF-8\n"
15"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Transfer-Encoding: 8bit\n"
16"Content-Transfer-Encoding: 8bit\n"
17−"X-Launchpad-Export-Date: 2013-07-17 07:49+0000\n"
17+"X-Launchpad-Export-Date: 2013-07-31 06:28+0000\n"
18−"X-Generator: Launchpad (build 16696)\n"
18+"X-Generator: Launchpad (build 16718)\n"
19
19
20#: Applications/applications.js:23
20#: Applications/applications.js:23
21msgid "Phone"
21msgid "Phone"
po/eo.po+2−2
@@ -14,8 +14,8 @@ msgstr ""
14"MIME-Version: 1.0\n"
14"MIME-Version: 1.0\n"
15"Content-Type: text/plain; charset=UTF-8\n"
15"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Transfer-Encoding: 8bit\n"
16"Content-Transfer-Encoding: 8bit\n"
17−"X-Launchpad-Export-Date: 2013-07-17 07:49+0000\n"
17+"X-Launchpad-Export-Date: 2013-07-31 06:28+0000\n"
18−"X-Generator: Launchpad (build 16696)\n"
18+"X-Generator: Launchpad (build 16718)\n"
19
19
20#: Applications/applications.js:23
20#: Applications/applications.js:23
21msgid "Phone"
21msgid "Phone"
po/es.po+2−2
@@ -14,8 +14,8 @@ msgstr ""
14"MIME-Version: 1.0\n"
14"MIME-Version: 1.0\n"
15"Content-Type: text/plain; charset=UTF-8\n"
15"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Transfer-Encoding: 8bit\n"
16"Content-Transfer-Encoding: 8bit\n"
17−"X-Launchpad-Export-Date: 2013-07-17 07:49+0000\n"
17+"X-Launchpad-Export-Date: 2013-07-31 06:28+0000\n"
18−"X-Generator: Launchpad (build 16696)\n"
18+"X-Generator: Launchpad (build 16718)\n"
19
19
20#: Applications/applications.js:23
20#: Applications/applications.js:23
21msgid "Phone"
21msgid "Phone"
po/fi.po+2−2
@@ -14,8 +14,8 @@ msgstr ""
14"MIME-Version: 1.0\n"
14"MIME-Version: 1.0\n"
15"Content-Type: text/plain; charset=UTF-8\n"
15"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Transfer-Encoding: 8bit\n"
16"Content-Transfer-Encoding: 8bit\n"
17−"X-Launchpad-Export-Date: 2013-07-17 07:49+0000\n"
17+"X-Launchpad-Export-Date: 2013-07-31 06:28+0000\n"
18−"X-Generator: Launchpad (build 16696)\n"
18+"X-Generator: Launchpad (build 16718)\n"
19
19
20#: Applications/applications.js:23
20#: Applications/applications.js:23
21msgid "Phone"
21msgid "Phone"
po/fo.po+2−2
@@ -14,8 +14,8 @@ msgstr ""
14"MIME-Version: 1.0\n"
14"MIME-Version: 1.0\n"
15"Content-Type: text/plain; charset=UTF-8\n"
15"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Transfer-Encoding: 8bit\n"
16"Content-Transfer-Encoding: 8bit\n"
17−"X-Launchpad-Export-Date: 2013-07-17 07:49+0000\n"
17+"X-Launchpad-Export-Date: 2013-07-31 06:28+0000\n"
18−"X-Generator: Launchpad (build 16696)\n"
18+"X-Generator: Launchpad (build 16718)\n"
19
19
20#: Applications/applications.js:23
20#: Applications/applications.js:23
21msgid "Phone"
21msgid "Phone"
po/fr.po+2−2
@@ -14,8 +14,8 @@ msgstr ""
14"MIME-Version: 1.0\n"
14"MIME-Version: 1.0\n"
15"Content-Type: text/plain; charset=UTF-8\n"
15"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Transfer-Encoding: 8bit\n"
16"Content-Transfer-Encoding: 8bit\n"
17−"X-Launchpad-Export-Date: 2013-07-17 07:49+0000\n"
17+"X-Launchpad-Export-Date: 2013-07-31 06:28+0000\n"
18−"X-Generator: Launchpad (build 16696)\n"
18+"X-Generator: Launchpad (build 16718)\n"
19
19
20#: Applications/applications.js:23
20#: Applications/applications.js:23
21msgid "Phone"
21msgid "Phone"
po/gl.po+2−2
@@ -14,8 +14,8 @@ msgstr ""
14"MIME-Version: 1.0\n"
14"MIME-Version: 1.0\n"
15"Content-Type: text/plain; charset=UTF-8\n"
15"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Transfer-Encoding: 8bit\n"
16"Content-Transfer-Encoding: 8bit\n"
17−"X-Launchpad-Export-Date: 2013-07-17 07:49+0000\n"
17+"X-Launchpad-Export-Date: 2013-07-31 06:28+0000\n"
18−"X-Generator: Launchpad (build 16696)\n"
18+"X-Generator: Launchpad (build 16718)\n"
19
19
20#: Applications/applications.js:23
20#: Applications/applications.js:23
21msgid "Phone"
21msgid "Phone"
po/he.po+2−2
@@ -14,8 +14,8 @@ msgstr ""
14"MIME-Version: 1.0\n"
14"MIME-Version: 1.0\n"
15"Content-Type: text/plain; charset=UTF-8\n"
15"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Transfer-Encoding: 8bit\n"
16"Content-Transfer-Encoding: 8bit\n"
17−"X-Launchpad-Export-Date: 2013-07-17 07:49+0000\n"
17+"X-Launchpad-Export-Date: 2013-07-31 06:28+0000\n"
18−"X-Generator: Launchpad (build 16696)\n"
18+"X-Generator: Launchpad (build 16718)\n"
19
19
20#: Applications/applications.js:23
20#: Applications/applications.js:23
21msgid "Phone"
21msgid "Phone"
po/hr.po+2−2
@@ -14,8 +14,8 @@ msgstr ""
14"MIME-Version: 1.0\n"
14"MIME-Version: 1.0\n"
15"Content-Type: text/plain; charset=UTF-8\n"
15"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Transfer-Encoding: 8bit\n"
16"Content-Transfer-Encoding: 8bit\n"
17−"X-Launchpad-Export-Date: 2013-07-17 07:49+0000\n"
17+"X-Launchpad-Export-Date: 2013-07-31 06:28+0000\n"
18−"X-Generator: Launchpad (build 16696)\n"
18+"X-Generator: Launchpad (build 16718)\n"
19
19
20#: Applications/applications.js:23
20#: Applications/applications.js:23
21msgid "Phone"
21msgid "Phone"
po/hu.po+2−2
@@ -14,8 +14,8 @@ msgstr ""
14"MIME-Version: 1.0\n"
14"MIME-Version: 1.0\n"
15"Content-Type: text/plain; charset=UTF-8\n"
15"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Transfer-Encoding: 8bit\n"
16"Content-Transfer-Encoding: 8bit\n"
17−"X-Launchpad-Export-Date: 2013-07-17 07:49+0000\n"
17+"X-Launchpad-Export-Date: 2013-07-31 06:28+0000\n"
18−"X-Generator: Launchpad (build 16696)\n"
18+"X-Generator: Launchpad (build 16718)\n"
19
19
20#: Applications/applications.js:23
20#: Applications/applications.js:23
21msgid "Phone"
21msgid "Phone"
po/hy.po+2−2
@@ -14,8 +14,8 @@ msgstr ""
14"MIME-Version: 1.0\n"
14"MIME-Version: 1.0\n"
15"Content-Type: text/plain; charset=UTF-8\n"
15"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Transfer-Encoding: 8bit\n"
16"Content-Transfer-Encoding: 8bit\n"
17−"X-Launchpad-Export-Date: 2013-07-17 07:49+0000\n"
17+"X-Launchpad-Export-Date: 2013-07-31 06:28+0000\n"
18−"X-Generator: Launchpad (build 16696)\n"
18+"X-Generator: Launchpad (build 16718)\n"
19
19
20#: Applications/applications.js:23
20#: Applications/applications.js:23
21msgid "Phone"
21msgid "Phone"
po/id.po+2−2
@@ -14,8 +14,8 @@ msgstr ""
14"MIME-Version: 1.0\n"
14"MIME-Version: 1.0\n"
15"Content-Type: text/plain; charset=UTF-8\n"
15"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Transfer-Encoding: 8bit\n"
16"Content-Transfer-Encoding: 8bit\n"
17−"X-Launchpad-Export-Date: 2013-07-17 07:49+0000\n"
17+"X-Launchpad-Export-Date: 2013-07-31 06:28+0000\n"
18−"X-Generator: Launchpad (build 16696)\n"
18+"X-Generator: Launchpad (build 16718)\n"
19
19
20#: Applications/applications.js:23
20#: Applications/applications.js:23
21msgid "Phone"
21msgid "Phone"
po/it.po+2−2
@@ -14,8 +14,8 @@ msgstr ""
14"MIME-Version: 1.0\n"
14"MIME-Version: 1.0\n"
15"Content-Type: text/plain; charset=UTF-8\n"
15"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Transfer-Encoding: 8bit\n"
16"Content-Transfer-Encoding: 8bit\n"
17−"X-Launchpad-Export-Date: 2013-07-17 07:49+0000\n"
17+"X-Launchpad-Export-Date: 2013-07-31 06:28+0000\n"
18−"X-Generator: Launchpad (build 16696)\n"
18+"X-Generator: Launchpad (build 16718)\n"
19
19
20#: Applications/applications.js:23
20#: Applications/applications.js:23
21msgid "Phone"
21msgid "Phone"
po/ja.po+2−2
@@ -14,8 +14,8 @@ msgstr ""
14"MIME-Version: 1.0\n"
14"MIME-Version: 1.0\n"
15"Content-Type: text/plain; charset=UTF-8\n"
15"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Transfer-Encoding: 8bit\n"
16"Content-Transfer-Encoding: 8bit\n"
17−"X-Launchpad-Export-Date: 2013-07-17 07:49+0000\n"
17+"X-Launchpad-Export-Date: 2013-07-31 06:28+0000\n"
18−"X-Generator: Launchpad (build 16696)\n"
18+"X-Generator: Launchpad (build 16718)\n"
19
19
20#: Applications/applications.js:23
20#: Applications/applications.js:23
21msgid "Phone"
21msgid "Phone"
po/kn.po+2−2
@@ -14,8 +14,8 @@ msgstr ""
14"MIME-Version: 1.0\n"
14"MIME-Version: 1.0\n"
15"Content-Type: text/plain; charset=UTF-8\n"
15"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Transfer-Encoding: 8bit\n"
16"Content-Transfer-Encoding: 8bit\n"
17−"X-Launchpad-Export-Date: 2013-07-17 07:49+0000\n"
17+"X-Launchpad-Export-Date: 2013-07-31 06:28+0000\n"
18−"X-Generator: Launchpad (build 16696)\n"
18+"X-Generator: Launchpad (build 16718)\n"
19
19
20#: Applications/applications.js:23
20#: Applications/applications.js:23
21msgid "Phone"
21msgid "Phone"
po/ko.po+2−2
@@ -14,8 +14,8 @@ msgstr ""
14"MIME-Version: 1.0\n"
14"MIME-Version: 1.0\n"
15"Content-Type: text/plain; charset=UTF-8\n"
15"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Transfer-Encoding: 8bit\n"
16"Content-Transfer-Encoding: 8bit\n"
17−"X-Launchpad-Export-Date: 2013-07-17 07:49+0000\n"
17+"X-Launchpad-Export-Date: 2013-07-31 06:28+0000\n"
18−"X-Generator: Launchpad (build 16696)\n"
18+"X-Generator: Launchpad (build 16718)\n"
19
19
20#: Applications/applications.js:23
20#: Applications/applications.js:23
21msgid "Phone"
21msgid "Phone"
po/ky.po+2−2
@@ -14,8 +14,8 @@ msgstr ""
14"MIME-Version: 1.0\n"
14"MIME-Version: 1.0\n"
15"Content-Type: text/plain; charset=UTF-8\n"
15"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Transfer-Encoding: 8bit\n"
16"Content-Transfer-Encoding: 8bit\n"
17−"X-Launchpad-Export-Date: 2013-07-17 07:49+0000\n"
17+"X-Launchpad-Export-Date: 2013-07-31 06:28+0000\n"
18−"X-Generator: Launchpad (build 16696)\n"
18+"X-Generator: Launchpad (build 16718)\n"
19
19
20#: Applications/applications.js:23
20#: Applications/applications.js:23
21msgid "Phone"
21msgid "Phone"
po/lv.po+2−2
@@ -14,8 +14,8 @@ msgstr ""
14"MIME-Version: 1.0\n"
14"MIME-Version: 1.0\n"
15"Content-Type: text/plain; charset=UTF-8\n"
15"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Transfer-Encoding: 8bit\n"
16"Content-Transfer-Encoding: 8bit\n"
17−"X-Launchpad-Export-Date: 2013-07-17 07:49+0000\n"
17+"X-Launchpad-Export-Date: 2013-07-31 06:28+0000\n"
18−"X-Generator: Launchpad (build 16696)\n"
18+"X-Generator: Launchpad (build 16718)\n"
19
19
20#: Applications/applications.js:23
20#: Applications/applications.js:23
21msgid "Phone"
21msgid "Phone"
po/my.po+2−2
@@ -14,8 +14,8 @@ msgstr ""
14"MIME-Version: 1.0\n"
14"MIME-Version: 1.0\n"
15"Content-Type: text/plain; charset=UTF-8\n"
15"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Transfer-Encoding: 8bit\n"
16"Content-Transfer-Encoding: 8bit\n"
17−"X-Launchpad-Export-Date: 2013-07-17 07:49+0000\n"
17+"X-Launchpad-Export-Date: 2013-07-31 06:28+0000\n"
18−"X-Generator: Launchpad (build 16696)\n"
18+"X-Generator: Launchpad (build 16718)\n"
19
19
20#: Applications/applications.js:23
20#: Applications/applications.js:23
21msgid "Phone"
21msgid "Phone"
po/nb.po+2−2
@@ -14,8 +14,8 @@ msgstr ""
14"MIME-Version: 1.0\n"
14"MIME-Version: 1.0\n"
15"Content-Type: text/plain; charset=UTF-8\n"
15"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Transfer-Encoding: 8bit\n"
16"Content-Transfer-Encoding: 8bit\n"
17−"X-Launchpad-Export-Date: 2013-07-17 07:49+0000\n"
17+"X-Launchpad-Export-Date: 2013-07-31 06:28+0000\n"
18−"X-Generator: Launchpad (build 16696)\n"
18+"X-Generator: Launchpad (build 16718)\n"
19
19
20#: Applications/applications.js:23
20#: Applications/applications.js:23
21msgid "Phone"
21msgid "Phone"
po/nl.po+2−2
@@ -14,8 +14,8 @@ msgstr ""
14"MIME-Version: 1.0\n"
14"MIME-Version: 1.0\n"
15"Content-Type: text/plain; charset=UTF-8\n"
15"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Transfer-Encoding: 8bit\n"
16"Content-Transfer-Encoding: 8bit\n"
17−"X-Launchpad-Export-Date: 2013-07-17 07:49+0000\n"
17+"X-Launchpad-Export-Date: 2013-07-31 06:28+0000\n"
18−"X-Generator: Launchpad (build 16696)\n"
18+"X-Generator: Launchpad (build 16718)\n"
19
19
20#: Applications/applications.js:23
20#: Applications/applications.js:23
21msgid "Phone"
21msgid "Phone"
po/pl.po+2−2
@@ -14,8 +14,8 @@ msgstr ""
14"MIME-Version: 1.0\n"
14"MIME-Version: 1.0\n"
15"Content-Type: text/plain; charset=UTF-8\n"
15"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Transfer-Encoding: 8bit\n"
16"Content-Transfer-Encoding: 8bit\n"
17−"X-Launchpad-Export-Date: 2013-07-17 07:49+0000\n"
17+"X-Launchpad-Export-Date: 2013-07-31 06:28+0000\n"
18−"X-Generator: Launchpad (build 16696)\n"
18+"X-Generator: Launchpad (build 16718)\n"
19
19
20#: Applications/applications.js:23
20#: Applications/applications.js:23
21msgid "Phone"
21msgid "Phone"
po/pt_BR.po+2−2
@@ -14,8 +14,8 @@ msgstr ""
14"MIME-Version: 1.0\n"
14"MIME-Version: 1.0\n"
15"Content-Type: text/plain; charset=UTF-8\n"
15"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Transfer-Encoding: 8bit\n"
16"Content-Transfer-Encoding: 8bit\n"
17−"X-Launchpad-Export-Date: 2013-07-17 07:49+0000\n"
17+"X-Launchpad-Export-Date: 2013-07-31 06:28+0000\n"
18−"X-Generator: Launchpad (build 16696)\n"
18+"X-Generator: Launchpad (build 16718)\n"
19
19
20#: Applications/applications.js:23
20#: Applications/applications.js:23
21msgid "Phone"
21msgid "Phone"
po/ro.po+2−2
@@ -14,8 +14,8 @@ msgstr ""
14"MIME-Version: 1.0\n"
14"MIME-Version: 1.0\n"
15"Content-Type: text/plain; charset=UTF-8\n"
15"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Transfer-Encoding: 8bit\n"
16"Content-Transfer-Encoding: 8bit\n"
17−"X-Launchpad-Export-Date: 2013-07-17 07:49+0000\n"
17+"X-Launchpad-Export-Date: 2013-07-31 06:28+0000\n"
18−"X-Generator: Launchpad (build 16696)\n"
18+"X-Generator: Launchpad (build 16718)\n"
19
19
20#: Applications/applications.js:23
20#: Applications/applications.js:23
21msgid "Phone"
21msgid "Phone"
po/ru.po+2−2
@@ -14,8 +14,8 @@ msgstr ""
14"MIME-Version: 1.0\n"
14"MIME-Version: 1.0\n"
15"Content-Type: text/plain; charset=UTF-8\n"
15"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Transfer-Encoding: 8bit\n"
16"Content-Transfer-Encoding: 8bit\n"
17−"X-Launchpad-Export-Date: 2013-07-17 07:49+0000\n"
17+"X-Launchpad-Export-Date: 2013-07-31 06:28+0000\n"
18−"X-Generator: Launchpad (build 16696)\n"
18+"X-Generator: Launchpad (build 16718)\n"
19
19
20#: Applications/applications.js:23
20#: Applications/applications.js:23
21msgid "Phone"
21msgid "Phone"
po/si.po+2−2
@@ -14,8 +14,8 @@ msgstr ""
14"MIME-Version: 1.0\n"
14"MIME-Version: 1.0\n"
15"Content-Type: text/plain; charset=UTF-8\n"
15"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Transfer-Encoding: 8bit\n"
16"Content-Transfer-Encoding: 8bit\n"
17−"X-Launchpad-Export-Date: 2013-07-17 07:49+0000\n"
17+"X-Launchpad-Export-Date: 2013-07-31 06:28+0000\n"
18−"X-Generator: Launchpad (build 16696)\n"
18+"X-Generator: Launchpad (build 16718)\n"
19
19
20#: Applications/applications.js:23
20#: Applications/applications.js:23
21msgid "Phone"
21msgid "Phone"
po/sl.po+2−2
@@ -14,8 +14,8 @@ msgstr ""
14"MIME-Version: 1.0\n"
14"MIME-Version: 1.0\n"
15"Content-Type: text/plain; charset=UTF-8\n"
15"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Transfer-Encoding: 8bit\n"
16"Content-Transfer-Encoding: 8bit\n"
17−"X-Launchpad-Export-Date: 2013-07-17 07:49+0000\n"
17+"X-Launchpad-Export-Date: 2013-07-31 06:28+0000\n"
18−"X-Generator: Launchpad (build 16696)\n"
18+"X-Generator: Launchpad (build 16718)\n"
19
19
20#: Applications/applications.js:23
20#: Applications/applications.js:23
21msgid "Phone"
21msgid "Phone"
po/sr.po+2−2
@@ -14,8 +14,8 @@ msgstr ""
14"MIME-Version: 1.0\n"
14"MIME-Version: 1.0\n"
15"Content-Type: text/plain; charset=UTF-8\n"
15"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Transfer-Encoding: 8bit\n"
16"Content-Transfer-Encoding: 8bit\n"
17−"X-Launchpad-Export-Date: 2013-07-17 07:49+0000\n"
17+"X-Launchpad-Export-Date: 2013-07-31 06:28+0000\n"
18−"X-Generator: Launchpad (build 16696)\n"
18+"X-Generator: Launchpad (build 16718)\n"
19
19
20#: Applications/applications.js:23
20#: Applications/applications.js:23
21msgid "Phone"
21msgid "Phone"
po/sv.po+2−2
@@ -14,8 +14,8 @@ msgstr ""
14"MIME-Version: 1.0\n"
14"MIME-Version: 1.0\n"
15"Content-Type: text/plain; charset=UTF-8\n"
15"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Transfer-Encoding: 8bit\n"
16"Content-Transfer-Encoding: 8bit\n"
17−"X-Launchpad-Export-Date: 2013-07-17 07:49+0000\n"
17+"X-Launchpad-Export-Date: 2013-07-31 06:28+0000\n"
18−"X-Generator: Launchpad (build 16696)\n"
18+"X-Generator: Launchpad (build 16718)\n"
19
19
20#: Applications/applications.js:23
20#: Applications/applications.js:23
21msgid "Phone"
21msgid "Phone"
po/te.po+2−2
@@ -14,8 +14,8 @@ msgstr ""
14"MIME-Version: 1.0\n"
14"MIME-Version: 1.0\n"
15"Content-Type: text/plain; charset=UTF-8\n"
15"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Transfer-Encoding: 8bit\n"
16"Content-Transfer-Encoding: 8bit\n"
17−"X-Launchpad-Export-Date: 2013-07-17 07:49+0000\n"
17+"X-Launchpad-Export-Date: 2013-07-31 06:28+0000\n"
18−"X-Generator: Launchpad (build 16696)\n"
18+"X-Generator: Launchpad (build 16718)\n"
19
19
20#: Applications/applications.js:23
20#: Applications/applications.js:23
21msgid "Phone"
21msgid "Phone"
po/tr.po+2−2
@@ -14,8 +14,8 @@ msgstr ""
14"MIME-Version: 1.0\n"
14"MIME-Version: 1.0\n"
15"Content-Type: text/plain; charset=UTF-8\n"
15"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Transfer-Encoding: 8bit\n"
16"Content-Transfer-Encoding: 8bit\n"
17−"X-Launchpad-Export-Date: 2013-07-17 07:49+0000\n"
17+"X-Launchpad-Export-Date: 2013-07-31 06:28+0000\n"
18−"X-Generator: Launchpad (build 16696)\n"
18+"X-Generator: Launchpad (build 16718)\n"
19
19
20#: Applications/applications.js:23
20#: Applications/applications.js:23
21msgid "Phone"
21msgid "Phone"
po/ug.po+2−2
@@ -14,8 +14,8 @@ msgstr ""
14"MIME-Version: 1.0\n"
14"MIME-Version: 1.0\n"
15"Content-Type: text/plain; charset=UTF-8\n"
15"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Transfer-Encoding: 8bit\n"
16"Content-Transfer-Encoding: 8bit\n"
17−"X-Launchpad-Export-Date: 2013-07-17 07:49+0000\n"
17+"X-Launchpad-Export-Date: 2013-07-31 06:28+0000\n"
18−"X-Generator: Launchpad (build 16696)\n"
18+"X-Generator: Launchpad (build 16718)\n"
19
19
20#: Applications/applications.js:23
20#: Applications/applications.js:23
21msgid "Phone"
21msgid "Phone"
po/uk.po+2−2
@@ -14,8 +14,8 @@ msgstr ""
14"MIME-Version: 1.0\n"
14"MIME-Version: 1.0\n"
15"Content-Type: text/plain; charset=UTF-8\n"
15"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Transfer-Encoding: 8bit\n"
16"Content-Transfer-Encoding: 8bit\n"
17−"X-Launchpad-Export-Date: 2013-07-22 06:19+0000\n"
17+"X-Launchpad-Export-Date: 2013-07-31 06:28+0000\n"
18−"X-Generator: Launchpad (build 16696)\n"
18+"X-Generator: Launchpad (build 16718)\n"
19
19
20#: Applications/applications.js:23
20#: Applications/applications.js:23
21msgid "Phone"
21msgid "Phone"
po/zh_CN.po+2−2
@@ -14,8 +14,8 @@ msgstr ""
14"MIME-Version: 1.0\n"
14"MIME-Version: 1.0\n"
15"Content-Type: text/plain; charset=UTF-8\n"
15"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Transfer-Encoding: 8bit\n"
16"Content-Transfer-Encoding: 8bit\n"
17−"X-Launchpad-Export-Date: 2013-07-17 07:49+0000\n"
17+"X-Launchpad-Export-Date: 2013-07-31 06:28+0000\n"
18−"X-Generator: Launchpad (build 16696)\n"
18+"X-Generator: Launchpad (build 16718)\n"
19
19
20#: Applications/applications.js:23
20#: Applications/applications.js:23
21msgid "Phone"
21msgid "Phone"
po/zh_TW.po+2−2
@@ -14,8 +14,8 @@ msgstr ""
14"MIME-Version: 1.0\n"
14"MIME-Version: 1.0\n"
15"Content-Type: text/plain; charset=UTF-8\n"
15"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Transfer-Encoding: 8bit\n"
16"Content-Transfer-Encoding: 8bit\n"
17−"X-Launchpad-Export-Date: 2013-07-17 07:49+0000\n"
17+"X-Launchpad-Export-Date: 2013-07-31 06:28+0000\n"
18−"X-Generator: Launchpad (build 16696)\n"
18+"X-Generator: Launchpad (build 16718)\n"
19
19
20#: Applications/applications.js:23
20#: Applications/applications.js:23
21msgid "Phone"
21msgid "Phone"
tests/autopilot/unity8/indicators_client/tests/test_battery.py+11−3
@@ -26,7 +26,7 @@ class TestDisplayMenus(IndicatorsTestCase):
26 self.pointing_device.move_to_object(self.main_window.get_battery_menu())
26 self.pointing_device.move_to_object(self.main_window.get_battery_menu())
27 self.pointing_device.click()
27 self.pointing_device.click()
28
28
29− fn_loader = lambda: self.app.select_single("IndicatorsPage/QQuickLoader", objectName="page_loader");
29+ fn_loader = lambda: self.app.select_single("IndicatorsPage/QQuickLoader", objectName="pageLoader");
30 self.assertThat(fn_loader, Eventually(NotEquals(None)));
30 self.assertThat(fn_loader, Eventually(NotEquals(None)));
31 page_loader = fn_loader();
31 page_loader = fn_loader();
32 self.assertThat(page_loader.progress, Eventually(Equals(1.0)))
32 self.assertThat(page_loader.progress, Eventually(Equals(1.0)))
@@ -70,7 +70,11 @@ class TestDisplayMenus(IndicatorsTestCase):
70
70
71 # wait for the switch menu item
71 # wait for the switch menu item
72 fn_auto_brightness = lambda: self.app.select_single("SwitchMenuItem", objectName="auto-brightness");
72 fn_auto_brightness = lambda: self.app.select_single("SwitchMenuItem", objectName="auto-brightness");
73+ # FIXME: this should go away when we switch to indicator-power
74+ try:
73− self.assertThat(fn_auto_brightness, Eventually(NotEquals(None)));
75+ self.assertThat(fn_auto_brightness, Eventually(NotEquals(None)));
76+ except AssertionError:
77+ self.skipTest("WARNING: test skipped due to missing indicator-battery")
74 auto_brightness = fn_auto_brightness();
78 auto_brightness = fn_auto_brightness();
75
79
76 old_ab_value = auto_brightness.checked
80 old_ab_value = auto_brightness.checked
@@ -86,7 +90,11 @@ class TestDisplayMenus(IndicatorsTestCase):
86 if self.input_device_class is Touch:
90 if self.input_device_class is Touch:
87 self.skipTest("Dragging is broken with Touch input (LP: #1203808).")
91 self.skipTest("Dragging is broken with Touch input (LP: #1203808).")
88 fn_brightness_menu = lambda: self.app.select_single("SliderMenuItem", objectName="brightness");
92 fn_brightness_menu = lambda: self.app.select_single("SliderMenuItem", objectName="brightness");
93+ # FIXME: this should go away when we switch to indicator-power
94+ try:
89− self.assertThat(fn_brightness_menu, Eventually(NotEquals(None)));
95+ self.assertThat(fn_brightness_menu, Eventually(NotEquals(None)));
96+ except AssertionError:
97+ self.skipTest("WARNING: test skipped due to missing indicator-battery")
90 brightness_menu = fn_brightness_menu();
98 brightness_menu = fn_brightness_menu();
91
99
92 old_ab_value = brightness_menu.value
100 old_ab_value = brightness_menu.value
tests/autopilot/unity8/shell/__init__.py+1−27
@@ -21,9 +21,6 @@
21
21
22from functools import wraps
22from functools import wraps
23import logging
23import logging
24−import os.path
25−
26−from unity8 import get_mocks_library_path, get_default_extra_mock_libraries
27
24
28
25
29logger = logging.getLogger(__name__)
26logger = logging.getLogger(__name__)
@@ -34,31 +31,8 @@ def with_lightdm_mock(mock_type):
34 def with_lightdm_mock_internal(fn):
31 def with_lightdm_mock_internal(fn):
35 @wraps(fn)
32 @wraps(fn)
36 def wrapper(*args, **kwargs):
33 def wrapper(*args, **kwargs):
37− logger.info("Setting up LightDM mock type '%s'", mock_type)
38− new_ld_library_path = "%s:%s" % (
39− get_default_extra_mock_libraries(),
40− _get_ld_library_path(mock_type)
41− )
42− logger.info("New library path: %s", new_ld_library_path)
43 tests_self = args[0]
34 tests_self = args[0]
44− tests_self.patch_environment(
35+ tests_self.patch_lightdm_mock(mock_type)
45− 'LD_LIBRARY_PATH',
46− new_ld_library_path
47− )
48 return fn(*args, **kwargs)
36 return fn(*args, **kwargs)
49 return wrapper
37 return wrapper
50 return with_lightdm_mock_internal
38 return with_lightdm_mock_internal
51−
52−
53−def _get_ld_library_path(mock_type):
54− lib_path = get_mocks_library_path()
55− new_ld_library_path = os.path.abspath(
56− os.path.join(lib_path, "LightDM", mock_type)
57− )
58−
59− if not os.path.exists(new_ld_library_path):
60− raise RuntimeError(
61− "LightDM mock '%s' does not exist at path '%s'."
62− % (mock_type, new_ld_library_path)
63− )
64− return new_ld_library_path
tests/autopilot/unity8/shell/emulators/greeter.py+4−1
@@ -25,7 +25,7 @@ class Greeter(UnityEmulatorBase):
25
25
26 """An emulator that understands the greeter screen."""
26 """An emulator that understands the greeter screen."""
27
27
28− def unlock(self):
28+ def swipe(self):
29 """Swipe the greeter screen away."""
29 """Swipe the greeter screen away."""
30 self.created.wait_for(True)
30 self.created.wait_for(True)
31 touch = Touch.create()
31 touch = Touch.create()
@@ -38,3 +38,6 @@ class Greeter(UnityEmulatorBase):
38 touch.drag(start_x, start_y, stop_x, stop_y)
38 touch.drag(start_x, start_y, stop_x, stop_y)
39
39
40 self.created.wait_for(False)
40 self.created.wait_for(False)
41+
42+ def get_prompt(self):
43+ return self.select_single("TextField", objectName="passwordInput")
tests/autopilot/unity8/shell/emulators/hud.py+4−7
@@ -38,13 +38,10 @@ class Hud(UnityEmulatorBase):
38 window = self.get_root_instance().select_single('QQuickView')
38 window = self.get_root_instance().select_single('QQuickView')
39 hud_show_button = window.select_single("HudButton")
39 hud_show_button = window.select_single("HudButton")
40
40
41− start_x = int(window.x + (window.width / 2))
41+ swipe_coords = self.get_button_swipe_coords(window, hud_show_button)
42− end_x = start_x
43− start_y = window.y + window.height
44− end_y = int(hud_show_button.y + (hud_show_button.height/2))
45
42
46− touch.press(start_x, start_y)
43+ touch.press(swipe_coords.start_x, swipe_coords.start_y)
47− touch._finger_move(end_x, end_y)
44+ touch._finger_move(swipe_coords.end_x, swipe_coords.end_y)
48 try:
45 try:
49 hud_show_button.opacity.wait_for(1.0)
46 hud_show_button.opacity.wait_for(1.0)
50 touch.release()
47 touch.release()
@@ -78,6 +75,6 @@ class Hud(UnityEmulatorBase):
78 start_x = int(main_view.x + (main_view.width / 2))
75 start_x = int(main_view.x + (main_view.width / 2))
79 end_x = start_x
76 end_x = start_x
80 start_y = main_view.y + (main_view.height - 3)
77 start_y = main_view.y + (main_view.height - 3)
81− end_y = int(hud_show_button.y + (hud_show_button.height/2))
78+ end_y = main_view.y + int(hud_show_button.y + (hud_show_button.height/2))
82
79
83 return SwipeCoords(start_x, end_x, start_y, end_y)
80 return SwipeCoords(start_x, end_x, start_y, end_y)
tests/autopilot/unity8/shell/emulators/main_window.py+1−1
@@ -89,4 +89,4 @@ class MainWindow(object):
89 return self.app.select_single("Lockscreen")
89 return self.app.select_single("Lockscreen")
90
90
91 def get_pinentryField(self):
91 def get_pinentryField(self):
92− return self.app.select_single("TextField", objectName="pinentryField")
92+ return self.app.select_single(objectName="pinentryField")
tests/autopilot/unity8/shell/tests/__init__.py+53−1
@@ -19,6 +19,11 @@
19
19
20"""unity autopilot tests."""
20"""unity autopilot tests."""
21
21
22+try:
23+ from gi.repository import Gio
24+except ImportError:
25+ Gio = None
26+
22from autopilot.platform import model
27from autopilot.platform import model
23from autopilot.testcase import AutopilotTestCase
28from autopilot.testcase import AutopilotTestCase
24from autopilot.matchers import Eventually
29from autopilot.matchers import Eventually
@@ -28,7 +33,12 @@ import logging
28import os.path
33import os.path
29from testtools.matchers import Equals, NotEquals
34from testtools.matchers import Equals, NotEquals
30
35
36+from unity8 import (
37+ get_lib_path,
38+ get_binary_path,
31−from unity8 import get_lib_path, get_binary_path, get_mocks_library_path
39+ get_mocks_library_path,
40+ get_default_extra_mock_libraries,
41+)
32from unity8.shell.emulators import UnityEmulatorBase
42from unity8.shell.emulators import UnityEmulatorBase
33from unity8.shell.emulators.dash import Dash
43from unity8.shell.emulators.dash import Dash
34from unity8.shell.emulators.main_window import MainWindow
44from unity8.shell.emulators.main_window import MainWindow
@@ -36,6 +46,10 @@ from unity8.shell.emulators.main_window import MainWindow
36
46
37logger = logging.getLogger(__name__)
47logger = logging.getLogger(__name__)
38
48
49+UNITYSHELL_GSETTINGS_SCHEMA = "org.compiz.unityshell"
50+UNITYSHELL_GSETTINGS_PATH = "/org/compiz/profiles/unity/plugins/unityshell/"
51+UNITYSHELL_LAUNCHER_KEY = "launcher-hide-mode"
52+UNITYSHELL_LAUNCHER_MODE = 1 # launcher hidden
39
53
40def _get_device_emulation_scenarios():
54def _get_device_emulation_scenarios():
41 if model() == 'Desktop':
55 if model() == 'Desktop':
@@ -64,10 +78,22 @@ class UnityTestCase(AutopilotTestCase):
64
78
65 def setUp(self):
79 def setUp(self):
66 super(UnityTestCase, self).setUp()
80 super(UnityTestCase, self).setUp()
81+ if Gio is not None and UNITYSHELL_GSETTINGS_SCHEMA in Gio.Settings.list_relocatable_schemas():
82+ # Hide Unity launcher
83+ self._unityshell_schema = Gio.Settings.new_with_path(UNITYSHELL_GSETTINGS_SCHEMA, UNITYSHELL_GSETTINGS_PATH)
84+ self._launcher_hide_mode = self._unityshell_schema.get_int(UNITYSHELL_LAUNCHER_KEY)
85+ self._unityshell_schema.set_int(UNITYSHELL_LAUNCHER_KEY, UNITYSHELL_LAUNCHER_MODE)
86+ self.addCleanup(self._reset_launcher)
87+
67 self._proxy = None
88 self._proxy = None
89+ self._lightdm_mock_type = None
68 self.touch = Touch.create()
90 self.touch = Touch.create()
69 self._setup_display_details()
91 self._setup_display_details()
70
92
93+ def _reset_launcher(self):
94+ """Reset Unity launcher hide mode"""
95+ self._unityshell_schema.set_int(UNITYSHELL_LAUNCHER_KEY, self._launcher_hide_mode)
96+
71 def _setup_display_details(self):
97 def _setup_display_details(self):
72 scale_divisor = self._determine_geometry()
98 scale_divisor = self._determine_geometry()
73 self._setup_grid_size(scale_divisor)
99 self._setup_grid_size(scale_divisor)
@@ -133,6 +159,8 @@ class UnityTestCase(AutopilotTestCase):
133 binary_path
159 binary_path
134 )
160 )
135
161
162+ if self._lightdm_mock_type is None:
163+ self.patch_lightdm_mock()
136 self._setup_extra_mock_environment_patch()
164 self._setup_extra_mock_environment_patch()
137
165
138 app_proxy = self.launch_test_application(
166 app_proxy = self.launch_test_application(
@@ -150,6 +178,30 @@ class UnityTestCase(AutopilotTestCase):
150
178
151 return app_proxy
179 return app_proxy
152
180
181+ def patch_lightdm_mock(self, mock_type='single'):
182+ self._lightdm_mock_type = mock_type
183+ logger.info("Setting up LightDM mock type '%s'", mock_type)
184+ new_ld_library_path = "%s:%s" % (
185+ get_default_extra_mock_libraries(),
186+ self._get_lightdm_mock_path(mock_type)
187+ )
188+ logger.info("New library path: %s", new_ld_library_path)
189+
190+ self.patch_environment('LD_LIBRARY_PATH', new_ld_library_path)
191+
192+ def _get_lightdm_mock_path(self, mock_type):
193+ lib_path = get_mocks_library_path()
194+ lightdm_mock_path = os.path.abspath(
195+ os.path.join(lib_path, "LightDM", mock_type)
196+ )
197+
198+ if not os.path.exists(lightdm_mock_path):
199+ raise RuntimeError(
200+ "LightDM mock '%s' does not exist at path '%s'."
201+ % (mock_type, lightdm_mock_path)
202+ )
203+ return lightdm_mock_path
204+
153 def _setup_extra_mock_environment_patch(self):
205 def _setup_extra_mock_environment_patch(self):
154 mocks_library_path = get_mocks_library_path()
206 mocks_library_path = get_mocks_library_path()
155 self.patch_environment('QML2_IMPORT_PATH', mocks_library_path)
207 self.patch_environment('QML2_IMPORT_PATH', mocks_library_path)
tests/autopilot/unity8/shell/tests/test_hud.py+5−10
@@ -32,13 +32,12 @@ class TestHud(UnityTestCase):
32
32
33 scenarios = _get_device_emulation_scenarios()
33 scenarios = _get_device_emulation_scenarios()
34
34
35− @with_lightdm_mock("single")
36 def test_show_hud_button_appears(self):
35 def test_show_hud_button_appears(self):
37 """Swiping up while an app is active must show the 'show hud' button.
36 """Swiping up while an app is active must show the 'show hud' button.
38
37
39 """
38 """
40 self.launch_unity()
39 self.launch_unity()
41− self.main_window.get_greeter().unlock()
40+ self.main_window.get_greeter().swipe()
42 window = self.main_window.get_qml_view()
41 window = self.main_window.get_qml_view()
43 hud_show_button = self.main_window.get_hud_show_button()
42 hud_show_button = self.main_window.get_hud_show_button()
44 hud = self.main_window.get_hud()
43 hud = self.main_window.get_hud()
@@ -54,13 +53,12 @@ class TestHud(UnityTestCase):
54 self.touch._finger_move(swipe_coords.end_x, swipe_coords.end_y)
53 self.touch._finger_move(swipe_coords.end_x, swipe_coords.end_y)
55 self.assertThat(hud_show_button.opacity, Eventually(Equals(1.0)))
54 self.assertThat(hud_show_button.opacity, Eventually(Equals(1.0)))
56
55
57− @with_lightdm_mock("single")
58 def test_show_hud_appears(self):
56 def test_show_hud_appears(self):
59 """Releasing the touch on the 'show hud' button must display the hud.
57 """Releasing the touch on the 'show hud' button must display the hud.
60
58
61 """
59 """
62 self.launch_unity()
60 self.launch_unity()
63− self.main_window.get_greeter().unlock()
61+ self.main_window.get_greeter().swipe()
64 window = self.main_window.get_qml_view()
62 window = self.main_window.get_qml_view()
65 hud_show_button = self.main_window.get_hud_show_button()
63 hud_show_button = self.main_window.get_hud_show_button()
66 hud = self.main_window.get_hud()
64 hud = self.main_window.get_hud()
@@ -80,11 +78,10 @@ class TestHud(UnityTestCase):
80 self.touch.release()
78 self.touch.release()
81 self.assertThat(hud.shown, Eventually(Equals(True)))
79 self.assertThat(hud.shown, Eventually(Equals(True)))
82
80
83− @with_lightdm_mock("single")
84 def test_hide_hud_click(self):
81 def test_hide_hud_click(self):
85 """Tapping the close button of the Hud must dismiss it."""
82 """Tapping the close button of the Hud must dismiss it."""
86 self.launch_unity()
83 self.launch_unity()
87− self.main_window.get_greeter().unlock()
84+ self.main_window.get_greeter().swipe()
88 hud = self.main_window.get_hud()
85 hud = self.main_window.get_hud()
89
86
90 self._launch_test_app_from_app_screen()
87 self._launch_test_app_from_app_screen()
@@ -94,14 +91,13 @@ class TestHud(UnityTestCase):
94 self.touch.tap(x, y)
91 self.touch.tap(x, y)
95 self.assertThat(hud.shown, Eventually(Equals(False)))
92 self.assertThat(hud.shown, Eventually(Equals(False)))
96
93
97− @with_lightdm_mock("single")
98 def test_hide_hud_dragging(self):
94 def test_hide_hud_dragging(self):
99 """Once open the Hud must close if the upper bar is dragged and
95 """Once open the Hud must close if the upper bar is dragged and
100 released downward.
96 released downward.
101
97
102 """
98 """
103 self.launch_unity()
99 self.launch_unity()
104− self.main_window.get_greeter().unlock()
100+ self.main_window.get_greeter().swipe()
105 hud = self.main_window.get_hud()
101 hud = self.main_window.get_hud()
106 window = self.main_window.get_qml_view()
102 window = self.main_window.get_qml_view()
107
103
@@ -115,11 +111,10 @@ class TestHud(UnityTestCase):
115 self.touch.drag(start_x, start_y, end_x, end_y)
111 self.touch.drag(start_x, start_y, end_x, end_y)
116 self.assertThat(hud.shown, Eventually(Equals(False)))
112 self.assertThat(hud.shown, Eventually(Equals(False)))
117
113
118− @with_lightdm_mock("single")
119 def test_launcher_hides_hud(self):
114 def test_launcher_hides_hud(self):
120 """Opening the Launcher while the Hud is active must close the Hud."""
115 """Opening the Launcher while the Hud is active must close the Hud."""
121 self.launch_unity()
116 self.launch_unity()
122− self.main_window.get_greeter().unlock()
117+ self.main_window.get_greeter().swipe()
123 hud = self.main_window.get_hud()
118 hud = self.main_window.get_hud()
124 launcher = self.main_window.get_launcher()
119 launcher = self.main_window.get_launcher()
125
120
tests/autopilot/unity8/shell/tests/test_lock_screen.py+58−28
@@ -40,54 +40,68 @@ class TestLockscreen(UnityTestCase):
40 """Must be able to unlock the PIN entry lock screen."""
40 """Must be able to unlock the PIN entry lock screen."""
41 self.launch_unity()
41 self.launch_unity()
42 greeter = self.main_window.get_greeter()
42 greeter = self.main_window.get_greeter()
43− greeter.unlock()
44
43
44+ if greeter.narrowMode:
45+ greeter.swipe()
45− lockscreen = self._wait_for_lockscreen()
46+ lockscreen = self._wait_for_lockscreen()
46− self._enter_pincode("1234")
47+ self._enter_pincode("1234")
48+ self.assertThat(lockscreen.shown, Eventually(Equals(False)))
49+ else:
50+ self._enter_prompt_passphrase("1234")
51+ self.assertThat(greeter.shown, Eventually(Equals(False)))
47
52
48− self.assertThat(lockscreen.shown, Eventually(Equals(False)))
49−
50− @skipUnless(model() == 'Desktop', "Broken passphrase entry on UInput (LP: #1203788).")
51 @with_lightdm_mock("single-passphrase")
53 @with_lightdm_mock("single-passphrase")
52 def test_can_unlock_passphrase_screen(self):
54 def test_can_unlock_passphrase_screen(self):
53 """Must be able to unlock the passphrase entry screen."""
55 """Must be able to unlock the passphrase entry screen."""
54 self.launch_unity()
56 self.launch_unity()
55 greeter = self.main_window.get_greeter()
57 greeter = self.main_window.get_greeter()
56− greeter.unlock()
57−
58− lockscreen = self._wait_for_lockscreen()
59− self._enter_passphrase("password")
60
58
59+ if greeter.narrowMode:
60+ greeter.swipe()
61+ lockscreen = self._wait_for_lockscreen()
62+ self._enter_pin_passphrase("password")
61− self.assertThat(lockscreen.shown, Eventually(Equals(False)))
63+ self.assertThat(lockscreen.shown, Eventually(Equals(False)))
64+ else:
65+ self._enter_prompt_passphrase("password")
66+ self.assertThat(greeter.shown, Eventually(Equals(False)))
62
67
63 @with_lightdm_mock("single-pin")
68 @with_lightdm_mock("single-pin")
64 def test_pin_screen_wrong_code(self):
69 def test_pin_screen_wrong_code(self):
65 """Entering the wrong pin code must not dismiss the lock screen."""
70 """Entering the wrong pin code must not dismiss the lock screen."""
66 self.launch_unity()
71 self.launch_unity()
67 greeter = self.main_window.get_greeter()
72 greeter = self.main_window.get_greeter()
68− greeter.unlock()
69−
70− lockscreen = self._wait_for_lockscreen()
71− self._enter_pincode("4321")
72
73
74+ if greeter.narrowMode:
75+ greeter.swipe()
76+ lockscreen = self._wait_for_lockscreen()
77+ self._enter_pincode("4321")
73− pinentryField = self.main_window.get_pinentryField()
78+ pinentryField = self.main_window.get_pinentryField()
74− self.assertThat(pinentryField.text, Eventually(Equals("")))
79+ self.assertThat(pinentryField.text, Eventually(Equals("")))
80+ self.assertThat(lockscreen.shown, Eventually(Equals(True)))
81+ else:
82+ self._enter_prompt_passphrase("4231")
83+ prompt = self.main_window.get_greeter().get_prompt()
84+ self.assertThat(prompt.text, Eventually(Equals("")))
75− self.assertThat(lockscreen.shown, Eventually(Equals(True)))
85+ self.assertThat(greeter.shown, Eventually(Equals(True)))
76
86
77− @skipUnless(model() == 'Desktop', "Broken passphrase entry on UInput (LP: #1203788).")
78 @with_lightdm_mock("single-passphrase")
87 @with_lightdm_mock("single-passphrase")
79 def test_passphrase_screen_wrong_password(self):
88 def test_passphrase_screen_wrong_password(self):
80 """Entering the wrong password must not dismiss the lock screen."""
89 """Entering the wrong password must not dismiss the lock screen."""
81 self.launch_unity()
90 self.launch_unity()
82 greeter = self.main_window.get_greeter()
91 greeter = self.main_window.get_greeter()
83− greeter.unlock()
84
92
93+ if greeter.narrowMode:
94+ greeter.swipe()
85− lockscreen = self._wait_for_lockscreen()
95+ lockscreen = self._wait_for_lockscreen()
86− self._enter_passphrase("foobar")
96+ self._enter_pin_passphrase("foobar")
87−
88− pinentryField = self.main_window.get_pinentryField()
97+ pinentryField = self.main_window.get_pinentryField()
89− self.assertThat(pinentryField.text, Eventually(Equals("")))
98+ self.assertThat(pinentryField.text, Eventually(Equals("")))
99+ self.assertThat(lockscreen.shown, Eventually(Equals(True)))
100+ else:
101+ self._enter_prompt_passphrase("foobar")
102+ prompt = self.main_window.get_greeter().get_prompt()
103+ self.assertThat(prompt.text, Eventually(Equals("")))
90− self.assertThat(lockscreen.shown, Eventually(Equals(True)))
104+ self.assertThat(greeter.shown, Eventually(Equals(True)))
91
105
92 def _wait_for_lockscreen(self):
106 def _wait_for_lockscreen(self):
93 """Wait for the lock screen to load, and return it."""
107 """Wait for the lock screen to load, and return it."""
@@ -116,9 +130,9 @@ class TestLockscreen(UnityTestCase):
116 )
130 )
117 self.touch.tap_object(self.main_window.get_pinPadButton(int(num)))
131 self.touch.tap_object(self.main_window.get_pinPadButton(int(num)))
118
132
119− def _enter_passphrase(self, passphrase):
133+ def _enter_pin_passphrase(self, passphrase):
120 """Enter the password specified in 'passphrase' into the password entry
134 """Enter the password specified in 'passphrase' into the password entry
121− field.
135+ field of the pin lock screen.
122
136
123 :param passphrase: The string you want to enter.
137 :param passphrase: The string you want to enter.
124 :raises: TypeError if passphrase is not a string.
138 :raises: TypeError if passphrase is not a string.
@@ -131,3 +145,19 @@ class TestLockscreen(UnityTestCase):
131 self.touch.tap_object(pinentryField)
145 self.touch.tap_object(pinentryField)
132 self.keyboard.type(passphrase)
146 self.keyboard.type(passphrase)
133 self.keyboard.type("\n")
147 self.keyboard.type("\n")
148+
149+ def _enter_prompt_passphrase(self, passphrase):
150+ """Enter the password specified in 'passphrase' into the password entry
151+ field of the main user list's prompt.
152+
153+ :param passphrase: The string you want to enter.
154+ :raises: TypeError if passphrase is not a string.
155+
156+ """
157+ if not isinstance(passphrase, basestring):
158+ raise TypeError("'passphrase' parameter must be a string.")
159+
160+ prompt = self.main_window.get_greeter().get_prompt()
161+ self.touch.tap_object(prompt)
162+ self.keyboard.type(passphrase)
163+ self.keyboard.type("\n")
tests/data/unity/backgrounds/blue.pngnew file

Binary file not shown.

tests/data/unity/backgrounds/red.pngnew file

Binary file not shown.

tests/mocks/CMakeLists.txt+2
@@ -1,5 +1,7 @@
1+add_subdirectory(GSettings)
1add_subdirectory(libusermetrics)
2add_subdirectory(libusermetrics)
2add_subdirectory(LightDM)
3add_subdirectory(LightDM)
4+add_subdirectory(QMenuModel)
3add_subdirectory(Ubuntu)
5add_subdirectory(Ubuntu)
4add_subdirectory(Unity)
6add_subdirectory(Unity)
5add_subdirectory(HudClient)
7add_subdirectory(HudClient)
tests/mocks/GSettings/CMakeLists.txtnew file+31
@@ -0,0 +1,31 @@
1+set(CMAKE_AUTOMOC ON)
2+
3+include(FindPkgConfig)
4+find_package(Qt5Core REQUIRED)
5+find_package(Qt5Quick REQUIRED)
6+
7+include_directories(
8+ ${CMAKE_CURRENT_BINARY_DIR}
9+ ${Qt5Core_INCLUDE_DIRS}
10+ ${Qt5Quick_INCLUDE_DIRS}
11+)
12+
13+add_definitions(-DQT_NO_KEYWORDS)
14+
15+set(GSettingsQML_SOURCES
16+ fake_gsettings.cpp
17+ plugin.cpp
18+)
19+
20+add_library(FakeGSettingsQml MODULE ${GSettingsQML_SOURCES})
21+target_link_libraries(FakeGSettingsQml
22+ ${Qt5Core_LIBRARIES}
23+ ${Qt5Quick_LIBRARIES}
24+)
25+
26+qt5_use_modules(FakeGSettingsQml Qml)
27+
28+# copy qmldir file into build directory for shadow builds
29+file(COPY "${CMAKE_CURRENT_SOURCE_DIR}/qmldir"
30+ DESTINATION ${CMAKE_CURRENT_BINARY_DIR}
31+ )
tests/mocks/GSettings/fake_gsettings.cppnew file+102
@@ -0,0 +1,102 @@
1+/*
2+ * Copyright 2013 Canonical Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU Lesser General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU Lesser General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU Lesser General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ */
16+
17+#include "fake_gsettings.h"
18+
19+#include <QList>
20+
21+GSettingsControllerQml* GSettingsControllerQml::s_controllerInstance = 0;
22+
23+GSettingsControllerQml::GSettingsControllerQml() {
24+}
25+
26+GSettingsControllerQml::~GSettingsControllerQml() {
27+ s_controllerInstance = 0;
28+}
29+
30+GSettingsControllerQml* GSettingsControllerQml::instance() {
31+ if(!s_controllerInstance) {
32+ s_controllerInstance = new GSettingsControllerQml();
33+ }
34+ return s_controllerInstance;
35+}
36+
37+void GSettingsControllerQml::registerSettingsObject(GSettingsQml *obj) {
38+ m_registeredGSettings.append(obj);
39+}
40+
41+void GSettingsControllerQml::unRegisterSettingsObject(GSettingsQml *obj) {
42+ m_registeredGSettings.removeOne(obj);
43+}
44+
45+void GSettingsControllerQml::setPictureUri(const QString &str) {
46+ Q_FOREACH (GSettingsQml *obj, m_registeredGSettings) {
47+ obj->setPictureUri(str);
48+ }
49+}
50+
51+GSettingsSchemaQml::GSettingsSchemaQml(QObject *parent): QObject(parent) {
52+}
53+
54+QByteArray GSettingsSchemaQml::id() const {
55+ return m_id;
56+}
57+
58+void GSettingsSchemaQml::setId(const QByteArray &id) {
59+ if (m_id.isEmpty()) {
60+ qWarning("GSettings.schema.id may only be set on construction");
61+ return;
62+ }
63+
64+ m_id = id;
65+}
66+
67+QByteArray GSettingsSchemaQml::path() const {
68+ return m_path;
69+}
70+
71+void GSettingsSchemaQml::setPath(const QByteArray &path) {
72+ if (m_path.isEmpty()) {
73+ qWarning("GSettings.schema.path may only be set on construction");
74+ return;
75+ }
76+
77+ m_path = path;
78+}
79+
80+GSettingsQml::GSettingsQml(QObject *parent): QObject(parent) {
81+ m_schema = new GSettingsSchemaQml(this);
82+ GSettingsControllerQml::instance()->registerSettingsObject(this);
83+}
84+
85+GSettingsQml::~GSettingsQml() {
86+ GSettingsControllerQml::instance()->unRegisterSettingsObject(this);
87+}
88+
89+GSettingsSchemaQml * GSettingsQml::schema() const {
90+ return m_schema;
91+}
92+
93+QString GSettingsQml::pictureUri() const {
94+ return m_pictureUri;
95+}
96+
97+void GSettingsQml::setPictureUri(const QString &str) {
98+ if (str != m_pictureUri) {
99+ m_pictureUri = str;
100+ Q_EMIT pictureUriChanged(m_pictureUri);
101+ }
102+}
tests/mocks/GSettings/fake_gsettings.hnew file+90
@@ -0,0 +1,90 @@
1+/*
2+ * Copyright 2013 Canonical Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU Lesser General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU Lesser General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU Lesser General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ */
16+
17+#ifndef FAKE_GSETTINGS_H
18+#define FAKE_GSETTINGS_H
19+
20+#include <QList>
21+#include <QtQml>
22+
23+class GSettingsSchemaQml: public QObject
24+{
25+ Q_OBJECT
26+
27+ Q_PROPERTY(QByteArray id READ id WRITE setId)
28+
29+public:
30+ GSettingsSchemaQml(QObject *parent = NULL);
31+
32+ QByteArray id() const;
33+ void setId(const QByteArray &id);
34+
35+ QByteArray path() const;
36+ void setPath(const QByteArray &path);
37+
38+private:
39+ QByteArray m_id;
40+ QByteArray m_path;
41+};
42+
43+class GSettingsQml: public QObject
44+{
45+ Q_OBJECT
46+
47+ Q_PROPERTY(GSettingsSchemaQml* schema READ schema NOTIFY schemaChanged)
48+ Q_PROPERTY(QString pictureUri READ pictureUri WRITE setPictureUri NOTIFY pictureUriChanged)
49+
50+public:
51+ GSettingsQml(QObject *parent = NULL);
52+ ~GSettingsQml();
53+
54+ GSettingsSchemaQml * schema() const;
55+ QString pictureUri() const;
56+
57+ void setPictureUri(const QString &str);
58+
59+Q_SIGNALS:
60+ void schemaChanged();
61+ void pictureUriChanged(const QString&);
62+
63+private:
64+ GSettingsSchemaQml* m_schema;
65+
66+ QString m_pictureUri;
67+
68+ friend class GSettingsSchemaQml;
69+};
70+
71+class GSettingsControllerQml: public QObject
72+{
73+ Q_OBJECT
74+
75+public:
76+ static GSettingsControllerQml* instance();
77+ ~GSettingsControllerQml();
78+
79+ void registerSettingsObject(GSettingsQml *obj);
80+ void unRegisterSettingsObject(GSettingsQml *obj);
81+ Q_INVOKABLE void setPictureUri(const QString &str);
82+
83+private:
84+ GSettingsControllerQml();
85+
86+ static GSettingsControllerQml* s_controllerInstance;
87+ QList<GSettingsQml *> m_registeredGSettings;
88+};
89+
90+#endif // FAKE_GSETTINGS_H
tests/mocks/GSettings/plugin.cppnew file+33
@@ -0,0 +1,33 @@
1+/*
2+ * Copyright (C) 2013 Canonical, Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ */
16+
17+#include "plugin.h"
18+#include "fake_gsettings.h"
19+
20+#include <QtQml>
21+
22+static QObject* controllerProvider(QQmlEngine* /* engine */, QJSEngine* /* scriptEngine */)
23+{
24+ return GSettingsControllerQml::instance();
25+}
26+
27+void FakeGSettingsQmlPlugin::registerTypes(const char *uri)
28+{
29+ qmlRegisterSingletonType<GSettingsControllerQml>(uri, 1, 0, "GSettingsController", controllerProvider);
30+ qmlRegisterType<GSettingsQml>(uri, 1, 0, "GSettings");
31+ qmlRegisterUncreatableType<GSettingsSchemaQml>(uri, 1, 0, "GSettingsSchema",
32+ "GSettingsSchema can only be used inside of a GSettings component");
33+}
tests/mocks/GSettings/plugin.hnew file+31
@@ -0,0 +1,31 @@
1+/*
2+ * Copyright (C) 2013 Canonical, Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ */
16+
17+#ifndef PLUGIN_H
18+#define PLUGIN_H
19+
20+#include <QtQml/QQmlExtensionPlugin>
21+
22+class FakeGSettingsQmlPlugin : public QQmlExtensionPlugin
23+{
24+ Q_OBJECT
25+ Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QQmlExtensionInterface")
26+
27+public:
28+ void registerTypes(const char *uri);
29+};
30+
31+#endif // PLUGIN_H
tests/mocks/GSettings/qmldirnew file+2
@@ -0,0 +1,2 @@
1+module GSettings
2+plugin FakeGSettingsQml
tests/mocks/LightDM/single/GreeterPrivate.cpp+2−4
@@ -34,10 +34,8 @@ void GreeterPrivate::handleAuthenticate()
34{
34{
35 Q_Q(Greeter);
35 Q_Q(Greeter);
36
36
37− if (authenticationUser == "one") {
38− authenticated = true;
37+ authenticated = true;
39− Q_EMIT q->authenticationComplete();
38+ Q_EMIT q->authenticationComplete();
40− }
41}
39}
42
40
43void GreeterPrivate::handleRespond(QString const &response)
41void GreeterPrivate::handleRespond(QString const &response)
tests/mocks/QMenuModel/CMakeLists.txtnew file+11
@@ -0,0 +1,11 @@
1+file(GLOB QMLFILES
2+ *.qml
3+ *.js
4+ qmldir
5+)
6+
7+# copy files into build directory for shadow builds
8+add_custom_target(QMenuModelQmlFiles ALL
9+ COMMAND cp ${QMLFILES} ${CMAKE_CURRENT_BINARY_DIR}
10+ DEPENDS ${QMLFILES}
11+)
tests/mocks/QMenuModel/QDBusActionGroup.qmlnew file+27
@@ -0,0 +1,27 @@
1+/*
2+ * Copyright (C) 2013 Canonical, Ltd.
3+ *
4+ * Authors:
5+ * Daniel d'Andrada <daniel.dandrada@canonical.com>
6+ *
7+ * This program is free software; you can redistribute it and/or modify
8+ * it under the terms of the GNU General Public License as published by
9+ * the Free Software Foundation; version 3.
10+ *
11+ * This program is distributed in the hope that it will be useful,
12+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
13+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14+ * GNU General Public License for more details.
15+ *
16+ * You should have received a copy of the GNU General Public License
17+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
18+ */
19+
20+import QtQuick 2.0
21+
22+QtObject {
23+ property int busType
24+ property string busName
25+ property string objectPath
26+ function start() {}
27+}
tests/mocks/QMenuModel/qmldirnew file+2
@@ -0,0 +1,2 @@
1+module QMenuModel
2+QDBusActionGroup 0.1 QDBusActionGroup.qml
tests/mocks/Ubuntu/Application/ApplicationManager.cpp+6−2
@@ -37,8 +37,6 @@ ApplicationManager::ApplicationManager(QObject *parent)
37 , m_sideStage(0)
37 , m_sideStage(0)
38{
38{
39 buildListOfAvailableApplications();
39 buildListOfAvailableApplications();
40− createMainStageComponent();
41− createSideStageComponent();
42}
40}
43
41
44ApplicationManager::~ApplicationManager()
42ApplicationManager::~ApplicationManager()
@@ -403,6 +401,9 @@ void ApplicationManager::createMainStageComponent()
403
401
404void ApplicationManager::createMainStage()
402void ApplicationManager::createMainStage()
405{
403{
404+ if (!m_mainStageComponent)
405+ createMainStageComponent();
406+
406 // The assumptions I make here really should hold.
407 // The assumptions I make here really should hold.
407 QQuickView *quickView =
408 QQuickView *quickView =
408 qobject_cast<QQuickView*>(QGuiApplication::topLevelWindows()[0]);
409 qobject_cast<QQuickView*>(QGuiApplication::topLevelWindows()[0]);
@@ -437,6 +438,9 @@ void ApplicationManager::createSideStageComponent()
437
438
438void ApplicationManager::createSideStage()
439void ApplicationManager::createSideStage()
439{
440{
441+ if (!m_sideStageComponent)
442+ createSideStageComponent();
443+
440 // The assumptions I make here really should hold.
444 // The assumptions I make here really should hold.
441 QQuickView *quickView =
445 QQuickView *quickView =
442 qobject_cast<QQuickView*>(QGuiApplication::topLevelWindows()[0]);
446 qobject_cast<QQuickView*>(QGuiApplication::topLevelWindows()[0]);
tests/mocks/Ubuntu/Application/ApplicationManager.h+4
@@ -46,6 +46,8 @@ class ApplicationManager : public QObject {
46 Q_PROPERTY(ApplicationInfo* sideStageFocusedApplication READ sideStageFocusedApplication
46 Q_PROPERTY(ApplicationInfo* sideStageFocusedApplication READ sideStageFocusedApplication
47 NOTIFY sideStageFocusedApplicationChanged)
47 NOTIFY sideStageFocusedApplicationChanged)
48
48
49+ Q_PROPERTY(bool fake READ fake CONSTANT)
50+
49 public:
51 public:
50 ApplicationManager(QObject *parent = NULL);
52 ApplicationManager(QObject *parent = NULL);
51 virtual ~ApplicationManager();
53 virtual ~ApplicationManager();
@@ -80,6 +82,8 @@ class ApplicationManager : public QObject {
80 ApplicationInfo* mainStageFocusedApplication() const;
82 ApplicationInfo* mainStageFocusedApplication() const;
81 ApplicationInfo* sideStageFocusedApplication() const;
83 ApplicationInfo* sideStageFocusedApplication() const;
82
84
85+ bool fake() { return true; }
86+
83 Q_INVOKABLE void focusApplication(int handle);
87 Q_INVOKABLE void focusApplication(int handle);
84 Q_INVOKABLE void unfocusCurrentApplication(StageHint stageHint);
88 Q_INVOKABLE void unfocusCurrentApplication(StageHint stageHint);
85 Q_INVOKABLE ApplicationInfo* startProcess(QString desktopFile,
89 Q_INVOKABLE ApplicationInfo* startProcess(QString desktopFile,
tests/mocks/Unity/CMakeLists.txt+1
@@ -44,3 +44,4 @@ file(COPY "${CMAKE_CURRENT_SOURCE_DIR}/qmldir"
44 )
44 )
45
45
46add_subdirectory(Launcher)
46add_subdirectory(Launcher)
47+add_subdirectory(Notifications)
tests/mocks/Unity/Indicators/qml/fake_menu_page1.qml−8
@@ -32,13 +32,5 @@ Indicators.FakeMenuPage {
32 horizontalCenter: parent.horizontalCenter
32 horizontalCenter: parent.horizontalCenter
33 verticalCenter: parent.verticalCenter
33 verticalCenter: parent.verticalCenter
34 }
34 }
35−
36− NumberAnimation on rotation {
37− id: rotation_animation
38− from: 0
39− to: 360
40− duration: 5000
41− loops: Animation.Infinite
42− }
43 }
35 }
44}
36}
tests/mocks/Unity/Indicators/qml/fake_menu_page2.qml−8
@@ -32,13 +32,5 @@ Indicators.FakeMenuPage {
32 horizontalCenter: parent.horizontalCenter
32 horizontalCenter: parent.horizontalCenter
33 verticalCenter: parent.verticalCenter
33 verticalCenter: parent.verticalCenter
34 }
34 }
35−
36− NumberAnimation on rotation {
37− id: rotation_animation
38− from: 0
39− to: 360
40− duration: 5000
41− loops: Animation.Infinite
42− }
43 }
35 }
44}
36}
tests/mocks/Unity/Indicators/qml/fake_menu_page3.qml−8
@@ -32,13 +32,5 @@ Indicators.FakeMenuPage {
32 horizontalCenter: parent.horizontalCenter
32 horizontalCenter: parent.horizontalCenter
33 verticalCenter: parent.verticalCenter
33 verticalCenter: parent.verticalCenter
34 }
34 }
35−
36− NumberAnimation on rotation {
37− id: rotation_animation
38− from: 0
39− to: 360
40− duration: 5000
41− loops: Animation.Infinite
42− }
43 }
35 }
44}
36}
tests/mocks/Unity/Indicators/qml/fake_menu_page4.qml−8
@@ -32,13 +32,5 @@ Indicators.FakeMenuPage {
32 horizontalCenter: parent.horizontalCenter
32 horizontalCenter: parent.horizontalCenter
33 verticalCenter: parent.verticalCenter
33 verticalCenter: parent.verticalCenter
34 }
34 }
35−
36− NumberAnimation on rotation {
37− id: rotation_animation
38− from: 0
39− to: 360
40− duration: 5000
41− loops: Animation.Infinite
42− }
43 }
35 }
44}
36}
tests/mocks/Unity/Indicators/qml/fake_menu_page5.qml−8
@@ -32,13 +32,5 @@ Indicators.FakeMenuPage {
32 horizontalCenter: parent.horizontalCenter
32 horizontalCenter: parent.horizontalCenter
33 verticalCenter: parent.verticalCenter
33 verticalCenter: parent.verticalCenter
34 }
34 }
35−
36− NumberAnimation on rotation {
37− id: rotation_animation
38− from: 0
39− to: 360
40− duration: 5000
41− loops: Animation.Infinite
42− }
43 }
35 }
44}
36}
tests/mocks/Unity/Notifications/CMakeLists.txtnew file+11
@@ -0,0 +1,11 @@
1+file(GLOB QMLFILES
2+ *.qml
3+ *.js
4+ qmldir
5+)
6+
7+# copy files into build directory for shadow builds
8+add_custom_target(NotificationsQmlFiles ALL
9+ COMMAND cp ${QMLFILES} ${CMAKE_CURRENT_BINARY_DIR}
10+ DEPENDS ${QMLFILES}
11+)
tests/mocks/Unity/fake_categories.cpp+5−2
@@ -32,10 +32,11 @@ Categories::Categories(QObject* parent)
32 m_roles[Categories::RoleName] = "name";
32 m_roles[Categories::RoleName] = "name";
33 m_roles[Categories::RoleIcon] = "icon";
33 m_roles[Categories::RoleIcon] = "icon";
34 m_roles[Categories::RoleRenderer] = "renderer";
34 m_roles[Categories::RoleRenderer] = "renderer";
35− m_roles[Categories::RoleContentType] = "content_type";
35+ m_roles[Categories::RoleContentType] = "contentType";
36 m_roles[Categories::RoleHints] = "hints";
36 m_roles[Categories::RoleHints] = "hints";
37 m_roles[Categories::RoleResults] = "results";
37 m_roles[Categories::RoleResults] = "results";
38 m_roles[Categories::RoleCount] = "count";
38 m_roles[Categories::RoleCount] = "count";
39+ m_roles[Categories::RoleCategoryIndex] = "categoryIndex";
39
40
40 // TODO This should not be needed but accumulatting the count changes
41 // TODO This should not be needed but accumulatting the count changes
41 // makes the visualization more stable and also makes crashes on fast
42 // makes the visualization more stable and also makes crashes on fast
@@ -154,7 +155,7 @@ Categories::data(const QModelIndex& index, int role) const
154
155
155 switch (role) {
156 switch (role) {
156 case RoleId:
157 case RoleId:
157− return QVariant::fromValue(index.row());
158+ return DeeListModel::data(index, 0); //ID
158 case RoleName:
159 case RoleName:
159 return DeeListModel::data(index, 1); //DISPLAY_NAME
160 return DeeListModel::data(index, 1); //DISPLAY_NAME
160 case RoleIcon:
161 case RoleIcon:
@@ -172,6 +173,8 @@ Categories::data(const QModelIndex& index, int role) const
172 return QVariant::fromValue(getFilter(index.row()));
173 return QVariant::fromValue(getFilter(index.row()));
173 case RoleCount:
174 case RoleCount:
174 return QVariant::fromValue(getFilter(index.row())->rowCount());
175 return QVariant::fromValue(getFilter(index.row())->rowCount());
176+ case RoleCategoryIndex:
177+ return QVariant::fromValue(index.row());
175 default:
178 default:
176 return QVariant();
179 return QVariant();
177 }
180 }
tests/mocks/Unity/fake_categories.h+2−1
@@ -41,7 +41,8 @@ public:
41 RoleContentType,
41 RoleContentType,
42 RoleHints,
42 RoleHints,
43 RoleResults,
43 RoleResults,
44− RoleCount
44+ RoleCount,
45+ RoleCategoryIndex
45 };
46 };
46
47
47 QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const;
48 QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const;
tests/mocks/Unity/fake_scopes.cpp+2−2
@@ -52,8 +52,8 @@ void Scopes::updateScopes()
52 clear();
52 clear();
53 addScope(new Scope("MockScope1", "People", true, this));
53 addScope(new Scope("MockScope1", "People", true, this));
54 addScope(new Scope("MockScope2", "Music", false, this));
54 addScope(new Scope("MockScope2", "Music", false, this));
55− addScope(new Scope("MockScope3", "Home", true, this));
55+ addScope(new Scope("home.scope", "Home", true, this));
56− addScope(new Scope("MockScope4", "Applications", true, this));
56+ addScope(new Scope("applications.scope", "Applications", true, this));
57 addScope(new Scope("MockScope5", "Videos", true, this));
57 addScope(new Scope("MockScope5", "Videos", true, this));
58
58
59 if (!m_loaded) {
59 if (!m_loaded) {
tests/plugins/ListViewWithPageHeader/CMakeLists.txt+6−1
@@ -1,7 +1,12 @@
1# There's no cmake var for v8 include path :-/
1# There's no cmake var for v8 include path :-/
2# so create one
2# so create one
3LIST(GET Qt5Core_INCLUDE_DIRS 0 QtCoreDir0)
3LIST(GET Qt5Core_INCLUDE_DIRS 0 QtCoreDir0)
4+if(${Qt5Core_VERSION_STRING} VERSION_LESS "5.1.0")
4−SET(Qt5V8_PRIVATE_INCLUDE_DIR ${QtCoreDir0}/../QtV8/${Qt5Core_VERSION_STRING}/QtV8)
5+ SET(Qt5V8_PRIVATE_INCLUDE_DIR ${QtCoreDir0}/../QtV8/${Qt5Core_VERSION_STRING}/QtV8)
6+else()
7+ SET(Qt5V8_PRIVATE_INCLUDE_DIR ${QtCoreDir0}/QtV8/${Qt5Core_VERSION_STRING}/QtV8)
8+endif()
9+
5
10
6include_directories(
11include_directories(
7 ${Qt5Qml_PRIVATE_INCLUDE_DIRS}
12 ${Qt5Qml_PRIVATE_INCLUDE_DIRS}
tests/plugins/ListViewWithPageHeader/listviewwithpageheadertest.cpp+12
@@ -22,7 +22,11 @@
22#include <QtTestGui>
22#include <QtTestGui>
23#pragma GCC diagnostic push
23#pragma GCC diagnostic push
24#pragma GCC diagnostic ignored "-pedantic"
24#pragma GCC diagnostic ignored "-pedantic"
25+#if (QT_VERSION < QT_VERSION_CHECK(5, 1, 0))
25#include <private/qquicklistmodel_p.h>
26#include <private/qquicklistmodel_p.h>
27+#else
28+#include <private/qqmllistmodel_p.h>
29+#endif
26#include <private/qquickanimation_p.h>
30#include <private/qquickanimation_p.h>
27#include <private/qquickitem_p.h>
31#include <private/qquickitem_p.h>
28#pragma GCC diagnostic pop
32#pragma GCC diagnostic pop
@@ -115,7 +119,11 @@ private Q_SLOTS:
115 view->engine()->addImportPath(BUILT_PLUGINS_DIR);
119 view->engine()->addImportPath(BUILT_PLUGINS_DIR);
116 view->setSource(QUrl::fromLocalFile(LISTVIEWWITHPAGEHEADER_FOLDER "/test.qml"));
120 view->setSource(QUrl::fromLocalFile(LISTVIEWWITHPAGEHEADER_FOLDER "/test.qml"));
117 lvwph = dynamic_cast<ListViewWithPageHeader*>(view->rootObject()->findChild<QQuickFlickable*>());
121 lvwph = dynamic_cast<ListViewWithPageHeader*>(view->rootObject()->findChild<QQuickFlickable*>());
122+#if (QT_VERSION < QT_VERSION_CHECK(5, 1, 0))
118 model = view->rootObject()->findChild<QQuickListModel*>();
123 model = view->rootObject()->findChild<QQuickListModel*>();
124+#else
125+ model = view->rootObject()->findChild<QQmlListModel*>();
126+#endif
119 otherDelegate = view->rootObject()->findChild<QQmlComponent*>();
127 otherDelegate = view->rootObject()->findChild<QQmlComponent*>();
120 QVERIFY(lvwph);
128 QVERIFY(lvwph);
121 QVERIFY(model);
129 QVERIFY(model);
@@ -1385,7 +1393,11 @@ private Q_SLOTS:
1385private:
1393private:
1386 QQuickView *view;
1394 QQuickView *view;
1387 ListViewWithPageHeader *lvwph;
1395 ListViewWithPageHeader *lvwph;
1396+#if (QT_VERSION < QT_VERSION_CHECK(5, 1, 0))
1388 QQuickListModel *model;
1397 QQuickListModel *model;
1398+#else
1399+ QQmlListModel *model;
1400+#endif
1389 QQmlComponent *otherDelegate;
1401 QQmlComponent *otherDelegate;
1390};
1402};
1391
1403
tests/plugins/ListViewWithPageHeader/listviewwithpageheadertestsection.cpp+63−2
@@ -22,7 +22,11 @@
22#include <QtTestGui>
22#include <QtTestGui>
23#pragma GCC diagnostic push
23#pragma GCC diagnostic push
24#pragma GCC diagnostic ignored "-pedantic"
24#pragma GCC diagnostic ignored "-pedantic"
25+#if QT_VERSION < QT_VERSION_CHECK(5, 1, 0)
25#include <private/qquicklistmodel_p.h>
26#include <private/qquicklistmodel_p.h>
27+#else
28+#include <private/qqmllistmodel_p.h>
29+#endif
26#include <private/qquickanimation_p.h>
30#include <private/qquickanimation_p.h>
27#include <private/qquickitem_p.h>
31#include <private/qquickitem_p.h>
28#pragma GCC diagnostic pop
32#pragma GCC diagnostic pop
@@ -41,6 +45,7 @@ private:
41 QCOMPARE(section(lvwph->m_visibleItems[visibleIndex]->m_sectionItem), sectionHeader);
45 QCOMPARE(section(lvwph->m_visibleItems[visibleIndex]->m_sectionItem), sectionHeader);
42 if (!sectionHeader.isNull()) {
46 if (!sectionHeader.isNull()) {
43 QCOMPARE(QQuickItemPrivate::get(lvwph->m_visibleItems[visibleIndex]->m_sectionItem)->culled, sectionHeaderCulled);
47 QCOMPARE(QQuickItemPrivate::get(lvwph->m_visibleItems[visibleIndex]->m_sectionItem)->culled, sectionHeaderCulled);
48+ QCOMPARE(sectionDelegateIndex(lvwph->m_visibleItems[visibleIndex]->m_sectionItem), lvwph->m_firstVisibleIndex + visibleIndex);
44 }
49 }
45 }
50 }
46
51
@@ -112,6 +117,11 @@ private:
112 return item ? QQmlEngine::contextForObject(item)->parentContext()->contextProperty(QLatin1String("section")).toString() : QString();
117 return item ? QQmlEngine::contextForObject(item)->parentContext()->contextProperty(QLatin1String("section")).toString() : QString();
113 }
118 }
114
119
120+ int sectionDelegateIndex(QQuickItem *item)
121+ {
122+ return item ? QQmlEngine::contextForObject(item)->parentContext()->contextProperty(QLatin1String("delegateIndex")).toInt() : -1;
123+ }
124+
115private Q_SLOTS:
125private Q_SLOTS:
116
126
117 void initTestCase()
127 void initTestCase()
@@ -124,7 +134,11 @@ private Q_SLOTS:
124 view->engine()->addImportPath(BUILT_PLUGINS_DIR);
134 view->engine()->addImportPath(BUILT_PLUGINS_DIR);
125 view->setSource(QUrl::fromLocalFile(LISTVIEWWITHPAGEHEADER_FOLDER "/test_section.qml"));
135 view->setSource(QUrl::fromLocalFile(LISTVIEWWITHPAGEHEADER_FOLDER "/test_section.qml"));
126 lvwph = dynamic_cast<ListViewWithPageHeader*>(view->rootObject()->findChild<QQuickFlickable*>());
136 lvwph = dynamic_cast<ListViewWithPageHeader*>(view->rootObject()->findChild<QQuickFlickable*>());
137+#if (QT_VERSION < QT_VERSION_CHECK(5, 1, 0))
127 model = view->rootObject()->findChild<QQuickListModel*>();
138 model = view->rootObject()->findChild<QQuickListModel*>();
139+#else
140+ model = view->rootObject()->findChild<QQmlListModel*>();
141+#endif
128 otherDelegate = view->rootObject()->findChild<QQmlComponent*>();
142 otherDelegate = view->rootObject()->findChild<QQmlComponent*>();
129 QVERIFY(lvwph);
143 QVERIFY(lvwph);
130 QVERIFY(model);
144 QVERIFY(model);
@@ -212,6 +226,7 @@ private Q_SLOTS:
212 QCOMPARE(lvwph->m_headerItemShownHeight, 0.);
226 QCOMPARE(lvwph->m_headerItemShownHeight, 0.);
213 QVERIFY(!QQuickItemPrivate::get(lvwph->m_topSectionItem)->culled);
227 QVERIFY(!QQuickItemPrivate::get(lvwph->m_topSectionItem)->culled);
214 QCOMPARE(section(lvwph->m_topSectionItem), QString("Regular"));
228 QCOMPARE(section(lvwph->m_topSectionItem), QString("Regular"));
229+ QCOMPARE(sectionDelegateIndex(lvwph->m_topSectionItem), 1);
215 QCOMPARE(lvwph->m_topSectionItem->y(), 0.);
230 QCOMPARE(lvwph->m_topSectionItem->y(), 0.);
216 }
231 }
217
232
@@ -233,6 +248,7 @@ private Q_SLOTS:
233 QCOMPARE(lvwph->m_headerItemShownHeight, 0.);
248 QCOMPARE(lvwph->m_headerItemShownHeight, 0.);
234 QVERIFY(!QQuickItemPrivate::get(lvwph->m_topSectionItem)->culled);
249 QVERIFY(!QQuickItemPrivate::get(lvwph->m_topSectionItem)->culled);
235 QCOMPARE(section(lvwph->m_topSectionItem), QString("Mild"));
250 QCOMPARE(section(lvwph->m_topSectionItem), QString("Mild"));
251+ QCOMPARE(sectionDelegateIndex(lvwph->m_topSectionItem), 2);
236 QCOMPARE(lvwph->m_topSectionItem->y(), 0.);
252 QCOMPARE(lvwph->m_topSectionItem->y(), 0.);
237 }
253 }
238
254
@@ -254,6 +270,7 @@ private Q_SLOTS:
254 QCOMPARE(lvwph->m_headerItemShownHeight, 0.);
270 QCOMPARE(lvwph->m_headerItemShownHeight, 0.);
255 QVERIFY(!QQuickItemPrivate::get(lvwph->m_topSectionItem)->culled);
271 QVERIFY(!QQuickItemPrivate::get(lvwph->m_topSectionItem)->culled);
256 QCOMPARE(section(lvwph->m_topSectionItem), QString("Agressive"));
272 QCOMPARE(section(lvwph->m_topSectionItem), QString("Agressive"));
273+ QCOMPARE(sectionDelegateIndex(lvwph->m_topSectionItem), 0);
257 QCOMPARE(lvwph->m_topSectionItem->y(), 0.);
274 QCOMPARE(lvwph->m_topSectionItem->y(), 0.);
258
275
259 changeContentY(-30);
276 changeContentY(-30);
@@ -272,6 +289,7 @@ private Q_SLOTS:
272 QCOMPARE(lvwph->m_headerItemShownHeight, 30.);
289 QCOMPARE(lvwph->m_headerItemShownHeight, 30.);
273 QVERIFY(!QQuickItemPrivate::get(lvwph->m_topSectionItem)->culled);
290 QVERIFY(!QQuickItemPrivate::get(lvwph->m_topSectionItem)->culled);
274 QCOMPARE(section(lvwph->m_topSectionItem), QString("Agressive"));
291 QCOMPARE(section(lvwph->m_topSectionItem), QString("Agressive"));
292+ QCOMPARE(sectionDelegateIndex(lvwph->m_topSectionItem), 0);
275 QCOMPARE(lvwph->m_topSectionItem->y(), 0.);
293 QCOMPARE(lvwph->m_topSectionItem->y(), 0.);
276 }
294 }
277
295
@@ -327,6 +345,7 @@ private Q_SLOTS:
327 QCOMPARE(lvwph->m_headerItemShownHeight, 0.);
345 QCOMPARE(lvwph->m_headerItemShownHeight, 0.);
328 QVERIFY(!QQuickItemPrivate::get(lvwph->m_topSectionItem)->culled);
346 QVERIFY(!QQuickItemPrivate::get(lvwph->m_topSectionItem)->culled);
329 QCOMPARE(section(lvwph->m_topSectionItem), QString("Regular"));
347 QCOMPARE(section(lvwph->m_topSectionItem), QString("Regular"));
348+ QCOMPARE(sectionDelegateIndex(lvwph->m_topSectionItem), 1);
330 QCOMPARE(lvwph->m_topSectionItem->y(), 0.);
349 QCOMPARE(lvwph->m_topSectionItem->y(), 0.);
331
350
332 lvwph->positionAtBeginning();
351 lvwph->positionAtBeginning();
@@ -352,6 +371,7 @@ private Q_SLOTS:
352 QCOMPARE(lvwph->m_headerItemShownHeight, 0.);
371 QCOMPARE(lvwph->m_headerItemShownHeight, 0.);
353 QVERIFY(!QQuickItemPrivate::get(lvwph->m_topSectionItem)->culled);
372 QVERIFY(!QQuickItemPrivate::get(lvwph->m_topSectionItem)->culled);
354 QCOMPARE(section(lvwph->m_topSectionItem), QString("Mild"));
373 QCOMPARE(section(lvwph->m_topSectionItem), QString("Mild"));
374+ QCOMPARE(sectionDelegateIndex(lvwph->m_topSectionItem), 2);
355 QCOMPARE(lvwph->m_topSectionItem->y(), 0.);
375 QCOMPARE(lvwph->m_topSectionItem->y(), 0.);
356
376
357 lvwph->positionAtBeginning();
377 lvwph->positionAtBeginning();
@@ -396,6 +416,7 @@ private Q_SLOTS:
396 QCOMPARE(lvwph->m_headerItemShownHeight, 0.);
416 QCOMPARE(lvwph->m_headerItemShownHeight, 0.);
397 QVERIFY(!QQuickItemPrivate::get(lvwph->m_topSectionItem)->culled);
417 QVERIFY(!QQuickItemPrivate::get(lvwph->m_topSectionItem)->culled);
398 QCOMPARE(section(lvwph->m_topSectionItem), QString("Regular"));
418 QCOMPARE(section(lvwph->m_topSectionItem), QString("Regular"));
419+ QCOMPARE(sectionDelegateIndex(lvwph->m_topSectionItem), 1);
399 QCOMPARE(lvwph->m_topSectionItem->y(), 0.);
420 QCOMPARE(lvwph->m_topSectionItem->y(), 0.);
400
421
401 model->setProperty(0, "size", 400);
422 model->setProperty(0, "size", 400);
@@ -415,6 +436,7 @@ private Q_SLOTS:
415 QCOMPARE(lvwph->m_headerItemShownHeight, 0.);
436 QCOMPARE(lvwph->m_headerItemShownHeight, 0.);
416 QVERIFY(!QQuickItemPrivate::get(lvwph->m_topSectionItem)->culled);
437 QVERIFY(!QQuickItemPrivate::get(lvwph->m_topSectionItem)->culled);
417 QCOMPARE(section(lvwph->m_topSectionItem), QString("Regular"));
438 QCOMPARE(section(lvwph->m_topSectionItem), QString("Regular"));
439+ QCOMPARE(sectionDelegateIndex(lvwph->m_topSectionItem), 1);
418 QCOMPARE(lvwph->m_topSectionItem->y(), 0.);
440 QCOMPARE(lvwph->m_topSectionItem->y(), 0.);
419
441
420 scrollToTop();
442 scrollToTop();
@@ -468,6 +490,7 @@ private Q_SLOTS:
468 QCOMPARE(lvwph->m_headerItemShownHeight, 0.);
490 QCOMPARE(lvwph->m_headerItemShownHeight, 0.);
469 QVERIFY(!QQuickItemPrivate::get(lvwph->m_topSectionItem)->culled);
491 QVERIFY(!QQuickItemPrivate::get(lvwph->m_topSectionItem)->culled);
470 QCOMPARE(section(lvwph->m_topSectionItem), QString("Mild"));
492 QCOMPARE(section(lvwph->m_topSectionItem), QString("Mild"));
493+ QCOMPARE(sectionDelegateIndex(lvwph->m_topSectionItem), 2);
471 QCOMPARE(lvwph->m_topSectionItem->y(), 0.);
494 QCOMPARE(lvwph->m_topSectionItem->y(), 0.);
472
495
473 model->setProperty(0, "size", 400);
496 model->setProperty(0, "size", 400);
@@ -487,6 +510,7 @@ private Q_SLOTS:
487 QCOMPARE(lvwph->m_headerItemShownHeight, 0.);
510 QCOMPARE(lvwph->m_headerItemShownHeight, 0.);
488 QVERIFY(!QQuickItemPrivate::get(lvwph->m_topSectionItem)->culled);
511 QVERIFY(!QQuickItemPrivate::get(lvwph->m_topSectionItem)->culled);
489 QCOMPARE(section(lvwph->m_topSectionItem), QString("Mild"));
512 QCOMPARE(section(lvwph->m_topSectionItem), QString("Mild"));
513+ QCOMPARE(sectionDelegateIndex(lvwph->m_topSectionItem), 2);
490 QCOMPARE(lvwph->m_topSectionItem->y(), 0.);
514 QCOMPARE(lvwph->m_topSectionItem->y(), 0.);
491
515
492 scrollToTop();
516 scrollToTop();
@@ -523,6 +547,7 @@ private Q_SLOTS:
523 QCOMPARE(lvwph->m_headerItemShownHeight, 0.);
547 QCOMPARE(lvwph->m_headerItemShownHeight, 0.);
524 QVERIFY(!QQuickItemPrivate::get(lvwph->m_topSectionItem)->culled);
548 QVERIFY(!QQuickItemPrivate::get(lvwph->m_topSectionItem)->culled);
525 QCOMPARE(section(lvwph->m_topSectionItem), QString("Bold"));
549 QCOMPARE(section(lvwph->m_topSectionItem), QString("Bold"));
550+ QCOMPARE(sectionDelegateIndex(lvwph->m_topSectionItem), 3);
526 QCOMPARE(lvwph->m_topSectionItem->y(), 0.);
551 QCOMPARE(lvwph->m_topSectionItem->y(), 0.);
527
552
528 changeContentY(-30);
553 changeContentY(-30);
@@ -540,6 +565,7 @@ private Q_SLOTS:
540 QCOMPARE(lvwph->m_headerItemShownHeight, 30.);
565 QCOMPARE(lvwph->m_headerItemShownHeight, 30.);
541 QVERIFY(!QQuickItemPrivate::get(lvwph->m_topSectionItem)->culled);
566 QVERIFY(!QQuickItemPrivate::get(lvwph->m_topSectionItem)->culled);
542 QCOMPARE(section(lvwph->m_topSectionItem), QString("Bold"));
567 QCOMPARE(section(lvwph->m_topSectionItem), QString("Bold"));
568+ QCOMPARE(sectionDelegateIndex(lvwph->m_topSectionItem), 3);
543 QCOMPARE(lvwph->m_topSectionItem->y(), 0.);
569 QCOMPARE(lvwph->m_topSectionItem->y(), 0.);
544
570
545 changeContentY(30);
571 changeContentY(30);
@@ -557,6 +583,7 @@ private Q_SLOTS:
557 QCOMPARE(lvwph->m_headerItemShownHeight, 0.);
583 QCOMPARE(lvwph->m_headerItemShownHeight, 0.);
558 QVERIFY(!QQuickItemPrivate::get(lvwph->m_topSectionItem)->culled);
584 QVERIFY(!QQuickItemPrivate::get(lvwph->m_topSectionItem)->culled);
559 QCOMPARE(section(lvwph->m_topSectionItem), QString("Bold"));
585 QCOMPARE(section(lvwph->m_topSectionItem), QString("Bold"));
586+ QCOMPARE(sectionDelegateIndex(lvwph->m_topSectionItem), 3);
560 QCOMPARE(lvwph->m_topSectionItem->y(), 0.);
587 QCOMPARE(lvwph->m_topSectionItem->y(), 0.);
561
588
562 changeContentY(-30);
589 changeContentY(-30);
@@ -574,6 +601,7 @@ private Q_SLOTS:
574 QCOMPARE(lvwph->m_headerItemShownHeight, 30.);
601 QCOMPARE(lvwph->m_headerItemShownHeight, 30.);
575 QVERIFY(!QQuickItemPrivate::get(lvwph->m_topSectionItem)->culled);
602 QVERIFY(!QQuickItemPrivate::get(lvwph->m_topSectionItem)->culled);
576 QCOMPARE(section(lvwph->m_topSectionItem), QString("Bold"));
603 QCOMPARE(section(lvwph->m_topSectionItem), QString("Bold"));
604+ QCOMPARE(sectionDelegateIndex(lvwph->m_topSectionItem), 3);
577 QCOMPARE(lvwph->m_topSectionItem->y(), 0.);
605 QCOMPARE(lvwph->m_topSectionItem->y(), 0.);
578 }
606 }
579
607
@@ -594,6 +622,7 @@ private Q_SLOTS:
594 QCOMPARE(lvwph->m_headerItemShownHeight, 0.);
622 QCOMPARE(lvwph->m_headerItemShownHeight, 0.);
595 QVERIFY(!QQuickItemPrivate::get(lvwph->m_topSectionItem)->culled);
623 QVERIFY(!QQuickItemPrivate::get(lvwph->m_topSectionItem)->culled);
596 QCOMPARE(section(lvwph->m_topSectionItem), QString("Bold"));
624 QCOMPARE(section(lvwph->m_topSectionItem), QString("Bold"));
625+ QCOMPARE(sectionDelegateIndex(lvwph->m_topSectionItem), 3);
597 QCOMPARE(lvwph->m_topSectionItem->y(), 0.);
626 QCOMPARE(lvwph->m_topSectionItem->y(), 0.);
598
627
599 lvwph->setDelegate(otherDelegate);
628 lvwph->setDelegate(otherDelegate);
@@ -652,6 +681,7 @@ private Q_SLOTS:
652 QCOMPARE(lvwph->m_headerItemShownHeight, 0.);
681 QCOMPARE(lvwph->m_headerItemShownHeight, 0.);
653 QVERIFY(!QQuickItemPrivate::get(lvwph->m_topSectionItem)->culled);
682 QVERIFY(!QQuickItemPrivate::get(lvwph->m_topSectionItem)->culled);
654 QCOMPARE(section(lvwph->m_topSectionItem), QString("Bold"));
683 QCOMPARE(section(lvwph->m_topSectionItem), QString("Bold"));
684+ QCOMPARE(sectionDelegateIndex(lvwph->m_topSectionItem), 3);
655 QCOMPARE(lvwph->m_topSectionItem->y(), 0.);
685 QCOMPARE(lvwph->m_topSectionItem->y(), 0.);
656
686
657 scrollToTop();
687 scrollToTop();
@@ -690,6 +720,7 @@ private Q_SLOTS:
690 QTRY_VERIFY(lvwph->isAtYEnd());
720 QTRY_VERIFY(lvwph->isAtYEnd());
691 QVERIFY(!QQuickItemPrivate::get(lvwph->m_topSectionItem)->culled);
721 QVERIFY(!QQuickItemPrivate::get(lvwph->m_topSectionItem)->culled);
692 QCOMPARE(section(lvwph->m_topSectionItem), QString("Bold"));
722 QCOMPARE(section(lvwph->m_topSectionItem), QString("Bold"));
723+ QCOMPARE(sectionDelegateIndex(lvwph->m_topSectionItem), 3);
693 QCOMPARE(lvwph->m_topSectionItem->y(), 0.);
724 QCOMPARE(lvwph->m_topSectionItem->y(), 0.);
694
725
695 scrollToTop();
726 scrollToTop();
@@ -726,6 +757,7 @@ private Q_SLOTS:
726 QCOMPARE(lvwph->m_headerItemShownHeight, 0.);
757 QCOMPARE(lvwph->m_headerItemShownHeight, 0.);
727 QVERIFY(!QQuickItemPrivate::get(lvwph->m_topSectionItem)->culled);
758 QVERIFY(!QQuickItemPrivate::get(lvwph->m_topSectionItem)->culled);
728 QCOMPARE(section(lvwph->m_topSectionItem), QString("Agressive"));
759 QCOMPARE(section(lvwph->m_topSectionItem), QString("Agressive"));
760+ QCOMPARE(sectionDelegateIndex(lvwph->m_topSectionItem), 0);
729 QCOMPARE(lvwph->m_topSectionItem->y(), 0.);
761 QCOMPARE(lvwph->m_topSectionItem->y(), 0.);
730 }
762 }
731
763
@@ -810,6 +842,7 @@ private Q_SLOTS:
810 QCOMPARE(lvwph->m_headerItemShownHeight, 0.);
842 QCOMPARE(lvwph->m_headerItemShownHeight, 0.);
811 QVERIFY(!QQuickItemPrivate::get(lvwph->m_topSectionItem)->culled);
843 QVERIFY(!QQuickItemPrivate::get(lvwph->m_topSectionItem)->culled);
812 QCOMPARE(section(lvwph->m_topSectionItem), QString("Mild"));
844 QCOMPARE(section(lvwph->m_topSectionItem), QString("Mild"));
845+ QCOMPARE(sectionDelegateIndex(lvwph->m_topSectionItem), 2);
813 QCOMPARE(lvwph->m_topSectionItem->y(), 0.);
846 QCOMPARE(lvwph->m_topSectionItem->y(), 0.);
814
847
815 QMetaObject::invokeMethod(model, "insertItem", Q_ARG(QVariant, 1), Q_ARG(QVariant, 100), Q_ARG(QVariant, "Agressive"));
848 QMetaObject::invokeMethod(model, "insertItem", Q_ARG(QVariant, 1), Q_ARG(QVariant, 100), Q_ARG(QVariant, "Agressive"));
@@ -830,6 +863,7 @@ private Q_SLOTS:
830 QCOMPARE(lvwph->m_headerItemShownHeight, 0.);
863 QCOMPARE(lvwph->m_headerItemShownHeight, 0.);
831 QVERIFY(!QQuickItemPrivate::get(lvwph->m_topSectionItem)->culled);
864 QVERIFY(!QQuickItemPrivate::get(lvwph->m_topSectionItem)->culled);
832 QCOMPARE(section(lvwph->m_topSectionItem), QString("Mild"));
865 QCOMPARE(section(lvwph->m_topSectionItem), QString("Mild"));
866+ QCOMPARE(sectionDelegateIndex(lvwph->m_topSectionItem), 4);
833 QCOMPARE(lvwph->m_topSectionItem->y(), 0.);
867 QCOMPARE(lvwph->m_topSectionItem->y(), 0.);
834
868
835 scrollToTop();
869 scrollToTop();
@@ -870,6 +904,7 @@ private Q_SLOTS:
870 QCOMPARE(lvwph->m_headerItemShownHeight, 0.);
904 QCOMPARE(lvwph->m_headerItemShownHeight, 0.);
871 QVERIFY(!QQuickItemPrivate::get(lvwph->m_topSectionItem)->culled);
905 QVERIFY(!QQuickItemPrivate::get(lvwph->m_topSectionItem)->culled);
872 QCOMPARE(section(lvwph->m_topSectionItem), QString("Agressive"));
906 QCOMPARE(section(lvwph->m_topSectionItem), QString("Agressive"));
907+ QCOMPARE(sectionDelegateIndex(lvwph->m_topSectionItem), 0);
873 QCOMPARE(lvwph->m_topSectionItem->y(), 0.);
908 QCOMPARE(lvwph->m_topSectionItem->y(), 0.);
874
909
875 QMetaObject::invokeMethod(model, "insertItem", Q_ARG(QVariant, 3), Q_ARG(QVariant, 100), Q_ARG(QVariant, "Agressive"));
910 QMetaObject::invokeMethod(model, "insertItem", Q_ARG(QVariant, 3), Q_ARG(QVariant, 100), Q_ARG(QVariant, "Agressive"));
@@ -890,6 +925,7 @@ private Q_SLOTS:
890 QCOMPARE(lvwph->m_headerItemShownHeight, 0.);
925 QCOMPARE(lvwph->m_headerItemShownHeight, 0.);
891 QVERIFY(!QQuickItemPrivate::get(lvwph->m_topSectionItem)->culled);
926 QVERIFY(!QQuickItemPrivate::get(lvwph->m_topSectionItem)->culled);
892 QCOMPARE(section(lvwph->m_topSectionItem), QString("Agressive"));
927 QCOMPARE(section(lvwph->m_topSectionItem), QString("Agressive"));
928+ QCOMPARE(sectionDelegateIndex(lvwph->m_topSectionItem), 0);
893 QCOMPARE(lvwph->m_topSectionItem->y(), 0.);
929 QCOMPARE(lvwph->m_topSectionItem->y(), 0.);
894 }
930 }
895
931
@@ -912,6 +948,7 @@ private Q_SLOTS:
912 QCOMPARE(lvwph->m_headerItemShownHeight, 0.);
948 QCOMPARE(lvwph->m_headerItemShownHeight, 0.);
913 QVERIFY(!QQuickItemPrivate::get(lvwph->m_topSectionItem)->culled);
949 QVERIFY(!QQuickItemPrivate::get(lvwph->m_topSectionItem)->culled);
914 QCOMPARE(section(lvwph->m_topSectionItem), QString("Mild"));
950 QCOMPARE(section(lvwph->m_topSectionItem), QString("Mild"));
951+ QCOMPARE(sectionDelegateIndex(lvwph->m_topSectionItem), 2);
915 QCOMPARE(lvwph->m_topSectionItem->y(), 0.);
952 QCOMPARE(lvwph->m_topSectionItem->y(), 0.);
916
953
917 QMetaObject::invokeMethod(model, "insertItem", Q_ARG(QVariant, 1), Q_ARG(QVariant, 100), Q_ARG(QVariant, "Agressive"));
954 QMetaObject::invokeMethod(model, "insertItem", Q_ARG(QVariant, 1), Q_ARG(QVariant, 100), Q_ARG(QVariant, "Agressive"));
@@ -932,6 +969,7 @@ private Q_SLOTS:
932 QCOMPARE(lvwph->m_headerItemShownHeight, 0.);
969 QCOMPARE(lvwph->m_headerItemShownHeight, 0.);
933 QVERIFY(!QQuickItemPrivate::get(lvwph->m_topSectionItem)->culled);
970 QVERIFY(!QQuickItemPrivate::get(lvwph->m_topSectionItem)->culled);
934 QCOMPARE(section(lvwph->m_topSectionItem), QString("Mild"));
971 QCOMPARE(section(lvwph->m_topSectionItem), QString("Mild"));
972+ QCOMPARE(sectionDelegateIndex(lvwph->m_topSectionItem), 4);
935 QCOMPARE(lvwph->m_topSectionItem->y(), 0.);
973 QCOMPARE(lvwph->m_topSectionItem->y(), 0.);
936 }
974 }
937
975
@@ -954,6 +992,7 @@ private Q_SLOTS:
954 QCOMPARE(lvwph->m_headerItemShownHeight, 0.);
992 QCOMPARE(lvwph->m_headerItemShownHeight, 0.);
955 QVERIFY(!QQuickItemPrivate::get(lvwph->m_topSectionItem)->culled);
993 QVERIFY(!QQuickItemPrivate::get(lvwph->m_topSectionItem)->culled);
956 QCOMPARE(section(lvwph->m_topSectionItem), QString("Regular"));
994 QCOMPARE(section(lvwph->m_topSectionItem), QString("Regular"));
995+ QCOMPARE(sectionDelegateIndex(lvwph->m_topSectionItem), 1);
957 QCOMPARE(lvwph->m_topSectionItem->y(), 0.);
996 QCOMPARE(lvwph->m_topSectionItem->y(), 0.);
958
997
959 QMetaObject::invokeMethod(model, "insertItem", Q_ARG(QVariant, 1), Q_ARG(QVariant, 100), Q_ARG(QVariant, "Agressive"));
998 QMetaObject::invokeMethod(model, "insertItem", Q_ARG(QVariant, 1), Q_ARG(QVariant, 100), Q_ARG(QVariant, "Agressive"));
@@ -974,6 +1013,7 @@ private Q_SLOTS:
974 QCOMPARE(lvwph->m_headerItemShownHeight, 0.);
1013 QCOMPARE(lvwph->m_headerItemShownHeight, 0.);
975 QVERIFY(!QQuickItemPrivate::get(lvwph->m_topSectionItem)->culled);
1014 QVERIFY(!QQuickItemPrivate::get(lvwph->m_topSectionItem)->culled);
976 QCOMPARE(section(lvwph->m_topSectionItem), QString("Regular"));
1015 QCOMPARE(section(lvwph->m_topSectionItem), QString("Regular"));
1016+ QCOMPARE(sectionDelegateIndex(lvwph->m_topSectionItem), 3);
977 QCOMPARE(lvwph->m_topSectionItem->y(), 0.);
1017 QCOMPARE(lvwph->m_topSectionItem->y(), 0.);
978
1018
979 scrollToTop();
1019 scrollToTop();
@@ -1021,6 +1061,7 @@ private Q_SLOTS:
1021 QVERIFY(!lvwph->isAtYEnd());
1061 QVERIFY(!lvwph->isAtYEnd());
1022 QVERIFY(!QQuickItemPrivate::get(lvwph->m_topSectionItem)->culled);
1062 QVERIFY(!QQuickItemPrivate::get(lvwph->m_topSectionItem)->culled);
1023 QCOMPARE(section(lvwph->m_topSectionItem), QString("Bold"));
1063 QCOMPARE(section(lvwph->m_topSectionItem), QString("Bold"));
1064+ QCOMPARE(sectionDelegateIndex(lvwph->m_topSectionItem), 3);
1024 QCOMPARE(lvwph->m_topSectionItem->y(), 0.);
1065 QCOMPARE(lvwph->m_topSectionItem->y(), 0.);
1025
1066
1026 scrollToBottom();
1067 scrollToBottom();
@@ -1041,6 +1082,7 @@ private Q_SLOTS:
1041 QVERIFY(lvwph->isAtYEnd());
1082 QVERIFY(lvwph->isAtYEnd());
1042 QVERIFY(!QQuickItemPrivate::get(lvwph->m_topSectionItem)->culled);
1083 QVERIFY(!QQuickItemPrivate::get(lvwph->m_topSectionItem)->culled);
1043 QCOMPARE(section(lvwph->m_topSectionItem), QString("Lazy"));
1084 QCOMPARE(section(lvwph->m_topSectionItem), QString("Lazy"));
1085+ QCOMPARE(sectionDelegateIndex(lvwph->m_topSectionItem), 5);
1044 QCOMPARE(lvwph->m_topSectionItem->y(), 0.);
1086 QCOMPARE(lvwph->m_topSectionItem->y(), 0.);
1045 }
1087 }
1046
1088
@@ -1094,6 +1136,7 @@ private Q_SLOTS:
1094 QCOMPARE(lvwph->m_headerItemShownHeight, 0.);
1136 QCOMPARE(lvwph->m_headerItemShownHeight, 0.);
1095 QVERIFY(!QQuickItemPrivate::get(lvwph->m_topSectionItem)->culled);
1137 QVERIFY(!QQuickItemPrivate::get(lvwph->m_topSectionItem)->culled);
1096 QCOMPARE(section(lvwph->m_topSectionItem), QString("Bold"));
1138 QCOMPARE(section(lvwph->m_topSectionItem), QString("Bold"));
1139+ QCOMPARE(sectionDelegateIndex(lvwph->m_topSectionItem), 13);
1097 QCOMPARE(lvwph->m_topSectionItem->y(), 0.);
1140 QCOMPARE(lvwph->m_topSectionItem->y(), 0.);
1098
1141
1099 changeContentY(-1700);
1142 changeContentY(-1700);
@@ -1118,6 +1161,7 @@ private Q_SLOTS:
1118 QCOMPARE(lvwph->m_headerItemShownHeight, 50.);
1161 QCOMPARE(lvwph->m_headerItemShownHeight, 50.);
1119 QVERIFY(!QQuickItemPrivate::get(lvwph->m_topSectionItem)->culled);
1162 QVERIFY(!QQuickItemPrivate::get(lvwph->m_topSectionItem)->culled);
1120 QCOMPARE(section(lvwph->m_topSectionItem), QString("Regular"));
1163 QCOMPARE(section(lvwph->m_topSectionItem), QString("Regular"));
1164+ QCOMPARE(sectionDelegateIndex(lvwph->m_topSectionItem), 4);
1121 QCOMPARE(lvwph->m_topSectionItem->y(), -23.);
1165 QCOMPARE(lvwph->m_topSectionItem->y(), -23.);
1122 }
1166 }
1123
1167
@@ -1179,6 +1223,7 @@ private Q_SLOTS:
1179 QCOMPARE(lvwph->m_headerItemShownHeight, 0.);
1223 QCOMPARE(lvwph->m_headerItemShownHeight, 0.);
1180 QVERIFY(!QQuickItemPrivate::get(lvwph->m_topSectionItem)->culled);
1224 QVERIFY(!QQuickItemPrivate::get(lvwph->m_topSectionItem)->culled);
1181 QCOMPARE(section(lvwph->m_topSectionItem), QString("Bold"));
1225 QCOMPARE(section(lvwph->m_topSectionItem), QString("Bold"));
1226+ QCOMPARE(sectionDelegateIndex(lvwph->m_topSectionItem), 1);
1182 QCOMPARE(lvwph->m_topSectionItem->y(), 0.);
1227 QCOMPARE(lvwph->m_topSectionItem->y(), 0.);
1183 }
1228 }
1184
1229
@@ -1202,6 +1247,7 @@ private Q_SLOTS:
1202 QCOMPARE(lvwph->m_headerItemShownHeight, 0.);
1247 QCOMPARE(lvwph->m_headerItemShownHeight, 0.);
1203 QVERIFY(!QQuickItemPrivate::get(lvwph->m_topSectionItem)->culled);
1248 QVERIFY(!QQuickItemPrivate::get(lvwph->m_topSectionItem)->culled);
1204 QCOMPARE(section(lvwph->m_topSectionItem), QString("Mild"));
1249 QCOMPARE(section(lvwph->m_topSectionItem), QString("Mild"));
1250+ QCOMPARE(sectionDelegateIndex(lvwph->m_topSectionItem), 2);
1205 QCOMPARE(lvwph->m_topSectionItem->y(), 0.);
1251 QCOMPARE(lvwph->m_topSectionItem->y(), 0.);
1206 }
1252 }
1207
1253
@@ -1224,6 +1270,7 @@ private Q_SLOTS:
1224 QCOMPARE(lvwph->m_headerItemShownHeight, 0.);
1270 QCOMPARE(lvwph->m_headerItemShownHeight, 0.);
1225 QVERIFY(!QQuickItemPrivate::get(lvwph->m_topSectionItem)->culled);
1271 QVERIFY(!QQuickItemPrivate::get(lvwph->m_topSectionItem)->culled);
1226 QCOMPARE(section(lvwph->m_topSectionItem), QString("Mild"));
1272 QCOMPARE(section(lvwph->m_topSectionItem), QString("Mild"));
1273+ QCOMPARE(sectionDelegateIndex(lvwph->m_topSectionItem), 2);
1227 QCOMPARE(lvwph->m_topSectionItem->y(), 0.);
1274 QCOMPARE(lvwph->m_topSectionItem->y(), 0.);
1228
1275
1229 QMetaObject::invokeMethod(model, "removeItems", Q_ARG(QVariant, 1), Q_ARG(QVariant, 1));
1276 QMetaObject::invokeMethod(model, "removeItems", Q_ARG(QVariant, 1), Q_ARG(QVariant, 1));
@@ -1243,6 +1290,7 @@ private Q_SLOTS:
1243 QCOMPARE(lvwph->m_headerItemShownHeight, 0.);
1290 QCOMPARE(lvwph->m_headerItemShownHeight, 0.);
1244 QVERIFY(!QQuickItemPrivate::get(lvwph->m_topSectionItem)->culled);
1291 QVERIFY(!QQuickItemPrivate::get(lvwph->m_topSectionItem)->culled);
1245 QCOMPARE(section(lvwph->m_topSectionItem), QString("Mild"));
1292 QCOMPARE(section(lvwph->m_topSectionItem), QString("Mild"));
1293+ QCOMPARE(sectionDelegateIndex(lvwph->m_topSectionItem), 1);
1246 QCOMPARE(lvwph->m_topSectionItem->y(), 0.);
1294 QCOMPARE(lvwph->m_topSectionItem->y(), 0.);
1247 }
1295 }
1248
1296
@@ -1265,6 +1313,7 @@ private Q_SLOTS:
1265 QCOMPARE(lvwph->m_headerItemShownHeight, 0.);
1313 QCOMPARE(lvwph->m_headerItemShownHeight, 0.);
1266 QVERIFY(!QQuickItemPrivate::get(lvwph->m_topSectionItem)->culled);
1314 QVERIFY(!QQuickItemPrivate::get(lvwph->m_topSectionItem)->culled);
1267 QCOMPARE(section(lvwph->m_topSectionItem), QString("Mild"));
1315 QCOMPARE(section(lvwph->m_topSectionItem), QString("Mild"));
1316+ QCOMPARE(sectionDelegateIndex(lvwph->m_topSectionItem), 2);
1268 QCOMPARE(lvwph->m_topSectionItem->y(), 0.);
1317 QCOMPARE(lvwph->m_topSectionItem->y(), 0.);
1269
1318
1270 QMetaObject::invokeMethod(model, "removeItems", Q_ARG(QVariant, 3), Q_ARG(QVariant, 1));
1319 QMetaObject::invokeMethod(model, "removeItems", Q_ARG(QVariant, 3), Q_ARG(QVariant, 1));
@@ -1284,6 +1333,7 @@ private Q_SLOTS:
1284 QCOMPARE(lvwph->m_headerItemShownHeight, 0.);
1333 QCOMPARE(lvwph->m_headerItemShownHeight, 0.);
1285 QVERIFY(!QQuickItemPrivate::get(lvwph->m_topSectionItem)->culled);
1334 QVERIFY(!QQuickItemPrivate::get(lvwph->m_topSectionItem)->culled);
1286 QCOMPARE(section(lvwph->m_topSectionItem), QString("Mild"));
1335 QCOMPARE(section(lvwph->m_topSectionItem), QString("Mild"));
1336+ QCOMPARE(sectionDelegateIndex(lvwph->m_topSectionItem), 2);
1287 QCOMPARE(lvwph->m_topSectionItem->y(), 0.);
1337 QCOMPARE(lvwph->m_topSectionItem->y(), 0.);
1288 }
1338 }
1289
1339
@@ -1363,6 +1413,7 @@ private Q_SLOTS:
1363 QCOMPARE(lvwph->m_headerItemShownHeight, 0.);
1413 QCOMPARE(lvwph->m_headerItemShownHeight, 0.);
1364 QVERIFY(!QQuickItemPrivate::get(lvwph->m_topSectionItem)->culled);
1414 QVERIFY(!QQuickItemPrivate::get(lvwph->m_topSectionItem)->culled);
1365 QCOMPARE(section(lvwph->m_topSectionItem), QString("Bold"));
1415 QCOMPARE(section(lvwph->m_topSectionItem), QString("Bold"));
1416+ QCOMPARE(sectionDelegateIndex(lvwph->m_topSectionItem), 3);
1366 QCOMPARE(lvwph->m_topSectionItem->y(), 0.);
1417 QCOMPARE(lvwph->m_topSectionItem->y(), 0.);
1367
1418
1368 QMetaObject::invokeMethod(model, "moveItems", Q_ARG(QVariant, 0), Q_ARG(QVariant, 5), Q_ARG(QVariant, 1));
1419 QMetaObject::invokeMethod(model, "moveItems", Q_ARG(QVariant, 0), Q_ARG(QVariant, 5), Q_ARG(QVariant, 1));
@@ -1383,6 +1434,7 @@ private Q_SLOTS:
1383 QVERIFY(!lvwph->isAtYEnd());
1434 QVERIFY(!lvwph->isAtYEnd());
1384 QVERIFY(!QQuickItemPrivate::get(lvwph->m_topSectionItem)->culled);
1435 QVERIFY(!QQuickItemPrivate::get(lvwph->m_topSectionItem)->culled);
1385 QCOMPARE(section(lvwph->m_topSectionItem), QString("Bold"));
1436 QCOMPARE(section(lvwph->m_topSectionItem), QString("Bold"));
1437+ QCOMPARE(sectionDelegateIndex(lvwph->m_topSectionItem), 2);
1386 QCOMPARE(lvwph->m_topSectionItem->y(), 0.);
1438 QCOMPARE(lvwph->m_topSectionItem->y(), 0.);
1387 }
1439 }
1388
1440
@@ -1406,6 +1458,7 @@ private Q_SLOTS:
1406 QCOMPARE(lvwph->m_headerItemShownHeight, 0.);
1458 QCOMPARE(lvwph->m_headerItemShownHeight, 0.);
1407 QVERIFY(!QQuickItemPrivate::get(lvwph->m_topSectionItem)->culled);
1459 QVERIFY(!QQuickItemPrivate::get(lvwph->m_topSectionItem)->culled);
1408 QCOMPARE(section(lvwph->m_topSectionItem), QString("Mild"));
1460 QCOMPARE(section(lvwph->m_topSectionItem), QString("Mild"));
1461+ QCOMPARE(sectionDelegateIndex(lvwph->m_topSectionItem), 2);
1409 QCOMPARE(lvwph->m_topSectionItem->y(), 0.);
1462 QCOMPARE(lvwph->m_topSectionItem->y(), 0.);
1410
1463
1411 model->setProperty(1, "size", 100);
1464 model->setProperty(1, "size", 100);
@@ -1426,6 +1479,7 @@ private Q_SLOTS:
1426 QCOMPARE(lvwph->m_headerItemShownHeight, 0.);
1479 QCOMPARE(lvwph->m_headerItemShownHeight, 0.);
1427 QVERIFY(!QQuickItemPrivate::get(lvwph->m_topSectionItem)->culled);
1480 QVERIFY(!QQuickItemPrivate::get(lvwph->m_topSectionItem)->culled);
1428 QCOMPARE(section(lvwph->m_topSectionItem), QString("Mild"));
1481 QCOMPARE(section(lvwph->m_topSectionItem), QString("Mild"));
1482+ QCOMPARE(sectionDelegateIndex(lvwph->m_topSectionItem), 2);
1429 QCOMPARE(lvwph->m_topSectionItem->y(), 0.);
1483 QCOMPARE(lvwph->m_topSectionItem->y(), 0.);
1430 }
1484 }
1431
1485
@@ -1447,7 +1501,7 @@ private Q_SLOTS:
1447 QCOMPARE(lvwph->m_headerItem->y(), 0.);
1501 QCOMPARE(lvwph->m_headerItem->y(), 0.);
1448 QCOMPARE(lvwph->m_headerItem->height(), 50.);
1502 QCOMPARE(lvwph->m_headerItem->height(), 50.);
1449 QCOMPARE(lvwph->contentY(), 20.);
1503 QCOMPARE(lvwph->contentY(), 20.);
1450− QCOMPARE(lvwph->m_headerItemShownHeight, 0.);;
1504+ QCOMPARE(lvwph->m_headerItemShownHeight, 0.);
1451 QVERIFY(QQuickItemPrivate::get(lvwph->m_topSectionItem)->culled);
1505 QVERIFY(QQuickItemPrivate::get(lvwph->m_topSectionItem)->culled);
1452
1506
1453 lvwph->showHeader();
1507 lvwph->showHeader();
@@ -1467,6 +1521,7 @@ private Q_SLOTS:
1467 QCOMPARE(lvwph->m_headerItemShownHeight, 50.);
1521 QCOMPARE(lvwph->m_headerItemShownHeight, 50.);
1468 QVERIFY(!QQuickItemPrivate::get(lvwph->m_topSectionItem)->culled);
1522 QVERIFY(!QQuickItemPrivate::get(lvwph->m_topSectionItem)->culled);
1469 QCOMPARE(section(lvwph->m_topSectionItem), QString("Agressive"));
1523 QCOMPARE(section(lvwph->m_topSectionItem), QString("Agressive"));
1524+ QCOMPARE(sectionDelegateIndex(lvwph->m_topSectionItem), 0);
1470 QCOMPARE(lvwph->m_topSectionItem->y(), 0.);
1525 QCOMPARE(lvwph->m_topSectionItem->y(), 0.);
1471
1526
1472 scrollToTop();
1527 scrollToTop();
@@ -1502,9 +1557,10 @@ private Q_SLOTS:
1502 QCOMPARE(lvwph->m_headerItem->y(), 0.);
1557 QCOMPARE(lvwph->m_headerItem->y(), 0.);
1503 QCOMPARE(lvwph->m_headerItem->height(), 50.);
1558 QCOMPARE(lvwph->m_headerItem->height(), 50.);
1504 QCOMPARE(lvwph->contentY(), 375.);
1559 QCOMPARE(lvwph->contentY(), 375.);
1505− QCOMPARE(lvwph->m_headerItemShownHeight, 0.);;
1560+ QCOMPARE(lvwph->m_headerItemShownHeight, 0.);
1506 QVERIFY(!QQuickItemPrivate::get(lvwph->m_topSectionItem)->culled);
1561 QVERIFY(!QQuickItemPrivate::get(lvwph->m_topSectionItem)->culled);
1507 QCOMPARE(section(lvwph->m_topSectionItem), QString("Regular"));
1562 QCOMPARE(section(lvwph->m_topSectionItem), QString("Regular"));
1563+ QCOMPARE(sectionDelegateIndex(lvwph->m_topSectionItem), 1);
1508 QCOMPARE(lvwph->m_topSectionItem->y(), 0.);
1564 QCOMPARE(lvwph->m_topSectionItem->y(), 0.);
1509
1565
1510 lvwph->showHeader();
1566 lvwph->showHeader();
@@ -1525,6 +1581,7 @@ private Q_SLOTS:
1525 QCOMPARE(lvwph->m_headerItemShownHeight, 50.);
1581 QCOMPARE(lvwph->m_headerItemShownHeight, 50.);
1526 QVERIFY(!QQuickItemPrivate::get(lvwph->m_topSectionItem)->culled);
1582 QVERIFY(!QQuickItemPrivate::get(lvwph->m_topSectionItem)->culled);
1527 QCOMPARE(section(lvwph->m_topSectionItem), QString("Regular"));
1583 QCOMPARE(section(lvwph->m_topSectionItem), QString("Regular"));
1584+ QCOMPARE(sectionDelegateIndex(lvwph->m_topSectionItem), 1);
1528 QCOMPARE(lvwph->m_topSectionItem->y(), 0.);
1585 QCOMPARE(lvwph->m_topSectionItem->y(), 0.);
1529
1586
1530 scrollToTop();
1587 scrollToTop();
@@ -1637,7 +1694,11 @@ private Q_SLOTS:
1637private:
1694private:
1638 QQuickView *view;
1695 QQuickView *view;
1639 ListViewWithPageHeader *lvwph;
1696 ListViewWithPageHeader *lvwph;
1697+#if (QT_VERSION < QT_VERSION_CHECK(5, 1, 0))
1640 QQuickListModel *model;
1698 QQuickListModel *model;
1699+#else
1700+ QQmlListModel *model;
1701+#endif
1641 QQmlComponent *otherDelegate;
1702 QQmlComponent *otherDelegate;
1642};
1703};
1643
1704
tests/plugins/Unity/Indicators/indicatorsmanagertest.cpp+1−1
@@ -134,5 +134,5 @@ private Q_SLOTS:
134 }
134 }
135};
135};
136
136
137−QTEST_MAIN(IndicatorsManagerTest)
137+QTEST_GUILESS_MAIN(IndicatorsManagerTest)
138#include "indicatorsmanagertest.moc"
138#include "indicatorsmanagertest.moc"
tests/plugins/Unity/Indicators/indicatorsmodeltest.cpp+1−1
@@ -97,6 +97,6 @@ private Q_SLOTS:
97 }
97 }
98};
98};
99
99
100−QTEST_MAIN(IndicatorsModelTest)
100+QTEST_GUILESS_MAIN(IndicatorsModelTest)
101
101
102#include "indicatorsmodeltest.moc"
102#include "indicatorsmodeltest.moc"
tests/plugins/Unity/Indicators/menucontentactivatortest.cpp+1−1
@@ -299,5 +299,5 @@ private:
299 QList<int> m_deltas;
299 QList<int> m_deltas;
300};
300};
301
301
302−QTEST_MAIN(MenuConentActivatorTest)
302+QTEST_GUILESS_MAIN(MenuConentActivatorTest)
303#include "menucontentactivatortest.moc"
303#include "menucontentactivatortest.moc"
tests/plugins/Utils/qlimitproxymodeltest.cpp+1−1
@@ -481,6 +481,6 @@ private Q_SLOTS:
481 }
481 }
482};
482};
483
483
484−QTEST_MAIN(QLimitProxyModelTest)
484+QTEST_GUILESS_MAIN(QLimitProxyModelTest)
485
485
486#include "qlimitproxymodeltest.moc"
486#include "qlimitproxymodeltest.moc"
tests/plugins/Utils/qsortfilterproxymodeltest.cpp+1−1
@@ -285,6 +285,6 @@ private Q_SLOTS:
285 }
285 }
286};
286};
287
287
288−QTEST_MAIN(QSortFilterProxyModelTest)
288+QTEST_GUILESS_MAIN(QSortFilterProxyModelTest)
289
289
290#include "qsortfilterproxymodeltest.moc"
290#include "qsortfilterproxymodeltest.moc"
tests/qmltests/CMakeLists.txt+3
@@ -25,6 +25,9 @@ add_qml_test(utils/Unity/Test UnityTest)
25set(qmltest_DEFAULT_TARGETS qmluitests)
25set(qmltest_DEFAULT_TARGETS qmluitests)
26set(qmltest_DEFAULT_NO_ADD_TEST TRUE)
26set(qmltest_DEFAULT_NO_ADD_TEST TRUE)
27set(qmltest_DEFAULT_PROPERTIES "")
27set(qmltest_DEFAULT_PROPERTIES "")
28+
29+add_qml_test(. Shell IMPORT_PATHS ${CMAKE_BINARY_DIR}/plugins ${qmltest_DEFAULT_IMPORT_PATHS} ${CMAKE_BINARY_DIR}/tests/mocks
30+ ENVIRONMENT "LD_LIBRARY_PATH=${CMAKE_BINARY_DIR}/tests/mocks/LightDM/single")
28add_manual_qml_test(Components DragHandle IMPORT_PATHS ${CMAKE_BINARY_DIR}/plugins)
31add_manual_qml_test(Components DragHandle IMPORT_PATHS ${CMAKE_BINARY_DIR}/plugins)
29add_qml_test(Components DraggingArea)
32add_qml_test(Components DraggingArea)
30add_qml_test(Components FilterGrid IMPORT_PATHS ${qmltest_DEFAULT_IMPORT_PATHS} ${CMAKE_BINARY_DIR}/plugins)
33add_qml_test(Components FilterGrid IMPORT_PATHS ${qmltest_DEFAULT_IMPORT_PATHS} ${CMAKE_BINARY_DIR}/plugins)
tests/qmltests/Components/tst_Stage.qml+1
@@ -161,6 +161,7 @@ Rectangle {
161 applicationManager: fakeAppManager
161 applicationManager: fakeAppManager
162 rightEdgeDraggingAreaWidth: units.gu(2)
162 rightEdgeDraggingAreaWidth: units.gu(2)
163 fullyShown: true
163 fullyShown: true
164+ fullyHidden: false
164 newApplicationScreenshot: FakeApplicationScreenshot {
165 newApplicationScreenshot: FakeApplicationScreenshot {
165 id: newAppScreenshot
166 id: newAppScreenshot
166 parent: stage
167 parent: stage
tests/qmltests/Dash/tst_Dash.qml+4−4
@@ -38,8 +38,8 @@ Item {
38 scopeDelegateMapping: {
38 scopeDelegateMapping: {
39 "MockScope1": "../tests/qmltests/Dash/qml/fake_scopeView1.qml",
39 "MockScope1": "../tests/qmltests/Dash/qml/fake_scopeView1.qml",
40 "MockScope2": "../tests/qmltests/Dash/qml/fake_scopeView2.qml",
40 "MockScope2": "../tests/qmltests/Dash/qml/fake_scopeView2.qml",
41− "MockScope3": "../tests/qmltests/Dash/qml/fake_scopeView3.qml",
41+ "home.scope": "../tests/qmltests/Dash/qml/fake_scopeView3.qml",
42− "MockScope4": "../tests/qmltests/Dash/qml/fake_scopeView4.qml"
42+ "applications.scope": "../tests/qmltests/Dash/qml/fake_scopeView4.qml"
43 }
43 }
44 genericScope: "../tests/qmltests/Dash/qml/fake_generic_scopeView.qml"
44 genericScope: "../tests/qmltests/Dash/qml/fake_generic_scopeView.qml"
45 }
45 }
@@ -69,8 +69,8 @@ Item {
69 return [
69 return [
70 { tag: "MockScope1", visualIndex: 0, shouldBeVisible: true },
70 { tag: "MockScope1", visualIndex: 0, shouldBeVisible: true },
71 { tag: "MockScope2", visualIndex: -1, shouldBeVisible: false },
71 { tag: "MockScope2", visualIndex: -1, shouldBeVisible: false },
72− { tag: "MockScope3", visualIndex: 1, shouldBeVisible: true },
72+ { tag: "home.scope", visualIndex: 1, shouldBeVisible: true },
73− { tag: "MockScope4", visualIndex: 2, shouldBeVisible: true },
73+ { tag: "applications.scope", visualIndex: 2, shouldBeVisible: true },
74 { tag: "MockScope5", visualIndex: 3, shouldBeVisible: true },
74 { tag: "MockScope5", visualIndex: 3, shouldBeVisible: true },
75 ]
75 ]
76 }
76 }
tests/qmltests/Dash/tst_DashContent.qml+12−12
@@ -31,8 +31,8 @@ Item {
31 property var scopeStatus: {
31 property var scopeStatus: {
32 'MockScope1': { 'movementStarted': 0, 'positionedAtBeginning': 0 },
32 'MockScope1': { 'movementStarted': 0, 'positionedAtBeginning': 0 },
33 'MockScope2': { 'movementStarted': 0, 'positionedAtBeginning': 0 },
33 'MockScope2': { 'movementStarted': 0, 'positionedAtBeginning': 0 },
34− 'MockScope3': { 'movementStarted': 0, 'positionedAtBeginning': 0 },
34+ 'home.scope': { 'movementStarted': 0, 'positionedAtBeginning': 0 },
35− 'MockScope4': { 'movementStarted': 0, 'positionedAtBeginning': 0 },
35+ 'applications.scope': { 'movementStarted': 0, 'positionedAtBeginning': 0 },
36 'MockScope5': { 'movementStarted': 0, 'positionedAtBeginning': 0 }
36 'MockScope5': { 'movementStarted': 0, 'positionedAtBeginning': 0 }
37 }
37 }
38
38
@@ -55,8 +55,8 @@ Item {
55 scopeDelegateMapping: {
55 scopeDelegateMapping: {
56 "MockScope1": "../tests/qmltests/Dash/qml/fake_scopeView1.qml",
56 "MockScope1": "../tests/qmltests/Dash/qml/fake_scopeView1.qml",
57 "MockScope2": "../tests/qmltests/Dash/qml/fake_scopeView2.qml",
57 "MockScope2": "../tests/qmltests/Dash/qml/fake_scopeView2.qml",
58− "MockScope3": "../tests/qmltests/Dash/qml/fake_scopeView3.qml",
58+ "home.scope": "../tests/qmltests/Dash/qml/fake_scopeView3.qml",
59− "MockScope4": "../tests/qmltests/Dash/qml/fake_scopeView4.qml"
59+ "applications.scope": "../tests/qmltests/Dash/qml/fake_scopeView4.qml"
60 }
60 }
61 genericScope: "../tests/qmltests/Dash/qml/fake_generic_scopeView.qml"
61 genericScope: "../tests/qmltests/Dash/qml/fake_generic_scopeView.qml"
62 }
62 }
@@ -68,11 +68,11 @@ Item {
68 scopeStatus["MockScope2"].movementStarted = 0;
68 scopeStatus["MockScope2"].movementStarted = 0;
69 scopeStatus["MockScope2"].positionedAtBeginning = 0;
69 scopeStatus["MockScope2"].positionedAtBeginning = 0;
70
70
71− scopeStatus["MockScope3"].movementStarted = 0;
71+ scopeStatus["home.scope"].movementStarted = 0;
72− scopeStatus["MockScope3"].positionedAtBeginning = 0;
72+ scopeStatus["home.scope"].positionedAtBeginning = 0;
73
73
74− scopeStatus["MockScope4"].movementStarted = 0;
74+ scopeStatus["applications.scope"].movementStarted = 0;
75− scopeStatus["MockScope4"].positionedAtBeginning = 0;
75+ scopeStatus["applications.scope"].positionedAtBeginning = 0;
76
76
77 scopeStatus["MockScope5"].movementStarted = 0;
77 scopeStatus["MockScope5"].movementStarted = 0;
78 scopeStatus["MockScope5"].positionedAtBeginning = 0;
78 scopeStatus["MockScope5"].positionedAtBeginning = 0;
@@ -127,8 +127,8 @@ Item {
127 compare(movementStartedSpy.count, 1, "DashContent should have emitted movementStarted signal when content list did.");
127 compare(movementStartedSpy.count, 1, "DashContent should have emitted movementStarted signal when content list did.");
128 compare(scopeStatus["MockScope1"].movementStarted, 1, "MockScope1 should have emitted movementStarted signal when content list did.");
128 compare(scopeStatus["MockScope1"].movementStarted, 1, "MockScope1 should have emitted movementStarted signal when content list did.");
129 compare(scopeStatus["MockScope2"].movementStarted, 1, "MockScope2 should have emitted movementStarted signal when content list did.");
129 compare(scopeStatus["MockScope2"].movementStarted, 1, "MockScope2 should have emitted movementStarted signal when content list did.");
130− compare(scopeStatus["MockScope3"].movementStarted, 1, "MockScope3 should have emitted movementStarted signal when content list did.");
130+ compare(scopeStatus["home.scope"].movementStarted, 1, "home.scope should have emitted movementStarted signal when content list did.");
131− compare(scopeStatus["MockScope4"].movementStarted, 1, "MockScope4 should have emitted movementStarted signal when content list did.");
131+ compare(scopeStatus["applications.scope"].movementStarted, 1, "applications.scope should have emitted movementStarted signal when content list did.");
132 compare(scopeStatus["MockScope5"].movementStarted, 1, "MockScope5 should have emitted movementStarted signal when content list did.");
132 compare(scopeStatus["MockScope5"].movementStarted, 1, "MockScope5 should have emitted movementStarted signal when content list did.");
133 }
133 }
134
134
@@ -140,8 +140,8 @@ Item {
140 dashContent.positionedAtBeginning();
140 dashContent.positionedAtBeginning();
141 compare(scopeStatus["MockScope1"].positionedAtBeginning, 1, "MockScope1 should have emitted positionedAtBeginning signal when DashContent did.");
141 compare(scopeStatus["MockScope1"].positionedAtBeginning, 1, "MockScope1 should have emitted positionedAtBeginning signal when DashContent did.");
142 compare(scopeStatus["MockScope2"].positionedAtBeginning, 1, "MockScope2 should have emitted positionedAtBeginning signal when DashContent did.");
142 compare(scopeStatus["MockScope2"].positionedAtBeginning, 1, "MockScope2 should have emitted positionedAtBeginning signal when DashContent did.");
143− compare(scopeStatus["MockScope3"].positionedAtBeginning, 1, "MockScope3 should have emitted positionedAtBeginning signal when DashContent did.");
143+ compare(scopeStatus["home.scope"].positionedAtBeginning, 1, "home.scope should have emitted positionedAtBeginning signal when DashContent did.");
144− compare(scopeStatus["MockScope4"].positionedAtBeginning, 1, "MockScope4 should have emitted positionedAtBeginning signal when DashContent did.");
144+ compare(scopeStatus["applications.scope"].positionedAtBeginning, 1, "applications.scope should have emitted positionedAtBeginning signal when DashContent did.");
145 compare(scopeStatus["MockScope5"].positionedAtBeginning, 1, "MockScope5 should have emitted positionedAtBeginning signal when DashContent did.");
145 compare(scopeStatus["MockScope5"].positionedAtBeginning, 1, "MockScope5 should have emitted positionedAtBeginning signal when DashContent did.");
146 }
146 }
147
147
tests/qmltests/Dash/tst_FilterGrids.qml+1−1
@@ -118,7 +118,7 @@ Rectangle {
118 gridLoader.source = "../../../Dash/" + data.component;
118 gridLoader.source = "../../../Dash/" + data.component;
119
119
120 // Wait until the FilterGrid is loaded by the loader
120 // Wait until the FilterGrid is loaded by the loader
121− tryCompare(gridLoader, "status", Loader.Ready, "Loader couldn't load " + data.component);
121+ tryCompare(gridLoader, "status", Loader.Ready);
122
122
123 // Wait until the GridView inside the model has finished rendering
123 // Wait until the GridView inside the model has finished rendering
124 var gridView = findChild(gridLoader, "responsiveGridViewGrid");
124 var gridView = findChild(gridLoader, "responsiveGridViewGrid");
tests/qmltests/Greeter/tst_Lockscreen.qml+1
@@ -186,6 +186,7 @@ Rectangle {
186 function test_unlock(data) {
186 function test_unlock(data) {
187 unlockedCheckBox.checked = false
187 unlockedCheckBox.checked = false
188 LightDM.Greeter.authenticate(data.username)
188 LightDM.Greeter.authenticate(data.username)
189+ waitForRendering(lockscreen)
189
190
190 var inputField = findChild(lockscreen, "pinentryField")
191 var inputField = findChild(lockscreen, "pinentryField")
191 if (data.alphanumeric) {
192 if (data.alphanumeric) {
tests/qmltests/tst_Shell.qmlnew file+295
@@ -0,0 +1,295 @@
1+/*
2+ * Copyright (C) 2013 Canonical, Ltd.
3+ *
4+ * Authors:
5+ * Daniel d'Andrada <daniel.dandrada@canonical.com>
6+ *
7+ * This program is free software; you can redistribute it and/or modify
8+ * it under the terms of the GNU General Public License as published by
9+ * the Free Software Foundation; version 3.
10+ *
11+ * This program is distributed in the hope that it will be useful,
12+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
13+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14+ * GNU General Public License for more details.
15+ *
16+ * You should have received a copy of the GNU General Public License
17+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
18+ */
19+
20+import QtQuick 2.0
21+import QtTest 1.0
22+import GSettings 1.0
23+import Ubuntu.Application 0.1
24+import Unity.Test 0.1 as UT
25+
26+import "../.."
27+
28+Item {
29+ width: shell.width
30+ height: shell.height
31+
32+ QtObject {
33+ id: applicationArguments
34+
35+ function hasGeometry() {
36+ return false;
37+ }
38+
39+ function width() {
40+ return 0;
41+ }
42+
43+ function height() {
44+ return 0;
45+ }
46+ }
47+
48+ Shell {
49+ id: shell
50+ }
51+
52+ UT.UnityTestCase {
53+ name: "Shell"
54+ when: windowShown
55+
56+ function initTestCase() {
57+ // swipe away the greeter/lockscreen
58+ var touchX = shell.width - (shell.edgeSize / 2);
59+ var touchY = shell.height / 2;
60+ touchFlick(shell, touchX, touchY, shell.width * 0.1, touchY);
61+
62+ var dash = findChild(shell, "dash");
63+ // wait until the animation has finished
64+ tryCompare(dash, "contentScale", 1.0);
65+ tryCompare(dash, "opacity", 1.0);
66+ }
67+
68+ function cleanup() {
69+ // kill all (fake) running apps
70+ ApplicationManager.mainStageApplications.clear();
71+ ApplicationManager.sideStageApplications.clear();
72+
73+ var dashHome = findChild(shell, "DashHome");
74+ swipeUntilScopeViewIsReached(dashHome);
75+ }
76+
77+ /*
78+ Test the effect of a right-edge drag on the dash in 3 situations:
79+ 1 - when no application has been launched yet
80+ 2 - when there's a minimized application
81+ 3 - after the last running application has been closed/stopped
82+
83+ The behavior of Dash on 3 should be the same as on 1.
84+ */
85+ function test_rightEdgeDrag() {
86+ checkRightEdgeDragWithNoRunningApps();
87+
88+ dragLauncherIntoView();
89+
90+ // Launch an app from the launcher
91+ tapOnAppIconInLauncher();
92+ waitUntilApplicationWindowIsFullyVisible();
93+
94+ // Minimize the application we just launched
95+ swipeFromLeftEdge();
96+
97+ waitForUIToSettle();
98+
99+ checkRightEdgeDragWithMinimizedApp();
100+
101+ // Minimize that application once again
102+ swipeFromLeftEdge();
103+
104+ // kill it
105+ ApplicationManager.mainStageApplications.clear();
106+
107+ waitForUIToSettle();
108+
109+ // Right edge behavior should now be the same as before that app was launched
110+ checkRightEdgeDragWithNoRunningApps();
111+ }
112+
113+ /*
114+ Perform a right-edge drag when the Dash is being show and there are
115+ no running/minimized apps to be restored.
116+
117+ The expected behavior is that an animation should be played to hint the
118+ user that his right-edge drag gesture has been successfully recognized
119+ but there is no application to be brought to foreground.
120+ */
121+ function checkRightEdgeDragWithNoRunningApps() {
122+ var touchX = shell.width - (shell.edgeSize / 2);
123+ var touchY = shell.height / 2;
124+
125+ var dash = findChild(shell, "dash");
126+ // check that dash has normal scale and opacity
127+ compare(dash.contentScale, 1.0);
128+ compare(dash.opacity, 1.0);
129+
130+ touchFlick(shell, touchX, touchY, shell.width * 0.1, touchY,
131+ true /* beginTouch */, false /* endTouch */);
132+
133+ // check that Dash has been scaled down and had its opacity reduced
134+ tryCompareFunction(function() { return dash.contentScale <= 0.9; }, true);
135+ tryCompareFunction(function() { return dash.opacity <= 0.5; }, true);
136+
137+ touchRelease(shell, shell.width * 0.1, touchY);
138+
139+ // and now everything should have gone back to normal
140+ tryCompare(dash, "contentScale", 1.0);
141+ tryCompare(dash, "opacity", 1.0);
142+ }
143+
144+ /*
145+ Perform a right-edge drag when the Dash is being show and there is
146+ a running/minimized app to be restored.
147+
148+ The expected behavior is that the dash should fade away and ultimately be
149+ made invisible once the gesture is finished as the restored app will now
150+ be on foreground.
151+ */
152+ function checkRightEdgeDragWithMinimizedApp() {
153+ var touchX = shell.width - (shell.edgeSize / 2);
154+ var touchY = shell.height / 2;
155+
156+ var dash = findChild(shell, "dash");
157+ // check that dash has normal scale and opacity
158+ tryCompare(dash, "contentScale", 1.0);
159+ tryCompare(dash, "opacity", 1.0);
160+
161+ touchFlick(shell, touchX, touchY, shell.width * 0.1, touchY,
162+ true /* beginTouch */, false /* endTouch */);
163+
164+ // check that Dash has been scaled down and had its opacity reduced
165+ tryCompareFunction(function() { return dash.contentScale <= 0.9; }, true);
166+ tryCompareFunction(function() { return dash.opacity <= 0.5; }, true);
167+
168+ touchRelease(shell, shell.width * 0.1, touchY);
169+
170+ // dash should have gone away, now that the app is on foreground
171+ tryCompare(dash, "visible", false);
172+ }
173+
174+ // Wait for the whole UI to settle down
175+ function waitForUIToSettle() {
176+ waitUntilApplicationWindowIsFullyHidden();
177+ var dashContentList = findChild(shell, "dashContentList");
178+ tryCompare(dashContentList, "moving", false);
179+ }
180+
181+ function dragLauncherIntoView() {
182+ var launcherPanel = findChild(shell, "launcherPanel");
183+ verify(launcherPanel.x = - launcherPanel.width);
184+ swipeFromLeftEdge();
185+ tryCompare(launcherPanel, "x", 0);
186+ }
187+
188+ function tapOnAppIconInLauncher() {
189+ var launcherPanel = findChild(shell, "launcherPanel");
190+
191+ // pick the first icon, the one at the bottom.
192+ var appIcon = findChild(launcherPanel, "launcherDelegate0")
193+
194+ // Swipe upwards over the launcher to ensure that this icon
195+ // at the bottom is not folded and faded away.
196+ var touchStartX = launcherPanel.width / 2;
197+ var touchStartY = launcherPanel.height / 2;
198+ touchFlick(launcherPanel, touchStartX, touchStartY, touchStartX, 0);
199+ tryCompare(launcherPanel, "moving", false);
200+
201+ // NB tapping (i.e., using touch events) doesn't activate the icon... go figure...
202+ mouseClick(appIcon, appIcon.width / 2, appIcon.height / 2);
203+ }
204+
205+ function waitUntilApplicationWindowIsFullyVisible() {
206+ var underlay = findChild(shell, "underlay");
207+ tryCompare(underlay, "visible", false);
208+ }
209+
210+ function waitUntilApplicationWindowIsFullyHidden() {
211+ var stages = findChild(shell, "stages");
212+ tryCompare(stages, "fullyHidden", true);
213+ }
214+
215+ function swipeUntilScopeViewIsReached(scopeView) {
216+ while (!itemIsOnScreen(scopeView)) {
217+ if (itemIsToLeftOfScreen(scopeView)) {
218+ swipeRightFromCenter();
219+ } else {
220+ swipeLeftFromCenter();
221+ }
222+ waitUntilItemStopsMoving(scopeView);
223+ }
224+ }
225+
226+ function swipeFromLeftEdge() {
227+ var touchStartX = 2;
228+ var touchStartY = shell.height / 2;
229+ touchFlick(shell, touchStartX, touchStartY, shell.width * 0.75, touchStartY);
230+ }
231+
232+ function swipeLeftFromCenter() {
233+ var touchStartX = shell.width / 2;
234+ var touchStartY = shell.height / 2;
235+ touchFlick(shell, touchStartX, touchStartY, 0, touchStartY);
236+ }
237+
238+ function swipeRightFromCenter() {
239+ var touchStartX = shell.width / 2;
240+ var touchStartY = shell.height / 2;
241+ touchFlick(shell, touchStartX, touchStartY, shell.width, touchStartY);
242+ }
243+
244+ function swipeUpFromCenter() {
245+ var touchStartX = shell.width / 2;
246+ var touchStartY = shell.height / 2;
247+ touchFlick(shell, touchStartX, touchStartY, touchStartX, 0);
248+ }
249+
250+ function itemIsOnScreen(item) {
251+ var itemRectInShell = item.mapToItem(shell, 0, 0, item.width, item.height);
252+
253+ return itemRectInShell.x >= 0
254+ && itemRectInShell.y >= 0
255+ && itemRectInShell.x + itemRectInShell.width <= shell.width
256+ && itemRectInShell.y + itemRectInShell.height <= shell.height;
257+ }
258+
259+ function itemIsToLeftOfScreen(item) {
260+ var itemRectInShell = item.mapToItem(shell, 0, 0, item.width, item.height);
261+ return itemRectInShell.x < 0;
262+ }
263+
264+ function waitUntilItemStopsMoving(item) {
265+ var itemRectInShell = item.mapToItem(shell, 0, 0, item.width, item.height);
266+ var previousX = itemRectInShell.x;
267+ var previousY = itemRectInShell.y;
268+ var isStill = false;
269+
270+ do {
271+ wait(100);
272+ itemRectInShell = item.mapToItem(shell, 0, 0, item.width, item.height);
273+ if (itemRectInShell.x == previousX && itemRectInShell.y == previousY) {
274+ isStill = true;
275+ } else {
276+ previousX = itemRectInShell.x;
277+ previousY = itemRectInShell.y;
278+ }
279+ } while (!isStill);
280+ }
281+
282+ function test_wallpaper_data() {
283+ return [
284+ {tag: "red", url: "tests/data/unity/backgrounds/red.png"},
285+ {tag: "blue", url: "tests/data/unity/backgrounds/blue.png"}
286+ ]
287+ }
288+
289+ function test_wallpaper(data) {
290+ var backgroundImage = findChild(shell, "backgroundImage")
291+ GSettingsController.setPictureUri(data.url)
292+ tryCompareFunction(function() { return backgroundImage.source.toString().indexOf(data.url) !== -1; }, true)
293+ }
294+ }
295+}
tests/utils/modules/Unity/Test/UnityTestCase.qml+10−5
@@ -72,11 +72,16 @@ TestCase {
72 // Find an object with the given name recursively, starting
72 // Find an object with the given name recursively, starting
73 // at the given object "obj"
73 // at the given object "obj"
74 function findChild(obj,objectName) {
74 function findChild(obj,objectName) {
75+ var childs = new Array(0);
76+ childs.push(obj)
77+ while (childs.length > 0) {
78+ if (childs[0].objectName == objectName) {
79+ return childs[0]
80+ }
75− for (var i in obj.children) {
81+ for (var i in childs[0].data) {
76− var child = obj.children[i];
82+ childs.push(childs[0].data[i])
77− if (child.objectName === objectName) return child;
83+ }
78− var subChild = findChild(child,objectName);
84+ childs.splice(0, 1);
79− if (subChild !== undefined) return subChild;
80 }
85 }
81 return undefined;
86 return undefined;
82 }
87 }