on xenial help sign in
Merged trunk.
commitf35cd953ce3a2d5f3eabed78fed16ac6910bc0b1 authorNicolas d'Offay <nicolas.doffay@canonical.com> dateTue 19 Nov 2013, 14:33 (13 years ago) parentf6c8e25024b6c7
166 files changed+4205−2204
Bottombar/Bottombar.qml+4−4 Components/Carousel.qml+4−6 Components/DragHandle.qml+22−24 Components/DraggingArea.qml+1−2 Components/EdgeDemoOverlay.qml+2 Components/EdgeDragArea.qml+12−4 Components/PageHeader.qml+25−6 Components/PinPadButton.qml+40−13 Components/Revealer.qml+1−2 Components/Stage.qml+8−7 Components/Time.js+9−9 Dash/Apps/AppInfo.qml−89 Dash/Apps/ApplicationsFilterGrid.qml−64 Dash/Apps/DashPluginFilterGrid.qml+2−2 Dash/Apps/RunningApplicationTile.qml−2 Dash/Generic/GenericCarouselLoader.qml+30 Dash/Generic/GenericFilterGrid.qml+4−4 Dash/Generic/WeatherFilterGrid.qml+2−2 Dash/GenericScopeView.qml+69−19 tests/mocks/QMenuModel/UnityMenuModel.qml → Dash/Music/MusicCarouselLoader.qml+5−7 Dash/Music/MusicFilterGrid.qml+2−2 Dash/ScopeView.qml−65 Dash/Video/VideosCarousel.qml → Dash/Video/VideoCarousel.qml Components/Math.js → Dash/Video/VideoCarouselLoader.qml+6−8 Dash/Video/VideoFilterGrid.qml+2−2 Dash/Video/VideoInfo.qml−84 Greeter/Greeter.qml+2−2 Greeter/GreeterContent.qml+23−20 Greeter/Lockscreen.qml+8−4 Greeter/PinLockscreen.qml+34−4 Launcher/Launcher.qml+1−1 Notifications/NotificationMenuItemFactory.qml+20−6 Panel/Indicators.qml+37−10 Panel/Indicators/DefaultIndicatorWidget.qml+32−10 Shell.qml+9−3 data/unity8.conf+20 debian/changelog+66 debian/control+1−1 plugins/ListViewWithPageHeader/listviewwithpageheader.cpp+11−1 plugins/ListViewWithPageHeader/listviewwithpageheader.h+5 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/CMakeLists.txt−1 plugins/Unity/Indicators/qml/IndicatorWidget.qml+1−1 plugins/Unity/Indicators/qml/SliderMenuItem.qml+3−2 plugins/Unity/Indicators/unitymenumodelstack.cpp+98−7 plugins/Unity/Indicators/unitymenumodelstack.h+10−2 plugins/Unity/Launcher/launcheritem.cpp+4−2 plugins/Unity/iconutils.cpp+10−10 plugins/Unity/plugin.cpp−12 plugins/Utils/CMakeLists.txt+1 plugins/Utils/albumartprovider.cpp+10−7 plugins/Unity/bottombarvisibilitycommunicatorshell.cpp → plugins/Utils/bottombarvisibilitycommunicatorshell.cpp plugins/Unity/bottombarvisibilitycommunicatorshell.h → plugins/Utils/bottombarvisibilitycommunicatorshell.h plugins/Utils/plugin.cpp+12 po/ar.po+23−10 po/ast.po+22−30 po/az.po+22−15 po/bg.po+22−21 po/ca.po+22−30 po/cs.po+22−24 po/de.po+22−9 po/el.po+22−15 po/en_AU.po+22−30 po/en_GB.po+22−30 po/eo.po+22−9 po/es.po+22−30 po/fa.po+22−9 po/fi.po+23−31 po/fo.po+22−15 po/fr.po+22−15 po/gd.po+22−30 po/gl.po+22−27 po/he.po+22−30 po/hr.po+22−15 po/hu.po+22−15 po/hy.po+22−15 po/id.po+22−9 po/is.po+22−30 po/it.po+22−30 po/ja.po+22−9 po/km.po+24−32 po/kn.po+22−15 po/ko.po+22−12 po/ky.po+22−15 po/lo.po+22−15 po/lv.po+22−15 po/my.po+22−24 po/nb.po+22−15 po/nl.po+22−15 po/pl.po+22−9 po/pt_BR.po+22−30 po/ro.po+22−15 po/ru.po+22−30 po/shn.po+22−9 po/si.po+22−9 po/sl.po+22−30 po/sr.po+22−15 po/sv.po+22−9 po/ta.po+22−9 po/te.po+22−12 po/tr.po+22−30 po/ug.po+22−24 po/uk.po+22−9 po/unity8.pot+20−7 po/xh.po+22−9 po/zh_CN.po+22−30 po/zh_TW.po+22−15 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−7 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/mocks/QMenuModel/CMakeLists.txt+23 tests/mocks/QMenuModel/UnityMenuAction.qml+30 tests/mocks/QMenuModel/actionstateparser.cpp+19 tests/mocks/QMenuModel/actionstateparser.h+35 tests/mocks/QMenuModel/plugin.cpp+30 tests/mocks/QMenuModel/plugin.h+34 tests/mocks/QMenuModel/qmldir+3−1 tests/mocks/QMenuModel/unitymenumodel.cpp+239 tests/mocks/QMenuModel/unitymenumodel.h+96 tests/mocks/Unity/Indicators/IndicatorBase.qml+37 tests/mocks/Unity/Indicators/IndicatorWidget.qml+28 tests/mocks/Unity/Indicators/RootActionState.qml+17−9 tests/mocks/Unity/Indicators/qmldir+2 tests/mocks/Unity/fake_scope.cpp+3−20 tests/plugins/ListViewWithPageHeader/CMakeLists.txt+7 tests/plugins/ListViewWithPageHeader/listviewwithpageheadertest.cpp+20 tests/plugins/ListViewWithPageHeader/tst_listviewwithpageheaderqml.qml+138 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/plugins/Unity/Indicators/CMakeLists.txt+36−27 tests/plugins/Unity/Indicators/unitymenumodelstacktest.cpp+206 tests/plugins/Unity/resultstest.cpp+3−3 tests/qmltests/CMakeLists.txt+5−4 tests/qmltests/Components/tst_DragHandle.cpp+4−5 tests/qmltests/Components/tst_EdgeDemoOverlay.qml+2−2 tests/qmltests/Components/tst_MathLocal.qml−91 tests/qmltests/Components/tst_PageHeader.qml+43−3 tests/qmltests/Dash/Apps/tst_RunningApplicationsGrid.qml+1 tests/qmltests/Dash/qml/FakeScopeView.qml+3−68 tests/qmltests/Dash/tst_Dash.qml+2 tests/qmltests/Dash/tst_DashContent.qml+35−2 tests/qmltests/Dash/tst_FilterGrids.qml+1−2 tests/qmltests/Dash/tst_GenericScopeView.qml+27−2 tests/qmltests/Dash/tst_ScopeView.qml−52 tests/qmltests/Greeter/tst_Clock.qml+16 tests/qmltests/Greeter/tst_Lockscreen.qml+42−4 tests/qmltests/Greeter/tst_Phone.qml+5−5 tests/qmltests/Panel/Indicators/tst_DefaultIndicatorWidget.qml+97 tests/qmltests/Panel/tst_Panel.qml+13−5 tests/qmltests/tst_Shell.qml+71−13 tests/utils/modules/Unity/Test/UnityTestCase.qml+36
Bottombar/Bottombar.qml+4−4
@@ -16,10 +16,10 @@
1616
1717import QtQuick 2.0
1818import "../Components"
19−import "../Components/Math.js" as MathLocal
20−import Unity 0.1
19+import Utils 0.1
2120import Unity.Application 0.1
2221import Ubuntu.Gestures 0.1
22+import Ubuntu.Components 0.1
2323
2424Item {
2525 id: bottombar
@@ -82,7 +82,7 @@ Item {
8282
8383 readonly property bool centeredHud: parent.width < units.gu(68) // Nexus 7 has 67 gu width
8484
85− x: centeredHud ? parent.width / 2 - width / 2 : MathLocal.clamp(dragArea.touchStartX - (width / 2), 0, bottombar.width - width)
85+ x: centeredHud ? parent.width / 2 - width / 2 : MathUtils.clamp(dragArea.touchStartX - (width / 2), 0, bottombar.width - width)
8686 y: bottombar.height - bottomEdgeButtonCenterDistance - (height / 2) - bottomMargin
8787 z: 1
8888 visible: opacity != 0
@@ -136,7 +136,7 @@ Item {
136136 readonly property real distanceFromThreshold: (-distance) - distanceThreshold // distance is negative
137137 readonly property real revealDistance: units.gu(2)
138138 readonly property real commitDistance: units.gu(6)
139− readonly property real commitProgress: MathLocal.clamp(distanceFromThreshold / commitDistance, 0, 1)
139+ readonly property real commitProgress: MathUtils.clamp(distanceFromThreshold / commitDistance, 0, 1)
140140
141141 onStatusChanged: {
142142 if (status === DirectionalDragArea.WaitingForTouch) {
Components/Carousel.qml+4−6
@@ -54,15 +54,13 @@ Item {
5454
5555 /// Emitted when the user clicked on an item
5656 /// @param index is the index of the clicked item
57− /// @param model is the model of all the items in the carousel
5857 /// @param itemY is y of the clicked delegate
59− signal clicked(int index, var model, real itemY)
58+ signal clicked(int index, real itemY)
6059
6160 /// Emitted when the user pressed and held on an item
6261 /// @param index is the index of the held item
63− /// @param model is the model of all the items in the carousel
6462 /// @param itemY is y of the held delegate
65− signal pressAndHold(int index, var model, real itemY)
63+ signal pressAndHold(int index, real itemY)
6664
6765 implicitHeight: listView.tileHeight * selectedItemScaleFactor
6866
@@ -163,7 +161,7 @@ Item {
163161 /* We're clicking the selected item and
164162 we're in the neighbourhood of radius 1 pixel from it.
165163 Let's emit the clicked signal. */
166− carousel.clicked(index, listView.model, delegateItem.y)
164+ carousel.clicked(index, delegateItem.y)
167165 return
168166 }
169167
@@ -187,7 +185,7 @@ Item {
187185 /* We're pressAndHold the selected item and
188186 we're in the neighbourhood of radius 1 pixel from it.
189187 Let's emit the pressAndHold signal. */
190− carousel.pressAndHold(index, listView.model, delegateItem.y);
188+ carousel.pressAndHold(index, delegateItem.y);
191189 return;
192190 }
193191
Components/DragHandle.qml+22−24
@@ -17,7 +17,6 @@
1717import QtQuick 2.0
1818import Ubuntu.Components 0.1
1919import Ubuntu.Gestures 0.1
20−import "Math.js" as MathLocal
2120
2221/*
2322 Put a DragHandle inside a Showable to enable the user to drag it from that handle.
@@ -48,9 +47,12 @@ EdgeDragArea {
4847 id: dragArea
4948 objectName: "dragHandle"
5049
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)
50+ // Disable most of the gesture recognition parameters by default when hinting is used as
51+ // it conflicts with the hinting idea.
52+ // The only part we keep in this situation is that it must be a single-finger gesture.
53+ distanceThreshold: hintDisplacement > 0 ? 0 : defaultDistanceThreshold
54+ maxSilenceTime: hintDisplacement > 0 ? 60*60*1000 : defaultMaxSilenceTime
55+ maxDeviation: hintDisplacement > 0 ? 999999 : defaultMaxDeviation
5456
5557 property bool stretch: false
5658
@@ -113,8 +115,8 @@ EdgeDragArea {
113115 }
114116 }
115117
116− function limitMovement(step) {
117− var targetValue = MathLocal.clamp(dragParent[targetProp] + step, minValue, maxValue);
118+ function limitMovement(inputStep) {
119+ var targetValue = MathUtils.clamp(dragParent[targetProp] + inputStep, minValue, maxValue);
118120 var step = targetValue - dragParent[targetProp];
119121
120122 if (hintDisplacement == 0) {
@@ -181,29 +183,25 @@ EdgeDragArea {
181183 }
182184 }
183185
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−
195186 onStatusChanged: {
196187 if (status === DirectionalDragArea.WaitingForTouch) {
188+ hintingAnimation.stop();
197189 if (d.previousStatus === DirectionalDragArea.Recognized) {
198190 d.onFinishedRecognizedGesture();
191+ } else /* d.previousStatus === DirectionalDragArea.Undecided */ {
192+ // Gesture was rejected.
193+ d.rollbackDrag();
194+ }
195+ } else /* Undecided || Recognized */ {
196+ if (d.previousStatus === DirectionalDragArea.WaitingForTouch ||
197+ d.previousStatus === undefined) {
198+ dragEvaluator.reset();
199+ d.startValue = parent[d.targetProp];
200+ }
201+ if (hintDisplacement > 0) {
202+ hintingAnimation.targetValue = d.startValue;
203+ hintingAnimation.start();
199204 }
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];
207205 }
208206
209207 d.previousStatus = status;
Components/DraggingArea.qml+1−2
@@ -16,7 +16,6 @@
1616
1717import QtQuick 2.0
1818import Ubuntu.Components 0.1
19−import "Math.js" as MathLocal
2019
2120MouseArea {
2221 id: draggingArea
@@ -26,7 +25,7 @@ MouseArea {
2625 property real dragVelocity: 0
2726 property real dragValue: (orientation == Qt.Vertical ? (mouseY - __pressedPosition.y)
2827 : (mouseX - __pressedPosition.x))
29− property real lateralPosition: orientation == Qt.Horizontal ? MathLocal.clamp(mouseY, 0, height) : MathLocal.clamp(mouseX, 0, width)
28+ property real lateralPosition: orientation == Qt.Horizontal ? MathUtils.clamp(mouseY, 0, height) : MathUtils.clamp(mouseX, 0, width)
3029 property point __pressedPosition: Qt.point(0, 0)
3130 property var __dragEvents: []
3231 property bool clickValidated: true
Components/EdgeDemoOverlay.qml+2
@@ -105,6 +105,8 @@ Showable {
105105 visible: overlay.active
106106
107107 MouseArea {
108+ objectName: "backgroundShadeMouseArea"
109+
108110 anchors.fill: parent
109111 enabled: overlay.edge == "none" && overlay.opacity == 1.0
110112 onClicked: overlay.doSkip()
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/PageHeader.qml+25−6
@@ -44,8 +44,8 @@ Item {
4444 if (!searchHistory) return;
4545
4646 searchHistory.addQuery(searchField.text);
47+ unfocus();
4748 searchField.text = "";
48− searchField.focus = false;
4949 }
5050
5151 function unfocus() {
@@ -112,6 +112,8 @@ Item {
112112 objectName: "searchContainer"
113113
114114 visible: searchEntryEnabled
115+ property bool popoverShouldOpen: false
116+ property bool popoverShouldClose: false
115117
116118 property bool narrowMode: parent.width < label.contentWidth + units.gu(50)
117119
@@ -127,6 +129,16 @@ Item {
127129 else if (active && !narrowMode) "active"
128130 else if (!active && !narrowMode) "inactive"
129131
132+ onStateChanged: {
133+ if (state == "active" || state == "narrowActive") {
134+ popoverShouldOpen = true;
135+ popoverShouldClose = false;
136+ } else {
137+ popoverShouldOpen = false;
138+ popoverShouldClose = true;
139+ }
140+ }
141+
130142 function openPopover() {
131143 if (searchHistory.count > 0) {
132144 searchContainer.popover = PopupUtils.open(popoverComponent, searchField,
@@ -137,10 +149,17 @@ Item {
137149 }
138150 )
139151 }
152+ popoverShouldOpen = false;
153+ popoverShouldClose = false;
140154 }
141155
142156 function closePopover() {
143− if (searchContainer.popover) PopupUtils.close(searchContainer.popover)
157+ if (searchContainer.popover) {
158+ PopupUtils.close(searchContainer.popover);
159+ searchContainer.popover = null;
160+ }
161+ popoverShouldOpen = false;
162+ popoverShouldClose = false;
144163 }
145164
146165 onActiveFocusChanged: if (!activeFocus) { searchHistory.addQuery(searchField.text) }
@@ -283,12 +302,12 @@ Item {
283302 PropertyAction { target: primaryImage; property: "source" }
284303 AnchorAnimation { targets: [searchContainer, textContainer]; duration: 200; easing.type: Easing.InOutQuad }
285304 }
286− ScriptAction { script: searchContainer.openPopover() }
305+ ScriptAction { script: if (searchContainer.popoverShouldOpen) { searchContainer.openPopover(); } }
287306 }
288307 },
289308 Transition {
290309 to: "inactive"
291− ScriptAction { script: searchContainer.closePopover() }
310+ ScriptAction { script: if (searchContainer.popoverShouldClose) { searchContainer.closePopover(); } }
292311 NumberAnimation { targets: [searchContainer, searchField] ; property: "width"; duration: 200; easing.type: Easing.InOutQuad }
293312 AnchorAnimation { targets: [searchContainer, textContainer]; duration: 200; easing.type: Easing.InOutQuad }
294313 },
@@ -299,12 +318,12 @@ Item {
299318 NumberAnimation { targets: [searchContainer, searchField] ; property: "width"; duration: 200; easing.type: Easing.OutQuad }
300319 AnchorAnimation { targets: [searchContainer, textContainer]; duration: 200; easing.type: Easing.InOutQuad }
301320 }
302− ScriptAction { script: searchContainer.openPopover() }
321+ ScriptAction { script: if (searchContainer.popoverShouldOpen) { searchContainer.openPopover(); } }
303322 }
304323 },
305324 Transition {
306325 to: "narrowInactive"
307− ScriptAction { script: searchContainer.closePopover() }
326+ ScriptAction { script: if (searchContainer.popoverShouldClose) { searchContainer.closePopover(); } }
308327 NumberAnimation { targets: [searchContainer, searchField] ; property: "width"; duration: 200; easing.type: Easing.OutQuad }
309328 AnchorAnimation { targets: [searchContainer, textContainer]; duration: 200; easing.type: Easing.InOutQuad }
310329 }
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/Revealer.qml+1−2
@@ -16,7 +16,6 @@
1616
1717import QtQuick 2.0
1818import Ubuntu.Components 0.1
19−import "Math.js" as MathLocal
2019
2120Item {
2221 id: revealer
@@ -95,7 +94,7 @@ Item {
9594 onClosedValueChanged: if (!__opened && !dragging) target[boundProperty] = closedValue
9695
9796 function __computeValue(dragPosition) {
98− return MathLocal.clamp(dragToValue(dragPosition), __hintValue, openedValue)
97+ return MathUtils.clamp(dragToValue(dragPosition), __hintValue, openedValue)
9998 }
10099
101100 function __open() {
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);
Dash/Apps/AppInfo.qmldeleted−89
@@ -1,89 +0,0 @@
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 "../../Components"
20−
21−Row {
22− id: root
23− property alias icon: image.source
24− property alias appName: appNameLabel.text
25− property alias rating: ratingStars.rating
26− property int rated: 0
27− property int reviews: 0
28−
29− spacing: units.gu(2)
30−
31− UbuntuShape {
32− id: imageShape
33− width: units.gu(6)
34− height: units.gu(6)
35− image: Image {
36− id: image
37− sourceSize { width: imageShape.width; height: imageShape.height }
38− asynchronous: true
39− fillMode: Image.PreserveAspectFit
40− }
41− }
42−
43− Column {
44− spacing: units.gu(1)
45−
46− Label {
47− id: appNameLabel
48− fontSize: "large"
49− color: "white"
50− style: Text.Raised
51− styleColor: "black"
52− opacity: .9
53− }
54−
55− Row {
56− visible: root.rating >= 0
57− spacing: units.gu(1)
58−
59− RatingStars {
60− id: ratingStars
61− maximumRating: 10
62− }
63−
64− Label {
65− id: ratedLabel
66− objectName: "ratedLabel"
67− fontSize: "medium"
68− color: "white"
69− style: Text.Raised
70− styleColor: "black"
71− opacity: .6
72− //TRANSLATORS: Number of persons who rated this app
73− text: i18n.tr("(%1)").arg(root.rated)
74− }
75−
76− Label {
77− id: reviewsLabel
78− objectName: "reviewsLabel"
79− fontSize: "medium"
80− color: "white"
81− style: Text.Raised
82− styleColor: "black"
83− opacity: .6
84− //TRANSLATORS: Number of persons who wrote reviews for this app
85− text: i18n.tr("%1 review", "%1 reviews", root.reviews).arg(root.reviews)
86− }
87− }
88− }
89−}
Dash/Apps/ApplicationsFilterGrid.qmldeleted−64
@@ -1,64 +0,0 @@
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 "../../Components"
19−import "../../Applications"
20−
21−FilterGrid {
22− id: filtergrid
23−
24− filter: false
25− minimumHorizontalSpacing: units.gu(0.5)
26− maximumNumberOfColumns: 6
27− delegateWidth: units.gu(11)
28− delegateHeight: units.gu(9.5)
29− verticalSpacing: units.gu(2)
30−
31− signal clicked(int index, var model, real itemY)
32− signal pressAndHold(int index, var model, real itemY)
33−
34− delegate: Tile {
35− id: tile
36− objectName: "delegate" + index
37− Application {
38− id: application
39− desktopFile: model.dndUri ? stripProtocol(model.dndUri) : model.desktopFile // FIXME: this is temporary
40−
41− function stripProtocol(uri) {
42− var chunks = uri.split('file://')
43− return chunks[chunks.length-1]
44− }
45− }
46−
47− property string icon: model.icon ? model.icon : "../../graphics/applicationIcons/" + application.icon + ".png" // FIXME: this is temporary
48−
49− width: filtergrid.cellWidth
50− height: filtergrid.cellHeight
51− text: model.title ? model.title : application.name // FIXME: this is temporary
52− imageWidth: units.gu(8)
53− imageHeight: units.gu(7.5)
54− source: icon
55−
56− onClicked: {
57− filtergrid.clicked(index, filtergrid.model, tile.y)
58− }
59−
60− onPressAndHold: {
61− filtergrid.pressAndHold(index, filtergrid.model, tile.y)
62− }
63− }
64−}
Dash/Apps/DashPluginFilterGrid.qml+2−2
@@ -37,11 +37,11 @@ GenericFilterGrid {
3737 }
3838
3939 onClicked: {
40− filtergrid.clicked(index, filtergrid.model, tile.y)
40+ filtergrid.clicked(index, tile.y)
4141 }
4242
4343 onPressAndHold: {
44− filtergrid.pressAndHold(index, filtergrid.model, tile.y)
44+ filtergrid.pressAndHold(index, tile.y)
4545 }
4646 }
4747}
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/Generic/GenericFilterGrid.qml+4−4
@@ -28,8 +28,8 @@ FilterGrid {
2828 property int iconWidth: units.gu(8)
2929 property int iconHeight: units.gu(7.5)
3030
31− signal clicked(int index, var model, real itemY)
32− signal pressAndHold(int index, var model, real itemY)
31+ signal clicked(int index, real itemY)
32+ signal pressAndHold(int index, real itemY)
3333
3434 delegate: Tile {
3535 id: tile
@@ -42,11 +42,11 @@ FilterGrid {
4242 source: model.icon
4343
4444 onClicked: {
45− filtergrid.clicked(index, filtergrid.model, tile.y)
45+ filtergrid.clicked(index, tile.y)
4646 }
4747
4848 onPressAndHold: {
49− filtergrid.pressAndHold(index, filtergrid.model, tile.y)
49+ filtergrid.pressAndHold(index, tile.y)
5050 }
5151 }
5252}
Dash/Generic/WeatherFilterGrid.qml+2−2
@@ -37,11 +37,11 @@ GenericFilterGrid {
3737 style: FlatTileStyle {}
3838
3939 onClicked: {
40− filtergrid.clicked(index, filtergrid.model, tile.y)
40+ filtergrid.clicked(index, tile.y)
4141 }
4242
4343 onPressAndHold: {
44− filtergrid.pressAndHold(index, filtergrid.model, tile.y)
44+ filtergrid.pressAndHold(index, tile.y)
4545 }
4646 }
4747}
Dash/GenericScopeView.qml+69−19
@@ -16,18 +16,60 @@
1616
1717import QtQuick 2.0
1818import Ubuntu.Components 0.1
19+import Utils 0.1
20+import Unity 0.1
1921import "../Components"
2022import "../Components/ListItems" as ListItems
2123
22−ScopeView {
24+FocusScope {
2325 id: scopeView
2426
27+ property Scope scope
28+ property SortFilterProxyModel categories: categoryFilter
29+ property bool isCurrent
2530 property ListModel searchHistory
31+ property alias moving: categoryView.moving
32+
33+ signal endReached
34+ signal movementStarted
35+ signal positionedAtBeginning
2636
2737 readonly property alias previewShown: previewListView.onScreen
2838 property bool enableHeightBehaviorOnNextCreation: false
2939
30− moving: categoryView.moving
40+ // FIXME delay the search so that daemons have time to settle, note that
41+ // removing this will break ScopeView::test_changeScope
42+ onScopeChanged: {
43+ if (scope) {
44+ timer.restart();
45+ scope.activateApplication.connect(activateApp);
46+ }
47+ }
48+
49+ function activateApp(desktopFilePath) {
50+ shell.activateApplication(desktopFilePath);
51+ }
52+
53+ Binding {
54+ target: scope
55+ property: "isActive"
56+ value: isCurrent
57+ }
58+
59+ Timer {
60+ id: timer
61+ interval: 2000
62+ onTriggered: scope.searchQuery = ""
63+ }
64+
65+ SortFilterProxyModel {
66+ id: categoryFilter
67+ model: scope ? scope.categories : null
68+ dynamicSortFilter: true
69+ filterRole: Categories.RoleCount
70+ filterRegExp: /^0$/
71+ invertMatch: true
72+ }
3173
3274 onIsCurrentChanged: {
3375 pageHeader.resetSearch();
@@ -133,14 +175,14 @@ ScopeView {
133175 target: rendererLoader.item
134176 onClicked: {
135177 // Prepare the preview in case activate() triggers a preview only
136− effect.positionPx = mapToItem(categoryView, 0, itemY).y
178+ effect.positionPx = Math.max(mapToItem(categoryView, 0, itemY).y, pageHeader.height + categoryView.stickyHeaderHeight);
137179 previewListView.categoryId = categoryId
138180 previewListView.categoryDelegate = rendererLoader.item
139− previewListView.model = model;
181+ previewListView.model = target.model;
140182 previewListView.init = true;
141183 previewListView.currentIndex = index;
142184
143− var item = model.get(index);
185+ var item = target.model.get(index);
144186
145187 if ((scopeView.scope.id == "applications.scope" && categoryId == "installed")
146188 || (scopeView.scope.id == "home.scope" && categoryId == "applications.scope")) {
@@ -154,15 +196,15 @@ ScopeView {
154196 }
155197 }
156198 onPressAndHold: {
157− effect.positionPx = mapToItem(categoryView, 0, itemY).y
199+ effect.positionPx = Math.max(mapToItem(categoryView, 0, itemY).y, pageHeader.height + categoryView.stickyHeaderHeight);
158200 previewListView.categoryId = categoryId
159201 previewListView.categoryDelegate = rendererLoader.item
160− previewListView.model = model;
202+ previewListView.model = target.model;
161203 previewListView.init = true;
162204 previewListView.currentIndex = index;
163205 previewListView.open = true
164206
165− var item = model.get(index)
207+ var item = target.model.get(index)
166208 scopeView.scope.preview( item.uri, item.icon, item.category, 0, item.mimetype, item.title,
167209 item.comment, item.dndUri, item.metadata)
168210 }
@@ -266,26 +308,27 @@ ScopeView {
266308 rendererId = getDefaultRendererId(contentType);
267309 }
268310 switch (rendererId) {
311+ case "carousel": {
312+ switch (contentType) {
313+ case "music": return "Music/MusicCarouselLoader.qml";
314+ case "video": return "Video/VideoCarouselLoader.qml";
315+ default: return "Generic/GenericCarouselLoader.qml";
316+ }
317+ }
269318 case "grid": {
270319 switch (contentType) {
271− case "video": return "Video/VideoFilterGrid.qml";
272− case "music": return "Music/MusicFilterGrid.qml";
273320 case "apps": {
274321 if (rendererHint == "toggled")
275322 return "Apps/DashPluginFilterGrid.qml";
276323 else
277324 return "Generic/GenericFilterGrid.qml";
278325 }
326+ case "music": return "Music/MusicFilterGrid.qml";
327+ case "video": return "Video/VideoFilterGrid.qml";
279328 case "weather": return "Generic/WeatherFilterGrid.qml";
280329 default: return "Generic/GenericFilterGrid.qml";
281330 }
282331 }
283− case "carousel": {
284− switch (contentType) {
285− case "music": return "Music/MusicCarousel.qml";
286− default: return "Generic/GenericCarousel.qml";
287− }
288− }
289332 case "special": {
290333 switch (contentType) {
291334 case "apps": return "Apps/RunningApplicationsGrid.qml";
@@ -396,12 +439,19 @@ ScopeView {
396439
397440 if (!init && model !== undefined) {
398441 var item = model.get(currentIndex)
399− scopeView.scope.preview( item.uri, item.icon, item.category, 0, item.mimetype, item.title, item.comment, item.dndUri, item.metadata)
442+ scopeView.scope.preview(item.uri, item.icon, item.category, 0, item.mimetype, item.title, item.comment, item.dndUri, item.metadata)
400443 }
401444
402445 var itemY = categoryView.contentItem.mapFromItem(categoryDelegate.currentItem).y;
446+
447+ // Find new contentY and effect.postionPx
403448 var newContentY = itemY - effect.positionPx - categoryDelegate.verticalSpacing;
404− var effectAdjust = effect.positionPx;
449+
450+ // Make sure the item is not covered by a header. Move the effect split down if necessary
451+ var headerHeight = pageHeader.height + categoryView.stickyHeaderHeight;
452+ var effectAdjust = Math.max(effect.positionPx, headerHeight);
453+
454+ // Make sure we don't overscroll the listview. If yes, adjust effect position
405455 if (newContentY < 0) {
406456 effectAdjust += newContentY;
407457 newContentY = 0;
@@ -412,7 +462,7 @@ ScopeView {
412462 }
413463
414464 effect.positionPx = effectAdjust;
415− categoryView.contentY = newContentY - categoryView.originY;
465+ categoryView.contentY = newContentY;
416466 }
417467
418468 property bool open: false
tests/mocks/QMenuModel/UnityMenuModel.qml → Dash/Music/MusicCarouselLoader.qmlrenamed+5−7
@@ -1,9 +1,6 @@
11/*
22 * Copyright (C) 2013 Canonical, Ltd.
33 *
4− * Authors:
5− * Mirco Müller <mirco.mueller@canonical.com>
6− *
74 * This program is free software; you can redistribute it and/or modify
85 * it under the terms of the GNU General Public License as published by
96 * the Free Software Foundation; version 3.
@@ -18,9 +15,10 @@
1815 */
1916
2017import QtQuick 2.0
18+import Ubuntu.Components 0.1
19+import "../Generic"
2120
22−QtObject {
23− property variant busName
24− property variant actions
25− property variant menuObjectPath
21+GenericCarouselLoader {
22+ carouselUrl: "MusicCarousel.qml"
23+ filtergridUrl: "MusicFilterGrid.qml"
2624}
Dash/Music/MusicFilterGrid.qml+2−2
@@ -44,11 +44,11 @@ GenericFilterGrid {
4444 }
4545
4646 onClicked: {
47− filtergrid.clicked(index, filtergrid.model, tile.y)
47+ filtergrid.clicked(index, tile.y)
4848 }
4949
5050 onPressAndHold: {
51− filtergrid.pressAndHold(index, filtergrid.model, tile.y)
51+ filtergrid.pressAndHold(index, tile.y)
5252 }
5353 }
5454}
Dash/ScopeView.qmldeleted−65
@@ -1,65 +0,0 @@
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 Utils 0.1
19−import Unity 0.1
20−
21−FocusScope {
22− property Scope scope
23− property SortFilterProxyModel categories: categoryFilter
24− property bool isCurrent
25− property ListModel searchHistory
26− property bool moving: false
27−
28− signal endReached
29− signal movementStarted
30− signal positionedAtBeginning
31−
32− // FIXME delay the search so that daemons have time to settle, note that
33− // removing this will break ScopeView::test_changeScope
34− onScopeChanged: {
35− if (scope) {
36− timer.restart();
37− scope.activateApplication.connect(activateApp);
38− }
39− }
40−
41− function activateApp(desktopFilePath) {
42− shell.activateApplication(desktopFilePath);
43− }
44−
45− Binding {
46− target: scope
47− property: "isActive"
48− value: isCurrent
49− }
50−
51− Timer {
52− id: timer
53− interval: 2000
54− onTriggered: scope.searchQuery = ""
55− }
56−
57− SortFilterProxyModel {
58− id: categoryFilter
59− model: scope ? scope.categories : null
60− dynamicSortFilter: true
61− filterRole: Categories.RoleCount
62− filterRegExp: /^0$/
63− invertMatch: true
64− }
65−}
Dash/Video/VideosCarousel.qml → Dash/Video/VideoCarousel.qmlrenamed

The content is the same.

Components/Math.js → Dash/Video/VideoCarouselLoader.qmlrenamed+6−8
@@ -14,13 +14,11 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−.pragma library
17+import QtQuick 2.0
18+import Ubuntu.Components 0.1
19+import "../Generic"
1820
19−function clamp(value, min, max) {
20− if (min <= max) {
21− return Math.max(min, Math.min(max, value))
22− } else {
23− // swap min/max if min > max
24− return clamp(value, max, min)
25− }
21+GenericCarouselLoader {
22+ carouselUrl: "VideoCarousel.qml"
23+ filtergridUrl: "VideoFilterGrid.qml"
2624}
Dash/Video/VideoFilterGrid.qml+2−2
@@ -42,11 +42,11 @@ GenericFilterGrid {
4242 style: VideoTileStyle {}
4343
4444 onClicked: {
45− filtergrid.clicked(index, filtergrid.model, tile.y)
45+ filtergrid.clicked(index, tile.y)
4646 }
4747
4848 onPressAndHold: {
49− filtergrid.pressAndHold(index, filtergrid.model, tile.y)
49+ filtergrid.pressAndHold(index, tile.y)
5050 }
5151 }
5252}
Dash/Video/VideoInfo.qmldeleted−84
@@ -1,84 +0,0 @@
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 QtQuick.XmlListModel 2.0
19−
20−Item {
21− id: info
22− property string source
23−
24− property bool ready: nfo.status == XmlListModel.Ready || nfoTV.status == XmlListModel.Ready
25− property bool isMovie: true
26− property variant video: null
27− property variant tvShow: null
28−
29− function getActors() {
30− var c = []
31− if (video.actor1) c.push(video.actor1)
32− if (video.actor2) c.push(video.actor2)
33− if (video.actor3) c.push(video.actor3)
34− return c
35− }
36−
37− onSourceChanged: isMovie = true
38−
39− XmlListModel {
40− id: nfo
41− source: info.source
42− query: (isMovie) ? "/movie" : "/episodedetails"
43−
44− XmlRole { name: "title"; query: "title/string()" }
45− XmlRole { name: "year"; query: "year/number()" }
46− XmlRole { name: "runtime"; query: "runtime/number()" }
47− XmlRole { name: "rating"; query: "rating/number()" }
48− XmlRole { name: "plot"; query: "plot/string()" }
49− XmlRole { name: "director"; query: "director[1]/string()" }
50− XmlRole { name: "actor1"; query: "actor[1]/name/string()" }
51− XmlRole { name: "actor2"; query: "actor[2]/name/string()" }
52− XmlRole { name: "actor3"; query: "actor[3]/name/string()" }
53− XmlRole { name: "author"; query: "author[1]/string()" }
54− XmlRole { name: "season"; query: "season/number()" }
55− XmlRole { name: "episode"; query: "episode/number()" }
56−
57− XmlRole { name: "rentPrice"; query: "rent_price/string()" }
58− XmlRole { name: "buyPrice"; query: "buy_price/string()" }
59− XmlRole { name: "expires"; query: "expires/string()" }
60−
61− onStatusChanged: if (status == XmlListModel.Ready) {
62− if (count > 0) info.video = nfo.get(0)
63− else info.isMovie = false
64− } else if (status == XmlListModel.Error) info.isMovie = false
65− }
66−
67− XmlListModel {
68− id: nfoTV
69− source: (nfo.isMovie) ? "" : info.source.substring(0, info.source.lastIndexOf("/") + 1) + "tvshow.nfo"
70− query: "/tvshow"
71−
72− XmlRole { name: "title"; query: "title/string()" }
73−
74− onStatusChanged: if (status == XmlListModel.Ready) {
75− if (count > 0) info.tvShow = nfoTV.get(0)
76− } else if (status == XmlListModel.Error) {
77− // Search for tvshow.nfo in the directory above this one to cater
78− // for directory layout Show/Season
79− var path = info.source.split("/")
80− path.splice(-2, 2, "tvshow.nfo")
81− source = path.join("/")
82− }
83− }
84−}
Greeter/Greeter.qml+2−2
@@ -19,7 +19,6 @@ import Ubuntu.Components 0.1
1919import Ubuntu.Gestures 0.1
2020import LightDM 0.1 as LightDM
2121import "../Components"
22−import "../Components/Math.js" as MathLocal
2322
2423Showable {
2524 id: greeter
@@ -29,7 +28,7 @@ Showable {
2928 property url defaultBackground
3029
3130 // 1 when fully shown and 0 when fully hidden
32− property real showProgress: MathLocal.clamp((width + x) / width, 0, 1)
31+ property real showProgress: MathUtils.clamp((width + x) / width, 0, 1)
3332
3433 showAnimation: StandardAnimation { property: "x"; to: 0 }
3534 hideAnimation: StandardAnimation { property: "x"; to: -width }
@@ -64,6 +63,7 @@ Showable {
6463 property var model: LightDM.Users
6564 property int currentIndex: 0
6665 property var infographicModel: LightDM.Infographic
66+ readonly property int backgroundTopMargin: -greeter.y
6767
6868 source: required ? "GreeterContent.qml" : ""
6969
Greeter/GreeterContent.qml+23−20
@@ -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 }
@@ -71,17 +74,6 @@ MouseArea {
7174 opacity: 0.4
7275 }
7376
74− Clock {
75− id: clock
76− visible: narrowMode
77−
78− anchors {
79− top: parent.top
80− topMargin: units.gu(2)
81− horizontalCenter: parent.horizontalCenter
82− }
83− }
84−
8577 MouseArea {
8678 id: teasingMouseArea
8779 anchors.fill: parent
@@ -160,4 +152,15 @@ MouseArea {
160152 right: root.right
161153 }
162154 }
155+
156+ Clock {
157+ id: clock
158+ visible: narrowMode
159+
160+ anchors {
161+ top: parent.top
162+ topMargin: units.gu(2)
163+ horizontalCenter: parent.horizontalCenter
164+ }
165+ }
163166}
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+1−1
@@ -29,7 +29,7 @@ Item {
2929 property int panelWidth: units.gu(8)
3030 property int dragAreaWidth: units.gu(1)
3131 property int minimizeDistance: units.gu(26)
32− property real progress: dragArea.dragging && dragArea.touchX > panelWidth ?
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;
Panel/Indicators.qml+37−10
@@ -21,7 +21,6 @@ import Unity.Indicators 0.1 as Indicators
2121
2222import "../Components"
2323import "../Components/ListItems"
24−import "../Components/Math.js" as MathLocal
2524
2625Showable {
2726 id: indicators
@@ -38,6 +37,7 @@ Showable {
3837 property bool partiallyOpened: height > panelHeight && !fullyOpened
3938 property real visualBottom: Math.max(y+height, y+indicatorRow.y+indicatorRow.height)
4039 property bool contentEnabled: true
40+ property bool initalizeItem: true
4141 readonly property alias content: menuContent
4242
4343 // TODO: Perhaps we need a animation standard for showing/hiding? Each showable seems to
@@ -64,14 +64,13 @@ Showable {
6464 }
6565
6666 height: panelHeight
67+ onHeightChanged: updateRevealProgressState(indicators.height - panelHeight, true)
6768
68− onHeightChanged: {
69− // need to use handle.get_height(). As the handle height depends on indicators.height changes (but this is called first!)
70− var revealProgress = indicators.height - panelHeight
69+ function updateRevealProgressState(revealProgress, enableRelease) {
7170 if (!showAnimation.running && !hideAnimation.running) {
72− if (revealProgress == 0) {
71+ if (revealProgress === 0) {
7372 indicators.state = "initial";
74− } else if (revealProgress <= hintValue) {
73+ } else if (revealProgress > 0 && revealProgress <= hintValue) {
7574 indicators.state = "hint";
7675 } else if (revealProgress > hintValue && revealProgress < lockThreshold) {
7776 indicators.state = "reveal";
@@ -80,7 +79,7 @@ Showable {
8079 }
8180 }
8281
83− if (revealProgress == 0) {
82+ if (enableRelease && revealProgress === 0) {
8483 menuContent.releaseContent();
8584 }
8685 }
@@ -100,14 +99,14 @@ Showable {
10099 Otherwise it contains the bar's location as a fraction of the distance between hintValue (is 0) and lockThreshold (is 1).
101100 */
102101 var verticalProgress =
103− MathLocal.clamp((indicators.height - handle.height - hintValue) /
102+ MathUtils.clamp((indicators.height - handle.height - hintValue) /
104103 (lockThreshold - hintValue), 0, 1);
105104
106105 /*
107106 Vertical velocity check. Don't change the indicator if we're moving too quickly.
108107 */
109108 var verticalSpeed = Math.abs(yVelocityCalculator.calculate());
110− if (verticalSpeed >= 0.05 && indicatorRow.currentItem!=null) {
109+ if (verticalSpeed >= 0.05 && !initalizeItem) {
111110 return;
112111 }
113112
@@ -147,6 +146,7 @@ Showable {
147146 } else if (!currentItem) {
148147 indicatorRow.setDefaultItem();
149148 }
149+ initalizeItem = indicatorRow.currentItem == null;
150150 }
151151
152152 // eater
@@ -282,6 +282,33 @@ Showable {
282282 enableIndexChangeSignal = oldActive;
283283 }
284284 }
285+
286+ EdgeDragArea {
287+ id: rowDragArea
288+ anchors.fill: indicatorRow
289+ direction: Direction.Downwards
290+ maxSilenceTime: 2000
291+ distanceThreshold: 0
292+
293+ enabled: fullyOpened
294+ onDraggingChanged: {
295+ if (dragging) {
296+ initalizeItem = true;
297+ updateRevealProgressState(Math.max(touchSceneY - panelHeight, hintValue), false);
298+ indicators.calculateCurrentItem(touchX, false);
299+ } else {
300+ indicators.state = "commit";
301+ }
302+ }
303+
304+ onTouchXChanged: {
305+ indicators.calculateCurrentItem(touchX, true);
306+ }
307+ onTouchSceneYChanged: {
308+ updateRevealProgressState(Math.max(touchSceneY - panelHeight, hintValue), false);
309+ yVelocityCalculator.trackedPosition = touchSceneY;
310+ }
311+ }
285312 }
286313
287314 Connections {
@@ -298,7 +325,7 @@ Showable {
298325 onRunningChanged: {
299326 if (hideAnimation.running) {
300327 indicators.state = "initial";
301− indicatorRow.currentItem = null;
328+ initalizeItem = true;
302329 }
303330 }
304331 }
Panel/Indicators/DefaultIndicatorWidget.qml+32−10
@@ -24,7 +24,7 @@ import Unity.Indicators 0.1 as Indicators
2424Indicators.IndicatorWidget {
2525 id: indicatorWidget
2626
27− width: itemRow.width + units.gu(0.5)
27+ width: itemRow.width
2828
2929 property alias leftLabel: itemLeftLabel.text
3030 property alias rightLabel: itemRightLabel.text
@@ -32,16 +32,17 @@ Indicators.IndicatorWidget {
3232
3333 Row {
3434 id: itemRow
35+ width: childrenRect.width
3536 objectName: "itemRow"
3637 anchors {
3738 top: parent.top
3839 bottom: parent.bottom
3940 horizontalCenter: parent.horizontalCenter
4041 }
41− spacing: units.gu(0.5)
4242
4343 Label {
4444 id: itemLeftLabel
45+ width: guRoundUp(implicitWidth)
4546 objectName: "leftLabel"
4647 color: Theme.palette.selected.backgroundText
4748 opacity: 0.8
@@ -57,25 +58,35 @@ Indicators.IndicatorWidget {
5758 top: parent.top
5859 bottom: parent.bottom
5960 }
60− spacing: units.gu(0.5)
6161
6262 Repeater {
6363 model: indicatorWidget.icons
6464
65− Image {
66− id: itemImage
67− objectName: "itemImage"
68− visible: source != ""
69− source: modelData
65+ Item {
66+ width: guRoundUp(itemImage.width)
7067 height: indicatorWidget.iconSize
71− width: indicatorWidget.iconSize
72− anchors.verticalCenter: parent.verticalCenter
68+
69+ Image {
70+ id: itemImage
71+ objectName: "itemImage"
72+ visible: source != ""
73+ source: modelData
74+ height: parent.height
75+ anchors.horizontalCenter: parent.horizontalCenter
76+ fillMode: Image.PreserveAspectFit
77+
78+ sourceSize {
79+ width: indicatorWidget.iconSize
80+ height: indicatorWidget.iconSize
81+ }
82+ }
7383 }
7484 }
7585 }
7686
7787 Label {
7888 id: itemRightLabel
89+ width: guRoundUp(implicitWidth)
7990 objectName: "rightLabel"
8091 color: Theme.palette.selected.backgroundText
8192 opacity: 0.8
@@ -86,6 +97,17 @@ Indicators.IndicatorWidget {
8697 }
8798 }
8899
100+ // TODO: Use toolkit function https://bugs.launchpad.net/ubuntu-ui-toolkit/+bug/1242575
101+ function guRoundUp(width) {
102+ if (width == 0) {
103+ return 0;
104+ }
105+ var gu1 = units.gu(1.0);
106+ var mod = (width % gu1);
107+
108+ return mod == 0 ? width : width + (gu1 - mod);
109+ }
110+
89111 onRootActionStateChanged: {
90112 if (rootActionState == undefined) {
91113 leftLabel = "";
Shell.qml+9−3
@@ -30,7 +30,6 @@ import "Launcher"
3030import "Panel"
3131import "Hud"
3232import "Components"
33−import "Components/Math.js" as MathLocal
3433import "Bottombar"
3534import "SideStage"
3635import "Notifications"
@@ -235,7 +234,7 @@ FocusScope {
235234 Behavior on x {SmoothedAnimation{velocity: 600}}
236235
237236 property real showProgress:
238− MathLocal.clamp(1 - (x + stages.x) / shell.width, 0, 1)
237+ MathUtils.clamp(1 - (x + stages.x) / shell.width, 0, 1)
239238
240239 Showable {
241240 id: stages
@@ -400,6 +399,10 @@ FocusScope {
400399
401400 Lockscreen {
402401 id: lockscreen
402+ objectName: "lockscreen"
403+
404+ readonly property int backgroundTopMargin: -panel.panelHeight
405+
403406 hides: [launcher, panel.indicators, hud]
404407 shown: false
405408 enabled: true
@@ -645,19 +648,22 @@ FocusScope {
645648 Launcher {
646649 id: launcher
647650
651+ readonly property bool dashSwipe: progress > 0
652+
648653 anchors.top: parent.top
649654 anchors.bottom: parent.bottom
650655 width: parent.width
651656 dragAreaWidth: shell.edgeSize
652657 available: (!greeter.shown || greeter.narrowMode) && edgeDemo.launcherEnabled
658+
653659 onDashItemSelected: showHome()
654660 onDash: {
655661 if (stages.shown) {
656− dash.setCurrentScope("applications.scope", true /* animate */, true /* reset */)
657662 stages.hide();
658663 launcher.hide();
659664 }
660665 }
666+ onDashSwipeChanged: if (dashSwipe && stages.shown) dash.setCurrentScope("applications.scope", false, true)
661667 onLauncherApplicationSelected:{
662668 greeter.hide()
663669 shell.activateApplication(appId)
data/unity8.conf+20
@@ -6,4 +6,24 @@ stop on desktop-end
66
77respawn
88
9+pre-start script
10+ if [ -n "$MIR_SOCKET" ]; then
11+ if [ -z "$UNITY_MIR_SOCKET" ]; then
12+ # Save original value of MIR_SOCKET in case we are restarted,
13+ # as we modify the variable for future jobs, including ourself.
14+ UNITY_MIR_SOCKET=$MIR_SOCKET
15+ initctl set-env --global UNITY_MIR_SOCKET=$UNITY_MIR_SOCKET
16+ fi
17+
18+ # Point unity8 at unity-system-compositor
19+ MIR_SERVER_FILE=$XDG_RUNTIME_DIR/mir_socket
20+ initctl set-env MIR_SERVER_FILE=$MIR_SERVER_FILE
21+ initctl set-env MIR_SERVER_HOST_SOCKET=$UNITY_MIR_SOCKET
22+
23+ # Point all future jobs in this session to our Mir socket instead of
24+ # unity-system-compositor's socket.
25+ initctl set-env --global MIR_SOCKET=$MIR_SERVER_FILE
26+ fi
27+end script
28+
929exec ${BINARY:-unity8} $ARGS
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/ListViewWithPageHeader/listviewwithpageheader.cpp+11−1
@@ -155,6 +155,7 @@ ListViewWithPageHeader::ListViewWithPageHeader()
155155 , m_topSectionItem(nullptr)
156156 , m_forceNoClip(false)
157157 , m_inLayout(false)
158+ , m_inContentHeightKeepHeaderShown(false)
158159{
159160 m_clipItem = new QQuickItem(contentItem());
160161// m_clipItem = new QQuickRectangle(contentItem());
@@ -286,10 +287,12 @@ void ListViewWithPageHeader::setSectionDelegate(QQmlComponent *delegate)
286287 m_topSectionItem = getSectionItem(QString());
287288 m_topSectionItem->setZ(3);
288289 QQuickItemPrivate::get(m_topSectionItem)->setCulled(true);
290+ connect(m_topSectionItem, SIGNAL(heightChanged()), SIGNAL(stickyHeaderHeightChanged()));
289291
290292 // TODO create sections for existing items
291293
292294 Q_EMIT sectionDelegateChanged();
295+ Q_EMIT stickyHeaderHeightChanged();
293296 }
294297}
295298
@@ -325,6 +328,11 @@ void ListViewWithPageHeader::setForceNoClip(bool noClip)
325328 }
326329}
327330
331+int ListViewWithPageHeader::stickyHeaderHeight() const
332+{
333+ return m_topSectionItem ? m_topSectionItem->height() : 0;
334+}
335+
328336void ListViewWithPageHeader::positionAtBeginning()
329337{
330338 if (m_delegateModel->count() <= 0)
@@ -494,7 +502,7 @@ void ListViewWithPageHeader::viewportMoved(Qt::Orientations orient)
494502 if (!scrolledUp && contentY() == -m_minYExtent) {
495503 m_headerItemShownHeight = 0;
496504 m_headerItem->setY(contentY());
497− } else if ((scrolledUp && notRebounding && notShownByItsOwn && !maximizeVisibleAreaRunning) || (m_headerItemShownHeight > 0)) {
505+ } else if ((scrolledUp && notRebounding && notShownByItsOwn && !maximizeVisibleAreaRunning) || (m_headerItemShownHeight > 0) || m_inContentHeightKeepHeaderShown) {
498506 if (maximizeVisibleAreaRunning && diff > 0) // If we are maximizing and the header was shown, make sure we hide it
499507 m_headerItemShownHeight -= diff;
500508 else
@@ -1267,7 +1275,9 @@ void ListViewWithPageHeader::updatePolish()
12671275
12681276 m_contentHeightDirty = false;
12691277 adjustMinYExtent();
1278+ m_inContentHeightKeepHeaderShown = m_headerItem && m_headerItem->y() == contentY();
12701279 setContentHeight(contentHeight);
1280+ m_inContentHeightKeepHeaderShown = false;
12711281 }
12721282}
12731283
plugins/ListViewWithPageHeader/listviewwithpageheader.h+5
@@ -60,6 +60,7 @@ class ListViewWithPageHeader : public QQuickFlickable, public QQuickItemChangeLi
6060 Q_PROPERTY(QQmlComponent *sectionDelegate READ sectionDelegate WRITE setSectionDelegate NOTIFY sectionDelegateChanged)
6161 Q_PROPERTY(QString sectionProperty READ sectionProperty WRITE setSectionProperty NOTIFY sectionPropertyChanged)
6262 Q_PROPERTY(bool forceNoClip READ forceNoClip WRITE setForceNoClip NOTIFY forceNoClipChanged)
63+ Q_PROPERTY(int stickyHeaderHeight READ stickyHeaderHeight NOTIFY stickyHeaderHeightChanged)
6364
6465 friend class ListViewWithPageHeaderTest;
6566 friend class ListViewWithPageHeaderTestSection;
@@ -87,6 +88,8 @@ public:
8788 bool forceNoClip() const;
8889 void setForceNoClip(bool noClip);
8990
91+ int stickyHeaderHeight() const;
92+
9093 Q_INVOKABLE void positionAtBeginning();
9194 Q_INVOKABLE void showHeader();
9295 Q_INVOKABLE QQuickItem *item(int modelIndex) const;
@@ -104,6 +107,7 @@ Q_SIGNALS:
104107 void sectionDelegateChanged();
105108 void sectionPropertyChanged();
106109 void forceNoClipChanged();
110+ void stickyHeaderHeightChanged();
107111
108112protected:
109113 void componentComplete();
@@ -202,6 +206,7 @@ private:
202206
203207 bool m_forceNoClip;
204208 bool m_inLayout;
209+ bool m_inContentHeightKeepHeaderShown;
205210
206211 // Qt 5.0 doesn't like releasing the items just after itemCreated
207212 // so we delay the releasing until the next updatePolish
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/CMakeLists.txt−1
@@ -34,7 +34,6 @@ set(QMLPLUGIN_SRC
3434 radiooptionfilter.cpp
3535 ratingsfilter.cpp
3636 ratingfilteroption.cpp
37− bottombarvisibilitycommunicatorshell.cpp
3837 applicationpreview.cpp
3938 genericpreview.cpp
4039 moviepreview.cpp
plugins/Unity/Indicators/qml/IndicatorWidget.qml+1−1
@@ -24,5 +24,5 @@ IndicatorBase {
2424 id: indicatorWidget
2525
2626 enabled: false
27− property int iconSize: height - units.gu(0.5)
27+ property int iconSize: height
2828}
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)
plugins/Unity/Indicators/unitymenumodelstack.cpp+98−7
@@ -19,6 +19,64 @@
1919
2020#include "unitymenumodelstack.h"
2121
22+#include <QDebug>
23+#include <unitymenumodel.h>
24+
25+class UnityMenuModelEntry : public QObject {
26+ Q_OBJECT
27+public:
28+ UnityMenuModelEntry(UnityMenuModel* model, UnityMenuModel* parentModel, int index)
29+ : m_model(model),
30+ m_parentModel(parentModel),
31+ m_index(index)
32+ {
33+ if (m_parentModel) {
34+ QObject::connect(m_parentModel, SIGNAL(rowsInserted(QModelIndex, int, int)), this, SLOT(onRowsInserted(QModelIndex, int, int)));
35+ QObject::connect(m_parentModel, SIGNAL(rowsRemoved(QModelIndex, int, int)), this, SLOT(onRowsRemoved(QModelIndex, int, int)));
36+ QObject::connect(m_parentModel, SIGNAL(modelReset()), this, SLOT(onModelReset()));
37+ }
38+ }
39+
40+ UnityMenuModel* model() const { return m_model; }
41+
42+private Q_SLOTS:
43+ void onRowsInserted(const QModelIndex&, int start, int end)
44+ {
45+ int delta = end-start + 1;
46+ if (start <= m_index) {
47+ m_index += delta;
48+ }
49+ }
50+
51+ void onRowsRemoved(const QModelIndex&, int start, int end)
52+ {
53+ int delta = end-start + 1;
54+ if (start <= m_index) {
55+ if (start + delta > m_index) {
56+ // in the range removed
57+ Q_EMIT remove();
58+ disconnect(m_parentModel, 0, this, 0);
59+ } else {
60+ m_index -= delta;
61+ }
62+ }
63+ }
64+
65+ void onModelReset()
66+ {
67+ Q_EMIT remove();
68+ disconnect(m_parentModel, 0, this, 0);
69+ }
70+
71+Q_SIGNALS:
72+ void remove();
73+
74+private:
75+ UnityMenuModel* m_model;
76+ UnityMenuModel* m_parentModel;
77+ int m_index;
78+};
79+
2280UnityMenuModelStack::UnityMenuModelStack(QObject* parent)
2381 : QObject(parent)
2482{
@@ -26,31 +84,44 @@ UnityMenuModelStack::UnityMenuModelStack(QObject* parent)
2684
2785UnityMenuModelStack::~UnityMenuModelStack()
2886{
87+ qDeleteAll(m_menuModels);
88+ m_menuModels.clear();
2989}
3090
3191UnityMenuModel* UnityMenuModelStack::head() const
3292{
33− return !m_menuModels.isEmpty() ? m_menuModels.first() : NULL;
93+ return !m_menuModels.isEmpty() ? m_menuModels.first()->model() : NULL;
3494}
3595
3696void UnityMenuModelStack::setHead(UnityMenuModel* model)
3797{
3898 if (head() != model) {
99+ qDeleteAll(m_menuModels);
39100 m_menuModels.clear();
40− push(model);
101+
102+ push(model, 0);
41103 Q_EMIT headChanged(model);
42104 }
43105}
44106
45107UnityMenuModel* UnityMenuModelStack::tail() const
46108{
47− return !m_menuModels.isEmpty() ? m_menuModels.last() : NULL;
109+ return !m_menuModels.isEmpty() ? m_menuModels.last()->model() : NULL;
110+}
111+
112+int UnityMenuModelStack::count() const
113+{
114+ return m_menuModels.count();
48115}
49116
50−void UnityMenuModelStack::push(UnityMenuModel* model)
117+void UnityMenuModelStack::push(UnityMenuModel* model, int index)
51118{
52− m_menuModels << model;
119+ UnityMenuModelEntry* entry = new UnityMenuModelEntry(model, tail(), index);
120+ QObject::connect(entry, SIGNAL(remove()), SLOT(onRemove()));
121+
122+ m_menuModels << entry;
53123 Q_EMIT tailChanged(model);
124+ Q_EMIT countChanged(m_menuModels.count());
54125}
55126
56127UnityMenuModel* UnityMenuModelStack::pop()
@@ -58,12 +129,32 @@ UnityMenuModel* UnityMenuModelStack::pop()
58129 if (m_menuModels.isEmpty()) {
59130 return NULL;
60131 }
61− UnityMenuModel* model = m_menuModels.takeLast();
132+ UnityMenuModelEntry* entry = m_menuModels.takeLast();
133+ UnityMenuModel* model = entry->model();
134+ entry->deleteLater();
62135
63136 Q_EMIT tailChanged(tail());
64137 if (m_menuModels.isEmpty()) {
65138 Q_EMIT headChanged(NULL);
66139 }
140+ Q_EMIT countChanged(m_menuModels.count());
67141
68142 return model;
69−}
143+}
144+
145+void UnityMenuModelStack::onRemove()
146+{
147+ UnityMenuModelEntry* removed = qobject_cast<UnityMenuModelEntry*>(sender());
148+ if (!m_menuModels.contains(removed))
149+ return;
150+
151+ for (int i = m_menuModels.count() -1; i >= 0; i--) {
152+ UnityMenuModelEntry* entry = m_menuModels[i];
153+ pop();
154+ if (entry == removed) {
155+ break;
156+ }
157+ }
158+}
159+
160+#include "unitymenumodelstack.moc"
plugins/Unity/Indicators/unitymenumodelstack.h+10−2
@@ -25,6 +25,7 @@
2525#include <QObject>
2626#include <QList>
2727
28+class UnityMenuModelEntry;
2829class UnityMenuModel;
2930
3031// A LIFO queue for storing the current submenu of a UnityMenuModel.
@@ -37,6 +38,7 @@ class UNITYINDICATORS_EXPORT UnityMenuModelStack : public QObject
3738 Q_OBJECT
3839 Q_PROPERTY(UnityMenuModel* head READ head WRITE setHead NOTIFY headChanged)
3940 Q_PROPERTY(UnityMenuModel* tail READ tail NOTIFY tailChanged)
41+ Q_PROPERTY(int count READ count NOTIFY countChanged)
4042public:
4143 UnityMenuModelStack(QObject*parent=NULL);
4244 ~UnityMenuModelStack();
@@ -46,15 +48,21 @@ public:
4648
4749 UnityMenuModel* tail() const;
4850
49− Q_INVOKABLE void push(UnityMenuModel* model);
51+ int count() const;
52+
53+ Q_INVOKABLE void push(UnityMenuModel* model, int menuIndex);
5054 Q_INVOKABLE UnityMenuModel* pop();
5155
5256Q_SIGNALS:
5357 void headChanged(UnityMenuModel* head);
5458 void tailChanged(UnityMenuModel* tail);
59+ void countChanged(int count);
60+
61+private Q_SLOTS:
62+ void onRemove();
5563
5664private:
57− QList<UnityMenuModel*> m_menuModels;
65+ QList<UnityMenuModelEntry*> m_menuModels;
5866};
5967
6068#endif // UNITYMENUMODELSTACK_H
plugins/Unity/Launcher/launcheritem.cpp+4−2
@@ -20,6 +20,8 @@
2020#include "launcheritem.h"
2121#include "quicklistmodel.h"
2222
23+#include <libintl.h>
24+
2325LauncherItem::LauncherItem(const QString &appId, const QString &name, const QString &icon, QObject *parent) :
2426 LauncherItemInterface(parent),
2527 m_appId(appId),
@@ -38,7 +40,7 @@ LauncherItem::LauncherItem(const QString &appId, const QString &name, const QStr
3840 m_quickList->appendAction(nameAction);
3941 QuickListEntry pinningAction;
4042 pinningAction.setActionId("pin_item");
41− pinningAction.setText("Pin to Launcher");
43+ pinningAction.setText(gettext("Lock to Launcher"));
4244 m_quickList->appendAction(pinningAction);
4345}
4446
@@ -68,7 +70,7 @@ void LauncherItem::setPinned(bool pinned)
6870 m_pinned = pinned;
6971 QuickListEntry entry;
7072 entry.setActionId("pin_item");
71− entry.setText(pinned ? "Remove from Launcher": "Pin to Launcher");
73+ entry.setText(pinned ? gettext("Unlock from Launcher") : gettext("Lock to Launcher"));
7274 m_quickList->updateAction(entry);
7375 Q_EMIT pinnedChanged(pinned);
7476 }
plugins/Unity/iconutils.cpp+10−10
@@ -17,11 +17,13 @@
1717 * Michal Hruby <michal.hruby@canonical.com>
1818 */
1919
20−#include <QStringList>
21−#include <QUrl>
20+#include "iconutils.h"
2221
2322#include <gio/gio.h>
24−#include "iconutils.h"
23+
24+#include <QStringList>
25+#include <QUrl>
26+#include <QUrlQuery>
2527
2628#define BASE_THEME_ICON_URI "image://theme/"
2729#define BASE_THUMBNAILER_URI "image://thumbnailer/"
@@ -104,13 +106,11 @@ QString uriToThumbnailerProviderString(QString const &uri, QString const &mimety
104106 if (contentHash.contains("content")) { // nested content in Home?
105107 contentHash = contentHash["content"].toHash();
106108 }
107− if (contentHash.contains("album") &&
108− contentHash.contains("artist")) {
109− const QString album = contentHash["album"].toString();
110− const QString artist = contentHash["artist"].toString();
111− thumbnailerUri.append(QUrl::toPercentEncoding(artist));
112− thumbnailerUri.append("/");
113− thumbnailerUri.append(QUrl::toPercentEncoding(album));
109+ if (contentHash.contains("album") && contentHash.contains("artist")) {
110+ QUrlQuery query;
111+ query.addQueryItem(QStringLiteral("artist"), contentHash["artist"].toString());
112+ query.addQueryItem(QStringLiteral("album"), contentHash["album"].toString());
113+ thumbnailerUri.append(query.toString());
114114 }
115115 }
116116 } else {
plugins/Unity/plugin.cpp−12
@@ -17,8 +17,6 @@
1717 */
1818
1919// Qt
20−#include <QDBusConnection>
21−#include <QQmlContext>
2220#include <qqml.h>
2321
2422// self
@@ -33,16 +31,12 @@
3331#include "scopes.h"
3432#include "categories.h"
3533#include "categoryresults.h"
36−#include "bottombarvisibilitycommunicatorshell.h"
3734#include "genericoptionsmodel.h"
3835#include "result.h"
3936
4037// libqtdee
4138#include "deelistmodel.h"
4239
43−static const char* BOTTOM_BAR_VISIBILITY_COMMUNICATOR_DBUS_PATH = "/BottomBarVisibilityCommunicator";
44−static const char* DBUS_SERVICE = "com.canonical.Shell.BottomBarVisibilityCommunicator";
45−
4640void UnityPlugin::registerTypes(const char *uri)
4741{
4842 Q_ASSERT(uri == QLatin1String("Unity"));
@@ -57,7 +51,6 @@ void UnityPlugin::registerTypes(const char *uri)
5751 qmlRegisterType<Categories>(uri, 0, 1, "Categories");
5852 qmlRegisterUncreatableType<CategoryResults>(uri, 0, 1, "CategoryResults", "Can't create new Category Results in QML. Get them from Categories instance.");
5953 qmlRegisterType<DeeListModel>(uri, 0, 1, "DeeListModel");
60− qmlRegisterUncreatableType<BottomBarVisibilityCommunicatorShell>(uri, 0, 1, "BottomBarVisibilityCommunicatorShell", "Can't create BottomBarVisibilityCommunicatorShell");
6154}
6255
6356void UnityPlugin::initializeEngine(QQmlEngine *engine, const char *uri)
@@ -66,9 +59,4 @@ void UnityPlugin::initializeEngine(QQmlEngine *engine, const char *uri)
6659#ifndef GLIB_VERSION_2_36
6760 g_type_init();
6861#endif
69−
70− QDBusConnection::sessionBus().registerService(DBUS_SERVICE);
71− BottomBarVisibilityCommunicatorShell *bottomBarVisibilityCommunicator = &BottomBarVisibilityCommunicatorShell::instance();
72− QDBusConnection::sessionBus().registerObject(BOTTOM_BAR_VISIBILITY_COMMUNICATOR_DBUS_PATH, bottomBarVisibilityCommunicator, QDBusConnection::ExportAllContents);
73− engine->rootContext()->setContextProperty("bottomBarVisibilityCommunicatorShell", bottomBarVisibilityCommunicator);
7462}
plugins/Utils/CMakeLists.txt+1
@@ -13,6 +13,7 @@ include_directories(
1313set(QMLPLUGIN_SRC
1414 albumartprovider.cpp
1515 applicationpaths.h
16+ bottombarvisibilitycommunicatorshell.cpp
1617 mediaartcache.cpp
1718 qlimitproxymodelqml.cpp
1819 qsortfilterproxymodelqml.cpp
plugins/Utils/albumartprovider.cpp+10−7
@@ -32,6 +32,7 @@
3232#include <QByteArray>
3333#include <QImage>
3434#include <QUrl>
35+#include <QUrlQuery>
3536
3637using namespace std;
3738
@@ -65,6 +66,9 @@ AlbumArtProvider::~AlbumArtProvider()
6566std::string AlbumArtProvider::get_lastfm_url(const albuminfo &ai) {
6667 QString artist = QString::fromStdString(ai.artist);
6768 QString album = QString::fromStdString(ai.album);
69+ // audioscrobbler wants it without any / (as it would break the URL)
70+ artist.remove('/');
71+ album.remove('/');
6872
6973 /// @todo: this is the old API which will probably get axed at some point in the future
7074 /// The new 2.0 API requires an API key, but supports JSON output, etc, so switching
@@ -200,21 +204,20 @@ std::string AlbumArtProvider::get_image(const std::string &artist, const std::st
200204QImage AlbumArtProvider::requestImage(const QString &id, QSize *realSize, const QSize &requestedSize) {
201205 Q_UNUSED(requestedSize)
202206
203− const QStringList parts = id.split("/");
204− if (parts.size() != 2) {
207+ QUrlQuery query(id);
208+ if (!query.hasQueryItem(QStringLiteral("artist")) || !query.hasQueryItem(QStringLiteral("album"))) {
205209 qWarning() << "Invalid albumart uri:" << id;
206210 return QImage(QString::fromStdString(DEFAULT_ALBUM_ART));
207211 }
208− const std::string artist = QUrl::fromPercentEncoding(parts[0].toUtf8()).toStdString();
209− const std::string album = QUrl::fromPercentEncoding(parts[1].toUtf8()).toStdString();
212+ const QString artist = query.queryItemValue(QStringLiteral("artist"), QUrl::FullyEncoded);
213+ const QString album = query.queryItemValue(QStringLiteral("album"), QUrl::FullyEncoded);
210214
211215 std::string tgt_path;
212216 try {
213− tgt_path = get_image(artist, album);
217+ tgt_path = get_image(artist.toStdString(), album.toStdString());
214218 if(!tgt_path.empty()) {
215− QString tgt(tgt_path.c_str());
216219 QImage image;
217− image.load(tgt);
220+ image.load(QString::fromStdString(tgt_path));
218221 // FIXME: Rescale to requested size preserving aspect.
219222 *realSize = image.size();
220223 return image;
plugins/Unity/bottombarvisibilitycommunicatorshell.cpp → plugins/Utils/bottombarvisibilitycommunicatorshell.cpprenamed

The content is the same.

plugins/Unity/bottombarvisibilitycommunicatorshell.h → plugins/Utils/bottombarvisibilitycommunicatorshell.hrenamed

The content is the same.

plugins/Utils/plugin.cpp+12
@@ -18,6 +18,8 @@
1818
1919// Qt
2020#include <QtQml/qqml.h>
21+#include <QDBusConnection>
22+#include <QQmlContext>
2123#include <QtQuick/QQuickWindow>
2224#include <QDebug>
2325// self
@@ -26,11 +28,15 @@
2628// local
2729#include "albumartprovider.h"
2830#include "applicationpaths.h"
31+#include "bottombarvisibilitycommunicatorshell.h"
2932#include "qlimitproxymodelqml.h"
3033#include "qsortfilterproxymodelqml.h"
3134#include "ubuntuwindow.h"
3235#include "unitymenumodelpaths.h"
3336
37+static const char* BOTTOM_BAR_VISIBILITY_COMMUNICATOR_DBUS_PATH = "/BottomBarVisibilityCommunicator";
38+static const char* DBUS_SERVICE = "com.canonical.Shell.BottomBarVisibilityCommunicator";
39+
3440static QObject* applicationsPathsSingleton(QQmlEngine* engine, QJSEngine* scriptEngine) {
3541 Q_UNUSED(engine);
3642 Q_UNUSED(scriptEngine);
@@ -46,6 +52,7 @@ void UtilsPlugin::registerTypes(const char *uri)
4652 qmlRegisterType<UnityMenuModelPaths>(uri, 0, 1, "UnityMenuModelPaths");
4753 qmlRegisterExtendedType<QQuickWindow, UbuntuWindow>(uri, 0, 1, "Window");
4854 qmlRegisterSingletonType<ApplicationPaths>(uri, 0, 1, "ApplicationPaths", applicationsPathsSingleton);
55+ qmlRegisterUncreatableType<BottomBarVisibilityCommunicatorShell>(uri, 0, 1, "BottomBarVisibilityCommunicatorShell", "Can't create BottomBarVisibilityCommunicatorShell");
4956}
5057
5158void UtilsPlugin::initializeEngine(QQmlEngine *engine, const char *uri)
@@ -64,4 +71,9 @@ void UtilsPlugin::initializeEngine(QQmlEngine *engine, const char *uri)
6471 {
6572 qWarning() << "Failed to register image provider for albumart (unknown error)";
6673 }
74+
75+ QDBusConnection::sessionBus().registerService(DBUS_SERVICE);
76+ BottomBarVisibilityCommunicatorShell *bottomBarVisibilityCommunicator = &BottomBarVisibilityCommunicatorShell::instance();
77+ QDBusConnection::sessionBus().registerObject(BOTTOM_BAR_VISIBILITY_COMMUNICATOR_DBUS_PATH, bottomBarVisibilityCommunicator, QDBusConnection::ExportAllContents);
78+ engine->rootContext()->setContextProperty("bottomBarVisibilityCommunicatorShell", bottomBarVisibilityCommunicator);
6779}
po/ar.po+23−10
@@ -7,8 +7,8 @@ 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"
11−"PO-Revision-Date: 2013-10-20 19:41+0000\n"
10+"POT-Creation-Date: 2013-11-12 16:10+0100\n"
11+"PO-Revision-Date: 2013-11-15 12:29+0000\n"
1212"Last-Translator: Ibrahim Saed <ibraheem5000@gmail.com>\n"
1313"Language-Team: Arabic <ar@li.org>\n"
1414"MIME-Version: 1.0\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-19 05:59+0000\n"
20+"X-Generator: Launchpad (build 16831)\n"
2121
2222#: Applications/applications.js:23
2323msgid "Phone"
@@ -87,7 +87,7 @@ msgstr "ويكيبيديا"
8787msgid "YouTube"
8888msgstr "يوتيوب"
8989
90−#: Components/EdgeDemoOverlay.qml:149
90+#: Components/EdgeDemoOverlay.qml:151
9191msgid "Skip intro"
9292msgstr "تخطي المقدمة"
9393
@@ -136,7 +136,7 @@ msgstr ""
136136"لقد أتقنت الآن إيماءات الحواف ويمكنك البدء باستخدام الهاتف<br><br>انقر في أي "
137137"مكان للبدء"
138138
139−#: Components/PageHeader.qml:341
139+#: Components/PageHeader.qml:345
140140msgid "Recent searches"
141141msgstr "عمليات البحث الأخيرة"
142142
@@ -160,7 +160,7 @@ msgstr[3] "%1 تعليقات"
160160msgstr[4] "%1 تعليقا"
161161msgstr[5] "%1 تعليق"
162162
163−#: Dash/Apps/AppPreview.qml:126
163+#: Dash/Apps/AppPreview.qml:135
164164msgid "Rate this"
165165msgstr "قيّم ذلك"
166166
@@ -180,7 +180,7 @@ msgstr "أرسل"
180180msgid "Comments:"
181181msgstr "التعليقات:"
182182
183−#: Greeter/Lockscreen.qml:142
183+#: Greeter/Lockscreen.qml:146
184184msgid "Emergency Call"
185185msgstr "مكالمة طوارئ"
186186
@@ -213,11 +213,24 @@ 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/Launcher/launcheritem.cpp:43
225+#: plugins/Unity/Launcher/launcheritem.cpp:73
226+msgid "Lock to Launcher"
227+msgstr ""
228+
229+#: plugins/Unity/Launcher/launcheritem.cpp:73
230+msgid "Unlock from Launcher"
231+msgstr ""
232+
233+#: plugins/Unity/scope.cpp:408
221234msgid "Sorry, there is nothing that matches your search."
222235msgstr "عذراً، لا يوجد ما يطابق بحثك."
223236
@@ -225,7 +238,7 @@ msgstr "عذراً، لا يوجد ما يطابق بحثك."
225238msgid "All"
226239msgstr "الكل"
227240
228−#: Shell.qml:438
241+#: Shell.qml:441
229242#, qt-format
230243msgid "Please enter %1"
231244msgstr "من فضلك أدخِل %1"
po/ast.po+22−30
@@ -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-12 16:10+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-19 05:59+0000\n"
19+"X-Generator: Launchpad (build 16831)\n"
2020
2121#: Applications/applications.js:23
2222msgid "Phone"
@@ -86,7 +86,7 @@ msgstr "Wikipedia"
8686msgid "YouTube"
8787msgstr "YouTube"
8888
89−#: Components/EdgeDemoOverlay.qml:149
89+#: Components/EdgeDemoOverlay.qml:151
9090msgid "Skip intro"
9191msgstr "Omitir la intro"
9292
@@ -136,7 +136,7 @@ msgstr ""
136136"Agora domines los xestos de berbesos y pues usar el teléfonu<br><br>Toca la "
137137"pantalla pa entamar"
138138
139−#: Components/PageHeader.qml:341
139+#: Components/PageHeader.qml:345
140140msgid "Recent searches"
141141msgstr "Busques recientes"
142142
@@ -156,7 +156,7 @@ msgid_plural "%1 reviews"
156156msgstr[0] "%1 reseña"
157157msgstr[1] "%1 reseñes"
158158
159−#: Dash/Apps/AppPreview.qml:126
159+#: Dash/Apps/AppPreview.qml:135
160160msgid "Rate this"
161161msgstr "Valorar esto"
162162
@@ -176,7 +176,7 @@ msgstr "Unviar"
176176msgid "Comments:"
177177msgstr "Comentarios:"
178178
179−#: Greeter/Lockscreen.qml:142
179+#: Greeter/Lockscreen.qml:146
180180msgid "Emergency Call"
181181msgstr "Llamada d'emerxencia"
182182
@@ -209,11 +209,24 @@ 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/Launcher/launcheritem.cpp:43
221+#: plugins/Unity/Launcher/launcheritem.cpp:73
222+msgid "Lock to Launcher"
223+msgstr ""
224+
225+#: plugins/Unity/Launcher/launcheritem.cpp:73
226+msgid "Unlock from Launcher"
227+msgstr ""
228+
229+#: plugins/Unity/scope.cpp:408
217230msgid "Sorry, there is nothing that matches your search."
218231msgstr "Sentímoslo, nun hai res que concase cola gueta"
219232
@@ -221,28 +234,7 @@ msgstr "Sentímoslo, nun hai res que concase cola gueta"
221234msgid "All"
222235msgstr "Too"
223236
224−#: Shell.qml:438
237+#: Shell.qml:441
225238#, qt-format
226239msgid "Please enter %1"
227240msgstr "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+22−15
@@ -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-12 16:10+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-19 05:59+0000\n"
19+"X-Generator: Launchpad (build 16831)\n"
2020
2121#: Applications/applications.js:23
2222msgid "Phone"
@@ -86,7 +86,7 @@ msgstr ""
8686msgid "YouTube"
8787msgstr ""
8888
89−#: Components/EdgeDemoOverlay.qml:149
89+#: Components/EdgeDemoOverlay.qml:151
9090msgid "Skip intro"
9191msgstr ""
9292
@@ -132,7 +132,7 @@ msgid ""
132132"phone<br><br>Tap anywhere to start"
133133msgstr ""
134134
135−#: Components/PageHeader.qml:341
135+#: Components/PageHeader.qml:345
136136msgid "Recent searches"
137137msgstr "Son axtarışlar"
138138
@@ -152,7 +152,7 @@ msgid_plural "%1 reviews"
152152msgstr[0] ""
153153msgstr[1] ""
154154
155−#: Dash/Apps/AppPreview.qml:126
155+#: Dash/Apps/AppPreview.qml:135
156156msgid "Rate this"
157157msgstr ""
158158
@@ -172,7 +172,7 @@ msgstr ""
172172msgid "Comments:"
173173msgstr ""
174174
175−#: Greeter/Lockscreen.qml:142
175+#: Greeter/Lockscreen.qml:146
176176msgid "Emergency Call"
177177msgstr ""
178178
@@ -205,11 +205,24 @@ 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/Launcher/launcheritem.cpp:43
217+#: plugins/Unity/Launcher/launcheritem.cpp:73
218+msgid "Lock to Launcher"
219+msgstr ""
220+
221+#: plugins/Unity/Launcher/launcheritem.cpp:73
222+msgid "Unlock from Launcher"
223+msgstr ""
224+
225+#: plugins/Unity/scope.cpp:408
213226msgid "Sorry, there is nothing that matches your search."
214227msgstr "Bağışlayın, amma axtarışınıza heç bir nəticə uyğun gəlmir."
215228
@@ -217,13 +230,7 @@ msgstr "Bağışlayın, amma axtarışınıza heç bir nəticə uyğun gəlmir."
217230msgid "All"
218231msgstr ""
219232
220−#: Shell.qml:438
233+#: Shell.qml:441
221234#, qt-format
222235msgid "Please enter %1"
223236msgstr ""
224−
225−#~ msgid "Music"
226−#~ msgstr "Musiqi"
227−
228−#~ msgid "Videos"
229−#~ msgstr "Videolar"
po/bg.po+22−21
@@ -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-12 16:10+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-19 05:59+0000\n"
20+"X-Generator: Launchpad (build 16831)\n"
2121
2222#: Applications/applications.js:23
2323msgid "Phone"
@@ -87,7 +87,7 @@ msgstr "Уикипедия"
8787msgid "YouTube"
8888msgstr "YouTube"
8989
90−#: Components/EdgeDemoOverlay.qml:149
90+#: Components/EdgeDemoOverlay.qml:151
9191msgid "Skip intro"
9292msgstr ""
9393
@@ -133,7 +133,7 @@ msgid ""
133133"phone<br><br>Tap anywhere to start"
134134msgstr ""
135135
136−#: Components/PageHeader.qml:341
136+#: Components/PageHeader.qml:345
137137msgid "Recent searches"
138138msgstr "Скорошни търсения"
139139
@@ -153,7 +153,7 @@ msgid_plural "%1 reviews"
153153msgstr[0] ""
154154msgstr[1] ""
155155
156−#: Dash/Apps/AppPreview.qml:126
156+#: Dash/Apps/AppPreview.qml:135
157157msgid "Rate this"
158158msgstr ""
159159
@@ -173,7 +173,7 @@ msgstr ""
173173msgid "Comments:"
174174msgstr ""
175175
176−#: Greeter/Lockscreen.qml:142
176+#: Greeter/Lockscreen.qml:146
177177msgid "Emergency Call"
178178msgstr ""
179179
@@ -206,11 +206,24 @@ 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/Launcher/launcheritem.cpp:43
218+#: plugins/Unity/Launcher/launcheritem.cpp:73
219+msgid "Lock to Launcher"
220+msgstr ""
221+
222+#: plugins/Unity/Launcher/launcheritem.cpp:73
223+msgid "Unlock from Launcher"
224+msgstr ""
225+
226+#: plugins/Unity/scope.cpp:408
214227msgid "Sorry, there is nothing that matches your search."
215228msgstr "Съжаляваме, няма нищо, което да отговаря на вашето търсене."
216229
@@ -218,19 +231,7 @@ msgstr "Съжаляваме, няма нищо, което да отговар
218231msgid "All"
219232msgstr ""
220233
221−#: Shell.qml:438
234+#: Shell.qml:441
222235#, qt-format
223236msgid "Please enter %1"
224237msgstr ""
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+22−30
@@ -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-12 16:10+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-19 05:59+0000\n"
19+"X-Generator: Launchpad (build 16831)\n"
2020
2121#: Applications/applications.js:23
2222msgid "Phone"
@@ -86,7 +86,7 @@ msgstr "Viquipèdia"
8686msgid "YouTube"
8787msgstr "YouTube"
8888
89−#: Components/EdgeDemoOverlay.qml:149
89+#: Components/EdgeDemoOverlay.qml:151
9090msgid "Skip intro"
9191msgstr "Omet la introducció"
9292
@@ -138,7 +138,7 @@ msgid ""
138138"phone<br><br>Tap anywhere to start"
139139msgstr ""
140140
141−#: Components/PageHeader.qml:341
141+#: Components/PageHeader.qml:345
142142msgid "Recent searches"
143143msgstr "Cerques recents"
144144
@@ -158,7 +158,7 @@ msgid_plural "%1 reviews"
158158msgstr[0] "%1 ressenya"
159159msgstr[1] "%1 ressenyes"
160160
161−#: Dash/Apps/AppPreview.qml:126
161+#: Dash/Apps/AppPreview.qml:135
162162msgid "Rate this"
163163msgstr ""
164164
@@ -178,7 +178,7 @@ msgstr "Envia"
178178msgid "Comments:"
179179msgstr "Comentaris:"
180180
181−#: Greeter/Lockscreen.qml:142
181+#: Greeter/Lockscreen.qml:146
182182msgid "Emergency Call"
183183msgstr "Trucada d'emergència"
184184
@@ -211,11 +211,24 @@ 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/Launcher/launcheritem.cpp:43
223+#: plugins/Unity/Launcher/launcheritem.cpp:73
224+msgid "Lock to Launcher"
225+msgstr ""
226+
227+#: plugins/Unity/Launcher/launcheritem.cpp:73
228+msgid "Unlock from Launcher"
229+msgstr ""
230+
231+#: plugins/Unity/scope.cpp:408
219232msgid "Sorry, there is nothing that matches your search."
220233msgstr "No hi ha res que coincideixi amb la cerca"
221234
@@ -223,28 +236,7 @@ msgstr "No hi ha res que coincideixi amb la cerca"
223236msgid "All"
224237msgstr ""
225238
226−#: Shell.qml:438
239+#: Shell.qml:441
227240#, qt-format
228241msgid "Please enter %1"
229242msgstr "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+22−24
@@ -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-12 16:10+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-19 05:59+0000\n"
19+"X-Generator: Launchpad (build 16831)\n"
2020
2121#: Applications/applications.js:23
2222msgid "Phone"
@@ -86,7 +86,7 @@ msgstr "Wikipedie"
8686msgid "YouTube"
8787msgstr "YouTube"
8888
89−#: Components/EdgeDemoOverlay.qml:149
89+#: Components/EdgeDemoOverlay.qml:151
9090msgid "Skip intro"
9191msgstr "Přeskočit intro"
9292
@@ -132,7 +132,7 @@ msgid ""
132132"phone<br><br>Tap anywhere to start"
133133msgstr ""
134134
135−#: Components/PageHeader.qml:341
135+#: Components/PageHeader.qml:345
136136msgid "Recent searches"
137137msgstr "Poslední vyhledávání"
138138
@@ -153,7 +153,7 @@ msgstr[0] "%1 recenze"
153153msgstr[1] "%1 recenze"
154154msgstr[2] "%1 recenzí"
155155
156−#: Dash/Apps/AppPreview.qml:126
156+#: Dash/Apps/AppPreview.qml:135
157157msgid "Rate this"
158158msgstr "Ohodnoťte to"
159159
@@ -173,7 +173,7 @@ msgstr "Odeslat"
173173msgid "Comments:"
174174msgstr "Komentáře:"
175175
176−#: Greeter/Lockscreen.qml:142
176+#: Greeter/Lockscreen.qml:146
177177msgid "Emergency Call"
178178msgstr "Tísňové volání"
179179
@@ -206,11 +206,24 @@ 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/Launcher/launcheritem.cpp:43
218+#: plugins/Unity/Launcher/launcheritem.cpp:73
219+msgid "Lock to Launcher"
220+msgstr ""
221+
222+#: plugins/Unity/Launcher/launcheritem.cpp:73
223+msgid "Unlock from Launcher"
224+msgstr ""
225+
226+#: plugins/Unity/scope.cpp:408
214227msgid "Sorry, there is nothing that matches your search."
215228msgstr "Je nám líto, ale nic neodpovídá zadání"
216229
@@ -218,22 +231,7 @@ msgstr "Je nám líto, ale nic neodpovídá zadání"
218231msgid "All"
219232msgstr "Vše"
220233
221−#: Shell.qml:438
234+#: Shell.qml:441
222235#, qt-format
223236msgid "Please enter %1"
224237msgstr "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+22−9
@@ -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-12 16:10+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-19 05:59+0000\n"
19+"X-Generator: Launchpad (build 16831)\n"
2020
2121#: Applications/applications.js:23
2222msgid "Phone"
@@ -86,7 +86,7 @@ msgstr "Wikipedia"
8686msgid "YouTube"
8787msgstr "YouTube"
8888
89−#: Components/EdgeDemoOverlay.qml:149
89+#: Components/EdgeDemoOverlay.qml:151
9090msgid "Skip intro"
9191msgstr "Überspringe Einführung"
9292
@@ -136,7 +136,7 @@ msgstr ""
136136"Sie haben nun die Einführung abgeschlossen und können Ihr Gerät nun "
137137"verwenden<br><br>Antippen um zu starten"
138138
139−#: Components/PageHeader.qml:341
139+#: Components/PageHeader.qml:345
140140msgid "Recent searches"
141141msgstr "Letzte Suchbegriffe"
142142
@@ -156,7 +156,7 @@ msgid_plural "%1 reviews"
156156msgstr[0] "%1 Bewertung"
157157msgstr[1] "%1 Bewertungen"
158158
159−#: Dash/Apps/AppPreview.qml:126
159+#: Dash/Apps/AppPreview.qml:135
160160msgid "Rate this"
161161msgstr "Bewerten"
162162
@@ -176,7 +176,7 @@ msgstr "Senden"
176176msgid "Comments:"
177177msgstr "Kommentare:"
178178
179−#: Greeter/Lockscreen.qml:142
179+#: Greeter/Lockscreen.qml:146
180180msgid "Emergency Call"
181181msgstr "Notruf"
182182
@@ -209,11 +209,24 @@ 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/Launcher/launcheritem.cpp:43
221+#: plugins/Unity/Launcher/launcheritem.cpp:73
222+msgid "Lock to Launcher"
223+msgstr ""
224+
225+#: plugins/Unity/Launcher/launcheritem.cpp:73
226+msgid "Unlock from Launcher"
227+msgstr ""
228+
229+#: plugins/Unity/scope.cpp:408
217230msgid "Sorry, there is nothing that matches your search."
218231msgstr "Entschuldigung, es wurden keine Treffer erzielt."
219232
@@ -221,7 +234,7 @@ msgstr "Entschuldigung, es wurden keine Treffer erzielt."
221234msgid "All"
222235msgstr "Alle"
223236
224−#: Shell.qml:438
237+#: Shell.qml:441
225238#, qt-format
226239msgid "Please enter %1"
227240msgstr "Bitte geben Sie %1 ein"
po/el.po+22−15
@@ -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-12 16:10+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-19 05:59+0000\n"
19+"X-Generator: Launchpad (build 16831)\n"
2020
2121#: Applications/applications.js:23
2222msgid "Phone"
@@ -86,7 +86,7 @@ msgstr ""
8686msgid "YouTube"
8787msgstr ""
8888
89−#: Components/EdgeDemoOverlay.qml:149
89+#: Components/EdgeDemoOverlay.qml:151
9090msgid "Skip intro"
9191msgstr ""
9292
@@ -132,7 +132,7 @@ msgid ""
132132"phone<br><br>Tap anywhere to start"
133133msgstr ""
134134
135−#: Components/PageHeader.qml:341
135+#: Components/PageHeader.qml:345
136136msgid "Recent searches"
137137msgstr "Πρόσφατες αναζητήσεις"
138138
@@ -152,7 +152,7 @@ msgid_plural "%1 reviews"
152152msgstr[0] ""
153153msgstr[1] ""
154154
155−#: Dash/Apps/AppPreview.qml:126
155+#: Dash/Apps/AppPreview.qml:135
156156msgid "Rate this"
157157msgstr ""
158158
@@ -172,7 +172,7 @@ msgstr ""
172172msgid "Comments:"
173173msgstr ""
174174
175−#: Greeter/Lockscreen.qml:142
175+#: Greeter/Lockscreen.qml:146
176176msgid "Emergency Call"
177177msgstr ""
178178
@@ -205,11 +205,24 @@ 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/Launcher/launcheritem.cpp:43
217+#: plugins/Unity/Launcher/launcheritem.cpp:73
218+msgid "Lock to Launcher"
219+msgstr ""
220+
221+#: plugins/Unity/Launcher/launcheritem.cpp:73
222+msgid "Unlock from Launcher"
223+msgstr ""
224+
225+#: plugins/Unity/scope.cpp:408
213226msgid "Sorry, there is nothing that matches your search."
214227msgstr "Λυπούμαστε, δεν υπάρχει τίποτα που να ταιριάζει στην αναζήτησή σας."
215228
@@ -217,13 +230,7 @@ msgstr "Λυπούμαστε, δεν υπάρχει τίποτα που να τ
217230msgid "All"
218231msgstr ""
219232
220−#: Shell.qml:438
233+#: Shell.qml:441
221234#, qt-format
222235msgid "Please enter %1"
223236msgstr ""
224−
225−#~ msgid "Music"
226−#~ msgstr "Μουσική"
227−
228−#~ msgid "Videos"
229−#~ msgstr "Βίντεο"
po/en_AU.po+22−30
@@ -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-12 16:10+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-19 05:59+0000\n"
19+"X-Generator: Launchpad (build 16831)\n"
2020
2121#: Applications/applications.js:23
2222msgid "Phone"
@@ -86,7 +86,7 @@ msgstr "Wikipedia"
8686msgid "YouTube"
8787msgstr "YouTube"
8888
89−#: Components/EdgeDemoOverlay.qml:149
89+#: Components/EdgeDemoOverlay.qml:151
9090msgid "Skip intro"
9191msgstr "Skip intro"
9292
@@ -132,7 +132,7 @@ msgid ""
132132"phone<br><br>Tap anywhere to start"
133133msgstr ""
134134
135−#: Components/PageHeader.qml:341
135+#: Components/PageHeader.qml:345
136136msgid "Recent searches"
137137msgstr "Recent searches"
138138
@@ -152,7 +152,7 @@ msgid_plural "%1 reviews"
152152msgstr[0] "%1 review"
153153msgstr[1] "%1 reviews"
154154
155−#: Dash/Apps/AppPreview.qml:126
155+#: Dash/Apps/AppPreview.qml:135
156156msgid "Rate this"
157157msgstr "Rate this"
158158
@@ -172,7 +172,7 @@ msgstr "Send"
172172msgid "Comments:"
173173msgstr "Comments:"
174174
175−#: Greeter/Lockscreen.qml:142
175+#: Greeter/Lockscreen.qml:146
176176msgid "Emergency Call"
177177msgstr "Emergency Call"
178178
@@ -205,11 +205,24 @@ 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/Launcher/launcheritem.cpp:43
217+#: plugins/Unity/Launcher/launcheritem.cpp:73
218+msgid "Lock to Launcher"
219+msgstr ""
220+
221+#: plugins/Unity/Launcher/launcheritem.cpp:73
222+msgid "Unlock from Launcher"
223+msgstr ""
224+
225+#: plugins/Unity/scope.cpp:408
213226msgid "Sorry, there is nothing that matches your search."
214227msgstr "Sorry, there is nothing that matches your search."
215228
@@ -217,28 +230,7 @@ msgstr "Sorry, there is nothing that matches your search."
217230msgid "All"
218231msgstr ""
219232
220−#: Shell.qml:438
233+#: Shell.qml:441
221234#, qt-format
222235msgid "Please enter %1"
223236msgstr "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+22−30
@@ -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-12 16:10+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-19 05:59+0000\n"
19+"X-Generator: Launchpad (build 16831)\n"
2020
2121#: Applications/applications.js:23
2222msgid "Phone"
@@ -86,7 +86,7 @@ msgstr "Wikipedia"
8686msgid "YouTube"
8787msgstr "YouTube"
8888
89−#: Components/EdgeDemoOverlay.qml:149
89+#: Components/EdgeDemoOverlay.qml:151
9090msgid "Skip intro"
9191msgstr ""
9292
@@ -132,7 +132,7 @@ msgid ""
132132"phone<br><br>Tap anywhere to start"
133133msgstr ""
134134
135−#: Components/PageHeader.qml:341
135+#: Components/PageHeader.qml:345
136136msgid "Recent searches"
137137msgstr "Recent searches"
138138
@@ -152,7 +152,7 @@ msgid_plural "%1 reviews"
152152msgstr[0] ""
153153msgstr[1] ""
154154
155−#: Dash/Apps/AppPreview.qml:126
155+#: Dash/Apps/AppPreview.qml:135
156156msgid "Rate this"
157157msgstr ""
158158
@@ -172,7 +172,7 @@ msgstr ""
172172msgid "Comments:"
173173msgstr ""
174174
175−#: Greeter/Lockscreen.qml:142
175+#: Greeter/Lockscreen.qml:146
176176msgid "Emergency Call"
177177msgstr ""
178178
@@ -205,11 +205,24 @@ 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/Launcher/launcheritem.cpp:43
217+#: plugins/Unity/Launcher/launcheritem.cpp:73
218+msgid "Lock to Launcher"
219+msgstr ""
220+
221+#: plugins/Unity/Launcher/launcheritem.cpp:73
222+msgid "Unlock from Launcher"
223+msgstr ""
224+
225+#: plugins/Unity/scope.cpp:408
213226msgid "Sorry, there is nothing that matches your search."
214227msgstr "Sorry, there is nothing that matches your search."
215228
@@ -217,28 +230,7 @@ msgstr "Sorry, there is nothing that matches your search."
217230msgid "All"
218231msgstr ""
219232
220−#: Shell.qml:438
233+#: Shell.qml:441
221234#, qt-format
222235msgid "Please enter %1"
223236msgstr "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+22−9
@@ -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-12 16:10+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-19 05:59+0000\n"
19+"X-Generator: Launchpad (build 16831)\n"
2020
2121#: Applications/applications.js:23
2222msgid "Phone"
@@ -86,7 +86,7 @@ msgstr ""
8686msgid "YouTube"
8787msgstr ""
8888
89−#: Components/EdgeDemoOverlay.qml:149
89+#: Components/EdgeDemoOverlay.qml:151
9090msgid "Skip intro"
9191msgstr ""
9292
@@ -132,7 +132,7 @@ msgid ""
132132"phone<br><br>Tap anywhere to start"
133133msgstr ""
134134
135−#: Components/PageHeader.qml:341
135+#: Components/PageHeader.qml:345
136136msgid "Recent searches"
137137msgstr ""
138138
@@ -152,7 +152,7 @@ msgid_plural "%1 reviews"
152152msgstr[0] ""
153153msgstr[1] ""
154154
155−#: Dash/Apps/AppPreview.qml:126
155+#: Dash/Apps/AppPreview.qml:135
156156msgid "Rate this"
157157msgstr ""
158158
@@ -172,7 +172,7 @@ msgstr ""
172172msgid "Comments:"
173173msgstr ""
174174
175−#: Greeter/Lockscreen.qml:142
175+#: Greeter/Lockscreen.qml:146
176176msgid "Emergency Call"
177177msgstr ""
178178
@@ -205,11 +205,24 @@ 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/Launcher/launcheritem.cpp:43
217+#: plugins/Unity/Launcher/launcheritem.cpp:73
218+msgid "Lock to Launcher"
219+msgstr ""
220+
221+#: plugins/Unity/Launcher/launcheritem.cpp:73
222+msgid "Unlock from Launcher"
223+msgstr ""
224+
225+#: plugins/Unity/scope.cpp:408
213226msgid "Sorry, there is nothing that matches your search."
214227msgstr ""
215228
@@ -217,7 +230,7 @@ msgstr ""
217230msgid "All"
218231msgstr ""
219232
220−#: Shell.qml:438
233+#: Shell.qml:441
221234#, qt-format
222235msgid "Please enter %1"
223236msgstr ""
po/es.po+22−30
@@ -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-12 16:10+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-19 05:59+0000\n"
19+"X-Generator: Launchpad (build 16831)\n"
2020
2121#: Applications/applications.js:23
2222msgid "Phone"
@@ -86,7 +86,7 @@ msgstr "Wikipedia"
8686msgid "YouTube"
8787msgstr "YouTube"
8888
89−#: Components/EdgeDemoOverlay.qml:149
89+#: Components/EdgeDemoOverlay.qml:151
9090msgid "Skip intro"
9191msgstr "Omitir la introducción"
9292
@@ -136,7 +136,7 @@ msgstr ""
136136"Ahora domina los gestos de bordes y puede usar el teléfono<br><br>Toque la "
137137"pantalla para comenzar"
138138
139−#: Components/PageHeader.qml:341
139+#: Components/PageHeader.qml:345
140140msgid "Recent searches"
141141msgstr "Búsquedas recientes"
142142
@@ -156,7 +156,7 @@ msgid_plural "%1 reviews"
156156msgstr[0] "%1 reseña"
157157msgstr[1] "%1 reseñas"
158158
159−#: Dash/Apps/AppPreview.qml:126
159+#: Dash/Apps/AppPreview.qml:135
160160msgid "Rate this"
161161msgstr "Valorar esto"
162162
@@ -176,7 +176,7 @@ msgstr "Enviar"
176176msgid "Comments:"
177177msgstr "Comentarios:"
178178
179−#: Greeter/Lockscreen.qml:142
179+#: Greeter/Lockscreen.qml:146
180180msgid "Emergency Call"
181181msgstr "Llamada de emergencia"
182182
@@ -209,11 +209,24 @@ 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/Launcher/launcheritem.cpp:43
221+#: plugins/Unity/Launcher/launcheritem.cpp:73
222+msgid "Lock to Launcher"
223+msgstr ""
224+
225+#: plugins/Unity/Launcher/launcheritem.cpp:73
226+msgid "Unlock from Launcher"
227+msgstr ""
228+
229+#: plugins/Unity/scope.cpp:408
217230msgid "Sorry, there is nothing that matches your search."
218231msgstr "No hay nada que coincida con su búsqueda."
219232
@@ -221,28 +234,7 @@ msgstr "No hay nada que coincida con su búsqueda."
221234msgid "All"
222235msgstr "Todo"
223236
224−#: Shell.qml:438
237+#: Shell.qml:441
225238#, qt-format
226239msgid "Please enter %1"
227240msgstr "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+22−9
@@ -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-12 16:10+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,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-11-01 06:44+0000\n"
19−"X-Generator: Launchpad (build 16820)\n"
18+"X-Launchpad-Export-Date: 2013-11-19 05:59+0000\n"
19+"X-Generator: Launchpad (build 16831)\n"
2020
2121#: Applications/applications.js:23
2222msgid "Phone"
@@ -86,7 +86,7 @@ msgstr ""
8686msgid "YouTube"
8787msgstr ""
8888
89−#: Components/EdgeDemoOverlay.qml:149
89+#: Components/EdgeDemoOverlay.qml:151
9090msgid "Skip intro"
9191msgstr ""
9292
@@ -132,7 +132,7 @@ msgid ""
132132"phone<br><br>Tap anywhere to start"
133133msgstr ""
134134
135−#: Components/PageHeader.qml:341
135+#: Components/PageHeader.qml:345
136136msgid "Recent searches"
137137msgstr ""
138138
@@ -152,7 +152,7 @@ msgid_plural "%1 reviews"
152152msgstr[0] ""
153153msgstr[1] ""
154154
155−#: Dash/Apps/AppPreview.qml:126
155+#: Dash/Apps/AppPreview.qml:135
156156msgid "Rate this"
157157msgstr ""
158158
@@ -172,7 +172,7 @@ msgstr ""
172172msgid "Comments:"
173173msgstr ""
174174
175−#: Greeter/Lockscreen.qml:142
175+#: Greeter/Lockscreen.qml:146
176176msgid "Emergency Call"
177177msgstr ""
178178
@@ -205,11 +205,24 @@ 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/Launcher/launcheritem.cpp:43
217+#: plugins/Unity/Launcher/launcheritem.cpp:73
218+msgid "Lock to Launcher"
219+msgstr ""
220+
221+#: plugins/Unity/Launcher/launcheritem.cpp:73
222+msgid "Unlock from Launcher"
223+msgstr ""
224+
225+#: plugins/Unity/scope.cpp:408
213226msgid "Sorry, there is nothing that matches your search."
214227msgstr ""
215228
@@ -217,7 +230,7 @@ msgstr ""
217230msgid "All"
218231msgstr ""
219232
220−#: Shell.qml:438
233+#: Shell.qml:441
221234#, qt-format
222235msgid "Please enter %1"
223236msgstr ""
po/fi.po+23−31
@@ -7,16 +7,16 @@ 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"
11−"PO-Revision-Date: 2013-10-03 09:21+0000\n"
10+"POT-Creation-Date: 2013-11-12 16:10+0100\n"
11+"PO-Revision-Date: 2013-11-11 14:07+0000\n"
1212"Last-Translator: Jiri Grönroos <Unknown>\n"
1313"Language-Team: Finnish <fi@li.org>\n"
1414"MIME-Version: 1.0\n"
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-19 05:59+0000\n"
19+"X-Generator: Launchpad (build 16831)\n"
2020
2121#: Applications/applications.js:23
2222msgid "Phone"
@@ -86,7 +86,7 @@ msgstr "Wikipedia"
8686msgid "YouTube"
8787msgstr "YouTube"
8888
89−#: Components/EdgeDemoOverlay.qml:149
89+#: Components/EdgeDemoOverlay.qml:151
9090msgid "Skip intro"
9191msgstr "Ohita esittely"
9292
@@ -134,7 +134,7 @@ msgstr ""
134134"Hallitset nyt reunaeleet, joten voit aloittaa puhelimen "
135135"käytön<br><br>Napauta missä tahansa aloittaaksesi"
136136
137−#: Components/PageHeader.qml:341
137+#: Components/PageHeader.qml:345
138138msgid "Recent searches"
139139msgstr "Viimeisimmät haut"
140140
@@ -154,7 +154,7 @@ msgid_plural "%1 reviews"
154154msgstr[0] "%1 arvostelu"
155155msgstr[1] "%1 arvostelua"
156156
157−#: Dash/Apps/AppPreview.qml:126
157+#: Dash/Apps/AppPreview.qml:135
158158msgid "Rate this"
159159msgstr "Arvioi tämä"
160160
@@ -174,7 +174,7 @@ msgstr "Lähetä"
174174msgid "Comments:"
175175msgstr "Kommentit:"
176176
177−#: Greeter/Lockscreen.qml:142
177+#: Greeter/Lockscreen.qml:146
178178msgid "Emergency Call"
179179msgstr "Hätäpuhelu"
180180
@@ -207,11 +207,24 @@ msgstr "Puhu nyt..."
207207msgid "Speaking..."
208208msgstr "Puhutaan..."
209209
210+#: Notifications/NotificationMenuItemFactory.qml:89
211+msgid "Show password"
212+msgstr "Näytä salasana"
213+
210214#: Panel/SearchIndicator.qml:27
211215msgid "Search"
212216msgstr "Hae"
213217
214−#: plugins/Unity/scope.cpp:398
218+#: plugins/Unity/Launcher/launcheritem.cpp:43
219+#: plugins/Unity/Launcher/launcheritem.cpp:73
220+msgid "Lock to Launcher"
221+msgstr ""
222+
223+#: plugins/Unity/Launcher/launcheritem.cpp:73
224+msgid "Unlock from Launcher"
225+msgstr ""
226+
227+#: plugins/Unity/scope.cpp:408
215228msgid "Sorry, there is nothing that matches your search."
216229msgstr "Hakuun täsmääviä tuloksia ei löydy."
217230
@@ -219,28 +232,7 @@ msgstr "Hakuun täsmääviä tuloksia ei löydy."
219232msgid "All"
220233msgstr "Kaikki"
221234
222−#: Shell.qml:438
235+#: Shell.qml:441
223236#, qt-format
224237msgid "Please enter %1"
225238msgstr "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+22−15
@@ -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-12 16:10+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-19 05:59+0000\n"
19+"X-Generator: Launchpad (build 16831)\n"
2020
2121#: Applications/applications.js:23
2222msgid "Phone"
@@ -86,7 +86,7 @@ msgstr ""
8686msgid "YouTube"
8787msgstr ""
8888
89−#: Components/EdgeDemoOverlay.qml:149
89+#: Components/EdgeDemoOverlay.qml:151
9090msgid "Skip intro"
9191msgstr ""
9292
@@ -132,7 +132,7 @@ msgid ""
132132"phone<br><br>Tap anywhere to start"
133133msgstr ""
134134
135−#: Components/PageHeader.qml:341
135+#: Components/PageHeader.qml:345
136136msgid "Recent searches"
137137msgstr ""
138138
@@ -152,7 +152,7 @@ msgid_plural "%1 reviews"
152152msgstr[0] ""
153153msgstr[1] ""
154154
155−#: Dash/Apps/AppPreview.qml:126
155+#: Dash/Apps/AppPreview.qml:135
156156msgid "Rate this"
157157msgstr ""
158158
@@ -172,7 +172,7 @@ msgstr ""
172172msgid "Comments:"
173173msgstr ""
174174
175−#: Greeter/Lockscreen.qml:142
175+#: Greeter/Lockscreen.qml:146
176176msgid "Emergency Call"
177177msgstr ""
178178
@@ -205,11 +205,24 @@ 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/Launcher/launcheritem.cpp:43
217+#: plugins/Unity/Launcher/launcheritem.cpp:73
218+msgid "Lock to Launcher"
219+msgstr ""
220+
221+#: plugins/Unity/Launcher/launcheritem.cpp:73
222+msgid "Unlock from Launcher"
223+msgstr ""
224+
225+#: plugins/Unity/scope.cpp:408
213226msgid "Sorry, there is nothing that matches your search."
214227msgstr "Tíanverri er tað einki sum hóskar til tína leiting."
215228
@@ -217,13 +230,7 @@ msgstr "Tíanverri er tað einki sum hóskar til tína leiting."
217230msgid "All"
218231msgstr ""
219232
220−#: Shell.qml:438
233+#: Shell.qml:441
221234#, qt-format
222235msgid "Please enter %1"
223236msgstr ""
224−
225−#~ msgid "Music"
226−#~ msgstr "Tónleikur"
227−
228−#~ msgid "Videos"
229−#~ msgstr "Sjónbond"
po/fr.po+22−15
@@ -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-12 16:10+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-19 05:59+0000\n"
19+"X-Generator: Launchpad (build 16831)\n"
2020
2121#: Applications/applications.js:23
2222msgid "Phone"
@@ -86,7 +86,7 @@ msgstr ""
8686msgid "YouTube"
8787msgstr ""
8888
89−#: Components/EdgeDemoOverlay.qml:149
89+#: Components/EdgeDemoOverlay.qml:151
9090msgid "Skip intro"
9191msgstr ""
9292
@@ -132,7 +132,7 @@ msgid ""
132132"phone<br><br>Tap anywhere to start"
133133msgstr ""
134134
135−#: Components/PageHeader.qml:341
135+#: Components/PageHeader.qml:345
136136msgid "Recent searches"
137137msgstr ""
138138
@@ -152,7 +152,7 @@ msgid_plural "%1 reviews"
152152msgstr[0] ""
153153msgstr[1] ""
154154
155−#: Dash/Apps/AppPreview.qml:126
155+#: Dash/Apps/AppPreview.qml:135
156156msgid "Rate this"
157157msgstr ""
158158
@@ -172,7 +172,7 @@ msgstr ""
172172msgid "Comments:"
173173msgstr ""
174174
175−#: Greeter/Lockscreen.qml:142
175+#: Greeter/Lockscreen.qml:146
176176msgid "Emergency Call"
177177msgstr ""
178178
@@ -205,11 +205,24 @@ 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/Launcher/launcheritem.cpp:43
217+#: plugins/Unity/Launcher/launcheritem.cpp:73
218+msgid "Lock to Launcher"
219+msgstr ""
220+
221+#: plugins/Unity/Launcher/launcheritem.cpp:73
222+msgid "Unlock from Launcher"
223+msgstr ""
224+
225+#: plugins/Unity/scope.cpp:408
213226msgid "Sorry, there is nothing that matches your search."
214227msgstr ""
215228
@@ -217,13 +230,7 @@ msgstr ""
217230msgid "All"
218231msgstr ""
219232
220−#: Shell.qml:438
233+#: Shell.qml:441
221234#, qt-format
222235msgid "Please enter %1"
223236msgstr ""
224−
225−#~ msgid "Music"
226−#~ msgstr "Musique"
227−
228−#~ msgid "Videos"
229−#~ msgstr "Vidéos"
po/gd.po+22−30
@@ -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-12 16:10+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-19 05:59+0000\n"
20+"X-Generator: Launchpad (build 16831)\n"
2121
2222#: Applications/applications.js:23
2323msgid "Phone"
@@ -87,7 +87,7 @@ msgstr "An Uicipeid"
8787msgid "YouTube"
8888msgstr "YouTube"
8989
90−#: Components/EdgeDemoOverlay.qml:149
90+#: Components/EdgeDemoOverlay.qml:151
9191msgid "Skip intro"
9292msgstr "Gearr leum thairis air an ro-ràdh"
9393
@@ -139,7 +139,7 @@ msgid ""
139139"phone<br><br>Tap anywhere to start"
140140msgstr ""
141141
142−#: Components/PageHeader.qml:341
142+#: Components/PageHeader.qml:345
143143msgid "Recent searches"
144144msgstr "Na lorg thu o chionn goirid"
145145
@@ -161,7 +161,7 @@ msgstr[1] "%1 lèirmheas"
161161msgstr[2] "%1 lèirmheasan"
162162msgstr[3] "%1 lèirmheas"
163163
164−#: Dash/Apps/AppPreview.qml:126
164+#: Dash/Apps/AppPreview.qml:135
165165msgid "Rate this"
166166msgstr "Rangaich seo"
167167
@@ -181,7 +181,7 @@ msgstr "Cuir"
181181msgid "Comments:"
182182msgstr "Beachdan"
183183
184−#: Greeter/Lockscreen.qml:142
184+#: Greeter/Lockscreen.qml:146
185185msgid "Emergency Call"
186186msgstr "Gairm èiginn"
187187
@@ -214,11 +214,24 @@ 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/Launcher/launcheritem.cpp:43
226+#: plugins/Unity/Launcher/launcheritem.cpp:73
227+msgid "Lock to Launcher"
228+msgstr ""
229+
230+#: plugins/Unity/Launcher/launcheritem.cpp:73
231+msgid "Unlock from Launcher"
232+msgstr ""
233+
234+#: plugins/Unity/scope.cpp:408
222235msgid "Sorry, there is nothing that matches your search."
223236msgstr "Tha sinn duilich ach chan eil dad a' freagairt ris na lorg thu."
224237
@@ -226,28 +239,7 @@ msgstr "Tha sinn duilich ach chan eil dad a' freagairt ris na lorg thu."
226239msgid "All"
227240msgstr ""
228241
229−#: Shell.qml:438
242+#: Shell.qml:441
230243#, qt-format
231244msgid "Please enter %1"
232245msgstr "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+22−27
@@ -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-12 16:10+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-19 05:59+0000\n"
19+"X-Generator: Launchpad (build 16831)\n"
2020
2121#: Applications/applications.js:23
2222msgid "Phone"
@@ -86,7 +86,7 @@ msgstr "Wikipedia"
8686msgid "YouTube"
8787msgstr "YouTube"
8888
89−#: Components/EdgeDemoOverlay.qml:149
89+#: Components/EdgeDemoOverlay.qml:151
9090msgid "Skip intro"
9191msgstr "Saltar introdución"
9292
@@ -134,7 +134,7 @@ msgstr ""
134134"Xa domina os xestos desde os bordos e pode comezar a usar o "
135135"móbil<br><br>Toque en calquera sitio para comezar"
136136
137−#: Components/PageHeader.qml:341
137+#: Components/PageHeader.qml:345
138138msgid "Recent searches"
139139msgstr "Buscas recentes"
140140
@@ -154,7 +154,7 @@ msgid_plural "%1 reviews"
154154msgstr[0] "%1 opinión"
155155msgstr[1] "%1 opinións"
156156
157−#: Dash/Apps/AppPreview.qml:126
157+#: Dash/Apps/AppPreview.qml:135
158158msgid "Rate this"
159159msgstr "Valore isto"
160160
@@ -174,7 +174,7 @@ msgstr "Enviar"
174174msgid "Comments:"
175175msgstr "Comentarios:"
176176
177−#: Greeter/Lockscreen.qml:142
177+#: Greeter/Lockscreen.qml:146
178178msgid "Emergency Call"
179179msgstr "Chamada de emerxencia"
180180
@@ -207,11 +207,24 @@ 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/Launcher/launcheritem.cpp:43
219+#: plugins/Unity/Launcher/launcheritem.cpp:73
220+msgid "Lock to Launcher"
221+msgstr ""
222+
223+#: plugins/Unity/Launcher/launcheritem.cpp:73
224+msgid "Unlock from Launcher"
225+msgstr ""
226+
227+#: plugins/Unity/scope.cpp:408
215228msgid "Sorry, there is nothing that matches your search."
216229msgstr "Sentímolo, non hai nada que coincida con esta busca."
217230
@@ -219,25 +232,7 @@ msgstr "Sentímolo, non hai nada que coincida con esta busca."
219232msgid "All"
220233msgstr "Todo"
221234
222−#: Shell.qml:438
235+#: Shell.qml:441
223236#, qt-format
224237msgid "Please enter %1"
225238msgstr "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+22−30
@@ -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-12 16:10+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-19 05:59+0000\n"
19+"X-Generator: Launchpad (build 16831)\n"
2020
2121#: Applications/applications.js:23
2222msgid "Phone"
@@ -86,7 +86,7 @@ msgstr "ויקיפדיה"
8686msgid "YouTube"
8787msgstr "YouTube"
8888
89−#: Components/EdgeDemoOverlay.qml:149
89+#: Components/EdgeDemoOverlay.qml:151
9090msgid "Skip intro"
9191msgstr "לדלג על הפתיחה"
9292
@@ -132,7 +132,7 @@ msgid ""
132132"phone<br><br>Tap anywhere to start"
133133msgstr ""
134134
135−#: Components/PageHeader.qml:341
135+#: Components/PageHeader.qml:345
136136msgid "Recent searches"
137137msgstr "חיפושים אחרונים"
138138
@@ -152,7 +152,7 @@ msgid_plural "%1 reviews"
152152msgstr[0] "סקירה %1"
153153msgstr[1] "%1 סקירות"
154154
155−#: Dash/Apps/AppPreview.qml:126
155+#: Dash/Apps/AppPreview.qml:135
156156msgid "Rate this"
157157msgstr "דירוג היישום"
158158
@@ -172,7 +172,7 @@ msgstr "שליחה"
172172msgid "Comments:"
173173msgstr "הערות:"
174174
175−#: Greeter/Lockscreen.qml:142
175+#: Greeter/Lockscreen.qml:146
176176msgid "Emergency Call"
177177msgstr "שיחת חירום"
178178
@@ -205,11 +205,24 @@ 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/Launcher/launcheritem.cpp:43
217+#: plugins/Unity/Launcher/launcheritem.cpp:73
218+msgid "Lock to Launcher"
219+msgstr ""
220+
221+#: plugins/Unity/Launcher/launcheritem.cpp:73
222+msgid "Unlock from Launcher"
223+msgstr ""
224+
225+#: plugins/Unity/scope.cpp:408
213226msgid "Sorry, there is nothing that matches your search."
214227msgstr "שום דבר אינו תואם לחיפוש שלך, עמך הסליחה."
215228
@@ -217,28 +230,7 @@ msgstr "שום דבר אינו תואם לחיפוש שלך, עמך הסליחה
217230msgid "All"
218231msgstr ""
219232
220−#: Shell.qml:438
233+#: Shell.qml:441
221234#, qt-format
222235msgid "Please enter %1"
223236msgstr "נא להזין %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+22−15
@@ -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-12 16:10+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-19 05:59+0000\n"
20+"X-Generator: Launchpad (build 16831)\n"
2121
2222#: Applications/applications.js:23
2323msgid "Phone"
@@ -87,7 +87,7 @@ msgstr ""
8787msgid "YouTube"
8888msgstr ""
8989
90−#: Components/EdgeDemoOverlay.qml:149
90+#: Components/EdgeDemoOverlay.qml:151
9191msgid "Skip intro"
9292msgstr ""
9393
@@ -133,7 +133,7 @@ msgid ""
133133"phone<br><br>Tap anywhere to start"
134134msgstr ""
135135
136−#: Components/PageHeader.qml:341
136+#: Components/PageHeader.qml:345
137137msgid "Recent searches"
138138msgstr "Nedavne pretrage"
139139
@@ -153,7 +153,7 @@ msgid_plural "%1 reviews"
153153msgstr[0] ""
154154msgstr[1] ""
155155
156−#: Dash/Apps/AppPreview.qml:126
156+#: Dash/Apps/AppPreview.qml:135
157157msgid "Rate this"
158158msgstr ""
159159
@@ -173,7 +173,7 @@ msgstr ""
173173msgid "Comments:"
174174msgstr ""
175175
176−#: Greeter/Lockscreen.qml:142
176+#: Greeter/Lockscreen.qml:146
177177msgid "Emergency Call"
178178msgstr ""
179179
@@ -206,11 +206,24 @@ 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/Launcher/launcheritem.cpp:43
218+#: plugins/Unity/Launcher/launcheritem.cpp:73
219+msgid "Lock to Launcher"
220+msgstr ""
221+
222+#: plugins/Unity/Launcher/launcheritem.cpp:73
223+msgid "Unlock from Launcher"
224+msgstr ""
225+
226+#: plugins/Unity/scope.cpp:408
214227msgid "Sorry, there is nothing that matches your search."
215228msgstr "Nažalost, ne postoji ništa što odgovara vašoj pretrazi."
216229
@@ -218,13 +231,7 @@ msgstr "Nažalost, ne postoji ništa što odgovara vašoj pretrazi."
218231msgid "All"
219232msgstr ""
220233
221−#: Shell.qml:438
234+#: Shell.qml:441
222235#, qt-format
223236msgid "Please enter %1"
224237msgstr ""
225−
226−#~ msgid "Music"
227−#~ msgstr "Glazba"
228−
229−#~ msgid "Videos"
230−#~ msgstr "Video"
po/hu.po+22−15
@@ -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-12 16:10+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-19 05:59+0000\n"
19+"X-Generator: Launchpad (build 16831)\n"
2020
2121#: Applications/applications.js:23
2222msgid "Phone"
@@ -86,7 +86,7 @@ msgstr ""
8686msgid "YouTube"
8787msgstr ""
8888
89−#: Components/EdgeDemoOverlay.qml:149
89+#: Components/EdgeDemoOverlay.qml:151
9090msgid "Skip intro"
9191msgstr ""
9292
@@ -132,7 +132,7 @@ msgid ""
132132"phone<br><br>Tap anywhere to start"
133133msgstr ""
134134
135−#: Components/PageHeader.qml:341
135+#: Components/PageHeader.qml:345
136136msgid "Recent searches"
137137msgstr "Legutóbbi keresések"
138138
@@ -152,7 +152,7 @@ msgid_plural "%1 reviews"
152152msgstr[0] ""
153153msgstr[1] ""
154154
155−#: Dash/Apps/AppPreview.qml:126
155+#: Dash/Apps/AppPreview.qml:135
156156msgid "Rate this"
157157msgstr ""
158158
@@ -172,7 +172,7 @@ msgstr ""
172172msgid "Comments:"
173173msgstr ""
174174
175−#: Greeter/Lockscreen.qml:142
175+#: Greeter/Lockscreen.qml:146
176176msgid "Emergency Call"
177177msgstr ""
178178
@@ -205,11 +205,24 @@ 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/Launcher/launcheritem.cpp:43
217+#: plugins/Unity/Launcher/launcheritem.cpp:73
218+msgid "Lock to Launcher"
219+msgstr ""
220+
221+#: plugins/Unity/Launcher/launcheritem.cpp:73
222+msgid "Unlock from Launcher"
223+msgstr ""
224+
225+#: plugins/Unity/scope.cpp:408
213226msgid "Sorry, there is nothing that matches your search."
214227msgstr "Elnézést, nincs találat a keresésre."
215228
@@ -217,13 +230,7 @@ msgstr "Elnézést, nincs találat a keresésre."
217230msgid "All"
218231msgstr ""
219232
220−#: Shell.qml:438
233+#: Shell.qml:441
221234#, qt-format
222235msgid "Please enter %1"
223236msgstr ""
224−
225−#~ msgid "Music"
226−#~ msgstr "Zene"
227−
228−#~ msgid "Videos"
229−#~ msgstr "Videók"
po/hy.po+22−15
@@ -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-12 16:10+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-19 05:59+0000\n"
19+"X-Generator: Launchpad (build 16831)\n"
2020
2121#: Applications/applications.js:23
2222msgid "Phone"
@@ -86,7 +86,7 @@ msgstr ""
8686msgid "YouTube"
8787msgstr ""
8888
89−#: Components/EdgeDemoOverlay.qml:149
89+#: Components/EdgeDemoOverlay.qml:151
9090msgid "Skip intro"
9191msgstr ""
9292
@@ -132,7 +132,7 @@ msgid ""
132132"phone<br><br>Tap anywhere to start"
133133msgstr ""
134134
135−#: Components/PageHeader.qml:341
135+#: Components/PageHeader.qml:345
136136msgid "Recent searches"
137137msgstr "Վերջին որոնումներ"
138138
@@ -152,7 +152,7 @@ msgid_plural "%1 reviews"
152152msgstr[0] ""
153153msgstr[1] ""
154154
155−#: Dash/Apps/AppPreview.qml:126
155+#: Dash/Apps/AppPreview.qml:135
156156msgid "Rate this"
157157msgstr ""
158158
@@ -172,7 +172,7 @@ msgstr ""
172172msgid "Comments:"
173173msgstr ""
174174
175−#: Greeter/Lockscreen.qml:142
175+#: Greeter/Lockscreen.qml:146
176176msgid "Emergency Call"
177177msgstr ""
178178
@@ -205,11 +205,24 @@ 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/Launcher/launcheritem.cpp:43
217+#: plugins/Unity/Launcher/launcheritem.cpp:73
218+msgid "Lock to Launcher"
219+msgstr ""
220+
221+#: plugins/Unity/Launcher/launcheritem.cpp:73
222+msgid "Unlock from Launcher"
223+msgstr ""
224+
225+#: plugins/Unity/scope.cpp:408
213226msgid "Sorry, there is nothing that matches your search."
214227msgstr "Կներերք, բայց Ձեր հարցումով ոչինչ չկար"
215228
@@ -217,13 +230,7 @@ msgstr "Կներերք, բայց Ձեր հարցումով ոչինչ չկար"
217230msgid "All"
218231msgstr ""
219232
220−#: Shell.qml:438
233+#: Shell.qml:441
221234#, qt-format
222235msgid "Please enter %1"
223236msgstr ""
224−
225−#~ msgid "Music"
226−#~ msgstr "Երգեր"
227−
228−#~ msgid "Videos"
229−#~ msgstr "Վիդեոներ"
po/id.po+22−9
@@ -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-12 16:10+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-19 05:59+0000\n"
19+"X-Generator: Launchpad (build 16831)\n"
2020
2121#: Applications/applications.js:23
2222msgid "Phone"
@@ -86,7 +86,7 @@ msgstr ""
8686msgid "YouTube"
8787msgstr ""
8888
89−#: Components/EdgeDemoOverlay.qml:149
89+#: Components/EdgeDemoOverlay.qml:151
9090msgid "Skip intro"
9191msgstr ""
9292
@@ -132,7 +132,7 @@ msgid ""
132132"phone<br><br>Tap anywhere to start"
133133msgstr ""
134134
135−#: Components/PageHeader.qml:341
135+#: Components/PageHeader.qml:345
136136msgid "Recent searches"
137137msgstr ""
138138
@@ -152,7 +152,7 @@ msgid_plural "%1 reviews"
152152msgstr[0] ""
153153msgstr[1] ""
154154
155−#: Dash/Apps/AppPreview.qml:126
155+#: Dash/Apps/AppPreview.qml:135
156156msgid "Rate this"
157157msgstr ""
158158
@@ -172,7 +172,7 @@ msgstr ""
172172msgid "Comments:"
173173msgstr ""
174174
175−#: Greeter/Lockscreen.qml:142
175+#: Greeter/Lockscreen.qml:146
176176msgid "Emergency Call"
177177msgstr ""
178178
@@ -205,11 +205,24 @@ 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/Launcher/launcheritem.cpp:43
217+#: plugins/Unity/Launcher/launcheritem.cpp:73
218+msgid "Lock to Launcher"
219+msgstr ""
220+
221+#: plugins/Unity/Launcher/launcheritem.cpp:73
222+msgid "Unlock from Launcher"
223+msgstr ""
224+
225+#: plugins/Unity/scope.cpp:408
213226msgid "Sorry, there is nothing that matches your search."
214227msgstr ""
215228
@@ -217,7 +230,7 @@ msgstr ""
217230msgid "All"
218231msgstr ""
219232
220−#: Shell.qml:438
233+#: Shell.qml:441
221234#, qt-format
222235msgid "Please enter %1"
223236msgstr ""
po/is.po+22−30
@@ -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-12 16:10+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-19 05:59+0000\n"
19+"X-Generator: Launchpad (build 16831)\n"
2020
2121#: Applications/applications.js:23
2222msgid "Phone"
@@ -86,7 +86,7 @@ msgstr "Wikipedia"
8686msgid "YouTube"
8787msgstr "YouTube"
8888
89−#: Components/EdgeDemoOverlay.qml:149
89+#: Components/EdgeDemoOverlay.qml:151
9090msgid "Skip intro"
9191msgstr "Hoppa yfir kynningu"
9292
@@ -133,7 +133,7 @@ msgid ""
133133"phone<br><br>Tap anywhere to start"
134134msgstr ""
135135
136−#: Components/PageHeader.qml:341
136+#: Components/PageHeader.qml:345
137137msgid "Recent searches"
138138msgstr "Nýlegar leitir"
139139
@@ -153,7 +153,7 @@ msgid_plural "%1 reviews"
153153msgstr[0] "%1 ummæli"
154154msgstr[1] "%1 ummæli"
155155
156−#: Dash/Apps/AppPreview.qml:126
156+#: Dash/Apps/AppPreview.qml:135
157157msgid "Rate this"
158158msgstr "Gefa þessu einkunn"
159159
@@ -173,7 +173,7 @@ msgstr "Senda"
173173msgid "Comments:"
174174msgstr "Athugasemdir:"
175175
176−#: Greeter/Lockscreen.qml:142
176+#: Greeter/Lockscreen.qml:146
177177msgid "Emergency Call"
178178msgstr "Neyðarsímtal"
179179
@@ -206,11 +206,24 @@ 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/Launcher/launcheritem.cpp:43
218+#: plugins/Unity/Launcher/launcheritem.cpp:73
219+msgid "Lock to Launcher"
220+msgstr ""
221+
222+#: plugins/Unity/Launcher/launcheritem.cpp:73
223+msgid "Unlock from Launcher"
224+msgstr ""
225+
226+#: plugins/Unity/scope.cpp:408
214227msgid "Sorry, there is nothing that matches your search."
215228msgstr "Því miður, það var ekkert sem passaði við leitarorðið þitt."
216229
@@ -218,28 +231,7 @@ msgstr "Því miður, það var ekkert sem passaði við leitarorðið þitt."
218231msgid "All"
219232msgstr ""
220233
221−#: Shell.qml:438
234+#: Shell.qml:441
222235#, qt-format
223236msgid "Please enter %1"
224237msgstr ""
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+22−30
@@ -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-12 16:10+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-19 05:59+0000\n"
19+"X-Generator: Launchpad (build 16831)\n"
2020
2121#: Applications/applications.js:23
2222msgid "Phone"
@@ -86,7 +86,7 @@ msgstr "Wikipedia"
8686msgid "YouTube"
8787msgstr "YouTube"
8888
89−#: Components/EdgeDemoOverlay.qml:149
89+#: Components/EdgeDemoOverlay.qml:151
9090msgid "Skip intro"
9191msgstr "Salta introduzione"
9292
@@ -139,7 +139,7 @@ msgstr ""
139139"I gesti sui bordi sono stati configurati ed è possibile iniziare a usare il "
140140"telefono<br><br>Toccare in un punto qualunque per iniziare"
141141
142−#: Components/PageHeader.qml:341
142+#: Components/PageHeader.qml:345
143143msgid "Recent searches"
144144msgstr "Ricerche recenti"
145145
@@ -159,7 +159,7 @@ msgid_plural "%1 reviews"
159159msgstr[0] "%1 recensione"
160160msgstr[1] "%1 recensioni"
161161
162−#: Dash/Apps/AppPreview.qml:126
162+#: Dash/Apps/AppPreview.qml:135
163163msgid "Rate this"
164164msgstr "Valuta"
165165
@@ -179,7 +179,7 @@ msgstr "Invia"
179179msgid "Comments:"
180180msgstr "Commenti:"
181181
182−#: Greeter/Lockscreen.qml:142
182+#: Greeter/Lockscreen.qml:146
183183msgid "Emergency Call"
184184msgstr "Chiamata di emergenza"
185185
@@ -212,11 +212,24 @@ 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/Launcher/launcheritem.cpp:43
224+#: plugins/Unity/Launcher/launcheritem.cpp:73
225+msgid "Lock to Launcher"
226+msgstr ""
227+
228+#: plugins/Unity/Launcher/launcheritem.cpp:73
229+msgid "Unlock from Launcher"
230+msgstr ""
231+
232+#: plugins/Unity/scope.cpp:408
220233msgid "Sorry, there is nothing that matches your search."
221234msgstr "Nessun risultato corrispondente alla ricerca."
222235
@@ -224,28 +237,7 @@ msgstr "Nessun risultato corrispondente alla ricerca."
224237msgid "All"
225238msgstr "Tutto"
226239
227−#: Shell.qml:438
240+#: Shell.qml:441
228241#, qt-format
229242msgid "Please enter %1"
230243msgstr "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+22−9
@@ -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-12 16:10+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-19 05:59+0000\n"
19+"X-Generator: Launchpad (build 16831)\n"
2020
2121#: Applications/applications.js:23
2222msgid "Phone"
@@ -86,7 +86,7 @@ msgstr ""
8686msgid "YouTube"
8787msgstr ""
8888
89−#: Components/EdgeDemoOverlay.qml:149
89+#: Components/EdgeDemoOverlay.qml:151
9090msgid "Skip intro"
9191msgstr ""
9292
@@ -132,7 +132,7 @@ msgid ""
132132"phone<br><br>Tap anywhere to start"
133133msgstr ""
134134
135−#: Components/PageHeader.qml:341
135+#: Components/PageHeader.qml:345
136136msgid "Recent searches"
137137msgstr ""
138138
@@ -152,7 +152,7 @@ msgid_plural "%1 reviews"
152152msgstr[0] ""
153153msgstr[1] ""
154154
155−#: Dash/Apps/AppPreview.qml:126
155+#: Dash/Apps/AppPreview.qml:135
156156msgid "Rate this"
157157msgstr ""
158158
@@ -172,7 +172,7 @@ msgstr ""
172172msgid "Comments:"
173173msgstr ""
174174
175−#: Greeter/Lockscreen.qml:142
175+#: Greeter/Lockscreen.qml:146
176176msgid "Emergency Call"
177177msgstr ""
178178
@@ -205,11 +205,24 @@ 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/Launcher/launcheritem.cpp:43
217+#: plugins/Unity/Launcher/launcheritem.cpp:73
218+msgid "Lock to Launcher"
219+msgstr ""
220+
221+#: plugins/Unity/Launcher/launcheritem.cpp:73
222+msgid "Unlock from Launcher"
223+msgstr ""
224+
225+#: plugins/Unity/scope.cpp:408
213226msgid "Sorry, there is nothing that matches your search."
214227msgstr ""
215228
@@ -217,7 +230,7 @@ msgstr ""
217230msgid "All"
218231msgstr ""
219232
220−#: Shell.qml:438
233+#: Shell.qml:441
221234#, qt-format
222235msgid "Please enter %1"
223236msgstr ""
po/km.po+24−32
@@ -7,16 +7,16 @@ 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"
11−"PO-Revision-Date: 2013-10-11 08:49+0000\n"
12−"Last-Translator: Khoem Sokhem <khoemsokhem@khmeros.info>\n"
10+"POT-Creation-Date: 2013-11-12 16:10+0100\n"
11+"PO-Revision-Date: 2013-11-14 03:02+0000\n"
12+"Last-Translator: Seng Sutha <sutha@khmeros.info>\n"
1313"Language-Team: Khmer <km@li.org>\n"
1414"MIME-Version: 1.0\n"
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-19 05:59+0000\n"
19+"X-Generator: Launchpad (build 16831)\n"
2020
2121#: Applications/applications.js:23
2222msgid "Phone"
@@ -86,7 +86,7 @@ msgstr "វីគីភីឌៀ"
8686msgid "YouTube"
8787msgstr "YouTube"
8888
89−#: Components/EdgeDemoOverlay.qml:149
89+#: Components/EdgeDemoOverlay.qml:151
9090msgid "Skip intro"
9191msgstr "រំលង​ការ​ណែនាំ"
9292
@@ -137,7 +137,7 @@ msgstr ""
137137"និង​អាច​ចាប់ផ្ដើម​ប្រើ​ទូរស័ព្ទ​បាន<br><br>ប៉ះ​កន្លែង​ណា​មួយ​ "
138138"ដើម្បី​ចាប់ផ្ដើម"
139139
140−#: Components/PageHeader.qml:341
140+#: Components/PageHeader.qml:345
141141msgid "Recent searches"
142142msgstr "ការ​ស្វែងរក​ថ្មី"
143143
@@ -156,7 +156,7 @@ msgid "%1 review"
156156msgid_plural "%1 reviews"
157157msgstr[0] "ពិនិត្យ​មើល %1"
158158
159−#: Dash/Apps/AppPreview.qml:126
159+#: Dash/Apps/AppPreview.qml:135
160160msgid "Rate this"
161161msgstr "វាយតម្លៃ​វា"
162162
@@ -176,7 +176,7 @@ msgstr "ផ្ញើ"
176176msgid "Comments:"
177177msgstr "មតិយោបល់៖"
178178
179−#: Greeter/Lockscreen.qml:142
179+#: Greeter/Lockscreen.qml:146
180180msgid "Emergency Call"
181181msgstr "ការ​ហៅ​ពេល​អាសន្ន"
182182
@@ -209,11 +209,24 @@ 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/Launcher/launcheritem.cpp:43
221+#: plugins/Unity/Launcher/launcheritem.cpp:73
222+msgid "Lock to Launcher"
223+msgstr ""
224+
225+#: plugins/Unity/Launcher/launcheritem.cpp:73
226+msgid "Unlock from Launcher"
227+msgstr ""
228+
229+#: plugins/Unity/scope.cpp:408
217230msgid "Sorry, there is nothing that matches your search."
218231msgstr "សូម​ទោស មិនមាន​ពាក្យ​ដែល​អ្នក​ស្វែងរក​ទេ​។"
219232
@@ -221,28 +234,7 @@ msgstr "សូម​ទោស មិនមាន​ពាក្យ​ដែល
221234msgid "All"
222235msgstr "ទាំង​អស់"
223236
224−#: Shell.qml:438
237+#: Shell.qml:441
225238#, qt-format
226239msgid "Please enter %1"
227240msgstr "សូម​បញ្ចូល %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+22−15
@@ -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-12 16:10+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-19 05:59+0000\n"
19+"X-Generator: Launchpad (build 16831)\n"
2020
2121#: Applications/applications.js:23
2222msgid "Phone"
@@ -86,7 +86,7 @@ msgstr ""
8686msgid "YouTube"
8787msgstr ""
8888
89−#: Components/EdgeDemoOverlay.qml:149
89+#: Components/EdgeDemoOverlay.qml:151
9090msgid "Skip intro"
9191msgstr ""
9292
@@ -132,7 +132,7 @@ msgid ""
132132"phone<br><br>Tap anywhere to start"
133133msgstr ""
134134
135−#: Components/PageHeader.qml:341
135+#: Components/PageHeader.qml:345
136136msgid "Recent searches"
137137msgstr "ಇತ್ತೀಚಿನ ಹುಡುಕಾಟಗಳು"
138138
@@ -152,7 +152,7 @@ msgid_plural "%1 reviews"
152152msgstr[0] ""
153153msgstr[1] ""
154154
155−#: Dash/Apps/AppPreview.qml:126
155+#: Dash/Apps/AppPreview.qml:135
156156msgid "Rate this"
157157msgstr ""
158158
@@ -172,7 +172,7 @@ msgstr ""
172172msgid "Comments:"
173173msgstr ""
174174
175−#: Greeter/Lockscreen.qml:142
175+#: Greeter/Lockscreen.qml:146
176176msgid "Emergency Call"
177177msgstr ""
178178
@@ -205,11 +205,24 @@ 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/Launcher/launcheritem.cpp:43
217+#: plugins/Unity/Launcher/launcheritem.cpp:73
218+msgid "Lock to Launcher"
219+msgstr ""
220+
221+#: plugins/Unity/Launcher/launcheritem.cpp:73
222+msgid "Unlock from Launcher"
223+msgstr ""
224+
225+#: plugins/Unity/scope.cpp:408
213226msgid "Sorry, there is nothing that matches your search."
214227msgstr "ಕ್ಷಮಿಸಿ ನಿಮ್ಮ ಶೋಧನೆಗೆ ಸರಿಯಾದ ಹೊಂದಾಣಿಕೆಗಳು ದೊರಕುತ್ತಿಲ್ಲ"
215228
@@ -217,13 +230,7 @@ msgstr "ಕ್ಷಮಿಸಿ ನಿಮ್ಮ ಶೋಧನೆಗೆ ಸರಿಯ
217230msgid "All"
218231msgstr ""
219232
220−#: Shell.qml:438
233+#: Shell.qml:441
221234#, qt-format
222235msgid "Please enter %1"
223236msgstr ""
224−
225−#~ msgid "Music"
226−#~ msgstr "ಸಂಗೀತ"
227−
228−#~ msgid "Videos"
229−#~ msgstr "ವೀಡಿಯೋಗಳು"
po/ko.po+22−12
@@ -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-12 16:10+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-19 05:59+0000\n"
19+"X-Generator: Launchpad (build 16831)\n"
2020
2121#: Applications/applications.js:23
2222msgid "Phone"
@@ -86,7 +86,7 @@ msgstr "위키백과"
8686msgid "YouTube"
8787msgstr "유튜브"
8888
89−#: Components/EdgeDemoOverlay.qml:149
89+#: Components/EdgeDemoOverlay.qml:151
9090msgid "Skip intro"
9191msgstr "도입부 건너뛰기"
9292
@@ -132,7 +132,7 @@ msgid ""
132132"phone<br><br>Tap anywhere to start"
133133msgstr ""
134134
135−#: Components/PageHeader.qml:341
135+#: Components/PageHeader.qml:345
136136msgid "Recent searches"
137137msgstr "최근 검색"
138138
@@ -152,7 +152,7 @@ msgid_plural "%1 reviews"
152152msgstr[0] ""
153153msgstr[1] ""
154154
155−#: Dash/Apps/AppPreview.qml:126
155+#: Dash/Apps/AppPreview.qml:135
156156msgid "Rate this"
157157msgstr ""
158158
@@ -172,7 +172,7 @@ msgstr ""
172172msgid "Comments:"
173173msgstr ""
174174
175−#: Greeter/Lockscreen.qml:142
175+#: Greeter/Lockscreen.qml:146
176176msgid "Emergency Call"
177177msgstr ""
178178
@@ -205,11 +205,24 @@ 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/Launcher/launcheritem.cpp:43
217+#: plugins/Unity/Launcher/launcheritem.cpp:73
218+msgid "Lock to Launcher"
219+msgstr ""
220+
221+#: plugins/Unity/Launcher/launcheritem.cpp:73
222+msgid "Unlock from Launcher"
223+msgstr ""
224+
225+#: plugins/Unity/scope.cpp:408
213226msgid "Sorry, there is nothing that matches your search."
214227msgstr ""
215228
@@ -217,10 +230,7 @@ msgstr ""
217230msgid "All"
218231msgstr ""
219232
220−#: Shell.qml:438
233+#: Shell.qml:441
221234#, qt-format
222235msgid "Please enter %1"
223236msgstr ""
224−
225−#~ msgid "Music"
226−#~ msgstr "음악"
po/ky.po+22−15
@@ -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-12 16:10+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-19 05:59+0000\n"
19+"X-Generator: Launchpad (build 16831)\n"
2020
2121#: Applications/applications.js:23
2222msgid "Phone"
@@ -86,7 +86,7 @@ msgstr ""
8686msgid "YouTube"
8787msgstr ""
8888
89−#: Components/EdgeDemoOverlay.qml:149
89+#: Components/EdgeDemoOverlay.qml:151
9090msgid "Skip intro"
9191msgstr ""
9292
@@ -132,7 +132,7 @@ msgid ""
132132"phone<br><br>Tap anywhere to start"
133133msgstr ""
134134
135−#: Components/PageHeader.qml:341
135+#: Components/PageHeader.qml:345
136136msgid "Recent searches"
137137msgstr "Соңку издөөлөр"
138138
@@ -152,7 +152,7 @@ msgid_plural "%1 reviews"
152152msgstr[0] ""
153153msgstr[1] ""
154154
155−#: Dash/Apps/AppPreview.qml:126
155+#: Dash/Apps/AppPreview.qml:135
156156msgid "Rate this"
157157msgstr ""
158158
@@ -172,7 +172,7 @@ msgstr ""
172172msgid "Comments:"
173173msgstr ""
174174
175−#: Greeter/Lockscreen.qml:142
175+#: Greeter/Lockscreen.qml:146
176176msgid "Emergency Call"
177177msgstr ""
178178
@@ -205,11 +205,24 @@ 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/Launcher/launcheritem.cpp:43
217+#: plugins/Unity/Launcher/launcheritem.cpp:73
218+msgid "Lock to Launcher"
219+msgstr ""
220+
221+#: plugins/Unity/Launcher/launcheritem.cpp:73
222+msgid "Unlock from Launcher"
223+msgstr ""
224+
225+#: plugins/Unity/scope.cpp:408
213226msgid "Sorry, there is nothing that matches your search."
214227msgstr "Тилекке каршы, сиздин издөөңүзгө эч нерсе дал келген жок."
215228
@@ -217,13 +230,7 @@ msgstr "Тилекке каршы, сиздин издөөңүзгө эч нер
217230msgid "All"
218231msgstr ""
219232
220−#: Shell.qml:438
233+#: Shell.qml:441
221234#, qt-format
222235msgid "Please enter %1"
223236msgstr ""
224−
225−#~ msgid "Music"
226−#~ msgstr "Музыка"
227−
228−#~ msgid "Videos"
229−#~ msgstr "Видеолор"
po/lo.po+22−15
@@ -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-12 16:10+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-19 05:59+0000\n"
19+"X-Generator: Launchpad (build 16831)\n"
2020
2121#: Applications/applications.js:23
2222msgid "Phone"
@@ -86,7 +86,7 @@ msgstr ""
8686msgid "YouTube"
8787msgstr "ິYouTube"
8888
89−#: Components/EdgeDemoOverlay.qml:149
89+#: Components/EdgeDemoOverlay.qml:151
9090msgid "Skip intro"
9191msgstr ""
9292
@@ -132,7 +132,7 @@ msgid ""
132132"phone<br><br>Tap anywhere to start"
133133msgstr ""
134134
135−#: Components/PageHeader.qml:341
135+#: Components/PageHeader.qml:345
136136msgid "Recent searches"
137137msgstr ""
138138
@@ -152,7 +152,7 @@ msgid_plural "%1 reviews"
152152msgstr[0] ""
153153msgstr[1] ""
154154
155−#: Dash/Apps/AppPreview.qml:126
155+#: Dash/Apps/AppPreview.qml:135
156156msgid "Rate this"
157157msgstr ""
158158
@@ -172,7 +172,7 @@ msgstr "ສົ່ງ"
172172msgid "Comments:"
173173msgstr "ຄໍ່ເຫັນ"
174174
175−#: Greeter/Lockscreen.qml:142
175+#: Greeter/Lockscreen.qml:146
176176msgid "Emergency Call"
177177msgstr ""
178178
@@ -205,11 +205,24 @@ 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/Launcher/launcheritem.cpp:43
217+#: plugins/Unity/Launcher/launcheritem.cpp:73
218+msgid "Lock to Launcher"
219+msgstr ""
220+
221+#: plugins/Unity/Launcher/launcheritem.cpp:73
222+msgid "Unlock from Launcher"
223+msgstr ""
224+
225+#: plugins/Unity/scope.cpp:408
213226msgid "Sorry, there is nothing that matches your search."
214227msgstr ""
215228
@@ -217,13 +230,7 @@ msgstr ""
217230msgid "All"
218231msgstr "ທັງໝົດ"
219232
220−#: Shell.qml:438
233+#: Shell.qml:441
221234#, qt-format
222235msgid "Please enter %1"
223236msgstr "ກະລູນາປ້ອນ %1"
224−
225−#~ msgid "Videos"
226−#~ msgstr "ວິດີໂອ"
227−
228−#~ msgid "Music"
229−#~ msgstr "ດົນຕີ"
po/lv.po+22−15
@@ -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-12 16:10+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-19 05:59+0000\n"
19+"X-Generator: Launchpad (build 16831)\n"
2020
2121#: Applications/applications.js:23
2222msgid "Phone"
@@ -86,7 +86,7 @@ msgstr "Vikipēdija"
8686msgid "YouTube"
8787msgstr "YouTube"
8888
89−#: Components/EdgeDemoOverlay.qml:149
89+#: Components/EdgeDemoOverlay.qml:151
9090msgid "Skip intro"
9191msgstr ""
9292
@@ -132,7 +132,7 @@ msgid ""
132132"phone<br><br>Tap anywhere to start"
133133msgstr ""
134134
135−#: Components/PageHeader.qml:341
135+#: Components/PageHeader.qml:345
136136msgid "Recent searches"
137137msgstr "Nesen veiktās meklēšanas"
138138
@@ -152,7 +152,7 @@ msgid_plural "%1 reviews"
152152msgstr[0] ""
153153msgstr[1] ""
154154
155−#: Dash/Apps/AppPreview.qml:126
155+#: Dash/Apps/AppPreview.qml:135
156156msgid "Rate this"
157157msgstr ""
158158
@@ -172,7 +172,7 @@ msgstr ""
172172msgid "Comments:"
173173msgstr ""
174174
175−#: Greeter/Lockscreen.qml:142
175+#: Greeter/Lockscreen.qml:146
176176msgid "Emergency Call"
177177msgstr ""
178178
@@ -205,11 +205,24 @@ 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/Launcher/launcheritem.cpp:43
217+#: plugins/Unity/Launcher/launcheritem.cpp:73
218+msgid "Lock to Launcher"
219+msgstr ""
220+
221+#: plugins/Unity/Launcher/launcheritem.cpp:73
222+msgid "Unlock from Launcher"
223+msgstr ""
224+
225+#: plugins/Unity/scope.cpp:408
213226msgid "Sorry, there is nothing that matches your search."
214227msgstr "Diemžēl nekas neatbilst jūsu meklētajam."
215228
@@ -217,13 +230,7 @@ msgstr "Diemžēl nekas neatbilst jūsu meklētajam."
217230msgid "All"
218231msgstr ""
219232
220−#: Shell.qml:438
233+#: Shell.qml:441
221234#, qt-format
222235msgid "Please enter %1"
223236msgstr ""
224−
225−#~ msgid "Music"
226−#~ msgstr "Mūzika"
227−
228−#~ msgid "Videos"
229−#~ msgstr "Video"
po/my.po+22−24
@@ -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-12 16:10+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-19 05:59+0000\n"
19+"X-Generator: Launchpad (build 16831)\n"
2020
2121#: Applications/applications.js:23
2222msgid "Phone"
@@ -86,7 +86,7 @@ msgstr "ဝီကီပီဒီးယား"
8686msgid "YouTube"
8787msgstr "YouTube"
8888
89−#: Components/EdgeDemoOverlay.qml:149
89+#: Components/EdgeDemoOverlay.qml:151
9090msgid "Skip intro"
9191msgstr "မိတ်ဆက်ကိုကျော်မည်"
9292
@@ -132,7 +132,7 @@ msgid ""
132132"phone<br><br>Tap anywhere to start"
133133msgstr ""
134134
135−#: Components/PageHeader.qml:341
135+#: Components/PageHeader.qml:345
136136msgid "Recent searches"
137137msgstr "မကြာသေးခင်က ရှာဖွေခြင်း"
138138
@@ -152,7 +152,7 @@ msgid_plural "%1 reviews"
152152msgstr[0] ""
153153msgstr[1] ""
154154
155−#: Dash/Apps/AppPreview.qml:126
155+#: Dash/Apps/AppPreview.qml:135
156156msgid "Rate this"
157157msgstr "ဒီဟာကိုအမှတ်ပေးမည်"
158158
@@ -172,7 +172,7 @@ msgstr "ပို့မည်"
172172msgid "Comments:"
173173msgstr "မှတ်ချက်များ-"
174174
175−#: Greeter/Lockscreen.qml:142
175+#: Greeter/Lockscreen.qml:146
176176msgid "Emergency Call"
177177msgstr ""
178178
@@ -205,11 +205,24 @@ 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/Launcher/launcheritem.cpp:43
217+#: plugins/Unity/Launcher/launcheritem.cpp:73
218+msgid "Lock to Launcher"
219+msgstr ""
220+
221+#: plugins/Unity/Launcher/launcheritem.cpp:73
222+msgid "Unlock from Launcher"
223+msgstr ""
224+
225+#: plugins/Unity/scope.cpp:408
213226msgid "Sorry, there is nothing that matches your search."
214227msgstr "ဆောရီး၊ သင်၏ရှာဖွေမူနှင့်တူညီတာဘာမှမရှိပါ။"
215228
@@ -217,22 +230,7 @@ msgstr "ဆောရီး၊ သင်၏ရှာဖွေမူနှင့
217230msgid "All"
218231msgstr ""
219232
220−#: Shell.qml:438
233+#: Shell.qml:441
221234#, qt-format
222235msgid "Please enter %1"
223236msgstr ""
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+22−15
@@ -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-12 16:10+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-19 05:59+0000\n"
19+"X-Generator: Launchpad (build 16831)\n"
2020
2121#: Applications/applications.js:23
2222msgid "Phone"
@@ -86,7 +86,7 @@ msgstr ""
8686msgid "YouTube"
8787msgstr ""
8888
89−#: Components/EdgeDemoOverlay.qml:149
89+#: Components/EdgeDemoOverlay.qml:151
9090msgid "Skip intro"
9191msgstr ""
9292
@@ -132,7 +132,7 @@ msgid ""
132132"phone<br><br>Tap anywhere to start"
133133msgstr ""
134134
135−#: Components/PageHeader.qml:341
135+#: Components/PageHeader.qml:345
136136msgid "Recent searches"
137137msgstr "Siste søk"
138138
@@ -152,7 +152,7 @@ msgid_plural "%1 reviews"
152152msgstr[0] ""
153153msgstr[1] ""
154154
155−#: Dash/Apps/AppPreview.qml:126
155+#: Dash/Apps/AppPreview.qml:135
156156msgid "Rate this"
157157msgstr ""
158158
@@ -172,7 +172,7 @@ msgstr ""
172172msgid "Comments:"
173173msgstr ""
174174
175−#: Greeter/Lockscreen.qml:142
175+#: Greeter/Lockscreen.qml:146
176176msgid "Emergency Call"
177177msgstr ""
178178
@@ -205,11 +205,24 @@ 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/Launcher/launcheritem.cpp:43
217+#: plugins/Unity/Launcher/launcheritem.cpp:73
218+msgid "Lock to Launcher"
219+msgstr ""
220+
221+#: plugins/Unity/Launcher/launcheritem.cpp:73
222+msgid "Unlock from Launcher"
223+msgstr ""
224+
225+#: plugins/Unity/scope.cpp:408
213226msgid "Sorry, there is nothing that matches your search."
214227msgstr "Søket ga ingen treff."
215228
@@ -217,13 +230,7 @@ msgstr "Søket ga ingen treff."
217230msgid "All"
218231msgstr ""
219232
220−#: Shell.qml:438
233+#: Shell.qml:441
221234#, qt-format
222235msgid "Please enter %1"
223236msgstr ""
224−
225−#~ msgid "Music"
226−#~ msgstr "Musikk"
227−
228−#~ msgid "Videos"
229−#~ msgstr "Videoer"
po/nl.po+22−15
@@ -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-12 16:10+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-19 05:59+0000\n"
19+"X-Generator: Launchpad (build 16831)\n"
2020
2121#: Applications/applications.js:23
2222msgid "Phone"
@@ -86,7 +86,7 @@ msgstr ""
8686msgid "YouTube"
8787msgstr ""
8888
89−#: Components/EdgeDemoOverlay.qml:149
89+#: Components/EdgeDemoOverlay.qml:151
9090msgid "Skip intro"
9191msgstr ""
9292
@@ -132,7 +132,7 @@ msgid ""
132132"phone<br><br>Tap anywhere to start"
133133msgstr ""
134134
135−#: Components/PageHeader.qml:341
135+#: Components/PageHeader.qml:345
136136msgid "Recent searches"
137137msgstr "Recente zoekopdrachten"
138138
@@ -152,7 +152,7 @@ msgid_plural "%1 reviews"
152152msgstr[0] ""
153153msgstr[1] ""
154154
155−#: Dash/Apps/AppPreview.qml:126
155+#: Dash/Apps/AppPreview.qml:135
156156msgid "Rate this"
157157msgstr ""
158158
@@ -172,7 +172,7 @@ msgstr ""
172172msgid "Comments:"
173173msgstr ""
174174
175−#: Greeter/Lockscreen.qml:142
175+#: Greeter/Lockscreen.qml:146
176176msgid "Emergency Call"
177177msgstr ""
178178
@@ -205,11 +205,24 @@ 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/Launcher/launcheritem.cpp:43
217+#: plugins/Unity/Launcher/launcheritem.cpp:73
218+msgid "Lock to Launcher"
219+msgstr ""
220+
221+#: plugins/Unity/Launcher/launcheritem.cpp:73
222+msgid "Unlock from Launcher"
223+msgstr ""
224+
225+#: plugins/Unity/scope.cpp:408
213226msgid "Sorry, there is nothing that matches your search."
214227msgstr "Er is helaas niets dat met uw zoekopdracht overeenkomt."
215228
@@ -217,13 +230,7 @@ msgstr "Er is helaas niets dat met uw zoekopdracht overeenkomt."
217230msgid "All"
218231msgstr ""
219232
220−#: Shell.qml:438
233+#: Shell.qml:441
221234#, qt-format
222235msgid "Please enter %1"
223236msgstr ""
224−
225−#~ msgid "Music"
226−#~ msgstr "Muziek"
227−
228−#~ msgid "Videos"
229−#~ msgstr "Video's"
po/pl.po+22−9
@@ -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-12 16:10+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-19 05:59+0000\n"
20+"X-Generator: Launchpad (build 16831)\n"
2121
2222#: Applications/applications.js:23
2323msgid "Phone"
@@ -87,7 +87,7 @@ msgstr "Wikipedia"
8787msgid "YouTube"
8888msgstr "YouTube"
8989
90−#: Components/EdgeDemoOverlay.qml:149
90+#: Components/EdgeDemoOverlay.qml:151
9191msgid "Skip intro"
9292msgstr "Pomiń intro"
9393
@@ -137,7 +137,7 @@ msgstr ""
137137"Polecenia aktywatorów krawędzi ekranu zostały opanowane<br><br>Dotknij "
138138"gdziekolwiek aby kontynuować"
139139
140−#: Components/PageHeader.qml:341
140+#: Components/PageHeader.qml:345
141141msgid "Recent searches"
142142msgstr "Ostatnie wyszukiwania"
143143
@@ -158,7 +158,7 @@ msgstr[0] "%1 opinia"
158158msgstr[1] "%1 opinie"
159159msgstr[2] "%1 opinii"
160160
161−#: Dash/Apps/AppPreview.qml:126
161+#: Dash/Apps/AppPreview.qml:135
162162msgid "Rate this"
163163msgstr "Oceń to"
164164
@@ -178,7 +178,7 @@ msgstr "Wyślij"
178178msgid "Comments:"
179179msgstr "Komentarze:"
180180
181−#: Greeter/Lockscreen.qml:142
181+#: Greeter/Lockscreen.qml:146
182182msgid "Emergency Call"
183183msgstr "Telefon ratunkowy"
184184
@@ -211,11 +211,24 @@ 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/Launcher/launcheritem.cpp:43
223+#: plugins/Unity/Launcher/launcheritem.cpp:73
224+msgid "Lock to Launcher"
225+msgstr ""
226+
227+#: plugins/Unity/Launcher/launcheritem.cpp:73
228+msgid "Unlock from Launcher"
229+msgstr ""
230+
231+#: plugins/Unity/scope.cpp:408
219232msgid "Sorry, there is nothing that matches your search."
220233msgstr "Nie znaleziono pasujących wyników."
221234
@@ -223,7 +236,7 @@ msgstr "Nie znaleziono pasujących wyników."
223236msgid "All"
224237msgstr "Wszystko"
225238
226−#: Shell.qml:438
239+#: Shell.qml:441
227240#, qt-format
228241msgid "Please enter %1"
229242msgstr "Wprowadź %1"
po/pt_BR.po+22−30
@@ -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-12 16:10+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-19 05:59+0000\n"
19+"X-Generator: Launchpad (build 16831)\n"
2020
2121#: Applications/applications.js:23
2222msgid "Phone"
@@ -86,7 +86,7 @@ msgstr "Wikipédia"
8686msgid "YouTube"
8787msgstr "YouTube"
8888
89−#: Components/EdgeDemoOverlay.qml:149
89+#: Components/EdgeDemoOverlay.qml:151
9090msgid "Skip intro"
9191msgstr "Pular introdução"
9292
@@ -134,7 +134,7 @@ msgid ""
134134"phone<br><br>Tap anywhere to start"
135135msgstr ""
136136
137−#: Components/PageHeader.qml:341
137+#: Components/PageHeader.qml:345
138138msgid "Recent searches"
139139msgstr "Pesquisas recentes"
140140
@@ -154,7 +154,7 @@ msgid_plural "%1 reviews"
154154msgstr[0] "%1 análise"
155155msgstr[1] "%1 análises"
156156
157−#: Dash/Apps/AppPreview.qml:126
157+#: Dash/Apps/AppPreview.qml:135
158158msgid "Rate this"
159159msgstr "Avaliar isto"
160160
@@ -174,7 +174,7 @@ msgstr "Enviar"
174174msgid "Comments:"
175175msgstr "Comentários:"
176176
177−#: Greeter/Lockscreen.qml:142
177+#: Greeter/Lockscreen.qml:146
178178msgid "Emergency Call"
179179msgstr "Chamada de emergência"
180180
@@ -207,11 +207,24 @@ 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/Launcher/launcheritem.cpp:43
219+#: plugins/Unity/Launcher/launcheritem.cpp:73
220+msgid "Lock to Launcher"
221+msgstr ""
222+
223+#: plugins/Unity/Launcher/launcheritem.cpp:73
224+msgid "Unlock from Launcher"
225+msgstr ""
226+
227+#: plugins/Unity/scope.cpp:408
215228msgid "Sorry, there is nothing that matches your search."
216229msgstr "Desculpe, não há nada que corresponda à sua pesquisa."
217230
@@ -219,28 +232,7 @@ msgstr "Desculpe, não há nada que corresponda à sua pesquisa."
219232msgid "All"
220233msgstr ""
221234
222−#: Shell.qml:438
235+#: Shell.qml:441
223236#, qt-format
224237msgid "Please enter %1"
225238msgstr "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+22−15
@@ -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-12 16:10+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-19 05:59+0000\n"
20+"X-Generator: Launchpad (build 16831)\n"
2121
2222#: Applications/applications.js:23
2323msgid "Phone"
@@ -87,7 +87,7 @@ msgstr ""
8787msgid "YouTube"
8888msgstr ""
8989
90−#: Components/EdgeDemoOverlay.qml:149
90+#: Components/EdgeDemoOverlay.qml:151
9191msgid "Skip intro"
9292msgstr ""
9393
@@ -133,7 +133,7 @@ msgid ""
133133"phone<br><br>Tap anywhere to start"
134134msgstr ""
135135
136−#: Components/PageHeader.qml:341
136+#: Components/PageHeader.qml:345
137137msgid "Recent searches"
138138msgstr "Căutări recente"
139139
@@ -153,7 +153,7 @@ msgid_plural "%1 reviews"
153153msgstr[0] ""
154154msgstr[1] ""
155155
156−#: Dash/Apps/AppPreview.qml:126
156+#: Dash/Apps/AppPreview.qml:135
157157msgid "Rate this"
158158msgstr ""
159159
@@ -173,7 +173,7 @@ msgstr ""
173173msgid "Comments:"
174174msgstr ""
175175
176−#: Greeter/Lockscreen.qml:142
176+#: Greeter/Lockscreen.qml:146
177177msgid "Emergency Call"
178178msgstr ""
179179
@@ -206,11 +206,24 @@ 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/Launcher/launcheritem.cpp:43
218+#: plugins/Unity/Launcher/launcheritem.cpp:73
219+msgid "Lock to Launcher"
220+msgstr ""
221+
222+#: plugins/Unity/Launcher/launcheritem.cpp:73
223+msgid "Unlock from Launcher"
224+msgstr ""
225+
226+#: plugins/Unity/scope.cpp:408
214227msgid "Sorry, there is nothing that matches your search."
215228msgstr ""
216229"Ne pare rău, nu este nimic care se potrivește căutării dumneavoastră."
@@ -219,13 +232,7 @@ msgstr ""
219232msgid "All"
220233msgstr ""
221234
222−#: Shell.qml:438
235+#: Shell.qml:441
223236#, qt-format
224237msgid "Please enter %1"
225238msgstr ""
226−
227−#~ msgid "Music"
228−#~ msgstr "Muzică"
229−
230−#~ msgid "Videos"
231−#~ msgstr "Video"
po/ru.po+22−30
@@ -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-12 16:10+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-19 05:59+0000\n"
20+"X-Generator: Launchpad (build 16831)\n"
2121
2222#: Applications/applications.js:23
2323msgid "Phone"
@@ -87,7 +87,7 @@ msgstr "Википедия"
8787msgid "YouTube"
8888msgstr "YouTube"
8989
90−#: Components/EdgeDemoOverlay.qml:149
90+#: Components/EdgeDemoOverlay.qml:151
9191msgid "Skip intro"
9292msgstr "Пропустить обучение"
9393
@@ -138,7 +138,7 @@ msgid ""
138138"phone<br><br>Tap anywhere to start"
139139msgstr ""
140140
141−#: Components/PageHeader.qml:341
141+#: Components/PageHeader.qml:345
142142msgid "Recent searches"
143143msgstr "Последние поисковые запросы"
144144
@@ -157,7 +157,7 @@ msgid "%1 review"
157157msgid_plural "%1 reviews"
158158msgstr[0] "%1 отзыв"
159159
160−#: Dash/Apps/AppPreview.qml:126
160+#: Dash/Apps/AppPreview.qml:135
161161msgid "Rate this"
162162msgstr "Оцените это"
163163
@@ -177,7 +177,7 @@ msgstr "Отправить"
177177msgid "Comments:"
178178msgstr "Комментарии:"
179179
180−#: Greeter/Lockscreen.qml:142
180+#: Greeter/Lockscreen.qml:146
181181msgid "Emergency Call"
182182msgstr "Экстренный вызов"
183183
@@ -210,11 +210,24 @@ 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/Launcher/launcheritem.cpp:43
222+#: plugins/Unity/Launcher/launcheritem.cpp:73
223+msgid "Lock to Launcher"
224+msgstr ""
225+
226+#: plugins/Unity/Launcher/launcheritem.cpp:73
227+msgid "Unlock from Launcher"
228+msgstr ""
229+
230+#: plugins/Unity/scope.cpp:408
218231msgid "Sorry, there is nothing that matches your search."
219232msgstr "Извините, поиск не дал результатов."
220233
@@ -222,28 +235,7 @@ msgstr "Извините, поиск не дал результатов."
222235msgid "All"
223236msgstr ""
224237
225−#: Shell.qml:438
238+#: Shell.qml:441
226239#, qt-format
227240msgid "Please enter %1"
228241msgstr "Пожалуйста, введите %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+22−9
@@ -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-12 16:10+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-19 05:59+0000\n"
19+"X-Generator: Launchpad (build 16831)\n"
2020
2121#: Applications/applications.js:23
2222msgid "Phone"
@@ -86,7 +86,7 @@ msgstr ""
8686msgid "YouTube"
8787msgstr ""
8888
89−#: Components/EdgeDemoOverlay.qml:149
89+#: Components/EdgeDemoOverlay.qml:151
9090msgid "Skip intro"
9191msgstr ""
9292
@@ -132,7 +132,7 @@ msgid ""
132132"phone<br><br>Tap anywhere to start"
133133msgstr ""
134134
135−#: Components/PageHeader.qml:341
135+#: Components/PageHeader.qml:345
136136msgid "Recent searches"
137137msgstr ""
138138
@@ -152,7 +152,7 @@ msgid_plural "%1 reviews"
152152msgstr[0] ""
153153msgstr[1] ""
154154
155−#: Dash/Apps/AppPreview.qml:126
155+#: Dash/Apps/AppPreview.qml:135
156156msgid "Rate this"
157157msgstr ""
158158
@@ -172,7 +172,7 @@ msgstr ""
172172msgid "Comments:"
173173msgstr ""
174174
175−#: Greeter/Lockscreen.qml:142
175+#: Greeter/Lockscreen.qml:146
176176msgid "Emergency Call"
177177msgstr ""
178178
@@ -205,11 +205,24 @@ 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/Launcher/launcheritem.cpp:43
217+#: plugins/Unity/Launcher/launcheritem.cpp:73
218+msgid "Lock to Launcher"
219+msgstr ""
220+
221+#: plugins/Unity/Launcher/launcheritem.cpp:73
222+msgid "Unlock from Launcher"
223+msgstr ""
224+
225+#: plugins/Unity/scope.cpp:408
213226msgid "Sorry, there is nothing that matches your search."
214227msgstr ""
215228
@@ -217,7 +230,7 @@ msgstr ""
217230msgid "All"
218231msgstr ""
219232
220−#: Shell.qml:438
233+#: Shell.qml:441
221234#, qt-format
222235msgid "Please enter %1"
223236msgstr ""
po/si.po+22−9
@@ -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-12 16:10+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-19 05:59+0000\n"
19+"X-Generator: Launchpad (build 16831)\n"
2020
2121#: Applications/applications.js:23
2222msgid "Phone"
@@ -86,7 +86,7 @@ msgstr ""
8686msgid "YouTube"
8787msgstr ""
8888
89−#: Components/EdgeDemoOverlay.qml:149
89+#: Components/EdgeDemoOverlay.qml:151
9090msgid "Skip intro"
9191msgstr ""
9292
@@ -132,7 +132,7 @@ msgid ""
132132"phone<br><br>Tap anywhere to start"
133133msgstr ""
134134
135−#: Components/PageHeader.qml:341
135+#: Components/PageHeader.qml:345
136136msgid "Recent searches"
137137msgstr ""
138138
@@ -152,7 +152,7 @@ msgid_plural "%1 reviews"
152152msgstr[0] ""
153153msgstr[1] ""
154154
155−#: Dash/Apps/AppPreview.qml:126
155+#: Dash/Apps/AppPreview.qml:135
156156msgid "Rate this"
157157msgstr ""
158158
@@ -172,7 +172,7 @@ msgstr ""
172172msgid "Comments:"
173173msgstr ""
174174
175−#: Greeter/Lockscreen.qml:142
175+#: Greeter/Lockscreen.qml:146
176176msgid "Emergency Call"
177177msgstr ""
178178
@@ -205,11 +205,24 @@ 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/Launcher/launcheritem.cpp:43
217+#: plugins/Unity/Launcher/launcheritem.cpp:73
218+msgid "Lock to Launcher"
219+msgstr ""
220+
221+#: plugins/Unity/Launcher/launcheritem.cpp:73
222+msgid "Unlock from Launcher"
223+msgstr ""
224+
225+#: plugins/Unity/scope.cpp:408
213226msgid "Sorry, there is nothing that matches your search."
214227msgstr ""
215228
@@ -217,7 +230,7 @@ msgstr ""
217230msgid "All"
218231msgstr ""
219232
220−#: Shell.qml:438
233+#: Shell.qml:441
221234#, qt-format
222235msgid "Please enter %1"
223236msgstr ""
po/sl.po+22−30
@@ -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-12 16:10+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-19 05:59+0000\n"
20+"X-Generator: Launchpad (build 16831)\n"
2121
2222#: Applications/applications.js:23
2323msgid "Phone"
@@ -87,7 +87,7 @@ msgstr "Wikipedija"
8787msgid "YouTube"
8888msgstr "YouTube"
8989
90−#: Components/EdgeDemoOverlay.qml:149
90+#: Components/EdgeDemoOverlay.qml:151
9191msgid "Skip intro"
9292msgstr "Preskoči uvod"
9393
@@ -137,7 +137,7 @@ msgstr ""
137137"Sedaj ste osvojili poteze robov ter lahko začnete uporabljati "
138138"telefon<br><br>Tapnite kjerkoli na začetek"
139139
140−#: Components/PageHeader.qml:341
140+#: Components/PageHeader.qml:345
141141msgid "Recent searches"
142142msgstr "Nedavna iskanja"
143143
@@ -159,7 +159,7 @@ msgstr[1] "%1 ocena"
159159msgstr[2] "%1 oceni"
160160msgstr[3] "%1 ocene"
161161
162−#: Dash/Apps/AppPreview.qml:126
162+#: Dash/Apps/AppPreview.qml:135
163163msgid "Rate this"
164164msgstr "Ocenite"
165165
@@ -179,7 +179,7 @@ msgstr "Pošlji"
179179msgid "Comments:"
180180msgstr "Opombe:"
181181
182−#: Greeter/Lockscreen.qml:142
182+#: Greeter/Lockscreen.qml:146
183183msgid "Emergency Call"
184184msgstr "Klic v sili"
185185
@@ -212,11 +212,24 @@ 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/Launcher/launcheritem.cpp:43
224+#: plugins/Unity/Launcher/launcheritem.cpp:73
225+msgid "Lock to Launcher"
226+msgstr ""
227+
228+#: plugins/Unity/Launcher/launcheritem.cpp:73
229+msgid "Unlock from Launcher"
230+msgstr ""
231+
232+#: plugins/Unity/scope.cpp:408
220233msgid "Sorry, there is nothing that matches your search."
221234msgstr "Nič se ne ujema z vašim iskalnim nizom."
222235
@@ -224,28 +237,7 @@ msgstr "Nič se ne ujema z vašim iskalnim nizom."
224237msgid "All"
225238msgstr "Vse"
226239
227−#: Shell.qml:438
240+#: Shell.qml:441
228241#, qt-format
229242msgid "Please enter %1"
230243msgstr "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+22−15
@@ -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-12 16:10+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-19 05:59+0000\n"
20+"X-Generator: Launchpad (build 16831)\n"
2121
2222#: Applications/applications.js:23
2323msgid "Phone"
@@ -87,7 +87,7 @@ msgstr ""
8787msgid "YouTube"
8888msgstr ""
8989
90−#: Components/EdgeDemoOverlay.qml:149
90+#: Components/EdgeDemoOverlay.qml:151
9191msgid "Skip intro"
9292msgstr ""
9393
@@ -133,7 +133,7 @@ msgid ""
133133"phone<br><br>Tap anywhere to start"
134134msgstr ""
135135
136−#: Components/PageHeader.qml:341
136+#: Components/PageHeader.qml:345
137137msgid "Recent searches"
138138msgstr "Скорашње претраге"
139139
@@ -153,7 +153,7 @@ msgid_plural "%1 reviews"
153153msgstr[0] ""
154154msgstr[1] ""
155155
156−#: Dash/Apps/AppPreview.qml:126
156+#: Dash/Apps/AppPreview.qml:135
157157msgid "Rate this"
158158msgstr ""
159159
@@ -173,7 +173,7 @@ msgstr ""
173173msgid "Comments:"
174174msgstr ""
175175
176−#: Greeter/Lockscreen.qml:142
176+#: Greeter/Lockscreen.qml:146
177177msgid "Emergency Call"
178178msgstr ""
179179
@@ -206,11 +206,24 @@ 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/Launcher/launcheritem.cpp:43
218+#: plugins/Unity/Launcher/launcheritem.cpp:73
219+msgid "Lock to Launcher"
220+msgstr ""
221+
222+#: plugins/Unity/Launcher/launcheritem.cpp:73
223+msgid "Unlock from Launcher"
224+msgstr ""
225+
226+#: plugins/Unity/scope.cpp:408
214227msgid "Sorry, there is nothing that matches your search."
215228msgstr "Нажалост, претрага није наишла на икакво подударање."
216229
@@ -218,13 +231,7 @@ msgstr "Нажалост, претрага није наишла на икакв
218231msgid "All"
219232msgstr ""
220233
221−#: Shell.qml:438
234+#: Shell.qml:441
222235#, qt-format
223236msgid "Please enter %1"
224237msgstr ""
225−
226−#~ msgid "Music"
227−#~ msgstr "Музика"
228−
229−#~ msgid "Videos"
230−#~ msgstr "Видео"
po/sv.po+22−9
@@ -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-12 16:10+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-19 05:59+0000\n"
19+"X-Generator: Launchpad (build 16831)\n"
2020
2121#: Applications/applications.js:23
2222msgid "Phone"
@@ -86,7 +86,7 @@ msgstr ""
8686msgid "YouTube"
8787msgstr ""
8888
89−#: Components/EdgeDemoOverlay.qml:149
89+#: Components/EdgeDemoOverlay.qml:151
9090msgid "Skip intro"
9191msgstr ""
9292
@@ -132,7 +132,7 @@ msgid ""
132132"phone<br><br>Tap anywhere to start"
133133msgstr ""
134134
135−#: Components/PageHeader.qml:341
135+#: Components/PageHeader.qml:345
136136msgid "Recent searches"
137137msgstr ""
138138
@@ -152,7 +152,7 @@ msgid_plural "%1 reviews"
152152msgstr[0] ""
153153msgstr[1] ""
154154
155−#: Dash/Apps/AppPreview.qml:126
155+#: Dash/Apps/AppPreview.qml:135
156156msgid "Rate this"
157157msgstr ""
158158
@@ -172,7 +172,7 @@ msgstr ""
172172msgid "Comments:"
173173msgstr ""
174174
175−#: Greeter/Lockscreen.qml:142
175+#: Greeter/Lockscreen.qml:146
176176msgid "Emergency Call"
177177msgstr ""
178178
@@ -205,11 +205,24 @@ 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/Launcher/launcheritem.cpp:43
217+#: plugins/Unity/Launcher/launcheritem.cpp:73
218+msgid "Lock to Launcher"
219+msgstr ""
220+
221+#: plugins/Unity/Launcher/launcheritem.cpp:73
222+msgid "Unlock from Launcher"
223+msgstr ""
224+
225+#: plugins/Unity/scope.cpp:408
213226msgid "Sorry, there is nothing that matches your search."
214227msgstr ""
215228
@@ -217,7 +230,7 @@ msgstr ""
217230msgid "All"
218231msgstr ""
219232
220−#: Shell.qml:438
233+#: Shell.qml:441
221234#, qt-format
222235msgid "Please enter %1"
223236msgstr ""
po/ta.po+22−9
@@ -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-12 16:10+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-19 05:59+0000\n"
19+"X-Generator: Launchpad (build 16831)\n"
2020"Language: ta\n"
2121
2222#: Applications/applications.js:23
@@ -87,7 +87,7 @@ msgstr "விக்கிப்பீடியா"
8787msgid "YouTube"
8888msgstr "யூட்யுப்"
8989
90−#: Components/EdgeDemoOverlay.qml:149
90+#: Components/EdgeDemoOverlay.qml:151
9191msgid "Skip intro"
9292msgstr "அறிமுகத்தை தவிர்"
9393
@@ -138,7 +138,7 @@ msgstr ""
138138"பயன்படுத்த தொடங்கவும் <br> <br>தட்டுவதன் மூலம் எங்க வேண்டுமானாலும் "
139139"தொடங்கலாம்."
140140
141−#: Components/PageHeader.qml:341
141+#: Components/PageHeader.qml:345
142142msgid "Recent searches"
143143msgstr "கடையாக தேடப்பட்டவைகள்"
144144
@@ -158,7 +158,7 @@ msgid_plural "%1 reviews"
158158msgstr[0] "%1 பரிசீலனை"
159159msgstr[1] "%1 பரிசீலனைகள்"
160160
161−#: Dash/Apps/AppPreview.qml:126
161+#: Dash/Apps/AppPreview.qml:135
162162msgid "Rate this"
163163msgstr "இதை மதிப்பிடு"
164164
@@ -178,7 +178,7 @@ msgstr "அனுப்பு"
178178msgid "Comments:"
179179msgstr "கருத்துகள்:"
180180
181−#: Greeter/Lockscreen.qml:142
181+#: Greeter/Lockscreen.qml:146
182182msgid "Emergency Call"
183183msgstr "அவசர அழைப்பு"
184184
@@ -211,11 +211,24 @@ 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/Launcher/launcheritem.cpp:43
223+#: plugins/Unity/Launcher/launcheritem.cpp:73
224+msgid "Lock to Launcher"
225+msgstr ""
226+
227+#: plugins/Unity/Launcher/launcheritem.cpp:73
228+msgid "Unlock from Launcher"
229+msgstr ""
230+
231+#: plugins/Unity/scope.cpp:408
219232msgid "Sorry, there is nothing that matches your search."
220233msgstr "மன்னிக்கவும், உங்களுடைய தேடலுக்கு தகுந்த பொருத்தம் கிடைக்கவில்லை."
221234
@@ -223,7 +236,7 @@ msgstr "மன்னிக்கவும், உங்களுடைய தே
223236msgid "All"
224237msgstr "அனைத்தும்"
225238
226−#: Shell.qml:438
239+#: Shell.qml:441
227240#, qt-format
228241msgid "Please enter %1"
229242msgstr "தயவுச்செய்து %1 உள்ளிடு"
po/te.po+22−12
@@ -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-12 16:10+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-19 05:59+0000\n"
19+"X-Generator: Launchpad (build 16831)\n"
2020
2121#: Applications/applications.js:23
2222msgid "Phone"
@@ -86,7 +86,7 @@ msgstr ""
8686msgid "YouTube"
8787msgstr ""
8888
89−#: Components/EdgeDemoOverlay.qml:149
89+#: Components/EdgeDemoOverlay.qml:151
9090msgid "Skip intro"
9191msgstr ""
9292
@@ -132,7 +132,7 @@ msgid ""
132132"phone<br><br>Tap anywhere to start"
133133msgstr ""
134134
135−#: Components/PageHeader.qml:341
135+#: Components/PageHeader.qml:345
136136msgid "Recent searches"
137137msgstr ""
138138
@@ -152,7 +152,7 @@ msgid_plural "%1 reviews"
152152msgstr[0] ""
153153msgstr[1] ""
154154
155−#: Dash/Apps/AppPreview.qml:126
155+#: Dash/Apps/AppPreview.qml:135
156156msgid "Rate this"
157157msgstr ""
158158
@@ -172,7 +172,7 @@ msgstr ""
172172msgid "Comments:"
173173msgstr ""
174174
175−#: Greeter/Lockscreen.qml:142
175+#: Greeter/Lockscreen.qml:146
176176msgid "Emergency Call"
177177msgstr ""
178178
@@ -205,11 +205,24 @@ 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/Launcher/launcheritem.cpp:43
217+#: plugins/Unity/Launcher/launcheritem.cpp:73
218+msgid "Lock to Launcher"
219+msgstr ""
220+
221+#: plugins/Unity/Launcher/launcheritem.cpp:73
222+msgid "Unlock from Launcher"
223+msgstr ""
224+
225+#: plugins/Unity/scope.cpp:408
213226msgid "Sorry, there is nothing that matches your search."
214227msgstr ""
215228
@@ -217,10 +230,7 @@ msgstr ""
217230msgid "All"
218231msgstr ""
219232
220−#: Shell.qml:438
233+#: Shell.qml:441
221234#, qt-format
222235msgid "Please enter %1"
223236msgstr ""
224−
225−#~ msgid "Music"
226−#~ msgstr "సంగీతం"
po/tr.po+22−30
@@ -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-12 16:10+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-19 05:59+0000\n"
19+"X-Generator: Launchpad (build 16831)\n"
2020
2121#: Applications/applications.js:23
2222msgid "Phone"
@@ -86,7 +86,7 @@ msgstr "Vikipedi"
8686msgid "YouTube"
8787msgstr "YouTube"
8888
89−#: Components/EdgeDemoOverlay.qml:149
89+#: Components/EdgeDemoOverlay.qml:151
9090msgid "Skip intro"
9191msgstr "İntro'yu geç"
9292
@@ -133,7 +133,7 @@ msgid ""
133133"phone<br><br>Tap anywhere to start"
134134msgstr ""
135135
136−#: Components/PageHeader.qml:341
136+#: Components/PageHeader.qml:345
137137msgid "Recent searches"
138138msgstr "Son Arananlar"
139139
@@ -153,7 +153,7 @@ msgid_plural "%1 reviews"
153153msgstr[0] "%1 inceleme"
154154msgstr[1] "%1 inceleme"
155155
156−#: Dash/Apps/AppPreview.qml:126
156+#: Dash/Apps/AppPreview.qml:135
157157msgid "Rate this"
158158msgstr "Oyla"
159159
@@ -173,7 +173,7 @@ msgstr "Gönder"
173173msgid "Comments:"
174174msgstr "Yorumlar:"
175175
176−#: Greeter/Lockscreen.qml:142
176+#: Greeter/Lockscreen.qml:146
177177msgid "Emergency Call"
178178msgstr "Acil Arama"
179179
@@ -206,11 +206,24 @@ 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/Launcher/launcheritem.cpp:43
218+#: plugins/Unity/Launcher/launcheritem.cpp:73
219+msgid "Lock to Launcher"
220+msgstr ""
221+
222+#: plugins/Unity/Launcher/launcheritem.cpp:73
223+msgid "Unlock from Launcher"
224+msgstr ""
225+
226+#: plugins/Unity/scope.cpp:408
214227msgid "Sorry, there is nothing that matches your search."
215228msgstr "Üzgünüz, aramanızla eşleşen hiçbir şey yok."
216229
@@ -218,28 +231,7 @@ msgstr "Üzgünüz, aramanızla eşleşen hiçbir şey yok."
218231msgid "All"
219232msgstr ""
220233
221−#: Shell.qml:438
234+#: Shell.qml:441
222235#, qt-format
223236msgid "Please enter %1"
224237msgstr "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+22−24
@@ -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-12 16:10+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-19 05:59+0000\n"
19+"X-Generator: Launchpad (build 16831)\n"
2020
2121#: Applications/applications.js:23
2222msgid "Phone"
@@ -86,7 +86,7 @@ msgstr "ۋىكىپېدىيە"
8686msgid "YouTube"
8787msgstr "YouTube"
8888
89−#: Components/EdgeDemoOverlay.qml:149
89+#: Components/EdgeDemoOverlay.qml:151
9090msgid "Skip intro"
9191msgstr ""
9292
@@ -132,7 +132,7 @@ msgid ""
132132"phone<br><br>Tap anywhere to start"
133133msgstr ""
134134
135−#: Components/PageHeader.qml:341
135+#: Components/PageHeader.qml:345
136136msgid "Recent searches"
137137msgstr "يېقىنقى ئىزدەشلەر"
138138
@@ -151,7 +151,7 @@ msgid "%1 review"
151151msgid_plural "%1 reviews"
152152msgstr[0] "%1 باھا"
153153
154−#: Dash/Apps/AppPreview.qml:126
154+#: Dash/Apps/AppPreview.qml:135
155155msgid "Rate this"
156156msgstr ""
157157
@@ -171,7 +171,7 @@ msgstr "ئەۋەت"
171171msgid "Comments:"
172172msgstr "ئىنكاس:"
173173
174−#: Greeter/Lockscreen.qml:142
174+#: Greeter/Lockscreen.qml:146
175175msgid "Emergency Call"
176176msgstr ""
177177
@@ -204,11 +204,24 @@ 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/Launcher/launcheritem.cpp:43
216+#: plugins/Unity/Launcher/launcheritem.cpp:73
217+msgid "Lock to Launcher"
218+msgstr ""
219+
220+#: plugins/Unity/Launcher/launcheritem.cpp:73
221+msgid "Unlock from Launcher"
222+msgstr ""
223+
224+#: plugins/Unity/scope.cpp:408
212225msgid "Sorry, there is nothing that matches your search."
213226msgstr "كەچۈرۈڭ، ئىزدىگىنىڭىزگە ماس نەتىجە تېپىلمىدى."
214227
@@ -216,22 +229,7 @@ msgstr "كەچۈرۈڭ، ئىزدىگىنىڭىزگە ماس نەتىجە تېپ
216229msgid "All"
217230msgstr "ھەممىسى"
218231
219−#: Shell.qml:438
232+#: Shell.qml:441
220233#, qt-format
221234msgid "Please enter %1"
222235msgstr "%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+22−9
@@ -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-12 16:10+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-19 05:59+0000\n"
20+"X-Generator: Launchpad (build 16831)\n"
2121
2222#: Applications/applications.js:23
2323msgid "Phone"
@@ -87,7 +87,7 @@ msgstr "Вікіпедія"
8787msgid "YouTube"
8888msgstr "YouTube"
8989
90−#: Components/EdgeDemoOverlay.qml:149
90+#: Components/EdgeDemoOverlay.qml:151
9191msgid "Skip intro"
9292msgstr "Пропустити вступ"
9393
@@ -138,7 +138,7 @@ msgstr ""
138138"Тепер жести налаштовано, ви можете почати користуватися "
139139"телефоном.<br><br>Натисніть у довільному місці екрана."
140140
141−#: Components/PageHeader.qml:341
141+#: Components/PageHeader.qml:345
142142msgid "Recent searches"
143143msgstr "Нещодавні пошуки"
144144
@@ -159,7 +159,7 @@ msgstr[0] "%1 рецензія"
159159msgstr[1] "%1 рецензії"
160160msgstr[2] "%1 рецензій"
161161
162−#: Dash/Apps/AppPreview.qml:126
162+#: Dash/Apps/AppPreview.qml:135
163163msgid "Rate this"
164164msgstr "Оцінити"
165165
@@ -179,7 +179,7 @@ msgstr "Надіслати"
179179msgid "Comments:"
180180msgstr "Коментарі:"
181181
182−#: Greeter/Lockscreen.qml:142
182+#: Greeter/Lockscreen.qml:146
183183msgid "Emergency Call"
184184msgstr "Терміновий виклик"
185185
@@ -212,11 +212,24 @@ 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/Launcher/launcheritem.cpp:43
224+#: plugins/Unity/Launcher/launcheritem.cpp:73
225+msgid "Lock to Launcher"
226+msgstr ""
227+
228+#: plugins/Unity/Launcher/launcheritem.cpp:73
229+msgid "Unlock from Launcher"
230+msgstr ""
231+
232+#: plugins/Unity/scope.cpp:408
220233msgid "Sorry, there is nothing that matches your search."
221234msgstr "Вибачте, для вказаних вами ключових слів нічого не знайдено."
222235
@@ -224,7 +237,7 @@ msgstr "Вибачте, для вказаних вами ключових слі
224237msgid "All"
225238msgstr "Усе"
226239
227−#: Shell.qml:438
240+#: Shell.qml:441
228241#, qt-format
229242msgid "Please enter %1"
230243msgstr "Будь ласка, введіть %1"
po/unity8.pot+20−7
@@ -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-12 16:10+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"
@@ -86,7 +86,7 @@ msgstr ""
8686msgid "YouTube"
8787msgstr ""
8888
89−#: Components/EdgeDemoOverlay.qml:149
89+#: Components/EdgeDemoOverlay.qml:151
9090msgid "Skip intro"
9191msgstr ""
9292
@@ -132,7 +132,7 @@ msgid ""
132132"phone<br><br>Tap anywhere to start"
133133msgstr ""
134134
135−#: Components/PageHeader.qml:341
135+#: Components/PageHeader.qml:345
136136msgid "Recent searches"
137137msgstr ""
138138
@@ -152,7 +152,7 @@ msgid_plural "%1 reviews"
152152msgstr[0] ""
153153msgstr[1] ""
154154
155−#: Dash/Apps/AppPreview.qml:126
155+#: Dash/Apps/AppPreview.qml:135
156156msgid "Rate this"
157157msgstr ""
158158
@@ -172,7 +172,7 @@ msgstr ""
172172msgid "Comments:"
173173msgstr ""
174174
175−#: Greeter/Lockscreen.qml:142
175+#: Greeter/Lockscreen.qml:146
176176msgid "Emergency Call"
177177msgstr ""
178178
@@ -205,11 +205,24 @@ 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/Launcher/launcheritem.cpp:43
217+#: plugins/Unity/Launcher/launcheritem.cpp:73
218+msgid "Lock to Launcher"
219+msgstr ""
220+
221+#: plugins/Unity/Launcher/launcheritem.cpp:73
222+msgid "Unlock from Launcher"
223+msgstr ""
224+
225+#: plugins/Unity/scope.cpp:408
213226msgid "Sorry, there is nothing that matches your search."
214227msgstr ""
215228
@@ -217,7 +230,7 @@ msgstr ""
217230msgid "All"
218231msgstr ""
219232
220−#: Shell.qml:438
233+#: Shell.qml:441
221234#, qt-format
222235msgid "Please enter %1"
223236msgstr ""
po/xh.po+22−9
@@ -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-12 16:10+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-19 05:59+0000\n"
19+"X-Generator: Launchpad (build 16831)\n"
2020
2121#: Applications/applications.js:23
2222msgid "Phone"
@@ -86,7 +86,7 @@ msgstr ""
8686msgid "YouTube"
8787msgstr ""
8888
89−#: Components/EdgeDemoOverlay.qml:149
89+#: Components/EdgeDemoOverlay.qml:151
9090msgid "Skip intro"
9191msgstr ""
9292
@@ -132,7 +132,7 @@ msgid ""
132132"phone<br><br>Tap anywhere to start"
133133msgstr ""
134134
135−#: Components/PageHeader.qml:341
135+#: Components/PageHeader.qml:345
136136msgid "Recent searches"
137137msgstr ""
138138
@@ -152,7 +152,7 @@ msgid_plural "%1 reviews"
152152msgstr[0] ""
153153msgstr[1] ""
154154
155−#: Dash/Apps/AppPreview.qml:126
155+#: Dash/Apps/AppPreview.qml:135
156156msgid "Rate this"
157157msgstr ""
158158
@@ -172,7 +172,7 @@ msgstr ""
172172msgid "Comments:"
173173msgstr ""
174174
175−#: Greeter/Lockscreen.qml:142
175+#: Greeter/Lockscreen.qml:146
176176msgid "Emergency Call"
177177msgstr ""
178178
@@ -205,11 +205,24 @@ 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/Launcher/launcheritem.cpp:43
217+#: plugins/Unity/Launcher/launcheritem.cpp:73
218+msgid "Lock to Launcher"
219+msgstr ""
220+
221+#: plugins/Unity/Launcher/launcheritem.cpp:73
222+msgid "Unlock from Launcher"
223+msgstr ""
224+
225+#: plugins/Unity/scope.cpp:408
213226msgid "Sorry, there is nothing that matches your search."
214227msgstr ""
215228
@@ -217,7 +230,7 @@ msgstr ""
217230msgid "All"
218231msgstr ""
219232
220−#: Shell.qml:438
233+#: Shell.qml:441
221234#, qt-format
222235msgid "Please enter %1"
223236msgstr ""
po/zh_CN.po+22−30
@@ -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-12 16:10+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-19 05:59+0000\n"
19+"X-Generator: Launchpad (build 16831)\n"
2020
2121#: Applications/applications.js:23
2222msgid "Phone"
@@ -86,7 +86,7 @@ msgstr "维基百科"
8686msgid "YouTube"
8787msgstr "YouTube"
8888
89−#: Components/EdgeDemoOverlay.qml:149
89+#: Components/EdgeDemoOverlay.qml:151
9090msgid "Skip intro"
9191msgstr ""
9292
@@ -132,7 +132,7 @@ msgid ""
132132"phone<br><br>Tap anywhere to start"
133133msgstr ""
134134
135−#: Components/PageHeader.qml:341
135+#: Components/PageHeader.qml:345
136136msgid "Recent searches"
137137msgstr "近期搜索"
138138
@@ -152,7 +152,7 @@ msgid_plural "%1 reviews"
152152msgstr[0] ""
153153msgstr[1] ""
154154
155−#: Dash/Apps/AppPreview.qml:126
155+#: Dash/Apps/AppPreview.qml:135
156156msgid "Rate this"
157157msgstr ""
158158
@@ -172,7 +172,7 @@ msgstr ""
172172msgid "Comments:"
173173msgstr ""
174174
175−#: Greeter/Lockscreen.qml:142
175+#: Greeter/Lockscreen.qml:146
176176msgid "Emergency Call"
177177msgstr ""
178178
@@ -205,11 +205,24 @@ 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/Launcher/launcheritem.cpp:43
217+#: plugins/Unity/Launcher/launcheritem.cpp:73
218+msgid "Lock to Launcher"
219+msgstr ""
220+
221+#: plugins/Unity/Launcher/launcheritem.cpp:73
222+msgid "Unlock from Launcher"
223+msgstr ""
224+
225+#: plugins/Unity/scope.cpp:408
213226msgid "Sorry, there is nothing that matches your search."
214227msgstr "对不起,没有找到您想要的结果。"
215228
@@ -217,28 +230,7 @@ msgstr "对不起,没有找到您想要的结果。"
217230msgid "All"
218231msgstr ""
219232
220−#: Shell.qml:438
233+#: Shell.qml:441
221234#, qt-format
222235msgid "Please enter %1"
223236msgstr ""
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+22−15
@@ -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-12 16:10+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-19 05:59+0000\n"
19+"X-Generator: Launchpad (build 16831)\n"
2020
2121#: Applications/applications.js:23
2222msgid "Phone"
@@ -86,7 +86,7 @@ msgstr ""
8686msgid "YouTube"
8787msgstr ""
8888
89−#: Components/EdgeDemoOverlay.qml:149
89+#: Components/EdgeDemoOverlay.qml:151
9090msgid "Skip intro"
9191msgstr ""
9292
@@ -132,7 +132,7 @@ msgid ""
132132"phone<br><br>Tap anywhere to start"
133133msgstr ""
134134
135−#: Components/PageHeader.qml:341
135+#: Components/PageHeader.qml:345
136136msgid "Recent searches"
137137msgstr "最近搜尋"
138138
@@ -152,7 +152,7 @@ msgid_plural "%1 reviews"
152152msgstr[0] ""
153153msgstr[1] ""
154154
155−#: Dash/Apps/AppPreview.qml:126
155+#: Dash/Apps/AppPreview.qml:135
156156msgid "Rate this"
157157msgstr ""
158158
@@ -172,7 +172,7 @@ msgstr ""
172172msgid "Comments:"
173173msgstr ""
174174
175−#: Greeter/Lockscreen.qml:142
175+#: Greeter/Lockscreen.qml:146
176176msgid "Emergency Call"
177177msgstr ""
178178
@@ -205,11 +205,24 @@ 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/Launcher/launcheritem.cpp:43
217+#: plugins/Unity/Launcher/launcheritem.cpp:73
218+msgid "Lock to Launcher"
219+msgstr ""
220+
221+#: plugins/Unity/Launcher/launcheritem.cpp:73
222+msgid "Unlock from Launcher"
223+msgstr ""
224+
225+#: plugins/Unity/scope.cpp:408
213226msgid "Sorry, there is nothing that matches your search."
214227msgstr "很抱歉,找不到符合您想搜尋的結果。"
215228
@@ -217,13 +230,7 @@ msgstr "很抱歉,找不到符合您想搜尋的結果。"
217230msgid "All"
218231msgstr ""
219232
220−#: Shell.qml:438
233+#: Shell.qml:441
221234#, qt-format
222235msgid "Please enter %1"
223236msgstr ""
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−7
@@ -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
@@ -64,12 +67,6 @@ class MainWindow(object):
6467 def get_dash(self):
6568 return self.app.select_single(Dash)
6669
67− def get_dash_home_applications_grid(self):
68− return self.app.select_single(
69− "ApplicationsFilterGrid",
70− objectName="dashHomeApplicationsGrid"
71− )
72−
7370 def get_bottombar(self):
7471 return self.app.select_single("Bottombar")
7572
@@ -93,3 +90,6 @@ class MainWindow(object):
9390
9491 def get_pinentryField(self):
9592 return self.app.select_single(objectName="pinentryField")
93+
94+ def get_shell_background(self):
95+ 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/mocks/QMenuModel/CMakeLists.txt+23
@@ -9,3 +9,26 @@ add_custom_target(QMenuModelQmlFiles ALL
99 COMMAND cp ${QMLFILES} ${CMAKE_CURRENT_BINARY_DIR}
1010 DEPENDS ${QMLFILES}
1111)
12+
13+include_directories(
14+ ${Qt5Core_INCLUDE_DIRS}
15+ ${Qt5Quick_INCLUDE_DIRS}
16+)
17+
18+set(QMenuModelQml_SOURCES
19+ actionstateparser.cpp
20+ plugin.cpp
21+ unitymenumodel.cpp
22+)
23+
24+add_library(QMenuModelQml SHARED ${QMenuModelQml_SOURCES})
25+target_link_libraries(QMenuModelQml
26+ ${Qt5Core_LIBRARIES}
27+ ${Qt5Quick_LIBRARIES}
28+)
29+
30+qt5_use_modules(QMenuModelQml Core Quick)
31+
32+set_target_properties(QMenuModelQml PROPERTIES
33+ OUTPUT_NAME qmenumodel
34+ VERSION 0)
tests/mocks/QMenuModel/UnityMenuAction.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+ * Authors:
17+ * Nick Dedekind <nick.dedekind@canonical.com>
18+ */
19+
20+import QtQuick 2.0
21+import QMenuModel 0.1
22+
23+QtObject {
24+ property string name
25+ property UnityMenuModel model
26+ property int index
27+
28+ readonly property var state: undefined
29+ readonly property bool valid: false
30+}
tests/mocks/QMenuModel/actionstateparser.cppnew file+19
@@ -0,0 +1,19 @@
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+ * Authors: Nick Dedekind <nick.dedekind@canonical.com>
17+ */
18+
19+#include "actionstateparser.h"
tests/mocks/QMenuModel/actionstateparser.hnew file+35
@@ -0,0 +1,35 @@
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+ * Authors: Nick Dedekind <nick.dedekind@canonical.com>
17+ */
18+
19+#ifndef MOCK_ACTIONSTATEPARSER_H
20+#define MOCK_ACTIONSTATEPARSER_H
21+
22+#include <QObject>
23+#include <QVariant>
24+
25+typedef struct _GVariant GVariant;
26+
27+class Q_DECL_EXPORT ActionStateParser : public QObject
28+{
29+ Q_OBJECT
30+public:
31+ ActionStateParser(QObject* parent = 0):QObject(parent) {}
32+ virtual QVariant toQVariant(GVariant*) const { return QVariant(); }
33+};
34+
35+#endif // MOCK_ACTIONSTATEPARSER_H
tests/mocks/QMenuModel/plugin.cppnew file+30
@@ -0,0 +1,30 @@
1+/*
2+ * Copyright (C) 2012,2013 Canonical, Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ *
16+ * Authors: Nick Dedekind <nick.dedekind@canonical.com>
17+ */
18+
19+#include "plugin.h"
20+#include "unitymenumodel.h"
21+#include "actionstateparser.h"
22+
23+#include <QtQml>
24+
25+void QMenuModelPlugin::registerTypes(const char *uri)
26+{
27+ Q_ASSERT(uri == QLatin1String("QMenuModel"));
28+ qmlRegisterType<UnityMenuModel>(uri, 0, 1, "UnityMenuModel");
29+ qmlRegisterType<ActionStateParser>(uri, 0, 1, "ActionStateParser");
30+}
tests/mocks/QMenuModel/plugin.hnew file+34
@@ -0,0 +1,34 @@
1+/*
2+ * Copyright (C) 2012,2013 Canonical, Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ *
16+ * Authors: Nick Dedekind <nick.dedekind@canonical.com>
17+ */
18+
19+#ifndef MOCK_QMENUMODEL_PLUGIN_H
20+#define MOCK_QMENUMODEL_PLUGIN_H
21+
22+#include <QQmlEngine>
23+#include <QQmlExtensionPlugin>
24+
25+class QMenuModelPlugin : public QQmlExtensionPlugin
26+{
27+ Q_OBJECT
28+ Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QQmlExtensionInterface")
29+
30+public:
31+ void registerTypes(const char *uri);
32+};
33+
34+#endif
tests/mocks/QMenuModel/qmldir+3−1
@@ -1,3 +1,5 @@
11module QMenuModel
2+plugin qmenumodel
3+
24QDBusActionGroup 0.1 QDBusActionGroup.qml
3−UnityMenuModel 0.1 UnityMenuModel.qml
5+UnityMenuAction 0.1 UnityMenuAction.qml
tests/mocks/QMenuModel/unitymenumodel.cppnew file+239
@@ -0,0 +1,239 @@
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+ * Authors: Nick Dedekind <nick.dedekind@canonical.com>
17+ */
18+
19+#include "unitymenumodel.h"
20+#include <QDebug>
21+
22+enum MenuRoles {
23+ LabelRole = Qt::DisplayRole + 1,
24+ SensitiveRole,
25+ IsSeparatorRole,
26+ IconRole,
27+ TypeRole,
28+ ExtendedAttributesRole,
29+ ActionRole,
30+ ActionStateRole,
31+ IsCheckRole,
32+ IsRadioRole,
33+ IsToggledRole
34+};
35+
36+UnityMenuModel::UnityMenuModel(QObject *parent)
37+: QAbstractListModel(parent)
38+{
39+}
40+
41+QVariant UnityMenuModel::modelData() const
42+{
43+ return m_modelData;
44+}
45+
46+void UnityMenuModel::setModelData(const QVariant& data)
47+{
48+ beginResetModel();
49+
50+ m_modelData.clear();
51+ m_modelData = data.toList();
52+
53+ endResetModel();
54+}
55+
56+
57+void UnityMenuModel::insertRow(int row, const QVariant& data)
58+{
59+ row = qMin(row, rowCount());
60+
61+ beginInsertRows(QModelIndex(), row, row);
62+
63+ m_modelData.insert(row, data);
64+
65+ endInsertRows();
66+}
67+
68+void UnityMenuModel::appendRow(const QVariant& data)
69+{
70+ insertRow(rowCount(), data);
71+}
72+
73+void UnityMenuModel::removeRow(int row)
74+{
75+ if (row < 0 || rowCount() <= row) {
76+ return;
77+ }
78+
79+ beginRemoveRows(QModelIndex(), row, row);
80+
81+ m_modelData.removeAt(row);
82+
83+ endRemoveRows();
84+}
85+
86+UnityMenuModel::~UnityMenuModel()
87+{
88+}
89+
90+QByteArray UnityMenuModel::busName() const
91+{
92+ return m_busName;
93+}
94+
95+void UnityMenuModel::setBusName(const QByteArray &busName)
96+{
97+ this->m_busName = busName;
98+}
99+
100+QVariantMap UnityMenuModel::actions() const
101+{
102+ return m_actions;
103+}
104+
105+void UnityMenuModel::setActions(const QVariantMap &actions)
106+{
107+ this->m_actions = actions;
108+}
109+
110+QByteArray UnityMenuModel::menuObjectPath() const
111+{
112+ return m_menuObjectPath;
113+}
114+
115+void UnityMenuModel::setMenuObjectPath(const QByteArray &path)
116+{
117+ this->m_menuObjectPath = path;
118+}
119+
120+ActionStateParser* UnityMenuModel::actionStateParser() const
121+{
122+ return NULL;
123+}
124+
125+void UnityMenuModel::setActionStateParser(ActionStateParser*)
126+{
127+}
128+
129+int UnityMenuModel::rowCount(const QModelIndex&) const
130+{
131+ return m_modelData.count();
132+}
133+
134+int UnityMenuModel::columnCount(const QModelIndex&) const
135+{
136+ return 1;
137+}
138+
139+QVariant UnityMenuModel::data(const QModelIndex &index, int role) const
140+{
141+ return rowData(index.row())[roleNames()[role]];
142+}
143+
144+QVariantMap UnityMenuModel::rowData(int row) const
145+{
146+ return m_modelData[row].toMap()["rowData"].toMap();
147+}
148+
149+QVariant UnityMenuModel::subMenuData(int row) const
150+{
151+ return m_modelData[row].toMap()["submenu"];
152+}
153+
154+QModelIndex UnityMenuModel::index(int row, int column, const QModelIndex&) const
155+{
156+ return createIndex(row, column);
157+}
158+
159+QModelIndex UnityMenuModel::parent(const QModelIndex &) const
160+{
161+ return QModelIndex();
162+}
163+
164+QHash<int, QByteArray> UnityMenuModel::roleNames() const
165+{
166+ QHash<int, QByteArray> names;
167+
168+ names[LabelRole] = "label";
169+ names[SensitiveRole] = "sensitive";
170+ names[IsSeparatorRole] = "isSeparator";
171+ names[IconRole] = "icon";
172+ names[TypeRole] = "type";
173+ names[ExtendedAttributesRole] = "ext";
174+ names[ActionRole] = "action";
175+ names[ActionStateRole] = "actionState";
176+ names[IsCheckRole] = "isCheck";
177+ names[IsRadioRole] = "isRadio";
178+ names[IsToggledRole] = "isToggled";
179+
180+ return names;
181+}
182+
183+QObject * UnityMenuModel::submenu(int position, QQmlComponent*)
184+{
185+ if (position < 0 || m_modelData.count() < position) {
186+ return NULL;
187+ }
188+
189+ while (submenus.count() <= position) {
190+ submenus.append(NULL);
191+ }
192+
193+ QVariant submenuData = subMenuData(position);
194+ if (submenuData.type() == (int)QMetaType::QVariantList) {
195+ UnityMenuModel*& model = submenus[position];
196+ if (!model) {
197+ model = new UnityMenuModel(this);
198+ }
199+ if (model->modelData() != submenuData) {
200+ model->setModelData(submenuData);
201+ }
202+ return model;
203+ }
204+
205+ return NULL;
206+}
207+
208+bool UnityMenuModel::loadExtendedAttributes(int, const QVariantMap &)
209+{
210+ return false;
211+}
212+
213+QVariant UnityMenuModel::get(int row, const QByteArray &role)
214+{
215+ static QHash<QByteArray, int> roles;
216+ if (roles.isEmpty()) {
217+ QHash<int, QByteArray> names = roleNames();
218+ Q_FOREACH (int role, names.keys())
219+ roles.insert(names[role], role);
220+ }
221+
222+ return this->data(this->index(row, 0), roles[role]);
223+}
224+
225+void UnityMenuModel::activate(int, const QVariant&)
226+{
227+}
228+
229+void UnityMenuModel::changeState(int, const QVariant&)
230+{
231+}
232+
233+void UnityMenuModel::registerAction(UnityMenuAction*)
234+{
235+}
236+
237+void UnityMenuModel::unregisterAction(UnityMenuAction*)
238+{
239+}
tests/mocks/QMenuModel/unitymenumodel.hnew file+96
@@ -0,0 +1,96 @@
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+ * Authors: Nick Dedekind <nick.dedekind@canonical.com>
17+ */
18+
19+#ifndef MOCK_UNITYMENUMODEL_H
20+#define MOCK_UNITYMENUMODEL_H
21+
22+#include <QAbstractListModel>
23+class QQmlComponent;
24+class UnityMenuAction;
25+class ActionStateParser;
26+
27+class Q_DECL_EXPORT UnityMenuModel : public QAbstractListModel
28+{
29+ Q_OBJECT
30+ Q_PROPERTY(QVariant modelData READ modelData WRITE setModelData NOTIFY modelDataChanged)
31+ Q_PROPERTY(QByteArray busName READ busName WRITE setBusName NOTIFY busNameChanged)
32+ Q_PROPERTY(QVariantMap actions READ actions WRITE setActions NOTIFY actionsChanged)
33+ Q_PROPERTY(QByteArray menuObjectPath READ menuObjectPath WRITE setMenuObjectPath NOTIFY menuObjectPathChanged)
34+ Q_PROPERTY(ActionStateParser* actionStateParser READ actionStateParser WRITE setActionStateParser NOTIFY actionStateParserChanged)
35+
36+public:
37+ UnityMenuModel(QObject *parent = NULL);
38+ virtual ~UnityMenuModel();
39+
40+ Q_INVOKABLE void insertRow(int row, const QVariant& data);
41+ Q_INVOKABLE void appendRow(const QVariant& data);
42+ Q_INVOKABLE void removeRow(int row);
43+
44+ QVariant modelData() const;
45+ void setModelData(const QVariant& data);
46+
47+ QByteArray busName() const;
48+ void setBusName(const QByteArray &busName);
49+
50+ QVariantMap actions() const;
51+ void setActions(const QVariantMap &actions);
52+
53+ QByteArray menuObjectPath() const;
54+ void setMenuObjectPath(const QByteArray &path);
55+
56+ ActionStateParser* actionStateParser() const;
57+ void setActionStateParser(ActionStateParser* actionStateParser);
58+
59+ int rowCount(const QModelIndex &parent = QModelIndex()) const;
60+ int columnCount(const QModelIndex &parent = QModelIndex()) const;
61+ QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const;
62+ QModelIndex index(int row, int column = 0, const QModelIndex &parent = QModelIndex()) const;
63+ QModelIndex parent(const QModelIndex &index) const;
64+ QHash<int, QByteArray> roleNames() const;
65+
66+ Q_INVOKABLE QObject * submenu(int position, QQmlComponent* actionStateParser = NULL);
67+ Q_INVOKABLE bool loadExtendedAttributes(int position, const QVariantMap &schema);
68+ Q_INVOKABLE QVariant get(int row, const QByteArray &role);
69+
70+ Q_INVOKABLE void activate(int index, const QVariant& parameter = QVariant());
71+ Q_INVOKABLE void changeState(int index, const QVariant& parameter);
72+
73+ void registerAction(UnityMenuAction* action);
74+ void unregisterAction(UnityMenuAction* action);
75+
76+Q_SIGNALS:
77+ void busNameChanged();
78+ void actionsChanged();
79+ void menuObjectPathChanged();
80+ void actionStateParserChanged();
81+ void modelDataChanged();
82+
83+private:
84+ QVariantMap rowData(int row) const;
85+ QVariant subMenuData(int row) const;
86+
87+ class Row;
88+ QVariantList m_modelData;
89+ QList<UnityMenuModel*> submenus;
90+
91+ QByteArray m_busName;
92+ QVariantMap m_actions;
93+ QByteArray m_menuObjectPath;
94+};
95+
96+#endif // MOCK_UNITYMENUMODEL_H
tests/mocks/Unity/Indicators/IndicatorBase.qmlnew file+37
@@ -0,0 +1,37 @@
1+/*
2+ * Copyright 2013 Canonical Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU Lesser General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU Lesser General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU Lesser General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ *
16+ * Authors:
17+ * Nick Dedekind <nick.dedekind@canonical.com>
18+ */
19+
20+import QtQuick 2.0
21+import QMenuModel 0.1
22+
23+Item {
24+ id: indicatorBase
25+
26+ //const
27+ property string busName
28+ property string actionsObjectPath
29+ property string rootMenuType: "com.canonical.indicator.root"
30+ property string deviceMenuObjectPath
31+
32+ property var menuModel: UnityMenuModel {}
33+
34+ property RootActionState rootActionState: RootActionState {
35+ onUpdated: indicatorBase.rootActionStateChanged()
36+ }
37+}
tests/mocks/Unity/Indicators/IndicatorWidget.qmlnew file+28
@@ -0,0 +1,28 @@
1+/*
2+ * Copyright 2013 Canonical Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU Lesser General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU Lesser General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU Lesser General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ *
16+ * Authors:
17+ * Nick Dedekind <nick.dedekind@canonical.com>
18+ */
19+
20+import QtQuick 2.0
21+import Unity.Indicators 0.1 as Indicators
22+
23+IndicatorBase {
24+ id: indicatorWidget
25+
26+ enabled: false
27+ property int iconSize: height
28+}
tests/mocks/Unity/Indicators/RootActionState.qml+17−9
@@ -20,14 +20,22 @@
2020import QtQuick 2.0
2121
2222QtObject {
23− property var menu
24− property bool valid: false
25− property string title
26− property string leftLabel
27− property string rightLabel
28− property var icons
29− property string accessibleName
30− property bool visible: true
23+ property var menu
24+ property bool valid: false
25+ property string title
26+ property string leftLabel
27+ property string rightLabel
28+ property var icons
29+ property string accessibleName
30+ property bool visible: true
3131
32− signal updated
32+ signal updated
33+
34+ onValidChanged: updated()
35+ onTitleChanged: updated()
36+ onLeftLabelChanged: updated()
37+ onRightLabelChanged: updated()
38+ onIconsChanged: updated()
39+ onAccessibleNameChanged: updated()
40+ onVisibleChanged: updated()
3341}
tests/mocks/Unity/Indicators/qmldir+2
@@ -2,6 +2,8 @@ module Unity.Indicators
22plugin IndicatorsFakeQml
33
44CachedUnityMenuModel 0.1 CachedUnityMenuModel.qml
5+IndicatorBase 0.1 IndicatorBase.qml
6+IndicatorWidget 0.1 IndicatorWidget.qml
57IndicatorsModel 0.1 IndicatorsModel.qml
68FakeMenuPage 0.1 FakeMenuPage.qml
79RootActionState 0.1 RootActionState.qml
tests/mocks/Unity/fake_scope.cpp+3−20
@@ -25,25 +25,8 @@ static DeeModel* create_results_model(unsigned category_count, unsigned result_c
2525
2626// TODO: Implement remaining pieces
2727
28−Scope::Scope(QObject* parent)
29− : QObject(parent)
30− , m_visible(false)
31− , m_searching(false)
32− , m_isActive(false)
33− , m_categories(new Categories(this))
34− , m_results(new DeeListModel(this))
28+Scope::Scope(QObject* parent) : Scope(QString(), QString(), false, parent)
3529{
36− DeeModel* results_model = create_results_model(4, 30);
37− m_categories->setResultModel(results_model);
38− m_categories->setModel(create_categories_model(4));
39− m_results->setModel(results_model);
40−
41− m_timer.setInterval(1000);
42− m_timer.setSingleShot(true);
43− connect(&m_timer, &QTimer::timeout, [this]() {
44− Preview *p = new Preview(this);
45− Q_EMIT previewReady(p);
46− });
4730}
4831
4932Scope::Scope(QString const& id, QString const& name, bool visible, QObject* parent)
@@ -56,9 +39,9 @@ Scope::Scope(QString const& id, QString const& name, bool visible, QObject* pare
5639 , m_categories(new Categories(this))
5740 , m_results(new DeeListModel(this))
5841{
59− DeeModel* results_model = create_results_model(4, 30);
42+ DeeModel* results_model = create_results_model(20, 300);
6043 m_categories->setResultModel(results_model);
61− m_categories->setModel(create_categories_model(4));
44+ m_categories->setModel(create_categories_model(20));
6245 m_results->setModel(results_model);
6346
6447 m_timer.setInterval(1000);
tests/plugins/ListViewWithPageHeader/CMakeLists.txt+7
@@ -1,3 +1,6 @@
1+# add_qml_test macro
2+include(QmlTest)
3+
14# There's no cmake var for v8 include path :-/
25# so create one
36LIST(GET Qt5Core_INCLUDE_DIRS 0 QtCoreDir0)
@@ -37,6 +40,10 @@ qt5_use_modules(listviewwithpageheadertestsectionexternalmodelExec Test Core Qml
3740target_link_libraries(listviewwithpageheadertestsectionexternalmodelExec ${Qt5Gui_LIBRARIES} ${Qt5Quick_LIBRARIES})
3841add_custom_target(testlistviewwithpageheadersectionexternalmodel ${CMAKE_CURRENT_BINARY_DIR}/listviewwithpageheadertestsectionexternalmodelExec -o ${CMAKE_BINARY_DIR}/testlistviewwithpageheadersectionexternalmodel.xml,xunitxml -o -,txt)
3942
43+set(qmltest_DEFAULT_NO_ADD_TEST TRUE)
44+add_qml_test(. listviewwithpageheaderqml IMPORT_PATHS ${CMAKE_BINARY_DIR}/plugins)
45+
4046add_dependencies(qmluitests testlistviewwithpageheader)
4147add_dependencies(qmluitests testlistviewwithpageheadersection)
4248add_dependencies(qmluitests testlistviewwithpageheadersectionexternalmodel)
49+add_dependencies(qmluitests testlistviewwithpageheaderqml)
tests/plugins/ListViewWithPageHeader/listviewwithpageheadertest.cpp+20
@@ -1724,6 +1724,9 @@ private Q_SLOTS:
17241724
17251725 void testMaximizeVisibleAreaMoveUpAndShowHeader()
17261726 {
1727+#if (QT_VERSION < QT_VERSION_CHECK(5, 1, 0))
1728+ QSKIP("This test is extremely unstable in 5.0.x");
1729+#endif
17271730 model->setProperty(0, "size", 800);
17281731 verifyItem(0, 50., 800., false);
17291732
@@ -1824,6 +1827,23 @@ private Q_SLOTS:
18241827 lvwph->positionAtBeginning();
18251828 }
18261829
1830+ void testHeaderPositionBug1240118()
1831+ {
1832+ scrollToBottom();
1833+ lvwph->showHeader();
1834+ QTRY_VERIFY(!lvwph->m_contentYAnimation->isRunning());
1835+ QTest::qWait(100); // Make sure stuff is stable
1836+ QMetaObject::invokeMethod(model, "insertItem", Q_ARG(QVariant, 0), Q_ARG(QVariant, 100));
1837+ model->setProperty(3, "size", 10);
1838+ model->setProperty(4, "size", 10);
1839+ model->setProperty(5, "size", 10);
1840+ model->setProperty(6, "size", 10);
1841+#if (QT_VERSION > QT_VERSION_CHECK(5, 0, 3))
1842+ QTRY_COMPARE(lvwph->m_minYExtent, 210.);
1843+#endif
1844+ QTRY_COMPARE(lvwph->m_headerItem->y(), -lvwph->m_minYExtent);
1845+ }
1846+
18271847private:
18281848 QQuickView *view;
18291849 ListViewWithPageHeader *lvwph;
tests/plugins/ListViewWithPageHeader/tst_listviewwithpageheaderqml.qmlnew file+138
@@ -0,0 +1,138 @@
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 QtTest 1.0
19+import ListViewWithPageHeader 0.1
20+
21+Rectangle {
22+ width: 300
23+ height: 542
24+ color: "lightblue"
25+
26+ ListModel {
27+ id: model
28+
29+ function insertItem(index, size, type) {
30+ insert(index, { size: size, type: type });
31+ }
32+
33+ function removeItems(index, count) {
34+ remove(index, count);
35+ }
36+
37+ function moveItems(indexFrom, indexTo, count) {
38+ move(indexFrom, indexTo, count);
39+ }
40+
41+ ListElement { type: "Agressive"; size: 150 }
42+ ListElement { type: "Regular"; size: 200 }
43+ ListElement { type: "Mild"; size: 350 }
44+ ListElement { type: "Bold"; size: 350 }
45+ ListElement { type: "Bold"; size: 350 }
46+ ListElement { type: "Lazy"; size: 350 }
47+ }
48+
49+ ListViewWithPageHeader {
50+ id: listView
51+ width: parent.width
52+ anchors.top: parent.top
53+ anchors.bottom: parent.bottom
54+ model: model
55+ delegate: Rectangle {
56+ property bool timerDone: false
57+ width: parent.width - 20
58+ x: 10
59+ color: index % 2 == 0 ? "red" : "blue"
60+ height: size
61+ Text {
62+ text: index
63+ }
64+ }
65+
66+ pageHeader: Rectangle {
67+ color: "transparent"
68+ width: parent.width
69+ height: 50
70+ implicitHeight: 50
71+ Text {
72+ anchors.fill: parent
73+ text: "APPS"
74+ font.pixelSize: 40
75+ }
76+ }
77+
78+ sectionProperty: "type"
79+
80+ property int sectionHeaderHeight: 40
81+ sectionDelegate: Component {
82+ id: sectionHeaderComponent
83+ Rectangle {
84+ color: "green"
85+ height: listView.sectionHeaderHeight
86+ Text { text: section; font.pixelSize: 34 }
87+ anchors { left: parent.left; right: parent.right }
88+ }
89+ }
90+ }
91+
92+ Component {
93+ id: otherSectionHeaderComponent
94+ Rectangle {
95+ color: "green"
96+ height: 50
97+ Text { text: section; font.pixelSize: 34 }
98+ anchors { left: parent.left; right: parent.right }
99+ }
100+ }
101+
102+ SignalSpy {
103+ id: stickyHeaderHeigthSpy
104+ target: listView
105+ signalName: "stickyHeaderHeightChanged"
106+ }
107+
108+ TestCase {
109+ name: "ListViewWithPageHeaderTest"
110+ when: windowShown
111+
112+ function test_stickyHeaderHeightNewHeader() {
113+ stickyHeaderHeigthSpy.clear();
114+ compare(listView.stickyHeaderHeight, 40);
115+
116+ listView.sectionDelegate = otherSectionHeaderComponent;
117+ compare(listView.stickyHeaderHeight, 50);
118+ compare(stickyHeaderHeigthSpy.count, 1);
119+
120+ listView.sectionDelegate = sectionHeaderComponent;
121+ compare(listView.stickyHeaderHeight, 40);
122+ compare(stickyHeaderHeigthSpy.count, 2);
123+ }
124+
125+ function test_stickyHeaderHeightGrowingHeader() {
126+ stickyHeaderHeigthSpy.clear();
127+
128+ compare(listView.stickyHeaderHeight, 40);
129+
130+ listView.sectionHeaderHeight = 60;
131+ compare(listView.stickyHeaderHeight, 60);
132+ compare(stickyHeaderHeigthSpy.count, 1);
133+
134+ // Restore height for other tests
135+ listView.sectionHeaderHeight = 40;
136+ }
137+ }
138+}
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/plugins/Unity/Indicators/CMakeLists.txt+36−27
@@ -1,34 +1,43 @@
1+pkg_check_modules(GLIB REQUIRED glib-2.0>=2.32)
2+pkg_check_modules(GIO REQUIRED gio-2.0>=2.32)
13pkg_check_modules(QMENUMODEL REQUIRED qmenumodel)
24
5+set(INDICATORS_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../../../../plugins/Unity/Indicators)
6+set(TEST_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../../..)
7+
38include_directories(
49 ${CMAKE_CURRENT_BINARY_DIR}
5− ${CMAKE_CURRENT_SOURCE_DIR}/../../../../plugins/Unity/Indicators
6− ${QMENUMODEL_INCLUDE_DIRS}
10+ ${INDICATORS_DIR}
11+ ${TEST_DIR}/mocks/QMenuModel
12+ ${GLIB_INCLUDE_DIRS}
13+ ${GIO_INCLUDE_DIRS}
714 )
815
9−macro(run_tests)
10− set(_test_list "")
11− foreach(_test ${ARGN})
12− set(testCommand ${CMAKE_CURRENT_BINARY_DIR}/${_test}Exec
13− -o ${CMAKE_BINARY_DIR}/${_test}.xml,xunitxml
14− -o -,txt)
15− add_test(NAME ${_test} COMMAND ${testCommand})
16− add_custom_target(${_test} ${testCommand})
17− add_executable(${_test}Exec ${_test}.cpp
18− )
19− qt5_use_modules(${_test}Exec Test Core Qml)
20− target_link_libraries(${_test}Exec
21− IndicatorsQml
22− ${QMENUMODEL_LDFLAGS}
23− )
24− set(_test_list "${_test_list};${_test}")
25− endforeach()
26−endmacro(run_tests)
16+macro(indicator_test TEST)
17+ set(multi_value_keywords ADDITIONAL_CPPS ADDITIONAL_LIBS)
18+ cmake_parse_arguments(test "" "" "${multi_value_keywords}" ${ARGN})
2719
28−run_tests(
29− indicatorsmanagertest
30− indicatorsmodeltest
31− menucontentactivatortest
32− rootactionstatetest
33− timeformattertest
34− )
20+ set(testCommand ${CMAKE_CURRENT_BINARY_DIR}/${TEST}Exec
21+ -o ${CMAKE_BINARY_DIR}/${TEST}.xml,xunitxml
22+ -o -,txt)
23+ add_test(NAME ${TEST} COMMAND ${testCommand})
24+ add_custom_target(${TEST} ${testCommand})
25+ add_executable(${TEST}Exec
26+ ${TEST}.cpp
27+ ${test_ADDITIONAL_CPPS}
28+ )
29+ qt5_use_modules(${TEST}Exec Test Core Qml)
30+ target_link_libraries(${TEST}Exec
31+ ${test_ADDITIONAL_LIBS}
32+ ${GLIB_LIBRARIES}
33+ ${GIO_LIBRARIES}
34+ ${QMENUMODEL_LDFLAGS}
35+ )
36+endmacro(indicator_test)
37+
38+indicator_test(indicatorsmanagertest ADDITIONAL_LIBS IndicatorsQml)
39+indicator_test(indicatorsmodeltest ADDITIONAL_LIBS IndicatorsQml)
40+indicator_test(menucontentactivatortest ADDITIONAL_CPPS ${INDICATORS_DIR}/menucontentactivator.cpp)
41+indicator_test(unitymenumodelstacktest ADDITIONAL_CPPS ${TEST_DIR}/mocks/QMenuModel/unitymenumodel.cpp ${INDICATORS_DIR}/unitymenumodelstack.cpp)
42+indicator_test(rootactionstatetest ADDITIONAL_LIBS IndicatorsQml)
43+indicator_test(timeformattertest ADDITIONAL_LIBS IndicatorsQml)
tests/plugins/Unity/Indicators/unitymenumodelstacktest.cppnew file+206
@@ -0,0 +1,206 @@
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+ * Authors:
17+ * Nick Dedekind <nick.dedekind@canonical.com>
18+ */
19+
20+#include "indicatorsmanager.h"
21+#include "paths.h"
22+#include "unitymenumodelstack.h"
23+
24+#include <QtTest>
25+#include <QDebug>
26+#include <unitymenumodel.h>
27+
28+class UnityMenuModelStackTest : public QObject
29+{
30+ Q_OBJECT
31+private Q_SLOTS:
32+
33+ void init()
34+ {
35+ m_model = new UnityMenuModel();
36+ m_headChanged = false;
37+ m_tailChanged = false;
38+ }
39+
40+ void cleanup()
41+ {
42+ delete m_model;
43+ m_model = NULL;
44+ }
45+
46+ void testHeadOnSetHead()
47+ {
48+ UnityMenuModelStack stack;
49+ connect(&stack, SIGNAL(headChanged(UnityMenuModel*)), this, SLOT(onHeadChanged()));
50+ stack.setHead(m_model);
51+
52+ QCOMPARE(stack.head(), m_model);
53+ QCOMPARE(m_headChanged, true);
54+ }
55+
56+ void testTailOnSetHead()
57+ {
58+ UnityMenuModelStack stack;
59+ connect(&stack, SIGNAL(tailChanged(UnityMenuModel*)), this, SLOT(onTailChanged()));
60+ stack.setHead(m_model);
61+
62+ QCOMPARE(stack.tail(), m_model);
63+ QCOMPARE(m_tailChanged, true);
64+ }
65+
66+ void testPushPop_data() {
67+ QTest::addColumn<int>("menuDepth");
68+ QTest::addColumn<int>("subMenuCount");
69+ QTest::addColumn<int>("subMenuIndex");
70+
71+ QTest::newRow("depth=0") << 0 << 1 << 0;
72+ QTest::newRow("depth=1") << 1 << 1 << 0;
73+ QTest::newRow("depth=8") << 8 << 2 << 1;
74+ }
75+
76+ void testPushPop()
77+ {
78+ QFETCH(int, menuDepth);
79+ QFETCH(int, subMenuCount);
80+ QFETCH(int, subMenuIndex);
81+
82+ m_model->setModelData(recuseAddMenu(subMenuCount, menuDepth));
83+
84+ UnityMenuModelStack stack;
85+ connect(&stack, SIGNAL(tailChanged(UnityMenuModel*)), this, SLOT(onTailChanged()));
86+
87+ QList<UnityMenuModel*> models;
88+
89+ int count = 0;
90+ auto foreachChild = [&](UnityMenuModel* child, int childIndex) {
91+ stack.push(child, childIndex);
92+ QCOMPARE(stack.count(), count+1);
93+
94+ count++;
95+ models << child;
96+ };
97+ recuseSubmenus(m_model, subMenuIndex, foreachChild);
98+
99+ QCOMPARE(stack.count(), models.count());
100+ QCOMPARE(stack.count(), menuDepth+1);
101+ while(stack.count() > 0) {
102+ m_tailChanged = false;
103+
104+ QCOMPARE(stack.pop(), models.takeLast());
105+
106+ QCOMPARE(m_tailChanged, true);
107+ if (stack.count()) {
108+ QCOMPARE(stack.tail(), models.last());
109+ }
110+ }
111+ QCOMPARE(m_tailChanged, true);
112+ }
113+
114+ void testPopOnRemove_data() {
115+ QTest::addColumn<int>("menuDepth");
116+ QTest::addColumn<int>("subMenuCount");
117+ QTest::addColumn<int>("subMenuIndex");
118+ QTest::addColumn<int>("removeIndex");
119+ QTest::addColumn<int>("resultCount");
120+
121+ QTest::newRow("removeIndexBefore") << 4 << 2 << 1 << 0 << 5;
122+ QTest::newRow("removeCurrentIndex") << 4 << 2 << 0 << 0 << 1;
123+ QTest::newRow("removeIndexAfter") << 4 << 2 << 0 << 1 << 5;
124+ }
125+
126+ void testPopOnRemove()
127+ {
128+ QFETCH(int, menuDepth);
129+ QFETCH(int, subMenuCount);
130+ QFETCH(int, subMenuIndex);
131+ QFETCH(int, removeIndex);
132+ QFETCH(int, resultCount);
133+
134+ m_model->setModelData(recuseAddMenu(subMenuCount, menuDepth));
135+
136+ UnityMenuModelStack stack;
137+
138+ auto foreachChild = [&](UnityMenuModel* child, int childIndex) {
139+ stack.push(child, childIndex);
140+ };
141+ recuseSubmenus(m_model, subMenuIndex, foreachChild);
142+
143+ QCOMPARE(stack.count(), menuDepth+1);
144+
145+ m_model->removeRow(removeIndex);
146+
147+ waitFor([&stack, resultCount]() { return stack.count() == resultCount; }, 1000);
148+ QCOMPARE(stack.count(), resultCount);
149+ }
150+
151+private:
152+ bool waitFor(std::function<bool()> functor, int ms) {
153+
154+ QElapsedTimer timer;
155+ timer.start();
156+ while(!functor() && timer.elapsed() < ms) { QTest::qWait(10); }
157+ return functor();
158+ }
159+
160+ QVariant recuseAddMenu(int subMenuCount, int depth_remaining)
161+ {
162+ QVariantList rows;
163+
164+ for (int i = 0; i < subMenuCount; i ++) {
165+ QVariantMap row;
166+ QVariantMap rowData;
167+
168+ if (depth_remaining > 0) {
169+ row["submenu"] = recuseAddMenu(subMenuCount, depth_remaining-1);
170+ }
171+
172+ row["rowData"] = rowData;
173+
174+ rows << row;
175+ }
176+
177+ return rows;
178+ }
179+
180+ void recuseSubmenus(UnityMenuModel* model, int childIndex, std::function<void(UnityMenuModel*, int)> func) {
181+ UnityMenuModel* parent = model;
182+ UnityMenuModel* child = model;
183+
184+ while(child) {
185+ if (func) {
186+ func(child, childIndex);
187+ }
188+
189+ parent = child;
190+ child = qobject_cast<UnityMenuModel*>(parent->submenu(childIndex));
191+ }
192+
193+ }
194+
195+private Q_SLOTS:
196+ void onHeadChanged() { m_headChanged = true; }
197+ void onTailChanged() { m_tailChanged = true; }
198+
199+public:
200+ UnityMenuModel* m_model;
201+ bool m_headChanged;
202+ bool m_tailChanged;
203+};
204+
205+QTEST_GUILESS_MAIN(UnityMenuModelStackTest)
206+#include "unitymenumodelstacktest.moc"
tests/plugins/Unity/resultstest.cpp+3−3
@@ -143,7 +143,7 @@ void ResultsTest::testSpecialIcons_data()
143143 g_variant_builder_init(&builder, G_VARIANT_TYPE_VARDICT);
144144 g_variant_builder_add(&builder, "{sv}", "content", g_variant_builder_end(&inner_builder));
145145
146− QTest::newRow("simple") << "file:///foo.mp3" << GVariantWrapper(g_variant_builder_end(&builder)) << "image://albumart/U2/War";
146+ QTest::newRow("simple") << "file:///foo.mp3" << GVariantWrapper(g_variant_builder_end(&builder)) << "image://albumart/artist=U2&album=War";
147147
148148 g_variant_builder_init(&inner_builder, G_VARIANT_TYPE_VARDICT);
149149 g_variant_builder_add(&inner_builder, "{sv}", "artist", g_variant_new_string("U2"));
@@ -153,7 +153,7 @@ void ResultsTest::testSpecialIcons_data()
153153 g_variant_builder_init(&builder, G_VARIANT_TYPE_VARDICT);
154154 g_variant_builder_add(&builder, "{sv}", "content", inner);
155155
156− QTest::newRow("with-slash") << "file:///foo.mp3" << GVariantWrapper(g_variant_builder_end(&builder)) << "image://albumart/U2/War%2FJoshua%20tree";
156+ QTest::newRow("with-slash") << "file:///foo.mp3" << GVariantWrapper(g_variant_builder_end(&builder)) << "image://albumart/artist=U2&album=War/Joshua tree";
157157
158158 g_variant_builder_init(&inner_builder, G_VARIANT_TYPE_VARDICT);
159159 g_variant_builder_add(&inner_builder, "{sv}", "artist", g_variant_new_string("U2"));
@@ -166,7 +166,7 @@ void ResultsTest::testSpecialIcons_data()
166166 g_variant_builder_init(&builder, G_VARIANT_TYPE_VARDICT);
167167 g_variant_builder_add(&builder, "{sv}", "content", g_variant_builder_end(&inner_builder));
168168
169− QTest::newRow("nested") << "file:///foo.mp3" << GVariantWrapper(g_variant_builder_end(&builder)) << "image://albumart/U2/War";
169+ QTest::newRow("nested") << "file:///foo.mp3" << GVariantWrapper(g_variant_builder_end(&builder)) << "image://albumart/artist=U2&album=War";
170170}
171171
172172void ResultsTest::testSpecialIcons()
tests/qmltests/CMakeLists.txt+5−4
@@ -13,11 +13,9 @@ set(qmltest_DEFAULT_NO_ADD_TEST FALSE)
1313set(qmltest_DEFAULT_PROPERTIES ENVIRONMENT "QT_QPA_PLATFORM=minimal")
1414add_qml_test(Components AnimationControllerWithSignals)
1515add_qml_test(Components Carousel)
16−add_qml_test(Components MathLocal)
1716add_qml_test(Components OpenEffect)
1817add_qml_test(Components RatingStars)
1918add_qml_test(Components TimeLocal)
20−add_qml_test(Greeter Clock IMPORT_PATHS ${qmltest_DEFAULT_IMPORT_PATHS} ${CMAKE_BINARY_DIR}/plugins)
2119add_qml_test(Panel IndicatorItem)
2220add_qml_test(utils/Unity/Test UnityTest)
2321
@@ -47,7 +45,6 @@ add_qml_test(Dash DashContent IMPORT_PATHS ${CMAKE_BINARY_DIR}/plugins ${qmltest
4745add_qml_test(Dash DashPreview)
4846add_qml_test(Dash GenericPreview)
4947add_qml_test(Dash GenericScopeView IMPORT_PATHS ${CMAKE_BINARY_DIR}/plugins ${qmltest_DEFAULT_IMPORT_PATHS})
50−add_qml_test(Dash ScopeView IMPORT_PATHS ${CMAKE_BINARY_DIR}/plugins ${qmltest_DEFAULT_IMPORT_PATHS})
5148add_qml_test(Dash FilterGrids IMPORT_PATHS ${qmltest_DEFAULT_IMPORT_PATHS} ${CMAKE_BINARY_DIR}/plugins ${CMAKE_CURRENT_SOURCE_DIR}/plugins
5249 ${CMAKE_BINARY_DIR}/tests/mocks)
5350add_qml_test(Dash/Apps RunningApplicationsGrid IMPORT_PATHS ${qmltest_DEFAULT_IMPORT_PATHS} ${CMAKE_BINARY_DIR}/tests/mocks)
@@ -61,15 +58,19 @@ add_qml_test(Greeter Phone IMPORT_PATHS ${CMAKE_BINARY_DIR}/plugins ${qmltest_DE
6158 ENVIRONMENT "LD_LIBRARY_PATH=${CMAKE_BINARY_DIR}/tests/mocks/libusermetrics:${CMAKE_BINARY_DIR}/tests/mocks/LightDM/single")
6259add_qml_test(Greeter Infographics IMPORT_PATHS ${CMAKE_BINARY_DIR}/plugins ${qmltest_DEFAULT_IMPORT_PATHS}
6360 ENVIRONMENT "LD_LIBRARY_PATH=${CMAKE_BINARY_DIR}/tests/mocks/libusermetrics:${CMAKE_BINARY_DIR}/tests/mocks/LightDM/full")
61+add_qml_test(Greeter Clock IMPORT_PATHS ${CMAKE_BINARY_DIR}/plugins ${qmltest_DEFAULT_IMPORT_PATHS}
62+ ENVIRONMENT "LD_LIBRARY_PATH=${CMAKE_BINARY_DIR}/tests/mocks/QMenuModel")
6463add_qml_test(Hud Hud)
6564add_qml_test(Hud Result)
6665add_qml_test(Launcher Launcher IMPORT_PATHS ${CMAKE_BINARY_DIR}/plugins ${qmltest_DEFAULT_IMPORT_PATHS})
67−add_qml_test(Notifications Notifications IMPORT_PATHS ${CMAKE_BINARY_DIR}/plugins ${qmltest_DEFAULT_IMPORT_PATHS} ${CMAKE_SOURCE_DIR}/tests/mocks)
66+add_qml_test(Notifications Notifications IMPORT_PATHS ${qmltest_DEFAULT_IMPORT_PATHS} ${CMAKE_BINARY_DIR}/plugins)
6867add_qml_test(Panel IndicatorRow)
6968add_qml_test(Panel Indicators IMPORT_PATHS ${CMAKE_BINARY_DIR}/plugins ${qmltest_DEFAULT_IMPORT_PATHS})
7069add_qml_test(Panel MenuContent IMPORT_PATHS ${CMAKE_BINARY_DIR}/plugins ${qmltest_DEFAULT_IMPORT_PATHS})
7170add_qml_test(Panel Panel IMPORT_PATHS ${CMAKE_BINARY_DIR}/plugins ${qmltest_DEFAULT_IMPORT_PATHS})
7271add_qml_test(Panel SearchIndicator)
72+add_qml_test(Panel/Indicators DefaultIndicatorWidget IMPORT_PATHS ${CMAKE_BINARY_DIR}/plugins ${qmltest_DEFAULT_IMPORT_PATHS}
73+ ENVIRONMENT "LD_LIBRARY_PATH=${CMAKE_BINARY_DIR}/tests/mocks/QMenuModel")
7374add_qml_test(SideStage SideStage IMPORT_PATHS ${qmltest_DEFAULT_IMPORT_PATHS}
7475 ${CMAKE_BINARY_DIR}/tests/mocks
7576 ${CMAKE_BINARY_DIR}/plugins)
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/Components/tst_EdgeDemoOverlay.qml+2−2
@@ -112,8 +112,8 @@ Item {
112112 // Test that the 'none' edge skips anywhere
113113 signalSpy.target = none
114114 signalSpy.clear()
115− var backgroundShade = findChild(none, "backgroundShade")
116− tryCompare(none, "opacity", 1)
115+ var backgroundShade = findChild(none, "backgroundShadeMouseArea")
116+ tryCompare(backgroundShade, "enabled", true)
117117 mousePress(backgroundShade, 1, 1)
118118 mouseRelease(backgroundShade, 1, 1)
119119 signalSpy.wait()
tests/qmltests/Components/tst_MathLocal.qmldeleted−91
@@ -1,91 +0,0 @@
1−/*
2− * Copyright 2013 Canonical Ltd.
3− *
4− * This program is free software; you can redistribute it and/or modify
5− * it under the terms of the GNU 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 QtTest 1.0
19−import "../../../Components/Math.js" as MathLocal
20−
21−TestCase {
22− name: "MathLocal"
23−
24− property int minValue
25− property int maxValue
26− property int clampValue
27− property int clamped
28−
29− function test_clamp_positive_lower() {
30− minValue = 9
31− maxValue = 42
32− clampValue = -7
33−
34− clamped = MathLocal.clamp(clampValue, minValue, maxValue)
35− compare(clamped, minValue, "clamped value not within range")
36− }
37−
38− function test_clamp_positive_greater() {
39− minValue = 9
40− maxValue = 42
41− clampValue = 111
42−
43− clamped = MathLocal.clamp(clampValue, minValue, maxValue)
44− compare(clamped, maxValue, "clamped value not within range")
45− }
46−
47− function test_clamp_positive_within() {
48− minValue = 9
49− maxValue = 53
50− clampValue = 42
51−
52− clamped = MathLocal.clamp(clampValue, minValue, maxValue)
53− compare(clamped, clampValue, "clamped value changed even though it shouldn't have")
54− }
55−
56− function test_clamp_positive_on_border() {
57− minValue = 9
58− maxValue = 42
59− clampValue = 9
60−
61− clamped = MathLocal.clamp(clampValue, minValue, maxValue)
62− compare(clamped, clampValue, "clamped value changed even though it shouldn't have")
63− }
64−
65− function test_clamp_negative_lower() {
66− minValue = -42
67− maxValue = -9
68− clampValue = -50
69−
70− clamped = MathLocal.clamp(clampValue, minValue, maxValue)
71− compare(clamped, minValue, "clamped value not within range")
72− }
73−
74− function test_clamp_negative_greater() {
75− minValue = -42
76− maxValue = -9
77− clampValue = 50
78−
79− clamped = MathLocal.clamp(clampValue, minValue, maxValue)
80− compare(clamped, maxValue, "clamped value not within range")
81− }
82−
83− function test_clamp_postive_and_negative_greater() {
84− minValue = -42
85− maxValue = 9
86− clampValue = 50
87−
88− clamped = MathLocal.clamp(clampValue, minValue, maxValue)
89− compare(clamped, maxValue, "clamped value not within range")
90− }
91−}
tests/qmltests/Components/tst_PageHeader.qml+43−3
@@ -37,6 +37,10 @@ Item {
3737 property alias searchEnabled : pageHeader.searchEntryEnabled
3838 property alias searchQuery : pageHeader.searchQuery
3939
40+ function init() {
41+ searchEnabled = true;
42+ }
43+
4044 function test_search_disabled() {
4145 searchEnabled = false
4246 pageHeader.resetSearch()
@@ -151,12 +155,48 @@ Item {
151155 scopeMock.searchInProgress = true
152156 compare(searchIndicator.running, true, "Search indicator isn't running.")
153157 tryCompare(primaryImage, "visible", false)
154−
155− pageHeader.resetSearch()
156158 }
157159
158160 function cleanup() {
159− scopeMock.searchInProgress = false
161+ scopeMock.searchInProgress = false;
162+ pageHeader.resetSearch();
163+ }
164+
165+ function test_popover() {
166+ searchEnabled = true;
167+ pageHeader.searchHistory.clear();
168+
169+ pageHeader.searchHistory.addQuery("Search1");
170+ pageHeader.searchHistory.addQuery("Search2");
171+
172+ pageHeader.triggerSearch();
173+
174+ var searchContainer = findChild(pageHeader, "searchContainer");
175+ verify(searchContainer !== undefined, "searchContainer != undefined");
176+ tryCompareFunction(function() { return searchContainer.popover !== null; }, true);
177+
178+ tryCompare(searchContainer.popover, "visible", true);
179+ }
180+
181+ function test_resetSearch_onPopupClose() {
182+ searchEnabled = true;
183+ pageHeader.searchHistory.clear();
184+
185+ pageHeader.searchHistory.addQuery("Search1");
186+ pageHeader.searchHistory.addQuery("Search2");
187+
188+ pageHeader.triggerSearch();
189+
190+ var searchContainer = findChild(pageHeader, "searchContainer");
191+ verify(searchContainer !== undefined, "searchContainer != undefined");
192+ tryCompareFunction(function() { return searchContainer.popover !== null; }, true);
193+ compare(searchContainer.popover.visible, true);
194+
195+ pageHeader.searchQuery = "test";
196+ tryCompareFunction( function() { return (searchContainer.popover===null || !searchContainer.popover.visible) }, true);
197+
198+ pageHeader.resetSearch();
199+ compare((searchContainer.popover===null || !searchContainer.popover.visible), true);
160200 }
161201 }
162202
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/Dash/qml/FakeScopeView.qml+3−68
@@ -19,13 +19,13 @@ import Unity 0.1
1919
2020import "../../../../Dash"
2121
22−ScopeView {
22+GenericScopeView {
2323 id: fakeScopeView
2424
2525 property alias backColor : back.color
2626
2727 onEndReached: {
28− if (shell != undefined && shell.scopeStatus != undefined) {
28+ if (scope != undefined && shell != undefined && shell.scopeStatus != undefined) {
2929 shell.scopeStatus[scope.id].endReached++;
3030 }
3131 }
@@ -44,71 +44,6 @@ ScopeView {
4444 id: back
4545 anchors.fill: parent
4646 color: "grey"
47− }
48−
49− function randomBg()
50− {
51− var hex1=new Array("4", "5", "6", "7", "8", "9", "A", "B", "C", "D", "E", "F")
52− var bg="#"+hex1[Math.floor(Math.random()*hex1.length)]+
53− hex1[Math.floor(Math.random()*hex1.length)]+
54− hex1[Math.floor(Math.random()*hex1.length)]+
55− hex1[Math.floor(Math.random()*hex1.length)]+
56− hex1[Math.floor(Math.random()*hex1.length)]+
57− hex1[Math.floor(Math.random()*hex1.length)]
58− return bg
59− }
60−
61−
62− ListView {
63− id: listView
64− anchors.fill: parent
65− model: scope ? scope.categories : null
66− orientation: ListView.Vertical
67−
68− delegate: Column {
69− id: column
70− width: listView.width
71− height: childrenRect.height
72−
73− Rectangle {
74− width: listView.width
75− height: units.gu(3)
76− color: randomBg()
77−
78− Text {
79− text: name
80− font.family: "Ubuntu"
81− font.weight: Font.Bold
82− font.pixelSize: 20
83− anchors.horizontalCenter: parent.horizontalCenter
84− }
85− }
86− GridView {
87− id: resultsGrid
88− model: results
89− cellWidth: units.gu(10); cellHeight: units.gu(10)
90− height: childrenRect.height
91− width: listView.width
92− interactive: false
93−
94− delegate: Component {
95− id: resultDelegate
96− Item {
97− width: resultsGrid.cellWidth; height: resultsGrid.cellHeight
98− Column {
99− anchors.verticalCenter: parent.verticalCenter
100− anchors.horizontalCenter: parent.horizontalCenter
101− Image {
102− width: units.gu(5)
103− height: units.gu(5)
104− source: icon
105− anchors.horizontalCenter: parent.horizontalCenter
106− }
107− Text { text: title; anchors.horizontalCenter: parent.horizontalCenter }
108− }
109− }
110− }
111− }
112− }
47+ z: -1
11348 }
11449}
tests/qmltests/Dash/tst_Dash.qml+2
@@ -103,6 +103,8 @@ Item {
103103 return;
104104 }
105105 dash.showScopeOnLoaded = data.tag
106+ scopes.clear();
107+ scopes.load();
106108
107109 var dashContentList = findChild(dash, "dashContentList");
108110 verify(dashContentList != undefined);
tests/qmltests/Dash/tst_DashContent.qml+35−2
@@ -26,6 +26,18 @@ Item {
2626 width: units.gu(40)
2727 height: units.gu(80)
2828
29+ Item {
30+ // Fake. Make a few components less noisy
31+ id: greeter
32+ signal shownChanged
33+ }
34+
35+ Item {
36+ // Fake. Make a few components less noisy
37+ id: panel
38+ signal searchClicked
39+ }
40+
2941 property var scopeStatus: {
3042 'MockScope1': { 'movementStarted': 0, 'positionedAtBeginning': 0 },
3143 'MockScope2': { 'movementStarted': 0, 'positionedAtBeginning': 0 },
@@ -110,10 +122,17 @@ Item {
110122 clear_scope_status();
111123 dashContent.visible = true;
112124
113− scopesModel.clear();
114− // wait for dash to empty scopes.
115125 var dashContentList = findChild(dashContent, "dashContentList");
116126 verify(dashContentList != undefined);
127+ // TODO For Qt 5.2 remove this wait
128+ // and the tryCompare and see if it still crashes when
129+ // looping the test
130+ wait(1000);
131+ if (dashContentList.currentItem !== null) {
132+ tryCompare(dashContentList.currentItem, "moving", false);
133+ }
134+ scopesModel.clear();
135+ // wait for dash to empty scopes.
117136 tryCompare(dashContentList, "count", 0);
118137 }
119138
@@ -228,5 +247,19 @@ Item {
228247 tryCompare(scopesModel.get(1), "isActive", data.active1);
229248 tryCompare(scopesModel.get(2), "isActive", data.active2);
230249 }
250+
251+ function test_hswipe_disabled_vswipe() {
252+ var dashContentList = findChild(dashContent, "dashContentList");
253+
254+ tryCompare(dashContentList, "interactive", true);
255+
256+ var startX = dashContentList.width/2;
257+ var startY = dashContentList.height/2;
258+ touchFlick(dashContentList, startX, startY, startX, startY - units.gu(80));
259+
260+ tryCompare(dashContentList.currentItem, "moving", true);
261+
262+ compare(dashContentList.interactive, false);
263+ }
231264 }
232265}
tests/qmltests/Dash/tst_FilterGrids.qml+1−2
@@ -108,8 +108,7 @@ Rectangle {
108108 function test_clicked_signal_data() {
109109 return [
110110 {tag: "VideoFilterGrid", component: "Video/VideoFilterGrid.qml"},
111− {tag: "MusicFilterGrid", component: "Music/MusicFilterGrid.qml"},
112− {tag: "ApplicationsFilterGrid", component: "Apps/ApplicationsFilterGrid.qml"}
111+ {tag: "MusicFilterGrid", component: "Music/MusicFilterGrid.qml"}
113112 ]
114113 }
115114
tests/qmltests/Dash/tst_GenericScopeView.qml+27−2
@@ -74,6 +74,9 @@ Item {
7474 }
7575
7676 function openPreview() {
77+ var categoryListView = findChild(genericScopeView, "categoryListView");
78+ categoryListView.positionAtBeginning();
79+
7780 var tile = findChild(genericScopeView, "delegate0");
7881 mouseClick(tile, tile.width / 2, tile.height / 2);
7982 var openEffect = findChild(genericScopeView, "openEffect");
@@ -129,7 +132,23 @@ Item {
129132 tryCompare(previewListView, "open", false);
130133 }
131134
132− function test_previewCycleOne() {
135+ function test_hiddenPreviewOpen() {
136+ var categoryListView = findChild(genericScopeView, "categoryListView");
137+ categoryListView.positionAtBeginning();
138+ waitForRendering(categoryListView);
139+ categoryListView.flick(0, -units.gu(80));
140+ tryCompare(categoryListView.flicking, false);
141+
142+ var tile = findChild(genericScopeView, "delegate0");
143+ mouseClick(tile, tile.width / 2, tile.height - 1);
144+ var openEffect = findChild(genericScopeView, "openEffect");
145+ tryCompare(openEffect, "gap", 1);
146+
147+ var pageHeader = findChild(genericScopeView, "pageHeader");
148+ verify(openEffect.positionPx >= pageHeader.height + categoryListView.stickyHeaderHeight);
149+ }
150+
151+ function test_previewCycle() {
133152 var previewListView = findChild(genericScopeView, "previewListView");
134153 tryCompare(previewListView, "open", false);
135154
@@ -170,7 +189,6 @@ Item {
170189
171190 checkArrowPosition(i);
172191 }
173−
174192 closePreview();
175193 }
176194
@@ -187,6 +205,13 @@ Item {
187205
188206 closePreview();
189207 }
208+
209+ function test_changeScope() {
210+ genericScopeView.scope.searchQuery = "test"
211+ genericScopeView.scope = scopes.get(1)
212+ genericScopeView.scope = scopes.get(0)
213+ tryCompare(genericScopeView.scope, "searchQuery", "")
214+ }
190215 }
191216 }
192217}
tests/qmltests/Dash/tst_ScopeView.qmldeleted−52
@@ -1,52 +0,0 @@
1−/*
2− * Copyright 2013 Canonical Ltd.
3− *
4− * This program is free software; you can redistribute it and/or modify
5− * it under the terms of the GNU 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 QtTest 1.0
19−import Unity 0.1
20−import ".."
21−import "../../../Dash"
22−import Ubuntu.Components 0.1
23−
24−Item {
25− width: units.gu(120)
26− height: units.gu(80)
27−
28− Scopes {
29− id: scopes
30− }
31−
32− ScopeView {
33− id: scopeView
34− anchors.fill: parent
35−
36− TestCase {
37− name: "ScopeView"
38− when: scopes.loaded
39−
40− function init() {
41− scopeView.scope = scopes.get(0)
42− }
43−
44− function test_changeScope() {
45− scopeView.scope.searchQuery = "test"
46− scopeView.scope = scopes.get(1)
47− scopeView.scope = scopes.get(0)
48− tryCompare(scopeView.scope, "searchQuery", "")
49− }
50− }
51− }
52−}
tests/qmltests/Greeter/tst_Clock.qml+16
@@ -19,6 +19,7 @@ import QtTest 1.0
1919import ".."
2020import "../../../Greeter"
2121import Ubuntu.Components 0.1
22+import QMenuModel 0.1
2223import Unity.Test 0.1 as UT
2324
2425Rectangle {
@@ -35,9 +36,24 @@ Rectangle {
3536 }
3637 }
3738
39+ UnityMenuModel {
40+ id: menuModel
41+ modelData: [{
42+ "rowData": {
43+ "actionState": { "label": Qt.formatTime(new Date("October 13, 1975 11:13:00")) }
44+ }
45+ }]
46+ }
47+
3848 UT.UnityTestCase {
3949 name: "Clock"
4050
51+ function init() {
52+ var cachedModel = findChild(clock, "timeModel");
53+ verify(cachedModel !== undefined);
54+ cachedModel.model = menuModel;
55+ }
56+
4157 function test_customDate() {
4258 var dateObj = new Date("October 13, 1975 11:13:00")
4359 var dateString = Qt.formatDate(dateObj, Qt.DefaultLocaleLongDate)
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/Indicators/tst_DefaultIndicatorWidget.qmlnew file+97
@@ -0,0 +1,97 @@
1+/*
2+ * Copyright 2013 Canonical Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU 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 QtTest 1.0
19+import Unity.Test 0.1 as UT
20+import QMenuModel 0.1
21+import "../../../../Panel/Indicators"
22+
23+Item {
24+ id: testView
25+ width: units.gu(40)
26+ height: units.gu(70)
27+
28+ DefaultIndicatorWidget {
29+ id: widget
30+
31+ anchors {
32+ left: parent.left
33+ top: parent.top
34+ }
35+
36+ busName: "test"
37+ actionsObjectPath: "test"
38+ deviceMenuObjectPath: "test"
39+
40+ rootMenuType: ""
41+
42+ iconSize: units.gu(3.2)
43+ height: units.gu(3)
44+
45+ rootActionState {
46+ icons: [ "image://theme/audio-volume-high", "image://theme/audio-volume-low" ]
47+ leftLabel: "left"
48+ rightLabel: "right"
49+ }
50+ }
51+
52+ UT.UnityTestCase {
53+ name: "DefaultIndicatorWidget"
54+ when: windowShown
55+
56+ function init() {
57+ widget.rootActionState.icons = [];
58+ widget.rootActionState.leftLabel = "";
59+ widget.rootActionState.rightLabel = "";
60+ wait(50);
61+ }
62+
63+ function test_guRoundedWidth_data() {
64+ return [
65+ { tag: "empty", icons: [], leftLabel: "", rightLabel: "" },
66+ { tag: "1-icon-no-label", icons: [ "image://theme/audio-volume-high" ], leftLabel: "", rightLabel: "" },
67+ { tag: "2-icon-no-label", icons: [ "image://theme/audio-volume-high", "image://theme/audio-volume-low" ], leftLabel: "", rightLabel: "" },
68+ { tag: "no-icon-l-label", icons: [], leftLabel: "left", rightLabel: "" },
69+ { tag: "no-icon-lr-label", icons: [], leftLabel: "left", rightLabel: "right" },
70+ { tag: "1-icon-l-label", icons: [ "image://theme/audio-volume-high" ], leftLabel: "left", rightLabel: "" },
71+ { tag: "1-icon-lr-label", icons: [ "image://theme/audio-volume-high" ], leftLabel: "left", rightLabel: "right" },
72+ { tag: "2-icon-l-label", icons: [ "image://theme/audio-volume-high", "image://theme/audio-volume-low" ], leftLabel: "left", rightLabel: "" },
73+ { tag: "2-icon-lr-label", icons: [ "image://theme/audio-volume-high", "image://theme/audio-volume-low" ], leftLabel: "left", rightLabel: "right" }
74+ ];
75+ }
76+
77+ function test_guRoundedWidth(data) {
78+ widget.rootActionState.icons = data.icons
79+ widget.rootActionState.leftLabel = data.leftLabel;
80+ widget.rootActionState.rightLabel = data.rightLabel;
81+ wait(50);
82+
83+ compare(widget.width, guRoundUp(widget.width));
84+ }
85+ }
86+
87+ // TODO: Use toolkit function https://bugs.launchpad.net/ubuntu-ui-toolkit/+bug/1242575
88+ function guRoundUp(width) {
89+ if (width == 0) {
90+ return 0;
91+ }
92+ var gu1 = units.gu(1.0);
93+ var mod = (width % gu1);
94+
95+ return mod == 0 ? width : width + (gu1 - mod);
96+ }
97+}
tests/qmltests/Panel/tst_Panel.qml+13−5
@@ -48,10 +48,12 @@ Item {
4848
4949 function get_window_data() {
5050 return [
51− {tag: "pinned", fullscreenFlag: false },
52− {tag: "fullscreen", fullscreenFlag: true }
53− ]}
54−
51+ {tag: "pinned", fullscreenFlag: false, alreadyOpen: false },
52+ {tag: "fullscreen", fullscreenFlag: true, alreadyOpen: false },
53+ {tag: "pinned-alreadyOpen", fullscreenFlag: false, alreadyOpen: true },
54+ {tag: "fullscreen-alreadyOpen", fullscreenFlag: true, alreadyOpen: true }
55+ ];
56+ }
5557
5658 function init() {
5759 searchClicked = false;
@@ -135,6 +137,10 @@ Item {
135137 // expose more of the panel, binding it to the selected indicator and opening it's menu.
136138 function test_drag_show(data) {
137139 panel.fullscreenMode = data.fullscreenFlag;
140+ if (data.alreadyOpen) {
141+ panel.indicators.show();
142+ tryCompare(panel.indicators, "fullyOpened", true);
143+ }
138144
139145 var indicatorRow = findChild(panel.indicators, "indicatorRow");
140146 verify(indicatorRow != undefined);
@@ -186,7 +192,9 @@ Item {
186192 compare(menuContent.currentMenuIndex, i, "Menu conetent should be enabled for item at position " + i);
187193
188194 // init for next indicatorItem
189− init();
195+ if (!data.alreadyOpen) {
196+ init();
197+ }
190198 }
191199 }
192200
tests/qmltests/tst_Shell.qml+71−13
@@ -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() {
@@ -297,6 +320,10 @@ Item {
297320
298321 waitUntilApplicationWindowIsFullyVisible();
299322
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+
300327 // Minimize the application we just launched
301328 swipeFromLeftEdge(units.gu(27));
302329
@@ -437,7 +464,7 @@ Item {
437464 } while (!isStill);
438465 }
439466
440− function test_wallpaper_data() {
467+ function test_background_data() {
441468 return [
442469 {tag: "red", url: "tests/data/unity/backgrounds/red.png", expectedUrl: "tests/data/unity/backgrounds/red.png"},
443470 {tag: "blue", url: "tests/data/unity/backgrounds/blue.png", expectedUrl: "tests/data/unity/backgrounds/blue.png"},
@@ -446,13 +473,21 @@ Item {
446473 ]
447474 }
448475
449− function test_wallpaper(data) {
476+ function test_background(data) {
450477 var backgroundImage = findChild(shell, "backgroundImage")
451478 GSettingsController.setPictureUri(data.url)
452479 tryCompareFunction(function() { return backgroundImage.source.toString().indexOf(data.expectedUrl) !== -1; }, true)
453480 tryCompare(backgroundImage, "status", Image.Ready)
454481 }
455482
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+
456491 function test_DashShown_data() {
457492 return [
458493 {tag: "in focus", greeter: false, app: false, launcher: false, indicators: false, expectedShown: true},
@@ -488,5 +523,28 @@ Item {
488523 var dash = findChild(shell, "dash");
489524 tryCompare(dash, "shown", data.expectedShown);
490525 }
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+ }
491549 }
492550}
tests/utils/modules/Unity/Test/UnityTestCase.qml+36
@@ -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
@@ -213,6 +214,8 @@ TestCase {
213214
214215 // speed is in pixels/second
215216 function touchFlick(item, x, y, toX, toY, beginTouch, endTouch, speed, iterations) {
217+ // Make sure the item is rendered
218+ waitForRendering(item);
216219
217220 // Default to true for beginTouch if not present
218221 beginTouch = (beginTouch !== undefined) ? beginTouch : true
@@ -297,4 +300,37 @@ TestCase {
297300 event.release(0 /* touchId */, x, y)
298301 event.commit()
299302 }
303+
304+ Component.onCompleted: {
305+ var rootItem = parent;
306+ while (rootItem.parent != undefined) {
307+ rootItem = rootItem.parent;
308+ }
309+ removeTimeConstraintsFromDirectionalDragAreas(rootItem);
310+ }
311+
312+ /*
313+ In qmltests, sequences of touch events are sent all at once, unlike in "real life".
314+ Also qmltests might run really slowly, e.g. when run from inside virtual machines.
315+ Thus to remove a variable that qmltests cannot really control, namely time, this
316+ function removes all constraints from DirectionalDragAreas that are sensible to
317+ elapsed time.
318+
319+ This effectively makes DirectionalDragAreas easier to fool.
320+ */
321+ function removeTimeConstraintsFromDirectionalDragAreas(item) {
322+
323+ // use duck-typing to identify a DirectionalDragArea
324+ if (item.minSpeed != undefined
325+ && item.maxSilenceTime != undefined
326+ && item.compositionTime != undefined) {
327+ item.minSpeed = 0;
328+ item.maxSilenceTime = 60 * 60 * 1000;
329+ item.compositionTime = 0;
330+ } else {
331+ for (var i in item.children) {
332+ removeTimeConstraintsFromDirectionalDragAreas(item.children[i]);
333+ }
334+ }
335+ }
300336}