on xenial help sign in
Merge
a2cfc47Albert Astals
CMakeLists.txt+2−10
@@ -108,11 +108,7 @@ declare_autopilot_test(shell unity8.shell ${CMAKE_SOURCE_DIR}/tests/autopilot/)
108
108
109set(SHELL_APP unity8)
109set(SHELL_APP unity8)
110
110
111−set(shell_app_HDRS
112− )
113−
114add_executable(${SHELL_APP}
111add_executable(${SHELL_APP}
115− ${shellapplication_MOC_SRCS}
116 ApplicationArguments.h
112 ApplicationArguments.h
117 main.cpp
113 main.cpp
118 MouseTouchAdaptor.cpp
114 MouseTouchAdaptor.cpp
@@ -123,14 +119,10 @@ pkg_check_modules(XCB REQUIRED xcb)
123
119
124if (NOT "${XCB_INCLUDE_DIRS}" STREQUAL "")
120if (NOT "${XCB_INCLUDE_DIRS}" STREQUAL "")
125 set_target_properties(${SHELL_APP} PROPERTIES INCLUDE_DIRECTORIES ${XCB_INCLUDE_DIRS})
121 set_target_properties(${SHELL_APP} PROPERTIES INCLUDE_DIRECTORIES ${XCB_INCLUDE_DIRS})
122+
123+ target_link_libraries(${SHELL_APP} ${XCB_LDFLAGS})
126endif()
124endif()
127
125
128−target_link_libraries(${SHELL_APP}
129− ${Qt5Qml_LIBRARIES}
130− ${Qt5Quick_LIBRARIES}
131− ${XCB_LDFLAGS}
132− ${CMAKE_DL_LIBS}
133− )
134
126
135# install binaries
127# install binaries
136install(TARGETS ${SHELL_APP}
128install(TARGETS ${SHELL_APP}
CODING+2−2
@@ -1,7 +1,7 @@
1Building Unity 8
1Building Unity 8
2================
2================
3
3
4−Only Ubuntu 13.10 (saucy) is supported as a developement environment.
4+Only Ubuntu 14.04 (trusty) is supported as a developement environment.
5
5
6download source
6download source
7---------------
7---------------
@@ -68,7 +68,7 @@ Notes
68
68
69Running Unity 8 on devices
69Running Unity 8 on devices
70==========================
70==========================
71−- Ubuntu Touch builds are currently only available in 13.10 flavour
71+- Ubuntu Touch builds are currently only available in 14.04 flavour
72- supported hardware should match one of those listed here
72- supported hardware should match one of those listed here
73 https://wiki.ubuntu.com/Touch/Devices#Running_fine
73 https://wiki.ubuntu.com/Touch/Devices#Running_fine
74- follow the Ubuntu Touch install instructions for your chosen device
74- follow the Ubuntu Touch install instructions for your chosen device
Notifications/Notification.qml+211−181
@@ -20,7 +20,7 @@ import Unity.Notifications 1.0
20import QMenuModel 0.1
20import QMenuModel 0.1
21import Utils 0.1
21import Utils 0.1
22
22
23−UbuntuShape {
23+Item {
24 id: notification
24 id: notification
25
25
26 property alias iconSource: icon.fileSource
26 property alias iconSource: icon.fileSource
@@ -32,262 +32,292 @@ UbuntuShape {
32 property var type
32 property var type
33 property var hints
33 property var hints
34 property var notification
34 property var notification
35+ property color color
36+ property bool fullscreen
35
37
38+ fullscreen: false
36 objectName: "background"
39 objectName: "background"
37− implicitHeight: type != Notification.PlaceHolder ? contentColumn.height + contentColumn.spacing * 2 : 0
40+ implicitHeight: type != Notification.PlaceHolder ? (fullscreen ? notificationList.fullHeight : contentColumn.height + contentColumn.spacing * 4) : 0
41+
38 color: Qt.rgba(0.132, 0.117, 0.109, 0.97)
42 color: Qt.rgba(0.132, 0.117, 0.109, 0.97)
39 opacity: 0
43 opacity: 0
40− radius: "medium"
41
44
42− clip: true
45+ clip: fullscreen ? false : true
43 visible: type != Notification.PlaceHolder
46 visible: type != Notification.PlaceHolder
44
47
45− UnityMenuModelPaths {
48+ UbuntuShape {
46− id: paths
49+ id: shapedBack
47−
48− source: hints["x-canonical-private-menu-model"]
49
50
50− busNameHint: "busName"
51+ visible: !fullscreen
51− actionsHint: "actions"
52+ anchors.fill: parent
52− menuObjectPathHint: "menuPath"
53+ anchors.margins: notificationList.margin
54+ color: parent.color
55+ opacity: parent.opacity
56+ radius: "medium"
53 }
57 }
54
58
55− UnityMenuModel {
59+ Rectangle {
56− id: unityMenuModel
60+ id: nonShapedBack
57
61
58− busName: paths.busName
62+ visible: fullscreen
59− actions: paths.actions
63+ anchors.fill: parent
60− menuObjectPath: paths.menuObjectPath
64+ color: parent.color
65+ opacity: parent.opacity
61 }
66 }
62
67
63− Behavior on implicitHeight {
68+ Item {
64− id: heightBehavior
69+ id: contents
70+ anchors.fill: fullscreen ? nonShapedBack : shapedBack
65
71
66− enabled: false
72+ UnityMenuModelPaths {
67− UbuntuNumberAnimation {
73+ id: paths
68− duration: UbuntuAnimation.SnapDuration
69− }
70− }
71
74
72− // delay enabling height behavior until the add transition is complete
75+ source: hints["x-canonical-private-menu-model"]
73− onOpacityChanged: if (opacity == 1) heightBehavior.enabled = true
74
76
75− MouseArea {
77+ busNameHint: "busName"
76− id: interactiveArea
78+ actionsHint: "actions"
79+ menuObjectPathHint: "menuPath"
80+ }
77
81
78− anchors.fill: contentColumn
82+ UnityMenuModel {
79− objectName: "interactiveArea"
83+ id: unityMenuModel
80− enabled: notification.type == Notification.Interactive
84+
81− onClicked: notification.notification.invokeAction(actionRepeater.itemAt(0).actionId)
85+ busName: paths.busName
86+ actions: paths.actions
87+ menuObjectPath: paths.menuObjectPath
82− }
88+ }
83
89
84− Column {
90+ Behavior on implicitHeight {
85− id: contentColumn
91+ id: heightBehavior
86
92
87− anchors {
93+ enabled: false
88− left: parent.left
94+ UbuntuNumberAnimation {
89− right: parent.right
95+ duration: UbuntuAnimation.SnapDuration
90− top: parent.top
96+ }
91− margins: spacing
92 }
97 }
93
98
94− spacing: units.gu(1)
99+ // delay enabling height behavior until the add transition is complete
100+ onOpacityChanged: if (opacity == 1) heightBehavior.enabled = true
95
101
96− Row {
102+ MouseArea {
97− id: topRow
103+ id: interactiveArea
104+
105+ anchors.fill: contentColumn
106+ objectName: "interactiveArea"
107+ enabled: notification.type == Notification.Interactive
108+ onClicked: notification.notification.invokeAction(actionRepeater.itemAt(0).actionId)
109+ }
110+
111+ Column {
112+ id: contentColumn
98
113
99− spacing: contentColumn.spacing
100 anchors {
114 anchors {
101 left: parent.left
115 left: parent.left
102 right: parent.right
116 right: parent.right
117+ top: parent.top
118+ margins: fullscreen ? 0 : spacing
103 }
119 }
104
120
105− ShapedIcon {
121+ spacing: units.gu(1)
106− id: icon
107
122
108− objectName: "icon"
123+ Row {
109− width: units.gu(6)
124+ id: topRow
110− height: units.gu(6)
111− shaped: notification.hints["x-canonical-non-shaped-icon"] == "true" ? false : true
112− visible: iconSource !== undefined && iconSource != ""
113− }
114
125
115− Image {
126+ spacing: contentColumn.spacing
116− id: secondaryIcon
127+ anchors {
128+ left: parent.left
129+ right: parent.right
130+ }
117
131
118− objectName: "secondaryIcon"
132+ ShapedIcon {
119− width: units.gu(2)
133+ id: icon
120− height: units.gu(2)
121− visible: source !== undefined && source != ""
122− fillMode: Image.PreserveAspectCrop
123− }
124
134
125− Column {
135+ objectName: "icon"
126− id: labelColumn
136+ width: units.gu(6)
127− width: parent.width - x
137+ height: units.gu(6)
138+ shaped: notification.hints["x-canonical-non-shaped-icon"] == "true" ? false : true
139+ visible: iconSource !== undefined && iconSource != ""
140+ }
128
141
129− anchors.verticalCenter: (icon.visible && !bodyLabel.visible) ? icon.verticalCenter : undefined
142+ Image {
143+ id: secondaryIcon
130
144
131− Label {
145+ objectName: "secondaryIcon"
132− id: summaryLabel
146+ width: units.gu(2)
147+ height: units.gu(2)
148+ visible: source !== undefined && source != ""
149+ fillMode: Image.PreserveAspectCrop
150+ }
133
151
152+ Column {
153+ id: labelColumn
154+ width: parent.width - x
155+
156+ anchors.verticalCenter: (icon.visible && !bodyLabel.visible) ? icon.verticalCenter : undefined
157+
158+ Label {
159+ id: summaryLabel
160+
134− objectName: "summaryLabel"
161+ objectName: "summaryLabel"
135− anchors {
162+ anchors {
136− left: parent.left
163+ left: parent.left
137− right: parent.right
164+ right: parent.right
165+ }
166+ fontSize: "medium"
167+ font.bold: true
168+ color: Theme.palette.selected.backgroundText
169+ elide: Text.ElideRight
138 }
170 }
139− fontSize: "medium"
140− font.bold: true
141− color: Theme.palette.selected.backgroundText
142− elide: Text.ElideRight
143− }
144
171
145− Label {
172+ Label {
146− id: bodyLabel
173+ id: bodyLabel
147
174
148− objectName: "bodyLabel"
175+ objectName: "bodyLabel"
149− anchors {
176+ anchors {
150− left: parent.left
177+ left: parent.left
151− right: parent.right
178+ right: parent.right
179+ }
180+ visible: body != ""
181+ fontSize: "small"
182+ color: Theme.palette.selected.backgroundText
183+ opacity: 0.6
184+ wrapMode: Text.WordWrap
185+ maximumLineCount: 10
186+ elide: Text.ElideRight
152 }
187 }
153− visible: body != ""
154− fontSize: "small"
155− color: Theme.palette.selected.backgroundText
156− opacity: 0.6
157− wrapMode: Text.WordWrap
158− maximumLineCount: 10
159− elide: Text.ElideRight
160 }
188 }
161 }
189 }
162− }
163
190
164− Column {
191+ Column {
165− objectName: "dialogListView"
192+ objectName: "dialogListView"
166− spacing: units.gu(2)
193+ spacing: units.gu(2)
167
194
168− visible: count > 0
195+ visible: count > 0
169
196
170− anchors.left: parent.left; anchors.right: parent.right
197+ anchors.left: parent.left; anchors.right: parent.right
198+ anchors.top: fullscreen ? parent.top : undefined
199+ anchors.bottom: fullscreen ? parent.bottom : undefined
171
200
172− Repeater {
201+ Repeater {
173− model: unityMenuModel
202+ model: unityMenuModel
174
203
175− NotificationMenuItemFactory {
204+ NotificationMenuItemFactory {
176− anchors.left: parent.left; anchors.right: parent.right
205+ anchors.left: parent.left; anchors.right: parent.right
177
206
178− menuModel: unityMenuModel
207+ menuModel: unityMenuModel
179− menuData: model
208+ menuData: model
180− menuIndex: index
209+ menuIndex: index
210+ }
181 }
211 }
182 }
212 }
183− }
184
213
185− Item {
214+ Item {
186− id: buttonRow
215+ id: buttonRow
187
216
188− objectName: "buttonRow"
217+ objectName: "buttonRow"
189− anchors {
218+ anchors {
190− left: parent.left
219+ left: parent.left
191− right: parent.right
220+ right: parent.right
192− }
221+ }
193− visible: notification.type == Notification.SnapDecision && actionRepeater.count > 0
222+ visible: notification.type == Notification.SnapDecision && actionRepeater.count > 0
194− height: units.gu(5)
223+ height: units.gu(5)
195
224
196− property real buttonWidth: (width - contentColumn.spacing) / 2
225+ property real buttonWidth: (width - contentColumn.spacing) / 2
197− property bool expanded
226+ property bool expanded
198
227
199− Button {
228+ Button {
200− id: leftButton
229+ id: leftButton
201
230
202− objectName: "button1"
231+ objectName: "button1"
203− width: parent.expanded ? parent.width : parent.buttonWidth
232+ width: parent.expanded ? parent.width : parent.buttonWidth
204− anchors {
233+ anchors {
205− top: parent.top
234+ top: parent.top
206− bottom: parent.bottom
235+ bottom: parent.bottom
207− }
236+ }
208− text: notification.type == Notification.SnapDecision && actionRepeater.count >= 2 ? actionRepeater.itemAt(1).actionLabel : ""
237+ text: notification.type == Notification.SnapDecision && actionRepeater.count >= 2 ? actionRepeater.itemAt(1).actionLabel : ""
209− gradient: UbuntuColors.greyGradient
238+ gradient: UbuntuColors.greyGradient
210− onClicked: {
239+ onClicked: {
211− if (actionRepeater.count > 2) {
240+ if (actionRepeater.count > 2) {
212− buttonRow.expanded = !buttonRow.expanded
241+ buttonRow.expanded = !buttonRow.expanded
213− } else {
242+ } else {
214− notification.notification.invokeAction(actionRepeater.itemAt(1).actionId)
243+ notification.notification.invokeAction(actionRepeater.itemAt(1).actionId)
244+ }
245+ }
246+
247+ Behavior on width {
248+ UbuntuNumberAnimation {
249+ duration: UbuntuAnimation.SnapDuration
250+ }
215 }
251 }
216 }
252 }
217
253
218− Behavior on width {
254+ Button {
219− UbuntuNumberAnimation {
255+ id: rightButton
220− duration: UbuntuAnimation.SnapDuration
256+
257+ objectName: "button0"
258+ anchors {
259+ left: leftButton.right
260+ leftMargin: contentColumn.spacing
261+ right: parent.right
221 }
262 }
263+ text: notification.type == Notification.SnapDecision && actionRepeater.count >= 1 ? actionRepeater.itemAt(0).actionLabel : ""
264+ anchors {
265+ top: parent.top
266+ bottom: parent.bottom
267+ }
268+ gradient: notification.hints["x-canonical-private-button-tint"] == "true" ? UbuntuColors.orangeGradient : UbuntuColors.greyGradient
269+ visible: width > 0
270+ onClicked: notification.notification.invokeAction(actionRepeater.itemAt(0).actionId)
222 }
271 }
223 }
272 }
224
273
225− Button {
274+ Column {
226− id: rightButton
227−
228− objectName: "button0"
275+ objectName: "buttonColumn"
276+ spacing: contentColumn.spacing
229 anchors {
277 anchors {
230− left: leftButton.right
278+ left: parent.left
231− leftMargin: contentColumn.spacing
232 right: parent.right
279 right: parent.right
233 }
280 }
234− text: notification.type == Notification.SnapDecision && actionRepeater.count >= 1 ? actionRepeater.itemAt(0).actionLabel : ""
235− anchors {
236− top: parent.top
237− bottom: parent.bottom
238− }
239− gradient: notification.hints["x-canonical-private-button-tint"] == "true" ? UbuntuColors.orangeGradient : UbuntuColors.greyGradient
240− visible: width > 0
241− onClicked: notification.notification.invokeAction(actionRepeater.itemAt(0).actionId)
242− }
243− }
244
281
245− Column {
282+ // calculate initial position before Column takes over
246− objectName: "buttonColumn"
247− spacing: contentColumn.spacing
283+ y: buttonRow.y + buttonRow.height + contentColumn.spacing
248− anchors {
249− left: parent.left
250− right: parent.right
251− }
252
284
253− // calculate initial position before Column takes over
285+ visible: notification.type == Notification.SnapDecision && buttonRow.expanded
254− y: buttonRow.y + buttonRow.height + contentColumn.spacing
286+ height: buttonRow.expanded ? implicitHeight : 0
255
287
256− visible: notification.type == Notification.SnapDecision
288+ Repeater {
257− height: buttonRow.expanded ? implicitHeight : 0
289+ id: actionRepeater
258
290
259− Repeater {
291+ model: notification.actions
260− id: actionRepeater
292+ delegate: Loader {
293+ id: loader
261
294
262− model: notification.actions
295+ property string actionId: id
263− delegate: Loader {
296+ property string actionLabel: label
264− id: loader
265
297
266− property string actionId: id
298+ anchors {
267− property string actionLabel: label
299+ left: parent.left
300+ right: parent.right
301+ }
268
302
269− anchors {
303+ Component {
270− left: parent.left
304+ id: actionButton
271− right: parent.right
272− }
273
305
274− Component {
306+ Button {
275− id: actionButton
307+ objectName: "button" + index
308+ anchors {
309+ left: parent.left
310+ right: parent.right
311+ }
276
312
277− Button {
313+ text: loader.actionLabel
278− objectName: "button" + index
314+ height: units.gu(5)
279− anchors {
315+ gradient: UbuntuColors.greyGradient
280− left: parent.left
316+ onClicked: notification.notification.invokeAction(loader.actionId)
281− right: parent.right
282 }
317 }
283−
284− text: loader.actionLabel
285− height: units.gu(5)
286− gradient: UbuntuColors.greyGradient
287− onClicked: notification.notification.invokeAction(loader.actionId)
288 }
318 }
319+ sourceComponent: (index == 0 || index == 1) ? undefined : actionButton
289 }
320 }
290− sourceComponent: (index == 0 || index == 1) ? undefined : actionButton
291 }
321 }
292 }
322 }
293 }
323 }
Notifications/NotificationMenuItemFactory.qml+9−2
@@ -28,7 +28,6 @@ Loader {
28 property QtObject menuModel: null
28 property QtObject menuModel: null
29 property QtObject menuData: null
29 property QtObject menuData: null
30 property int menuIndex
30 property int menuIndex
31− property var notification
32
31
33 property var _map: {
32 property var _map: {
34 "com.canonical.snapdecision.textfield": textfield,
33 "com.canonical.snapdecision.textfield": textfield,
@@ -44,6 +43,10 @@ Loader {
44 }
43 }
45 }
44 }
46
45
46+ Component.onCompleted: {
47+ notification.fullscreen = menuData.type == "com.canonical.snapdecision.pinlock"
48+ }
49+
47 Component {
50 Component {
48 id: textfield
51 id: textfield
49
52
@@ -94,8 +97,12 @@ Loader {
94
97
95 Component {
98 Component {
96 id: pinLock
99 id: pinLock
97− PinLockscreen {
100+
101+ Lockscreen {
98 anchors.left: parent.left; anchors.right: parent.right
102 anchors.left: parent.left; anchors.right: parent.right
103+ height: notificationList.fullHeight
104+ placeholderText: i18n.tr("Please enter SIM PIN")
105+ background: shell.background
99
106
100 onEntered: {
107 onEntered: {
101 menuModel.changeState(menuIndex, passphrase);
108 menuModel.changeState(menuIndex, passphrase);
Notifications/Notifications.qml+3−1
@@ -24,7 +24,9 @@ ListView {
24 objectName: "notificationList"
24 objectName: "notificationList"
25 interactive: false
25 interactive: false
26
26
27− spacing: units.gu(.5)
27+ property real margin
28+ property real fullHeight
29+
28 delegate: Notification {
30 delegate: Notification {
29 objectName: "notification" + index
31 objectName: "notification" + index
30 anchors {
32 anchors {
Shell.qml+4−3
@@ -704,13 +704,14 @@ FocusScope {
704 id: notifications
704 id: notifications
705
705
706 model: NotificationBackend.Model
706 model: NotificationBackend.Model
707+ margin: units.gu(1)
708+ fullHeight: parent.height - panel.panelHeight
709+
707 anchors {
710 anchors {
708 top: parent.top
711 top: parent.top
709 right: parent.right
712 right: parent.right
710 bottom: parent.bottom
713 bottom: parent.bottom
711− leftMargin: units.gu(1)
712− rightMargin: units.gu(1)
713− topMargin: panel.panelHeight + units.gu(1)
714+ topMargin: panel.panelHeight
714 }
715 }
715 states: [
716 states: [
716 State {
717 State {
data/unity8.overridenew file+1
@@ -0,0 +1 @@
1+kill timeout 30
debian/changelog+26
@@ -1,3 +1,29 @@
1+unity8 (7.84+14.04.20131212-0ubuntu1) trusty; urgency=low
2+
3+ [ Michał Sawicz ]
4+ * Add PyDev project files for autopilot tests. Also tweak .bzrignore
5+ to not ignore generic Eclipse project definitions.
6+ * Retry unlocking the greeter three times.
7+ * Reduce code duplication and clean up CMakeLists and includes in
8+ indicator tests.
9+
10+ [ Nick Dedekind ]
11+ * Replaced indicator page dynamic menuSelected binding with Connection
12+ to listview selectedIndex property. (LP: #1243146)
13+ * Indicators close when menu items are activated. (LP: #1238182)
14+ * Fixed up connections for changes to model data. (LP: #1253810)
15+
16+ [ Albert Astals ]
17+ * dashItemSelected -> showDashHome Because we are not using the index
18+ at all in the upper layers.
19+ * Fix filtering colllapsing/expanding again Also the delegate creation
20+ range stuff flows up->down not down->up so rearrange the bindings.
21+
22+ [ Ubuntu daily release ]
23+ * Automatic snapshot from revision 590
24+
25+ -- Ubuntu daily release <ps-jenkins@lists.canonical.com> Thu, 12 Dec 2013 21:41:19 +0000
26+
1unity8 (7.84+14.04.20131206.1-0ubuntu1) trusty; urgency=low
27unity8 (7.84+14.04.20131206.1-0ubuntu1) trusty; urgency=low
2
28
3 [ Michal Hruby ]
29 [ Michal Hruby ]
debian/unity8-autopilot.install+1
@@ -1 +1,2 @@
1usr/lib/python*/*/unity*
1usr/lib/python*/*/unity*
2+data/unity8.override usr/share/upstart/sessions
main.cpp−40
@@ -19,7 +19,6 @@
19
19
20// Qt
20// Qt
21#include <QtQuick/QQuickView>
21#include <QtQuick/QQuickView>
22−#include <QtGui/QIcon>
23#include <QtGui/QGuiApplication>
22#include <QtGui/QGuiApplication>
24#include <QtQml/QQmlEngine>
23#include <QtQml/QQmlEngine>
25#include <QtQml/QQmlContext>
24#include <QtQml/QQmlContext>
@@ -37,45 +36,6 @@
37
36
38#include <unity-mir/qmirserver.h>
37#include <unity-mir/qmirserver.h>
39
38
40−namespace {
41−
42−void prependImportPaths(QQmlEngine *engine, const QStringList &paths)
43−{
44− QStringList importPathList = engine->importPathList();
45− for (int i = paths.count() -1; i >= 0; i--) {
46− // don't duplicate
47− const QString& path = paths[i];
48− QStringList::iterator iter = qFind(importPathList.begin(), importPathList.end(), path);
49− if (iter == importPathList.end()) {
50− engine->addImportPath(path);
51− }
52− }
53−}
54−
55−/* When you append and import path to the list of import paths it will be the *last*
56− place where Qt will search for QML modules.
57− The usual QQmlEngine::addImportPath() actually prepends the given path.*/
58−void appendImportPaths(QQmlEngine *engine, const QStringList &paths)
59−{
60− QStringList importPathList = engine->importPathList();
61− Q_FOREACH(const QString& path, paths) {
62− // don't duplicate
63− QStringList::iterator iter = qFind(importPathList.begin(), importPathList.end(), path);
64− if (iter == importPathList.end()) {
65− importPathList.append(path);
66− }
67− }
68− engine->setImportPathList(importPathList);
69−}
70−
71−void resolveIconTheme() {
72− const char *ubuntuIconTheme = getenv("UBUNTU_ICON_THEME");
73− if (ubuntuIconTheme == NULL) {
74− ubuntuIconTheme = "ubuntu-mobile";
75− }
76− QIcon::setThemeName(ubuntuIconTheme);
77−}
78−} // namespace {
79
39
80int startShell(int argc, const char** argv, void* server)
40int startShell(int argc, const char** argv, void* server)
81{
41{
paths.h.in+39
@@ -23,6 +23,8 @@
23// Qt
23// Qt
24#include <QtCore/QCoreApplication>
24#include <QtCore/QCoreApplication>
25#include <QtCore/QDir>
25#include <QtCore/QDir>
26+#include <QtGui/QIcon>
27+#include <QtQml/QQmlEngine>
26#include <QStandardPaths>
28#include <QStandardPaths>
27
29
28inline bool isRunningInstalled() {
30inline bool isRunningInstalled() {
@@ -86,4 +88,41 @@ inline QString sourceDirectory() {
86 return QString("@CMAKE_SOURCE_DIR@/");
88 return QString("@CMAKE_SOURCE_DIR@/");
87}
89}
88
90
91+inline void prependImportPaths(QQmlEngine *engine, const QStringList &paths)
92+{
93+ QStringList importPathList = engine->importPathList();
94+ for (int i = paths.count() -1; i >= 0; i--) {
95+ // don't duplicate
96+ const QString& path = paths[i];
97+ QStringList::iterator iter = qFind(importPathList.begin(), importPathList.end(), path);
98+ if (iter == importPathList.end()) {
99+ engine->addImportPath(path);
100+ }
101+ }
102+}
103+
104+/* When you append and import path to the list of import paths it will be the *last*
105+ place where Qt will search for QML modules.
106+ The usual QQmlEngine::addImportPath() actually prepends the given path.*/
107+inline void appendImportPaths(QQmlEngine *engine, const QStringList &paths)
108+{
109+ QStringList importPathList = engine->importPathList();
110+ Q_FOREACH(const QString& path, paths) {
111+ // don't duplicate
112+ QStringList::iterator iter = qFind(importPathList.begin(), importPathList.end(), path);
113+ if (iter == importPathList.end()) {
114+ importPathList.append(path);
115+ }
116+ }
117+ engine->setImportPathList(importPathList);
118+}
119+
120+inline void resolveIconTheme() {
121+ const char *ubuntuIconTheme = getenv("UBUNTU_ICON_THEME");
122+ if (ubuntuIconTheme == NULL) {
123+ ubuntuIconTheme = "ubuntu-mobile";
124+ }
125+ QIcon::setThemeName(ubuntuIconTheme);
126+}
127+
89#endif
128#endif
plugins/DashViews/plugin.cpp+2
@@ -18,6 +18,7 @@
18#include "plugin.h"
18#include "plugin.h"
19
19
20#include "listviewwithpageheader.h"
20#include "listviewwithpageheader.h"
21+#include "verticaljournal.h"
21
22
22#include <QAbstractItemModel>
23#include <QAbstractItemModel>
23
24
@@ -26,4 +27,5 @@ void DashViewsPlugin::registerTypes(const char *uri)
26 Q_ASSERT(uri == QLatin1String("DashViews"));
27 Q_ASSERT(uri == QLatin1String("DashViews"));
27 qmlRegisterType<QAbstractItemModel>();
28 qmlRegisterType<QAbstractItemModel>();
28 qmlRegisterType<ListViewWithPageHeader>(uri, 0, 1, "ListViewWithPageHeader");
29 qmlRegisterType<ListViewWithPageHeader>(uri, 0, 1, "ListViewWithPageHeader");
30+ qmlRegisterType<VerticalJournal>(uri, 0, 1, "VerticalJournal");
29}
31}
plugins/DashViews/verticaljournal.cpp+45−1
@@ -69,8 +69,18 @@ void VerticalJournal::setModel(QAbstractItemModel *model)
69 if (model != this->model()) {
69 if (model != this->model()) {
70 if (!m_delegateModel) {
70 if (!m_delegateModel) {
71 createDelegateModel();
71 createDelegateModel();
72+ } else {
73+#if (QT_VERSION < QT_VERSION_CHECK(5, 1, 0))
74+ disconnect(m_delegateModel, SIGNAL(modelUpdated(QQuickChangeSet,bool)), this, SLOT(onModelUpdated(QQuickChangeSet,bool)));
75+ }
76+ m_delegateModel->setModel(QVariant::fromValue<QAbstractItemModel *>(model));
77+ connect(m_delegateModel, SIGNAL(modelUpdated(QQuickChangeSet,bool)), this, SLOT(onModelUpdated(QQuickChangeSet,bool)));
78+#else
79+ disconnect(m_delegateModel, SIGNAL(modelUpdated(QQmlChangeSet,bool)), this, SLOT(onModelUpdated(QQmlChangeSet,bool)));
72 }
80 }
73 m_delegateModel->setModel(QVariant::fromValue<QAbstractItemModel *>(model));
81 m_delegateModel->setModel(QVariant::fromValue<QAbstractItemModel *>(model));
82+ connect(m_delegateModel, SIGNAL(modelUpdated(QQmlChangeSet,bool)), this, SLOT(onModelUpdated(QQmlChangeSet,bool)));
83+#endif
74
84
75 cleanupExistingItems();
85 cleanupExistingItems();
76
86
@@ -477,7 +487,7 @@ void VerticalJournal::itemCreated(int modelIndex, QObject *object)
477{
487{
478 QQuickItem *item = qmlobject_cast<QQuickItem*>(object);
488 QQuickItem *item = qmlobject_cast<QQuickItem*>(object);
479 if (!item) {
489 if (!item) {
480− qWarning() << "ListViewWithPageHeader::itemCreated got a non item for index" << modelIndex;
490+ qWarning() << "VerticalJournal::itemCreated got a non item for index" << modelIndex;
481 return;
491 return;
482 }
492 }
483#endif
493#endif
@@ -489,6 +499,40 @@ void VerticalJournal::itemCreated(int modelIndex, QObject *object)
489 }
499 }
490}
500}
491
501
502+#if (QT_VERSION < QT_VERSION_CHECK(5, 1, 0))
503+void VerticalJournal::onModelUpdated(const QQuickChangeSet &changeSet, bool reset)
504+#else
505+void VerticalJournal::onModelUpdated(const QQmlChangeSet &changeSet, bool reset)
506+#endif
507+{
508+ if (reset) {
509+ cleanupExistingItems();
510+ } else {
511+#if (QT_VERSION < QT_VERSION_CHECK(5, 1, 0))
512+ Q_FOREACH(const QQuickChangeSet::Remove &remove, changeSet.removes()) {
513+#else
514+ Q_FOREACH(const QQmlChangeSet::Remove &remove, changeSet.removes()) {
515+#endif
516+ for (int i = remove.count - 1; i >= 0; --i) {
517+ const int indexToRemove = remove.index + i;
518+ // We only support removing from the end so
519+ // any of the last items of a column has to be indexToRemove
520+ bool found = false;
521+ for (int i = 0; !found && i < m_columnVisibleItems.count(); ++i) {
522+ QList<ViewItem> &column = m_columnVisibleItems[i];
523+ if (!column.isEmpty() && column.last().m_modelIndex == indexToRemove) {
524+ releaseItem(column.takeLast());
525+ found = true;
526+ }
527+ }
528+ Q_ASSERT(found);
529+ }
530+ }
531+ }
532+ polish();
533+}
534+
535+
492void VerticalJournal::relayout()
536void VerticalJournal::relayout()
493{
537{
494 m_needsRelayout = true;
538 m_needsRelayout = true;
plugins/DashViews/verticaljournal.h+4
@@ -22,8 +22,10 @@
22class QAbstractItemModel;
22class QAbstractItemModel;
23class QQmlComponent;
23class QQmlComponent;
24#if (QT_VERSION < QT_VERSION_CHECK(5, 1, 0))
24#if (QT_VERSION < QT_VERSION_CHECK(5, 1, 0))
25+class QQuickChangeSet;
25class QQuickVisualDataModel;
26class QQuickVisualDataModel;
26#else
27#else
28+class QQmlChangeSet;
27class QQmlDelegateModel;
29class QQmlDelegateModel;
28#endif
30#endif
29
31
@@ -120,8 +122,10 @@ protected:
120private Q_SLOTS:
122private Q_SLOTS:
121#if (QT_VERSION < QT_VERSION_CHECK(5, 1, 0))
123#if (QT_VERSION < QT_VERSION_CHECK(5, 1, 0))
122 void itemCreated(int modelIndex, QQuickItem *item);
124 void itemCreated(int modelIndex, QQuickItem *item);
125+ void onModelUpdated(const QQuickChangeSet &changeSet, bool reset);
123#else
126#else
124 void itemCreated(int modelIndex, QObject *object);
127 void itemCreated(int modelIndex, QObject *object);
128+ void onModelUpdated(const QQmlChangeSet &changeSet, bool reset);
125#endif
129#endif
126 void relayout();
130 void relayout();
127 void onHeightChanged();
131 void onHeightChanged();
plugins/Unity/Indicators/Messaging/qml/MessageMenuItemFactory.qml+79−47
@@ -24,12 +24,39 @@ import Unity.Indicators 0.1 as Indicators
24import QMenuModel 0.1 as QMenuModel
24import QMenuModel 0.1 as QMenuModel
25
25
26Indicators.BaseMenuItem {
26Indicators.BaseMenuItem {
27− id: menuItem
27+ id: messageFactoryItem
28− property var actionsDescription: menu ? menu.ext.xCanonicalMessageActions : undefined
28+ property var menuModel: null
29+ property QtObject menuData: null
30+ property int menuIndex: -1
29
31
30− implicitHeight: contents.status == Loader.Ready ? contents.item.implicitHeight : 0
32+ property var extendedData: menuData && menuData.ext || undefined
33+ property var actionsDescription: getExtendedProperty(extendedData, "xCanonicalMessageActions", undefined)
34+
35+ onMenuModelChanged: {
36+ loadAttributes();
37+ }
38+ onMenuIndexChanged: {
39+ loadAttributes();
40+ }
31
41
32− property var model: null
42+ function loadAttributes() {
43+ if (!menuModel || menuIndex == undefined) return;
44+
45+ menuModel.loadExtendedAttributes(menuIndex, {'x-canonical-time': 'int64',
46+ 'x-canonical-text': 'string',
47+ 'x-canonical-message-actions': 'variant',
48+ 'icon': 'icon',
49+ 'x-canonical-app-icon': 'icon'});
50+ }
51+
52+ function getExtendedProperty(object, propertyName, defaultValue) {
53+ if (object && object.hasOwnProperty(propertyName)) {
54+ return object[propertyName];
55+ }
56+ return defaultValue;
57+ }
58+
59+ implicitHeight: contents.status == Loader.Ready ? contents.item.implicitHeight : 0
33
60
34 Loader {
61 Loader {
35 id: contents
62 id: contents
@@ -41,96 +68,101 @@ Indicators.BaseMenuItem {
41 id: simpleTextMessage
68 id: simpleTextMessage
42 SimpleTextMessage {
69 SimpleTextMessage {
43 // text
70 // text
44− title: menu && menu.label ? menu.label : ""
71+ title: menuData && menuData.label || ""
45− time: menu ? menu.ext.xCanonicalTime : 0
72+ time: getExtendedProperty(extendedData, "xCanonicalTime", 0)
46− message: menu && menu.ext.xCanonicalText ? menu.ext.xCanonicalText : ""
73+ message: getExtendedProperty(extendedData, "xCanonicalText", "")
47 // icons
74 // icons
48− avatar: menu && menu.ext.icon !== undefined ? menu.ext.icon : "qrc:/indicators/artwork/messaging/default_contact.png"
75+ avatar: getExtendedProperty(extendedData, "icon", "qrc:/indicators/artwork/messaging/default_contact.png")
49− appIcon: menu && menu.ext.xCanonicalAppIcon !== undefined ? menu.ext.xCanonicalAppIcon : "qrc:/indicators/artwork/messaging/default_app.svg"
76+ appIcon: getExtendedProperty(extendedData, "xCanonicalAppIcon", "qrc:/indicators/artwork/messaging/default_app.svg")
50
77
51 onActivateApp: {
78 onActivateApp: {
52− menuItem.model.activate(modelIndex, true);
79+ menuModel.activate(menuIndex, true);
53 shell.hideIndicatorMenu(UbuntuAnimation.FastDuration);
80 shell.hideIndicatorMenu(UbuntuAnimation.FastDuration);
54 }
81 }
55 onDismiss: {
82 onDismiss: {
56− menuItem.model.activate(modelIndex, false);
83+ menuModel.activate(menuIndex, false);
57 }
84 }
58
85
59− menuSelected: menuItem.menuSelected
86+ menuSelected: messageFactoryItem.menuSelected
60− onSelectMenu: menuItem.selectMenu()
87+ onSelectMenu: messageFactoryItem.selectMenu()
61− onDeselectMenu: menuItem.deselectMenu()
88+ onDeselectMenu: messageFactoryItem.deselectMenu()
62 }
89 }
63 }
90 }
64 Component {
91 Component {
65 id: textMessage
92 id: textMessage
66 TextMessage {
93 TextMessage {
94+ property var replyActionDescription: actionsDescription && actionsDescription.length > 0 ? actionsDescription[0] : undefined
95+
67 property var replyAction: QMenuModel.UnityMenuAction {
96 property var replyAction: QMenuModel.UnityMenuAction {
68− model: menuItem.model
97+ model: menuModel
69− index: modelIndex
98+ index: menuIndex
70− name: menu && actionsDescription[0].name ? actionsDescription[0].name : ""
99+ name: getExtendedProperty(replyActionDescription, "name", "")
71 }
100 }
72
101
73 // text
102 // text
74− title: menu && menu.label ? menu.label : ""
103+ title: menuData && menuData.label || ""
75− time: menu ? menu.ext.xCanonicalTime : 0
104+ time: getExtendedProperty(extendedData, "xCanonicalTime", 0)
76− message: menu && menu.ext.xCanonicalText ? menu.ext.xCanonicalText : ""
105+ message: getExtendedProperty(extendedData, "xCanonicalText", "")
77− replyButtonText: actionsDescription && actionsDescription[0].label ? actionsDescription[0].label : "Send"
106+ replyButtonText: getExtendedProperty(replyActionDescription, "label", "Send")
78 // icons
107 // icons
79− avatar: menu && menu.ext.icon !== undefined ? menu.ext.icon : "qrc:/indicators/artwork/messaging/default_contact.png"
108+ avatar: getExtendedProperty(extendedData, "icon", "qrc:/indicators/artwork/messaging/default_contact.png")
80− appIcon: menu && menu.ext.xCanonicalAppIcon !== undefined ? menu.ext.xCanonicalAppIcon : "qrc:/indicators/artwork/messaging/default_app.svg"
109+ appIcon: getExtendedProperty(extendedData, "xCanonicalAppIcon", "qrc:/indicators/artwork/messaging/default_app.svg")
81 // actions
110 // actions
82 replyEnabled: replyAction.valid && replyAction.enabled
111 replyEnabled: replyAction.valid && replyAction.enabled
83
112
84 onActivateApp: {
113 onActivateApp: {
85− menuItem.model.activate(modelIndex, true);
114+ menuModel.activate(menuIndex, true);
86 shell.hideIndicatorMenu(UbuntuAnimation.FastDuration);
115 shell.hideIndicatorMenu(UbuntuAnimation.FastDuration);
87 }
116 }
88 onDismiss: {
117 onDismiss: {
89− menuItem.model.activate(modelIndex, false);
118+ menuModel.activate(menuIndex, false);
90 }
119 }
91 onReply: {
120 onReply: {
92 replyAction.activate(value);
121 replyAction.activate(value);
93 }
122 }
94
123
95− menuSelected: menuItem.menuSelected
124+ menuSelected: messageFactoryItem.menuSelected
96− onSelectMenu: menuItem.selectMenu()
125+ onSelectMenu: messageFactoryItem.selectMenu()
97− onDeselectMenu: menuItem.deselectMenu()
126+ onDeselectMenu: messageFactoryItem.deselectMenu()
98 }
127 }
99 }
128 }
100 Component {
129 Component {
101 id: snapDecision
130 id: snapDecision
102 SnapDecision {
131 SnapDecision {
132+ property var activateActionDescription: actionsDescription && actionsDescription.length > 0 ? actionsDescription[0] : undefined
133+ property var replyActionDescription: actionsDescription && actionsDescription.length > 1 ? actionsDescription[1] : undefined
134+
103 property var activateAction: QMenuModel.UnityMenuAction {
135 property var activateAction: QMenuModel.UnityMenuAction {
104− model: menuItem.model
136+ model: menuModel
105− index: modelIndex
137+ index: menuIndex
106− name: menu && actionsDescription[0].name ? actionsDescription[0].name : ""
138+ name: getExtendedProperty(activateActionDescription, "name", "")
107 }
139 }
108 property var replyAction: QMenuModel.UnityMenuAction {
140 property var replyAction: QMenuModel.UnityMenuAction {
109− model: menuItem.model
141+ model: menuModel
110− index: modelIndex
142+ index: menuIndex
111− name: menu && actionsDescription[1].name ? actionsDescription[1].name : ""
143+ name: getExtendedProperty(replyActionDescription, "name", "")
112 }
144 }
113
145
114 // text
146 // text
115− title: menu && menu.label ? menu.label : ""
147+ title: menuData && menuData.label || ""
116− time: menu ? menu.ext.xCanonicalTime : ""
148+ time: getExtendedProperty(extendedData, "xCanonicalTime", 0)
117− message: menu && menu.ext.xCanonicalText ? menu.ext.xCanonicalText : ""
149+ message: getExtendedProperty(extendedData, "xCanonicalText", "")
118− actionButtonText: actionsDescription && actionsDescription[0].label ? actionsDescription[0].label : "Call back"
150+ actionButtonText: getExtendedProperty(activateActionDescription, "label", "Call back")
119− replyButtonText: actionsDescription && actionsDescription[1].label ? actionsDescription[1].label : "Send"
151+ replyButtonText: getExtendedProperty(replyActionDescription, "label", "Send")
120− replyMessages: actionsDescription && actionsDescription[1]["parameter-hint"] ? actionsDescription[1]["parameter-hint"] : ""
152+ replyMessages: getExtendedProperty(replyActionDescription, "parameter-hint", "")
121 // icons
153 // icons
122− avatar: menu && menu.ext.icon !== undefined ? menu.ext.icon : "qrc:/indicators/artwork/messaging/default_contact.png"
154+ avatar: getExtendedProperty(extendedData, "icon", "qrc:/indicators/artwork/messaging/default_contact.png")
123− appIcon: menu && menu.ext.xCanonicalAppIcon !== undefined ? menu.ext.xCanonicalAppIcon : "qrc:/indicators/artwork/messaging/default_app.svg"
155+ appIcon: getExtendedProperty(extendedData, "xCanonicalAppIcon", "qrc:/indicators/artwork/messaging/default_app.svg")
124 // actions
156 // actions
125 activateEnabled: activateAction.valid && activateAction.enabled
157 activateEnabled: activateAction.valid && activateAction.enabled
126 replyEnabled: replyAction.valid && replyAction.enabled
158 replyEnabled: replyAction.valid && replyAction.enabled
127
159
128 onActivateApp: {
160 onActivateApp: {
129− menuItem.model.activate(modelIndex, true);
161+ menuModel.activate(menuIndex, true);
130 shell.hideIndicatorMenu(UbuntuAnimation.FastDuration);
162 shell.hideIndicatorMenu(UbuntuAnimation.FastDuration);
131 }
163 }
132 onDismiss: {
164 onDismiss: {
133− menuItem.model.activate(modelIndex, false);
165+ menuModel.activate(menuIndex, false);
134 }
166 }
135 onActivate: {
167 onActivate: {
136 activateAction.activate();
168 activateAction.activate();
@@ -139,9 +171,9 @@ Indicators.BaseMenuItem {
139 replyAction.activate(value);
171 replyAction.activate(value);
140 }
172 }
141
173
142− menuSelected: menuItem.menuSelected
174+ menuSelected: messageFactoryItem.menuSelected
143− onSelectMenu: menuItem.selectMenu()
175+ onSelectMenu: messageFactoryItem.selectMenu()
144− onDeselectMenu: menuItem.deselectMenu()
176+ onDeselectMenu: messageFactoryItem.deselectMenu()
145 }
177 }
146 }
178 }
147 }
179 }
plugins/Unity/Indicators/qml/IndicatorPage.qml+6−4
@@ -144,9 +144,11 @@ IndicatorBase {
144 item.selectMenu.connect(function() { mainMenu.selectedIndex = index; });
144 item.selectMenu.connect(function() { mainMenu.selectedIndex = index; });
145 item.deselectMenu.connect(function() { mainMenu.selectedIndex = -1; });
145 item.deselectMenu.connect(function() { mainMenu.selectedIndex = -1; });
146 }
146 }
147−
148− if (item.hasOwnProperty("menu")) {
147+ if (item.hasOwnProperty("menuData")) {
149− item.menu = Qt.binding(function() { return model; });
148+ item.menuData = Qt.binding(function() { return model; });
149+ }
150+ if (item.hasOwnProperty("menuIndex")) {
151+ item.menuIndex = Qt.binding(function() { return modelIndex; });
150 }
152 }
151 }
153 }
152
154
@@ -172,7 +174,7 @@ IndicatorBase {
172
174
173 MenuItemFactory {
175 MenuItemFactory {
174 id: factory
176 id: factory
175− model: mainMenu.model
177+ menuModel: mainMenu.model ? mainMenu.model : null
176 }
178 }
177
179
178 Components.Label {
180 Components.Label {
plugins/Unity/Indicators/qml/MenuItemFactory.qml+132−85
@@ -27,7 +27,7 @@ import Ubuntu.Components 0.1
27Item {
27Item {
28 id: menuFactory
28 id: menuFactory
29
29
30− property var model: null
30+ property var menuModel: null
31
31
32 property var _map: {
32 property var _map: {
33 "unity.widgets.systemsettings.tablet.volumecontrol" : sliderMenu,
33 "unity.widgets.systemsettings.tablet.volumecontrol" : sliderMenu,
@@ -50,38 +50,55 @@ Item {
50 "unity.widgets.systemsettings.tablet.accesspoint" : accessPoint,
50 "unity.widgets.systemsettings.tablet.accesspoint" : accessPoint,
51 }
51 }
52
52
53+ function getExtendedProperty(object, propertyName, defaultValue) {
54+ if (object && object.hasOwnProperty(propertyName)) {
55+ return object[propertyName];
56+ }
57+ return defaultValue;
58+ }
59+
53 Component { id: divMenu; Indicators.DivMenuItem {} }
60 Component { id: divMenu; Indicators.DivMenuItem {} }
54
61
55 Component {
62 Component {
56 id: sliderMenu;
63 id: sliderMenu;
57 Indicators.SliderMenuItem {
64 Indicators.SliderMenuItem {
58− property QtObject menu: null
65+ property QtObject menuData: null
66+ property var menuModel: menuFactory.menuModel
67+ property int menuIndex: -1
68+ property var extendedData: menuData && menuData.ext || undefined
59
69
60− text: menu && menu.label ? menu.label : ""
70+ text: menuData && menuData.label || ""
61− icon: menu && menu.icon ? menu.icon : ""
71+ iconSource: menuData && menuData.icon || ""
62− minIcon: menu && menu.ext.minIcon ? menu.ext.minIcon : ""
72+ minIcon: getExtendedProperty(extendedData, "minIcon", "")
63− maxIcon: menu && menu.ext.maxIcon ? menu.ext.maxIcon : ""
73+ maxIcon: getExtendedProperty(extendedData, "maxIcon", "")
64
74
65− minimumValue: menu.ext.minValue ? menu.ext.minValue : 0.0
75+ minimumValue: getExtendedProperty(extendedData, "minValue", 0.0)
66 maximumValue: {
76 maximumValue: {
67− var maximum = menu.ext.maxValue ? menu.ext.maxValue : 1.0
77+ var maximum = getExtendedProperty(extendedData, "maxValue", 1.0);
68 if (maximum <= minimumValue) {
78 if (maximum <= minimumValue) {
69 return minimumValue + 1;
79 return minimumValue + 1;
70 }
80 }
71 return maximum;
81 return maximum;
72 }
82 }
73− value: menu ? menu.actionState : 0.0
83+ value: menuData && menuData.actionState || 0.0
74− enabled: menu ? menu.sensitive : false
84+ enabled: menuData && menuData.sensitive || false
75
85
76− Component.onCompleted: {
86+ onMenuModelChanged: {
77− model.loadExtendedAttributes(modelIndex, {'min-value': 'double',
87+ loadAttributes();
78− 'max-value': 'double',
88+ }
79− 'min-icon': 'icon',
89+ onMenuIndexChanged: {
80− 'max-icon': 'icon'});
90+ loadAttributes();
81 }
91 }
82−
83 onChangeState: {
92 onChangeState: {
84− model.changeState(modelIndex, value);
93+ menuModel.changeState(menuIndex, value);
94+ }
95+
96+ function loadAttributes() {
97+ if (!menuModel || menuIndex == undefined) return;
98+ menuModel.loadExtendedAttributes(menuIndex, {'min-value': 'double',
99+ 'max-value': 'double',
100+ 'min-icon': 'icon',
101+ 'max-icon': 'icon'});
85 }
102 }
86 }
103 }
87 }
104 }
@@ -89,13 +106,15 @@ Item {
89 Component {
106 Component {
90 id: buttonMenu;
107 id: buttonMenu;
91 Indicators.ButtonMenuItem {
108 Indicators.ButtonMenuItem {
92− property QtObject menu: null
109+ property QtObject menuData: null
110+ property var menuModel: menuFactory.menuModel
111+ property int menuIndex: -1
93
112
94− text: menu && menu.label ? menu.label : ""
113+ text: menuData && menuData.label || ""
95− enabled: menu ? menu.sensitive : false
114+ enabled: menuData && menuData.sensitive || false
96
115
97 onActivate: {
116 onActivate: {
98− model.activate(modelIndex);
117+ menuModel.activate(menuIndex);
99 shell.hideIndicatorMenu(UbuntuAnimation.FastDuration);
118 shell.hideIndicatorMenu(UbuntuAnimation.FastDuration);
100 }
119 }
101 }
120 }
@@ -103,37 +122,40 @@ Item {
103 Component {
122 Component {
104 id: sectionMenu;
123 id: sectionMenu;
105 Indicators.SectionMenuItem {
124 Indicators.SectionMenuItem {
106− property QtObject menu: null
125+ property QtObject menuData: null
126+ property var menuIndex: undefined
107
127
108− text: menu && menu.label ? menu.label : ""
128+ text: menuData && menuData.label || ""
109 }
129 }
110 }
130 }
111
131
112 Component {
132 Component {
113 id: progressMenu;
133 id: progressMenu;
114 Indicators.ProgressMenuItem {
134 Indicators.ProgressMenuItem {
115− property QtObject menu: null
135+ property QtObject menuData: null
136+ property int menuIndex: -1
116
137
117− text: menu && menu.label ? menu.label : ""
138+ text: menuData && menuData.label || ""
118− icon: menu ? menu.icon : ""
139+ iconSource: menuData && menuData.icon || ""
119− value : menu ? menu.actionState : 0.0
140+ value : menuData && menuData.actionState || 0.0
120− enabled: menu ? menu.sensitive : false
141+ enabled: menuData && menuData.sensitive || false
121 }
142 }
122 }
143 }
123
144
124 Component {
145 Component {
125 id: standardMenu;
146 id: standardMenu;
126 Indicators.StandardMenuItem {
147 Indicators.StandardMenuItem {
127− property QtObject menu: null
148+ property QtObject menuData: null
149+ property int menuIndex: -1
128
150
129− text: menu && menu.label ? menu.label : ""
151+ text: menuData && menuData.label || ""
130− icon: menu && menu.icon ? menu.icon : ""
152+ iconSource: menuData && menuData.icon || ""
153+ enabled: menuData && menuData.sensitive || false
131− checkable: menu ? (menu.isCheck || menu.isRadio) : false
154+ checkable: menuData ? (menuData.isCheck || menuData.isRadio) : false
132− checked: checkable ? menu.isToggled : false
155+ checked: checkable ? menuData.isToggled : false
133− enabled: menu ? menu.sensitive : false
134
156
135 onActivate: {
157 onActivate: {
136− model.activate(modelIndex);
158+ menuModel.activate(menuIndex);
137 shell.hideIndicatorMenu(UbuntuAnimation.BriskDuration);
159 shell.hideIndicatorMenu(UbuntuAnimation.BriskDuration);
138 }
160 }
139 }
161 }
@@ -142,15 +164,16 @@ Item {
142 Component {
164 Component {
143 id: switchMenu;
165 id: switchMenu;
144 Indicators.SwitchMenuItem {
166 Indicators.SwitchMenuItem {
145− property QtObject menu: null
167+ property QtObject menuData: null
168+ property int menuIndex: -1
146
169
147− text: menu && menu.label ? menu.label : ""
170+ text: menuData && menuData.label || ""
148− icon: menu && menu.icon ? menu.icon : ""
171+ iconSource: menuData && menuData.icon || ""
172+ enabled: menuData && menuData.sensitive || false
149− checked: menu ? menu.isToggled : false
173+ checked: menuData ? menuData.isToggled : false
150− enabled: menu ? menu.sensitive : false
151
174
152 onActivate: {
175 onActivate: {
153− model.activate(modelIndex);
176+ menuModel.activate(menuIndex);
154 shell.hideIndicatorMenu(UbuntuAnimation.BriskDuration);
177 shell.hideIndicatorMenu(UbuntuAnimation.BriskDuration);
155 }
178 }
156 }
179 }
@@ -159,13 +182,24 @@ Item {
159 Component {
182 Component {
160 id: wifiSection;
183 id: wifiSection;
161 Indicators.SectionMenuItem {
184 Indicators.SectionMenuItem {
162− property QtObject menu: null
185+ property QtObject menuData: null
186+ property var menuModel: menuFactory.menuModel
187+ property int menuIndex: -1
188+ property var extendedData: menuData && menuData.ext || undefined
189+
190+ text: menuData && menuData.label || ""
191+ busy: getExtendedProperty(extendedData, "xCanonicalBusyAction", false)
163
192
164− text: menu && menu.label ? menu.label : ""
193+ onMenuModelChanged: {
165− busy: menu ? menu.ext.xCanonicalBusyAction : false
194+ loadAttributes();
195+ }
196+ onMenuIndexChanged: {
197+ loadAttributes();
198+ }
166
199
167− Component.onCompleted: {
200+ function loadAttributes() {
201+ if (!menuModel || menuIndex == undefined) return;
168− model.loadExtendedAttributes(modelIndex, {'x-canonical-busy-action': 'bool'});
202+ menuModel.loadExtendedAttributes(menuIndex, {'x-canonical-busy-action': 'bool'})
169 }
203 }
170 }
204 }
171 }
205 }
@@ -173,67 +207,81 @@ Item {
173 Component {
207 Component {
174 id: accessPoint;
208 id: accessPoint;
175 ICNetwork.AccessPoint {
209 ICNetwork.AccessPoint {
176− property QtObject menu: null
210+ property QtObject menuData: null
211+ property var menuModel: menuFactory.menuModel
212+ property int menuIndex: -1
213+ property var extendedData: menuData && menuData.ext || undefined
214+
177 property var strengthAction: QMenuModel.UnityMenuAction {
215 property var strengthAction: QMenuModel.UnityMenuAction {
178− model: menuFactory.model ? menuFactory.model : null
216+ model: menuModel
179− index: modelIndex
217+ index: menuIndex
180− name: menu ? menu.ext.xCanonicalWifiApStrengthAction : ""
218+ name: getExtendedProperty(extendedData, "xCanonicalWifiApStrengthAction", "")
181 }
219 }
182
220
183− text: menu && menu.label ? menu.label : ""
221+ text: menuData && menuData.label || ""
222+ enabled: menuData && menuData.sensitive || false
184− secure: menu ? menu.ext.xCanonicalWifiApIsSecure : false
223+ secure: getExtendedProperty(extendedData, "xCanonicalWifiApIsSecure", false)
185− adHoc: menu ? menu.ext.xCanonicalWifiApIsAdhoc : false
224+ adHoc: getExtendedProperty(extendedData, "xCanonicalWifiApIsAdhoc", false)
186− checked: menu ? menu.isToggled : false
225+ checked: menuData ? menuData.isToggled : false
187 signalStrength: strengthAction.valid ? strengthAction.state : 0
226 signalStrength: strengthAction.valid ? strengthAction.state : 0
188− enabled: menu ? menu.sensitive : false
189
227
190− Component.onCompleted: {
228+ onMenuModelChanged: {
191− model.loadExtendedAttributes(modelIndex, {'x-canonical-wifi-ap-is-adhoc': 'bool',
229+ loadAttributes();
192− 'x-canonical-wifi-ap-is-secure': 'bool',
230+ }
193− 'x-canonical-wifi-ap-strength-action': 'string'});
231+ onMenuIndexChanged: {
232+ loadAttributes();
194 }
233 }
195 onActivate: {
234 onActivate: {
196− model.activate(modelIndex);
235+ menuModel.activate(menuIndex);
197 shell.hideIndicatorMenu(UbuntuAnimation.BriskDuration);
236 shell.hideIndicatorMenu(UbuntuAnimation.BriskDuration);
198 }
237 }
238+
239+ function loadAttributes() {
240+ if (!menuModel || menuIndex == undefined) return;
241+ menuModel.loadExtendedAttributes(menuIndex, {'x-canonical-wifi-ap-is-adhoc': 'bool',
242+ 'x-canonical-wifi-ap-is-secure': 'bool',
243+ 'x-canonical-wifi-ap-strength-action': 'string'});
244+ }
199 }
245 }
200 }
246 }
201
247
202 Component {
248 Component {
203 id: messageItem
249 id: messageItem
204 ICMessaging.MessageMenuItemFactory {
250 ICMessaging.MessageMenuItemFactory {
205−
251+ menuModel: menuFactory.menuModel
206− property QtObject menu: null
207− model: menuFactory.model ? menuFactory.model : null
208−
209− Component.onCompleted: {
210− model.loadExtendedAttributes(modelIndex, {'x-canonical-time': 'int64',
211− 'x-canonical-text': 'string',
212− 'x-canonical-message-actions': 'variant',
213− 'icon': 'icon',
214− 'x-canonical-app-icon': 'icon'});
215− }
216 }
252 }
217 }
253 }
218
254
219 Component {
255 Component {
220 id: groupedMessage
256 id: groupedMessage
221 ICMessaging.GroupedMessage {
257 ICMessaging.GroupedMessage {
222− property QtObject menu: null
258+ property QtObject menuData: null
223−
259+ property var menuModel: menuFactory.menuModel
224− title: menu && menu.label ? menu.label : ""
260+ property int menuIndex: -1
225− count: menu && menu.actionState[0] ? menu.actionState[0] : "0"
261+ property var extendedData: menuData && menuData.ext || undefined
262+
263+ title: menuData && menuData.label || ""
226− appIcon: menu && menu.ext.icon !== undefined ? menu.ext.icon : "qrc:/indicators/artwork/messaging/default_app.svg"
264+ appIcon: getExtendedProperty(extendedData, "icon", "qrc:/indicators/artwork/messaging/default_app.svg")
227−
265+ count: menuData && menuData.actionState.length > 0 ? menuData.actionState[0] : "0"
228− Component.onCompleted: {
266+ enabled: menuData && menuData.sensitive || false
229− model.loadExtendedAttributes(modelIndex, {'icon': 'icon'});
267+
268+ onMenuModelChanged: {
269+ loadAttributes();
270+ }
271+ onMenuIndexChanged: {
272+ loadAttributes();
230 }
273 }
231 onActivateApp: {
274 onActivateApp: {
232− model.activate(modelIndex, true);
275+ menuModel.activate(menuIndex, true);
233 shell.hideIndicatorMenu(UbuntuAnimation.FastDuration);
276 shell.hideIndicatorMenu(UbuntuAnimation.FastDuration);
234 }
277 }
235 onDismiss: {
278 onDismiss: {
236− model.activate(modelIndex, false);
279+ menuModel.activate(menuIndex, false);
280+ }
281+
282+ function loadAttributes() {
283+ if (!menuModel || menuIndex == undefined) return;
284+ menuModel.loadExtendedAttributes(modelIndex, {'icon': 'icon'});
237 }
285 }
238 }
286 }
239 }
287 }
@@ -244,10 +292,9 @@ Item {
244 if (component !== undefined) {
292 if (component !== undefined) {
245 return component;
293 return component;
246 }
294 }
247− } else {
295+ }
248− if (modelData.isSeparator) {
296+ if (modelData.isSeparator) {
249− return divMenu;
297+ return divMenu;
250− }
251 }
298 }
252 return standardMenu;
299 return standardMenu;
253 }
300 }
po/my.po+10−10
@@ -8,15 +8,15 @@ msgstr ""
8"Project-Id-Version: unity\n"
8"Project-Id-Version: unity\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10"POT-Creation-Date: 2013-11-29 09:21+0100\n"
10"POT-Creation-Date: 2013-11-29 09:21+0100\n"
11−"PO-Revision-Date: 2013-10-09 11:35+0000\n"
11+"PO-Revision-Date: 2013-12-12 11:12+0000\n"
12"Last-Translator: Pyae Sone <Unknown>\n"
12"Last-Translator: Pyae Sone <Unknown>\n"
13"Language-Team: Burmese <my@li.org>\n"
13"Language-Team: Burmese <my@li.org>\n"
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"Plural-Forms: nplurals=1; plural=0;\n"
17"Plural-Forms: nplurals=1; plural=0;\n"
18−"X-Launchpad-Export-Date: 2013-11-30 05:33+0000\n"
18+"X-Launchpad-Export-Date: 2013-12-13 06:46+0000\n"
19−"X-Generator: Launchpad (build 16856)\n"
19+"X-Generator: Launchpad (build 16869)\n"
20
20
21#: Components/EdgeDemoOverlay.qml:151
21#: Components/EdgeDemoOverlay.qml:151
22msgid "Skip intro"
22msgid "Skip intro"
@@ -104,16 +104,16 @@ msgstr "မှတ်ချက်များ-"
104
104
105#: Greeter/Lockscreen.qml:149
105#: Greeter/Lockscreen.qml:149
106msgid "Emergency Call"
106msgid "Emergency Call"
107−msgstr ""
107+msgstr "အရေးပေါ်ခေါ်မည်"
108
108
109#: Greeter/PassphraseLockscreen.qml:59
109#: Greeter/PassphraseLockscreen.qml:59
110#, qt-format
110#, qt-format
111msgid "Hello %1"
111msgid "Hello %1"
112−msgstr ""
112+msgstr "ဟဲလို %1"
113
113
114#: Greeter/PassphraseLockscreen.qml:59
114#: Greeter/PassphraseLockscreen.qml:59
115msgid "Hello"
115msgid "Hello"
116−msgstr ""
116+msgstr "ဟဲလို"
117
117
118#: Hud/HudParametrizedActionsPage.qml:132
118#: Hud/HudParametrizedActionsPage.qml:132
119msgid "Confirm"
119msgid "Confirm"
@@ -137,7 +137,7 @@ msgstr "ပြောနေသည်"
137
137
138#: Notifications/NotificationMenuItemFactory.qml:89
138#: Notifications/NotificationMenuItemFactory.qml:89
139msgid "Show password"
139msgid "Show password"
140−msgstr ""
140+msgstr "စကားဝှက်ကိုပြ"
141
141
142#: Panel/SearchIndicator.qml:27
142#: Panel/SearchIndicator.qml:27
143msgid "Search"
143msgid "Search"
@@ -146,13 +146,13 @@ msgstr "ရှာဖွေ"
146#: plugins/Unity/Launcher/launcheritem.cpp:43
146#: plugins/Unity/Launcher/launcheritem.cpp:43
147#: plugins/Unity/Launcher/launcheritem.cpp:73
147#: plugins/Unity/Launcher/launcheritem.cpp:73
148msgid "Lock to Launcher"
148msgid "Lock to Launcher"
149−msgstr ""
149+msgstr "Launcher တွင်ထားမည်"
150
150
151#: plugins/Unity/Launcher/launcheritem.cpp:73
151#: plugins/Unity/Launcher/launcheritem.cpp:73
152msgid "Unlock from Launcher"
152msgid "Unlock from Launcher"
153−msgstr ""
153+msgstr "Launcher မှဖြုတ်မည်"
154
154
155#: Shell.qml:439
155#: Shell.qml:439
156#, qt-format
156#, qt-format
157msgid "Please enter %1"
157msgid "Please enter %1"
158−msgstr ""
158+msgstr "%1ကိုရိုက်ထည့်ပါ"
po/tr.po+7−7
@@ -8,15 +8,15 @@ msgstr ""
8"Project-Id-Version: unity\n"
8"Project-Id-Version: unity\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10"POT-Creation-Date: 2013-11-29 09:21+0100\n"
10"POT-Creation-Date: 2013-11-29 09:21+0100\n"
11−"PO-Revision-Date: 2013-10-01 13:21+0000\n"
11+"PO-Revision-Date: 2013-12-12 16:06+0000\n"
12−"Last-Translator: Volkan Gezer <Unknown>\n"
12+"Last-Translator: Arda Ünlü <aarda.uunlu@gmail.com>\n"
13"Language-Team: Turkish <tr@li.org>\n"
13"Language-Team: Turkish <tr@li.org>\n"
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"Plural-Forms: nplurals=2; plural=n != 1;\n"
17"Plural-Forms: nplurals=2; plural=n != 1;\n"
18−"X-Launchpad-Export-Date: 2013-11-30 05:33+0000\n"
18+"X-Launchpad-Export-Date: 2013-12-13 06:46+0000\n"
19−"X-Generator: Launchpad (build 16856)\n"
19+"X-Generator: Launchpad (build 16869)\n"
20
20
21#: Components/EdgeDemoOverlay.qml:151
21#: Components/EdgeDemoOverlay.qml:151
22msgid "Skip intro"
22msgid "Skip intro"
@@ -138,7 +138,7 @@ msgstr "Konuşuyor..."
138
138
139#: Notifications/NotificationMenuItemFactory.qml:89
139#: Notifications/NotificationMenuItemFactory.qml:89
140msgid "Show password"
140msgid "Show password"
141−msgstr ""
141+msgstr "Parolayı göster"
142
142
143#: Panel/SearchIndicator.qml:27
143#: Panel/SearchIndicator.qml:27
144msgid "Search"
144msgid "Search"
@@ -147,11 +147,11 @@ msgstr "Ara"
147#: plugins/Unity/Launcher/launcheritem.cpp:43
147#: plugins/Unity/Launcher/launcheritem.cpp:43
148#: plugins/Unity/Launcher/launcheritem.cpp:73
148#: plugins/Unity/Launcher/launcheritem.cpp:73
149msgid "Lock to Launcher"
149msgid "Lock to Launcher"
150−msgstr ""
150+msgstr "Başlatıcıya Sabitle"
151
151
152#: plugins/Unity/Launcher/launcheritem.cpp:73
152#: plugins/Unity/Launcher/launcheritem.cpp:73
153msgid "Unlock from Launcher"
153msgid "Unlock from Launcher"
154−msgstr ""
154+msgstr "Başlatıcıdan Ayır"
155
155
156#: Shell.qml:439
156#: Shell.qml:439
157#, qt-format
157#, qt-format
src/Panel/Indicators/client/indicatorsclient.cpp−35
@@ -26,41 +26,6 @@
26#include <QQmlEngine>
26#include <QQmlEngine>
27#include <QDebug>
27#include <QDebug>
28
28
29−namespace {
30−
31−void prependImportPaths(QQmlEngine *engine, const QStringList &paths)
32−{
33− QStringList importPathList = engine->importPathList();
34− for (int i = paths.count()-1; i >= 0; i--) {
35− importPathList.prepend(paths[i]);
36− }
37− engine->setImportPathList(importPathList);
38−}
39−
40−/* When you append and import path to the list of import paths it will be the *last*
41− place where Qt will search for QML modules.
42− The usual QQmlEngine::addImportPath() actually prepends the given path.*/
43−void appendImportPaths(QQmlEngine *engine, const QStringList &paths)
44−{
45− QStringList importPathList = engine->importPathList();
46− Q_FOREACH(const QString& path, paths) {
47− // don't duplicate
48− QStringList::iterator iter = qFind(importPathList.begin(), importPathList.end(), path);
49− if (iter == importPathList.end()) {
50− importPathList.append(path);
51− }
52− }
53− engine->setImportPathList(importPathList);
54−}
55−
56−void resolveIconTheme() {
57− QString ubuntuIconTheme = getenv("UBUNTU_ICON_THEME");
58− if (ubuntuIconTheme.isEmpty()) {
59− QIcon::setThemeName("ubuntu-mobile");
60− }
61−}
62−} // namespace
63−
64IndicatorsClient::IndicatorsClient(int &argc, char **argv)
29IndicatorsClient::IndicatorsClient(int &argc, char **argv)
65 : QObject(0),
30 : QObject(0),
66 m_view(0)
31 m_view(0)
tests/autopilot/unity8/application_lifecycle/tests/test_application_lifecycle.py+7−6
@@ -21,6 +21,7 @@
21
21
22from __future__ import absolute_import
22from __future__ import absolute_import
23
23
24+from unity8.process_helpers import unlock_unity
24from unity8.shell import disable_qml_mocking
25from unity8.shell import disable_qml_mocking
25from unity8.shell.tests import UnityTestCase, _get_device_emulation_scenarios
26from unity8.shell.tests import UnityTestCase, _get_device_emulation_scenarios
26
27
@@ -78,8 +79,8 @@ class ApplicationLifecycleTests(UnityTestCase):
78 @disable_qml_mocking
79 @disable_qml_mocking
79 def test_can_launch_application(self):
80 def test_can_launch_application(self):
80 """Must be able to launch an application."""
81 """Must be able to launch an application."""
81− self.launch_unity()
82+ unity_proxy = self.launch_unity()
82− self.main_window.get_greeter().swipe()
83+ unlock_unity(unity_proxy)
83
84
84 app = self._launch_app("messaging-app")
85 app = self._launch_app("messaging-app")
85
86
@@ -92,8 +93,8 @@ class ApplicationLifecycleTests(UnityTestCase):
92 @disable_qml_mocking
93 @disable_qml_mocking
93 def test_can_launch_multiple_applications(self):
94 def test_can_launch_multiple_applications(self):
94 """A second application launched must be focused."""
95 """A second application launched must be focused."""
95− self.launch_unity()
96+ unity_proxy = self.launch_unity()
96− self.main_window.get_greeter().swipe()
97+ unlock_unity(unity_proxy)
97
98
98 self._launch_app("messaging-app")
99 self._launch_app("messaging-app")
99 self.assertThat(
100 self.assertThat(
@@ -113,8 +114,8 @@ class ApplicationLifecycleTests(UnityTestCase):
113 brought back to the focused state.
114 brought back to the focused state.
114
115
115 """
116 """
116− self.launch_unity()
117+ unity_proxy = self.launch_unity()
117− self.main_window.get_greeter().swipe()
118+ unlock_unity(unity_proxy)
118
119
119 self._launch_app("messaging-app")
120 self._launch_app("messaging-app")
120 self.assertThat(
121 self.assertThat(
tests/autopilot/unity8/shell/tests/test_lock_screen.py+9−8
@@ -20,6 +20,7 @@
20
20
21from __future__ import absolute_import
21from __future__ import absolute_import
22
22
23+from unity8.process_helpers import unlock_unity
23from unity8.shell import with_lightdm_mock
24from unity8.shell import with_lightdm_mock
24from unity8.shell.tests import UnityTestCase, _get_device_emulation_scenarios
25from unity8.shell.tests import UnityTestCase, _get_device_emulation_scenarios
25
26
@@ -40,11 +41,11 @@ class TestLockscreen(UnityTestCase):
40 @with_lightdm_mock("single-pin")
41 @with_lightdm_mock("single-pin")
41 def test_can_unlock_pin_screen(self):
42 def test_can_unlock_pin_screen(self):
42 """Must be able to unlock the PIN entry lock screen."""
43 """Must be able to unlock the PIN entry lock screen."""
43− self.launch_unity()
44+ unity_proxy = self.launch_unity()
44 greeter = self.main_window.get_greeter()
45 greeter = self.main_window.get_greeter()
45
46
46 if greeter.narrowMode:
47 if greeter.narrowMode:
47− greeter.swipe()
48+ unlock_unity(unity_proxy)
48 lockscreen = self._wait_for_lockscreen()
49 lockscreen = self._wait_for_lockscreen()
49 self._enter_pincode("1234")
50 self._enter_pincode("1234")
50 self.assertThat(lockscreen.shown, Eventually(Equals(False)))
51 self.assertThat(lockscreen.shown, Eventually(Equals(False)))
@@ -55,11 +56,11 @@ class TestLockscreen(UnityTestCase):
55 @with_lightdm_mock("single-passphrase")
56 @with_lightdm_mock("single-passphrase")
56 def test_can_unlock_passphrase_screen(self):
57 def test_can_unlock_passphrase_screen(self):
57 """Must be able to unlock the passphrase entry screen."""
58 """Must be able to unlock the passphrase entry screen."""
58− self.launch_unity()
59+ unity_proxy = self.launch_unity()
59 greeter = self.main_window.get_greeter()
60 greeter = self.main_window.get_greeter()
60
61
61 if greeter.narrowMode:
62 if greeter.narrowMode:
62− greeter.swipe()
63+ unlock_unity(unity_proxy)
63 lockscreen = self._wait_for_lockscreen()
64 lockscreen = self._wait_for_lockscreen()
64 self._enter_pin_passphrase("password")
65 self._enter_pin_passphrase("password")
65 self.assertThat(lockscreen.shown, Eventually(Equals(False)))
66 self.assertThat(lockscreen.shown, Eventually(Equals(False)))
@@ -70,11 +71,11 @@ class TestLockscreen(UnityTestCase):
70 @with_lightdm_mock("single-pin")
71 @with_lightdm_mock("single-pin")
71 def test_pin_screen_wrong_code(self):
72 def test_pin_screen_wrong_code(self):
72 """Entering the wrong pin code must not dismiss the lock screen."""
73 """Entering the wrong pin code must not dismiss the lock screen."""
73− self.launch_unity()
74+ unity_proxy = self.launch_unity()
74 greeter = self.main_window.get_greeter()
75 greeter = self.main_window.get_greeter()
75
76
76 if greeter.narrowMode:
77 if greeter.narrowMode:
77− greeter.swipe()
78+ unlock_unity(unity_proxy)
78 lockscreen = self._wait_for_lockscreen()
79 lockscreen = self._wait_for_lockscreen()
79 self._enter_pincode("4321")
80 self._enter_pincode("4321")
80 pinentryField = self.main_window.get_pinentryField()
81 pinentryField = self.main_window.get_pinentryField()
@@ -89,11 +90,11 @@ class TestLockscreen(UnityTestCase):
89 @with_lightdm_mock("single-passphrase")
90 @with_lightdm_mock("single-passphrase")
90 def test_passphrase_screen_wrong_password(self):
91 def test_passphrase_screen_wrong_password(self):
91 """Entering the wrong password must not dismiss the lock screen."""
92 """Entering the wrong password must not dismiss the lock screen."""
92− self.launch_unity()
93+ unity_proxy = self.launch_unity()
93 greeter = self.main_window.get_greeter()
94 greeter = self.main_window.get_greeter()
94
95
95 if greeter.narrowMode:
96 if greeter.narrowMode:
96− greeter.swipe()
97+ unlock_unity(unity_proxy)
97 lockscreen = self._wait_for_lockscreen()
98 lockscreen = self._wait_for_lockscreen()
98 self._enter_pin_passphrase("foobar")
99 self._enter_pin_passphrase("foobar")
99 pinentryField = self.main_window.get_pinentryField()
100 pinentryField = self.main_window.get_pinentryField()
tests/autopilot/unity8/shell/tests/test_notifications.py+1−1
@@ -65,7 +65,7 @@ class NotificationsBase(UnityTestCase):
65 def _get_notifications_list(self):
65 def _get_notifications_list(self):
66 main_view = self.main_window.get_qml_view()
66 main_view = self.main_window.get_qml_view()
67 return main_view.select_single(
67 return main_view.select_single(
68− "QQuickListView",
68+ "Notifications",
69 objectName='notificationList'
69 objectName='notificationList'
70 )
70 )
71
71
tests/mocks/LightDM/demo/CMakeLists.txt−1
@@ -1,4 +1,3 @@
1−include(FindPkgConfig)
2pkg_check_modules(LIBUSERMETRICSOUTPUT REQUIRED libusermetricsoutput-1)
1pkg_check_modules(LIBUSERMETRICSOUTPUT REQUIRED libusermetricsoutput-1)
3
2
4set(LibLightDM_SOURCES
3set(LibLightDM_SOURCES
tests/mocks/Unity/Application/CMakeLists.txt−1
@@ -1,4 +1,3 @@
1−include(FindPkgConfig)
2pkg_check_modules(APPLICATION_API REQUIRED unity-shell-application)
1pkg_check_modules(APPLICATION_API REQUIRED unity-shell-application)
3
2
4set(FakeUnityApplicationQml_SOURCES
3set(FakeUnityApplicationQml_SOURCES
tests/mocks/Unity/Launcher/CMakeLists.txt−1
@@ -1,4 +1,3 @@
1−include(FindPkgConfig)
2pkg_check_modules(LAUNCHER_API REQUIRED unity-shell-launcher=3)
1pkg_check_modules(LAUNCHER_API REQUIRED unity-shell-launcher=3)
3
2
4add_definitions(-DTOP_SRCDIR="${CMAKE_SOURCE_DIR}")
3add_definitions(-DTOP_SRCDIR="${CMAKE_SOURCE_DIR}")
tests/plugins/AccountsService/CMakeLists.txt+6−1
@@ -1,6 +1,11 @@
1+if(DEFINED ENV{DEB_BUILD_MULTIARCH})
2+ set(QDBUSXML2CPP_EXECUTABLE "/usr/lib/$ENV{DEB_BUILD_MULTIARCH}/qt5/bin/qdbusxml2cpp")
3+else()
4+ FIND_PROGRAM(QDBUSXML2CPP_EXECUTABLE qdbusxml2cpp)
5+endif()
1macro(make_dbus_class NAME INTERFACE)
6macro(make_dbus_class NAME INTERFACE)
2 if(${CMAKE_CURRENT_SOURCE_DIR}/interfaces.xml IS_NEWER_THAN ${CMAKE_CURRENT_BINARY_DIR}/${NAME}Adaptor.h)
7 if(${CMAKE_CURRENT_SOURCE_DIR}/interfaces.xml IS_NEWER_THAN ${CMAKE_CURRENT_BINARY_DIR}/${NAME}Adaptor.h)
3− execute_process(COMMAND qdbusxml2cpp -c ${NAME}Adaptor -a ${CMAKE_CURRENT_BINARY_DIR}/${NAME}Adaptor ${CMAKE_CURRENT_SOURCE_DIR}/interfaces.xml ${INTERFACE})
8+ execute_process(COMMAND ${QDBUSXML2CPP_EXECUTABLE} -c ${NAME}Adaptor -a ${CMAKE_CURRENT_BINARY_DIR}/${NAME}Adaptor ${CMAKE_CURRENT_SOURCE_DIR}/interfaces.xml ${INTERFACE})
4 endif()
9 endif()
5endmacro(make_dbus_class)
10endmacro(make_dbus_class)
6
11
tests/plugins/DashViews/CMakeLists.txt+5
@@ -45,6 +45,11 @@ qt5_use_modules(verticaljournaltestExec Test Core Qml)
45target_link_libraries(verticaljournaltestExec ${Qt5Gui_LIBRARIES} ${Qt5Quick_LIBRARIES})
45target_link_libraries(verticaljournaltestExec ${Qt5Gui_LIBRARIES} ${Qt5Quick_LIBRARIES})
46add_custom_target(testVerticalJournal ${CMAKE_CURRENT_BINARY_DIR}/verticaljournaltestExec -o ${CMAKE_BINARY_DIR}/testVerticalJournal.xml,xunitxml -o -,txt)
46add_custom_target(testVerticalJournal ${CMAKE_CURRENT_BINARY_DIR}/verticaljournaltestExec -o ${CMAKE_BINARY_DIR}/testVerticalJournal.xml,xunitxml -o -,txt)
47
47
48+add_executable(verticaljournaltryExec verticaljournaltry.cpp ${CMAKE_CURRENT_SOURCE_DIR}/../../../plugins/DashViews/verticaljournal.cpp)
49+qt5_use_modules(verticaljournaltryExec Test Core Qml)
50+target_link_libraries(verticaljournaltryExec ${Qt5Gui_LIBRARIES} ${Qt5Quick_LIBRARIES})
51+add_custom_target(tryVerticalJournal ${CMAKE_CURRENT_BINARY_DIR}/verticaljournaltryExec -o ${CMAKE_BINARY_DIR}/testVerticalJournal.xml,xunitxml -o -,txt)
52+
48set(qmltest_DEFAULT_NO_ADD_TEST TRUE)
53set(qmltest_DEFAULT_NO_ADD_TEST TRUE)
49add_qml_test(. listviewwithpageheaderqml IMPORT_PATHS ${CMAKE_BINARY_DIR}/plugins)
54add_qml_test(. listviewwithpageheaderqml IMPORT_PATHS ${CMAKE_BINARY_DIR}/plugins)
50
55
tests/plugins/DashViews/verticaljournaltest.cpp+136−19
@@ -22,6 +22,7 @@
22#include <QtQml/qqml.h>
22#include <QtQml/qqml.h>
23#include <QStringListModel>
23#include <QStringListModel>
24#include <QQmlContext>
24#include <QQmlContext>
25+#include <QQmlEngine>
25#pragma GCC diagnostic push
26#pragma GCC diagnostic push
26#pragma GCC diagnostic ignored "-pedantic"
27#pragma GCC diagnostic ignored "-pedantic"
27#include <private/qquickitem_p.h>
28#include <private/qquickitem_p.h>
@@ -29,7 +30,7 @@
29
30
30#include "verticaljournal.h"
31#include "verticaljournal.h"
31
32
32−class QHeightModel : public QStringListModel {
33+class QHeightModel : public QAbstractListModel {
33public:
34public:
34 QHash<int, QByteArray> roleNames() const
35 QHash<int, QByteArray> roleNames() const
35 {
36 {
@@ -37,6 +38,45 @@ public:
37 roles.insert(Qt::DisplayRole, "modelHeight");
38 roles.insert(Qt::DisplayRole, "modelHeight");
38 return roles;
39 return roles;
39 }
40 }
41+
42+ int rowCount(const QModelIndex & /*parent*/) const
43+ {
44+ return m_list.count();
45+ }
46+
47+ QVariant data(const QModelIndex &index, int /*role*/) const
48+ {
49+ return m_list[index.row()];
50+ }
51+
52+ QStringList stringList() const
53+ {
54+ return m_list;
55+ }
56+
57+ void setStringList(const QStringList &list)
58+ {
59+ beginResetModel();
60+ m_list = list;
61+ endResetModel();
62+ }
63+
64+ void addString(const QString& string)
65+ {
66+ beginInsertRows(QModelIndex(), m_list.count(), m_list.count());
67+ m_list << string;
68+ endInsertRows();
69+ }
70+
71+ void removeLast()
72+ {
73+ beginRemoveRows(QModelIndex(), m_list.count() - 1, m_list.count() - 1);
74+ m_list.takeLast();
75+ endRemoveRows();
76+ }
77+
78+private:
79+ QStringList m_list;
40};
80};
41
81
42class VerticalJournalTest : public QObject
82class VerticalJournalTest : public QObject
@@ -49,7 +89,7 @@ private:
49 QTRY_COMPARE(item.m_modelIndex, modelIndex);
89 QTRY_COMPARE(item.m_modelIndex, modelIndex);
50 QTRY_COMPARE(item.x(), x);
90 QTRY_COMPARE(item.x(), x);
51 QTRY_COMPARE(item.y(), y);
91 QTRY_COMPARE(item.y(), y);
52− QTRY_COMPARE(item.height(), heightList[modelIndex].toDouble());
92+ QTRY_COMPARE(item.height(), model->stringList()[modelIndex].toDouble());
53 QTRY_COMPARE(QQuickItemPrivate::get(item.m_item)->culled, !visible);
93 QTRY_COMPARE(QQuickItemPrivate::get(item.m_item)->culled, !visible);
54 }
94 }
55
95
@@ -81,31 +121,24 @@ private:
81 }
121 }
82
122
83private Q_SLOTS:
123private Q_SLOTS:
84− void initTestCase()
85− {
86− qmlRegisterType<QAbstractItemModel>();
87− qmlRegisterType<VerticalJournal>("Journals", 0, 1, "VerticalJournal");
88− }
89−
90 void init()
124 void init()
91 {
125 {
92 view = new QQuickView();
126 view = new QQuickView();
93 view->setResizeMode(QQuickView::SizeRootObjectToView);
127 view->setResizeMode(QQuickView::SizeRootObjectToView);
128+ view->engine()->addImportPath(BUILT_PLUGINS_DIR);
94
129
95 model = new QHeightModel();
130 model = new QHeightModel();
96− heightList.clear();
131+ QStringList heightList;
97 heightList << "100" << "50" << "125" << "10" << "40" << "70" << "200" << "110" << "160" << "20" << "20" << "65" << "80" << "200" << "300" << "130" << "400" << "300" << "500" << "10";
132 heightList << "100" << "50" << "125" << "10" << "40" << "70" << "200" << "110" << "160" << "20" << "20" << "65" << "80" << "200" << "300" << "130" << "400" << "300" << "500" << "10";
98 model->setStringList(heightList);
133 model->setStringList(heightList);
99
134
100− view->rootContext()->setContextProperty("theModel", model);
101−
102 view->setSource(QUrl::fromLocalFile(DASHVIEWSTEST_FOLDER "/verticaljournaltest.qml"));
135 view->setSource(QUrl::fromLocalFile(DASHVIEWSTEST_FOLDER "/verticaljournaltest.qml"));
103
136
104 view->show();
137 view->show();
105 view->resize(470, 400);
138 view->resize(470, 400);
106 QTest::qWaitForWindowExposed(view);
139 QTest::qWaitForWindowExposed(view);
107
140
108− vj = view->rootObject()->findChild<VerticalJournal*>();
141+ vj = dynamic_cast<VerticalJournal*>(view->rootObject()->findChild<QObject*>("vj"));
109 vj->setModel(model);
142 vj->setModel(model);
110
143
111 checkInitialPositions();
144 checkInitialPositions();
@@ -160,7 +193,7 @@ private Q_SLOTS:
160 checkInitialPositions();
193 checkInitialPositions();
161 }
194 }
162
195
163− void testHorizontalSpacing()
196+ void testColumnSpacing()
164 {
197 {
165 vj->setColumnSpacing(11);
198 vj->setColumnSpacing(11);
166
199
@@ -191,7 +224,7 @@ private Q_SLOTS:
191 checkInitialPositions();
224 checkInitialPositions();
192 }
225 }
193
226
194− void testVerticalSpacing()
227+ void testRowSpacing()
195 {
228 {
196 vj->setRowSpacing(11);
229 vj->setRowSpacing(11);
197
230
@@ -290,12 +323,51 @@ private Q_SLOTS:
290
323
291 void testChangeModel()
324 void testChangeModel()
292 {
325 {
293− QHeightModel model2;
326+ QHeightModel *model2 = new QHeightModel();
327+ QStringList list2;
328+ list2 << "100" << "50" << "25" << "25" << "50" << "50";
329+ model2->setStringList(list2);
330+ vj->setModel(model2);
331+ delete model;
332+ model = model2;
333+
334+ QTRY_COMPARE(vj->m_columnVisibleItems.count(), 3);
335+ QTRY_COMPARE(vj->m_columnVisibleItems[0].count(), 1);
336+ QTRY_COMPARE(vj->m_columnVisibleItems[1].count(), 2);
337+ QTRY_COMPARE(vj->m_columnVisibleItems[2].count(), 3);
338+ verifyItem(vj->m_columnVisibleItems[0][0], 0, 0, 0, true);
339+ verifyItem(vj->m_columnVisibleItems[1][0], 1, 160, 0, true);
340+ verifyItem(vj->m_columnVisibleItems[2][0], 2, 320, 0, true);
341+ verifyItem(vj->m_columnVisibleItems[2][1], 3, 320, 35, true);
342+ verifyItem(vj->m_columnVisibleItems[1][1], 4, 160, 60, true);
343+ verifyItem(vj->m_columnVisibleItems[2][2], 5, 320, 70, true);
344+ }
345+
346+ void testModelReset()
347+ {
348+ QStringList heightList;
349+ heightList << "100" << "50" << "50" << "30";
350+ model->setStringList(heightList);
351+
352+ QTRY_COMPARE(vj->m_columnVisibleItems.count(), 3);
353+ QTRY_COMPARE(vj->m_columnVisibleItems[0].count(), 1);
354+ QTRY_COMPARE(vj->m_columnVisibleItems[1].count(), 2);
355+ QTRY_COMPARE(vj->m_columnVisibleItems[2].count(), 1);
356+ verifyItem(vj->m_columnVisibleItems[0][0], 0, 0, 0, true);
357+ verifyItem(vj->m_columnVisibleItems[1][0], 1, 160, 0, true);
358+ verifyItem(vj->m_columnVisibleItems[2][0], 2, 320, 0, true);
359+ verifyItem(vj->m_columnVisibleItems[1][1], 3, 160, 60, true);
360+ }
361+
362+ void testModelAppendRemoveLast()
363+ {
364+ QHeightModel *model2 = new QHeightModel();
294 QStringList list2;
365 QStringList list2;
295 list2 << "100" << "50" << "25" << "25" << "50" << "50";
366 list2 << "100" << "50" << "25" << "25" << "50" << "50";
296− model2.setStringList(list2);
367+ model2->setStringList(list2);
297− vj->setModel(&model2);
368+ vj->setModel(model2);
298− heightList = list2;
369+ delete model;
370+ model = model2;
299
371
300 QTRY_COMPARE(vj->m_columnVisibleItems.count(), 3);
372 QTRY_COMPARE(vj->m_columnVisibleItems.count(), 3);
301 QTRY_COMPARE(vj->m_columnVisibleItems[0].count(), 1);
373 QTRY_COMPARE(vj->m_columnVisibleItems[0].count(), 1);
@@ -307,12 +379,57 @@ private Q_SLOTS:
307 verifyItem(vj->m_columnVisibleItems[2][1], 3, 320, 35, true);
379 verifyItem(vj->m_columnVisibleItems[2][1], 3, 320, 35, true);
308 verifyItem(vj->m_columnVisibleItems[1][1], 4, 160, 60, true);
380 verifyItem(vj->m_columnVisibleItems[1][1], 4, 160, 60, true);
309 verifyItem(vj->m_columnVisibleItems[2][2], 5, 320, 70, true);
381 verifyItem(vj->m_columnVisibleItems[2][2], 5, 320, 70, true);
382+
383+ model2->addString("75");
384+
385+ QTRY_COMPARE(vj->m_columnVisibleItems.count(), 3);
386+ QTRY_COMPARE(vj->m_columnVisibleItems[0].count(), 2);
387+ QTRY_COMPARE(vj->m_columnVisibleItems[1].count(), 2);
388+ QTRY_COMPARE(vj->m_columnVisibleItems[2].count(), 3);
389+ verifyItem(vj->m_columnVisibleItems[0][0], 0, 0, 0, true);
390+ verifyItem(vj->m_columnVisibleItems[1][0], 1, 160, 0, true);
391+ verifyItem(vj->m_columnVisibleItems[2][0], 2, 320, 0, true);
392+ verifyItem(vj->m_columnVisibleItems[2][1], 3, 320, 35, true);
393+ verifyItem(vj->m_columnVisibleItems[1][1], 4, 160, 60, true);
394+ verifyItem(vj->m_columnVisibleItems[2][2], 5, 320, 70, true);
395+ verifyItem(vj->m_columnVisibleItems[0][1], 6, 0, 110, true);
396+
397+ model2->addString("50");
398+ model2->addString("50");
399+
400+ QTRY_COMPARE(vj->m_columnVisibleItems.count(), 3);
401+ QTRY_COMPARE(vj->m_columnVisibleItems[0].count(), 2);
402+ QTRY_COMPARE(vj->m_columnVisibleItems[1].count(), 3);
403+ QTRY_COMPARE(vj->m_columnVisibleItems[2].count(), 4);
404+ verifyItem(vj->m_columnVisibleItems[0][0], 0, 0, 0, true);
405+ verifyItem(vj->m_columnVisibleItems[1][0], 1, 160, 0, true);
406+ verifyItem(vj->m_columnVisibleItems[2][0], 2, 320, 0, true);
407+ verifyItem(vj->m_columnVisibleItems[2][1], 3, 320, 35, true);
408+ verifyItem(vj->m_columnVisibleItems[1][1], 4, 160, 60, true);
409+ verifyItem(vj->m_columnVisibleItems[2][2], 5, 320, 70, true);
410+ verifyItem(vj->m_columnVisibleItems[0][1], 6, 0, 110, true);
411+ verifyItem(vj->m_columnVisibleItems[1][2], 7, 160, 120, true);
412+ verifyItem(vj->m_columnVisibleItems[2][3], 8, 320, 130, true);
413+
414+ model2->removeLast();
415+
416+ QTRY_COMPARE(vj->m_columnVisibleItems.count(), 3);
417+ QTRY_COMPARE(vj->m_columnVisibleItems[0].count(), 2);
418+ QTRY_COMPARE(vj->m_columnVisibleItems[1].count(), 3);
419+ QTRY_COMPARE(vj->m_columnVisibleItems[2].count(), 3);
420+ verifyItem(vj->m_columnVisibleItems[0][0], 0, 0, 0, true);
421+ verifyItem(vj->m_columnVisibleItems[1][0], 1, 160, 0, true);
422+ verifyItem(vj->m_columnVisibleItems[2][0], 2, 320, 0, true);
423+ verifyItem(vj->m_columnVisibleItems[2][1], 3, 320, 35, true);
424+ verifyItem(vj->m_columnVisibleItems[1][1], 4, 160, 60, true);
425+ verifyItem(vj->m_columnVisibleItems[2][2], 5, 320, 70, true);
426+ verifyItem(vj->m_columnVisibleItems[0][1], 6, 0, 110, true);
427+ verifyItem(vj->m_columnVisibleItems[1][2], 7, 160, 120, true);
310 }
428 }
311
429
312private:
430private:
313 QQuickView *view;
431 QQuickView *view;
314 VerticalJournal *vj;
432 VerticalJournal *vj;
315− QStringList heightList;
316 QHeightModel *model;
433 QHeightModel *model;
317};
434};
318
435
tests/plugins/DashViews/verticaljournaltest.qml+2−1
@@ -15,12 +15,13 @@
15 */
15 */
16
16
17import QtQuick 2.1
17import QtQuick 2.1
18−import Journals 0.1
18+import DashViews 0.1
19
19
20Item {
20Item {
21
21
22 VerticalJournal {
22 VerticalJournal {
23 id: vj
23 id: vj
24+ objectName: "vj"
24 anchors.fill: parent
25 anchors.fill: parent
25 columnWidth: 150
26 columnWidth: 150
26 columnSpacing: 10
27 columnSpacing: 10
tests/plugins/DashViews/verticaljournaltry.cppnew file+90
@@ -0,0 +1,90 @@
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 <QQuickView>
18+#include <QDebug>
19+#include <QGuiApplication>
20+#include <QQuickView>
21+#include <QtQml/qqml.h>
22+#include <QStringListModel>
23+#include <QQmlContext>
24+#include <QQmlEngine>
25+#include <QGuiApplication>
26+
27+#include "verticaljournal.h"
28+
29+class QHeightModel : public QStringListModel {
30+ Q_OBJECT
31+public:
32+ QHash<int, QByteArray> roleNames() const
33+ {
34+ QHash<int, QByteArray> roles;
35+ roles.insert(Qt::DisplayRole, "modelHeight");
36+ return roles;
37+ }
38+
39+public slots:
40+ void add(int height)
41+ {
42+ if (height <= 0) {
43+ height = 50 + 50. * qrand() / RAND_MAX ;
44+ }
45+ QStringList sl = stringList();
46+ sl << QString::number(height);
47+ setStringList(sl);
48+ }
49+
50+ void remove()
51+ {
52+ QStringList sl = stringList();
53+ if (!sl.isEmpty()) {
54+ sl.removeLast();
55+ setStringList(sl);
56+ }
57+ }
58+};
59+
60+int main(int argc, char *argv[])
61+{
62+ QGuiApplication a(argc, argv);
63+
64+ QQuickView *view = new QQuickView();
65+ view->setResizeMode(QQuickView::SizeRootObjectToView);
66+ view->engine()->addImportPath(BUILT_PLUGINS_DIR);
67+
68+ QHeightModel model;
69+ QStringList heightList;
70+ heightList << "100" << "50" << "125";
71+ model.setStringList(heightList);
72+
73+ QStringListModel listModel;
74+ listModel.setStringList(QStringList() << QString());
75+
76+ view->rootContext()->setContextProperty("listModel", &listModel);
77+ view->rootContext()->setContextProperty("vjModel", &model);
78+
79+ view->setSource(QUrl::fromLocalFile(DASHVIEWSTEST_FOLDER "/verticaljournaltry.qml"));
80+
81+ view->show();
82+ view->resize(530, 400);
83+
84+ QObject::connect(view->rootObject(), SIGNAL(add(int)), &model, SLOT(add(int)));
85+ QObject::connect(view->rootObject(), SIGNAL(remove()), &model, SLOT(remove()));
86+
87+ return a.exec();
88+}
89+
90+#include "verticaljournaltry.moc"
tests/plugins/DashViews/verticaljournaltry.qmlnew file+100
@@ -0,0 +1,100 @@
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+import QtQuick 2.1
18+import DashViews 0.1
19+
20+Item {
21+ id: root
22+ signal add(int height)
23+ signal remove()
24+
25+ ListViewWithPageHeader {
26+ id: lvwph
27+ model: listModel
28+ height: parent.height
29+ width: parent.width - controls.width
30+
31+ delegate: VerticalJournal {
32+ id: vj
33+ model: vjModel
34+ columnWidth: 100
35+ columnSpacing: 10
36+ rowSpacing: 10
37+ width: parent.width
38+ height: implicitHeight > 100 ? implicitHeight : 100
39+ delegateCreationBegin: lvwph.contentY
40+ delegateCreationEnd: lvwph.contentY + lvwph.height
41+
42+ delegate: Rectangle {
43+ width: 100
44+ color: "red";
45+ height: modelHeight
46+ border.width: 3
47+
48+ Text {
49+ text: index + "\ny: " + parent.y + "\nheight: " + parent.height
50+ x: 10
51+ y: 10
52+ }
53+ }
54+ }
55+ }
56+
57+ Rectangle {
58+ id: controls
59+ height: parent.height
60+ width: 100
61+ anchors.right: parent.right
62+ color: "gray"
63+ opacity: 0.4
64+
65+ Rectangle {
66+ id: addButton
67+ height: 50
68+ width: parent.width
69+ color: "blue"
70+ Text {
71+ text: "Add"
72+ anchors.centerIn: parent
73+ }
74+ MouseArea {
75+ anchors.fill: parent
76+ onClicked: root.add(addField.text)
77+ }
78+ }
79+ TextInput {
80+ id: addField
81+ anchors.top: addButton.bottom
82+ height: 30
83+ width: parent.width
84+ }
85+ Rectangle {
86+ anchors.top: addField.bottom
87+ height: 50
88+ width: parent.width
89+ color: "red"
90+ Text {
91+ text: "Remove"
92+ anchors.centerIn: parent
93+ }
94+ MouseArea {
95+ anchors.fill: parent
96+ onClicked: root.remove()
97+ }
98+ }
99+ }
100+}
tests/plugins/Unity/Indicators/menucontentactivatortest.cpp−1
@@ -18,7 +18,6 @@
18 */
18 */
19
19
20#include "menucontentactivator.h"
20#include "menucontentactivator.h"
21−#include "paths.h"
22
21
23#include <QtTest>
22#include <QtTest>
24#include <QDebug>
23#include <QDebug>
tests/plugins/Unity/Indicators/unitymenumodelstacktest.cpp−1
@@ -18,7 +18,6 @@
18 */
18 */
19
19
20#include "indicatorsmanager.h"
20#include "indicatorsmanager.h"
21−#include "paths.h"
22#include "unitymenumodelstack.h"
21#include "unitymenumodelstack.h"
23
22
24#include <QtTest>
23#include <QtTest>
tests/qmltests/Notifications/tst_Notifications.qml+3−4
@@ -140,8 +140,10 @@ Row {
140 Notifications {
140 Notifications {
141 id: notifications
141 id: notifications
142
142
143+ margin: units.gu(1)
144+ fullHeight: parent.height
145+
143 anchors.fill: parent
146 anchors.fill: parent
144− anchors.margins: units.gu(1)
145 model: mockModel
147 model: mockModel
146 }
148 }
147 }
149 }
@@ -401,9 +403,6 @@ Row {
401 actionSpy.wait()
403 actionSpy.wait()
402 compare(actionSpy.signalArguments[0][0], data.actions[0]["id"], "got wrong id for interactive action")
404 compare(actionSpy.signalArguments[0][0], data.actions[0]["id"], "got wrong id for interactive action")
403 compare(clickThroughSpy.count, 0, "click on interactive notification fell through")
405 compare(clickThroughSpy.count, 0, "click on interactive notification fell through")
404− } else {
405− mouseClick(notification, notification.width / 2, notification.height / 2)
406− clickThroughSpy.wait()
407 }
406 }
408
407
409 compare(secondaryIcon.visible, data.secondaryIconVisible, "secondary-icon visibility is incorrect")
408 compare(secondaryIcon.visible, data.secondaryIconVisible, "secondary-icon visibility is incorrect")