on xenial help sign in
Merge
commit7cdc91ccd47223a9853004bc9765826c8c863949 authorAlbert Astals <albert.astals@canonical.com> dateFri 8 Nov 2013, 09:38 (13 years ago) parent75f9c2aa6883d5
103 files changed+1886−1209
Components/DragHandle.qml+22−23 Components/EdgeDragArea.qml+12−4 Components/PinPadButton.qml+40−13 Components/Stage.qml+8−7 Components/Time.js+9−9 Components/UbuntuShapeForItem.qml+1 Dash/Apps/RunningApplicationTile.qml−2 Dash/Generic/GenericCarouselLoader.qml+30 Dash/GenericScopeView.qml+9−8 Dash/Music/MusicCarouselLoader.qml+24 Dash/Video/VideosCarousel.qml → Dash/Video/VideoCarousel.qml Dash/Video/VideoCarouselLoader.qml+24 Greeter/Greeter.qml+1 Greeter/GreeterContent.qml+12−9 Greeter/Lockscreen.qml+8−4 Greeter/PinLockscreen.qml+34−4 Launcher/Launcher.qml+2−2 Notifications/NotificationMenuItemFactory.qml+20−6 Shell.qml+8−1 debian/changelog+66 debian/control+1−1 plugins/Ubuntu/Gestures/AxisVelocityCalculator.cpp+9−18 plugins/Ubuntu/Gestures/AxisVelocityCalculator.h+9−16 plugins/Ubuntu/Gestures/CMakeLists.txt+1 plugins/Ubuntu/Gestures/DirectionalDragArea.cpp+307−71 plugins/Ubuntu/Gestures/DirectionalDragArea.h+50−13 plugins/Ubuntu/Gestures/TimeSource.cpp+49 plugins/Ubuntu/Gestures/TimeSource.h+54 plugins/Unity/Indicators/qml/SliderMenuItem.qml+3−2 po/ar.po+8−4 po/ast.po+8−25 po/az.po+8−10 po/bg.po+8−16 po/ca.po+8−25 po/cs.po+8−19 po/de.po+8−4 po/el.po+8−10 po/en_AU.po+8−25 po/en_GB.po+8−25 po/eo.po+8−4 po/es.po+8−25 po/fa.po+7−3 po/fi.po+8−25 po/fo.po+8−10 po/fr.po+8−10 po/gd.po+8−25 po/gl.po+8−22 po/he.po+8−25 po/hr.po+8−10 po/hu.po+8−10 po/hy.po+8−10 po/id.po+8−4 po/is.po+8−25 po/it.po+8−25 po/ja.po+8−4 po/km.po+8−25 po/kn.po+8−10 po/ko.po+8−7 po/ky.po+8−10 po/lo.po+8−10 po/lv.po+8−10 po/my.po+8−19 po/nb.po+8−10 po/nl.po+8−10 po/pl.po+8−4 po/pt_BR.po+8−25 po/ro.po+8−10 po/ru.po+8−25 po/shn.po+8−4 po/si.po+8−4 po/sl.po+8−25 po/sr.po+8−10 po/sv.po+8−4 po/ta.po+8−4 po/te.po+8−7 po/tr.po+8−25 po/ug.po+8−19 po/uk.po+8−4 po/unity8.pot+6−2 po/xh.po+8−4 po/zh_CN.po+8−25 po/zh_TW.po+8−10 tests/autopilot/unity8/shell/emulators/create_interactive_notification.py tests/autopilot/unity8/shell/emulators/dash.py+7−17 tests/autopilot/unity8/shell/emulators/hud.py+12−4 tests/autopilot/unity8/shell/emulators/main_window.py+7−1 tests/autopilot/unity8/shell/tests/__init__.py+58−27 tests/autopilot/unity8/shell/tests/test_greeter.py+38 tests/autopilot/unity8/shell/tests/test_notifications.py+49−42 tests/plugins/Ubuntu/Gestures/DownwardsLauncher.qml+2−10 tests/plugins/Ubuntu/Gestures/LeftwardsLauncher.qml+5−13 tests/plugins/Ubuntu/Gestures/RightwardsLauncher.qml+3−10 tests/plugins/Ubuntu/Gestures/UpwardsLauncher.qml+5−13 tests/plugins/Ubuntu/Gestures/edgeDragExample.qml+7−1 tests/plugins/Ubuntu/Gestures/tst_AxisVelocityCalculator.cpp+3−3 tests/plugins/Ubuntu/Gestures/tst_DirectionalDragArea.cpp+285−96 tests/qmltests/Components/tst_DragHandle.cpp+4−5 tests/qmltests/Dash/Apps/tst_RunningApplicationsGrid.qml+1 tests/qmltests/Greeter/tst_Lockscreen.qml+42−4 tests/qmltests/Greeter/tst_Phone.qml+5−5 tests/qmltests/Panel/tst_Panel.qml−1 tests/qmltests/tst_Shell.qml+85−22 tests/utils/modules/Unity/Test/UnityTestCase.qml+34
Components/DragHandle.qml+22−23
@@ -48,9 +48,12 @@ EdgeDragArea {
4848 id: dragArea
4949 objectName: "dragHandle"
5050
51− // Disable gesture detection by default when hinting is used.
52− // It doesn't make sense to have both.
53− distanceThreshold: hintDisplacement > 0 ? 0 : units.gu(1.5)
51+ // Disable most of the gesture recognition parameters by default when hinting is used as
52+ // it conflicts with the hinting idea.
53+ // The only part we keep in this situation is that it must be a single-finger gesture.
54+ distanceThreshold: hintDisplacement > 0 ? 0 : defaultDistanceThreshold
55+ maxSilenceTime: hintDisplacement > 0 ? 60*60*1000 : defaultMaxSilenceTime
56+ maxDeviation: hintDisplacement > 0 ? 999999 : defaultMaxDeviation
5457
5558 property bool stretch: false
5659
@@ -113,8 +116,8 @@ EdgeDragArea {
113116 }
114117 }
115118
116− function limitMovement(step) {
117− var targetValue = MathLocal.clamp(dragParent[targetProp] + step, minValue, maxValue);
119+ function limitMovement(inputStep) {
120+ var targetValue = MathLocal.clamp(dragParent[targetProp] + inputStep, minValue, maxValue);
118121 var step = targetValue - dragParent[targetProp];
119122
120123 if (hintDisplacement == 0) {
@@ -181,29 +184,25 @@ EdgeDragArea {
181184 }
182185 }
183186
184− onDraggingChanged: {
185− if (dragging) {
186− if (hintDisplacement > 0) {
187− hintingAnimation.targetValue = d.startValue;
188− hintingAnimation.start();
189− }
190− } else {
191− hintingAnimation.stop();
192− }
193− }
194−
195187 onStatusChanged: {
196188 if (status === DirectionalDragArea.WaitingForTouch) {
189+ hintingAnimation.stop();
197190 if (d.previousStatus === DirectionalDragArea.Recognized) {
198191 d.onFinishedRecognizedGesture();
192+ } else /* d.previousStatus === DirectionalDragArea.Undecided */ {
193+ // Gesture was rejected.
194+ d.rollbackDrag();
195+ }
196+ } else /* Undecided || Recognized */ {
197+ if (d.previousStatus === DirectionalDragArea.WaitingForTouch ||
198+ d.previousStatus === undefined) {
199+ dragEvaluator.reset();
200+ d.startValue = parent[d.targetProp];
201+ }
202+ if (hintDisplacement > 0) {
203+ hintingAnimation.targetValue = d.startValue;
204+ hintingAnimation.start();
199205 }
200− d.startValue = parent[d.targetProp];
201− }
202−
203− if (d.previousStatus === DirectionalDragArea.WaitingForTouch ||
204− d.previousStatus === undefined) {
205− dragEvaluator.reset();
206− d.startValue = parent[d.targetProp];
207206 }
208207
209208 d.previousStatus = status;
Components/EdgeDragArea.qml+12−4
@@ -29,8 +29,16 @@ DirectionalDragArea {
2929 //
3030 // The idea here is that it's better having lax rules than false negatives.
3131 // False negatives are very frustrating to the user.
32− maxDeviation: units.gu(3)
33− wideningAngle: 50
34− distanceThreshold: units.gu(1.5)
35− minSpeed: units.gu(0) // some people were getting false negatives with it enabled.
32+ maxDeviation: defaultMaxDeviation
33+ wideningAngle: defaultWideningAngle
34+ distanceThreshold: defaultDistanceThreshold
35+ minSpeed: defaultMinSpeed
36+ maxSilenceTime: defaultMaxSilenceTime
37+
38+ readonly property real defaultMaxDeviation: units.gu(3)
39+ readonly property real defaultWideningAngle: 50
40+ readonly property real defaultDistanceThreshold: units.gu(1.5)
41+ // some people were getting false negatives with it enabled.
42+ readonly property real defaultMinSpeed: units.gu(0)
43+ readonly property int defaultMaxSilenceTime: 200
3644}
Components/PinPadButton.qml+40−13
@@ -21,24 +21,51 @@ Item {
2121 id: root
2222
2323 property alias text: label.text
24− property alias iconName: icon.name
24+ property alias subText: subTextLabel.text
25+ property string iconName
2526
2627 signal clicked()
2728
28− Label {
29− id: label
29+ Column {
3030 anchors.centerIn: parent
31− color: "#f3f3e7"
32− fontSize: "large"
33− font.weight: Font.DemiBold
34− }
31+ width: parent.width
32+ height: childrenRect.height
3533
36− Icon {
37− id: icon
38− height: units.gu(3)
39− width: height
40− anchors.centerIn: parent
41− color: "#f3f3e7"
34+ Item {
35+ anchors {
36+ left: parent.left
37+ right: parent.right
38+ }
39+ height: label.visible || icon.visible ? Math.max(label.height, icon.height) : 0
40+
41+ Label {
42+ id: label
43+ anchors.centerIn: parent
44+ width: parent.width
45+ horizontalAlignment: Text.AlignHCenter
46+ color: "#f3f3e7"
47+ fontSize: "large"
48+ font.weight: Font.DemiBold
49+ visible: text.length > 0
50+ }
51+
52+ Icon {
53+ id: icon
54+ height: units.gu(3)
55+ width: height
56+ anchors.centerIn: parent
57+ name: root.iconName
58+ color: "#f3f3e7"
59+ visible: name.length > 0
60+ }
61+ }
62+ Label {
63+ id: subTextLabel
64+ fontSize: "small"
65+ color: "grey"
66+ anchors.horizontalCenter: parent.horizontalCenter
67+ visible: text.length > 0
68+ }
4269 }
4370
4471 MouseArea {
Components/Stage.qml+8−7
@@ -482,19 +482,20 @@ Showable {
482482 switchToApplicationAnimationController.progress += 0.4 * delta
483483 }
484484
485− property bool gotRejected: false
485+ property int lastStatus: -1
486486
487487 onStatusChanged: {
488488 if (status == DirectionalDragArea.Undecided) {
489− gotRejected = false
490489 onUndecided();
491− } else if (status == DirectionalDragArea.Rejected) {
492− switchToApplicationAnimationController.completeToBeginningWithSignal();
493− gotRejected = true;
494490 } else if (status == DirectionalDragArea.WaitingForTouch) {
495− if (!gotRejected)
496− onGestureEnded()
491+ if (lastStatus == DirectionalDragArea.Undecided) {
492+ // got rejected
493+ switchToApplicationAnimationController.completeToBeginningWithSignal();
494+ } else {
495+ onGestureEnded();
496+ }
497497 }
498+ lastStatus = status;
498499 }
499500
500501 function onUndecided() {
Components/Time.js+9−9
@@ -16,15 +16,15 @@
1616
1717.pragma library
1818
19−var factors = {
20− "second": [ 1000, "a second ago", "in a second", "%1 seconds ago", "in %1 seconds" ],
21− "minute": [ 60, "a minute ago", "in a minute", "%1 minutes ago", "in %1 minutes" ],
22− "hour": [ 60, "an hour ago", "in an hour", "%1 hours ago", "in %1 hours" ],
23− "day": [ 24, "yesterday", "tomorrow", "%1 days ago", "in %1 days" ],
24− "week": [ 7, "a week ago", "in a week", "about %1 weeks ago", "in about %1 weeks" ],
25− "month": [ 4.35, "a month ago", "in a month", "%1 months ago", "in %1 months" ], // == 365.25 days / 12 months / 7 days
26− "year": [ 12, "a year ago", "in a year", "%1 years ago", "in %1 years" ]
27−}
19+var factors = [
20+ [ 1000, "a second ago", "in a second", "%1 seconds ago", "in %1 seconds" ],
21+ [ 60, "a minute ago", "in a minute", "%1 minutes ago", "in %1 minutes" ],
22+ [ 60, "an hour ago", "in an hour", "%1 hours ago", "in %1 hours" ],
23+ [ 24, "yesterday", "tomorrow", "%1 days ago", "in %1 days" ],
24+ [ 7, "a week ago", "in a week", "about %1 weeks ago", "in about %1 weeks" ],
25+ [ 4.35, "a month ago", "in a month", "%1 months ago", "in %1 months" ], // == 365.25 days / 12 months / 7 days
26+ [ 12, "a year ago", "in a year", "%1 years ago", "in %1 years" ]
27+]
2828
2929function readableFromNow(date, now) {
3030 var then = new Date(date);
Components/UbuntuShapeForItem.qml+1
@@ -31,6 +31,7 @@ Item {
3131
3232 ShaderEffectSource {
3333 id: source
34+ anchors.centerIn: parent // Placed under shape, so it's hidden
3435 width: 1
3536 height: 1
3637 hideSource: true
Dash/Apps/RunningApplicationTile.qml−2
@@ -105,8 +105,6 @@ AbstractButton {
105105 baseline: parent.bottom
106106 left: parent.left
107107 right: parent.right
108− leftMargin: units.gu(1)
109− rightMargin: units.gu(1)
110108 }
111109 text: (application) ? application.name : ""
112110
Dash/Generic/GenericCarouselLoader.qmlnew file+30
@@ -0,0 +1,30 @@
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.0
18+import Ubuntu.Components 0.1
19+
20+Loader {
21+ property var model: null
22+ property url carouselUrl: "GenericCarousel.qml"
23+ property url filtergridUrl: "GenericFilterGrid.qml"
24+
25+ source: model.count > 6 ? carouselUrl : filtergridUrl // FIXME do not hardcode 6, but retrieve correct minimum required count
26+
27+ onLoaded: {
28+ item.model = Qt.binding(function() { return model; })
29+ }
30+}
Dash/GenericScopeView.qml+9−8
@@ -262,26 +262,27 @@ ScopeView {
262262 rendererId = getDefaultRendererId(contentType);
263263 }
264264 switch (rendererId) {
265+ case "carousel": {
266+ switch (contentType) {
267+ case "music": return "Music/MusicCarouselLoader.qml";
268+ case "video": return "Video/VideoCarouselLoader.qml";
269+ default: return "Generic/GenericCarouselLoader.qml";
270+ }
271+ }
265272 case "grid": {
266273 switch (contentType) {
267− case "video": return "Video/VideoFilterGrid.qml";
268− case "music": return "Music/MusicFilterGrid.qml";
269274 case "apps": {
270275 if (rendererHint == "toggled")
271276 return "Apps/DashPluginFilterGrid.qml";
272277 else
273278 return "Generic/GenericFilterGrid.qml";
274279 }
280+ case "music": return "Music/MusicFilterGrid.qml";
281+ case "video": return "Video/VideoFilterGrid.qml";
275282 case "weather": return "Generic/WeatherFilterGrid.qml";
276283 default: return "Generic/GenericFilterGrid.qml";
277284 }
278285 }
279− case "carousel": {
280− switch (contentType) {
281− case "music": return "Music/MusicCarousel.qml";
282− default: return "Generic/GenericCarousel.qml";
283− }
284− }
285286 case "special": {
286287 switch (contentType) {
287288 case "apps": return "Apps/RunningApplicationsGrid.qml";
Dash/Music/MusicCarouselLoader.qmlnew file+24
@@ -0,0 +1,24 @@
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.0
18+import Ubuntu.Components 0.1
19+import "../Generic"
20+
21+GenericCarouselLoader {
22+ carouselUrl: "MusicCarousel.qml"
23+ filtergridUrl: "MusicFilterGrid.qml"
24+}
Dash/Video/VideosCarousel.qml → Dash/Video/VideoCarousel.qmlrenamed

The content is the same.

Dash/Video/VideoCarouselLoader.qmlnew file+24
@@ -0,0 +1,24 @@
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.0
18+import Ubuntu.Components 0.1
19+import "../Generic"
20+
21+GenericCarouselLoader {
22+ carouselUrl: "VideoCarousel.qml"
23+ filtergridUrl: "VideoFilterGrid.qml"
24+}
Greeter/Greeter.qml+1
@@ -64,6 +64,7 @@ Showable {
6464 property var model: LightDM.Users
6565 property int currentIndex: 0
6666 property var infographicModel: LightDM.Infographic
67+ readonly property int backgroundTopMargin: -greeter.y
6768
6869 source: required ? "GreeterContent.qml" : ""
6970
Greeter/GreeterContent.qml+12−9
@@ -24,7 +24,7 @@ MouseArea {
2424 id: root
2525 anchors.fill: parent
2626
27− property bool ready: wallpaper.source == "" || wallpaper.status == Image.Ready || wallpaper.status == Image.Error
27+ property bool ready: background.source == "" || background.status == Image.Ready || background.status == Image.Error
2828 property bool leftTeaserPressed: teasingMouseArea.pressed &&
2929 teasingMouseArea.mouseX < teasingMouseArea.width / 2
3030 property bool rightTeaserPressed: teasingMouseArea.pressed &&
@@ -34,33 +34,36 @@ MouseArea {
3434 signal unlocked(int uid)
3535
3636 Rectangle {
37− // In case wallpaper fails to load
38− id: wallpaperBackup
37+ // In case background fails to load
38+ id: backgroundBackup
3939 anchors.fill: parent
4040 color: "black"
4141 }
4242
4343 property url backgroundValue: AccountsService.backgroundFile != undefined && AccountsService.backgroundFile.length > 0 ? AccountsService.backgroundFile : greeter.defaultBackground
44− onBackgroundValueChanged: wallpaper.source = backgroundValue
44+ onBackgroundValueChanged: background.source = backgroundValue
4545
4646 CrossFadeImage {
47− id: wallpaper
48− objectName: "wallpaper"
49− anchors.fill: parent
47+ id: background
48+ objectName: "greeterBackground"
49+ anchors {
50+ fill: parent
51+ topMargin: backgroundTopMargin
52+ }
5053 fillMode: Image.PreserveAspectCrop
5154 }
5255
5356 // See Shell.qml's backgroundSettings treatment for why we need a separate
5457 // Image, but it boils down to avoiding binding loop detection.
5558 Image {
56− source: wallpaper.source
59+ source: background.source
5760 height: 0
5861 width: 0
5962 sourceSize.height: 0
6063 sourceSize.width: 0
6164 onStatusChanged: {
6265 if (status == Image.Error && source != greeter.defaultBackground) {
63− wallpaper.source = greeter.defaultBackground
66+ background.source = greeter.defaultBackground
6467 }
6568 }
6669 }
Greeter/Lockscreen.qml+8−4
@@ -54,15 +54,19 @@ Showable {
5454 }
5555
5656 Rectangle {
57− // In case wallpaper fails to load or is undefined
58− id: wallpaperBackup
57+ // In case background fails to load or is undefined
58+ id: backgroundBackup
5959 anchors.fill: parent
6060 color: "black"
6161 }
6262
6363 Image {
64− id: wallpaper
65− anchors.fill: parent
64+ id: backgroundImage
65+ objectName: "lockscreenBackground"
66+ anchors {
67+ fill: parent
68+ topMargin: backgroundTopMargin
69+ }
6670 source: root.required ? root.background : ""
6771 fillMode: Image.PreserveAspectCrop
6872 }
Greeter/PinLockscreen.qml+34−4
@@ -27,7 +27,7 @@ Column {
2727 property alias placeholderText: pinentryField.placeholderText
2828 property int padWidth: units.gu(34)
2929 property int padHeight: units.gu(28)
30− property int pinLength: 4
30+ property int pinLength: -1
3131
3232 signal entered(string passphrase)
3333 signal cancel()
@@ -65,6 +65,9 @@ Column {
6565 Label {
6666 id: pinentryFieldLabel
6767 anchors.centerIn: parent
68+ width: parent.width - (backspaceIcon.width + backspaceIcon.anchors.rightMargin) * 2
69+ elide: Text.ElideMiddle
70+ horizontalAlignment: Text.AlignHCenter
6871 font.pixelSize: units.dp(44)
6972 color: "#f3f3e7"
7073 opacity: 0.6
@@ -76,6 +79,26 @@ Column {
7679 text: parent.placeholderText
7780 visible: pinentryFieldLabel.text.length == 0
7881 }
82+
83+ Icon {
84+ id: backspaceIcon
85+ objectName: "backspaceIcon"
86+ anchors {
87+ top: parent.top
88+ topMargin: units.gu(1)
89+ right: parent.right
90+ rightMargin: units.gu(2)
91+ bottom: parent.bottom
92+ bottomMargin: units.gu(1)
93+ }
94+ visible: root.pinLength == -1
95+ width: height
96+ name: "erase"
97+ MouseArea {
98+ anchors.fill: parent
99+ onClicked: pinentryField.text = pinentryField.text.substring(0, pinentryField.text.length-1);
100+ }
101+ }
79102 }
80103
81104 UbuntuShape {
@@ -154,7 +177,7 @@ Column {
154177 objectName: "pinPadButtonBack"
155178 width: root.padWidth / 3
156179 height: root.padHeight / 4
157− iconName: "back"
180+ subText: "CANCEL"
158181 onClicked: root.cancel();
159182 }
160183
@@ -171,8 +194,15 @@ Column {
171194 objectName: "pinPadButtonErase"
172195 width: root.padWidth / 3
173196 height: root.padHeight / 4
174− iconName: "erase"
175− onClicked: pinentryField.text = pinentryField.text.substring(0, pinentryField.text.length-1)
197+ iconName: root.pinLength == -1 ? "" : "erase"
198+ subText: root.pinLength == -1 ? "DONE" : ""
199+ onClicked: {
200+ if (root.pinLength !== -1) {
201+ pinentryField.text = pinentryField.text.substring(0, pinentryField.text.length-1);
202+ } else {
203+ root.entered(pinentryField.text);
204+ }
205+ }
176206 enabled: entryEnabled
177207 }
178208 }
Launcher/Launcher.qml+2−2
@@ -28,8 +28,8 @@ Item {
2828
2929 property int panelWidth: units.gu(8)
3030 property int dragAreaWidth: units.gu(1)
31− property int minimizeDistance: panelWidth * 2.5
32− property real progress: dragArea.dragging && dragArea.touchX > panelWidth ?
31+ property int minimizeDistance: units.gu(26)
32+ property real progress: dragArea.dragging && dragArea.touchX > panelWidth ?
3333 (width * (dragArea.touchX-panelWidth) / (width - panelWidth)) : 0
3434
3535 readonly property bool shown: panel.x > -panel.width
Notifications/NotificationMenuItemFactory.qml+20−6
@@ -54,7 +54,8 @@ Loader {
5454
5555 Component.onCompleted: {
5656 menuModel.loadExtendedAttributes(menuIndex, {"x-echo-mode-password": "bool"});
57− textfield.echoMode = menuData.ext.xEchoModePassword ? TextInput.Password : TextInput.Normal
57+ checkBox.checked = menuData.ext.xEchoModePassword ? false : true
58+ checkBoxRow.visible = menuData.ext.xEchoModePassword
5859 }
5960
6061 Label {
@@ -65,11 +66,29 @@ Loader {
6566 id: textfield
6667
6768 anchors.left: parent.left; anchors.right: parent.right
69+ echoMode: checkBox.checked ? TextInput.Normal : TextInput.Password
6870 height: units.gu(5)
6971 onTextChanged: {
7072 menuModel.changeState(menuIndex, text);
7173 }
7274 }
75+
76+ Row {
77+ id: checkBoxRow
78+
79+ spacing: units.gu(.5)
80+
81+ CheckBox {
82+ id: checkBox
83+
84+ checked: false
85+ }
86+
87+ Label {
88+ anchors.verticalCenter: checkBox.verticalCenter
89+ text: i18n.tr("Show password")
90+ }
91+ }
7392 }
7493 }
7594
@@ -78,11 +97,6 @@ Loader {
7897 PinLockscreen {
7998 anchors.left: parent.left; anchors.right: parent.right
8099
81− Component.onCompleted: {
82− menuModel.loadExtendedAttributes(menuIndex, {'x-canonical-pin-length': 'int'});
83− pinLength = menuData.ext.xCanonicalPinLength;
84− }
85−
86100 onEntered: {
87101 menuModel.changeState(menuIndex, passphrase);
88102 entryEnabled = false;
Shell.qml+8−1
@@ -402,6 +402,10 @@ FocusScope {
402402
403403 Lockscreen {
404404 id: lockscreen
405+ objectName: "lockscreen"
406+
407+ readonly property int backgroundTopMargin: -panel.panelHeight
408+
405409 hides: [launcher, panel.indicators, hud]
406410 shown: false
407411 enabled: true
@@ -647,19 +651,22 @@ FocusScope {
647651 Launcher {
648652 id: launcher
649653
654+ readonly property bool dashSwipe: progress > 0
655+
650656 anchors.top: parent.top
651657 anchors.bottom: parent.bottom
652658 width: parent.width
653659 dragAreaWidth: shell.edgeSize
654660 available: (!greeter.shown || greeter.narrowMode) && edgeDemo.launcherEnabled
661+
655662 onDashItemSelected: showHome()
656663 onDash: {
657664 if (stages.shown) {
658− dash.setCurrentScope("applications.scope", true /* animate */, true /* reset */)
659665 stages.hide();
660666 launcher.hide();
661667 }
662668 }
669+ onDashSwipeChanged: if (dashSwipe && stages.shown) dash.setCurrentScope("applications.scope", false, true)
663670 onLauncherApplicationSelected:{
664671 greeter.hide()
665672 shell.activateApplication(appId)
debian/changelog+66
@@ -1,3 +1,69 @@
1+unity8 (7.83+14.04.20131106-0ubuntu1) trusty; urgency=low
2+
3+ [ Andrea Cimitan ]
4+ * Place ShaderEffectSource of UbuntuShapeForItem under the Shape Item.
5+ (LP: #1239317)
6+
7+ [ Omer Akram ]
8+ * test: make sure the search indicator hides when an app has focus.
9+
10+ [ Nick Dedekind ]
11+ * Fixed indicator slider menu item alignment to label field and icon.
12+ (LP: #1240756)
13+
14+ [ chris.gagnon ]
15+ * Update to autopilot 1.4.
16+
17+ [ Ubuntu daily release ]
18+ * Automatic snapshot from revision 500
19+
20+ -- Ubuntu daily release <ps-jenkins@lists.canonical.com> Wed, 06 Nov 2013 03:37:02 +0000
21+
22+unity8 (7.83+14.04.20131105.1-0ubuntu1) trusty; urgency=low
23+
24+ [ Michał Sawicz ]
25+ * Implement switching between previews by swiping. (LP: #1220651,
26+ #1088572)
27+
28+ [ Nick Dedekind ]
29+ * Faster loading of indicator menus. (LP: #1226650)
30+
31+ [ Albert Astals ]
32+ * Make sure we have ssh started when we need it .
33+ * Fix a few warnings in DashContent.qml on shutdown
34+ Dash/DashContent.qml:119: TypeError: Cannot read property
35+ 'previewShown' of null Dash/DashContent.qml:120: TypeError: Cannot
36+ read property 'moving' of null .
37+ * Don't use deprecated Panel methods.
38+
39+ [ Christopher Lee ]
40+ * Adds an easy to consume function that attempts to unlock the unity
41+ greeter. (LP: #1240261)
42+
43+ [ Lars Uebernickel ]
44+ * Indicators: add TimeFormatter and use it in the messaging menu This
45+ component can be used to turn a timestamp and a format string into a
46+ string with the corresponding time and format. The string will
47+ change whenever the timezone changes. (LP: #1236413)
48+
49+ [ Andrea Cimitan ]
50+ * Allow drag over bounds, but not overshoot. (LP: #1204300)
51+ * Threshold to activate the left edge swipe to reveal dash is now 26
52+ GU. (LP: #1236286)
53+
54+ [ Michael Zanetti ]
55+ * replace the launcher quicklist's Popover with an own quicklist
56+ implementation The Popover probably won't ever support what the
57+ launcher needs.
58+ * Implement switching between previews by swiping. (LP: #1220651,
59+ #1088572)
60+ * don't trigger the greeter teasing during a movement of the greeter.
61+
62+ [ Ubuntu daily release ]
63+ * Automatic snapshot from revision 495
64+
65+ -- Ubuntu daily release <ps-jenkins@lists.canonical.com> Tue, 05 Nov 2013 12:22:04 +0000
66+
167unity8 (7.83+14.04.20131031-0ubuntu1) trusty; urgency=low
268
369 [ Michał Sawicz ]
debian/control+1−1
@@ -91,7 +91,7 @@ Description: Unity 8 shell
9191Package: unity8-autopilot
9292Architecture: all
9393Depends: gir1.2-glib-2.0,
94− libautopilot-qt,
94+ libautopilot-qt (>= 1.4),
9595 libqt5test5,
9696 libqt5widgets5,
9797 python-evdev,
plugins/Ubuntu/Gestures/AxisVelocityCalculator.cpp+9−18
@@ -21,25 +21,19 @@
2121#include "AxisVelocityCalculator.h"
2222#include <QtCore/QElapsedTimer>
2323
24−class RealTimeSource : public UbuntuGestures::TimeSource {
25−public:
26− RealTimeSource()
27− : UbuntuGestures::TimeSource() {
28− m_timer.start();
29− }
30− virtual qint64 msecsSinceReference() {
31− return m_timer.elapsed();
32− }
33−private:
34− QElapsedTimer m_timer;
35−};
24+using namespace UbuntuGestures;
3625
3726AxisVelocityCalculator::AxisVelocityCalculator(QObject *parent)
27+ : AxisVelocityCalculator(SharedTimeSource(new RealTimeSource), parent)
28+{
29+}
30+
31+AxisVelocityCalculator::AxisVelocityCalculator(const SharedTimeSource &timeSource,
32+ QObject *parent)
3833 : QObject(parent)
39− , m_timeSource(new RealTimeSource)
34+ , m_timeSource(timeSource)
4035 , m_trackedPosition(0.0)
4136{
42− m_timeSource->setParent(this);
4337 reset();
4438}
4539
@@ -142,11 +136,8 @@ int AxisVelocityCalculator::numSamples() const
142136 }
143137}
144138
145−void AxisVelocityCalculator::setTimeSource(UbuntuGestures::TimeSource *timeSource)
139+void AxisVelocityCalculator::setTimeSource(const SharedTimeSource &timeSource)
146140{
147− if (m_timeSource && m_timeSource->parent() == this)
148− delete m_timeSource;
149−
150141 m_timeSource = timeSource;
151142
152143 if (numSamples() > 0) {
plugins/Ubuntu/Gestures/AxisVelocityCalculator.h+9−16
@@ -24,19 +24,7 @@
2424#include "UbuntuGesturesGlobal.h"
2525#include <stdint.h>
2626#include <QtCore/QObject>
27−
28−namespace UbuntuGestures {
29−/*
30− Interface for a time source.
31− */
32−class UBUNTUGESTURES_EXPORT TimeSource : public QObject {
33− Q_OBJECT
34−public:
35− virtual ~TimeSource() {}
36− /* Returns the current time in milliseconds since some reference time in the past. */
37− virtual qint64 msecsSinceReference() = 0;
38−};
39−}
27+#include "TimeSource.h"
4028
4129/*
4230 Estimates the current velocity of a finger based on recent movement along an axis
@@ -73,10 +61,15 @@ class UBUNTUGESTURES_EXPORT AxisVelocityCalculator : public QObject
7361public:
7462
7563 /*
76− Regular constructor
64+ Regular, simple, constructor
7765 */
7866 AxisVelocityCalculator(QObject *parent = 0);
7967
68+ /*
69+ Constructor that takes a TimeSource
70+ */
71+ AxisVelocityCalculator(const UbuntuGestures::SharedTimeSource &timeSource, QObject *parent = 0);
72+
8073 virtual ~AxisVelocityCalculator();
8174
8275 qreal trackedPosition() const;
@@ -97,7 +90,7 @@ public:
9790 /*
9891 Replaces the TimeSource with the given one. Useful for testing purposes.
9992 */
100− void setTimeSource(UbuntuGestures::TimeSource *timeSource);
93+ void setTimeSource(const UbuntuGestures::SharedTimeSource &timeSource);
10194
10295 /*
10396 The minimum amount of samples needed for a velocity calculation.
@@ -145,7 +138,7 @@ private:
145138 int m_samplesRead; /* index of the oldest sample available. -1 if buffer is empty */
146139 int m_samplesWrite; /* index where the next sample will be written */
147140
148− UbuntuGestures::TimeSource *m_timeSource;
141+ UbuntuGestures::SharedTimeSource m_timeSource;
149142
150143 qreal m_trackedPosition;
151144};
plugins/Ubuntu/Gestures/CMakeLists.txt+1
@@ -6,6 +6,7 @@ set(UbuntuGestureQml_SOURCES
66 AxisVelocityCalculator.cpp
77 Direction.cpp
88 DirectionalDragArea.cpp
9+ TimeSource.cpp
910)
1011
1112add_definitions(-DUBUNTUGESTURES_LIBRARY)
plugins/Ubuntu/Gestures/DirectionalDragArea.cpp+307−71
@@ -18,6 +18,75 @@
1818
1919#include <QtCore/qmath.h>
2020#include <QtCore/QTimer>
21+#include <QDebug>
22+
23+using namespace UbuntuGestures;
24+
25+#define DIRECTIONALDRAGAREA_DEBUG 0
26+
27+#if DIRECTIONALDRAGAREA_DEBUG
28+#define DDA_DEBUG(msg) qDebug("[DDA] " msg)
29+namespace {
30+QString touchPointStateToString(Qt::TouchPointState state) {
31+ switch (state) {
32+ case Qt::TouchPointPressed:
33+ return QString("pressed");
34+ case Qt::TouchPointMoved:
35+ return QString("moved");
36+ case Qt::TouchPointStationary:
37+ return QString("stationary");
38+ default: // Qt::TouchPointReleased:
39+ return QString("released");
40+ }
41+}
42+QString touchEventToString(QTouchEvent *ev)
43+{
44+ QString message;
45+
46+ switch (ev->type()) {
47+ case QEvent::TouchBegin:
48+ message.append("TouchBegin ");
49+ break;
50+ case QEvent::TouchUpdate:
51+ message.append("TouchUpdate ");
52+ break;
53+ case QEvent::TouchEnd:
54+ message.append("TouchEnd ");
55+ break;
56+ default: //QEvent::TouchCancel
57+ message.append("TouchCancel ");
58+ }
59+
60+ for (int i=0; i < ev->touchPoints().size(); ++i) {
61+
62+ const QTouchEvent::TouchPoint& touchPoint = ev->touchPoints().at(i);
63+ message.append(
64+ QString("(id:%1, state:%2, scenePos:(%3,%4)) ")
65+ .arg(touchPoint.id())
66+ .arg(touchPointStateToString(touchPoint.state()))
67+ .arg(touchPoint.scenePos().x())
68+ .arg(touchPoint.scenePos().y())
69+ );
70+ }
71+
72+ return message;
73+}
74+
75+const char *statusToString(DirectionalDragArea::Status status)
76+{
77+ if (status == DirectionalDragArea::WaitingForTouch) {
78+ return "WaitingForTouch";
79+ } else if (status == DirectionalDragArea::Undecided) {
80+ return "Undecided";
81+ } else {
82+ return "Recognized";
83+ }
84+}
85+
86+} // namespace {
87+#else // DIRECTIONALDRAGAREA_DEBUG
88+#define DDA_DEBUG(msg) do{}while(0)
89+#endif // DIRECTIONALDRAGAREA_DEBUG
2190
2291// Essentially a QTimer wrapper
2392class RecognitionTimer : public UbuntuGestures::AbstractTimer
@@ -48,9 +117,12 @@ DirectionalDragArea::DirectionalDragArea(QQuickItem *parent)
48117 , m_minSpeed(0)
49118 , m_maxSilenceTime(200)
50119 , m_silenceTime(0)
120+ , m_compositionTime(60)
51121 , m_numSamplesOnLastSpeedCheck(0)
52122 , m_recognitionTimer(0)
53123 , m_velocityCalculator(0)
124+ , m_timeSource(new RealTimeSource)
125+ , m_activeTouches(m_timeSource)
54126{
55127 setRecognitionTimer(new RecognitionTimer(this));
56128 m_recognitionTimer->setInterval(60);
@@ -73,8 +145,8 @@ void DirectionalDragArea::setDirection(Direction::Type direction)
73145
74146void DirectionalDragArea::setMaxDeviation(qreal value)
75147{
76− if (m_dampedPos.maxDelta() != value) {
77− m_dampedPos.setMaxDelta(value);
148+ if (m_dampedScenePos.maxDelta() != value) {
149+ m_dampedScenePos.setMaxDelta(value);
78150 Q_EMIT maxDeviationChanged(value);
79151 }
80152}
@@ -118,6 +190,14 @@ void DirectionalDragArea::setMaxSilenceTime(int value)
118190 }
119191}
120192
193+void DirectionalDragArea::setCompositionTime(int value)
194+{
195+ if (m_compositionTime != value) {
196+ m_compositionTime = value;
197+ Q_EMIT compositionTimeChanged(value);
198+ }
199+}
200+
121201void DirectionalDragArea::setRecognitionTimer(UbuntuGestures::AbstractTimer *timer)
122202{
123203 int interval = 0;
@@ -141,9 +221,11 @@ void DirectionalDragArea::setRecognitionTimer(UbuntuGestures::AbstractTimer *tim
141221 }
142222}
143223
144−void DirectionalDragArea::setTimeSource(UbuntuGestures::TimeSource *timeSource)
224+void DirectionalDragArea::setTimeSource(const SharedTimeSource &timeSource)
145225{
226+ m_timeSource = timeSource;
146227 m_velocityCalculator->setTimeSource(timeSource);
228+ m_activeTouches.m_timeSource = timeSource;
147229}
148230
149231qreal DirectionalDragArea::distance() const
@@ -186,6 +268,12 @@ qreal DirectionalDragArea::touchSceneY() const
186268
187269void DirectionalDragArea::touchEvent(QTouchEvent *event)
188270{
271+ #if DIRECTIONALDRAGAREA_DEBUG
272+ // TODO Consider using qCDebug() when available (Qt 5.2)
273+ qDebug() << "[DDA]" << m_timeSource->msecsSinceReference()
274+ << qPrintable(touchEventToString(event));
275+ #endif
276+
189277 if (!isEnabled() || !isVisible()) {
190278 QQuickItem::touchEvent(event);
191279 return;
@@ -198,76 +286,124 @@ void DirectionalDragArea::touchEvent(QTouchEvent *event)
198286 case Undecided:
199287 touchEvent_undecided(event);
200288 break;
201− case Recognized:
289+ default: // Recognized:
202290 touchEvent_recognized(event);
203291 break;
204− default: // Rejected
205− touchEvent_rejected(event);
206− break;
207292 }
293+
294+ m_activeTouches.update(event);
208295}
209296
210297void DirectionalDragArea::touchEvent_absent(QTouchEvent *event)
211298{
212− if ((event->touchPointStates() && (Qt::TouchPointPressed || Qt::TouchPointMoved))
213− && event->touchPoints().count() == 1) {
214− const QTouchEvent::TouchPoint &touchPoint = event->touchPoints()[0];
215− m_startPos = touchPoint.pos();
216− m_startScenePos = touchPoint.scenePos();
217− m_touchId = touchPoint.id();
218− m_dampedPos.reset(m_startPos);
219− updateVelocityCalculator(m_startPos);
220− m_velocityCalculator->reset();
221− m_numSamplesOnLastSpeedCheck = 0;
222− m_silenceTime = 0;
223− setPreviousPos(m_startPos);
224− setPreviousScenePos(m_startScenePos);
299+ if (!event->touchPointStates().testFlag(Qt::TouchPointPressed)) {
300+ // Nothing to see here. No touch starting in this event.
301+ return;
302+ }
225303
226− if (m_distanceThreshold > 0)
227− setStatus(Undecided);
228− else
229− setStatus(Recognized);
304+ if (isWithinTouchCompositionWindow()) {
305+ // too close to the last touch start. So we consider them as starting roughly at the same time.
306+ // Can't be a single-touch gesture.
307+ #if DIRECTIONALDRAGAREA_DEBUG
308+ qDebug("[DDA] A new touch point came in but we're still within time composition window. Ignoring it.");
309+ #endif
310+ return;
230311 }
312+
313+ const QList<QTouchEvent::TouchPoint> &touchPoints = event->touchPoints();
314+
315+ const QTouchEvent::TouchPoint *newTouchPoint = nullptr;
316+ for (int i = 0; i < touchPoints.count(); ++i) {
317+ const QTouchEvent::TouchPoint &touchPoint = touchPoints.at(i);
318+ if (touchPoint.state() == Qt::TouchPointPressed) {
319+ if (newTouchPoint) {
320+ // more than one touch starting in this QTouchEvent. Can't be a single-touch gesture
321+ return;
322+ } else {
323+ // that's our candidate
324+ m_touchId = touchPoint.id();
325+ newTouchPoint = &touchPoint;
326+ }
327+ }
328+ }
329+
330+ Q_ASSERT(newTouchPoint);
331+
332+ // If we have made this far, we are good to go to the next status.
333+
334+ m_startPos = newTouchPoint->pos();
335+ m_startScenePos = newTouchPoint->scenePos();
336+ m_touchId = newTouchPoint->id();
337+ m_dampedScenePos.reset(m_startScenePos);
338+ updateVelocityCalculator(m_startScenePos);
339+ m_velocityCalculator->reset();
340+ m_numSamplesOnLastSpeedCheck = 0;
341+ m_silenceTime = 0;
342+ setPreviousPos(m_startPos);
343+ setPreviousScenePos(m_startScenePos);
344+
345+ setStatus(Undecided);
231346}
232347
233348void DirectionalDragArea::touchEvent_undecided(QTouchEvent *event)
234349{
235350 const QTouchEvent::TouchPoint *touchPoint = fetchTargetTouchPoint(event);
236− const QPointF &touchPos = touchPoint->pos();
351+
352+ if (!touchPoint) {
353+ qCritical() << "DirectionalDragArea[status=Undecided]: touch " << m_touchId
354+ << "missing from QTouchEvent without first reaching state Qt::TouchPointReleased. "
355+ "Considering it as released.";
356+ setStatus(WaitingForTouch);
357+ return;
358+ }
359+
360+ const QPointF &touchScenePos = touchPoint->scenePos();
237361
238362 if (touchPoint->state() == Qt::TouchPointReleased) {
239363 // touch has ended before recognition concluded
364+ DDA_DEBUG("Touch has ended before recognition concluded");
240365 setStatus(WaitingForTouch);
241366 return;
242367 }
243368
244− if (event->touchPointStates().testFlag(Qt::TouchPointPressed)
245− || event->touchPoints().count() > 1) {
369+ if (event->touchPointStates().testFlag(Qt::TouchPointPressed) && isWithinTouchCompositionWindow()) {
246370 // multi-finger drags are not accepted
247− setStatus(Rejected);
371+ DDA_DEBUG("Multi-finger drags are not accepted");
372+ setStatus(WaitingForTouch);
248373 return;
249374 }
250375
251− m_previousDampedPos.setX(m_dampedPos.x());
252− m_previousDampedPos.setY(m_dampedPos.y());
253− m_dampedPos.update(touchPos);
254− updateVelocityCalculator(touchPos);
376+ m_previousDampedScenePos.setX(m_dampedScenePos.x());
377+ m_previousDampedScenePos.setY(m_dampedScenePos.y());
378+ m_dampedScenePos.update(touchScenePos);
379+ updateVelocityCalculator(touchScenePos);
255380
256381 if (!pointInsideAllowedArea()) {
257− setStatus(Rejected);
382+ DDA_DEBUG("Rejecting gesture because touch point is outside allowed area.");
383+ setStatus(WaitingForTouch);
258384 return;
259385 }
260386
261387 if (!movingInRightDirection()) {
262− setStatus(Rejected);
388+ DDA_DEBUG("Rejecting gesture becauuse touch point is moving in the wrong direction.");
389+ setStatus(WaitingForTouch);
263390 return;
264391 }
265392
266− setPreviousPos(touchPos);
267− setPreviousScenePos(touchPoint->scenePos());
393+ setPreviousPos(touchPoint->pos());
394+ setPreviousScenePos(touchScenePos);
268395
269− if (movedFarEnough(touchPos)) {
396+ if (isWithinTouchCompositionWindow()) {
397+ // There's still time for some new touch to appear and ruin our party as it would be combined
398+ // with our m_touchId one and therefore deny the possibility of a single-finger gesture.
399+ DDA_DEBUG("Sill within composition window. Let's wait more.");
400+ return;
401+ }
402+
403+ if (movedFarEnough(touchScenePos)) {
270404 setStatus(Recognized);
405+ } else {
406+ DDA_DEBUG("Didn't move far enough yet. Let's wait more.");
271407 }
272408}
273409
@@ -275,20 +411,18 @@ void DirectionalDragArea::touchEvent_recognized(QTouchEvent *event)
275411{
276412 const QTouchEvent::TouchPoint *touchPoint = fetchTargetTouchPoint(event);
277413
278− setPreviousPos(touchPoint->pos());
279− setPreviousScenePos(touchPoint->scenePos());
280−
281− if (touchPoint->state() == Qt::TouchPointReleased) {
414+ if (!touchPoint) {
415+ qCritical() << "DirectionalDragArea[status=Recognized]: touch " << m_touchId
416+ << "missing from QTouchEvent without first reaching state Qt::TouchPointReleased. "
417+ "Considering it as released.";
282418 setStatus(WaitingForTouch);
283− }
284−}
285−
286−void DirectionalDragArea::touchEvent_rejected(QTouchEvent *event)
287−{
288− const QTouchEvent::TouchPoint *touchPoint = fetchTargetTouchPoint(event);
419+ } else {
420+ setPreviousPos(touchPoint->pos());
421+ setPreviousScenePos(touchPoint->scenePos());
289422
290− if (!touchPoint || touchPoint->state() == Qt::TouchPointReleased) {
291− setStatus(WaitingForTouch);
423+ if (touchPoint->state() == Qt::TouchPointReleased) {
424+ setStatus(WaitingForTouch);
425+ }
292426 }
293427}
294428
@@ -307,8 +441,8 @@ const QTouchEvent::TouchPoint *DirectionalDragArea::fetchTargetTouchPoint(QTouch
307441
308442bool DirectionalDragArea::pointInsideAllowedArea() const
309443{
310− qreal dX = m_dampedPos.x() - m_startPos.x();
311− qreal dY = m_dampedPos.y() - m_startPos.y();
444+ qreal dX = m_dampedScenePos.x() - m_startScenePos.x();
445+ qreal dY = m_dampedScenePos.y() - m_startScenePos.y();
312446
313447 switch (m_direction) {
314448 case Direction::Upwards:
@@ -326,22 +460,26 @@ bool DirectionalDragArea::movingInRightDirection() const
326460{
327461 switch (m_direction) {
328462 case Direction::Upwards:
329− return m_dampedPos.y() <= m_previousDampedPos.y();
463+ return m_dampedScenePos.y() <= m_previousDampedScenePos.y();
330464 case Direction::Downwards:
331− return m_dampedPos.y() >= m_previousDampedPos.y();
465+ return m_dampedScenePos.y() >= m_previousDampedScenePos.y();
332466 case Direction::Leftwards:
333− return m_dampedPos.x() <= m_previousDampedPos.x();
467+ return m_dampedScenePos.x() <= m_previousDampedScenePos.x();
334468 default: // Direction::Rightwards:
335− return m_dampedPos.x() >= m_previousDampedPos.x();
469+ return m_dampedScenePos.x() >= m_previousDampedScenePos.x();
336470 }
337471}
338472
339473bool DirectionalDragArea::movedFarEnough(const QPointF &point) const
340474{
341− if (Direction::isHorizontal(m_direction))
342− return qFabs(point.x() - m_startPos.x()) > m_distanceThreshold;
343− else
344− return qFabs(point.y() - m_startPos.y()) > m_distanceThreshold;
475+ if (m_distanceThreshold > 0) {
476+ if (Direction::isHorizontal(m_direction))
477+ return qFabs(point.x() - m_startScenePos.x()) > m_distanceThreshold;
478+ else
479+ return qFabs(point.y() - m_startScenePos.y()) > m_distanceThreshold;
480+ } else {
481+ return true;
482+ }
345483}
346484
347485void DirectionalDragArea::checkSpeed()
@@ -351,7 +489,8 @@ void DirectionalDragArea::checkSpeed()
351489 qreal minSpeedMsecs = m_minSpeed / 1000.0;
352490
353491 if (speed < minSpeedMsecs) {
354− setStatus(Rejected);
492+ DDA_DEBUG("Rejecting gesture because it's below minimum speed.");
493+ setStatus(WaitingForTouch);
355494 }
356495 }
357496
@@ -359,7 +498,8 @@ void DirectionalDragArea::checkSpeed()
359498 m_silenceTime += m_recognitionTimer->interval();
360499
361500 if (m_silenceTime > m_maxSilenceTime) {
362− setStatus(Rejected);
501+ DDA_DEBUG("Rejecting gesture because it's silence time has been exceeded.");
502+ setStatus(WaitingForTouch);
363503 }
364504 } else {
365505 m_silenceTime = 0;
@@ -381,11 +521,13 @@ void DirectionalDragArea::setStatus(DirectionalDragArea::Status newStatus)
381521 m_status = newStatus;
382522 Q_EMIT statusChanged(m_status);
383523
524+ #if DIRECTIONALDRAGAREA_DEBUG
525+ qDebug() << "[DDA]" << statusToString(oldStatus) << "->" << statusToString(newStatus);
526+ #endif
527+
384528 switch (newStatus) {
385529 case WaitingForTouch:
386− if (oldStatus != DirectionalDragArea::Rejected) {
387− Q_EMIT draggingChanged(false);
388− }
530+ Q_EMIT draggingChanged(false);
389531 break;
390532 case Undecided:
391533 m_recognitionTimer->start();
@@ -395,9 +537,6 @@ void DirectionalDragArea::setStatus(DirectionalDragArea::Status newStatus)
395537 if (oldStatus == WaitingForTouch)
396538 Q_EMIT draggingChanged(true);
397539 break;
398− case Rejected:
399− Q_EMIT draggingChanged(false);
400− break;
401540 default:
402541 // no-op
403542 break;
@@ -406,8 +545,6 @@ void DirectionalDragArea::setStatus(DirectionalDragArea::Status newStatus)
406545
407546void DirectionalDragArea::setPreviousPos(const QPointF &point)
408547{
409− Q_ASSERT(m_status != Rejected);
410−
411548 bool xChanged = m_previousPos.x() != point.x();
412549 bool yChanged = m_previousPos.y() != point.y();
413550
@@ -428,8 +565,6 @@ void DirectionalDragArea::setPreviousPos(const QPointF &point)
428565
429566void DirectionalDragArea::setPreviousScenePos(const QPointF &point)
430567{
431− Q_ASSERT(m_status != Rejected);
432−
433568 bool xChanged = m_previousScenePos.x() != point.x();
434569 bool yChanged = m_previousScenePos.y() != point.y();
435570
@@ -457,5 +592,106 @@ void DirectionalDragArea::updateVelocityCalculator(const QPointF &point)
457592 }
458593}
459594
595+bool DirectionalDragArea::isWithinTouchCompositionWindow()
596+{
597+ return !m_activeTouches.isEmpty() &&
598+ m_timeSource->msecsSinceReference() <=
599+ m_activeTouches.mostRecentStartTime() + (qint64)compositionTime();
600+}
601+
602+//************************** ActiveTouchesInfo **************************
603+
604+DirectionalDragArea::ActiveTouchesInfo::ActiveTouchesInfo(const SharedTimeSource &timeSource)
605+ : m_timeSource(timeSource), m_lastUsedIndex(-1)
606+{
607+ // Estimate of the maximum number of active touches we might reach.
608+ // Not a problem if it ends up being an underestimate as this is just
609+ // an optimization.
610+ m_vector.resize(3);
611+}
612+
613+void DirectionalDragArea::ActiveTouchesInfo::update(QTouchEvent *event)
614+{
615+ if (!(event->touchPointStates() & (Qt::TouchPointPressed | Qt::TouchPointReleased))) {
616+ // nothing to update
617+ return;
618+ }
619+
620+ const QList<QTouchEvent::TouchPoint> &touchPoints = event->touchPoints();
621+ for (int i = 0; i < touchPoints.count(); ++i) {
622+ const QTouchEvent::TouchPoint &touchPoint = touchPoints.at(i);
623+ if (touchPoint.state() == Qt::TouchPointPressed) {
624+ addTouchPoint(touchPoint);
625+ } else if (touchPoint.state() == Qt::TouchPointReleased) {
626+ removeTouchPoint(touchPoint);
627+ }
628+ }
629+}
630+
631+void DirectionalDragArea::ActiveTouchesInfo::addTouchPoint(const QTouchEvent::TouchPoint &touchPoint)
632+{
633+ ActiveTouchInfo &activeTouchInfo = getEmptySlot();
634+ activeTouchInfo.id = touchPoint.id();
635+ activeTouchInfo.startTime = m_timeSource->msecsSinceReference();
636+}
637+
638+void DirectionalDragArea::ActiveTouchesInfo::removeTouchPoint(const QTouchEvent::TouchPoint &touchPoint)
639+{
640+ for (int i = 0; i <= m_lastUsedIndex; ++i) {
641+ if (touchPoint.id() == m_vector.at(i).id) {
642+ freeSlot(i);
643+ return;
644+ }
645+ }
646+ Q_ASSERT(false); // shouldn't reach this point
647+}
648+
649+DirectionalDragArea::ActiveTouchInfo &DirectionalDragArea::ActiveTouchesInfo::getEmptySlot()
650+{
651+ Q_ASSERT(m_lastUsedIndex < m_vector.size());
652+
653+ // Look for an in-between vacancy first
654+ for (int i = 0; i < m_lastUsedIndex; ++i) {
655+ ActiveTouchInfo &activeTouchInfo = m_vector[i];
656+ if (!activeTouchInfo.isValid()) {
657+ return activeTouchInfo;
658+ }
659+ }
660+
661+ ++m_lastUsedIndex;
662+ if (m_lastUsedIndex >= m_vector.size()) {
663+ m_vector.resize(m_lastUsedIndex + 1);
664+ }
665+
666+ return m_vector[m_lastUsedIndex];
667+}
668+
669+void DirectionalDragArea::ActiveTouchesInfo::freeSlot(int index)
670+{
671+ m_vector[index].reset();
672+ if (index == m_lastUsedIndex) {
673+ do {
674+ --m_lastUsedIndex;
675+ } while (m_lastUsedIndex >= 0 && !m_vector.at(m_lastUsedIndex).isValid());
676+ }
677+}
678+
679+qint64 DirectionalDragArea::ActiveTouchesInfo::mostRecentStartTime()
680+{
681+ Q_ASSERT(m_lastUsedIndex >= 0);
682+
683+ qint64 highestStartTime = m_vector.at(0).startTime;
684+ int i = 1;
685+ do {
686+ const ActiveTouchInfo &activeTouchInfo = m_vector.at(i);
687+ if (activeTouchInfo.isValid() && activeTouchInfo.startTime > highestStartTime) {
688+ highestStartTime = activeTouchInfo.startTime;
689+ }
690+ ++i;
691+ } while (i < m_lastUsedIndex);
692+
693+ return highestStartTime;
694+}
695+
460696// Because we are defining a new QObject-based class (RecognitionTimer) here.
461697#include "DirectionalDragArea.moc"
plugins/Ubuntu/Gestures/DirectionalDragArea.h+50−13
@@ -117,9 +117,17 @@ class UBUNTUGESTURES_EXPORT DirectionalDragArea : public QQuickItem {
117117 Q_PROPERTY(int maxSilenceTime READ maxSilenceTime
118118 WRITE setMaxSilenceTime
119119 NOTIFY maxSilenceTimeChanged)
120+
120121 //
121122 /////
122123
124+ // Maximum time (in milliseconds) after the start of a given touch point where
125+ // subsequent touch starts are grouped with the first one into an N-touches gesture
126+ // (e.g. a two-fingers tap or drag).
127+ Q_PROPERTY(int compositionTime READ compositionTime
128+ WRITE setCompositionTime
129+ NOTIFY compositionTimeChanged)
130+
123131 Q_ENUMS(Direction)
124132 Q_ENUMS(Status)
125133public:
@@ -130,26 +138,23 @@ public:
130138
131139 // Describes the state of the directional drag gesture.
132140 enum Status {
133− // There's no touch point over this area.
141+ // Waiting for a new touch point to land on this area. No gesture is being processed
142+ // or tracked.
134143 WaitingForTouch,
135144
136145 // A touch point has landed on this area but it's not know yet whether it is
137146 // performing a drag in the correct direction.
147+ // If it's decided that the touch point is not performing a directional drag gesture,
148+ // it will be rejected/ignored and status will return to WaitingForTouch.
138149 Undecided, //Recognizing,
139150
140151 // There's a touch point in this area and it performed a drag in the correct
141152 // direction.
142153 //
143− // Once recognized, the gesture state will move back to Absent only once
154+ // Once recognized, the gesture state will move back to WaitingForTouch only once
144155 // that touch point ends. The gesture will remain in the Recognized state even if
145156 // the touch point starts moving in other directions or halts.
146157 Recognized,
147−
148− // A gesture was performed but it wasn't a single-touch drag in the correct
149− // direction.
150− // It will remain in this state until there are no more touch points over this
151− // area, at which point it will move to Absent state.
152− Rejected
153158 };
154159 Status status() const { return m_status; }
155160
@@ -164,7 +169,7 @@ public:
164169
165170 bool dragging() const { return (m_status == Undecided) || (m_status == Recognized); }
166171
167− qreal maxDeviation() const { return m_dampedPos.maxDelta(); }
172+ qreal maxDeviation() const { return m_dampedScenePos.maxDelta(); }
168173 void setMaxDeviation(qreal value);
169174
170175 qreal wideningAngle() const;
@@ -179,13 +184,16 @@ public:
179184 int maxSilenceTime() const { return m_maxSilenceTime; }
180185 void setMaxSilenceTime(int value);
181186
187+ int compositionTime() const { return m_compositionTime; }
188+ void setCompositionTime(int value);
189+
182190 // Replaces the existing Timer with the given one.
183191 //
184192 // Useful for providing a fake timer when testing.
185193 void setRecognitionTimer(UbuntuGestures::AbstractTimer *timer);
186194
187195 // Useful for testing, where a fake time source can be supplied
188− void setTimeSource(UbuntuGestures::TimeSource *timeSource);
196+ void setTimeSource(const UbuntuGestures::SharedTimeSource &timeSource);
189197
190198Q_SIGNALS:
191199 void directionChanged(Direction::Type direction);
@@ -198,6 +206,7 @@ Q_SIGNALS:
198206 void distanceThresholdChanged(qreal value);
199207 void minSpeedChanged(qreal value);
200208 void maxSilenceTimeChanged(int value);
209+ void compositionTimeChanged(int value);
201210 void touchXChanged(qreal value);
202211 void touchYChanged(qreal value);
203212 void touchSceneXChanged(qreal value);
@@ -213,7 +222,6 @@ private:
213222 void touchEvent_absent(QTouchEvent *event);
214223 void touchEvent_undecided(QTouchEvent *event);
215224 void touchEvent_recognized(QTouchEvent *event);
216− void touchEvent_rejected(QTouchEvent *event);
217225 bool pointInsideAllowedArea() const;
218226 bool movingInRightDirection() const;
219227 bool movedFarEnough(const QPointF &point) const;
@@ -222,6 +230,7 @@ private:
222230 void setPreviousPos(const QPointF &point);
223231 void setPreviousScenePos(const QPointF &point);
224232 void updateVelocityCalculator(const QPointF &point);
233+ bool isWithinTouchCompositionWindow();
225234
226235 Status m_status;
227236
@@ -233,8 +242,8 @@ private:
233242
234243 // A movement damper is used in some of the gesture recognition calculations
235244 // to get rid of noise or small oscillations in the touch position.
236− DampedPointF m_dampedPos;
237− QPointF m_previousDampedPos;
245+ DampedPointF m_dampedScenePos;
246+ QPointF m_previousDampedScenePos;
238247
239248 Direction::Type m_direction;
240249 qreal m_wideningAngle; // in degrees
@@ -243,9 +252,37 @@ private:
243252 qreal m_minSpeed;
244253 int m_maxSilenceTime; // in milliseconds
245254 int m_silenceTime; // in milliseconds
255+ int m_compositionTime; // in milliseconds
246256 int m_numSamplesOnLastSpeedCheck;
247257 UbuntuGestures::AbstractTimer *m_recognitionTimer;
248258 AxisVelocityCalculator *m_velocityCalculator;
259+
260+ UbuntuGestures::SharedTimeSource m_timeSource;
261+
262+ // Information about an active touch point
263+ struct ActiveTouchInfo {
264+ ActiveTouchInfo() : id(-1), startTime(-1) {}
265+ bool isValid() const { return id != -1; }
266+ void reset() { id = -1; }
267+ int id;
268+ qint64 startTime;
269+ };
270+ class ActiveTouchesInfo {
271+ public:
272+ ActiveTouchesInfo(const UbuntuGestures::SharedTimeSource &timeSource);
273+ void update(QTouchEvent *event);
274+ ActiveTouchInfo &touchInfo(int id);
275+ qint64 mostRecentStartTime();
276+ UbuntuGestures::SharedTimeSource m_timeSource;
277+ bool isEmpty() const { return m_lastUsedIndex == -1; }
278+ private:
279+ void addTouchPoint(const QTouchEvent::TouchPoint &touchPoint);
280+ ActiveTouchInfo &getEmptySlot();
281+ void freeSlot(int index);
282+ void removeTouchPoint(const QTouchEvent::TouchPoint &touchPoint);
283+ QVector<struct ActiveTouchInfo> m_vector;
284+ int m_lastUsedIndex;
285+ } m_activeTouches;
249286};
250287
251288#endif // DIRECTIONAL_DRAG_AREA_H
plugins/Ubuntu/Gestures/TimeSource.cppnew file+49
@@ -0,0 +1,49 @@
1+/*
2+ * Copyright (C) 2013 - Canonical Ltd.
3+ *
4+ * This program is free software: you can redistribute it and/or modify it
5+ * under the terms of the GNU Lesser General Public License, as
6+ * published by the Free Software Foundation; either version 2.1 or 3.0
7+ * of the License.
8+ *
9+ * This program is distributed in the hope that it will be useful, but
10+ * WITHOUT ANY WARRANTY; without even the implied warranties of
11+ * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR
12+ * PURPOSE. See the applicable version of the GNU Lesser General Public
13+ * License for more details.
14+ *
15+ * You should have received a copy of both the GNU Lesser General Public
16+ * License along with this program. If not, see <http://www.gnu.org/licenses/>
17+ *
18+ * Authored by: Daniel d'Andrada <daniel.dandrada@canonical.com>
19+ */
20+
21+#include "TimeSource.h"
22+
23+#include <QElapsedTimer>
24+
25+namespace UbuntuGestures {
26+class RealTimeSourcePrivate {
27+public:
28+ QElapsedTimer timer;
29+};
30+}
31+
32+using namespace UbuntuGestures;
33+
34+RealTimeSource::RealTimeSource()
35+ : UbuntuGestures::TimeSource()
36+ , d(new RealTimeSourcePrivate)
37+{
38+ d->timer.start();
39+}
40+
41+RealTimeSource::~RealTimeSource()
42+{
43+ delete d;
44+}
45+
46+qint64 RealTimeSource::msecsSinceReference()
47+{
48+ return d->timer.elapsed();
49+}
plugins/Ubuntu/Gestures/TimeSource.hnew file+54
@@ -0,0 +1,54 @@
1+/*
2+ * Copyright (C) 2013 - Canonical Ltd.
3+ *
4+ * This program is free software: you can redistribute it and/or modify it
5+ * under the terms of the GNU Lesser General Public License, as
6+ * published by the Free Software Foundation; either version 2.1 or 3.0
7+ * of the License.
8+ *
9+ * This program is distributed in the hope that it will be useful, but
10+ * WITHOUT ANY WARRANTY; without even the implied warranties of
11+ * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR
12+ * PURPOSE. See the applicable version of the GNU Lesser General Public
13+ * License for more details.
14+ *
15+ * You should have received a copy of both the GNU Lesser General Public
16+ * License along with this program. If not, see <http://www.gnu.org/licenses/>
17+ *
18+ * Authored by: Daniel d'Andrada <daniel.dandrada@canonical.com>
19+ */
20+
21+#ifndef UBUNTUGESTURES_TIMESOURCE_H
22+#define UBUNTUGESTURES_TIMESOURCE_H
23+
24+#include "UbuntuGesturesGlobal.h"
25+#include <QSharedPointer>
26+
27+namespace UbuntuGestures {
28+/*
29+ Interface for a time source.
30+ */
31+class UBUNTUGESTURES_EXPORT TimeSource {
32+public:
33+ virtual ~TimeSource() {}
34+ /* Returns the current time in milliseconds since some reference time in the past. */
35+ virtual qint64 msecsSinceReference() = 0;
36+};
37+typedef QSharedPointer<TimeSource> SharedTimeSource;
38+
39+/*
40+ Implementation of a time source
41+ */
42+class RealTimeSourcePrivate;
43+class RealTimeSource : public TimeSource {
44+public:
45+ RealTimeSource();
46+ virtual ~RealTimeSource();
47+ qint64 msecsSinceReference() override;
48+private:
49+ RealTimeSourcePrivate *d;
50+};
51+
52+} // namespace UbuntuGestures
53+
54+#endif // UBUNTUGESTURES_TIMESOURCE_H
plugins/Unity/Indicators/qml/SliderMenuItem.qml+3−2
@@ -51,12 +51,12 @@ FramedMenuItem {
5151
5252 control: Item {
5353 id: row
54− width: sliderMenu.text ? units.gu(20) : menuItem.width - (2 * menuItem.__contentsMargins)
54+ width: menuItem.text ? units.gu(20) : menuItem.width - (2 * menuItem.__contentsMargins)
5555 height: slider.height
5656
5757 Image {
5858 id: leftImage
59− visible: source != ""
59+ visible: status === Image.Ready
6060 anchors.left: row.left
6161 anchors.verticalCenter: row.verticalCenter
6262 height: units.gu(4)
@@ -96,6 +96,7 @@ FramedMenuItem {
9696
9797 Image {
9898 id: rightImage
99+ visible: status === Image.Ready
99100 anchors.right: row.right
100101 anchors.verticalCenter: row.verticalCenter
101102 height: units.gu(4)
po/ar.po+8−4
@@ -7,7 +7,7 @@ msgid ""
77msgstr ""
88"Project-Id-Version: unity\n"
99"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10−"POT-Creation-Date: 2013-10-11 12:12+0200\n"
10+"POT-Creation-Date: 2013-11-05 17:53+0100\n"
1111"PO-Revision-Date: 2013-10-20 19:41+0000\n"
1212"Last-Translator: Ibrahim Saed <ibraheem5000@gmail.com>\n"
1313"Language-Team: Arabic <ar@li.org>\n"
@@ -16,8 +16,8 @@ msgstr ""
1616"Content-Transfer-Encoding: 8bit\n"
1717"Plural-Forms: nplurals=6; plural=n==0 ? 0 : n==1 ? 1 : n==2 ? 2 : n % 100 >= "
1818"3 && n % 100 <= 10 ? 3 : n % 100 >= 11 && n % 100 <= 99 ? 4 : 5;\n"
19−"X-Launchpad-Export-Date: 2013-10-21 05:04+0000\n"
20−"X-Generator: Launchpad (build 16807)\n"
19+"X-Launchpad-Export-Date: 2013-11-08 06:37+0000\n"
20+"X-Generator: Launchpad (build 16820)\n"
2121
2222#: Applications/applications.js:23
2323msgid "Phone"
@@ -213,11 +213,15 @@ msgstr "تكلم الآن..."
213213msgid "Speaking..."
214214msgstr "تتكلم الآن..."
215215
216+#: Notifications/NotificationMenuItemFactory.qml:89
217+msgid "Show password"
218+msgstr ""
219+
216220#: Panel/SearchIndicator.qml:27
217221msgid "Search"
218222msgstr "ابحث"
219223
220−#: plugins/Unity/scope.cpp:398
224+#: plugins/Unity/scope.cpp:408
221225msgid "Sorry, there is nothing that matches your search."
222226msgstr "عذراً، لا يوجد ما يطابق بحثك."
223227
po/ast.po+8−25
@@ -7,7 +7,7 @@ msgid ""
77msgstr ""
88"Project-Id-Version: unity8\n"
99"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10−"POT-Creation-Date: 2013-10-11 12:12+0200\n"
10+"POT-Creation-Date: 2013-11-05 17:53+0100\n"
1111"PO-Revision-Date: 2013-10-03 14:02+0000\n"
1212"Last-Translator: ivarela <ivarela@ubuntu.com>\n"
1313"Language-Team: Asturian <ast@li.org>\n"
@@ -15,8 +15,8 @@ msgstr ""
1515"Content-Type: text/plain; charset=UTF-8\n"
1616"Content-Transfer-Encoding: 8bit\n"
1717"Plural-Forms: nplurals=2; plural=n != 1;\n"
18−"X-Launchpad-Export-Date: 2013-10-13 05:43+0000\n"
19−"X-Generator: Launchpad (build 16799)\n"
18+"X-Launchpad-Export-Date: 2013-11-08 06:37+0000\n"
19+"X-Generator: Launchpad (build 16820)\n"
2020
2121#: Applications/applications.js:23
2222msgid "Phone"
@@ -209,11 +209,15 @@ msgstr "Fala agora…"
209209msgid "Speaking..."
210210msgstr "Falando…"
211211
212+#: Notifications/NotificationMenuItemFactory.qml:89
213+msgid "Show password"
214+msgstr ""
215+
212216#: Panel/SearchIndicator.qml:27
213217msgid "Search"
214218msgstr "Guetar"
215219
216−#: plugins/Unity/scope.cpp:398
220+#: plugins/Unity/scope.cpp:408
217221msgid "Sorry, there is nothing that matches your search."
218222msgstr "Sentímoslo, nun hai res que concase cola gueta"
219223
@@ -225,24 +229,3 @@ msgstr "Too"
225229#, qt-format
226230msgid "Please enter %1"
227231msgstr "Introduz %1"
228−
229−#~ msgid "New Releases"
230−#~ msgstr "Llanzamientos nuevos"
231−
232−#~ msgid "Featured"
233−#~ msgstr "Destacaos"
234−
235−#~ msgid "Top Charting"
236−#~ msgstr "Meyor posicionaes"
237−
238−#~ msgid "Recent"
239−#~ msgstr "Recientes"
240−
241−#~ msgid "Videos"
242−#~ msgstr "Vídeos"
243−
244−#~ msgid "Music"
245−#~ msgstr "Música"
246−
247−#~ msgid "Popular Online"
248−#~ msgstr "Populares en llinia"
po/az.po+8−10
@@ -7,7 +7,7 @@ msgid ""
77msgstr ""
88"Project-Id-Version: unity\n"
99"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10−"POT-Creation-Date: 2013-10-11 12:12+0200\n"
10+"POT-Creation-Date: 2013-11-05 17:53+0100\n"
1111"PO-Revision-Date: 2013-06-26 23:48+0000\n"
1212"Last-Translator: Michał Sawicz <michal.sawicz@canonical.com>\n"
1313"Language-Team: Azerbaijani <az@li.org>\n"
@@ -15,8 +15,8 @@ msgstr ""
1515"Content-Type: text/plain; charset=UTF-8\n"
1616"Content-Transfer-Encoding: 8bit\n"
1717"Plural-Forms: nplurals=2; plural=n != 1;\n"
18−"X-Launchpad-Export-Date: 2013-10-13 05:43+0000\n"
19−"X-Generator: Launchpad (build 16799)\n"
18+"X-Launchpad-Export-Date: 2013-11-08 06:37+0000\n"
19+"X-Generator: Launchpad (build 16820)\n"
2020
2121#: Applications/applications.js:23
2222msgid "Phone"
@@ -205,11 +205,15 @@ msgstr "Söyləyin..."
205205msgid "Speaking..."
206206msgstr "Söylənilir..."
207207
208+#: Notifications/NotificationMenuItemFactory.qml:89
209+msgid "Show password"
210+msgstr ""
211+
208212#: Panel/SearchIndicator.qml:27
209213msgid "Search"
210214msgstr "Axtar"
211215
212−#: plugins/Unity/scope.cpp:398
216+#: plugins/Unity/scope.cpp:408
213217msgid "Sorry, there is nothing that matches your search."
214218msgstr "Bağışlayın, amma axtarışınıza heç bir nəticə uyğun gəlmir."
215219
@@ -221,9 +225,3 @@ msgstr ""
221225#, qt-format
222226msgid "Please enter %1"
223227msgstr ""
224−
225−#~ msgid "Music"
226−#~ msgstr "Musiqi"
227−
228−#~ msgid "Videos"
229−#~ msgstr "Videolar"
po/bg.po+8−16
@@ -7,7 +7,7 @@ msgid ""
77msgstr ""
88"Project-Id-Version: unity\n"
99"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10−"POT-Creation-Date: 2013-10-11 12:12+0200\n"
10+"POT-Creation-Date: 2013-11-05 17:53+0100\n"
1111"PO-Revision-Date: 2013-06-27 00:06+0000\n"
1212"Last-Translator: Miroslav E. Hadzhiev (Хаджиев) "
1313"<miroslav.hadzhiev@gmail.com>\n"
@@ -16,8 +16,8 @@ msgstr ""
1616"Content-Type: text/plain; charset=UTF-8\n"
1717"Content-Transfer-Encoding: 8bit\n"
1818"Plural-Forms: nplurals=2; plural=n != 1;\n"
19−"X-Launchpad-Export-Date: 2013-10-13 05:43+0000\n"
20−"X-Generator: Launchpad (build 16799)\n"
19+"X-Launchpad-Export-Date: 2013-11-08 06:37+0000\n"
20+"X-Generator: Launchpad (build 16820)\n"
2121
2222#: Applications/applications.js:23
2323msgid "Phone"
@@ -206,11 +206,15 @@ msgstr ""
206206msgid "Speaking..."
207207msgstr ""
208208
209+#: Notifications/NotificationMenuItemFactory.qml:89
210+msgid "Show password"
211+msgstr ""
212+
209213#: Panel/SearchIndicator.qml:27
210214msgid "Search"
211215msgstr "Търсене"
212216
213−#: plugins/Unity/scope.cpp:398
217+#: plugins/Unity/scope.cpp:408
214218msgid "Sorry, there is nothing that matches your search."
215219msgstr "Съжаляваме, няма нищо, което да отговаря на вашето търсене."
216220
@@ -222,15 +226,3 @@ msgstr ""
222226#, qt-format
223227msgid "Please enter %1"
224228msgstr ""
225−
226−#~ msgid "Featured"
227−#~ msgstr "Най-отличени"
228−
229−#~ msgid "Recent"
230−#~ msgstr "Най-нови"
231−
232−#~ msgid "Music"
233−#~ msgstr "Музика"
234−
235−#~ msgid "Videos"
236−#~ msgstr "Видеоклипове"
po/ca.po+8−25
@@ -7,7 +7,7 @@ msgid ""
77msgstr ""
88"Project-Id-Version: unity\n"
99"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10−"POT-Creation-Date: 2013-10-11 12:12+0200\n"
10+"POT-Creation-Date: 2013-11-05 17:53+0100\n"
1111"PO-Revision-Date: 2013-09-28 07:38+0000\n"
1212"Last-Translator: David Planella <david.planella@ubuntu.com>\n"
1313"Language-Team: Catalan <ca@li.org>\n"
@@ -15,8 +15,8 @@ msgstr ""
1515"Content-Type: text/plain; charset=UTF-8\n"
1616"Content-Transfer-Encoding: 8bit\n"
1717"Plural-Forms: nplurals=2; plural=n != 1;\n"
18−"X-Launchpad-Export-Date: 2013-10-13 05:43+0000\n"
19−"X-Generator: Launchpad (build 16799)\n"
18+"X-Launchpad-Export-Date: 2013-11-08 06:37+0000\n"
19+"X-Generator: Launchpad (build 16820)\n"
2020
2121#: Applications/applications.js:23
2222msgid "Phone"
@@ -211,11 +211,15 @@ msgstr "Parleu..."
211211msgid "Speaking..."
212212msgstr "S'està parlant..."
213213
214+#: Notifications/NotificationMenuItemFactory.qml:89
215+msgid "Show password"
216+msgstr ""
217+
214218#: Panel/SearchIndicator.qml:27
215219msgid "Search"
216220msgstr "Cerca"
217221
218−#: plugins/Unity/scope.cpp:398
222+#: plugins/Unity/scope.cpp:408
219223msgid "Sorry, there is nothing that matches your search."
220224msgstr "No hi ha res que coincideixi amb la cerca"
221225
@@ -227,24 +231,3 @@ msgstr ""
227231#, qt-format
228232msgid "Please enter %1"
229233msgstr "Introduïu %1"
230−
231−#~ msgid "Music"
232−#~ msgstr "Música"
233−
234−#~ msgid "Videos"
235−#~ msgstr "Vídeos"
236−
237−#~ msgid "Recent"
238−#~ msgstr "Recents"
239−
240−#~ msgid "Featured"
241−#~ msgstr "Destacats"
242−
243−#~ msgid "New Releases"
244−#~ msgstr "Novetats"
245−
246−#~ msgid "Top Charting"
247−#~ msgstr "El millor de les llistes"
248−
249−#~ msgid "Popular Online"
250−#~ msgstr "Popular a la xarxa"
po/cs.po+8−19
@@ -7,7 +7,7 @@ msgid ""
77msgstr ""
88"Project-Id-Version: unity8\n"
99"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10−"POT-Creation-Date: 2013-10-11 12:12+0200\n"
10+"POT-Creation-Date: 2013-11-05 17:53+0100\n"
1111"PO-Revision-Date: 2013-10-08 08:09+0000\n"
1212"Last-Translator: Tadeáš Pařík <tadeas.parik@gmail.com>\n"
1313"Language-Team: Czech <cs@li.org>\n"
@@ -15,8 +15,8 @@ msgstr ""
1515"Content-Type: text/plain; charset=UTF-8\n"
1616"Content-Transfer-Encoding: 8bit\n"
1717"Plural-Forms: nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;\n"
18−"X-Launchpad-Export-Date: 2013-10-13 05:43+0000\n"
19−"X-Generator: Launchpad (build 16799)\n"
18+"X-Launchpad-Export-Date: 2013-11-08 06:37+0000\n"
19+"X-Generator: Launchpad (build 16820)\n"
2020
2121#: Applications/applications.js:23
2222msgid "Phone"
@@ -206,11 +206,15 @@ msgstr "Mluvte..."
206206msgid "Speaking..."
207207msgstr "Mluvte..."
208208
209+#: Notifications/NotificationMenuItemFactory.qml:89
210+msgid "Show password"
211+msgstr ""
212+
209213#: Panel/SearchIndicator.qml:27
210214msgid "Search"
211215msgstr "Hledat"
212216
213−#: plugins/Unity/scope.cpp:398
217+#: plugins/Unity/scope.cpp:408
214218msgid "Sorry, there is nothing that matches your search."
215219msgstr "Je nám líto, ale nic neodpovídá zadání"
216220
@@ -222,18 +226,3 @@ msgstr "Vše"
222226#, qt-format
223227msgid "Please enter %1"
224228msgstr "Zadejte prosím %1"
225−
226−#~ msgid "Featured"
227−#~ msgstr "Oblíbené"
228−
229−#~ msgid "Recent"
230−#~ msgstr "Nedávné"
231−
232−#~ msgid "Videos"
233−#~ msgstr "Videa"
234−
235−#~ msgid "Music"
236−#~ msgstr "Hudba"
237−
238−#~ msgid "Popular Online"
239−#~ msgstr "Oblíbené on-line"
po/de.po+8−4
@@ -7,7 +7,7 @@ msgid ""
77msgstr ""
88"Project-Id-Version: unity\n"
99"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10−"POT-Creation-Date: 2013-10-11 12:12+0200\n"
10+"POT-Creation-Date: 2013-11-05 17:53+0100\n"
1111"PO-Revision-Date: 2013-10-18 12:26+0000\n"
1212"Last-Translator: Phillip Sz <Unknown>\n"
1313"Language-Team: German <de@li.org>\n"
@@ -15,8 +15,8 @@ msgstr ""
1515"Content-Type: text/plain; charset=UTF-8\n"
1616"Content-Transfer-Encoding: 8bit\n"
1717"Plural-Forms: nplurals=2; plural=n != 1;\n"
18−"X-Launchpad-Export-Date: 2013-10-19 05:30+0000\n"
19−"X-Generator: Launchpad (build 16807)\n"
18+"X-Launchpad-Export-Date: 2013-11-08 06:37+0000\n"
19+"X-Generator: Launchpad (build 16820)\n"
2020
2121#: Applications/applications.js:23
2222msgid "Phone"
@@ -209,11 +209,15 @@ msgstr "Sprechen Sie jetzt …"
209209msgid "Speaking..."
210210msgstr "Sie sprechen …"
211211
212+#: Notifications/NotificationMenuItemFactory.qml:89
213+msgid "Show password"
214+msgstr ""
215+
212216#: Panel/SearchIndicator.qml:27
213217msgid "Search"
214218msgstr "Suchen"
215219
216−#: plugins/Unity/scope.cpp:398
220+#: plugins/Unity/scope.cpp:408
217221msgid "Sorry, there is nothing that matches your search."
218222msgstr "Entschuldigung, es wurden keine Treffer erzielt."
219223
po/el.po+8−10
@@ -7,7 +7,7 @@ msgid ""
77msgstr ""
88"Project-Id-Version: unity\n"
99"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10−"POT-Creation-Date: 2013-10-11 12:12+0200\n"
10+"POT-Creation-Date: 2013-11-05 17:53+0100\n"
1111"PO-Revision-Date: 2013-06-27 00:53+0000\n"
1212"Last-Translator: Michał Sawicz <michal.sawicz@canonical.com>\n"
1313"Language-Team: Greek <el@li.org>\n"
@@ -15,8 +15,8 @@ msgstr ""
1515"Content-Type: text/plain; charset=UTF-8\n"
1616"Content-Transfer-Encoding: 8bit\n"
1717"Plural-Forms: nplurals=2; plural=n != 1;\n"
18−"X-Launchpad-Export-Date: 2013-10-13 05:43+0000\n"
19−"X-Generator: Launchpad (build 16799)\n"
18+"X-Launchpad-Export-Date: 2013-11-08 06:37+0000\n"
19+"X-Generator: Launchpad (build 16820)\n"
2020
2121#: Applications/applications.js:23
2222msgid "Phone"
@@ -205,11 +205,15 @@ msgstr "Μιλήστε τώρα..."
205205msgid "Speaking..."
206206msgstr "Ομιλία..."
207207
208+#: Notifications/NotificationMenuItemFactory.qml:89
209+msgid "Show password"
210+msgstr ""
211+
208212#: Panel/SearchIndicator.qml:27
209213msgid "Search"
210214msgstr "Αναζήτηση"
211215
212−#: plugins/Unity/scope.cpp:398
216+#: plugins/Unity/scope.cpp:408
213217msgid "Sorry, there is nothing that matches your search."
214218msgstr "Λυπούμαστε, δεν υπάρχει τίποτα που να ταιριάζει στην αναζήτησή σας."
215219
@@ -221,9 +225,3 @@ msgstr ""
221225#, qt-format
222226msgid "Please enter %1"
223227msgstr ""
224−
225−#~ msgid "Music"
226−#~ msgstr "Μουσική"
227−
228−#~ msgid "Videos"
229−#~ msgstr "Βίντεο"
po/en_AU.po+8−25
@@ -7,7 +7,7 @@ msgid ""
77msgstr ""
88"Project-Id-Version: unity\n"
99"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10−"POT-Creation-Date: 2013-10-11 12:12+0200\n"
10+"POT-Creation-Date: 2013-11-05 17:53+0100\n"
1111"PO-Revision-Date: 2013-09-28 07:46+0000\n"
1212"Last-Translator: Jared Norris <jarednorris@ubuntu.com>\n"
1313"Language-Team: English (Australia) <en_AU@li.org>\n"
@@ -15,8 +15,8 @@ msgstr ""
1515"Content-Type: text/plain; charset=UTF-8\n"
1616"Content-Transfer-Encoding: 8bit\n"
1717"Plural-Forms: nplurals=2; plural=n != 1;\n"
18−"X-Launchpad-Export-Date: 2013-10-13 05:43+0000\n"
19−"X-Generator: Launchpad (build 16799)\n"
18+"X-Launchpad-Export-Date: 2013-11-08 06:38+0000\n"
19+"X-Generator: Launchpad (build 16820)\n"
2020
2121#: Applications/applications.js:23
2222msgid "Phone"
@@ -205,11 +205,15 @@ msgstr "Speak Now..."
205205msgid "Speaking..."
206206msgstr "Speaking..."
207207
208+#: Notifications/NotificationMenuItemFactory.qml:89
209+msgid "Show password"
210+msgstr ""
211+
208212#: Panel/SearchIndicator.qml:27
209213msgid "Search"
210214msgstr "Search"
211215
212−#: plugins/Unity/scope.cpp:398
216+#: plugins/Unity/scope.cpp:408
213217msgid "Sorry, there is nothing that matches your search."
214218msgstr "Sorry, there is nothing that matches your search."
215219
@@ -221,24 +225,3 @@ msgstr ""
221225#, qt-format
222226msgid "Please enter %1"
223227msgstr "Please enter %1"
224−
225−#~ msgid "Featured"
226−#~ msgstr "Featured"
227−
228−#~ msgid "Recent"
229−#~ msgstr "Recent"
230−
231−#~ msgid "New Releases"
232−#~ msgstr "New Releases"
233−
234−#~ msgid "Top Charting"
235−#~ msgstr "Top Charting"
236−
237−#~ msgid "Music"
238−#~ msgstr "Music"
239−
240−#~ msgid "Popular Online"
241−#~ msgstr "Popular Online"
242−
243−#~ msgid "Videos"
244−#~ msgstr "Videos"
po/en_GB.po+8−25
@@ -7,7 +7,7 @@ msgid ""
77msgstr ""
88"Project-Id-Version: unity\n"
99"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10−"POT-Creation-Date: 2013-10-11 12:12+0200\n"
10+"POT-Creation-Date: 2013-11-05 17:53+0100\n"
1111"PO-Revision-Date: 2013-06-27 08:53+0000\n"
1212"Last-Translator: Michał Sawicz <michal.sawicz@canonical.com>\n"
1313"Language-Team: English (United Kingdom) <en_GB@li.org>\n"
@@ -15,8 +15,8 @@ msgstr ""
1515"Content-Type: text/plain; charset=UTF-8\n"
1616"Content-Transfer-Encoding: 8bit\n"
1717"Plural-Forms: nplurals=2; plural=n != 1;\n"
18−"X-Launchpad-Export-Date: 2013-10-13 05:43+0000\n"
19−"X-Generator: Launchpad (build 16799)\n"
18+"X-Launchpad-Export-Date: 2013-11-08 06:38+0000\n"
19+"X-Generator: Launchpad (build 16820)\n"
2020
2121#: Applications/applications.js:23
2222msgid "Phone"
@@ -205,11 +205,15 @@ msgstr "Speak Now..."
205205msgid "Speaking..."
206206msgstr "Speaking..."
207207
208+#: Notifications/NotificationMenuItemFactory.qml:89
209+msgid "Show password"
210+msgstr ""
211+
208212#: Panel/SearchIndicator.qml:27
209213msgid "Search"
210214msgstr "Search"
211215
212−#: plugins/Unity/scope.cpp:398
216+#: plugins/Unity/scope.cpp:408
213217msgid "Sorry, there is nothing that matches your search."
214218msgstr "Sorry, there is nothing that matches your search."
215219
@@ -221,24 +225,3 @@ msgstr ""
221225#, qt-format
222226msgid "Please enter %1"
223227msgstr "Please enter %1"
224−
225−#~ msgid "Featured"
226−#~ msgstr "Featured"
227−
228−#~ msgid "Recent"
229−#~ msgstr "Recent"
230−
231−#~ msgid "New Releases"
232−#~ msgstr "New Releases"
233−
234−#~ msgid "Top Charting"
235−#~ msgstr "Top Charting"
236−
237−#~ msgid "Music"
238−#~ msgstr "Music"
239−
240−#~ msgid "Popular Online"
241−#~ msgstr "Popular Online"
242−
243−#~ msgid "Videos"
244−#~ msgstr "Videos"
po/eo.po+8−4
@@ -7,7 +7,7 @@ msgid ""
77msgstr ""
88"Project-Id-Version: unity\n"
99"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10−"POT-Creation-Date: 2013-10-11 12:12+0200\n"
10+"POT-Creation-Date: 2013-11-05 17:53+0100\n"
1111"PO-Revision-Date: 2013-06-26 22:35+0000\n"
1212"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
1313"Language-Team: Esperanto <eo@li.org>\n"
@@ -15,8 +15,8 @@ msgstr ""
1515"Content-Type: text/plain; charset=UTF-8\n"
1616"Content-Transfer-Encoding: 8bit\n"
1717"Plural-Forms: nplurals=2; plural=n != 1;\n"
18−"X-Launchpad-Export-Date: 2013-10-13 05:43+0000\n"
19−"X-Generator: Launchpad (build 16799)\n"
18+"X-Launchpad-Export-Date: 2013-11-08 06:37+0000\n"
19+"X-Generator: Launchpad (build 16820)\n"
2020
2121#: Applications/applications.js:23
2222msgid "Phone"
@@ -205,11 +205,15 @@ msgstr ""
205205msgid "Speaking..."
206206msgstr ""
207207
208+#: Notifications/NotificationMenuItemFactory.qml:89
209+msgid "Show password"
210+msgstr ""
211+
208212#: Panel/SearchIndicator.qml:27
209213msgid "Search"
210214msgstr ""
211215
212−#: plugins/Unity/scope.cpp:398
216+#: plugins/Unity/scope.cpp:408
213217msgid "Sorry, there is nothing that matches your search."
214218msgstr ""
215219
po/es.po+8−25
@@ -7,7 +7,7 @@ msgid ""
77msgstr ""
88"Project-Id-Version: unity\n"
99"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10−"POT-Creation-Date: 2013-10-11 12:12+0200\n"
10+"POT-Creation-Date: 2013-11-05 17:53+0100\n"
1111"PO-Revision-Date: 2013-10-02 04:59+0000\n"
1212"Last-Translator: Adolfo Jayme Barrientos <fitoschido@gmail.com>\n"
1313"Language-Team: Spanish <es@li.org>\n"
@@ -15,8 +15,8 @@ msgstr ""
1515"Content-Type: text/plain; charset=UTF-8\n"
1616"Content-Transfer-Encoding: 8bit\n"
1717"Plural-Forms: nplurals=2; plural=n != 1;\n"
18−"X-Launchpad-Export-Date: 2013-10-13 05:43+0000\n"
19−"X-Generator: Launchpad (build 16799)\n"
18+"X-Launchpad-Export-Date: 2013-11-08 06:38+0000\n"
19+"X-Generator: Launchpad (build 16820)\n"
2020
2121#: Applications/applications.js:23
2222msgid "Phone"
@@ -209,11 +209,15 @@ msgstr "Hable ahora…"
209209msgid "Speaking..."
210210msgstr "Hablando…"
211211
212+#: Notifications/NotificationMenuItemFactory.qml:89
213+msgid "Show password"
214+msgstr ""
215+
212216#: Panel/SearchIndicator.qml:27
213217msgid "Search"
214218msgstr "Buscar"
215219
216−#: plugins/Unity/scope.cpp:398
220+#: plugins/Unity/scope.cpp:408
217221msgid "Sorry, there is nothing that matches your search."
218222msgstr "No hay nada que coincida con su búsqueda."
219223
@@ -225,24 +229,3 @@ msgstr "Todo"
225229#, qt-format
226230msgid "Please enter %1"
227231msgstr "Introduzca %1"
228−
229−#~ msgid "Featured"
230−#~ msgstr "Destacados"
231−
232−#~ msgid "Recent"
233−#~ msgstr "Recientes"
234−
235−#~ msgid "New Releases"
236−#~ msgstr "Lanzamientos nuevos"
237−
238−#~ msgid "Top Charting"
239−#~ msgstr "Mejor posicionadas"
240−
241−#~ msgid "Music"
242−#~ msgstr "Música"
243−
244−#~ msgid "Popular Online"
245−#~ msgstr "Populares en línea"
246−
247−#~ msgid "Videos"
248−#~ msgstr "Vídeos"
po/fa.po+7−3
@@ -7,7 +7,7 @@ msgid ""
77msgstr ""
88"Project-Id-Version: unity8\n"
99"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10−"POT-Creation-Date: 2013-10-11 12:12+0200\n"
10+"POT-Creation-Date: 2013-11-05 17:53+0100\n"
1111"PO-Revision-Date: 2013-10-31 19:02+0000\n"
1212"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
1313"Language-Team: Persian <fa@li.org>\n"
@@ -15,7 +15,7 @@ msgstr ""
1515"Content-Type: text/plain; charset=UTF-8\n"
1616"Content-Transfer-Encoding: 8bit\n"
1717"Plural-Forms: nplurals=1; plural=0;\n"
18−"X-Launchpad-Export-Date: 2013-11-01 06:44+0000\n"
18+"X-Launchpad-Export-Date: 2013-11-08 06:37+0000\n"
1919"X-Generator: Launchpad (build 16820)\n"
2020
2121#: Applications/applications.js:23
@@ -205,11 +205,15 @@ msgstr ""
205205msgid "Speaking..."
206206msgstr ""
207207
208+#: Notifications/NotificationMenuItemFactory.qml:89
209+msgid "Show password"
210+msgstr ""
211+
208212#: Panel/SearchIndicator.qml:27
209213msgid "Search"
210214msgstr ""
211215
212−#: plugins/Unity/scope.cpp:398
216+#: plugins/Unity/scope.cpp:408
213217msgid "Sorry, there is nothing that matches your search."
214218msgstr ""
215219
po/fi.po+8−25
@@ -7,7 +7,7 @@ msgid ""
77msgstr ""
88"Project-Id-Version: unity\n"
99"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10−"POT-Creation-Date: 2013-10-11 12:12+0200\n"
10+"POT-Creation-Date: 2013-11-05 17:53+0100\n"
1111"PO-Revision-Date: 2013-10-03 09:21+0000\n"
1212"Last-Translator: Jiri Grönroos <Unknown>\n"
1313"Language-Team: Finnish <fi@li.org>\n"
@@ -15,8 +15,8 @@ msgstr ""
1515"Content-Type: text/plain; charset=UTF-8\n"
1616"Content-Transfer-Encoding: 8bit\n"
1717"Plural-Forms: nplurals=2; plural=n != 1;\n"
18−"X-Launchpad-Export-Date: 2013-10-13 05:43+0000\n"
19−"X-Generator: Launchpad (build 16799)\n"
18+"X-Launchpad-Export-Date: 2013-11-08 06:37+0000\n"
19+"X-Generator: Launchpad (build 16820)\n"
2020
2121#: Applications/applications.js:23
2222msgid "Phone"
@@ -207,11 +207,15 @@ msgstr "Puhu nyt..."
207207msgid "Speaking..."
208208msgstr "Puhutaan..."
209209
210+#: Notifications/NotificationMenuItemFactory.qml:89
211+msgid "Show password"
212+msgstr ""
213+
210214#: Panel/SearchIndicator.qml:27
211215msgid "Search"
212216msgstr "Hae"
213217
214−#: plugins/Unity/scope.cpp:398
218+#: plugins/Unity/scope.cpp:408
215219msgid "Sorry, there is nothing that matches your search."
216220msgstr "Hakuun täsmääviä tuloksia ei löydy."
217221
@@ -223,24 +227,3 @@ msgstr "Kaikki"
223227#, qt-format
224228msgid "Please enter %1"
225229msgstr "Kirjoita %1"
226−
227−#~ msgid "Featured"
228−#~ msgstr "Suositellut"
229−
230−#~ msgid "Recent"
231−#~ msgstr "Viimeisimmät"
232−
233−#~ msgid "New Releases"
234−#~ msgstr "Uudet julkaisut"
235−
236−#~ msgid "Top Charting"
237−#~ msgstr "Nousukiidossa"
238−
239−#~ msgid "Music"
240−#~ msgstr "Musiikki"
241−
242−#~ msgid "Popular Online"
243−#~ msgstr "Suosittua verkossa"
244−
245−#~ msgid "Videos"
246−#~ msgstr "Videot"
po/fo.po+8−10
@@ -7,7 +7,7 @@ msgid ""
77msgstr ""
88"Project-Id-Version: unity\n"
99"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10−"POT-Creation-Date: 2013-10-11 12:12+0200\n"
10+"POT-Creation-Date: 2013-11-05 17:53+0100\n"
1111"PO-Revision-Date: 2013-10-01 15:13+0000\n"
1212"Last-Translator: Jógvan Olsen <jeggy@jebster.net>\n"
1313"Language-Team: Faroese <fo@li.org>\n"
@@ -15,8 +15,8 @@ msgstr ""
1515"Content-Type: text/plain; charset=UTF-8\n"
1616"Content-Transfer-Encoding: 8bit\n"
1717"Plural-Forms: nplurals=2; plural=n != 1;\n"
18−"X-Launchpad-Export-Date: 2013-10-13 05:43+0000\n"
19−"X-Generator: Launchpad (build 16799)\n"
18+"X-Launchpad-Export-Date: 2013-11-08 06:37+0000\n"
19+"X-Generator: Launchpad (build 16820)\n"
2020
2121#: Applications/applications.js:23
2222msgid "Phone"
@@ -205,11 +205,15 @@ msgstr "Snakka nú..."
205205msgid "Speaking..."
206206msgstr "Snakkar..."
207207
208+#: Notifications/NotificationMenuItemFactory.qml:89
209+msgid "Show password"
210+msgstr ""
211+
208212#: Panel/SearchIndicator.qml:27
209213msgid "Search"
210214msgstr "Leita"
211215
212−#: plugins/Unity/scope.cpp:398
216+#: plugins/Unity/scope.cpp:408
213217msgid "Sorry, there is nothing that matches your search."
214218msgstr "Tíanverri er tað einki sum hóskar til tína leiting."
215219
@@ -221,9 +225,3 @@ msgstr ""
221225#, qt-format
222226msgid "Please enter %1"
223227msgstr ""
224−
225−#~ msgid "Music"
226−#~ msgstr "Tónleikur"
227−
228−#~ msgid "Videos"
229−#~ msgstr "Sjónbond"
po/fr.po+8−10
@@ -7,7 +7,7 @@ msgid ""
77msgstr ""
88"Project-Id-Version: unity\n"
99"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10−"POT-Creation-Date: 2013-10-11 12:12+0200\n"
10+"POT-Creation-Date: 2013-11-05 17:53+0100\n"
1111"PO-Revision-Date: 2013-06-27 03:21+0000\n"
1212"Last-Translator: Michał Sawicz <michal.sawicz@canonical.com>\n"
1313"Language-Team: French <fr@li.org>\n"
@@ -15,8 +15,8 @@ msgstr ""
1515"Content-Type: text/plain; charset=UTF-8\n"
1616"Content-Transfer-Encoding: 8bit\n"
1717"Plural-Forms: nplurals=2; plural=n > 1;\n"
18−"X-Launchpad-Export-Date: 2013-10-13 05:43+0000\n"
19−"X-Generator: Launchpad (build 16799)\n"
18+"X-Launchpad-Export-Date: 2013-11-08 06:37+0000\n"
19+"X-Generator: Launchpad (build 16820)\n"
2020
2121#: Applications/applications.js:23
2222msgid "Phone"
@@ -205,11 +205,15 @@ msgstr ""
205205msgid "Speaking..."
206206msgstr ""
207207
208+#: Notifications/NotificationMenuItemFactory.qml:89
209+msgid "Show password"
210+msgstr ""
211+
208212#: Panel/SearchIndicator.qml:27
209213msgid "Search"
210214msgstr ""
211215
212−#: plugins/Unity/scope.cpp:398
216+#: plugins/Unity/scope.cpp:408
213217msgid "Sorry, there is nothing that matches your search."
214218msgstr ""
215219
@@ -221,9 +225,3 @@ msgstr ""
221225#, qt-format
222226msgid "Please enter %1"
223227msgstr ""
224−
225−#~ msgid "Music"
226−#~ msgstr "Musique"
227−
228−#~ msgid "Videos"
229−#~ msgstr "Vidéos"
po/gd.po+8−25
@@ -7,7 +7,7 @@ msgid ""
77msgstr ""
88"Project-Id-Version: unity8\n"
99"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10−"POT-Creation-Date: 2013-10-11 12:12+0200\n"
10+"POT-Creation-Date: 2013-11-05 17:53+0100\n"
1111"PO-Revision-Date: 2013-09-30 10:34+0000\n"
1212"Last-Translator: Akerbeltz <fios@akerbeltz.org>\n"
1313"Language-Team: Gaelic; Scottish <gd@li.org>\n"
@@ -16,8 +16,8 @@ msgstr ""
1616"Content-Transfer-Encoding: 8bit\n"
1717"Plural-Forms: nplurals=4; plural=(n==1 || n==11) ? 0 : (n==2 || n==12) ? 1 : "
1818"(n > 2 && n < 20) ? 2 : 3;\n"
19−"X-Launchpad-Export-Date: 2013-10-13 05:43+0000\n"
20−"X-Generator: Launchpad (build 16799)\n"
19+"X-Launchpad-Export-Date: 2013-11-08 06:37+0000\n"
20+"X-Generator: Launchpad (build 16820)\n"
2121
2222#: Applications/applications.js:23
2323msgid "Phone"
@@ -214,11 +214,15 @@ msgstr "Can rud a-nis..."
214214msgid "Speaking..."
215215msgstr "A' bruidhinn..."
216216
217+#: Notifications/NotificationMenuItemFactory.qml:89
218+msgid "Show password"
219+msgstr ""
220+
217221#: Panel/SearchIndicator.qml:27
218222msgid "Search"
219223msgstr "Lorg"
220224
221−#: plugins/Unity/scope.cpp:398
225+#: plugins/Unity/scope.cpp:408
222226msgid "Sorry, there is nothing that matches your search."
223227msgstr "Tha sinn duilich ach chan eil dad a' freagairt ris na lorg thu."
224228
@@ -230,24 +234,3 @@ msgstr ""
230234#, qt-format
231235msgid "Please enter %1"
232236msgstr "Cuir a-steach %1"
233−
234−#~ msgid "Top Charting"
235−#~ msgstr "Gràinnean-mullaich nan cairt"
236−
237−#~ msgid "Featured"
238−#~ msgstr "Brosnaichte"
239−
240−#~ msgid "Recent"
241−#~ msgstr "O chionn goirid"
242−
243−#~ msgid "New Releases"
244−#~ msgstr "Air ùr-sgaoileadh"
245−
246−#~ msgid "Videos"
247−#~ msgstr "Videothan"
248−
249−#~ msgid "Music"
250−#~ msgstr "Ceòl"
251−
252−#~ msgid "Popular Online"
253−#~ msgstr "Fèill mhòr air air loidhne"
po/gl.po+8−22
@@ -7,7 +7,7 @@ msgid ""
77msgstr ""
88"Project-Id-Version: unity\n"
99"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10−"POT-Creation-Date: 2013-10-11 12:12+0200\n"
10+"POT-Creation-Date: 2013-11-05 17:53+0100\n"
1111"PO-Revision-Date: 2013-10-03 18:49+0000\n"
1212"Last-Translator: Marcos Lans <Unknown>\n"
1313"Language-Team: Galician <gl@li.org>\n"
@@ -15,8 +15,8 @@ msgstr ""
1515"Content-Type: text/plain; charset=UTF-8\n"
1616"Content-Transfer-Encoding: 8bit\n"
1717"Plural-Forms: nplurals=2; plural=n != 1;\n"
18−"X-Launchpad-Export-Date: 2013-10-13 05:43+0000\n"
19−"X-Generator: Launchpad (build 16799)\n"
18+"X-Launchpad-Export-Date: 2013-11-08 06:37+0000\n"
19+"X-Generator: Launchpad (build 16820)\n"
2020
2121#: Applications/applications.js:23
2222msgid "Phone"
@@ -207,11 +207,15 @@ msgstr "Fale agora…"
207207msgid "Speaking..."
208208msgstr "Falando…"
209209
210+#: Notifications/NotificationMenuItemFactory.qml:89
211+msgid "Show password"
212+msgstr ""
213+
210214#: Panel/SearchIndicator.qml:27
211215msgid "Search"
212216msgstr "Buscar"
213217
214−#: plugins/Unity/scope.cpp:398
218+#: plugins/Unity/scope.cpp:408
215219msgid "Sorry, there is nothing that matches your search."
216220msgstr "Sentímolo, non hai nada que coincida con esta busca."
217221
@@ -223,21 +227,3 @@ msgstr "Todo"
223227#, qt-format
224228msgid "Please enter %1"
225229msgstr "Introduza %1"
226−
227−#~ msgid "Music"
228−#~ msgstr "Música"
229−
230−#~ msgid "Videos"
231−#~ msgstr "Vídeos"
232−
233−#~ msgid "Featured"
234−#~ msgstr "Destacado"
235−
236−#~ msgid "Recent"
237−#~ msgstr "Recentes"
238−
239−#~ msgid "New Releases"
240−#~ msgstr "Novas versións"
241−
242−#~ msgid "Popular Online"
243−#~ msgstr "Populares en liña"
po/he.po+8−25
@@ -7,7 +7,7 @@ msgid ""
77msgstr ""
88"Project-Id-Version: unity\n"
99"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10−"POT-Creation-Date: 2013-10-11 12:12+0200\n"
10+"POT-Creation-Date: 2013-11-05 17:53+0100\n"
1111"PO-Revision-Date: 2013-10-01 09:19+0000\n"
1212"Last-Translator: Yaron <sh.yaron@gmail.com>\n"
1313"Language-Team: Hebrew <he@li.org>\n"
@@ -15,8 +15,8 @@ msgstr ""
1515"Content-Type: text/plain; charset=UTF-8\n"
1616"Content-Transfer-Encoding: 8bit\n"
1717"Plural-Forms: nplurals=2; plural=n != 1;\n"
18−"X-Launchpad-Export-Date: 2013-10-13 05:43+0000\n"
19−"X-Generator: Launchpad (build 16799)\n"
18+"X-Launchpad-Export-Date: 2013-11-08 06:37+0000\n"
19+"X-Generator: Launchpad (build 16820)\n"
2020
2121#: Applications/applications.js:23
2222msgid "Phone"
@@ -205,11 +205,15 @@ msgstr "יש לדבר כעת..."
205205msgid "Speaking..."
206206msgstr "הדיבור מושמע…"
207207
208+#: Notifications/NotificationMenuItemFactory.qml:89
209+msgid "Show password"
210+msgstr ""
211+
208212#: Panel/SearchIndicator.qml:27
209213msgid "Search"
210214msgstr "חיפוש"
211215
212−#: plugins/Unity/scope.cpp:398
216+#: plugins/Unity/scope.cpp:408
213217msgid "Sorry, there is nothing that matches your search."
214218msgstr "שום דבר אינו תואם לחיפוש שלך, עמך הסליחה."
215219
@@ -221,24 +225,3 @@ msgstr ""
221225#, qt-format
222226msgid "Please enter %1"
223227msgstr "נא להזין %1"
224−
225−#~ msgid "Music"
226−#~ msgstr "מוזיקה"
227−
228−#~ msgid "Videos"
229−#~ msgstr "סרטונים"
230−
231−#~ msgid "Top Charting"
232−#~ msgstr "בראש הטבלה"
233−
234−#~ msgid "Featured"
235−#~ msgstr "מומלצים"
236−
237−#~ msgid "Recent"
238−#~ msgstr "אחרונים"
239−
240−#~ msgid "New Releases"
241−#~ msgstr "מהדורות חדשות"
242−
243−#~ msgid "Popular Online"
244−#~ msgstr "פופולריים ברחבי הרשת"
po/hr.po+8−10
@@ -7,7 +7,7 @@ msgid ""
77msgstr ""
88"Project-Id-Version: unity\n"
99"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10−"POT-Creation-Date: 2013-10-11 12:12+0200\n"
10+"POT-Creation-Date: 2013-11-05 17:53+0100\n"
1111"PO-Revision-Date: 2013-06-27 04:14+0000\n"
1212"Last-Translator: Michał Sawicz <michal.sawicz@canonical.com>\n"
1313"Language-Team: Croatian <hr@li.org>\n"
@@ -16,8 +16,8 @@ msgstr ""
1616"Content-Transfer-Encoding: 8bit\n"
1717"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && "
1818"n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n"
19−"X-Launchpad-Export-Date: 2013-10-13 05:43+0000\n"
20−"X-Generator: Launchpad (build 16799)\n"
19+"X-Launchpad-Export-Date: 2013-11-08 06:38+0000\n"
20+"X-Generator: Launchpad (build 16820)\n"
2121
2222#: Applications/applications.js:23
2323msgid "Phone"
@@ -206,11 +206,15 @@ msgstr "Recite..."
206206msgid "Speaking..."
207207msgstr "Govor..."
208208
209+#: Notifications/NotificationMenuItemFactory.qml:89
210+msgid "Show password"
211+msgstr ""
212+
209213#: Panel/SearchIndicator.qml:27
210214msgid "Search"
211215msgstr "Pretraživanje"
212216
213−#: plugins/Unity/scope.cpp:398
217+#: plugins/Unity/scope.cpp:408
214218msgid "Sorry, there is nothing that matches your search."
215219msgstr "Nažalost, ne postoji ništa što odgovara vašoj pretrazi."
216220
@@ -222,9 +226,3 @@ msgstr ""
222226#, qt-format
223227msgid "Please enter %1"
224228msgstr ""
225−
226−#~ msgid "Music"
227−#~ msgstr "Glazba"
228−
229−#~ msgid "Videos"
230−#~ msgstr "Video"
po/hu.po+8−10
@@ -7,7 +7,7 @@ msgid ""
77msgstr ""
88"Project-Id-Version: unity\n"
99"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10−"POT-Creation-Date: 2013-10-11 12:12+0200\n"
10+"POT-Creation-Date: 2013-11-05 17:53+0100\n"
1111"PO-Revision-Date: 2013-06-27 04:28+0000\n"
1212"Last-Translator: Michał Sawicz <michal.sawicz@canonical.com>\n"
1313"Language-Team: Hungarian <hu@li.org>\n"
@@ -15,8 +15,8 @@ msgstr ""
1515"Content-Type: text/plain; charset=UTF-8\n"
1616"Content-Transfer-Encoding: 8bit\n"
1717"Plural-Forms: nplurals=2; plural=n != 1;\n"
18−"X-Launchpad-Export-Date: 2013-10-13 05:43+0000\n"
19−"X-Generator: Launchpad (build 16799)\n"
18+"X-Launchpad-Export-Date: 2013-11-08 06:37+0000\n"
19+"X-Generator: Launchpad (build 16820)\n"
2020
2121#: Applications/applications.js:23
2222msgid "Phone"
@@ -205,11 +205,15 @@ msgstr "Beszéljen most…"
205205msgid "Speaking..."
206206msgstr "Beszéd…"
207207
208+#: Notifications/NotificationMenuItemFactory.qml:89
209+msgid "Show password"
210+msgstr ""
211+
208212#: Panel/SearchIndicator.qml:27
209213msgid "Search"
210214msgstr "Keresés"
211215
212−#: plugins/Unity/scope.cpp:398
216+#: plugins/Unity/scope.cpp:408
213217msgid "Sorry, there is nothing that matches your search."
214218msgstr "Elnézést, nincs találat a keresésre."
215219
@@ -221,9 +225,3 @@ msgstr ""
221225#, qt-format
222226msgid "Please enter %1"
223227msgstr ""
224−
225−#~ msgid "Music"
226−#~ msgstr "Zene"
227−
228−#~ msgid "Videos"
229−#~ msgstr "Videók"
po/hy.po+8−10
@@ -7,7 +7,7 @@ msgid ""
77msgstr ""
88"Project-Id-Version: unity\n"
99"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10−"POT-Creation-Date: 2013-10-11 12:12+0200\n"
10+"POT-Creation-Date: 2013-11-05 17:53+0100\n"
1111"PO-Revision-Date: 2013-06-27 04:43+0000\n"
1212"Last-Translator: iAbaS <sosabazyan@yandex.ru>\n"
1313"Language-Team: Armenian <hy@li.org>\n"
@@ -15,8 +15,8 @@ msgstr ""
1515"Content-Type: text/plain; charset=UTF-8\n"
1616"Content-Transfer-Encoding: 8bit\n"
1717"Plural-Forms: nplurals=1; plural=0;\n"
18−"X-Launchpad-Export-Date: 2013-10-13 05:43+0000\n"
19−"X-Generator: Launchpad (build 16799)\n"
18+"X-Launchpad-Export-Date: 2013-11-08 06:37+0000\n"
19+"X-Generator: Launchpad (build 16820)\n"
2020
2121#: Applications/applications.js:23
2222msgid "Phone"
@@ -205,11 +205,15 @@ msgstr "Խոսի՛ր"
205205msgid "Speaking..."
206206msgstr "Խոսում եմ..."
207207
208+#: Notifications/NotificationMenuItemFactory.qml:89
209+msgid "Show password"
210+msgstr ""
211+
208212#: Panel/SearchIndicator.qml:27
209213msgid "Search"
210214msgstr "Որոնում"
211215
212−#: plugins/Unity/scope.cpp:398
216+#: plugins/Unity/scope.cpp:408
213217msgid "Sorry, there is nothing that matches your search."
214218msgstr "Կներերք, բայց Ձեր հարցումով ոչինչ չկար"
215219
@@ -221,9 +225,3 @@ msgstr ""
221225#, qt-format
222226msgid "Please enter %1"
223227msgstr ""
224−
225−#~ msgid "Music"
226−#~ msgstr "Երգեր"
227−
228−#~ msgid "Videos"
229−#~ msgstr "Վիդեոներ"
po/id.po+8−4
@@ -7,7 +7,7 @@ msgid ""
77msgstr ""
88"Project-Id-Version: unity\n"
99"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10−"POT-Creation-Date: 2013-10-11 12:12+0200\n"
10+"POT-Creation-Date: 2013-11-05 17:53+0100\n"
1111"PO-Revision-Date: 2013-06-26 22:35+0000\n"
1212"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
1313"Language-Team: Indonesian <id@li.org>\n"
@@ -15,8 +15,8 @@ msgstr ""
1515"Content-Type: text/plain; charset=UTF-8\n"
1616"Content-Transfer-Encoding: 8bit\n"
1717"Plural-Forms: nplurals=1; plural=0;\n"
18−"X-Launchpad-Export-Date: 2013-10-13 05:43+0000\n"
19−"X-Generator: Launchpad (build 16799)\n"
18+"X-Launchpad-Export-Date: 2013-11-08 06:37+0000\n"
19+"X-Generator: Launchpad (build 16820)\n"
2020
2121#: Applications/applications.js:23
2222msgid "Phone"
@@ -205,11 +205,15 @@ msgstr ""
205205msgid "Speaking..."
206206msgstr ""
207207
208+#: Notifications/NotificationMenuItemFactory.qml:89
209+msgid "Show password"
210+msgstr ""
211+
208212#: Panel/SearchIndicator.qml:27
209213msgid "Search"
210214msgstr ""
211215
212−#: plugins/Unity/scope.cpp:398
216+#: plugins/Unity/scope.cpp:408
213217msgid "Sorry, there is nothing that matches your search."
214218msgstr ""
215219
po/is.po+8−25
@@ -7,7 +7,7 @@ msgid ""
77msgstr ""
88"Project-Id-Version: unity8\n"
99"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10−"POT-Creation-Date: 2013-10-11 12:12+0200\n"
10+"POT-Creation-Date: 2013-11-05 17:53+0100\n"
1111"PO-Revision-Date: 2013-09-18 16:22+0000\n"
1212"Last-Translator: Andri Thorlacius <Unknown>\n"
1313"Language-Team: Icelandic <is@li.org>\n"
@@ -15,8 +15,8 @@ msgstr ""
1515"Content-Type: text/plain; charset=UTF-8\n"
1616"Content-Transfer-Encoding: 8bit\n"
1717"Plural-Forms: nplurals=2; plural=n != 1;\n"
18−"X-Launchpad-Export-Date: 2013-10-13 05:43+0000\n"
19−"X-Generator: Launchpad (build 16799)\n"
18+"X-Launchpad-Export-Date: 2013-11-08 06:37+0000\n"
19+"X-Generator: Launchpad (build 16820)\n"
2020
2121#: Applications/applications.js:23
2222msgid "Phone"
@@ -206,11 +206,15 @@ msgstr "Talaðu Núna..."
206206msgid "Speaking..."
207207msgstr "Tala..."
208208
209+#: Notifications/NotificationMenuItemFactory.qml:89
210+msgid "Show password"
211+msgstr ""
212+
209213#: Panel/SearchIndicator.qml:27
210214msgid "Search"
211215msgstr "Leita"
212216
213−#: plugins/Unity/scope.cpp:398
217+#: plugins/Unity/scope.cpp:408
214218msgid "Sorry, there is nothing that matches your search."
215219msgstr "Því miður, það var ekkert sem passaði við leitarorðið þitt."
216220
@@ -222,24 +226,3 @@ msgstr ""
222226#, qt-format
223227msgid "Please enter %1"
224228msgstr ""
225−
226−#~ msgid "Top Charting"
227−#~ msgstr "Topp Listi"
228−
229−#~ msgid "Featured"
230−#~ msgstr "Efst á baugi"
231−
232−#~ msgid "Recent"
233−#~ msgstr "Nýlegt"
234−
235−#~ msgid "New Releases"
236−#~ msgstr "Nýjar Útgáfur"
237−
238−#~ msgid "Videos"
239−#~ msgstr "Myndbönd"
240−
241−#~ msgid "Music"
242−#~ msgstr "Tónlist"
243−
244−#~ msgid "Popular Online"
245−#~ msgstr "Vinsælt á Netinu"
po/it.po+8−25
@@ -7,7 +7,7 @@ msgid ""
77msgstr ""
88"Project-Id-Version: unity\n"
99"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10−"POT-Creation-Date: 2013-10-11 12:12+0200\n"
10+"POT-Creation-Date: 2013-11-05 17:53+0100\n"
1111"PO-Revision-Date: 2013-10-07 09:34+0000\n"
1212"Last-Translator: Claudio Arseni <claudio.arseni@gmail.com>\n"
1313"Language-Team: Italian <it@li.org>\n"
@@ -15,8 +15,8 @@ msgstr ""
1515"Content-Type: text/plain; charset=UTF-8\n"
1616"Content-Transfer-Encoding: 8bit\n"
1717"Plural-Forms: nplurals=2; plural=n != 1;\n"
18−"X-Launchpad-Export-Date: 2013-10-13 05:43+0000\n"
19−"X-Generator: Launchpad (build 16799)\n"
18+"X-Launchpad-Export-Date: 2013-11-08 06:37+0000\n"
19+"X-Generator: Launchpad (build 16820)\n"
2020
2121#: Applications/applications.js:23
2222msgid "Phone"
@@ -212,11 +212,15 @@ msgstr "Parla ora..."
212212msgid "Speaking..."
213213msgstr "Sto parlando..."
214214
215+#: Notifications/NotificationMenuItemFactory.qml:89
216+msgid "Show password"
217+msgstr ""
218+
215219#: Panel/SearchIndicator.qml:27
216220msgid "Search"
217221msgstr "Cerca"
218222
219−#: plugins/Unity/scope.cpp:398
223+#: plugins/Unity/scope.cpp:408
220224msgid "Sorry, there is nothing that matches your search."
221225msgstr "Nessun risultato corrispondente alla ricerca."
222226
@@ -228,24 +232,3 @@ msgstr "Tutto"
228232#, qt-format
229233msgid "Please enter %1"
230234msgstr "Inserire %1"
231−
232−#~ msgid "Music"
233−#~ msgstr "Musica"
234−
235−#~ msgid "Videos"
236−#~ msgstr "Video"
237−
238−#~ msgid "Recent"
239−#~ msgstr "Recenti"
240−
241−#~ msgid "New Releases"
242−#~ msgstr "Nuovi rilasci"
243−
244−#~ msgid "Featured"
245−#~ msgstr "In evidenza"
246−
247−#~ msgid "Popular Online"
248−#~ msgstr "Popolari online"
249−
250−#~ msgid "Top Charting"
251−#~ msgstr "Più votate"
po/ja.po+8−4
@@ -7,7 +7,7 @@ msgid ""
77msgstr ""
88"Project-Id-Version: unity\n"
99"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10−"POT-Creation-Date: 2013-10-11 12:12+0200\n"
10+"POT-Creation-Date: 2013-11-05 17:53+0100\n"
1111"PO-Revision-Date: 2013-06-26 22:36+0000\n"
1212"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
1313"Language-Team: Japanese <ja@li.org>\n"
@@ -15,8 +15,8 @@ msgstr ""
1515"Content-Type: text/plain; charset=UTF-8\n"
1616"Content-Transfer-Encoding: 8bit\n"
1717"Plural-Forms: nplurals=1; plural=0;\n"
18−"X-Launchpad-Export-Date: 2013-10-13 05:43+0000\n"
19−"X-Generator: Launchpad (build 16799)\n"
18+"X-Launchpad-Export-Date: 2013-11-08 06:37+0000\n"
19+"X-Generator: Launchpad (build 16820)\n"
2020
2121#: Applications/applications.js:23
2222msgid "Phone"
@@ -205,11 +205,15 @@ msgstr ""
205205msgid "Speaking..."
206206msgstr ""
207207
208+#: Notifications/NotificationMenuItemFactory.qml:89
209+msgid "Show password"
210+msgstr ""
211+
208212#: Panel/SearchIndicator.qml:27
209213msgid "Search"
210214msgstr ""
211215
212−#: plugins/Unity/scope.cpp:398
216+#: plugins/Unity/scope.cpp:408
213217msgid "Sorry, there is nothing that matches your search."
214218msgstr ""
215219
po/km.po+8−25
@@ -7,7 +7,7 @@ msgid ""
77msgstr ""
88"Project-Id-Version: unity8\n"
99"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10−"POT-Creation-Date: 2013-10-11 12:12+0200\n"
10+"POT-Creation-Date: 2013-11-05 17:53+0100\n"
1111"PO-Revision-Date: 2013-10-11 08:49+0000\n"
1212"Last-Translator: Khoem Sokhem <khoemsokhem@khmeros.info>\n"
1313"Language-Team: Khmer <km@li.org>\n"
@@ -15,8 +15,8 @@ msgstr ""
1515"Content-Type: text/plain; charset=UTF-8\n"
1616"Content-Transfer-Encoding: 8bit\n"
1717"Plural-Forms: nplurals=1; plural=0;\n"
18−"X-Launchpad-Export-Date: 2013-10-13 05:43+0000\n"
19−"X-Generator: Launchpad (build 16799)\n"
18+"X-Launchpad-Export-Date: 2013-11-08 06:37+0000\n"
19+"X-Generator: Launchpad (build 16820)\n"
2020
2121#: Applications/applications.js:23
2222msgid "Phone"
@@ -209,11 +209,15 @@ msgstr "និយាយ​ឥឡូវ..."
209209msgid "Speaking..."
210210msgstr "កំពុង​និយាយ..."
211211
212+#: Notifications/NotificationMenuItemFactory.qml:89
213+msgid "Show password"
214+msgstr ""
215+
212216#: Panel/SearchIndicator.qml:27
213217msgid "Search"
214218msgstr "ស្វែង​រក"
215219
216−#: plugins/Unity/scope.cpp:398
220+#: plugins/Unity/scope.cpp:408
217221msgid "Sorry, there is nothing that matches your search."
218222msgstr "សូម​ទោស មិនមាន​ពាក្យ​ដែល​អ្នក​ស្វែងរក​ទេ​។"
219223
@@ -225,24 +229,3 @@ msgstr "ទាំង​អស់"
225229#, qt-format
226230msgid "Please enter %1"
227231msgstr "សូម​បញ្ចូល %1"
228−
229−#~ msgid "Popular Online"
230−#~ msgstr "លើ​បណ្ដាញ​ប្រជាប្រិយ"
231−
232−#~ msgid "Music"
233−#~ msgstr "តន្ត្រី"
234−
235−#~ msgid "New Releases"
236−#~ msgstr "ការ​ចេញ​ផ្សាយ​ថ្មី"
237−
238−#~ msgid "Top Charting"
239−#~ msgstr "តារាង​ខាង​លើ"
240−
241−#~ msgid "Featured"
242−#~ msgstr "ដែល​ល្បី"
243−
244−#~ msgid "Recent"
245−#~ msgstr "ថ្មីៗ"
246−
247−#~ msgid "Videos"
248−#~ msgstr "វីដេអូ"
po/kn.po+8−10
@@ -7,7 +7,7 @@ msgid ""
77msgstr ""
88"Project-Id-Version: unity\n"
99"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10−"POT-Creation-Date: 2013-10-11 12:12+0200\n"
10+"POT-Creation-Date: 2013-11-05 17:53+0100\n"
1111"PO-Revision-Date: 2013-06-27 05:43+0000\n"
1212"Last-Translator: Michał Sawicz <michal.sawicz@canonical.com>\n"
1313"Language-Team: Kannada <kn@li.org>\n"
@@ -15,8 +15,8 @@ msgstr ""
1515"Content-Type: text/plain; charset=UTF-8\n"
1616"Content-Transfer-Encoding: 8bit\n"
1717"Plural-Forms: nplurals=2; plural=n != 1;\n"
18−"X-Launchpad-Export-Date: 2013-10-13 05:43+0000\n"
19−"X-Generator: Launchpad (build 16799)\n"
18+"X-Launchpad-Export-Date: 2013-11-08 06:37+0000\n"
19+"X-Generator: Launchpad (build 16820)\n"
2020
2121#: Applications/applications.js:23
2222msgid "Phone"
@@ -205,11 +205,15 @@ msgstr "ಈಗ ಮಾತನಾಡಿ ..."
205205msgid "Speaking..."
206206msgstr "ಮಾತನಾಡುತಿದ್ದೀರಿ"
207207
208+#: Notifications/NotificationMenuItemFactory.qml:89
209+msgid "Show password"
210+msgstr ""
211+
208212#: Panel/SearchIndicator.qml:27
209213msgid "Search"
210214msgstr "ಹುಡುಕು"
211215
212−#: plugins/Unity/scope.cpp:398
216+#: plugins/Unity/scope.cpp:408
213217msgid "Sorry, there is nothing that matches your search."
214218msgstr "ಕ್ಷಮಿಸಿ ನಿಮ್ಮ ಶೋಧನೆಗೆ ಸರಿಯಾದ ಹೊಂದಾಣಿಕೆಗಳು ದೊರಕುತ್ತಿಲ್ಲ"
215219
@@ -221,9 +225,3 @@ msgstr ""
221225#, qt-format
222226msgid "Please enter %1"
223227msgstr ""
224−
225−#~ msgid "Music"
226−#~ msgstr "ಸಂಗೀತ"
227−
228−#~ msgid "Videos"
229−#~ msgstr "ವೀಡಿಯೋಗಳು"
po/ko.po+8−7
@@ -7,7 +7,7 @@ msgid ""
77msgstr ""
88"Project-Id-Version: unity\n"
99"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10−"POT-Creation-Date: 2013-10-11 12:12+0200\n"
10+"POT-Creation-Date: 2013-11-05 17:53+0100\n"
1111"PO-Revision-Date: 2013-10-10 07:04+0000\n"
1212"Last-Translator: Kim Boram <boramism@gmail.com>\n"
1313"Language-Team: Korean <ko@li.org>\n"
@@ -15,8 +15,8 @@ msgstr ""
1515"Content-Type: text/plain; charset=UTF-8\n"
1616"Content-Transfer-Encoding: 8bit\n"
1717"Plural-Forms: nplurals=1; plural=0;\n"
18−"X-Launchpad-Export-Date: 2013-10-13 05:43+0000\n"
19−"X-Generator: Launchpad (build 16799)\n"
18+"X-Launchpad-Export-Date: 2013-11-08 06:37+0000\n"
19+"X-Generator: Launchpad (build 16820)\n"
2020
2121#: Applications/applications.js:23
2222msgid "Phone"
@@ -205,11 +205,15 @@ msgstr ""
205205msgid "Speaking..."
206206msgstr ""
207207
208+#: Notifications/NotificationMenuItemFactory.qml:89
209+msgid "Show password"
210+msgstr ""
211+
208212#: Panel/SearchIndicator.qml:27
209213msgid "Search"
210214msgstr "검색"
211215
212−#: plugins/Unity/scope.cpp:398
216+#: plugins/Unity/scope.cpp:408
213217msgid "Sorry, there is nothing that matches your search."
214218msgstr ""
215219
@@ -221,6 +225,3 @@ msgstr ""
221225#, qt-format
222226msgid "Please enter %1"
223227msgstr ""
224−
225−#~ msgid "Music"
226−#~ msgstr "음악"
po/ky.po+8−10
@@ -7,7 +7,7 @@ msgid ""
77msgstr ""
88"Project-Id-Version: unity\n"
99"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10−"POT-Creation-Date: 2013-10-11 12:12+0200\n"
10+"POT-Creation-Date: 2013-11-05 17:53+0100\n"
1111"PO-Revision-Date: 2013-06-27 06:17+0000\n"
1212"Last-Translator: Michał Sawicz <michal.sawicz@canonical.com>\n"
1313"Language-Team: Kirghiz <ky@li.org>\n"
@@ -15,8 +15,8 @@ msgstr ""
1515"Content-Type: text/plain; charset=UTF-8\n"
1616"Content-Transfer-Encoding: 8bit\n"
1717"Plural-Forms: nplurals=1; plural=0;\n"
18−"X-Launchpad-Export-Date: 2013-10-13 05:43+0000\n"
19−"X-Generator: Launchpad (build 16799)\n"
18+"X-Launchpad-Export-Date: 2013-11-08 06:37+0000\n"
19+"X-Generator: Launchpad (build 16820)\n"
2020
2121#: Applications/applications.js:23
2222msgid "Phone"
@@ -205,11 +205,15 @@ msgstr "Азыр сүйлөңүз..."
205205msgid "Speaking..."
206206msgstr "Сүйлөнүүдө..."
207207
208+#: Notifications/NotificationMenuItemFactory.qml:89
209+msgid "Show password"
210+msgstr ""
211+
208212#: Panel/SearchIndicator.qml:27
209213msgid "Search"
210214msgstr "Издөө"
211215
212−#: plugins/Unity/scope.cpp:398
216+#: plugins/Unity/scope.cpp:408
213217msgid "Sorry, there is nothing that matches your search."
214218msgstr "Тилекке каршы, сиздин издөөңүзгө эч нерсе дал келген жок."
215219
@@ -221,9 +225,3 @@ msgstr ""
221225#, qt-format
222226msgid "Please enter %1"
223227msgstr ""
224−
225−#~ msgid "Music"
226−#~ msgstr "Музыка"
227−
228−#~ msgid "Videos"
229−#~ msgstr "Видеолор"
po/lo.po+8−10
@@ -7,7 +7,7 @@ msgid ""
77msgstr ""
88"Project-Id-Version: unity8\n"
99"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10−"POT-Creation-Date: 2013-10-11 12:12+0200\n"
10+"POT-Creation-Date: 2013-11-05 17:53+0100\n"
1111"PO-Revision-Date: 2013-10-02 10:00+0000\n"
1212"Last-Translator: Anousak <anousak@gmail.com>\n"
1313"Language-Team: Lao <lo@li.org>\n"
@@ -15,8 +15,8 @@ msgstr ""
1515"Content-Type: text/plain; charset=UTF-8\n"
1616"Content-Transfer-Encoding: 8bit\n"
1717"Plural-Forms: nplurals=1; plural=0;\n"
18−"X-Launchpad-Export-Date: 2013-10-13 05:43+0000\n"
19−"X-Generator: Launchpad (build 16799)\n"
18+"X-Launchpad-Export-Date: 2013-11-08 06:37+0000\n"
19+"X-Generator: Launchpad (build 16820)\n"
2020
2121#: Applications/applications.js:23
2222msgid "Phone"
@@ -205,11 +205,15 @@ msgstr "ເວົ້າໂລດ"
205205msgid "Speaking..."
206206msgstr "ກໍາລັງເວົ້າ"
207207
208+#: Notifications/NotificationMenuItemFactory.qml:89
209+msgid "Show password"
210+msgstr ""
211+
208212#: Panel/SearchIndicator.qml:27
209213msgid "Search"
210214msgstr "ຊອກຫາ"
211215
212−#: plugins/Unity/scope.cpp:398
216+#: plugins/Unity/scope.cpp:408
213217msgid "Sorry, there is nothing that matches your search."
214218msgstr ""
215219
@@ -221,9 +225,3 @@ msgstr "ທັງໝົດ"
221225#, qt-format
222226msgid "Please enter %1"
223227msgstr "ກະລູນາປ້ອນ %1"
224−
225−#~ msgid "Videos"
226−#~ msgstr "ວິດີໂອ"
227−
228−#~ msgid "Music"
229−#~ msgstr "ດົນຕີ"
po/lv.po+8−10
@@ -7,7 +7,7 @@ msgid ""
77msgstr ""
88"Project-Id-Version: unity\n"
99"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10−"POT-Creation-Date: 2013-10-11 12:12+0200\n"
10+"POT-Creation-Date: 2013-11-05 17:53+0100\n"
1111"PO-Revision-Date: 2013-09-28 16:29+0000\n"
1212"Last-Translator: Jānis-Marks Gailis <jeanmarc.gailis@gmail.com>\n"
1313"Language-Team: Latvian <lv@li.org>\n"
@@ -15,8 +15,8 @@ msgstr ""
1515"Content-Type: text/plain; charset=UTF-8\n"
1616"Content-Transfer-Encoding: 8bit\n"
1717"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n != 0 ? 1 : 2;\n"
18−"X-Launchpad-Export-Date: 2013-10-13 05:43+0000\n"
19−"X-Generator: Launchpad (build 16799)\n"
18+"X-Launchpad-Export-Date: 2013-11-08 06:37+0000\n"
19+"X-Generator: Launchpad (build 16820)\n"
2020
2121#: Applications/applications.js:23
2222msgid "Phone"
@@ -205,11 +205,15 @@ msgstr "Runajiet Tagad"
205205msgid "Speaking..."
206206msgstr "Runa..."
207207
208+#: Notifications/NotificationMenuItemFactory.qml:89
209+msgid "Show password"
210+msgstr ""
211+
208212#: Panel/SearchIndicator.qml:27
209213msgid "Search"
210214msgstr "Meklēt"
211215
212−#: plugins/Unity/scope.cpp:398
216+#: plugins/Unity/scope.cpp:408
213217msgid "Sorry, there is nothing that matches your search."
214218msgstr "Diemžēl nekas neatbilst jūsu meklētajam."
215219
@@ -221,9 +225,3 @@ msgstr ""
221225#, qt-format
222226msgid "Please enter %1"
223227msgstr ""
224−
225−#~ msgid "Music"
226−#~ msgstr "Mūzika"
227−
228−#~ msgid "Videos"
229−#~ msgstr "Video"
po/my.po+8−19
@@ -7,7 +7,7 @@ msgid ""
77msgstr ""
88"Project-Id-Version: unity\n"
99"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10−"POT-Creation-Date: 2013-10-11 12:12+0200\n"
10+"POT-Creation-Date: 2013-11-05 17:53+0100\n"
1111"PO-Revision-Date: 2013-10-09 11:35+0000\n"
1212"Last-Translator: Pyae Sone <Unknown>\n"
1313"Language-Team: Burmese <my@li.org>\n"
@@ -15,8 +15,8 @@ msgstr ""
1515"Content-Type: text/plain; charset=UTF-8\n"
1616"Content-Transfer-Encoding: 8bit\n"
1717"Plural-Forms: nplurals=1; plural=0;\n"
18−"X-Launchpad-Export-Date: 2013-10-13 05:43+0000\n"
19−"X-Generator: Launchpad (build 16799)\n"
18+"X-Launchpad-Export-Date: 2013-11-08 06:37+0000\n"
19+"X-Generator: Launchpad (build 16820)\n"
2020
2121#: Applications/applications.js:23
2222msgid "Phone"
@@ -205,11 +205,15 @@ msgstr "ယခုပြောပါ"
205205msgid "Speaking..."
206206msgstr "ပြောနေသည်"
207207
208+#: Notifications/NotificationMenuItemFactory.qml:89
209+msgid "Show password"
210+msgstr ""
211+
208212#: Panel/SearchIndicator.qml:27
209213msgid "Search"
210214msgstr "ရှာဖွေ"
211215
212−#: plugins/Unity/scope.cpp:398
216+#: plugins/Unity/scope.cpp:408
213217msgid "Sorry, there is nothing that matches your search."
214218msgstr "ဆောရီး၊ သင်၏ရှာဖွေမူနှင့်တူညီတာဘာမှမရှိပါ။"
215219
@@ -221,18 +225,3 @@ msgstr ""
221225#, qt-format
222226msgid "Please enter %1"
223227msgstr ""
224−
225−#~ msgid "Music"
226−#~ msgstr "တေးဂီတ"
227−
228−#~ msgid "Videos"
229−#~ msgstr "ဗီဒီယိုများ"
230−
231−#~ msgid "New Releases"
232−#~ msgstr "အသစ်ထွက်ရှိသော"
233−
234−#~ msgid "Recent"
235−#~ msgstr "မကြာသေးခင်က"
236−
237−#~ msgid "Popular Online"
238−#~ msgstr "အွန်လိုင်းတွင်ပေါ်ပြူလာဖြစ်သော"
po/nb.po+8−10
@@ -7,7 +7,7 @@ msgid ""
77msgstr ""
88"Project-Id-Version: unity\n"
99"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10−"POT-Creation-Date: 2013-10-11 12:12+0200\n"
10+"POT-Creation-Date: 2013-11-05 17:53+0100\n"
1111"PO-Revision-Date: 2013-06-27 07:02+0000\n"
1212"Last-Translator: Joakim Langvand <jlangvand@gmail.com>\n"
1313"Language-Team: Norwegian Bokmal <nb@li.org>\n"
@@ -15,8 +15,8 @@ msgstr ""
1515"Content-Type: text/plain; charset=UTF-8\n"
1616"Content-Transfer-Encoding: 8bit\n"
1717"Plural-Forms: nplurals=2; plural=n != 1;\n"
18−"X-Launchpad-Export-Date: 2013-10-13 05:43+0000\n"
19−"X-Generator: Launchpad (build 16799)\n"
18+"X-Launchpad-Export-Date: 2013-11-08 06:37+0000\n"
19+"X-Generator: Launchpad (build 16820)\n"
2020
2121#: Applications/applications.js:23
2222msgid "Phone"
@@ -205,11 +205,15 @@ msgstr "Snakk nå …"
205205msgid "Speaking..."
206206msgstr "Snakker …"
207207
208+#: Notifications/NotificationMenuItemFactory.qml:89
209+msgid "Show password"
210+msgstr ""
211+
208212#: Panel/SearchIndicator.qml:27
209213msgid "Search"
210214msgstr "Søk"
211215
212−#: plugins/Unity/scope.cpp:398
216+#: plugins/Unity/scope.cpp:408
213217msgid "Sorry, there is nothing that matches your search."
214218msgstr "Søket ga ingen treff."
215219
@@ -221,9 +225,3 @@ msgstr ""
221225#, qt-format
222226msgid "Please enter %1"
223227msgstr ""
224−
225−#~ msgid "Music"
226−#~ msgstr "Musikk"
227−
228−#~ msgid "Videos"
229−#~ msgstr "Videoer"
po/nl.po+8−10
@@ -7,7 +7,7 @@ msgid ""
77msgstr ""
88"Project-Id-Version: unity\n"
99"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10−"POT-Creation-Date: 2013-10-11 12:12+0200\n"
10+"POT-Creation-Date: 2013-11-05 17:53+0100\n"
1111"PO-Revision-Date: 2013-06-27 07:19+0000\n"
1212"Last-Translator: Michał Sawicz <michal.sawicz@canonical.com>\n"
1313"Language-Team: Dutch <nl@li.org>\n"
@@ -15,8 +15,8 @@ msgstr ""
1515"Content-Type: text/plain; charset=UTF-8\n"
1616"Content-Transfer-Encoding: 8bit\n"
1717"Plural-Forms: nplurals=2; plural=n != 1;\n"
18−"X-Launchpad-Export-Date: 2013-10-13 05:43+0000\n"
19−"X-Generator: Launchpad (build 16799)\n"
18+"X-Launchpad-Export-Date: 2013-11-08 06:37+0000\n"
19+"X-Generator: Launchpad (build 16820)\n"
2020
2121#: Applications/applications.js:23
2222msgid "Phone"
@@ -205,11 +205,15 @@ msgstr "Nu inspreken…"
205205msgid "Speaking..."
206206msgstr "Inspreken…"
207207
208+#: Notifications/NotificationMenuItemFactory.qml:89
209+msgid "Show password"
210+msgstr ""
211+
208212#: Panel/SearchIndicator.qml:27
209213msgid "Search"
210214msgstr "Zoeken"
211215
212−#: plugins/Unity/scope.cpp:398
216+#: plugins/Unity/scope.cpp:408
213217msgid "Sorry, there is nothing that matches your search."
214218msgstr "Er is helaas niets dat met uw zoekopdracht overeenkomt."
215219
@@ -221,9 +225,3 @@ msgstr ""
221225#, qt-format
222226msgid "Please enter %1"
223227msgstr ""
224−
225−#~ msgid "Music"
226−#~ msgstr "Muziek"
227−
228−#~ msgid "Videos"
229−#~ msgstr "Video's"
po/pl.po+8−4
@@ -7,7 +7,7 @@ msgid ""
77msgstr ""
88"Project-Id-Version: unity\n"
99"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10−"POT-Creation-Date: 2013-10-11 12:12+0200\n"
10+"POT-Creation-Date: 2013-11-05 17:53+0100\n"
1111"PO-Revision-Date: 2013-10-13 13:44+0000\n"
1212"Last-Translator: GTriderXC <gtriderxc@yahoo.com>\n"
1313"Language-Team: Polish <pl@li.org>\n"
@@ -16,8 +16,8 @@ msgstr ""
1616"Content-Transfer-Encoding: 8bit\n"
1717"Plural-Forms: nplurals=3; plural=n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 "
1818"|| n%100>=20) ? 1 : 2;\n"
19−"X-Launchpad-Export-Date: 2013-10-14 05:47+0000\n"
20−"X-Generator: Launchpad (build 16799)\n"
19+"X-Launchpad-Export-Date: 2013-11-08 06:38+0000\n"
20+"X-Generator: Launchpad (build 16820)\n"
2121
2222#: Applications/applications.js:23
2323msgid "Phone"
@@ -211,11 +211,15 @@ msgstr "Mów teraz..."
211211msgid "Speaking..."
212212msgstr "Rozpoznanie..."
213213
214+#: Notifications/NotificationMenuItemFactory.qml:89
215+msgid "Show password"
216+msgstr ""
217+
214218#: Panel/SearchIndicator.qml:27
215219msgid "Search"
216220msgstr "Szukaj"
217221
218−#: plugins/Unity/scope.cpp:398
222+#: plugins/Unity/scope.cpp:408
219223msgid "Sorry, there is nothing that matches your search."
220224msgstr "Nie znaleziono pasujących wyników."
221225
po/pt_BR.po+8−25
@@ -7,7 +7,7 @@ msgid ""
77msgstr ""
88"Project-Id-Version: unity\n"
99"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10−"POT-Creation-Date: 2013-10-11 12:12+0200\n"
10+"POT-Creation-Date: 2013-11-05 17:53+0100\n"
1111"PO-Revision-Date: 2013-10-01 13:05+0000\n"
1212"Last-Translator: Rafael Neri <Unknown>\n"
1313"Language-Team: Brazilian Portuguese <pt_BR@li.org>\n"
@@ -15,8 +15,8 @@ msgstr ""
1515"Content-Type: text/plain; charset=UTF-8\n"
1616"Content-Transfer-Encoding: 8bit\n"
1717"Plural-Forms: nplurals=2; plural=n > 1;\n"
18−"X-Launchpad-Export-Date: 2013-10-13 05:43+0000\n"
19−"X-Generator: Launchpad (build 16799)\n"
18+"X-Launchpad-Export-Date: 2013-11-08 06:38+0000\n"
19+"X-Generator: Launchpad (build 16820)\n"
2020
2121#: Applications/applications.js:23
2222msgid "Phone"
@@ -207,11 +207,15 @@ msgstr "Fale agora..."
207207msgid "Speaking..."
208208msgstr "Falando..."
209209
210+#: Notifications/NotificationMenuItemFactory.qml:89
211+msgid "Show password"
212+msgstr ""
213+
210214#: Panel/SearchIndicator.qml:27
211215msgid "Search"
212216msgstr "Pesquisar"
213217
214−#: plugins/Unity/scope.cpp:398
218+#: plugins/Unity/scope.cpp:408
215219msgid "Sorry, there is nothing that matches your search."
216220msgstr "Desculpe, não há nada que corresponda à sua pesquisa."
217221
@@ -223,24 +227,3 @@ msgstr ""
223227#, qt-format
224228msgid "Please enter %1"
225229msgstr "Por favor, digite %1"
226−
227−#~ msgid "Music"
228−#~ msgstr "Músicas"
229−
230−#~ msgid "Videos"
231−#~ msgstr "Vídeos"
232−
233−#~ msgid "New Releases"
234−#~ msgstr "Lançamentos"
235−
236−#~ msgid "Recent"
237−#~ msgstr "Recente"
238−
239−#~ msgid "Featured"
240−#~ msgstr "Em destaque"
241−
242−#~ msgid "Top Charting"
243−#~ msgstr "Top gráficos"
244−
245−#~ msgid "Popular Online"
246−#~ msgstr "Popular Online"
po/ro.po+8−10
@@ -7,7 +7,7 @@ msgid ""
77msgstr ""
88"Project-Id-Version: unity\n"
99"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10−"POT-Creation-Date: 2013-10-11 12:12+0200\n"
10+"POT-Creation-Date: 2013-11-05 17:53+0100\n"
1111"PO-Revision-Date: 2013-06-27 07:53+0000\n"
1212"Last-Translator: Michał Sawicz <michal.sawicz@canonical.com>\n"
1313"Language-Team: Romanian <ro@li.org>\n"
@@ -16,8 +16,8 @@ msgstr ""
1616"Content-Transfer-Encoding: 8bit\n"
1717"Plural-Forms: nplurals=3; plural=(n == 1 ? 0: (((n % 100 > 19) || ((n % 100 "
1818"== 0) && (n != 0))) ? 2: 1));\n"
19−"X-Launchpad-Export-Date: 2013-10-13 05:43+0000\n"
20−"X-Generator: Launchpad (build 16799)\n"
19+"X-Launchpad-Export-Date: 2013-11-08 06:38+0000\n"
20+"X-Generator: Launchpad (build 16820)\n"
2121
2222#: Applications/applications.js:23
2323msgid "Phone"
@@ -206,11 +206,15 @@ msgstr "Vorbiți acum..."
206206msgid "Speaking..."
207207msgstr "Vorbire..."
208208
209+#: Notifications/NotificationMenuItemFactory.qml:89
210+msgid "Show password"
211+msgstr ""
212+
209213#: Panel/SearchIndicator.qml:27
210214msgid "Search"
211215msgstr "Căutare"
212216
213−#: plugins/Unity/scope.cpp:398
217+#: plugins/Unity/scope.cpp:408
214218msgid "Sorry, there is nothing that matches your search."
215219msgstr ""
216220"Ne pare rău, nu este nimic care se potrivește căutării dumneavoastră."
@@ -223,9 +227,3 @@ msgstr ""
223227#, qt-format
224228msgid "Please enter %1"
225229msgstr ""
226−
227−#~ msgid "Music"
228−#~ msgstr "Muzică"
229−
230−#~ msgid "Videos"
231−#~ msgstr "Video"
po/ru.po+8−25
@@ -7,7 +7,7 @@ msgid ""
77msgstr ""
88"Project-Id-Version: unity\n"
99"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10−"POT-Creation-Date: 2013-10-11 12:12+0200\n"
10+"POT-Creation-Date: 2013-11-05 17:53+0100\n"
1111"PO-Revision-Date: 2013-10-01 05:55+0000\n"
1212"Last-Translator: Zonov Roman <Unknown>\n"
1313"Language-Team: Russian <ru@li.org>\n"
@@ -16,8 +16,8 @@ msgstr ""
1616"Content-Transfer-Encoding: 8bit\n"
1717"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && "
1818"n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n"
19−"X-Launchpad-Export-Date: 2013-10-13 05:43+0000\n"
20−"X-Generator: Launchpad (build 16799)\n"
19+"X-Launchpad-Export-Date: 2013-11-08 06:38+0000\n"
20+"X-Generator: Launchpad (build 16820)\n"
2121
2222#: Applications/applications.js:23
2323msgid "Phone"
@@ -210,11 +210,15 @@ msgstr "Говорите..."
210210msgid "Speaking..."
211211msgstr "Говорите..."
212212
213+#: Notifications/NotificationMenuItemFactory.qml:89
214+msgid "Show password"
215+msgstr ""
216+
213217#: Panel/SearchIndicator.qml:27
214218msgid "Search"
215219msgstr "Поиск"
216220
217−#: plugins/Unity/scope.cpp:398
221+#: plugins/Unity/scope.cpp:408
218222msgid "Sorry, there is nothing that matches your search."
219223msgstr "Извините, поиск не дал результатов."
220224
@@ -226,24 +230,3 @@ msgstr ""
226230#, qt-format
227231msgid "Please enter %1"
228232msgstr "Пожалуйста, введите %1"
229−
230−#~ msgid "New Releases"
231−#~ msgstr "Новые релизы"
232−
233−#~ msgid "Music"
234−#~ msgstr "Музыка"
235−
236−#~ msgid "Videos"
237−#~ msgstr "Видео"
238−
239−#~ msgid "Recent"
240−#~ msgstr "Недавние"
241−
242−#~ msgid "Top Charting"
243−#~ msgstr "Наиболее популярное"
244−
245−#~ msgid "Popular Online"
246−#~ msgstr "Популярное в Интернете"
247−
248−#~ msgid "Featured"
249−#~ msgstr "Рекомендованное"
po/shn.po+8−4
@@ -7,7 +7,7 @@ msgid ""
77msgstr ""
88"Project-Id-Version: unity8\n"
99"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10−"POT-Creation-Date: 2013-10-11 12:12+0200\n"
10+"POT-Creation-Date: 2013-11-05 17:53+0100\n"
1111"PO-Revision-Date: 2013-10-07 11:46+0000\n"
1212"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
1313"Language-Team: Shan <shn@li.org>\n"
@@ -15,8 +15,8 @@ msgstr ""
1515"Content-Type: text/plain; charset=UTF-8\n"
1616"Content-Transfer-Encoding: 8bit\n"
1717"Plural-Forms: nplurals=2; plural=(n == 1) ? 0 : 1;\n"
18−"X-Launchpad-Export-Date: 2013-10-13 05:43+0000\n"
19−"X-Generator: Launchpad (build 16799)\n"
18+"X-Launchpad-Export-Date: 2013-11-08 06:38+0000\n"
19+"X-Generator: Launchpad (build 16820)\n"
2020
2121#: Applications/applications.js:23
2222msgid "Phone"
@@ -205,11 +205,15 @@ msgstr ""
205205msgid "Speaking..."
206206msgstr ""
207207
208+#: Notifications/NotificationMenuItemFactory.qml:89
209+msgid "Show password"
210+msgstr ""
211+
208212#: Panel/SearchIndicator.qml:27
209213msgid "Search"
210214msgstr ""
211215
212−#: plugins/Unity/scope.cpp:398
216+#: plugins/Unity/scope.cpp:408
213217msgid "Sorry, there is nothing that matches your search."
214218msgstr ""
215219
po/si.po+8−4
@@ -7,7 +7,7 @@ msgid ""
77msgstr ""
88"Project-Id-Version: unity\n"
99"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10−"POT-Creation-Date: 2013-10-11 12:12+0200\n"
10+"POT-Creation-Date: 2013-11-05 17:53+0100\n"
1111"PO-Revision-Date: 2013-06-26 22:36+0000\n"
1212"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
1313"Language-Team: Sinhalese <si@li.org>\n"
@@ -15,8 +15,8 @@ msgstr ""
1515"Content-Type: text/plain; charset=UTF-8\n"
1616"Content-Transfer-Encoding: 8bit\n"
1717"Plural-Forms: nplurals=2; plural=n != 1;\n"
18−"X-Launchpad-Export-Date: 2013-10-13 05:43+0000\n"
19−"X-Generator: Launchpad (build 16799)\n"
18+"X-Launchpad-Export-Date: 2013-11-08 06:38+0000\n"
19+"X-Generator: Launchpad (build 16820)\n"
2020
2121#: Applications/applications.js:23
2222msgid "Phone"
@@ -205,11 +205,15 @@ msgstr ""
205205msgid "Speaking..."
206206msgstr ""
207207
208+#: Notifications/NotificationMenuItemFactory.qml:89
209+msgid "Show password"
210+msgstr ""
211+
208212#: Panel/SearchIndicator.qml:27
209213msgid "Search"
210214msgstr ""
211215
212−#: plugins/Unity/scope.cpp:398
216+#: plugins/Unity/scope.cpp:408
213217msgid "Sorry, there is nothing that matches your search."
214218msgstr ""
215219
po/sl.po+8−25
@@ -7,7 +7,7 @@ msgid ""
77msgstr ""
88"Project-Id-Version: unity\n"
99"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10−"POT-Creation-Date: 2013-10-11 12:12+0200\n"
10+"POT-Creation-Date: 2013-11-05 17:53+0100\n"
1111"PO-Revision-Date: 2013-10-02 10:55+0000\n"
1212"Last-Translator: Damir Jerovšek <Unknown>\n"
1313"Language-Team: Slovenian <sl@li.org>\n"
@@ -16,8 +16,8 @@ msgstr ""
1616"Content-Transfer-Encoding: 8bit\n"
1717"Plural-Forms: nplurals=4; plural=(n%100==1 ? 1 : n%100==2 ? 2 : n%100==3 || "
1818"n%100==4 ? 3 : 0);\n"
19−"X-Launchpad-Export-Date: 2013-10-13 05:43+0000\n"
20−"X-Generator: Launchpad (build 16799)\n"
19+"X-Launchpad-Export-Date: 2013-11-08 06:38+0000\n"
20+"X-Generator: Launchpad (build 16820)\n"
2121
2222#: Applications/applications.js:23
2323msgid "Phone"
@@ -212,11 +212,15 @@ msgstr "Govorite zdaj ..."
212212msgid "Speaking..."
213213msgstr "Govorjenje ..."
214214
215+#: Notifications/NotificationMenuItemFactory.qml:89
216+msgid "Show password"
217+msgstr ""
218+
215219#: Panel/SearchIndicator.qml:27
216220msgid "Search"
217221msgstr "Iskanje"
218222
219−#: plugins/Unity/scope.cpp:398
223+#: plugins/Unity/scope.cpp:408
220224msgid "Sorry, there is nothing that matches your search."
221225msgstr "Nič se ne ujema z vašim iskalnim nizom."
222226
@@ -228,24 +232,3 @@ msgstr "Vse"
228232#, qt-format
229233msgid "Please enter %1"
230234msgstr "Vnesite %1"
231−
232−#~ msgid "Music"
233−#~ msgstr "Glasba"
234−
235−#~ msgid "Videos"
236−#~ msgstr "Videi"
237−
238−#~ msgid "New Releases"
239−#~ msgstr "Nove izdaje"
240−
241−#~ msgid "Top Charting"
242−#~ msgstr "Najvišje na lestvici"
243−
244−#~ msgid "Featured"
245−#~ msgstr "Predstavljeno"
246−
247−#~ msgid "Recent"
248−#~ msgstr "Nedavno"
249−
250−#~ msgid "Popular Online"
251−#~ msgstr "Priljubljeno na spletu"
po/sr.po+8−10
@@ -7,7 +7,7 @@ msgid ""
77msgstr ""
88"Project-Id-Version: unity\n"
99"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10−"POT-Creation-Date: 2013-10-11 12:12+0200\n"
10+"POT-Creation-Date: 2013-11-05 17:53+0100\n"
1111"PO-Revision-Date: 2013-06-27 09:19+0000\n"
1212"Last-Translator: Michał Sawicz <michal.sawicz@canonical.com>\n"
1313"Language-Team: Serbian <sr@li.org>\n"
@@ -16,8 +16,8 @@ msgstr ""
1616"Content-Transfer-Encoding: 8bit\n"
1717"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && "
1818"n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n"
19−"X-Launchpad-Export-Date: 2013-10-13 05:43+0000\n"
20−"X-Generator: Launchpad (build 16799)\n"
19+"X-Launchpad-Export-Date: 2013-11-08 06:38+0000\n"
20+"X-Generator: Launchpad (build 16820)\n"
2121
2222#: Applications/applications.js:23
2323msgid "Phone"
@@ -206,11 +206,15 @@ msgstr "Изговорите сада..."
206206msgid "Speaking..."
207207msgstr "Говор..."
208208
209+#: Notifications/NotificationMenuItemFactory.qml:89
210+msgid "Show password"
211+msgstr ""
212+
209213#: Panel/SearchIndicator.qml:27
210214msgid "Search"
211215msgstr "Претрага"
212216
213−#: plugins/Unity/scope.cpp:398
217+#: plugins/Unity/scope.cpp:408
214218msgid "Sorry, there is nothing that matches your search."
215219msgstr "Нажалост, претрага није наишла на икакво подударање."
216220
@@ -222,9 +226,3 @@ msgstr ""
222226#, qt-format
223227msgid "Please enter %1"
224228msgstr ""
225−
226−#~ msgid "Music"
227−#~ msgstr "Музика"
228−
229−#~ msgid "Videos"
230−#~ msgstr "Видео"
po/sv.po+8−4
@@ -7,7 +7,7 @@ msgid ""
77msgstr ""
88"Project-Id-Version: unity\n"
99"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10−"POT-Creation-Date: 2013-10-11 12:12+0200\n"
10+"POT-Creation-Date: 2013-11-05 17:53+0100\n"
1111"PO-Revision-Date: 2013-06-26 22:36+0000\n"
1212"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
1313"Language-Team: Swedish <sv@li.org>\n"
@@ -15,8 +15,8 @@ msgstr ""
1515"Content-Type: text/plain; charset=UTF-8\n"
1616"Content-Transfer-Encoding: 8bit\n"
1717"Plural-Forms: nplurals=2; plural=n != 1;\n"
18−"X-Launchpad-Export-Date: 2013-10-13 05:43+0000\n"
19−"X-Generator: Launchpad (build 16799)\n"
18+"X-Launchpad-Export-Date: 2013-11-08 06:38+0000\n"
19+"X-Generator: Launchpad (build 16820)\n"
2020
2121#: Applications/applications.js:23
2222msgid "Phone"
@@ -205,11 +205,15 @@ msgstr ""
205205msgid "Speaking..."
206206msgstr ""
207207
208+#: Notifications/NotificationMenuItemFactory.qml:89
209+msgid "Show password"
210+msgstr ""
211+
208212#: Panel/SearchIndicator.qml:27
209213msgid "Search"
210214msgstr ""
211215
212−#: plugins/Unity/scope.cpp:398
216+#: plugins/Unity/scope.cpp:408
213217msgid "Sorry, there is nothing that matches your search."
214218msgstr ""
215219
po/ta.po+8−4
@@ -7,7 +7,7 @@ msgid ""
77msgstr ""
88"Project-Id-Version: unity8\n"
99"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10−"POT-Creation-Date: 2013-10-11 12:12+0200\n"
10+"POT-Creation-Date: 2013-11-05 17:53+0100\n"
1111"PO-Revision-Date: 2013-10-24 11:36+0000\n"
1212"Last-Translator: Thangamani Arun - தங்கமணி அருண் <thangam.arunx@gmail.com>\n"
1313"Language-Team: Ubuntu Tamil Team/Free Tamil Computing/Thamizha\n"
@@ -15,8 +15,8 @@ msgstr ""
1515"Content-Type: text/plain; charset=UTF-8\n"
1616"Content-Transfer-Encoding: 8bit\n"
1717"Plural-Forms: nplurals=2; plural=n != 1;\n"
18−"X-Launchpad-Export-Date: 2013-10-25 06:05+0000\n"
19−"X-Generator: Launchpad (build 16810)\n"
18+"X-Launchpad-Export-Date: 2013-11-08 06:38+0000\n"
19+"X-Generator: Launchpad (build 16820)\n"
2020"Language: ta\n"
2121
2222#: Applications/applications.js:23
@@ -211,11 +211,15 @@ msgstr "இப்பொது பேசு..."
211211msgid "Speaking..."
212212msgstr "பேசுகிறது..."
213213
214+#: Notifications/NotificationMenuItemFactory.qml:89
215+msgid "Show password"
216+msgstr ""
217+
214218#: Panel/SearchIndicator.qml:27
215219msgid "Search"
216220msgstr "தெடு"
217221
218−#: plugins/Unity/scope.cpp:398
222+#: plugins/Unity/scope.cpp:408
219223msgid "Sorry, there is nothing that matches your search."
220224msgstr "மன்னிக்கவும், உங்களுடைய தேடலுக்கு தகுந்த பொருத்தம் கிடைக்கவில்லை."
221225
po/te.po+8−7
@@ -7,7 +7,7 @@ msgid ""
77msgstr ""
88"Project-Id-Version: unity\n"
99"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10−"POT-Creation-Date: 2013-10-11 12:12+0200\n"
10+"POT-Creation-Date: 2013-11-05 17:53+0100\n"
1111"PO-Revision-Date: 2013-06-27 09:57+0000\n"
1212"Last-Translator: Michał Sawicz <michal.sawicz@canonical.com>\n"
1313"Language-Team: Telugu <te@li.org>\n"
@@ -15,8 +15,8 @@ msgstr ""
1515"Content-Type: text/plain; charset=UTF-8\n"
1616"Content-Transfer-Encoding: 8bit\n"
1717"Plural-Forms: nplurals=2; plural=n != 1;\n"
18−"X-Launchpad-Export-Date: 2013-10-13 05:43+0000\n"
19−"X-Generator: Launchpad (build 16799)\n"
18+"X-Launchpad-Export-Date: 2013-11-08 06:38+0000\n"
19+"X-Generator: Launchpad (build 16820)\n"
2020
2121#: Applications/applications.js:23
2222msgid "Phone"
@@ -205,11 +205,15 @@ msgstr ""
205205msgid "Speaking..."
206206msgstr ""
207207
208+#: Notifications/NotificationMenuItemFactory.qml:89
209+msgid "Show password"
210+msgstr ""
211+
208212#: Panel/SearchIndicator.qml:27
209213msgid "Search"
210214msgstr ""
211215
212−#: plugins/Unity/scope.cpp:398
216+#: plugins/Unity/scope.cpp:408
213217msgid "Sorry, there is nothing that matches your search."
214218msgstr ""
215219
@@ -221,6 +225,3 @@ msgstr ""
221225#, qt-format
222226msgid "Please enter %1"
223227msgstr ""
224−
225−#~ msgid "Music"
226−#~ msgstr "సంగీతం"
po/tr.po+8−25
@@ -7,7 +7,7 @@ msgid ""
77msgstr ""
88"Project-Id-Version: unity\n"
99"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10−"POT-Creation-Date: 2013-10-11 12:12+0200\n"
10+"POT-Creation-Date: 2013-11-05 17:53+0100\n"
1111"PO-Revision-Date: 2013-10-01 13:21+0000\n"
1212"Last-Translator: Volkan Gezer <Unknown>\n"
1313"Language-Team: Turkish <tr@li.org>\n"
@@ -15,8 +15,8 @@ msgstr ""
1515"Content-Type: text/plain; charset=UTF-8\n"
1616"Content-Transfer-Encoding: 8bit\n"
1717"Plural-Forms: nplurals=2; plural=n != 1;\n"
18−"X-Launchpad-Export-Date: 2013-10-13 05:43+0000\n"
19−"X-Generator: Launchpad (build 16799)\n"
18+"X-Launchpad-Export-Date: 2013-11-08 06:38+0000\n"
19+"X-Generator: Launchpad (build 16820)\n"
2020
2121#: Applications/applications.js:23
2222msgid "Phone"
@@ -206,11 +206,15 @@ msgstr "Şimdi Konuşun..."
206206msgid "Speaking..."
207207msgstr "Konuşuyor..."
208208
209+#: Notifications/NotificationMenuItemFactory.qml:89
210+msgid "Show password"
211+msgstr ""
212+
209213#: Panel/SearchIndicator.qml:27
210214msgid "Search"
211215msgstr "Ara"
212216
213−#: plugins/Unity/scope.cpp:398
217+#: plugins/Unity/scope.cpp:408
214218msgid "Sorry, there is nothing that matches your search."
215219msgstr "Üzgünüz, aramanızla eşleşen hiçbir şey yok."
216220
@@ -222,24 +226,3 @@ msgstr ""
222226#, qt-format
223227msgid "Please enter %1"
224228msgstr "Lütfen %1 girin"
225−
226−#~ msgid "Featured"
227−#~ msgstr "Öne Çıkanlar"
228−
229−#~ msgid "Recent"
230−#~ msgstr "En Son"
231−
232−#~ msgid "Music"
233−#~ msgstr "Müzik"
234−
235−#~ msgid "Popular Online"
236−#~ msgstr "Genellikle Çevrimiçi"
237−
238−#~ msgid "Videos"
239−#~ msgstr "Videolar"
240−
241−#~ msgid "Top Charting"
242−#~ msgstr "En Çok Beğenilenler"
243−
244−#~ msgid "New Releases"
245−#~ msgstr "Yeni Sürümler"
po/ug.po+8−19
@@ -7,7 +7,7 @@ msgid ""
77msgstr ""
88"Project-Id-Version: unity\n"
99"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10−"POT-Creation-Date: 2013-10-11 12:12+0200\n"
10+"POT-Creation-Date: 2013-11-05 17:53+0100\n"
1111"PO-Revision-Date: 2013-10-09 22:38+0000\n"
1212"Last-Translator: Gheyret T.Kenji <Unknown>\n"
1313"Language-Team: Uyghur <ug@li.org>\n"
@@ -15,8 +15,8 @@ msgstr ""
1515"Content-Type: text/plain; charset=UTF-8\n"
1616"Content-Transfer-Encoding: 8bit\n"
1717"Plural-Forms: nplurals=1; plural=0;\n"
18−"X-Launchpad-Export-Date: 2013-10-13 05:43+0000\n"
19−"X-Generator: Launchpad (build 16799)\n"
18+"X-Launchpad-Export-Date: 2013-11-08 06:38+0000\n"
19+"X-Generator: Launchpad (build 16820)\n"
2020
2121#: Applications/applications.js:23
2222msgid "Phone"
@@ -204,11 +204,15 @@ msgstr "ئەمدى سۆزلەڭ…"
204204msgid "Speaking..."
205205msgstr "سۆزلەۋاتىسىز…"
206206
207+#: Notifications/NotificationMenuItemFactory.qml:89
208+msgid "Show password"
209+msgstr ""
210+
207211#: Panel/SearchIndicator.qml:27
208212msgid "Search"
209213msgstr "ئىزدە"
210214
211−#: plugins/Unity/scope.cpp:398
215+#: plugins/Unity/scope.cpp:408
212216msgid "Sorry, there is nothing that matches your search."
213217msgstr "كەچۈرۈڭ، ئىزدىگىنىڭىزگە ماس نەتىجە تېپىلمىدى."
214218
@@ -220,18 +224,3 @@ msgstr "ھەممىسى"
220224#, qt-format
221225msgid "Please enter %1"
222226msgstr "%1 نى كىرگۈزۈڭ"
223−
224−#~ msgid "Featured"
225−#~ msgstr "داڭلىق"
226−
227−#~ msgid "Recent"
228−#~ msgstr "يېقىنقى"
229−
230−#~ msgid "New Releases"
231−#~ msgstr "يېڭى ئېلان قىلىنغانلىرى"
232−
233−#~ msgid "Music"
234−#~ msgstr "مۇزىكا"
235−
236−#~ msgid "Videos"
237−#~ msgstr "سىنلار"
po/uk.po+8−4
@@ -7,7 +7,7 @@ msgid ""
77msgstr ""
88"Project-Id-Version: unity\n"
99"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10−"POT-Creation-Date: 2013-10-11 12:12+0200\n"
10+"POT-Creation-Date: 2013-11-05 17:53+0100\n"
1111"PO-Revision-Date: 2013-10-19 16:44+0000\n"
1212"Last-Translator: Yuri Chornoivan <yurchor@gmail.com>\n"
1313"Language-Team: Ukrainian <uk@li.org>\n"
@@ -16,8 +16,8 @@ msgstr ""
1616"Content-Transfer-Encoding: 8bit\n"
1717"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && "
1818"n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n"
19−"X-Launchpad-Export-Date: 2013-10-20 05:20+0000\n"
20−"X-Generator: Launchpad (build 16807)\n"
19+"X-Launchpad-Export-Date: 2013-11-08 06:38+0000\n"
20+"X-Generator: Launchpad (build 16820)\n"
2121
2222#: Applications/applications.js:23
2323msgid "Phone"
@@ -212,11 +212,15 @@ msgstr "Можна говорити…"
212212msgid "Speaking..."
213213msgstr "Мовлення…"
214214
215+#: Notifications/NotificationMenuItemFactory.qml:89
216+msgid "Show password"
217+msgstr ""
218+
215219#: Panel/SearchIndicator.qml:27
216220msgid "Search"
217221msgstr "Пошук"
218222
219−#: plugins/Unity/scope.cpp:398
223+#: plugins/Unity/scope.cpp:408
220224msgid "Sorry, there is nothing that matches your search."
221225msgstr "Вибачте, для вказаних вами ключових слів нічого не знайдено."
222226
po/unity8.pot+6−2
@@ -8,7 +8,7 @@ msgid ""
88msgstr ""
99"Project-Id-Version: unity8\n"
1010"Report-Msgid-Bugs-To: \n"
11−"POT-Creation-Date: 2013-10-11 12:12+0200\n"
11+"POT-Creation-Date: 2013-11-05 17:53+0100\n"
1212"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
1313"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
1414"Language-Team: LANGUAGE <LL@li.org>\n"
@@ -205,11 +205,15 @@ msgstr ""
205205msgid "Speaking..."
206206msgstr ""
207207
208+#: Notifications/NotificationMenuItemFactory.qml:89
209+msgid "Show password"
210+msgstr ""
211+
208212#: Panel/SearchIndicator.qml:27
209213msgid "Search"
210214msgstr ""
211215
212−#: plugins/Unity/scope.cpp:398
216+#: plugins/Unity/scope.cpp:408
213217msgid "Sorry, there is nothing that matches your search."
214218msgstr ""
215219
po/xh.po+8−4
@@ -7,7 +7,7 @@ msgid ""
77msgstr ""
88"Project-Id-Version: unity8\n"
99"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10−"POT-Creation-Date: 2013-10-11 12:12+0200\n"
10+"POT-Creation-Date: 2013-11-05 17:53+0100\n"
1111"PO-Revision-Date: 2013-09-28 13:20+0000\n"
1212"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
1313"Language-Team: Xhosa <xh@li.org>\n"
@@ -15,8 +15,8 @@ msgstr ""
1515"Content-Type: text/plain; charset=UTF-8\n"
1616"Content-Transfer-Encoding: 8bit\n"
1717"Plural-Forms: nplurals=2; plural=n != 1;\n"
18−"X-Launchpad-Export-Date: 2013-10-13 05:43+0000\n"
19−"X-Generator: Launchpad (build 16799)\n"
18+"X-Launchpad-Export-Date: 2013-11-08 06:38+0000\n"
19+"X-Generator: Launchpad (build 16820)\n"
2020
2121#: Applications/applications.js:23
2222msgid "Phone"
@@ -205,11 +205,15 @@ msgstr ""
205205msgid "Speaking..."
206206msgstr ""
207207
208+#: Notifications/NotificationMenuItemFactory.qml:89
209+msgid "Show password"
210+msgstr ""
211+
208212#: Panel/SearchIndicator.qml:27
209213msgid "Search"
210214msgstr ""
211215
212−#: plugins/Unity/scope.cpp:398
216+#: plugins/Unity/scope.cpp:408
213217msgid "Sorry, there is nothing that matches your search."
214218msgstr ""
215219
po/zh_CN.po+8−25
@@ -7,7 +7,7 @@ msgid ""
77msgstr ""
88"Project-Id-Version: unity\n"
99"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10−"POT-Creation-Date: 2013-10-11 12:12+0200\n"
10+"POT-Creation-Date: 2013-11-05 17:53+0100\n"
1111"PO-Revision-Date: 2013-10-09 13:51+0000\n"
1212"Last-Translator: Aron Xu <Unknown>\n"
1313"Language-Team: Chinese (Simplified) <zh_CN@li.org>\n"
@@ -15,8 +15,8 @@ msgstr ""
1515"Content-Type: text/plain; charset=UTF-8\n"
1616"Content-Transfer-Encoding: 8bit\n"
1717"Plural-Forms: nplurals=1; plural=0;\n"
18−"X-Launchpad-Export-Date: 2013-10-13 05:43+0000\n"
19−"X-Generator: Launchpad (build 16799)\n"
18+"X-Launchpad-Export-Date: 2013-11-08 06:38+0000\n"
19+"X-Generator: Launchpad (build 16820)\n"
2020
2121#: Applications/applications.js:23
2222msgid "Phone"
@@ -205,11 +205,15 @@ msgstr "现在请讲..."
205205msgid "Speaking..."
206206msgstr "讲话中..."
207207
208+#: Notifications/NotificationMenuItemFactory.qml:89
209+msgid "Show password"
210+msgstr ""
211+
208212#: Panel/SearchIndicator.qml:27
209213msgid "Search"
210214msgstr "搜索"
211215
212−#: plugins/Unity/scope.cpp:398
216+#: plugins/Unity/scope.cpp:408
213217msgid "Sorry, there is nothing that matches your search."
214218msgstr "对不起,没有找到您想要的结果。"
215219
@@ -221,24 +225,3 @@ msgstr ""
221225#, qt-format
222226msgid "Please enter %1"
223227msgstr ""
224−
225−#~ msgid "Featured"
226−#~ msgstr "推荐"
227−
228−#~ msgid "New Releases"
229−#~ msgstr "新版本"
230−
231−#~ msgid "Top Charting"
232−#~ msgstr "排行榜图"
233−
234−#~ msgid "Music"
235−#~ msgstr "音乐"
236−
237−#~ msgid "Popular Online"
238−#~ msgstr "经常在线"
239−
240−#~ msgid "Videos"
241−#~ msgstr "视频"
242−
243−#~ msgid "Recent"
244−#~ msgstr "最近使用"
po/zh_TW.po+8−10
@@ -7,7 +7,7 @@ msgid ""
77msgstr ""
88"Project-Id-Version: unity\n"
99"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10−"POT-Creation-Date: 2013-10-11 12:12+0200\n"
10+"POT-Creation-Date: 2013-11-05 17:53+0100\n"
1111"PO-Revision-Date: 2013-06-27 10:24+0000\n"
1212"Last-Translator: Michał Sawicz <michal.sawicz@canonical.com>\n"
1313"Language-Team: Chinese (Traditional) <zh_TW@li.org>\n"
@@ -15,8 +15,8 @@ msgstr ""
1515"Content-Type: text/plain; charset=UTF-8\n"
1616"Content-Transfer-Encoding: 8bit\n"
1717"Plural-Forms: nplurals=1; plural=0;\n"
18−"X-Launchpad-Export-Date: 2013-10-13 05:43+0000\n"
19−"X-Generator: Launchpad (build 16799)\n"
18+"X-Launchpad-Export-Date: 2013-11-08 06:38+0000\n"
19+"X-Generator: Launchpad (build 16820)\n"
2020
2121#: Applications/applications.js:23
2222msgid "Phone"
@@ -205,11 +205,15 @@ msgstr "請說..."
205205msgid "Speaking..."
206206msgstr "說話中..."
207207
208+#: Notifications/NotificationMenuItemFactory.qml:89
209+msgid "Show password"
210+msgstr ""
211+
208212#: Panel/SearchIndicator.qml:27
209213msgid "Search"
210214msgstr "搜尋"
211215
212−#: plugins/Unity/scope.cpp:398
216+#: plugins/Unity/scope.cpp:408
213217msgid "Sorry, there is nothing that matches your search."
214218msgstr "很抱歉,找不到符合您想搜尋的結果。"
215219
@@ -221,9 +225,3 @@ msgstr ""
221225#, qt-format
222226msgid "Please enter %1"
223227msgstr ""
224−
225−#~ msgid "Music"
226−#~ msgstr "音樂"
227−
228−#~ msgid "Videos"
229−#~ msgstr "影片"
tests/autopilot/unity8/shell/emulators/create_interactive_notification.pymode 100755 → 100644

Only the mode changed.

tests/autopilot/unity8/shell/emulators/dash.py+7−17
@@ -18,42 +18,32 @@
1818#
1919
2020from unity8.shell.emulators import UnityEmulatorBase
21−from time import sleep
21+
2222
2323class Dash(UnityEmulatorBase):
2424
2525 """An emulator that understands the Dash."""
2626
2727 def get_home_applications_grid(self):
28− for i in range(1,10):
29− get_grid = self.get_scope('home').select_single(
30− "GenericFilterGrid",
31− objectName="applications.scope"
32− )
33− if get_grid != None:
34− break
35− sleep(1)
28+ get_grid = self.get_scope('home').wait_select_single(
29+ "GenericFilterGrid",
30+ objectName="applications.scope"
31+ )
3632 return get_grid
3733
3834 def get_application_icon(self, text):
3935 """Returns a 'Tile' icon that has the text 'text' from the application
4036 grid.
4137
42− Will return None if the icon isn't found.
43−
4438 :param text: String containing the text of the icon to search for.
4539
4640 """
4741 app_grid = self.get_home_applications_grid()
48− for i in range(1,10):
49− resp_grid = app_grid.select_single('ResponsiveGridView')
50− if resp_grid != None:
51− break
52− sleep(1)
42+ resp_grid = app_grid.wait_select_single('ResponsiveGridView')
5343 return resp_grid.select_single('Tile', text=text)
5444
5545 def get_scope(self, scope_name='home'):
56− dash_content = self.select_single(
46+ dash_content = self.wait_select_single(
5747 'QQuickListView',
5848 objectName='dashContentList'
5949 )
tests/autopilot/unity8/shell/emulators/hud.py+12−4
@@ -26,6 +26,7 @@ from autopilot.input import Touch
2626
2727SwipeCoords = namedtuple('SwipeCoords', 'start_x end_x start_y end_y')
2828
29+
2930class Hud(UnityEmulatorBase, DragMixin):
3031
3132 """An emulator that understands the Hud."""
@@ -34,13 +35,18 @@ class Hud(UnityEmulatorBase, DragMixin):
3435 """Swipes open the Hud."""
3536 self.touch = Touch.create()
3637
37− window = self.get_root_instance().select_single('QQuickView')
38− hud_show_button = window.select_single("HudButton")
38+ window = self.get_root_instance().wait_select_single('QQuickView')
39+ hud_show_button = window.wait_select_single("HudButton")
3940
4041 swipe_coords = self.get_button_swipe_coords(window, hud_show_button)
4142
4243 self.touch.press(swipe_coords.start_x, swipe_coords.start_y)
43− self._drag(swipe_coords.start_x, swipe_coords.start_y, swipe_coords.start_x, swipe_coords.end_y)
44+ self._drag(
45+ swipe_coords.start_x,
46+ swipe_coords.start_y,
47+ swipe_coords.start_x,
48+ swipe_coords.end_y
49+ )
4450 try:
4551 hud_show_button.opacity.wait_for(1.0)
4652 self.touch.release()
@@ -74,6 +80,8 @@ class Hud(UnityEmulatorBase, DragMixin):
7480 start_x = int(main_view.x + (main_view.width / 2))
7581 end_x = start_x
7682 start_y = main_view.y + (main_view.height - 3)
77− end_y = main_view.y + int(hud_show_button.y + (hud_show_button.height/2))
83+ end_y = main_view.y + int(
84+ hud_show_button.y + (hud_show_button.height/2)
85+ )
7886
7987 return SwipeCoords(start_x, end_x, start_y, end_y)
tests/autopilot/unity8/shell/emulators/main_window.py+7−1
@@ -38,11 +38,14 @@ class MainWindow(object):
3838 return self.app.select_single(Greeter)
3939
4040 def get_greeter_content_loader(self):
41− return self.app.select_single(
41+ return self.app.wait_select_single(
4242 "QQuickLoader",
4343 objectName="greeterContentLoader"
4444 )
4545
46+ def get_greeter_background(self):
47+ return self.app.select_single("CrossFadeImage", objectName="greeterBackground")
48+
4649 def get_login_loader(self):
4750 return self.app.select_single("QQuickLoader", objectName="loginLoader")
4851
@@ -93,3 +96,6 @@ class MainWindow(object):
9396
9497 def get_pinentryField(self):
9598 return self.app.select_single(objectName="pinentryField")
99+
100+ def get_shell_background(self):
101+ return self.app.select_single("CrossFadeImage", objectName="backgroundImage")
tests/autopilot/unity8/shell/tests/__init__.py+58−27
@@ -34,7 +34,7 @@ import logging
3434import os.path
3535import subprocess
3636import sys
37−from testtools.matchers import Equals, NotEquals
37+from testtools.matchers import Equals
3838
3939from unity8 import (
4040 get_lib_path,
@@ -53,7 +53,7 @@ logger = logging.getLogger(__name__)
5353UNITYSHELL_GSETTINGS_SCHEMA = "org.compiz.unityshell"
5454UNITYSHELL_GSETTINGS_PATH = "/org/compiz/profiles/unity/plugins/unityshell/"
5555UNITYSHELL_LAUNCHER_KEY = "launcher-hide-mode"
56−UNITYSHELL_LAUNCHER_MODE = 1 # launcher hidden
56+UNITYSHELL_LAUNCHER_MODE = 1 # launcher hidden
5757
5858
5959def _get_device_emulation_scenarios(devices='All'):
@@ -93,17 +93,25 @@ class UnityTestCase(AutopilotTestCase):
9393 ], stderr=subprocess.STDOUT)
9494 except subprocess.CalledProcessError, e:
9595 sys.stderr.write(
96− "Error: `initctl status unity8` failed, most probably the unity8 session could not be found:\n\n"
96+ "Error: `initctl status unity8` failed, most probably the "
97+ "unity8 session could not be found:\n\n"
9798 "{0}\n"
98− "Please install unity8 or copy data/unity8.conf to {1}\n".format(
99+ "Please install unity8 or copy data/unity8.conf to "
100+ "{1}\n".format(
99101 e.output,
100− os.path.join(os.getenv("XDG_CONFIG_HOME", os.path.join(os.getenv("HOME"), ".config")), "upstart")
101− ))
102+ os.path.join(os.getenv("XDG_CONFIG_HOME",
103+ os.path.join(os.getenv("HOME"),
104+ ".config")
105+ ),
106+ "upstart")
107+ )
108+ )
102109 sys.exit(1)
103110
104111 if "start/" in output:
105112 sys.stderr.write(
106− "Error: Unity is currently running, these tests require it to be 'stopped'.\n"
113+ "Error: Unity is currently running, these tests require it to "
114+ "be 'stopped'.\n"
107115 "Please run this command before running these tests: \n"
108116 "initctl stop unity8\n"
109117 )
@@ -111,11 +119,22 @@ class UnityTestCase(AutopilotTestCase):
111119
112120 def setUp(self):
113121 super(UnityTestCase, self).setUp()
114− if Gio is not None and UNITYSHELL_GSETTINGS_SCHEMA in Gio.Settings.list_relocatable_schemas():
122+ if (Gio is not None and
123+ UNITYSHELL_GSETTINGS_SCHEMA in
124+ Gio.Settings.list_relocatable_schemas()):
125+
115126 # Hide Unity launcher
116− self._unityshell_schema = Gio.Settings.new_with_path(UNITYSHELL_GSETTINGS_SCHEMA, UNITYSHELL_GSETTINGS_PATH)
117− self._launcher_hide_mode = self._unityshell_schema.get_int(UNITYSHELL_LAUNCHER_KEY)
118− self._unityshell_schema.set_int(UNITYSHELL_LAUNCHER_KEY, UNITYSHELL_LAUNCHER_MODE)
127+ self._unityshell_schema = Gio.Settings.new_with_path(
128+ UNITYSHELL_GSETTINGS_SCHEMA,
129+ UNITYSHELL_GSETTINGS_PATH,
130+ )
131+ self._launcher_hide_mode = self._unityshell_schema.get_int(
132+ UNITYSHELL_LAUNCHER_KEY,
133+ )
134+ self._unityshell_schema.set_int(
135+ UNITYSHELL_LAUNCHER_KEY,
136+ UNITYSHELL_LAUNCHER_MODE,
137+ )
119138 self.addCleanup(self._reset_launcher)
120139
121140 self._proxy = None
@@ -136,7 +155,10 @@ class UnityTestCase(AutopilotTestCase):
136155
137156 def _reset_launcher(self):
138157 """Reset Unity launcher hide mode"""
139− self._unityshell_schema.set_int(UNITYSHELL_LAUNCHER_KEY, self._launcher_hide_mode)
158+ self._unityshell_schema.set_int(
159+ UNITYSHELL_LAUNCHER_KEY,
160+ self._launcher_hide_mode,
161+ )
140162
141163 def _setup_display_details(self):
142164 scale_divisor = self._determine_geometry()
@@ -217,7 +239,10 @@ class UnityTestCase(AutopilotTestCase):
217239 def _upstart_reset_env(self, key, value):
218240 logger.info("Resetting upstart env %s to %s", key, value)
219241 if value is None:
220− subprocess.call(["/sbin/initctl", "unset-env", key], stderr=subprocess.STDOUT)
242+ subprocess.call(
243+ ["/sbin/initctl", "unset-env", key],
244+ stderr=subprocess.STDOUT,
245+ )
221246 else:
222247 subprocess.call([
223248 "/sbin/initctl",
@@ -244,9 +269,13 @@ class UnityTestCase(AutopilotTestCase):
244269 self._setup_extra_mock_environment_patch()
245270
246271 # FIXME: we shouldn't be doing this
247− # $MIR_SOCKET, fallback to $XDG_RUNTIME_DIR/mir_socket and /tmp/mir_socket as last resort
272+ # $MIR_SOCKET, fallback to $XDG_RUNTIME_DIR/mir_socket and
273+ # /tmp/mir_socket as last resort
248274 try:
249− os.unlink(os.getenv('MIR_SOCKET', os.path.join(os.getenv('XDG_RUNTIME_DIR', "/tmp"), "mir_socket")))
275+ os.unlink(
276+ os.getenv('MIR_SOCKET',
277+ os.path.join(os.getenv('XDG_RUNTIME_DIR', "/tmp"),
278+ "mir_socket")))
250279 except OSError:
251280 pass
252281 try:
@@ -256,7 +285,7 @@ class UnityTestCase(AutopilotTestCase):
256285
257286 app_proxy = self._launch_unity_with_upstart(
258287 binary_path,
259− self.unity_geometry_args
288+ self.unity_geometry_args,
260289 )
261290
262291 self._set_proxy(app_proxy)
@@ -275,14 +304,16 @@ class UnityTestCase(AutopilotTestCase):
275304 binary_arg = "BINARY=%s" % binary_path
276305 extra_args = "ARGS=%s" % " ".join(args)
277306
278− output = subprocess.check_output([
279− "/sbin/initctl",
280− "start",
281− "unity8",
282− binary_arg,
283− extra_args
284− ] + ["%s=%s" % (k,v) for k,v in self._environment.iteritems()],
285− stderr=subprocess.STDOUT)
307+ output = subprocess.check_output(
308+ [
309+ "/sbin/initctl",
310+ "start",
311+ "unity8",
312+ binary_arg,
313+ extra_args,
314+ ] + ["%s=%s" % (k, v) for k, v in self._environment.iteritems()],
315+ stderr=subprocess.STDOUT,
316+ )
286317
287318 self.addCleanup(self._cleanup_launching_upstart_unity)
288319
@@ -296,7 +327,8 @@ class UnityTestCase(AutopilotTestCase):
296327 def _cleanup_launching_upstart_unity(self):
297328 logger.info("Stopping unity")
298329 try:
299− subprocess.check_output(["/sbin/initctl", "stop", "unity8"], stderr=subprocess.STDOUT)
330+ subprocess.check_output(
331+ ["/sbin/initctl", "stop", "unity8"], stderr=subprocess.STDOUT)
300332 except subprocess.CalledProcessError:
301333 logger.warning("Appears unity was already stopped!")
302334
@@ -366,8 +398,7 @@ class UnityTestCase(AutopilotTestCase):
366398 self.assertThat(home_scope.isCurrent, Eventually(Equals(True)))
367399
368400 def get_dash(self):
369− dash = self._proxy.select_single(Dash)
370− self.assertThat(dash, NotEquals(None))
401+ dash = self._proxy.wait_select_single(Dash)
371402 return dash
372403
373404 @property
tests/autopilot/unity8/shell/tests/test_greeter.pynew file+38
@@ -0,0 +1,38 @@
1+# -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*-
2+#
3+# Unity Autopilot Test Suite
4+# Copyright (C) 2012-2013 Canonical
5+#
6+# This program is free software: you can redistribute it and/or modify
7+# it under the terms of the GNU General Public License as published by
8+# the Free Software Foundation, either version 3 of the License, or
9+# (at your option) any later version.
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+from unity8.shell.tests import UnityTestCase, _get_device_emulation_scenarios
21+
22+from testtools.matchers import Equals
23+
24+class TestGreeter(UnityTestCase):
25+
26+ """Tests the Shell Greeter."""
27+
28+ scenarios = _get_device_emulation_scenarios()
29+
30+ def test_greeter_background(self):
31+ """Test that the background of the greeter and the background of the shell are placed correctly
32+
33+ """
34+ self.launch_unity()
35+ self.main_window.get_greeter()
36+ greeter_background = self.main_window.get_greeter_background()
37+ shell_background = self.main_window.get_shell_background()
38+ self.assertThat(greeter_background.globalRect, Equals(shell_background.globalRect))
tests/autopilot/unity8/shell/tests/test_notifications.py+49−42
@@ -45,7 +45,7 @@ class NotificationsBase(UnityTestCase):
4545 """Given an icons file name returns the full path (either system or
4646 source tree.
4747
48− Consider the graphics directory as root so for example (runnign tests
48+ Consider the graphics directory as root so for example (running tests
4949 from installed unity8-autopilot package):
5050 >>> self.get_icon_path('clock.png')
5151 /usr/share/unity8/graphics/clock.png
@@ -145,8 +145,8 @@ class InteractiveNotificationBase(NotificationsBase):
145145 hints,
146146 )
147147
148− get_notification = lambda: notify_list.select_single('Notification', objectName='notification1')
149− self.assertThat(get_notification, Eventually(NotEquals(None)))
148+ get_notification = lambda: notify_list.wait_select_single(
149+ 'Notification', objectName='notification1')
150150 notification = get_notification()
151151
152152 self.touch.tap_object(
@@ -156,7 +156,8 @@ class InteractiveNotificationBase(NotificationsBase):
156156 self.assert_notification_action_id_was_called('action_id')
157157
158158 def test_sd_incoming_call(self):
159− """Rejecting a call should make notification expand and offer more options."""
159+ """Rejecting a call should make notification expand and
160+ offer more options."""
160161 self.launch_unity()
161162 greeter = self.main_window.get_greeter()
162163 greeter.swipe()
@@ -191,8 +192,8 @@ class InteractiveNotificationBase(NotificationsBase):
191192 hints
192193 )
193194
194− get_notification = lambda: notify_list.select_single('Notification', objectName='notification1')
195− self.assertThat(get_notification, Eventually(NotEquals(None)))
195+ get_notification = lambda: notify_list.wait_select_single(
196+ 'Notification', objectName='notification1')
196197 notification = get_notification()
197198 self._assert_notification(notification, None, None, True, True, 1.0)
198199 initial_height = notification.height
@@ -200,8 +201,10 @@ class InteractiveNotificationBase(NotificationsBase):
200201 self.assertThat(
201202 notification.height,
202203 Eventually(Equals(initial_height +
203− 3 * notification.select_single(objectName="buttonColumn").spacing +
204− 3 * notification.select_single(objectName="button4").height)))
204+ 3 * notification.select_single(
205+ objectName="buttonColumn").spacing +
206+ 3 * notification.select_single(
207+ objectName="button4").height)))
205208 self.touch.tap_object(notification.select_single(objectName="button4"))
206209 self.assert_notification_action_id_was_called("action_decline_4")
207210
@@ -360,13 +363,20 @@ class EphemeralNotificationsTests(NotificationsBase):
360363
361364 notification.show()
362365
363− get_notification = lambda: notify_list.select_single('Notification', objectName='notification1')
364− self.assertThat(get_notification, Eventually(NotEquals(None)))
365− notification = get_notification()
366− self._assert_notification(notification, summary, body, True, True, 1.0)
366+ notification = lambda: notify_list.wait_select_single(
367+ 'Notification', objectName='notification1')
368+ self._assert_notification(
369+ notification(),
370+ summary,
371+ body,
372+ True,
373+ True,
374+ 1.0,
375+ )
367376
368377 def test_icon_summary(self):
369− """Notification must display the expected summary and secondary icon."""
378+ """Notification must display the expected summary and secondary
379+ icon."""
370380 self.launch_unity()
371381 greeter = self.main_window.get_greeter()
372382 greeter.swipe()
@@ -391,11 +401,11 @@ class EphemeralNotificationsTests(NotificationsBase):
391401
392402 notification.show()
393403
394− get_notification = lambda: notify_list.select_single('Notification', objectName='notification1')
395− self.assertThat(get_notification, Eventually(NotEquals(None)))
396− notification = get_notification()
404+ notification = lambda: notify_list.wait_select_single(
405+ 'Notification', objectName='notification1')
406+
397407 self._assert_notification(
398− notification,
408+ notification(),
399409 summary,
400410 None,
401411 False,
@@ -404,7 +414,8 @@ class EphemeralNotificationsTests(NotificationsBase):
404414 )
405415
406416 def test_urgency_order(self):
407− """Notifications must be displayed in order according to their urgency."""
417+ """Notifications must be displayed in order according to their
418+ urgency."""
408419 self.launch_unity()
409420 greeter = self.main_window.get_greeter()
410421 greeter.swipe()
@@ -448,11 +459,10 @@ class EphemeralNotificationsTests(NotificationsBase):
448459 )
449460 notification_critical.show()
450461
451− get_notification = lambda: notify_list.select_single(
462+ get_notification = lambda: notify_list.wait_select_single(
452463 'Notification',
453464 summary=summary_critical
454465 )
455− self.assertThat(get_notification, Eventually(NotEquals(None)))
456466
457467 notification = get_notification()
458468 self._assert_notification(
@@ -464,11 +474,10 @@ class EphemeralNotificationsTests(NotificationsBase):
464474 1.0
465475 )
466476
467− get_normal_notification = lambda: notify_list.select_single(
477+ get_normal_notification = lambda: notify_list.wait_select_single(
468478 'Notification',
469479 summary=summary_normal
470480 )
471− self.assertThat(get_normal_notification, Eventually(NotEquals(None)))
472481 notification = get_normal_notification()
473482 self._assert_notification(
474483 notification,
@@ -479,11 +488,10 @@ class EphemeralNotificationsTests(NotificationsBase):
479488 1.0
480489 )
481490
482− get_low_notification = lambda: notify_list.select_single(
491+ get_low_notification = lambda: notify_list.wait_select_single(
483492 'Notification',
484493 summary=summary_low
485494 )
486− self.assertThat(get_low_notification, Eventually(NotEquals(None)))
487495 notification = get_low_notification()
488496 self._assert_notification(
489497 notification,
@@ -508,9 +516,8 @@ class EphemeralNotificationsTests(NotificationsBase):
508516 notification = self._create_ephemeral_notification(summary, body)
509517 notification.show()
510518
511− get_notification = lambda: notify_list.select_single('Notification', objectName='notification1')
512− self.assertThat(get_notification, Eventually(NotEquals(None)))
513− notification = get_notification()
519+ notification = notify_list.wait_select_single(
520+ 'Notification', objectName='notification1')
514521 self._assert_notification(
515522 notification,
516523 summary,
@@ -533,14 +540,14 @@ class EphemeralNotificationsTests(NotificationsBase):
533540 notification = self._create_ephemeral_notification(summary)
534541 notification.show()
535542
536− get_notification = lambda: notify_list.select_single('Notification', objectName='notification1')
537− self.assertThat(get_notification, Eventually(NotEquals(None)))
538− notification = get_notification()
543+ notification = notify_list.wait_select_single(
544+ 'Notification', objectName='notification1')
539545
540546 self._assert_notification(notification, summary, '', False, False, 1.0)
541547
542548 def test_update_notification_same_layout(self):
543− """Notification must allow updating its contents while being displayed."""
549+ """Notification must allow updating its contents while being
550+ displayed."""
544551 self.launch_unity()
545552 greeter = self.main_window.get_greeter()
546553 greeter.swipe()
@@ -558,8 +565,8 @@ class EphemeralNotificationsTests(NotificationsBase):
558565 )
559566 notification.show()
560567
561− get_notification = lambda: notify_list.select_single('Notification', summary=summary)
562− self.assertThat(get_notification, Eventually(NotEquals(None)))
568+ get_notification = lambda: notify_list.wait_select_single(
569+ 'Notification', summary=summary)
563570 self._assert_notification(
564571 get_notification(),
565572 summary,
@@ -575,11 +582,11 @@ class EphemeralNotificationsTests(NotificationsBase):
575582 icon_path = self._get_icon_path('avatars/amanda.png')
576583 notification.update(summary, body, icon_path)
577584 notification.show()
578− self.assertThat(get_notification, Eventually(NotEquals(None)))
579585 self._assert_notification(get_notification(), summary, body)
580586
581587 def test_update_notification_layout_change(self):
582− """Notification must allow updating its contents and layout while being displayed."""
588+ """Notification must allow updating its contents and layout while
589+ being displayed."""
583590 self.launch_unity()
584591 greeter = self.main_window.get_greeter()
585592 greeter.swipe()
@@ -603,8 +610,8 @@ class EphemeralNotificationsTests(NotificationsBase):
603610 )
604611 notification.show()
605612
606− get_notification = lambda: notify_list.select_single('Notification', objectName='notification1')
607− self.assertThat(get_notification, Eventually(NotEquals(None)))
613+ get_notification = lambda: notify_list.wait_select_single(
614+ 'Notification', objectName='notification1')
608615 self._assert_notification(
609616 get_notification(),
610617 summary,
@@ -645,8 +652,8 @@ class EphemeralNotificationsTests(NotificationsBase):
645652
646653 notification.show()
647654
648− get_notification = lambda: notify_list.select_single('Notification', objectName='notification1')
649− self.assertThat(get_notification, Eventually(NotEquals(None)))
655+ get_notification = lambda: notify_list.wait_select_single(
656+ 'Notification', objectName='notification1')
650657 notification = get_notification()
651658 self._assert_notification(
652659 notification,
@@ -662,7 +669,8 @@ class EphemeralNotificationsTests(NotificationsBase):
662669 'Did you watch the air-race in Oshkosh last week?',
663670 'Phil owned the place like no one before him!',
664671 'Did really everything in the race work according to regulations?',
665− 'Somehow I think to remember Burt Williams did cut corners and was not punished for this.',
672+ 'Somehow I think to remember Burt Williams did cut corners and '
673+ 'was not punished for this.',
666674 'Hopefully the referees will watch the videos of the race.',
667675 'Burt could get fined with US$ 50000 for that rule-violation :)'
668676 ]
@@ -677,11 +685,10 @@ class EphemeralNotificationsTests(NotificationsBase):
677685 hints=[('x-canonical-append', 'true')]
678686 )
679687 notification.show()
680− get_notification = lambda: notify_list.select_single(
688+ get_notification = lambda: notify_list.wait_select_single(
681689 'Notification',
682690 objectName='notification1'
683691 )
684− self.assertThat(get_notification, Eventually(NotEquals(None)))
685692 notification = get_notification()
686693 self._assert_notification(
687694 notification,
tests/plugins/Ubuntu/Gestures/DownwardsLauncher.qml+2−10
@@ -31,10 +31,7 @@ Item {
3131 y: followDragArea()
3232
3333 function followDragArea() {
34− if (dragArea.status === DirectionalDragArea.Rejected)
35− return -height
36− else
37− return dragArea.distance < height ? -height + dragArea.distance : 0
34+ return dragArea.distance < height ? -height + dragArea.distance : 0
3835 }
3936 }
4037
@@ -66,15 +63,10 @@ Item {
6663 dragAreaRect.opacity = 0.3
6764 launcher.y = Qt.binding(launcher.followDragArea)
6865 break;
69− case DirectionalDragArea.Recognized:
66+ defaut: // DirectionalDragArea.Recognized:
7067 dragAreaRect.color = "green"
7168 dragAreaRect.opacity = 0.5
7269 break;
73− default: //case DirectionalDragArea.Rejected:
74− dragAreaRect.color = "red"
75− dragAreaRect.opacity = 0.5
76− launcher.y = -launcher.height
77− break;
7870 }
7971 }
8072
tests/plugins/Ubuntu/Gestures/LeftwardsLauncher.qml+5−13
@@ -32,13 +32,10 @@ Item {
3232 y: 0
3333
3434 function followDragArea() {
35− if (dragArea.status === DirectionalDragArea.Rejected)
36− return root.width
37− else
38− return dragArea.distance > -width ?
39− root.width + dragArea.distance
40− :
41− root.width - width
35+ return dragArea.distance > -width ?
36+ root.width + dragArea.distance
37+ :
38+ root.width - width
4239 }
4340 }
4441
@@ -69,15 +66,10 @@ Item {
6966 dragAreaRect.opacity = 0.3
7067 launcher.x = Qt.binding(launcher.followDragArea)
7168 break;
72− case DirectionalDragArea.Recognized:
69+ default: //case DirectionalDragArea.Recognized:
7370 dragAreaRect.color = "green"
7471 dragAreaRect.opacity = 0.5
7572 break;
76− default: //case DirectionalDragArea.Rejected:
77− dragAreaRect.color = "red"
78− dragAreaRect.opacity = 0.5
79− launcher.x = -launcher.height
80− break;
8173 }
8274 }
8375
tests/plugins/Ubuntu/Gestures/RightwardsLauncher.qml+3−10
@@ -19,6 +19,7 @@ import Ubuntu.Gestures 0.1
1919import Ubuntu.Components 0.1
2020
2121Item {
22+ objectName: "rightwardsLauncher"
2223
2324 function reset() { launcher.x = -launcher.width }
2425
@@ -31,10 +32,7 @@ Item {
3132 y: 0
3233
3334 function followDragArea() {
34− if (dragArea.status === DirectionalDragArea.Rejected)
35− return -width
36− else
37− return dragArea.distance < width ? -width + dragArea.distance : 0
35+ return dragArea.distance < width ? -width + dragArea.distance : 0
3836 }
3937 }
4038
@@ -66,15 +64,10 @@ Item {
6664 dragAreaRect.opacity = 0.3
6765 launcher.x = Qt.binding(launcher.followDragArea)
6866 break;
69− case DirectionalDragArea.Recognized:
67+ default: //case DirectionalDragArea.Recognized:
7068 dragAreaRect.color = "green"
7169 dragAreaRect.opacity = 0.5
7270 break;
73− default: //case DirectionalDragArea.Rejected:
74− dragAreaRect.color = "red"
75− dragAreaRect.opacity = 0.5
76− launcher.x = -launcher.height
77− break;
7871 }
7972 }
8073
tests/plugins/Ubuntu/Gestures/UpwardsLauncher.qml+5−13
@@ -32,13 +32,10 @@ Item {
3232 y: root.height
3333
3434 function followDragArea() {
35− if (dragArea.status === DirectionalDragArea.Rejected)
36− return root.height
37− else
38− return dragArea.distance > -height ?
39− root.height + dragArea.distance
40− :
41− root.height - height
35+ return dragArea.distance > -height ?
36+ root.height + dragArea.distance
37+ :
38+ root.height - height
4239 }
4340 }
4441
@@ -69,15 +66,10 @@ Item {
6966 dragAreaRect.opacity = 0.3
7067 launcher.y = Qt.binding(launcher.followDragArea)
7168 break;
72− case DirectionalDragArea.Recognized:
69+ default: //case DirectionalDragArea.Recognized:
7370 dragAreaRect.color = "green"
7471 dragAreaRect.opacity = 0.5
7572 break;
76− default: //case DirectionalDragArea.Rejected:
77− dragAreaRect.color = "red"
78− dragAreaRect.opacity = 0.5
79− launcher.y = -launcher.height
80− break;
8173 }
8274 }
8375
tests/plugins/Ubuntu/Gestures/edgeDragExample.qml+7−1
@@ -33,7 +33,13 @@ Rectangle {
3333 }
3434 }
3535
36− RightwardsLauncher { id: hpLauncher; anchors.fill: parent }
36+ // NB: Do not anchor it as we will move it programmatically from the test
37+ RightwardsLauncher {
38+ id: hpLauncher;
39+ width: parent.width
40+ height: parent.height
41+ }
42+
3743 LeftwardsLauncher { id: hnLauncher; anchors.fill: parent }
3844 DownwardsLauncher { id: vpLauncher; anchors.fill: parent }
3945 UpwardsLauncher { id: vnLauncher; anchors.fill: parent }
tests/plugins/Ubuntu/Gestures/tst_AxisVelocityCalculator.cpp+3−3
@@ -54,12 +54,12 @@ private Q_SLOTS:
5454
5555private:
5656 AxisVelocityCalculator *velCalc;
57− FakeTimeSource *fakeTimeSource;
57+ QSharedPointer<FakeTimeSource> fakeTimeSource;
5858};
5959
6060void tst_AxisVelocityCalculator::init()
6161{
62− fakeTimeSource = new FakeTimeSource;
62+ fakeTimeSource.reset(new FakeTimeSource);
6363
6464 velCalc = new AxisVelocityCalculator;
6565 velCalc->setTimeSource(fakeTimeSource);
@@ -68,7 +68,7 @@ void tst_AxisVelocityCalculator::init()
6868void tst_AxisVelocityCalculator::cleanup()
6969{
7070 delete velCalc;
71− delete fakeTimeSource;
71+ fakeTimeSource.reset();
7272}
7373
7474void tst_AxisVelocityCalculator::simpleSamples()
tests/plugins/Ubuntu/Gestures/tst_DirectionalDragArea.cpp+285−96
@@ -19,23 +19,38 @@
1919#include <qpa/qwindowsysteminterface.h>
2020#include <QtQuick/QQuickView>
2121#include <QtQml/QQmlEngine>
22+#include <QPointer>
2223
2324#include <DirectionalDragArea.h>
2425
25−class FakeTimer : public UbuntuGestures::AbstractTimer
26+using namespace UbuntuGestures;
27+
28+class FakeTimer : public AbstractTimer
2629{
2730 Q_OBJECT
2831public:
29− FakeTimer(QObject *parent = 0)
30− : UbuntuGestures::AbstractTimer(parent)
32+ FakeTimer(const SharedTimeSource &timeSource, QObject *parent = 0)
33+ : UbuntuGestures::AbstractTimer(parent),
34+ m_timeSource(timeSource)
3135 {}
3236
33− virtual int interval() const { return m_duration; }
34− virtual void setInterval(int msecs) { m_duration = msecs; }
37+ int interval() const override { return m_interval; }
38+ void setInterval(int msecs) override { m_interval = msecs; }
39+ void start() override {
40+ AbstractTimer::start();
41+ m_nextTimeoutTime = m_timeSource->msecsSinceReference() + (qint64)m_interval;
42+ }
43+
44+ void emitTimeout() {
45+ m_nextTimeoutTime += m_interval;
46+ Q_EMIT timeout();
47+ }
3548
36− void emitTimeout() {Q_EMIT timeout();}
49+ qint64 nextTimeoutTime() const { return m_nextTimeoutTime; }
3750private:
38− int m_duration;
51+ int m_interval;
52+ SharedTimeSource m_timeSource;
53+ qint64 m_nextTimeoutTime;
3954};
4055
4156class FakeTimeSource : public UbuntuGestures::TimeSource
@@ -67,14 +82,17 @@ private Q_SLOTS:
6782 void maxSilenceTime();
6883 void sceneXAndX();
6984 void sceneYAndY();
70− void emitDraggingChangedOnDirectRecognition();
85+ void twoFingerTap();
86+ void movingDDA();
87+ void ignoreOldFinger();
7188
7289private:
7390 QQuickView *createView();
91+ void passTime(qint64 timeSpan);
7492 QQuickView *view;
7593 QTouchDevice *device;
7694 FakeTimer *fakeTimer;
77− FakeTimeSource *fakeTimeSource;
95+ QSharedPointer<FakeTimeSource> fakeTimeSource;
7896};
7997
8098void tst_DirectionalDragArea::initTestCase()
@@ -101,8 +119,8 @@ void tst_DirectionalDragArea::init()
101119 QVERIFY(view->rootObject() != 0);
102120 qApp->processEvents();
103121
104− fakeTimer = new FakeTimer;
105− fakeTimeSource = new FakeTimeSource;
122+ fakeTimeSource.reset(new FakeTimeSource);
123+ fakeTimer = new FakeTimer(fakeTimeSource);
106124}
107125
108126void tst_DirectionalDragArea::cleanup()
@@ -113,8 +131,7 @@ void tst_DirectionalDragArea::cleanup()
113131 delete fakeTimer;
114132 fakeTimer = 0;
115133
116− delete fakeTimeSource;
117− fakeTimeSource = 0;
134+ fakeTimeSource.reset();
118135}
119136
120137QQuickView *tst_DirectionalDragArea::createView()
@@ -127,6 +144,23 @@ QQuickView *tst_DirectionalDragArea::createView()
127144 return window;
128145}
129146
147+void tst_DirectionalDragArea::passTime(qint64 timeSpan)
148+{
149+ qint64 finalTime = fakeTimeSource->m_msecsSinceReference + timeSpan;
150+
151+ if (fakeTimer->isRunning() && finalTime >= fakeTimer->nextTimeoutTime()) {
152+ fakeTimeSource->m_msecsSinceReference = fakeTimer->nextTimeoutTime();
153+ fakeTimer->emitTimeout();
154+
155+ qint64 timeSpanRemainder = finalTime - fakeTimeSource->m_msecsSinceReference;
156+ if (timeSpanRemainder > 0) {
157+ passTime(timeSpanRemainder);
158+ }
159+ } else {
160+ fakeTimeSource->m_msecsSinceReference = finalTime;
161+ }
162+}
163+
130164namespace {
131165QPointF calculateInitialTouchPos(DirectionalDragArea *edgeDragArea, QQuickView *view)
132166{
@@ -180,7 +214,7 @@ void tst_DirectionalDragArea::edgeDrag()
180214 QFETCH(QString, dragAreaObjectName);
181215 QFETCH(qreal, wideningAngleMultiplier);
182216 QFETCH(qreal, dragDistanceFactor);
183− QFETCH(int, expectedGestureRecognition);
217+ QFETCH(bool, expectGestureRecognition);
184218
185219 DirectionalDragArea *edgeDragArea =
186220 view->rootObject()->findChild<DirectionalDragArea*>(dragAreaObjectName);
@@ -196,7 +230,10 @@ void tst_DirectionalDragArea::edgeDrag()
196230 qreal desiredDragDistance = edgeDragArea->distanceThreshold()*dragDistanceFactor;
197231 QPointF dragDirectionVector = calculateDirectionVector(edgeDragArea,
198232 wideningAngleMultiplier);
199− QPointF touchMovement = dragDirectionVector * (edgeDragArea->distanceThreshold() * 0.1f);
233+ qreal movementStepDistance = edgeDragArea->distanceThreshold() * 0.1f;
234+ QPointF touchMovement = dragDirectionVector * movementStepDistance;
235+ int totalMovementSteps = qCeil(desiredDragDistance / movementStepDistance);
236+ int movementTimeStepMs = (edgeDragArea->compositionTime() * 1.5f) / totalMovementSteps;
200237
201238 QTest::touchEvent(view, device).press(0, touchPoint.toPoint());
202239
@@ -211,15 +248,16 @@ void tst_DirectionalDragArea::edgeDrag()
211248 QTest::touchEvent(view, device).move(0, touchPoint.toPoint());
212249 }
213250
214− do {
251+ for (int i = 0; i < totalMovementSteps; ++i) {
215252 touchPoint += touchMovement;
253+ passTime(movementTimeStepMs);
216254 QTest::touchEvent(view, device).move(0, touchPoint.toPoint());
217− } while ((touchPoint - initialTouchPos).manhattanLength() < desiredDragDistance);
255+ }
218256
219− if (expectedGestureRecognition)
257+ if (expectGestureRecognition)
220258 QCOMPARE((int)edgeDragArea->status(), (int)DirectionalDragArea::Recognized);
221259
222− if (edgeDragArea->status() == DirectionalDragArea::Rejected) {
260+ if (edgeDragArea->status() == DirectionalDragArea::WaitingForTouch) {
223261 QCOMPARE(edgeDragArea->dragging(), false);
224262 QCOMPARE(draggingSpy.count(), 2);
225263 }
@@ -235,49 +273,49 @@ void tst_DirectionalDragArea::edgeDrag_data()
235273 QTest::addColumn<QString>("dragAreaObjectName");
236274 QTest::addColumn<qreal>("wideningAngleMultiplier");
237275 QTest::addColumn<qreal>("dragDistanceFactor");
238− QTest::addColumn<int>("expectedGestureRecognition");
276+ QTest::addColumn<bool>("expectGestureRecognition");
239277
240278 QTest::newRow("rightwards, tiny drag")
241− << "hpDragArea" << 0.0 << 0.2 << 0;
279+ << "hpDragArea" << 0.0 << 0.2 << false;
242280
243281 QTest::newRow("rightwards, straight drag")
244− << "hpDragArea" << 0.0 << 3.0 << 1;
282+ << "hpDragArea" << 0.0 << 3.0 << true;
245283
246284 QTest::newRow("rightwards, diagonal drag")
247− << "hpDragArea" << 0.9 << 3.0 << 1;
285+ << "hpDragArea" << 0.9 << 3.0 << true;
248286
249287 QTest::newRow("rightwards, overly diagonal drag")
250− << "hpDragArea" << 2.0 << 3.0 << 0;
288+ << "hpDragArea" << 2.0 << 3.0 << false;
251289
252290 QTest::newRow("leftwards, tiny drag")
253− << "hnDragArea" << 0.0 << 0.2 << 0;
291+ << "hnDragArea" << 0.0 << 0.2 << false;
254292
255293 QTest::newRow("leftwards, straight drag")
256− << "hnDragArea" << 0.0 << 3.0 << 1;
294+ << "hnDragArea" << 0.0 << 3.0 << true;
257295
258296 QTest::newRow("leftwards, diagonal drag")
259− << "hnDragArea" << 0.9 << 3.0 << 1;
297+ << "hnDragArea" << 0.9 << 3.0 << true;
260298
261299 QTest::newRow("downwards, tiny drag")
262− << "vpDragArea" << 0.0 << 0.2 << 0;
300+ << "vpDragArea" << 0.0 << 0.2 << false;
263301
264302 QTest::newRow("downwards, straight drag")
265− << "vpDragArea" << 0.0 << 3.0 << 1;
303+ << "vpDragArea" << 0.0 << 3.0 << true;
266304
267305 QTest::newRow("downwards, diagonal drag")
268− << "vpDragArea" << 0.9 << 3.0 << 1;
306+ << "vpDragArea" << 0.9 << 3.0 << true;
269307
270308 QTest::newRow("upwards, tiny drag")
271− << "vnDragArea" << 0.0 << 0.2 << 0;
309+ << "vnDragArea" << 0.0 << 0.2 << false;
272310
273311 QTest::newRow("upwards, straight drag")
274− << "vnDragArea" << 0.0 << 3.0 << 1;
312+ << "vnDragArea" << 0.0 << 3.0 << true;
275313
276314 QTest::newRow("upwards, diagonal drag")
277− << "vnDragArea" << 0.9 << 3.0 << 1;
315+ << "vnDragArea" << 0.9 << 3.0 << true;
278316
279317 QTest::newRow("upwards, overly diagonal drag")
280− << "vnDragArea" << 2.0 << 3.0 << 0;
318+ << "vnDragArea" << 2.0 << 3.0 << false;
281319}
282320
283321/*
@@ -298,25 +336,33 @@ void tst_DirectionalDragArea::dragWithShortDirectionChange()
298336
299337 qreal desiredDragDistance = edgeDragArea->distanceThreshold()*2.0;
300338 QPointF dragDirectionVector(1.0, 0.0);
301− QPointF touchMovement = dragDirectionVector * (edgeDragArea->distanceThreshold() * 0.1f);
339+ qreal touchStepDistance = edgeDragArea->distanceThreshold() * 0.1f;
340+ // make sure we are above minimum speed
341+ int touchStepTimeMs = (touchStepDistance / (edgeDragArea->minSpeed() * 5.0f)) * 1000.0f;
342+ QPointF touchMovement = dragDirectionVector * touchStepDistance;
302343
303344 QTest::touchEvent(view, device).press(0, touchPoint.toPoint());
304345
305346 // Move a bit in the proper direction
306347 for (int i=0; i < 3; ++i) {
307348 touchPoint += touchMovement;
349+ passTime(touchStepTimeMs);
308350 QTest::touchEvent(view, device).move(0, touchPoint.toPoint());
309351 }
310352
311353 // Then a sudden and small movement to the opposite direction
312− touchPoint -= dragDirectionVector * (edgeDragArea->maxDeviation() * 0.7);
354+ touchPoint -= touchMovement*0.2;
355+ passTime(touchStepTimeMs*0.2);
313356 QTest::touchEvent(view, device).move(0, touchPoint.toPoint());
314357
315− // And then resume movment in the correct direction until it crosses the distance threshold.
358+ // And then resume movment in the correct direction until it crosses the distance and time
359+ // thresholds.
316360 do {
317361 touchPoint += touchMovement;
362+ passTime(touchStepTimeMs);
318363 QTest::touchEvent(view, device).move(0, touchPoint.toPoint());
319− } while ((touchPoint - initialTouchPos).manhattanLength() < desiredDragDistance);
364+ } while ((touchPoint - initialTouchPos).manhattanLength() < desiredDragDistance
365+ || fakeTimeSource->m_msecsSinceReference < (edgeDragArea->compositionTime() * 1.5f));
320366
321367 QCOMPARE((int)edgeDragArea->status(), (int)DirectionalDragArea::Recognized);
322368
@@ -329,7 +375,8 @@ void tst_DirectionalDragArea::dragWithShortDirectionChange()
329375 */
330376void tst_DirectionalDragArea::minSpeed()
331377{
332− QFETCH(int, minSpeedMsecsDeviation);
378+ QFETCH(qreal, minSpeed);
379+ QFETCH(qreal, speed);
333380 QFETCH(int, expectedStatusAfterSpeedCheck);
334381
335382 DirectionalDragArea *edgeDragArea =
@@ -338,44 +385,40 @@ void tst_DirectionalDragArea::minSpeed()
338385 edgeDragArea->setRecognitionTimer(fakeTimer);
339386 edgeDragArea->setTimeSource(fakeTimeSource);
340387
388+ // A really long, unattainable, number. We don't want it getting recognized before
389+ // the speed checks we want have been performed
390+ edgeDragArea->setDistanceThreshold(500000);
391+
392+ edgeDragArea->setMinSpeed(minSpeed);
393+
341394 QPointF initialTouchPos = calculateInitialTouchPos(edgeDragArea, view);
342395 QPointF touchPoint = initialTouchPos;
343396
344397 QPointF dragDirectionVector(1.0, 0.0);
345− qreal distanceStep = edgeDragArea->distanceThreshold() * 0.1f;
398+ qint64 timeStepMsecs = 10;
399+ qreal distanceStep = (speed / 1000.0f) * timeStepMsecs;
346400 QPointF touchMovement = dragDirectionVector * distanceStep;
347− qreal minSpeedMsecs = edgeDragArea->minSpeed() / 1000.0;
348− qint64 timeStepMsecs = qFloor(distanceStep / minSpeedMsecs) + minSpeedMsecsDeviation;
349401
350− // if it fails it means the params set in the QML file are not in harmony with the values
351− // used in this test
352− Q_ASSERT(timeStepMsecs > 0);
353−
354− fakeTimeSource->m_msecsSinceReference = 0;
355402 QTest::touchEvent(view, device).press(0, touchPoint.toPoint());
356403
357− // Move a bit in the proper direction
358− for (int i=0; i < 4; ++i) {
404+ // Move for a while to ensure our speed check is performed a couple of times
405+ for (int i=0; i < 20; ++i) {
359406 touchPoint += touchMovement;
360− fakeTimeSource->m_msecsSinceReference += timeStepMsecs;
407+ passTime(timeStepMsecs);
361408 QTest::touchEvent(view, device).move(0, touchPoint.toPoint());
362409 }
363410
364− QCOMPARE((int)edgeDragArea->status(), (int)DirectionalDragArea::Undecided);
365−
366− // Force the periodic speed check.
367− fakeTimer->emitTimeout();
368−
369411 QCOMPARE((int)edgeDragArea->status(), expectedStatusAfterSpeedCheck);
370412}
371413
372414void tst_DirectionalDragArea::minSpeed_data()
373415{
374− QTest::addColumn<int>("minSpeedMsecsDeviation");
416+ QTest::addColumn<qreal>("minSpeed");
417+ QTest::addColumn<qreal>("speed");
375418 QTest::addColumn<int>("expectedStatusAfterSpeedCheck");
376419
377− QTest::newRow("slower than minSpeed") << 20 << (int)DirectionalDragArea::Rejected;
378− QTest::newRow("faster than minSpeed") << -20 << (int)DirectionalDragArea::Undecided;
420+ QTest::newRow("slower than minSpeed") << 100.0 << 50.0 << (int)DirectionalDragArea::WaitingForTouch;
421+ QTest::newRow("faster than minSpeed") << 100.0 << 150.0 << (int)DirectionalDragArea::Undecided;
379422}
380423
381424/*
@@ -391,32 +434,37 @@ void tst_DirectionalDragArea::recognitionTimerUsage()
391434 edgeDragArea->setRecognitionTimer(fakeTimer);
392435 edgeDragArea->setTimeSource(fakeTimeSource);
393436
437+ // don't let it interfere with our test
438+ edgeDragArea->setMinSpeed(0.0);
439+
440+ int timeStepMs = 5; // some arbitrary small value.
441+
394442 QPointF initialTouchPos = calculateInitialTouchPos(edgeDragArea, view);
395443 QPointF touchPoint = initialTouchPos;
396444
397445 QPointF dragDirectionVector(1.0, 0.0);
398446 QPointF touchMovement = dragDirectionVector * (edgeDragArea->distanceThreshold() * 0.2f);
399447
448+ QCOMPARE((int)edgeDragArea->status(), (int)DirectionalDragArea::WaitingForTouch);
400449 QVERIFY(!fakeTimer->isRunning());
401450
402451 QTest::touchEvent(view, device).press(0, touchPoint.toPoint());
403452
453+ QCOMPARE((int)edgeDragArea->status(), (int)DirectionalDragArea::Undecided);
404454 QVERIFY(fakeTimer->isRunning());
405455
406− // Move a bit in the proper direction
407− for (int i=0; i < 3; ++i) {
456+ // Move beyond distance threshold and composition time to ensure recognition
457+ while (fakeTimeSource->m_msecsSinceReference <= edgeDragArea->compositionTime() ||
458+ (touchPoint - initialTouchPos).manhattanLength() <= edgeDragArea->distanceThreshold()) {
459+
460+ QCOMPARE(edgeDragArea->status() == DirectionalDragArea::Undecided, fakeTimer->isRunning());
461+
408462 touchPoint += touchMovement;
463+ passTime(timeStepMs);
409464 QTest::touchEvent(view, device).move(0, touchPoint.toPoint());
410465 }
411466
412− QVERIFY(fakeTimer->isRunning());
413−
414− // Move beyond distance threshold
415− touchPoint += 3*touchMovement;
416− QTest::touchEvent(view, device).move(0, touchPoint.toPoint());
417−
418467 QCOMPARE((int)edgeDragArea->status(), (int)DirectionalDragArea::Recognized);
419−
420468 QVERIFY(!fakeTimer->isRunning());
421469}
422470
@@ -432,29 +480,23 @@ void tst_DirectionalDragArea::maxSilenceTime()
432480 edgeDragArea->setRecognitionTimer(fakeTimer);
433481 edgeDragArea->setTimeSource(fakeTimeSource);
434482
483+ // Make sure this property is not disabled
484+ edgeDragArea->setMaxSilenceTime(100);
485+
435486 QPointF initialTouchPos = calculateInitialTouchPos(edgeDragArea, view);
436487 QPointF touchPoint = initialTouchPos;
437488
438− fakeTimeSource->m_msecsSinceReference = 0;
439489 QTest::touchEvent(view, device).press(0, touchPoint.toPoint());
440490
441491 QCOMPARE((int)edgeDragArea->status(), (int)DirectionalDragArea::Undecided);
492+ QVERIFY(fakeTimer->isRunning());
442493
443− int neededTimeouts = qCeil((qreal)edgeDragArea->maxSilenceTime() / (qreal)fakeTimer->interval());
444− if ((edgeDragArea->maxSilenceTime() % fakeTimer->interval()) == 0) {
445− ++neededTimeouts;
446− }
447−
448− // Force the periodic speed check.
449− for (int i = 0; i < neededTimeouts; ++i) {
450− fakeTimer->emitTimeout();
451−
452− if (i < neededTimeouts - 1) {
453− QCOMPARE((int)edgeDragArea->status(), (int)DirectionalDragArea::Undecided);
454− }
494+ // Force timer to timeout until after maxSilenceTime has been reached
495+ while (fakeTimeSource->m_msecsSinceReference < edgeDragArea->maxSilenceTime()) {
496+ passTime(fakeTimer->interval());
455497 }
456498
457− QCOMPARE((int)edgeDragArea->status(), (int)DirectionalDragArea::Rejected);
499+ QCOMPARE((int)edgeDragArea->status(), (int)DirectionalDragArea::WaitingForTouch);
458500}
459501
460502/*
@@ -471,7 +513,6 @@ void tst_DirectionalDragArea::sceneXAndX()
471513
472514 QPointF touchScenePos(view->width() - (edgeDragArea->width()/2.0f), view->height()/2.0f);
473515
474− fakeTimeSource->m_msecsSinceReference = 0;
475516 QTest::touchEvent(view, device).press(0, touchScenePos.toPoint());
476517
477518 QSignalSpy touchXSpy(edgeDragArea, SIGNAL(touchXChanged(qreal)));
@@ -500,7 +541,6 @@ void tst_DirectionalDragArea::sceneYAndY()
500541
501542 QPointF touchScenePos(view->width()/2.0f, view->height() - (edgeDragArea->height()/2.0f));
502543
503− fakeTimeSource->m_msecsSinceReference = 0;
504544 QTest::touchEvent(view, device).press(0, touchScenePos.toPoint());
505545
506546 QSignalSpy touchYSpy(edgeDragArea, SIGNAL(touchYChanged(qreal)));
@@ -516,11 +556,12 @@ void tst_DirectionalDragArea::sceneYAndY()
516556}
517557
518558/*
519− Emit draggingChanged() when status change from WaitingForTouch directly to Recognized.
520− This happens when the gesture recognition is effectively disabled (e.g. by setting a
521− distanceThreshold of zero)
559+ Regression test for https://bugs.launchpad.net/bugs/1228336
560+
561+ Perform a quick two-finger double-tap and check that DirectionalDragArea properly
562+ rejects those touch points. In the bug above it got confused and crashed.
522563 */
523−void tst_DirectionalDragArea::emitDraggingChangedOnDirectRecognition()
564+void tst_DirectionalDragArea::twoFingerTap()
524565{
525566 DirectionalDragArea *edgeDragArea =
526567 view->rootObject()->findChild<DirectionalDragArea*>("hpDragArea");
@@ -528,22 +569,170 @@ void tst_DirectionalDragArea::emitDraggingChangedOnDirectRecognition()
528569 edgeDragArea->setRecognitionTimer(fakeTimer);
529570 edgeDragArea->setTimeSource(fakeTimeSource);
530571
531− QPointF touchPos = calculateInitialTouchPos(edgeDragArea, view);
572+ // Make touches evenly spaced along the edgeDragArea
573+ QPoint touchAPos(edgeDragArea->width()/2.0f, view->height()*0.33f);
574+ QPoint touchBPos(edgeDragArea->width()/2.0f, view->height()*0.66f);
532575
533− QSignalSpy draggingSpy(edgeDragArea, SIGNAL(draggingChanged(bool)));
576+ qint64 timeStepMsecs = 5; // some arbitrary, small value
534577
535− // That will make it completetly skip the recognition phase ("Undecided" status).
536− edgeDragArea->setDistanceThreshold(0.0);
578+ // Perform the first two-finger tap
579+ // NB: using move() instead of stationary() becasue in the latter you cannot provide
580+ // the touch position and therefore it's left with some garbage numbers.
581+ QTest::touchEvent(view, device)
582+ .press(0, touchAPos);
537583
584+ QCOMPARE((int)edgeDragArea->status(), (int)DirectionalDragArea::Undecided);
585+
586+ passTime(timeStepMsecs);
587+ QTest::touchEvent(view, device)
588+ .move(0, touchAPos)
589+ .press(1, touchBPos);
590+
591+ // A second touch point appeared during recognition, reject immediately as this
592+ // can't be a single-touch gesture anymore.
538593 QCOMPARE((int)edgeDragArea->status(), (int)DirectionalDragArea::WaitingForTouch);
539− QCOMPARE(edgeDragArea->dragging(), false);
540594
541− fakeTimeSource->m_msecsSinceReference = 0;
542− QTest::touchEvent(view, device).press(0, touchPos.toPoint());
595+ passTime(timeStepMsecs);
596+ QTest::touchEvent(view, device)
597+ .release(0, touchAPos)
598+ .move(1, touchBPos);
599+
600+ QCOMPARE((int)edgeDragArea->status(), (int)DirectionalDragArea::WaitingForTouch);
601+
602+ passTime(timeStepMsecs);
603+ QTest::touchEvent(view, device)
604+ .release(1, touchBPos);
605+
606+ QCOMPARE((int)edgeDragArea->status(), (int)DirectionalDragArea::WaitingForTouch);
607+
608+ // Perform the second two-finger tap
609+
610+ passTime(timeStepMsecs);
611+ QTest::touchEvent(view, device)
612+ .press(0, touchAPos);
613+
614+ QCOMPARE((int)edgeDragArea->status(), (int)DirectionalDragArea::Undecided);
615+
616+ passTime(timeStepMsecs);
617+ QTest::touchEvent(view, device)
618+ .move(0, touchAPos)
619+ .press(1, touchBPos);
620+
621+ QCOMPARE((int)edgeDragArea->status(), (int)DirectionalDragArea::WaitingForTouch);
622+
623+ passTime(timeStepMsecs);
624+ QTest::touchEvent(view, device)
625+ .release(0, touchAPos)
626+ .move(1, touchBPos);
627+
628+ QCOMPARE((int)edgeDragArea->status(), (int)DirectionalDragArea::WaitingForTouch);
629+
630+ passTime(timeStepMsecs);
631+ QTest::touchEvent(view, device)
632+ .release(1, touchBPos);
633+
634+ QCOMPARE((int)edgeDragArea->status(), (int)DirectionalDragArea::WaitingForTouch);
635+}
636+
637+/*
638+ Tests that gesture recognition works normally even if the DirectionalDragArea moves
639+ during recognition.
640+ This effectively means that we have to do gesture recognition with scene coordinates
641+ instead of local item coordinates.
642+ */
643+void tst_DirectionalDragArea::movingDDA()
644+{
645+ QQuickItem *rightwardsLauncher = view->rootObject()->findChild<QQuickItem*>("rightwardsLauncher");
646+ Q_ASSERT(rightwardsLauncher != 0);
647+
648+ DirectionalDragArea *edgeDragArea =
649+ rightwardsLauncher->findChild<DirectionalDragArea*>("hpDragArea");
650+ Q_ASSERT(edgeDragArea != 0);
651+ edgeDragArea->setRecognitionTimer(fakeTimer);
652+ edgeDragArea->setTimeSource(fakeTimeSource);
653+
654+ QPointF initialTouchPos = calculateInitialTouchPos(edgeDragArea, view);
655+ QPointF touchPoint = initialTouchPos;
656+
657+ qreal desiredDragDistance = edgeDragArea->distanceThreshold()*2.0f;
658+ QPointF dragDirectionVector(1.0f, 0.0f);
659+
660+ qreal movementStepDistance = edgeDragArea->distanceThreshold() * 0.1f;
661+ QPointF touchMovement = dragDirectionVector * movementStepDistance;
662+ int totalMovementSteps = qCeil(desiredDragDistance / movementStepDistance);
663+ int movementTimeStepMs = (edgeDragArea->compositionTime() * 1.5f) / totalMovementSteps;
664+
665+ QTest::touchEvent(view, device).press(0, touchPoint.toPoint());
666+
667+ // Move it far ahead along the direction of the gesture
668+ // rightwardsLauncher is a parent of our DirectionalDragArea. So moving it will move our DDA
669+ rightwardsLauncher->setX(rightwardsLauncher->x() + edgeDragArea->distanceThreshold() * 5.0f);
670+
671+ for (int i = 0; i < totalMovementSteps; ++i) {
672+ touchPoint += touchMovement;
673+ passTime(movementTimeStepMs);
674+ QTest::touchEvent(view, device).move(0, touchPoint.toPoint());
675+ }
543676
544677 QCOMPARE((int)edgeDragArea->status(), (int)DirectionalDragArea::Recognized);
545− QCOMPARE(draggingSpy.count(), 1);
546− QCOMPARE(edgeDragArea->dragging(), true);
678+
679+ QTest::touchEvent(view, device).release(0, touchPoint.toPoint());
680+}
681+
682+/*
683+ The presence of and old, rejected, touch point lying on the DirectionalDragArea
684+ shouldn't impede the recognition of a gesture from a new touch point.
685+ */
686+void tst_DirectionalDragArea::ignoreOldFinger()
687+{
688+ DirectionalDragArea *edgeDragArea =
689+ view->rootObject()->findChild<DirectionalDragArea*>("hpDragArea");
690+ Q_ASSERT(edgeDragArea != 0);
691+ edgeDragArea->setRecognitionTimer(fakeTimer);
692+ edgeDragArea->setTimeSource(fakeTimeSource);
693+
694+ // Make touches evenly spaced along the edgeDragArea
695+ QPoint touch0Pos(edgeDragArea->width()/2.0f, view->height()*0.33f);
696+ QPoint touch1Pos(edgeDragArea->width()/2.0f, view->height()*0.66f);
697+
698+ QTest::touchEvent(view, device).press(0, touch0Pos);
699+
700+ QCOMPARE((int)edgeDragArea->status(), (int)DirectionalDragArea::Undecided);
701+
702+ // leave it lying around for some time
703+ passTime(qMax(edgeDragArea->maxSilenceTime(), edgeDragArea->compositionTime()) * 10);
704+
705+ QCOMPARE((int)edgeDragArea->status(), (int)DirectionalDragArea::WaitingForTouch);
706+
707+ qreal desiredDragDistance = edgeDragArea->distanceThreshold()*2.0f;
708+ QPointF dragDirectionVector(1.0f, 0.0f);
709+
710+ qreal movementStepDistance = edgeDragArea->distanceThreshold() * 0.1f;
711+ QPointF touchMovement = dragDirectionVector * movementStepDistance;
712+ int totalMovementSteps = qCeil(desiredDragDistance / movementStepDistance);
713+ int movementTimeStepMs = (edgeDragArea->compositionTime() * 1.5f) / totalMovementSteps;
714+
715+ QTest::touchEvent(view, device)
716+ .move(0, touch0Pos)
717+ .press(1, touch1Pos);
718+
719+ QCOMPARE((int)edgeDragArea->status(), (int)DirectionalDragArea::Undecided);
720+
721+ for (int i = 0; i < totalMovementSteps; ++i) {
722+ touch1Pos += touchMovement.toPoint();
723+ passTime(movementTimeStepMs);
724+ QTest::touchEvent(view, device)
725+ .move(0, touch0Pos)
726+ .move(1, touch1Pos);
727+ }
728+
729+ QCOMPARE((int)edgeDragArea->status(), (int)DirectionalDragArea::Recognized);
730+
731+ QTest::touchEvent(view, device)
732+ .move(0, touch0Pos)
733+ .release(1, touch1Pos);
734+
735+ QCOMPARE((int)edgeDragArea->status(), (int)DirectionalDragArea::WaitingForTouch);
547736}
548737
549738QTEST_MAIN(tst_DirectionalDragArea)
tests/qmltests/Components/tst_DragHandle.cpp+4−5
@@ -41,7 +41,7 @@ class FakeTimeSource : public UbuntuGestures::TimeSource
4141{
4242public:
4343 FakeTimeSource() { m_msecsSinceReference = 0; }
44− virtual qint64 msecsSinceReference() {return m_msecsSinceReference;}
44+ qint64 msecsSinceReference() override {return m_msecsSinceReference;}
4545 qint64 m_msecsSinceReference;
4646};
4747
@@ -73,7 +73,7 @@ private:
7373 QQuickView *m_view;
7474 QTouchDevice *m_device;
7575 FakeTimer *m_fakeTimer;
76− FakeTimeSource *m_fakeTimeSource;
76+ QSharedPointer<FakeTimeSource> m_fakeTimeSource;
7777};
7878
7979
@@ -102,7 +102,7 @@ void tst_DragHandle::init()
102102 qApp->processEvents();
103103
104104 m_fakeTimer = new FakeTimer;
105− m_fakeTimeSource = new FakeTimeSource;
105+ m_fakeTimeSource.reset(new FakeTimeSource);
106106}
107107
108108void tst_DragHandle::cleanup()
@@ -113,8 +113,7 @@ void tst_DragHandle::cleanup()
113113 delete m_fakeTimer;
114114 m_fakeTimer = 0;
115115
116− delete m_fakeTimeSource;
117− m_fakeTimeSource = 0;
116+ m_fakeTimeSource.reset();
118117}
119118
120119QQuickView *tst_DragHandle::createView()
tests/qmltests/Dash/Apps/tst_RunningApplicationsGrid.qml+1
@@ -226,6 +226,7 @@ Item {
226226 verify(fakeRunningAppsModel.contains("calendar"))
227227
228228 mouseClick(calendarTileCloseButton, calendarTileCloseButton.width/2, calendarTileCloseButton.height/2)
229+ wait(0) // spin event loop to start any pending animation
229230
230231 verify(!fakeRunningAppsModel.contains("calendar"))
231232
tests/qmltests/Greeter/tst_Lockscreen.qml+42−4
@@ -176,15 +176,17 @@ Rectangle {
176176
177177 function test_unlock_data() {
178178 return [
179− {tag: "numeric", alphanumeric: false, username: "has-pin", password: "1234", unlockedSignal: true},
180− {tag: "alphanumeric", alphanumeric: true, username: "has-password", password: "password", unlockedSignal: true},
181− {tag: "numeric (wrong)", alphanumeric: false, username: "has-pin", password: "4321", unlockedSignal: false},
182− {tag: "alphanumeric (wrong)", alphanumeric: true, username: "has-password", password: "drowssap", unlockedSignal: false},
179+ {tag: "numeric", alphanumeric: false, username: "has-pin", password: "1234", unlockedSignal: true, pinLength: 4},
180+ {tag: "alphanumeric", alphanumeric: true, username: "has-password", password: "password", unlockedSignal: true, pinLength: -1},
181+ {tag: "numeric (wrong)", alphanumeric: false, username: "has-pin", password: "4321", unlockedSignal: false, pinLength: 4},
182+ {tag: "alphanumeric (wrong)", alphanumeric: true, username: "has-password", password: "drowssap", unlockedSignal: false, pinLength: -1},
183+ {tag: "flexible length", alphanumeric: false, username: "has-pin", password: "1234", unlockedSignal: true, pinLength: -1},
183184 ]
184185 }
185186
186187 function test_unlock(data) {
187188 unlockedCheckBox.checked = false
189+ pinLengthTextField.text = data.pinLength
188190 LightDM.Greeter.authenticate(data.username)
189191 waitForRendering(lockscreen)
190192
@@ -199,7 +201,12 @@ Rectangle {
199201 var button = findChild(lockscreen, "pinPadButton" + character)
200202 mouseClick(button, units.gu(1), units.gu(1))
201203 }
204+ if (data.pinLength == -1) {
205+ var pinPadButtonErase = findChild(lockscreen, "pinPadButtonErase");
206+ mouseClick(pinPadButtonErase, units.gu(1), units.gu(1));
207+ }
202208 }
209+
203210 tryCompare(unlockedCheckBox, "checked", data.unlockedSignal)
204211 if (!data.unlockedSignal) {
205212 // make sure the input is cleared on wrong input
@@ -208,5 +215,36 @@ Rectangle {
208215 tryCompareFunction(function() {return inputField.text.length > 0}, true)
209216 }
210217 }
218+
219+ function test_backspace_data() {
220+ return [
221+ {tag: "fixed length", pinLength: 4},
222+ {tag: "variable length", pinLength: -1}
223+ ];
224+ }
225+
226+ function test_backspace(data) {
227+ LightDM.Greeter.authenticate("has-pin");
228+ pinLengthTextField.text = data.pinLength
229+ waitForRendering(lockscreen);
230+
231+ var pinPadButtonErase = findChild(lockscreen, "pinPadButtonErase");
232+ var backspaceIcon = findChild(lockscreen, "backspaceIcon");
233+ var pinEntryField = findChild(lockscreen, "pinentryField");
234+
235+ compare(pinPadButtonErase.iconName, data.pinLength == -1 ? "" : "erase");
236+ compare(backspaceIcon.visible, data.pinLength == -1);
237+
238+ var pinPadButton5 = findChild(lockscreen, "pinPadButton5");
239+ mouseClick(pinPadButton5, units.gu(1), units.gu(1));
240+ compare(pinEntryField.text, "5");
241+
242+ if (data.pinLength == -1) {
243+ mouseClick(backspaceIcon, units.gu(1), units.gu(1));
244+ } else {
245+ mouseClick(pinPadButtonErase, units.gu(1), units.gu(1));
246+ }
247+ compare(pinEntryField.text, "");
248+ }
211249 }
212250}
tests/qmltests/Greeter/tst_Phone.qml+5−5
@@ -133,7 +133,7 @@ Item {
133133 tryCompare(LightDM.Infographic, "username", "single")
134134 }
135135
136− function test_wallpaper_data() {
136+ function test_background_data() {
137137 return [
138138 {tag: "set", accounts: "../tests/data/unity/backgrounds/blue.png", expected: "blue.png"},
139139 {tag: "unset", accounts: "", expected: "background.jpg"},
@@ -141,12 +141,12 @@ Item {
141141 ]
142142 }
143143
144− function test_wallpaper(data) {
144+ function test_background(data) {
145145 var loader = findChild(greeter, "greeterContentLoader")
146− var wallpaper = findChild(loader.item, "wallpaper")
146+ var background = findChild(loader.item, "greeterBackground")
147147 AccountsService.backgroundFile = data.accounts
148− tryCompareFunction(function() { return wallpaper.source.toString().indexOf(data.expected) !== -1; }, true)
149− tryCompare(wallpaper, "status", Image.Ready)
148+ tryCompareFunction(function() { return background.source.toString().indexOf(data.expected) !== -1; }, true)
149+ tryCompare(background, "status", Image.Ready)
150150 }
151151 }
152152}
tests/qmltests/Panel/tst_Panel.qml−1
@@ -52,7 +52,6 @@ Item {
5252 {tag: "fullscreen", fullscreenFlag: true }
5353 ]}
5454
55−
5655 function init() {
5756 searchClicked = false;
5857 panel.indicators.hide();
tests/qmltests/tst_Shell.qml+85−22
@@ -55,19 +55,42 @@ Item {
5555 when: windowShown
5656
5757 function initTestCase() {
58− swipeAwayGreeter();
58+ var ok = false;
59+ var attempts = 0;
60+ var maxAttempts = 1000;
61+
62+ // Qt loads a qml scene asynchronously. So early on, some findChild() calls made in
63+ // tests may fail because the desired child item wasn't loaded yet.
64+ // Thus here we try to ensure the scene has been fully loaded before proceeding with the tests.
65+ // As I couldn't find an API in QQuickView & friends to tell me that the scene is 100% loaded
66+ // (all items instantiated, etc), I resort to checking the existence of some key items until
67+ // repeatedly until they're all there.
68+ do {
69+ var dashContentList = findChild(shell, "dashContentList");
70+ waitForRendering(dashContentList);
71+ var homeLoader = findChild(dashContentList, "home.scope loader");
72+ ok = homeLoader !== undefined
73+ && homeLoader.item !== undefined;
5974
60− // Ensure DashHome is loaded before continuing
61− var dashContentList = findChild(shell, "dashContentList");
62− waitForRendering(dashContentList);
63− var homeLoader = findChild(dashContentList, "home.scope loader");
64− verify(homeLoader);
65− tryCompareFunction(function() {return homeLoader.item !== undefined;}, true);
75+ var greeter = findChild(shell, "greeter");
76+ ok &= greeter !== undefined;
77+
78+ var launcherPanel = findChild(shell, "launcherPanel");
79+ ok &= launcherPanel !== undefined;
80+
81+ attempts++;
82+ if (!ok) {
83+ console.log("Attempt " + attempts + " failed. Waiting a bit before trying again.");
84+ // wait a bit before retrying
85+ wait(100);
86+ } else {
87+ console.log("All seem fine after " + attempts + " attempts.");
88+ }
89+ } while (!ok && attempts <= maxAttempts);
6690
67− // FIXME: Desperate measure to ensure Jenkins has the scene graph fully loaded
68− // before it calls the test functions (otherwise findChild calls will fail).
69− // The code above just didn't solve it.
70− wait(2000);
91+ verify(ok);
92+
93+ swipeAwayGreeter();
7194 }
7295
7396 function cleanup() {
@@ -111,14 +134,14 @@ Item {
111134 waitUntilApplicationWindowIsFullyVisible();
112135
113136 // Minimize the application we just launched
114− swipeFromLeftEdge();
137+ swipeFromLeftEdge(units.gu(27));
115138
116139 waitForUIToSettle();
117140
118141 checkRightEdgeDragWithMinimizedApp();
119142
120143 // Minimize that application once again
121− swipeFromLeftEdge();
144+ swipeFromLeftEdge(units.gu(27));
122145
123146 // Right edge behavior should now be the same as before that app,
124147 // was launched. Manually cleanup beforehand to get to initial
@@ -130,8 +153,10 @@ Item {
130153
131154 function test_leftEdgeDrag_data() {
132155 return [
133− {tag: "without launcher", revealLauncher: false},
134− {tag: "with launcher", revealLauncher: true},
156+ {tag: "without launcher", revealLauncher: false, swipeLength: units.gu(27), appHides: true},
157+ {tag: "with launcher", revealLauncher: true, swipeLength: units.gu(27), appHides: true},
158+ {tag: "small swipe", revealLauncher: false, swipeLength: units.gu(25), appHides: false},
159+ {tag: "long swipe", revealLauncher: false, swipeLength: units.gu(27), appHides: true}
135160 ];
136161 }
137162
@@ -144,8 +169,11 @@ Item {
144169 dragLauncherIntoView();
145170 }
146171
147− swipeFromLeftEdge();
148− waitUntilApplicationWindowIsFullyHidden();
172+ swipeFromLeftEdge(data.swipeLength);
173+ if (data.appHides)
174+ waitUntilApplicationWindowIsFullyHidden();
175+ else
176+ waitUntilApplicationWindowIsFullyVisible();
149177 }
150178
151179 function test_suspend() {
@@ -292,8 +320,12 @@ Item {
292320
293321 waitUntilApplicationWindowIsFullyVisible();
294322
323+ // Dragging launcher into view with a little bit of gap (units.gu(1)) should switch to Apps scope
324+ dragLauncherIntoView();
325+ verify(itemIsOnScreen(dashApps));
326+
295327 // Minimize the application we just launched
296− swipeFromLeftEdge();
328+ swipeFromLeftEdge(units.gu(27));
297329
298330 // Wait for the whole UI to settle down
299331 waitUntilApplicationWindowIsFullyHidden();
@@ -376,10 +408,10 @@ Item {
376408 }
377409 }
378410
379− function swipeFromLeftEdge() {
411+ function swipeFromLeftEdge(swipeLength) {
380412 var touchStartX = 2;
381413 var touchStartY = shell.height / 2;
382− touchFlick(shell, touchStartX, touchStartY, shell.width * 0.75, touchStartY);
414+ touchFlick(shell, touchStartX, touchStartY, swipeLength, touchStartY);
383415 }
384416
385417 function swipeLeftFromCenter() {
@@ -432,7 +464,7 @@ Item {
432464 } while (!isStill);
433465 }
434466
435− function test_wallpaper_data() {
467+ function test_background_data() {
436468 return [
437469 {tag: "red", url: "tests/data/unity/backgrounds/red.png", expectedUrl: "tests/data/unity/backgrounds/red.png"},
438470 {tag: "blue", url: "tests/data/unity/backgrounds/blue.png", expectedUrl: "tests/data/unity/backgrounds/blue.png"},
@@ -441,13 +473,21 @@ Item {
441473 ]
442474 }
443475
444− function test_wallpaper(data) {
476+ function test_background(data) {
445477 var backgroundImage = findChild(shell, "backgroundImage")
446478 GSettingsController.setPictureUri(data.url)
447479 tryCompareFunction(function() { return backgroundImage.source.toString().indexOf(data.expectedUrl) !== -1; }, true)
448480 tryCompare(backgroundImage, "status", Image.Ready)
449481 }
450482
483+ function test_lockscreen_background() {
484+ var backgroundImage = findChild(shell, "backgroundImage")
485+ var lockscreen = findChild(shell, "lockscreen")
486+ var lockscreenBackground = findChild(lockscreen, "lockscreenBackground")
487+ var lockscreenBackgroundMapped = lockscreenBackground.mapToItem(shell, 0, 0)
488+ compare(backgroundImage.y, lockscreenBackgroundMapped.y)
489+ }
490+
451491 function test_DashShown_data() {
452492 return [
453493 {tag: "in focus", greeter: false, app: false, launcher: false, indicators: false, expectedShown: true},
@@ -483,5 +523,28 @@ Item {
483523 var dash = findChild(shell, "dash");
484524 tryCompare(dash, "shown", data.expectedShown);
485525 }
526+
527+ function test_searchIndicatorHidesOnAppFocus() {
528+ var searchIndicator = findChild(shell, "container")
529+ tryCompare(searchIndicator, "opacity", 1)
530+ dragLauncherIntoView();
531+
532+ // Launch an app from the launcher
533+ tapOnAppIconInLauncher();
534+ waitUntilApplicationWindowIsFullyVisible();
535+
536+ tryCompare(searchIndicator, "opacity", 0);
537+ }
538+
539+ function test_searchIndicatorHidesOnGreeterShown() {
540+ var searchIndicator = findChild(shell, "container")
541+ var greeter = findChild(shell, "greeter");
542+
543+ tryCompare(searchIndicator, "opacity", 1)
544+
545+ greeter.show()
546+ tryCompare(greeter, "shown", true)
547+ tryCompare(searchIndicator, "opacity", 0)
548+ }
486549 }
487550}
tests/utils/modules/Unity/Test/UnityTestCase.qml+34
@@ -14,6 +14,7 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17+import QtQuick 2.0
1718import QtTest 1.0
1819import Ubuntu.Components 0.1
1920import Unity.Test 0.1 as UT
@@ -297,4 +298,37 @@ TestCase {
297298 event.release(0 /* touchId */, x, y)
298299 event.commit()
299300 }
301+
302+ Component.onCompleted: {
303+ var rootItem = parent;
304+ while (rootItem.parent != undefined) {
305+ rootItem = rootItem.parent;
306+ }
307+ removeTimeConstraintsFromDirectionalDragAreas(rootItem);
308+ }
309+
310+ /*
311+ In qmltests, sequences of touch events are sent all at once, unlike in "real life".
312+ Also qmltests might run really slowly, e.g. when run from inside virtual machines.
313+ Thus to remove a variable that qmltests cannot really control, namely time, this
314+ function removes all constraints from DirectionalDragAreas that are sensible to
315+ elapsed time.
316+
317+ This effectively makes DirectionalDragAreas easier to fool.
318+ */
319+ function removeTimeConstraintsFromDirectionalDragAreas(item) {
320+
321+ // use duck-typing to identify a DirectionalDragArea
322+ if (item.minSpeed != undefined
323+ && item.maxSilenceTime != undefined
324+ && item.compositionTime != undefined) {
325+ item.minSpeed = 0;
326+ item.maxSilenceTime = 60 * 60 * 1000;
327+ item.compositionTime = 0;
328+ } else {
329+ for (var i in item.children) {
330+ removeTimeConstraintsFromDirectionalDragAreas(item.children[i]);
331+ }
332+ }
333+ }
300334}